/*
 * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
 * This devtool is neither made for production nor for readable output files.
 * It uses "eval()" calls to create a separate source file in the browser devtools.
 * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
 * or disable the default devtool with "devtool: false".
 * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
 */
/******/ (() => { // webpackBootstrap
/******/ 	"use strict";
/******/ 	var __webpack_modules__ = ({

/***/ "./main.ts":
/*!*****************!*\
  !*** ./main.ts ***!
  \*****************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   MathliveSettingTab: () => (/* binding */ MathliveSettingTab),\n/* harmony export */   \"default\": () => (/* binding */ MathLivePlugin)\n/* harmony export */ });\n/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! tslib */ \"./node_modules/tslib/tslib.es6.js\");\n/* harmony import */ var mathlive__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! mathlive */ \"./node_modules/mathlive/dist/mathlive.mjs\");\n/* harmony import */ var obsidian__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! obsidian */ \"obsidian\");\n/* harmony import */ var obsidian__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(obsidian__WEBPACK_IMPORTED_MODULE_1__);\n\n\n\n\nconst DEFAULT_SETTINGS = {\n    apiKey: null,\n    selfHosted: false\n};\nclass MathLivePlugin extends obsidian__WEBPACK_IMPORTED_MODULE_1__.Plugin {\n    onload() {\n        return (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__awaiter)(this, void 0, void 0, function* () {\n            if (customElements.get(\"math-field\") === undefined)\n                customElements.define(\"math-field\", mathlive__WEBPACK_IMPORTED_MODULE_0__.MathfieldElement);\n            this.addCommand({\n                id: 'open-modal',\n                name: 'Add full-line math',\n                editorCallback: (editor, ctx) => {\n                    new MathLiveModal(this.app, editor, this).open();\n                }\n            });\n            this.addCommand({\n                id: 'open-modal-inline',\n                name: 'Add inline math',\n                editorCallback: (editor, ctx) => {\n                    new MathLiveModal(this.app, editor, this, true).open();\n                }\n            });\n            yield this.loadSettings();\n            this.addSettingTab(new MathliveSettingTab(this.app, this));\n        });\n    }\n    loadSettings() {\n        return (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__awaiter)(this, void 0, void 0, function* () {\n            this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());\n        });\n    }\n    saveSettings() {\n        return (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__awaiter)(this, void 0, void 0, function* () {\n            yield this.saveData(this.settings);\n        });\n    }\n}\nclass MathliveSettingTab extends obsidian__WEBPACK_IMPORTED_MODULE_1__.PluginSettingTab {\n    constructor(app, plugin) {\n        super(app, plugin);\n        this.plugin = plugin;\n    }\n    display() {\n        let { containerEl } = this;\n        containerEl.empty();\n        const title = document.createElement('h2');\n        title.textContent = 'Obsidian Mathlive';\n        title.setCssStyles({\n            fontSize: '28px'\n        });\n        containerEl.appendChild(title);\n        const intro = `This plugins currently has 2 main features, visual formula editor, and image to MathJax scanner.\nThe MathJax image scanner is available for free when self hosting.\nIn addition, there is a cloud option that requires no setup.\n\n* Self hosting the image scanner may require technical knowledge of docker and requires background processing resources. For most people, the cloud options is better.`;\n        const introEl = document.createElement('p');\n        introEl.textContent = intro;\n        introEl.style.whiteSpace = 'pre-wrap';\n        containerEl.appendChild(introEl);\n        new obsidian__WEBPACK_IMPORTED_MODULE_1__.Setting(containerEl);\n        const cloudTitle = document.createElement('h2');\n        cloudTitle.textContent = 'Cloud Settings';\n        cloudTitle.setCssStyles({\n            fontSize: '24px'\n        });\n        containerEl.appendChild(cloudTitle);\n        new obsidian__WEBPACK_IMPORTED_MODULE_1__.Setting(containerEl)\n            .setName('API key')\n            .addText(tc => tc.setValue(this.plugin.settings.apiKey).onChange((val) => (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__awaiter)(this, void 0, void 0, function* () {\n            this.plugin.settings.apiKey = val;\n            yield this.plugin.saveSettings();\n        })));\n        const homepageLink = document.createElement('a');\n        homepageLink.href = 'https://mathlive.danz.blog';\n        homepageLink.text = 'Create an API key here';\n        containerEl.appendChild(homepageLink);\n        new obsidian__WEBPACK_IMPORTED_MODULE_1__.Setting(containerEl);\n        const selfHostTitle = document.createElement('h2');\n        selfHostTitle.textContent = 'Self Hosting Settings';\n        selfHostTitle.setCssStyles({\n            fontSize: '24px'\n        });\n        containerEl.appendChild(selfHostTitle);\n        new obsidian__WEBPACK_IMPORTED_MODULE_1__.Setting(containerEl)\n            .setName('Self hosted')\n            .addToggle(toggle => toggle.setValue(this.plugin.settings.useLocalInference).onChange((val) => (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__awaiter)(this, void 0, void 0, function* () {\n            this.plugin.settings.useLocalInference = val;\n            yield this.plugin.saveSettings();\n        })));\n    }\n}\nclass MathLiveModal extends obsidian__WEBPACK_IMPORTED_MODULE_1__.Modal {\n    constructor(app, editor, plugin, inline = false) {\n        super(app);\n        this.editor = editor;\n        this.plugin = plugin;\n        this.inline = inline;\n    }\n    parseSelection(selectionText) {\n        if (selectionText.length === 0) {\n            const wrapper = this.inline ? \"$\" : \"$$\";\n            return {\n                resultRenderTemplate: result => result.length > 0 ? wrapper + result + wrapper : \"\",\n                initialLatex: \"\"\n            };\n        }\n        const mathPreviewStartIndex = selectionText.indexOf(\"$$\");\n        if (mathPreviewStartIndex >= 0) {\n            const mathPreviewEndIndex = selectionText.indexOf(\"$$\", mathPreviewStartIndex + 2);\n            if (mathPreviewEndIndex >= 0) {\n                return {\n                    resultRenderTemplate: result => selectionText.substring(0, mathPreviewStartIndex)\n                        + \"$$\"\n                        + result\n                        + \"$$\"\n                        + selectionText.substring(mathPreviewEndIndex + 2, selectionText.length),\n                    initialLatex: selectionText.substring(mathPreviewStartIndex + 2, mathPreviewEndIndex),\n                };\n            }\n        }\n        const mathInlineStartIndex = selectionText.indexOf(\"$\");\n        if (mathInlineStartIndex >= 0) {\n            const mathInlineEndIndex = selectionText.indexOf(\"$\", mathInlineStartIndex + 1);\n            return {\n                resultRenderTemplate: result => selectionText.substring(0, mathInlineStartIndex)\n                    + \"$\"\n                    + result\n                    + \"$\"\n                    + selectionText.substring(mathInlineEndIndex + 1, selectionText.length),\n                initialLatex: selectionText.substring(mathInlineStartIndex + 1, mathInlineEndIndex),\n            };\n        }\n        return {\n            resultRenderTemplate: result => result,\n            initialLatex: selectionText\n        };\n    }\n    onOpen() {\n        const modalContent = this.containerEl.querySelector('.modal-content');\n        const header = this.initHeader(modalContent);\n        this.initMadeByButton(header);\n        this.initSupportButton(header);\n        this.initMathlive(modalContent);\n        this.initSubmitButton(modalContent);\n        this.initImageScanner(modalContent);\n    }\n    initMathlive(modalContent) {\n        var _a;\n        const mathliveModalRoot = (_a = modalContent.parentElement) === null || _a === void 0 ? void 0 : _a.parentElement;\n        mathliveModalRoot === null || mathliveModalRoot === void 0 ? void 0 : mathliveModalRoot.addClass(\"mathlive-modal-root\");\n        const keyboardContainer = window.createEl('div');\n        keyboardContainer.addClass(\"virt-keyboard\");\n        mathliveModalRoot === null || mathliveModalRoot === void 0 ? void 0 : mathliveModalRoot.append(keyboardContainer);\n        const markdownView = this.app.workspace.getActiveViewOfType(obsidian__WEBPACK_IMPORTED_MODULE_1__.MarkdownView);\n        const selectionText = markdownView === null || markdownView === void 0 ? void 0 : markdownView.editor.getSelection();\n        const parseResult = this.parseSelection(selectionText !== null && selectionText !== void 0 ? selectionText : \"\");\n        if (!parseResult) {\n            new obsidian__WEBPACK_IMPORTED_MODULE_1__.Notice(\"MathLive: Failed to parse the selected text\");\n            this.close();\n            return;\n        }\n        const { initialLatex, resultRenderTemplate } = parseResult;\n        this.resultRenderTemplate = resultRenderTemplate;\n        this.renderedResult = resultRenderTemplate(initialLatex);\n        this.mfe = document.createElement(\"math-field\");\n        this.mfe.id = \"mathfield\";\n        this.mfe.value = initialLatex;\n        this.mfe.addEventListener('input', () => {\n            var _a, _b;\n            this.renderedResult = resultRenderTemplate((_b = (_a = this.mfe) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : '');\n        });\n        window.mathVirtualKeyboard.container = keyboardContainer;\n        modalContent.addClass(\"mathlive-modal-content\");\n        modalContent.appendChild(this.mfe);\n        this.mfe.focus();\n        setTimeout(() => document.getElementById(\"mathfield\").focus(), 10);\n    }\n    initHeader(modalContent) {\n        const header = document.createElement('div');\n        header.addClass('header');\n        modalContent.appendChild(header);\n        return header;\n    }\n    initMadeByButton(modalContent) {\n        const link = document.createElement('a');\n        link.innerText = '👱‍♂️ Made by Dan Zilberman';\n        link.addClass('badge');\n        link.setAttr('href', 'https://danzilberdan.github.io/');\n        link.setAttr('target', '_blank');\n        link.addClass('external-link');\n        modalContent.appendChild(link);\n    }\n    initSupportButton(modalContent) {\n        const link = document.createElement('a');\n        link.innerText = '☕ Support';\n        link.addClass('badge');\n        link.setAttr('href', 'https://www.buymeacoffee.com/danzilberdan');\n        link.setAttr('target', '_blank');\n        link.addClass('external-link');\n        modalContent.appendChild(link);\n    }\n    initSubmitButton(modalContent) {\n        const submitButton = document.createElement('button');\n        submitButton.innerText = 'Insert';\n        submitButton.addClass('submit');\n        submitButton.addEventListener('click', this.close.bind(this));\n        modalContent.appendChild(submitButton);\n    }\n    initImageScanner(modalContent) {\n        const scan = document.createElement('button');\n        scan.innerText = 'Scan MathJax from Clipboard';\n        scan.addClass('scan-button');\n        scan.onclick = this.onImageScanRequest.bind(this);\n        modalContent.appendChild(scan);\n    }\n    onImageScanRequest() {\n        var _a, _b;\n        return (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__awaiter)(this, void 0, void 0, function* () {\n            if (!this.plugin.settings.apiKey) {\n                new obsidian__WEBPACK_IMPORTED_MODULE_1__.Notice('Please open plugin settings to create API key.');\n                return;\n            }\n            try {\n                const clipboardItems = yield navigator.clipboard.read();\n                for (const item of clipboardItems) {\n                    for (const type of item.types) {\n                        if (item.types.includes('image/png')) {\n                            const blob = yield item.getType(type);\n                            new obsidian__WEBPACK_IMPORTED_MODULE_1__.Notice('Scanning MathJax image');\n                            const mathjax = yield this.scanImage(blob);\n                            this.mfe.value += mathjax;\n                            this.renderedResult = this.resultRenderTemplate((_b = (_a = this.mfe) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : '');\n                            new obsidian__WEBPACK_IMPORTED_MODULE_1__.Notice(`Got scan result for MathJax`);\n                            return;\n                        }\n                    }\n                }\n                new obsidian__WEBPACK_IMPORTED_MODULE_1__.Notice('No image found in clipboard.');\n            }\n            catch (error) {\n                console.error('Error reading clipboard or uploading image:', error);\n                new obsidian__WEBPACK_IMPORTED_MODULE_1__.Notice(`Failed to scan image. See console for details.`);\n            }\n        });\n    }\n    scanImage(imageData) {\n        return (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__awaiter)(this, void 0, void 0, function* () {\n            let address = 'https://mathlive-ocr.danz.blog';\n            if (this.plugin.settings.useLocalInference) {\n                address = 'http://localhost:8502';\n            }\n            const formData = new FormData();\n            formData.append('file', imageData);\n            const res = yield fetch(address + '/predict/', {\n                headers: {\n                    'Api-key': this.plugin.settings.apiKey\n                },\n                method: 'POST',\n                body: formData\n            });\n            return yield res.json();\n        });\n    }\n    convertToJPEG(imageData) {\n        return (0,tslib__WEBPACK_IMPORTED_MODULE_2__.__awaiter)(this, void 0, void 0, function* () {\n            const img = new Image();\n            img.src = imageData;\n            yield new Promise((resolve) => { img.onload = resolve; });\n            const canvas = document.createElement('canvas');\n            canvas.width = img.width;\n            canvas.height = img.height;\n            const ctx = canvas.getContext('2d');\n            ctx.drawImage(img, 0, 0);\n            return canvas.toDataURL('image/jpeg', 0.8);\n        });\n    }\n    onClose() {\n        if (!!this.renderedResult)\n            this.editor.replaceSelection(this.renderedResult);\n    }\n}\n\n\n//# sourceURL=webpack://obsidian-mathlive/./main.ts?");

/***/ }),

/***/ "./node_modules/tslib/tslib.es6.js":
/*!*****************************************!*\
  !*** ./node_modules/tslib/tslib.es6.js ***!
  \*****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   __assign: () => (/* binding */ __assign),\n/* harmony export */   __asyncDelegator: () => (/* binding */ __asyncDelegator),\n/* harmony export */   __asyncGenerator: () => (/* binding */ __asyncGenerator),\n/* harmony export */   __asyncValues: () => (/* binding */ __asyncValues),\n/* harmony export */   __await: () => (/* binding */ __await),\n/* harmony export */   __awaiter: () => (/* binding */ __awaiter),\n/* harmony export */   __classPrivateFieldGet: () => (/* binding */ __classPrivateFieldGet),\n/* harmony export */   __classPrivateFieldIn: () => (/* binding */ __classPrivateFieldIn),\n/* harmony export */   __classPrivateFieldSet: () => (/* binding */ __classPrivateFieldSet),\n/* harmony export */   __createBinding: () => (/* binding */ __createBinding),\n/* harmony export */   __decorate: () => (/* binding */ __decorate),\n/* harmony export */   __exportStar: () => (/* binding */ __exportStar),\n/* harmony export */   __extends: () => (/* binding */ __extends),\n/* harmony export */   __generator: () => (/* binding */ __generator),\n/* harmony export */   __importDefault: () => (/* binding */ __importDefault),\n/* harmony export */   __importStar: () => (/* binding */ __importStar),\n/* harmony export */   __makeTemplateObject: () => (/* binding */ __makeTemplateObject),\n/* harmony export */   __metadata: () => (/* binding */ __metadata),\n/* harmony export */   __param: () => (/* binding */ __param),\n/* harmony export */   __read: () => (/* binding */ __read),\n/* harmony export */   __rest: () => (/* binding */ __rest),\n/* harmony export */   __spread: () => (/* binding */ __spread),\n/* harmony export */   __spreadArray: () => (/* binding */ __spreadArray),\n/* harmony export */   __spreadArrays: () => (/* binding */ __spreadArrays),\n/* harmony export */   __values: () => (/* binding */ __values)\n/* harmony export */ });\n/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n    extendStatics = Object.setPrototypeOf ||\r\n        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n        function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n    return extendStatics(d, b);\r\n};\r\n\r\nfunction __extends(d, b) {\r\n    if (typeof b !== \"function\" && b !== null)\r\n        throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n    extendStatics(d, b);\r\n    function __() { this.constructor = d; }\r\n    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nvar __assign = function() {\r\n    __assign = Object.assign || function __assign(t) {\r\n        for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n            s = arguments[i];\r\n            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n        }\r\n        return t;\r\n    }\r\n    return __assign.apply(this, arguments);\r\n}\r\n\r\nfunction __rest(s, e) {\r\n    var t = {};\r\n    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n        t[p] = s[p];\r\n    if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n                t[p[i]] = s[p[i]];\r\n        }\r\n    return t;\r\n}\r\n\r\nfunction __decorate(decorators, target, key, desc) {\r\n    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n    if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n    return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nfunction __param(paramIndex, decorator) {\r\n    return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nfunction __metadata(metadataKey, metadataValue) {\r\n    if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nfunction __awaiter(thisArg, _arguments, P, generator) {\r\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n    return new (P || (P = Promise))(function (resolve, reject) {\r\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n    });\r\n}\r\n\r\nfunction __generator(thisArg, body) {\r\n    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n    return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n    function verb(n) { return function (v) { return step([n, v]); }; }\r\n    function step(op) {\r\n        if (f) throw new TypeError(\"Generator is already executing.\");\r\n        while (_) try {\r\n            if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n            if (y = 0, t) op = [op[0] & 2, t.value];\r\n            switch (op[0]) {\r\n                case 0: case 1: t = op; break;\r\n                case 4: _.label++; return { value: op[1], done: false };\r\n                case 5: _.label++; y = op[1]; op = [0]; continue;\r\n                case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n                default:\r\n                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n                    if (t[2]) _.ops.pop();\r\n                    _.trys.pop(); continue;\r\n            }\r\n            op = body.call(thisArg, _);\r\n        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n    }\r\n}\r\n\r\nvar __createBinding = Object.create ? (function(o, m, k, k2) {\r\n    if (k2 === undefined) k2 = k;\r\n    var desc = Object.getOwnPropertyDescriptor(m, k);\r\n    if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n        desc = { enumerable: true, get: function() { return m[k]; } };\r\n    }\r\n    Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n    if (k2 === undefined) k2 = k;\r\n    o[k2] = m[k];\r\n});\r\n\r\nfunction __exportStar(m, o) {\r\n    for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nfunction __values(o) {\r\n    var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n    if (m) return m.call(o);\r\n    if (o && typeof o.length === \"number\") return {\r\n        next: function () {\r\n            if (o && i >= o.length) o = void 0;\r\n            return { value: o && o[i++], done: !o };\r\n        }\r\n    };\r\n    throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nfunction __read(o, n) {\r\n    var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n    if (!m) return o;\r\n    var i = m.call(o), r, ar = [], e;\r\n    try {\r\n        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n    }\r\n    catch (error) { e = { error: error }; }\r\n    finally {\r\n        try {\r\n            if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n        }\r\n        finally { if (e) throw e.error; }\r\n    }\r\n    return ar;\r\n}\r\n\r\n/** @deprecated */\r\nfunction __spread() {\r\n    for (var ar = [], i = 0; i < arguments.length; i++)\r\n        ar = ar.concat(__read(arguments[i]));\r\n    return ar;\r\n}\r\n\r\n/** @deprecated */\r\nfunction __spreadArrays() {\r\n    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n    for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n            r[k] = a[j];\r\n    return r;\r\n}\r\n\r\nfunction __spreadArray(to, from, pack) {\r\n    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n        if (ar || !(i in from)) {\r\n            if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n            ar[i] = from[i];\r\n        }\r\n    }\r\n    return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nfunction __await(v) {\r\n    return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nfunction __asyncGenerator(thisArg, _arguments, generator) {\r\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n    var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n    return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n    function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n    function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n    function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n    function fulfill(value) { resume(\"next\", value); }\r\n    function reject(value) { resume(\"throw\", value); }\r\n    function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nfunction __asyncDelegator(o) {\r\n    var i, p;\r\n    return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n    function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nfunction __asyncValues(o) {\r\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n    var m = o[Symbol.asyncIterator], i;\r\n    return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n    function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n    function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nfunction __makeTemplateObject(cooked, raw) {\r\n    if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n    return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n    o[\"default\"] = v;\r\n};\r\n\r\nfunction __importStar(mod) {\r\n    if (mod && mod.__esModule) return mod;\r\n    var result = {};\r\n    if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n    __setModuleDefault(result, mod);\r\n    return result;\r\n}\r\n\r\nfunction __importDefault(mod) {\r\n    return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nfunction __classPrivateFieldGet(receiver, state, kind, f) {\r\n    if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n    if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n    return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nfunction __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n    if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n    if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n    if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n    return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nfunction __classPrivateFieldIn(state, receiver) {\r\n    if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n    return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n\n\n//# sourceURL=webpack://obsidian-mathlive/./node_modules/tslib/tslib.es6.js?");

/***/ }),

/***/ "obsidian":
/*!***************************!*\
  !*** external "obsidian" ***!
  \***************************/
/***/ ((module) => {

module.exports = require("obsidian");

/***/ }),

/***/ "./node_modules/mathlive/dist/mathlive.mjs":
/*!*************************************************!*\
  !*** ./node_modules/mathlive/dist/mathlive.mjs ***!
  \*************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   MathfieldElement: () => (/* binding */ MathfieldElement),\n/* harmony export */   _renderMathInElement: () => (/* binding */ _renderMathInElement),\n/* harmony export */   convertAsciiMathToLatex: () => (/* binding */ convertAsciiMathToLatex),\n/* harmony export */   convertLatexToAsciiMath: () => (/* binding */ convertLatexToAsciiMath),\n/* harmony export */   convertLatexToMarkup: () => (/* binding */ convertLatexToMarkup),\n/* harmony export */   convertLatexToMathMl: () => (/* binding */ convertLatexToMathMl),\n/* harmony export */   convertLatexToSpeakableText: () => (/* binding */ convertLatexToSpeakableText),\n/* harmony export */   convertMathJsonToLatex: () => (/* binding */ convertMathJsonToLatex),\n/* harmony export */   globalMathLive: () => (/* binding */ globalMathLive),\n/* harmony export */   renderMathInDocument: () => (/* binding */ renderMathInDocument),\n/* harmony export */   renderMathInElement: () => (/* binding */ renderMathInElement),\n/* harmony export */   validateLatex: () => (/* binding */ validateLatex2),\n/* harmony export */   version: () => (/* binding */ version)\n/* harmony export */ });\n/** MathLive 0.101.0 */\nvar __defProp = Object.defineProperty;\nvar __defProps = Object.defineProperties;\nvar __getOwnPropDescs = Object.getOwnPropertyDescriptors;\nvar __getOwnPropSymbols = Object.getOwnPropertySymbols;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __propIsEnum = Object.prototype.propertyIsEnumerable;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __spreadValues = (a, b) => {\n  for (var prop in b || (b = {}))\n    if (__hasOwnProp.call(b, prop))\n      __defNormalProp(a, prop, b[prop]);\n  if (__getOwnPropSymbols)\n    for (var prop of __getOwnPropSymbols(b)) {\n      if (__propIsEnum.call(b, prop))\n        __defNormalProp(a, prop, b[prop]);\n    }\n  return a;\n};\nvar __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));\nvar __restKey = (key) => typeof key === \"symbol\" ? key : key + \"\";\nvar __objRest = (source, exclude) => {\n  var target = {};\n  for (var prop in source)\n    if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)\n      target[prop] = source[prop];\n  if (source != null && __getOwnPropSymbols)\n    for (var prop of __getOwnPropSymbols(source)) {\n      if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))\n        target[prop] = source[prop];\n    }\n  return target;\n};\n\n// src/common/types.ts\nfunction isArray(x) {\n  return Array.isArray(x);\n}\n\n// src/editor/l10n-strings.ts\nvar STRINGS = {\n  \"en\": {\n    \"keyboard.tooltip.symbols\": \"Symbols\",\n    \"keyboard.tooltip.greek\": \"Greek Letters\",\n    \"keyboard.tooltip.numeric\": \"Numeric\",\n    \"keyboard.tooltip.alphabetic\": \"Roman Letters\",\n    \"tooltip.copy to clipboard\": \"Copy to Clipboard\",\n    \"tooltip.cut to clipboard\": \"Cut to Clipboard\",\n    \"tooltip.paste from clipboard\": \"Paste from Clipboard\",\n    \"tooltip.redo\": \"Redo\",\n    \"tooltip.toggle virtual keyboard\": \"Toggle Virtual Keyboard\",\n    \"tooltip.menu\": \"Menu\",\n    \"tooltip.undo\": \"Undo\",\n    \"menu.borders\": \"Borders\",\n    \"menu.insert matrix\": \"Insert Matrix\",\n    \"menu.array.add row above\": \"Add Row Before\",\n    \"menu.array.add row below\": \"Add Row After\",\n    \"menu.array.add column after\": \"Add Column After\",\n    \"menu.array.add column before\": \"Add Column Before\",\n    \"menu.array.delete row\": \"Delete Row\",\n    \"menu.array.delete rows\": \"Delete Selected Rows\",\n    \"menu.array.delete column\": \"Delete Column\",\n    \"menu.array.delete columns\": \"Delete Selected Columns\",\n    \"menu.mode\": \"Mode\",\n    \"menu.mode-math\": \"Math\",\n    \"menu.mode-text\": \"Text\",\n    \"menu.mode-latex\": \"LaTeX\",\n    \"menu.insert\": \"Insert\",\n    \"menu.insert.abs\": \"Absolute Value\",\n    \"menu.insert.abs-template\": \"\\\\left|x\\\\right|\",\n    \"menu.insert.nth-root\": \"n<sup>th</sup> Root\",\n    \"menu.insert.nth-root-template\": \"\\\\sqrt[n]{x}\",\n    \"menu.insert.log-base\": \"Logarithm base a\",\n    \"menu.insert.log-base-template\": \"\\\\log_a(x)\",\n    \"menu.insert.heading-calculus\": \"Calculus\",\n    \"menu.insert.derivative\": \"Derivative\",\n    \"menu.insert.derivative-template\": \"\\\\dfrac{\\\\mathrm{d}}{\\\\mathrm{d}x}f(x)\\\\bigm|_{x=a}\",\n    \"menu.insert.nth-derivative\": \"n<sup>th</sup> derivative\",\n    \"menu.insert.nth-derivative-template\": \"\\\\dfrac{\\\\mathrm{d}^n}{\\\\mathrm{d}x^n}f(x)\\\\bigm|_{x=a}\",\n    \"menu.insert.integral\": \"Integral\",\n    \"menu.insert.integral-template\": \"$\\\\int_a^b f(x)\\\\,\\\\mathrm{d}x$\",\n    \"menu.insert.sum\": \"Sum\",\n    \"menu.insert.sum-template\": \"$\\\\sum_{i=1}^n x_i$\",\n    \"menu.insert.product\": \"Product\",\n    \"menu.insert.product-template\": \"\\\\prod_{i=1}^n x_i\",\n    \"menu.insert.heading-complex-numbers\": \"Complex Numbers\",\n    \"menu.insert.modulus\": \"Modulus\",\n    \"menu.insert.modulus-template\": \"\\\\lvert z \\\\rvert\",\n    \"menu.insert.argument\": \"Argument\",\n    \"menu.insert.argument-template\": \"\\\\arg(z)\",\n    \"menu.insert.real-part\": \"Real Part\",\n    \"menu.insert.real-part-template\": \"\\\\Re(z)\",\n    \"menu.insert.imaginary-part\": \"Imaginary Part\",\n    \"menu.insert.imaginary-part-template\": \"\\\\Im(z)\",\n    \"menu.insert.conjugate\": \"Conjugate\",\n    \"menu.insert.conjugate-template\": \"\\\\overline{z}\",\n    \"tooltip.blackboard\": \"Blackboard\",\n    \"tooltip.bold\": \"Bold\",\n    \"tooltip.italic\": \"Italic\",\n    \"tooltip.fraktur\": \"Fraktur\",\n    \"tooltip.script\": \"Script\",\n    \"tooltip.caligraphic\": \"Caligraphic\",\n    \"tooltip.typewriter\": \"Typewriter\",\n    \"tooltip.roman-upright\": \"Roman Upright\",\n    \"tooltip.row-by-col\": \"%@ \\xD7 %@\",\n    \"menu.font-style\": \"Font Style\",\n    \"menu.accent\": \"Accent\",\n    \"menu.decoration\": \"Decoration\",\n    \"menu.color\": \"Color\",\n    \"menu.background-color\": \"Background\",\n    \"menu.evaluate\": \"Evaluate\",\n    \"menu.simplify\": \"Simplify\",\n    \"menu.solve\": \"Solve\",\n    \"menu.solve-for\": \"Solve for %@\",\n    \"menu.cut\": \"Cut\",\n    \"menu.copy\": \"Copy\",\n    \"menu.copy-as-latex\": \"Copy as LaTeX\",\n    \"menu.copy-as-ascii-math\": \"Copy as ASCII Math\",\n    \"menu.copy-as-mathml\": \"Copy as MathML\",\n    \"menu.paste\": \"Paste\",\n    \"menu.select-all\": \"Select All\",\n    // Colors (accessible labels in color swatches)\n    \"color.red\": \"Red\",\n    \"color.orange\": \"Orange\",\n    \"color.yellow\": \"Yellow\",\n    \"color.lime\": \"Lime\",\n    \"color.green\": \"Green\",\n    \"color.teal\": \"Teal\",\n    \"color.cyan\": \"Cyan\",\n    \"color.blue\": \"Blue\",\n    \"color.indigo\": \"Indigo\",\n    \"color.purple\": \"Purple\",\n    \"color.magenta\": \"Magenta\",\n    \"color.black\": \"Black\",\n    \"color.dark-grey\": \"Dark Grey\",\n    \"color.grey\": \"Grey\",\n    \"color.light-grey\": \"Light Grey\",\n    \"color.white\": \"White\"\n  },\n  // Arabic\n  \"ar\": {\n    \"keyboard.tooltip.symbols\": \"\\u062D\\u0631\\u0641 \\u0627\\u0648 \\u0631\\u0645\\u0632\",\n    \"keyboard.tooltip.greek\": \"\\u062D\\u0631\\u0648\\u0641 \\u064A\\u0648\\u0646\\u0627\\u0646\\u064A\\u0629\",\n    \"keyboard.tooltip.numeric\": \"\\u0627\\u0644\\u0631\\u0642\\u0645\\u064A\\u0629\",\n    \"keyboard.tooltip.alphabetic\": \"\\u0631\\u0645\\u0648\\u0632 \\u0627\\u0644\\u0627\\u062D\\u0631\\u0641 \\u0627\\u0644\\u0631\\u0648\\u0645\\u0627\\u0646\\u064A\\u0629\",\n    \"tooltip.copy to clipboard\": \"\\u0646\\u0633\\u062E \\u0625\\u0644\\u0649 \\u0627\\u0644\\u062D\\u0627\\u0641\\u0638\\u0629\",\n    \"tooltip.cut to clipboard\": \"\\u0642\\u0635 \\u0625\\u0644\\u0649 \\u0627\\u0644\\u062D\\u0627\\u0641\\u0638\\u0629\",\n    \"tooltip.paste from clipboard\": \"\\u0644\\u0635\\u0642 \\u0645\\u0646 \\u0627\\u0644\\u062D\\u0627\\u0641\\u0638\\u0629\",\n    \"tooltip.redo\": \"\\u0627\\u0644\\u0625\\u0639\\u0627\\u062F\\u0629\",\n    \"tooltip.toggle virtual keyboard\": \"\\u062A\\u0628\\u062F\\u064A\\u0644 \\u0644\\u0648\\u062D\\u0629 \\u0627\\u0644\\u0645\\u0641\\u0627\\u062A\\u064A\\u062D \\u0627\\u0644\\u0625\\u0641\\u062A\\u0631\\u0627\\u0636\\u064A\\u0629\",\n    \"tooltip.undo\": \"\\u0625\\u0644\\u063A\\u0627\\u0621\",\n    \"menu.insert matrix\": \"\\u0623\\u062F\\u062E\\u0644 \\u0627\\u0644\\u0645\\u0635\\u0641\\u0648\\u0641\\u0629\",\n    \"menu.borders\": \"\\u0645\\u062D\\u062F\\u062F\\u0627\\u062A \\u0627\\u0644\\u0645\\u0635\\u0641\\u0648\\u0641\\u0629\",\n    \"menu.array.add row above\": \"\\u0623\\u0636\\u0641 \\u0635\\u0641\\u064B\\u0627 \\u0628\\u0639\\u062F \\u0630\\u0644\\u0643\",\n    \"menu.array.add row below\": \"\\u0623\\u0636\\u0641 \\u0627\\u0644\\u0635\\u0641 \\u0642\\u0628\\u0644\",\n    \"menu.array.add column after\": \"\\u0623\\u0636\\u0641 \\u0627\\u0644\\u0639\\u0645\\u0648\\u062F \\u0628\\u0639\\u062F \\u0630\\u0644\\u0643\",\n    \"menu.array.add column before\": \"\\u0623\\u0636\\u0641 \\u0627\\u0644\\u0639\\u0645\\u0648\\u062F \\u0642\\u0628\\u0644\",\n    \"menu.array.delete row\": \"\\u0627\\u062D\\u0630\\u0641 \\u0635\\u0641\",\n    \"menu.array.delete rows\": \"\\u062D\\u0630\\u0641 \\u0627\\u0644\\u0635\\u0641\\u0648\\u0641 \\u0627\\u0644\\u0645\\u062D\\u062F\\u062F\\u0629\",\n    \"menu.array.delete column\": \"\\u062D\\u0630\\u0641 \\u0627\\u0644\\u0639\\u0645\\u0648\\u062F\",\n    \"menu.array.delete columns\": \"\\u062D\\u0630\\u0641 \\u0627\\u0644\\u0623\\u0639\\u0645\\u062F\\u0629 \\u0627\\u0644\\u0645\\u062D\\u062F\\u062F\\u0629\",\n    \"menu.mode\": \"\\u0648\\u0636\\u0639\",\n    \"menu.mode-math\": \"\\u0631\\u064A\\u0627\\u0636\\u064A\\u0627\\u062A\",\n    \"menu.mode-text\": \"\\u0646\\u0635\",\n    \"menu.mode-latex\": \"\\u0644\\u0627\\u062A\\u0643\\u0633\",\n    \"tooltip.blackboard\": \"\\u0633\\u0628\\u0648\\u0631\\u0629\",\n    \"tooltip.bold\": \"\\u0639\\u0631\\u064A\\u0636\",\n    \"tooltip.italic\": \"\\u0645\\u0627\\u0626\\u0644\",\n    \"tooltip.fraktur\": \"\\u0641\\u0631\\u0627\\u0643\\u062A\\u0648\\u0631\",\n    \"tooltip.script\": \"\\u0633\\u0643\\u0631\\u064A\\u0628\\u062A\",\n    \"tooltip.caligraphic\": \"\\u0643\\u0627\\u0644\\u064A\\u062C\\u0631\\u0627\\u0641\\u064A\\u0643\",\n    \"tooltip.typewriter\": \"\\u0622\\u0644\\u0629 \\u0643\\u0627\\u062A\\u0628\\u0629\",\n    \"tooltip.roman-upright\": \"\\u0631\\u0648\\u0645\\u0627\\u0646\\u064A \\u0645\\u0633\\u062A\\u0642\\u064A\\u0645\",\n    \"tooltip.row-by-col\": \"%@ \\xD7 %@\",\n    \"menu.font-style\": \"\\u0646\\u0645\\u0637 \\u0627\\u0644\\u062E\\u0637\",\n    \"menu.accent\": \"\\u062A\\u0634\\u0643\\u064A\\u0644\",\n    \"menu.decoration\": \"\\u0632\\u062E\\u0631\\u0641\\u0629\",\n    \"menu.color\": \"\\u0644\\u0648\\u0646\",\n    \"menu.background-color\": \"\\u0627\\u0644\\u062E\\u0644\\u0641\\u064A\\u0629\",\n    \"menu.evaluate\": \"\\u062A\\u0642\\u064A\\u064A\\u0645\",\n    \"menu.simplify\": \"\\u062A\\u0628\\u0633\\u064A\\u0637\",\n    \"menu.solve\": \"\\u062D\\u0644\",\n    \"menu.solve-for\": \"\\u062D\\u0644 \\u0644\\u0640 %@\",\n    \"menu.cut\": \"\\u0642\\u0635\",\n    \"menu.copy\": \"\\u0646\\u0633\\u062E\",\n    \"menu.copy-as-latex\": \"\\u0646\\u0633\\u062E \\u0643\\u0640 LaTeX\",\n    \"menu.copy-as-ascii-math\": \"\\u0646\\u0633\\u062E \\u0643\\u0640 ASCII Math\",\n    \"menu.copy-as-mathml\": \"\\u0646\\u0633\\u062E \\u0643\\u0640 MathML\",\n    \"menu.paste\": \"\\u0644\\u0635\\u0642\",\n    \"menu.select-all\": \"\\u062A\\u062D\\u062F\\u064A\\u062F \\u0627\\u0644\\u0643\\u0644\",\n    // Colors (accessible labels in color swatches)\n    \"color.red\": \"\\u0623\\u062D\\u0645\\u0631\",\n    \"color.orange\": \"\\u0628\\u0631\\u062A\\u0642\\u0627\\u0644\\u064A\",\n    \"color.yellow\": \"\\u0623\\u0635\\u0641\\u0631\",\n    \"color.lime\": \"\\u0644\\u064A\\u0645\\u0648\\u0646\\u064A\",\n    \"color.green\": \"\\u0623\\u062E\\u0636\\u0631\",\n    \"color.teal\": \"\\u0633\\u0645\\u0627\\u0648\\u064A\",\n    \"color.cyan\": \"\\u0633\\u0645\\u0627\\u0648\\u064A \\u0641\\u0627\\u062A\\u062D\",\n    \"color.blue\": \"\\u0623\\u0632\\u0631\\u0642\",\n    \"color.indigo\": \"\\u0646\\u064A\\u0644\\u064A\",\n    \"color.purple\": \"\\u0628\\u0646\\u0641\\u0633\\u062C\\u064A\",\n    \"color.magenta\": \"\\u0623\\u0631\\u062C\\u0648\\u0627\\u0646\\u064A\",\n    \"color.black\": \"\\u0623\\u0633\\u0648\\u062F\",\n    \"color.dark-grey\": \"\\u0631\\u0645\\u0627\\u062F\\u064A \\u063A\\u0627\\u0645\\u0642\",\n    \"color.grey\": \"\\u0631\\u0645\\u0627\\u062F\\u064A\",\n    \"color.light-grey\": \"\\u0631\\u0645\\u0627\\u062F\\u064A \\u0641\\u0627\\u062A\\u062D\",\n    \"color.white\": \"\\u0623\\u0628\\u064A\\u0636\"\n  },\n  // German\n  \"de\": {\n    \"keyboard.tooltip.symbols\": \"Symbole\",\n    \"keyboard.tooltip.greek\": \"Griechische Buchstaben\",\n    \"keyboard.tooltip.numeric\": \"Numerisch\",\n    \"keyboard.tooltip.alphabetic\": \"R\\xF6mische Buchstaben\",\n    \"tooltip.copy to clipboard\": \"In die Zwischenablage kopieren\",\n    \"tooltip.redo\": \"Wiederholen\",\n    \"tooltip.toggle virtual keyboard\": \"Virtuelle Tastatur umschalten\",\n    \"tooltip.undo\": \"Widerrufen\",\n    \"menu.insert matrix\": \"Matrix einf\\xFCgen\",\n    \"menu.borders\": \"Matrixtrennzeichen\",\n    \"menu.array.add row above\": \"Zeile hinzuf\\xFCgen nach\",\n    \"menu.array.add row below\": \"Zeile hinzuf\\xFCgen vor\",\n    \"menu.array.add column after\": \"Spalte hinzuf\\xFCgen nach\",\n    \"menu.array.add column before\": \"Spalte hinzuf\\xFCgen vor\",\n    \"menu.array.delete row\": \"Zeile l\\xF6schen\",\n    \"menu.array.delete rows\": \"Ausgew\\xE4hlte Zeilen l\\xF6schen\",\n    \"menu.array.delete column\": \"Spalte l\\xF6schen\",\n    \"menu.array.delete columns\": \"Ausgew\\xE4hlte Spalten l\\xF6schen\",\n    \"menu.mode\": \"Modus\",\n    \"menu.mode-math\": \"Mathematik\",\n    \"menu.mode-text\": \"Text\",\n    \"menu.mode-latex\": \"LaTeX\",\n    \"tooltip.blackboard\": \"Tafel\",\n    \"tooltip.bold\": \"Fett\",\n    \"tooltip.italic\": \"Kursiv\",\n    \"tooltip.fraktur\": \"Fraktur\",\n    \"tooltip.script\": \"Skript\",\n    \"tooltip.caligraphic\": \"Kalligraphie\",\n    \"tooltip.typewriter\": \"Schreibmaschine\",\n    \"tooltip.roman-upright\": \"R\\xF6misch aufrecht\",\n    \"tooltip.row-by-col\": \"%@ \\xD7 %@\",\n    \"menu.font-style\": \"Schriftstil\",\n    \"menu.accent\": \"Akzent\",\n    \"menu.decoration\": \"Dekoration\",\n    \"menu.color\": \"Farbe\",\n    \"menu.background-color\": \"Hintergrund\",\n    \"menu.evaluate\": \"Auswerten\",\n    \"menu.simplify\": \"Vereinfachen\",\n    \"menu.solve\": \"L\\xF6sen\",\n    \"menu.solve-for\": \"L\\xF6sen f\\xFCr %@\",\n    \"menu.cut\": \"Ausschneiden\",\n    \"menu.copy\": \"Kopieren\",\n    \"menu.copy-as-latex\": \"Als LaTeX kopieren\",\n    \"menu.copy-as-ascii-math\": \"Als ASCII Math kopieren\",\n    \"menu.copy-as-mathml\": \"Als MathML kopieren\",\n    \"menu.paste\": \"Einf\\xFCgen\",\n    \"menu.select-all\": \"Alles ausw\\xE4hlen\",\n    // Colors (accessible labels in color swatches)\n    \"color.red\": \"Rot\",\n    \"color.orange\": \"Orange\",\n    \"color.yellow\": \"Gelb\",\n    \"color.lime\": \"Limette\",\n    \"color.green\": \"Gr\\xFCn\",\n    \"color.teal\": \"Blaugr\\xFCn\",\n    \"color.cyan\": \"Cyan\",\n    \"color.blue\": \"Blau\",\n    \"color.indigo\": \"Indigo\",\n    \"color.purple\": \"Lila\",\n    \"color.magenta\": \"Magenta\",\n    \"color.black\": \"Schwarz\",\n    \"color.dark-grey\": \"Dunkelgrau\",\n    \"color.grey\": \"Grau\",\n    \"color.light-grey\": \"Hellgrau\",\n    \"color.white\": \"Wei\\xDF\"\n  },\n  // Greek\n  \"el\": {\n    \"keyboard.tooltip.symbols\": \"\\u03C3\\u03CD\\u03BC\\u03B2\\u03BF\\u03BB\\u03B1\",\n    \"keyboard.tooltip.greek\": \"\\u03B5\\u03BB\\u03BB\\u03B7\\u03BD\\u03B9\\u03BA\\u03AC \\u03B3\\u03C1\\u03AC\\u03BC\\u03BC\\u03B1\\u03C4\\u03B1\",\n    \"keyboard.tooltip.numeric\": \"\\u0391\\u03C1\\u03B9\\u03B8\\u03BC\\u03B7\\u03C4\\u03B9\\u03BA\\u03CC\\u03C2\",\n    \"keyboard.tooltip.alphabetic\": \"\\u03A1\\u03C9\\u03BC\\u03B1\\u03CA\\u03BA\\u03AC \\u03B3\\u03C1\\u03AC\\u03BC\\u03BC\\u03B1\\u03C4\\u03B1\",\n    \"tooltip.copy to clipboard\": \"\\u0391\\u03BD\\u03C4\\u03B9\\u03B3\\u03C1\\u03B1\\u03C6\\u03AE \\u03C3\\u03C4\\u03BF \\u03C0\\u03C1\\u03CC\\u03C7\\u03B5\\u03B9\\u03C1\\u03BF\",\n    \"tooltip.redo\": \"\\u039E\\u03B1\\u03BD\\u03B1\\u03BA\\u03AC\\u03BD\\u03C9\",\n    \"tooltip.toggle virtual keyboard\": \"\\u0395\\u03BD\\u03B1\\u03BB\\u03BB\\u03B1\\u03B3\\u03AE \\u03B5\\u03B9\\u03BA\\u03BF\\u03BD\\u03B9\\u03BA\\u03BF\\u03CD \\u03C0\\u03BB\\u03B7\\u03BA\\u03C4\\u03C1\\u03BF\\u03BB\\u03BF\\u03B3\\u03AF\\u03BF\\u03C5\",\n    \"tooltip.undo\": \"\\u039E\\u03B5\\u03BA\\u03AC\\u03BD\\u03C9\",\n    \"menu.insert matrix\": \"\\u0395\\u03B9\\u03C3\\u03B1\\u03B3\\u03C9\\u03B3\\u03AE \\u03BC\\u03AE\\u03C4\\u03C1\\u03B1\",\n    \"menu.borders\": \"\\u039F\\u03C1\\u03B9\\u03BF\\u03B8\\u03AD\\u03C4\\u03B5\\u03C2 \\u03BC\\u03AE\\u03C4\\u03C1\\u03B1\",\n    \"menu.array.add row above\": \"\\u03A0\\u03C1\\u03BF\\u03C3\\u03B8\\u03AE\\u03BA\\u03B7 \\u03C3\\u03B5\\u03B9\\u03C1\\u03AC\\u03C2 \\u03BC\\u03B5\\u03C4\\u03AC\",\n    \"menu.array.add row below\": \"\\u03A0\\u03C1\\u03BF\\u03C3\\u03B8\\u03AE\\u03BA\\u03B7 \\u03C3\\u03B5\\u03B9\\u03C1\\u03AC\\u03C2 \\u03C0\\u03C1\\u03B9\\u03BD\",\n    \"menu.array.add column after\": \"\\u03A0\\u03C1\\u03BF\\u03C3\\u03B8\\u03AE\\u03BA\\u03B7 \\u03C3\\u03C4\\u03AE\\u03BB\\u03B7\\u03C2 \\u03BC\\u03B5\\u03C4\\u03AC\",\n    \"menu.array.add column before\": \"\\u03A0\\u03C1\\u03BF\\u03C3\\u03B8\\u03AE\\u03BA\\u03B7 \\u03C3\\u03C4\\u03AE\\u03BB\\u03B7\\u03C2 \\u03C0\\u03C1\\u03B9\\u03BD\",\n    \"menu.array.delete row\": \"\\u0394\\u03B9\\u03B1\\u03B3\\u03C1\\u03B1\\u03C6\\u03AE \\u03C3\\u03B5\\u03B9\\u03C1\\u03AC\\u03C2\",\n    \"menu.array.delete rows\": \"\\u0394\\u03B9\\u03B1\\u03B3\\u03C1\\u03B1\\u03C6\\u03AE \\u03B5\\u03C0\\u03B9\\u03BB\\u03B5\\u03B3\\u03BC\\u03AD\\u03BD\\u03C9\\u03BD \\u03C3\\u03B5\\u03B9\\u03C1\\u03CE\\u03BD\",\n    \"menu.array.delete column\": \"\\u0394\\u03B9\\u03B1\\u03B3\\u03C1\\u03B1\\u03C6\\u03AE \\u03C3\\u03C4\\u03AE\\u03BB\\u03B7\\u03C2\",\n    \"menu.array.delete columns\": \"\\u0394\\u03B9\\u03B1\\u03B3\\u03C1\\u03B1\\u03C6\\u03AE \\u03B5\\u03C0\\u03B9\\u03BB\\u03B5\\u03B3\\u03BC\\u03AD\\u03BD\\u03C9\\u03BD \\u03C3\\u03C4\\u03B7\\u03BB\\u03CE\\u03BD\",\n    \"menu.mode\": \"\\u039B\\u03B5\\u03B9\\u03C4\\u03BF\\u03C5\\u03C1\\u03B3\\u03AF\\u03B1\",\n    \"menu.mode-math\": \"\\u039C\\u03B1\\u03B8\\u03B7\\u03BC\\u03B1\\u03C4\\u03B9\\u03BA\\u03AC\",\n    \"menu.mode-text\": \"\\u039A\\u03B5\\u03AF\\u03BC\\u03B5\\u03BD\\u03BF\",\n    \"menu.mode-latex\": \"LaTeX\",\n    \"tooltip.blackboard\": \"\\u03A0\\u03AF\\u03BD\\u03B1\\u03BA\\u03B1\\u03C2\",\n    \"tooltip.bold\": \"\\u0388\\u03BD\\u03C4\\u03BF\\u03BD\\u03B7\",\n    \"tooltip.italic\": \"\\u03A0\\u03BB\\u03AC\\u03B3\\u03B9\\u03B1\",\n    \"tooltip.fraktur\": \"\\u03A6\\u03C1\\u03AC\\u03BA\\u03C4\\u03BF\\u03C5\\u03C1\",\n    \"tooltip.script\": \"\\u03A3\\u03B5\\u03BD\\u03AC\\u03C1\\u03B9\\u03BF\",\n    \"tooltip.caligraphic\": \"\\u039A\\u03B1\\u03BB\\u03BB\\u03B9\\u03B3\\u03C1\\u03B1\\u03C6\\u03B9\\u03BA\\u03AE\",\n    \"tooltip.typewriter\": \"\\u039C\\u03B7\\u03C7\\u03B1\\u03BD\\u03AE \\u03B3\\u03C1\\u03B1\\u03C6\\u03AE\\u03C2\",\n    \"tooltip.roman-upright\": \"\\u03A1\\u03C9\\u03BC\\u03B1\\u03CA\\u03BA\\u03CC \\u039A\\u03B1\\u03C4\\u03B1\\u03BA\\u03CC\\u03C1\\u03C5\\u03C6\\u03BF\",\n    \"tooltip.row-by-col\": \"%@ \\xD7 %@\",\n    \"menu.font-style\": \"\\u03A3\\u03C4\\u03C5\\u03BB \\u03B3\\u03C1\\u03B1\\u03BC\\u03BC\\u03B1\\u03C4\\u03BF\\u03C3\\u03B5\\u03B9\\u03C1\\u03AC\\u03C2\",\n    \"menu.accent\": \"\\u03A4\\u03CC\\u03BD\\u03BF\\u03C2\",\n    \"menu.decoration\": \"\\u0394\\u03B9\\u03B1\\u03BA\\u03CC\\u03C3\\u03BC\\u03B7\\u03C3\\u03B7\",\n    \"menu.color\": \"\\u03A7\\u03C1\\u03CE\\u03BC\\u03B1\",\n    \"menu.background-color\": \"\\u03A7\\u03C1\\u03CE\\u03BC\\u03B1 \\u03C6\\u03CC\\u03BD\\u03C4\\u03BF\\u03C5\",\n    \"menu.evaluate\": \"\\u0391\\u03BE\\u03B9\\u03BF\\u03BB\\u03CC\\u03B3\\u03B7\\u03C3\\u03B7\",\n    \"menu.simplify\": \"\\u0391\\u03C0\\u03BB\\u03BF\\u03C0\\u03BF\\u03AF\\u03B7\\u03C3\\u03B7\",\n    \"menu.solve\": \"\\u039B\\u03CD\\u03C3\\u03B7\",\n    \"menu.solve-for\": \"\\u039B\\u03CD\\u03C3\\u03B7 \\u03B3\\u03B9\\u03B1 %@\",\n    \"menu.cut\": \"\\u0391\\u03C0\\u03BF\\u03BA\\u03BF\\u03C0\\u03AE\",\n    \"menu.copy\": \"\\u0391\\u03BD\\u03C4\\u03B9\\u03B3\\u03C1\\u03B1\\u03C6\\u03AE\",\n    \"menu.copy-as-latex\": \"\\u0391\\u03BD\\u03C4\\u03B9\\u03B3\\u03C1\\u03B1\\u03C6\\u03AE \\u03C9\\u03C2 LaTeX\",\n    \"menu.copy-as-ascii-math\": \"\\u0391\\u03BD\\u03C4\\u03B9\\u03B3\\u03C1\\u03B1\\u03C6\\u03AE \\u03C9\\u03C2 ASCII Math\",\n    \"menu.copy-as-mathml\": \"\\u0391\\u03BD\\u03C4\\u03B9\\u03B3\\u03C1\\u03B1\\u03C6\\u03AE \\u03C9\\u03C2 MathML\",\n    \"menu.paste\": \"\\u0395\\u03C0\\u03B9\\u03BA\\u03CC\\u03BB\\u03BB\\u03B7\\u03C3\\u03B7\",\n    \"menu.select-all\": \"\\u0395\\u03C0\\u03B9\\u03BB\\u03BF\\u03B3\\u03AE \\u03CC\\u03BB\\u03C9\\u03BD\",\n    // Colors (accessible labels in color swatches)\n    \"color.red\": \"\\u039A\\u03CC\\u03BA\\u03BA\\u03B9\\u03BD\\u03BF\",\n    \"color.orange\": \"\\u03A0\\u03BF\\u03C1\\u03C4\\u03BF\\u03BA\\u03B1\\u03BB\\u03AF\",\n    \"color.yellow\": \"\\u039A\\u03AF\\u03C4\\u03C1\\u03B9\\u03BD\\u03BF\",\n    \"color.lime\": \"\\u039B\\u03B1\\u03C7\\u03B1\\u03BD\\u03AF\",\n    \"color.green\": \"\\u03A0\\u03C1\\u03AC\\u03C3\\u03B9\\u03BD\\u03BF\",\n    \"color.teal\": \"\\u039A\\u03C5\\u03B1\\u03BD\\u03CC\",\n    \"color.cyan\": \"\\u0393\\u03B1\\u03BB\\u03AC\\u03B6\\u03B9\\u03BF\",\n    \"color.blue\": \"\\u039C\\u03C0\\u03BB\\u03B5\",\n    \"color.indigo\": \"\\u0399\\u03BD\\u03B4\\u03B9\\u03BA\\u03CC\",\n    \"color.purple\": \"\\u039C\\u03C9\\u03B2\",\n    \"color.magenta\": \"\\u039C\\u03B1\\u03C4\\u03B6\\u03AD\\u03BD\\u03C4\\u03B1\",\n    \"color.black\": \"\\u039C\\u03B1\\u03CD\\u03C1\\u03BF\",\n    \"color.dark-grey\": \"\\u03A3\\u03BA\\u03BF\\u03CD\\u03C1\\u03BF \\u0393\\u03BA\\u03C1\\u03B9\",\n    \"color.grey\": \"\\u0393\\u03BA\\u03C1\\u03B9\",\n    \"color.light-grey\": \"\\u0391\\u03BD\\u03BF\\u03B9\\u03C7\\u03C4\\u03CC \\u0393\\u03BA\\u03C1\\u03B9\",\n    \"color.white\": \"\\u039B\\u03B5\\u03C5\\u03BA\\u03CC\"\n  },\n  // Spanish\n  \"es\": {\n    \"keyboard.tooltip.symbols\": \"S\\xEDmbolos\",\n    \"keyboard.tooltip.greek\": \"Letras griegas\",\n    \"keyboard.tooltip.numeric\": \"Num\\xE9rico\",\n    \"keyboard.tooltip.alphabetic\": \"Letras romanas\",\n    \"tooltip.copy to clipboard\": \"Copiar al portapapeles\",\n    \"tooltip.redo\": \"Rehacer\",\n    \"tooltip.toggle virtual keyboard\": \"Alternar teclado virtual\",\n    \"tooltip.undo\": \"Deshacer\",\n    \"menu.insert matrix\": \"A\\xF1adir Matriz\",\n    \"menu.borders\": \"Delimitadores de Matriz\",\n    \"menu.array.add row above\": \"A\\xF1adir L\\xEDnea Antes\",\n    \"menu.array.add row below\": \"A\\xF1adir L\\xEDnea Despues\",\n    \"menu.array.add column after\": \"A\\xF1adir Columna Despues\",\n    \"menu.array.add column before\": \"A\\xF1adir Columna Antes\",\n    \"menu.array.delete row\": \"Borrar L\\xEDnea\",\n    \"menu.array.delete rows\": \"Borrar L\\xEDneas Seleccionadas\",\n    \"menu.array.delete column\": \"Borrar Columna\",\n    \"menu.array.delete columns\": \"Borrar Columnas Seleccionadas\",\n    \"menu.mode\": \"Modo\",\n    \"menu.mode-math\": \"Matem\\xE1ticas\",\n    \"menu.mode-text\": \"Texto\",\n    \"menu.mode-latex\": \"LaTeX\",\n    \"tooltip.blackboard\": \"Pizarra\",\n    \"tooltip.bold\": \"Negrita\",\n    \"tooltip.italic\": \"Cursiva\",\n    \"tooltip.fraktur\": \"Fraktur\",\n    \"tooltip.script\": \"Script\",\n    \"tooltip.caligraphic\": \"Caligr\\xE1fico\",\n    \"tooltip.typewriter\": \"M\\xE1quina de escribir\",\n    \"tooltip.roman-upright\": \"Romano Vertical\",\n    \"tooltip.row-by-col\": \"%@ \\xD7 %@\",\n    \"menu.font-style\": \"Estilo de fuente\",\n    \"menu.accent\": \"Acento\",\n    \"menu.decoration\": \"Decoraci\\xF3n\",\n    \"menu.color\": \"Color\",\n    \"menu.background-color\": \"Fondo\",\n    \"menu.evaluate\": \"Evaluar\",\n    \"menu.simplify\": \"Simplificar\",\n    \"menu.solve\": \"Resolver\",\n    \"menu.solve-for\": \"Resolver para %@\",\n    \"menu.cut\": \"Cortar\",\n    \"menu.copy\": \"Copiar\",\n    \"menu.copy-as-latex\": \"Copiar como LaTeX\",\n    \"menu.copy-as-ascii-math\": \"Copiar como ASCII Math\",\n    \"menu.copy-as-mathml\": \"Copiar como MathML\",\n    \"menu.paste\": \"Pegar\",\n    \"menu.select-all\": \"Seleccionar todo\",\n    // Colors (accessible labels in color swatches)\n    \"color.red\": \"Rojo\",\n    \"color.orange\": \"Naranja\",\n    \"color.yellow\": \"Amarillo\",\n    \"color.lime\": \"Lima\",\n    \"color.green\": \"Verde\",\n    \"color.teal\": \"Verde azulado\",\n    \"color.cyan\": \"Cian\",\n    \"color.blue\": \"Azul\",\n    \"color.indigo\": \"\\xCDndigo\",\n    \"color.purple\": \"Morado\",\n    \"color.magenta\": \"Magenta\",\n    \"color.black\": \"Negro\",\n    \"color.dark-grey\": \"Gris oscuro\",\n    \"color.grey\": \"Gris\",\n    \"color.light-grey\": \"Gris claro\",\n    \"color.white\": \"Blanco\"\n  },\n  // French\n  \"fr\": {\n    \"keyboard.tooltip.symbols\": \"Symboles\",\n    \"keyboard.tooltip.greek\": \"Lettres grecques\",\n    \"keyboard.tooltip.numeric\": \"Num\\xE9rique\",\n    \"keyboard.tooltip.alphabetic\": \"Lettres romaines\",\n    \"tooltip.menu\": \"Menu\",\n    \"tooltip.copy to clipboard\": \"Copier dans le presse-papiers\",\n    \"tooltip.redo\": \"R\\xE9tablir\",\n    \"tooltip.toggle virtual keyboard\": \"Afficher/Masquer le clavier virtuel\",\n    \"tooltip.undo\": \"Annuler\",\n    \"menu.insert matrix\": \"Ins\\xE9rer une Matrice\",\n    \"menu.borders\": \"Bords\",\n    \"menu.array.add row above\": \"Ajouter une Ligne Avant\",\n    \"menu.array.add row below\": \"Ajouter une Ligne Apr\\xE8s\",\n    \"menu.array.add column before\": \"Ajouter une Colonne Avant\",\n    \"menu.array.add column after\": \"Ajouter une Colonne Apr\\xE8s\",\n    \"menu.array.delete row\": \"Enlever une Ligne\",\n    \"menu.array.delete rows\": \"Enlever les Lignes S\\xE9lection\\xE9es\",\n    \"menu.array.delete column\": \"Enlever une Colone\",\n    \"menu.array.delete columns\": \"Enlever les Colonnes S\\xE9lection\\xE9es\",\n    \"menu.mode\": \"Mode\",\n    \"menu.mode-math\": \"Math\",\n    \"menu.mode-text\": \"Text\",\n    \"menu.mode-latex\": \"LaTeX\",\n    \"tooltip.blackboard\": \"Tableau noir\",\n    \"tooltip.bold\": \"Gras\",\n    \"tooltip.italic\": \"Italique\",\n    \"tooltip.fraktur\": \"Fraktur\",\n    \"tooltip.script\": \"Script\",\n    \"tooltip.caligraphic\": \"Calligraphique\",\n    \"tooltip.typewriter\": \"Machine \\xE0 \\xE9crire\",\n    \"tooltip.roman-upright\": \"Romain droit\",\n    \"tooltip.row-by-col\": \"%@ \\xD7 %@\",\n    \"menu.font-style\": \"Style de police\",\n    \"menu.accent\": \"Accent\",\n    \"menu.decoration\": \"D\\xE9coration\",\n    \"menu.color\": \"Couleur\",\n    \"menu.background-color\": \"Arri\\xE8re-plan\",\n    \"menu.evaluate\": \"\\xC9valuer\",\n    \"menu.simplify\": \"Simplifier\",\n    \"menu.solve\": \"R\\xE9soudre\",\n    \"menu.solve-for\": \"R\\xE9soudre pour %@\",\n    \"menu.cut\": \"Couper\",\n    \"menu.copy\": \"Copier\",\n    \"menu.copy-as-latex\": \"Copier en LaTeX\",\n    \"menu.copy-as-ascii-math\": \"Copier en ASCII Math\",\n    \"menu.copy-as-mathml\": \"Copier en MathML\",\n    \"menu.paste\": \"Coller\",\n    \"menu.select-all\": \"S\\xE9lectionner tout\",\n    // Colors (accessible labels in color swatches)\n    \"color.red\": \"Rouge\",\n    \"color.orange\": \"Orange\",\n    \"color.yellow\": \"Jaune\",\n    \"color.lime\": \"Citron vert\",\n    \"color.green\": \"Vert\",\n    \"color.teal\": \"Turquoise\",\n    \"color.cyan\": \"Cyan\",\n    \"color.blue\": \"Bleu\",\n    \"color.indigo\": \"Indigo\",\n    \"color.purple\": \"Violet\",\n    \"color.magenta\": \"Magenta\",\n    \"color.black\": \"Noir\",\n    \"color.dark-grey\": \"Gris fonc\\xE9\",\n    \"color.grey\": \"Gris\",\n    \"color.light-grey\": \"Gris clair\",\n    \"color.white\": \"Blanc\"\n  },\n  // Hebrew (Israel)\n  \"he\": {\n    \"keyboard.tooltip.symbols\": \"\\u05E1\\u05DE\\u05DC\\u05D9\\u05DD\",\n    \"keyboard.tooltip.greek\": \"\\u05D0\\u05D5\\u05EA\\u05D9\\u05D5\\u05EA \\u05D9\\u05D5\\u05D5\\u05E0\\u05D9\\u05D5\\u05EA\",\n    \"keyboard.tooltip.numeric\": \"\\u05DE\\u05E1\\u05E4\\u05E8\\u05D9\",\n    \"keyboard.tooltip.alphabetic\": \"\\u05DE\\u05DB\\u05EA\\u05D1\\u05D9\\u05DD \\u05E8\\u05D5\\u05DE\\u05D9\\u05D9\\u05DD\",\n    \"tooltip.copy to clipboard\": \"\\u05D4\\u05E2\\u05EA\\u05E7 \\u05DC\\u05DC\\u05D5\\u05D7\",\n    \"tooltip.redo\": \"\\u05DC\\u05B7\\u05E2\\u05B2\\u05E9\\u05C2\\u05D5\\u05B9\\u05EA \\u05E9\\u05C1\\u05D5\\u05BC\\u05D1\",\n    \"tooltip.toggle virtual keyboard\": \"\\u05D4\\u05D7\\u05DC\\u05E3 \\u05D0\\u05EA \\u05D4\\u05DE\\u05E7\\u05DC\\u05D3\\u05EA \\u05D4\\u05D5\\u05D5\\u05D9\\u05E8\\u05D8\\u05D5\\u05D0\\u05DC\\u05D9\\u05EA\",\n    \"tooltip.undo\": \"\\u05DC\\u05D1\\u05D8\\u05DC\",\n    \"menu.insert matrix\": \"\\u05D4\\u05DB\\u05E0\\u05E1 \\u05DE\\u05D8\\u05E8\\u05D9\\u05E7\\u05E1\",\n    \"menu.borders\": \"\\u05DE\\u05E4\\u05E8\\u05D9\\u05D3\\u05D9 \\u05DE\\u05D8\\u05E8\\u05D9\\u05E7\\u05E1\",\n    \"menu.array.add row above\": \"\\u05D4\\u05D5\\u05E1\\u05E3 \\u05E9\\u05D5\\u05E8\\u05D4 \\u05D0\\u05D7\\u05E8\\u05D9\",\n    \"menu.array.add row below\": \"\\u05D4\\u05D5\\u05E1\\u05E3 \\u05E9\\u05D5\\u05E8\\u05D4 \\u05DC\\u05E4\\u05E0\\u05D9\",\n    \"menu.array.add column after\": \"\\u05D4\\u05D5\\u05E1\\u05E3 \\u05E2\\u05DE\\u05D5\\u05D3\\u05D4 \\u05D0\\u05D7\\u05E8\\u05D9\",\n    \"menu.array.add column before\": \"\\u05D4\\u05D5\\u05E1\\u05E3 \\u05E2\\u05DE\\u05D5\\u05D3\\u05D4 \\u05DC\\u05E4\\u05E0\\u05D9\",\n    \"menu.array.delete row\": \"\\u05DE\\u05D7\\u05E7 \\u05E9\\u05D5\\u05E8\\u05D4\",\n    \"menu.array.delete rows\": \"\\u05DE\\u05D7\\u05E7 \\u05E9\\u05D5\\u05E8\\u05D5\\u05EA \\u05E9\\u05E0\\u05D1\\u05D7\\u05E8\\u05D5\",\n    \"menu.array.delete column\": \"\\u05DE\\u05D7\\u05E7 \\u05E2\\u05DE\\u05D5\\u05D3\\u05D4\",\n    \"menu.array.delete columns\": \"\\u05DE\\u05D7\\u05E7 \\u05E2\\u05DE\\u05D5\\u05D3\\u05D5\\u05EA \\u05E9\\u05E0\\u05D1\\u05D7\\u05E8\\u05D5\",\n    \"menu.mode\": \"\\u05DE\\u05E6\\u05D1\",\n    \"menu.mode-math\": \"\\u05DE\\u05EA\\u05DE\\u05D8\\u05D9\\u05E7\\u05D4\",\n    \"menu.mode-text\": \"\\u05D8\\u05E7\\u05E1\\u05D8\",\n    \"menu.mode-latex\": \"LaTeX\",\n    \"tooltip.blackboard\": \"\\u05DC\\u05D5\\u05D7 \\u05E9\\u05D7\\u05D5\\u05E8\",\n    \"tooltip.bold\": \"\\u05DE\\u05D5\\u05D3\\u05D2\\u05E9\",\n    \"tooltip.italic\": \"\\u05E0\\u05D8\\u05D5\\u05D9\",\n    \"tooltip.fraktur\": \"\\u05E4\\u05E8\\u05E7\\u05D8\\u05D5\\u05E8\",\n    \"tooltip.script\": \"\\u05DB\\u05EA\\u05D1\",\n    \"tooltip.caligraphic\": \"\\u05E7\\u05DC\\u05D9\\u05D2\\u05E8\\u05E4\\u05D9\",\n    \"tooltip.typewriter\": \"\\u05DE\\u05DB\\u05D5\\u05E0\\u05EA \\u05DB\\u05EA\\u05D9\\u05D1\\u05D4\",\n    \"tooltip.roman-upright\": \"\\u05E8\\u05D5\\u05DE\\u05D9 \\u05D9\\u05E9\\u05E8\",\n    \"tooltip.row-by-col\": \"%@ \\xD7 %@\",\n    \"menu.font-style\": \"\\u05E1\\u05D2\\u05E0\\u05D5\\u05DF \\u05D2\\u05D5\\u05E4\\u05DF\",\n    \"menu.accent\": \"\\u05E6\\u05DC\\u05D9\\u05DC\",\n    \"menu.decoration\": \"\\u05E7\\u05D9\\u05E9\\u05D5\\u05D8\",\n    \"menu.color\": \"\\u05E6\\u05D1\\u05E2\",\n    \"menu.background-color\": \"\\u05E8\\u05E7\\u05E2\",\n    \"menu.evaluate\": \"\\u05D7\\u05E9\\u05D1\",\n    \"menu.simplify\": \"\\u05E4\\u05E9\\u05D8\",\n    \"menu.solve\": \"\\u05E4\\u05EA\\u05D5\\u05E8\",\n    \"menu.solve-for\": \"\\u05E4\\u05EA\\u05D5\\u05E8 \\u05E2\\u05D1\\u05D5\\u05E8 %@\",\n    \"menu.cut\": \"\\u05D2\\u05D6\\u05D5\\u05E8\",\n    \"menu.copy\": \"\\u05D4\\u05E2\\u05EA\\u05E7\",\n    \"menu.copy-as-latex\": \"\\u05D4\\u05E2\\u05EA\\u05E7 \\u05DB\\u05BELaTeX\",\n    \"menu.copy-as-ascii-math\": \"\\u05D4\\u05E2\\u05EA\\u05E7 \\u05DB\\u05BEASCII Math\",\n    \"menu.copy-as-mathml\": \"\\u05D4\\u05E2\\u05EA\\u05E7 \\u05DB\\u05BEMathML\",\n    \"menu.paste\": \"\\u05D4\\u05D3\\u05D1\\u05E7\",\n    \"menu.select-all\": \"\\u05D1\\u05D7\\u05E8 \\u05D4\\u05DB\\u05DC\",\n    // Colors (accessible labels in color swatches)\n    \"color.red\": \"\\u05D0\\u05D3\\u05D5\\u05DD\",\n    \"color.orange\": \"\\u05DB\\u05EA\\u05D5\\u05DD\",\n    \"color.yellow\": \"\\u05E6\\u05D4\\u05D5\\u05D1\",\n    \"color.lime\": \"\\u05D9\\u05E8\\u05D5\\u05E7 \\u05DC\\u05D9\\u05D9\\u05DD\",\n    \"color.green\": \"\\u05D9\\u05E8\\u05D5\\u05E7\",\n    \"color.teal\": \"\\u05D8\\u05D9\\u05DC\",\n    \"color.cyan\": \"\\u05E6\\u05D9\\u05D0\\u05DF\",\n    \"color.blue\": \"\\u05DB\\u05D7\\u05D5\\u05DC\",\n    \"color.indigo\": \"\\u05D0\\u05D9\\u05E0\\u05D3\\u05D9\\u05D2\\u05D5\",\n    \"color.purple\": \"\\u05E1\\u05D2\\u05D5\\u05DC\",\n    \"color.magenta\": \"\\u05DE\\u05D2\\u05E0\\u05D8\\u05D4\",\n    \"color.black\": \"\\u05E9\\u05D7\\u05D5\\u05E8\",\n    \"color.dark-grey\": \"\\u05D0\\u05E4\\u05D5\\u05E8 \\u05DB\\u05D4\\u05D4\",\n    \"color.grey\": \"\\u05D0\\u05E4\\u05D5\\u05E8\",\n    \"color.light-grey\": \"\\u05D0\\u05E4\\u05D5\\u05E8 \\u05D1\\u05D4\\u05D9\\u05E8\",\n    \"color.white\": \"\\u05DC\\u05D1\\u05DF\"\n  },\n  // Italian\n  \"it\": {\n    \"keyboard.tooltip.symbols\": \"Simboli\",\n    \"keyboard.tooltip.greek\": \"Lettere greche\",\n    \"keyboard.tooltip.numeric\": \"Numerico\",\n    \"keyboard.tooltip.alphabetic\": \"Lettere romane\",\n    \"tooltip.copy to clipboard\": \"Copia negli appunti\",\n    \"tooltip.redo\": \"Rifare\",\n    \"tooltip.toggle virtual keyboard\": \"Attiva / disattiva la tastiera virtuale\",\n    \"tooltip.undo\": \"Disfare\",\n    \"menu.insert matrix\": \"Inserisci una Matrice\",\n    \"menu.borders\": \"Delimitatori di Matrice\",\n    \"menu.array.add row above\": \"Aggiungi una Riga Prima\",\n    \"menu.array.add row below\": \"Aggiungi una Riga Dopo\",\n    \"menu.array.add column before\": \"Aggiungi una Colonna Prima\",\n    \"menu.array.add column after\": \"Aggiungi una Colonna Dopo\",\n    \"menu.array.delete row\": \"Rimuovi una Riga\",\n    \"menu.array.delete rows\": \"Rimuovi le Righe Selezionate\",\n    \"menu.array.delete column\": \"Rimuovi una Colonna\",\n    \"menu.array.delete columns\": \"Rimuovi le Colonne Selezionate\",\n    \"menu.mode\": \"Modalit\\xE0\",\n    \"menu.mode-math\": \"Matematica\",\n    \"menu.mode-text\": \"Testo\",\n    \"menu.mode-latex\": \"LaTeX\",\n    \"tooltip.blackboard\": \"Lavagna\",\n    \"tooltip.bold\": \"Grassetto\",\n    \"tooltip.italic\": \"Corsivo\",\n    \"tooltip.fraktur\": \"Fraktur\",\n    \"tooltip.script\": \"Script\",\n    \"tooltip.caligraphic\": \"Caligrafico\",\n    \"tooltip.typewriter\": \"Macchina da scrivere\",\n    \"tooltip.roman-upright\": \"Romano dritto\",\n    \"tooltip.row-by-col\": \"%@ \\xD7 %@\",\n    \"menu.font-style\": \"Stile del carattere\",\n    \"menu.accent\": \"Accento\",\n    \"menu.decoration\": \"Decorazione\",\n    \"menu.color\": \"Colore\",\n    \"menu.background-color\": \"Sfondo\",\n    \"menu.evaluate\": \"Valuta\",\n    \"menu.simplify\": \"Semplifica\",\n    \"menu.solve\": \"Risolvi\",\n    \"menu.solve-for\": \"Risolvi per %@\",\n    \"menu.cut\": \"Taglia\",\n    \"menu.copy\": \"Copia\",\n    \"menu.copy-as-latex\": \"Copia come LaTeX\",\n    \"menu.copy-as-ascii-math\": \"Copia come ASCII Math\",\n    \"menu.copy-as-mathml\": \"Copia come MathML\",\n    \"menu.paste\": \"Incolla\",\n    \"menu.select-all\": \"Seleziona tutto\",\n    // Colors (accessible labels in color swatches)\n    \"color.red\": \"Rosso\",\n    \"color.orange\": \"Arancione\",\n    \"color.yellow\": \"Giallo\",\n    \"color.lime\": \"Lime\",\n    \"color.green\": \"Verde\",\n    \"color.teal\": \"Verde acqua\",\n    \"color.cyan\": \"Ciano\",\n    \"color.blue\": \"Blu\",\n    \"color.indigo\": \"Indaco\",\n    \"color.purple\": \"Viola\",\n    \"color.magenta\": \"Magenta\",\n    \"color.black\": \"Nero\",\n    \"color.dark-grey\": \"Grigio scuro\",\n    \"color.grey\": \"Grigio\",\n    \"color.light-grey\": \"Grigio chiaro\",\n    \"color.white\": \"Bianco\"\n  },\n  // Japanese\n  \"ja\": {\n    \"keyboard.tooltip.symbols\": \"\\u30B7\\u30F3\\u30DC\\u30EB\",\n    \"keyboard.tooltip.greek\": \"\\u30AE\\u30EA\\u30B7\\u30E3\\u6587\\u5B57\",\n    \"keyboard.tooltip.numeric\": \"\\u6570\\u5024\",\n    \"keyboard.tooltip.alphabetic\": \"\\u30ED\\u30FC\\u30DE\\u5B57\",\n    \"tooltip.menu\": \"\\u30E1\\u30CB\\u30E5\\u30FC\",\n    \"tooltip.copy to clipboard\": \"\\u30AF\\u30EA\\u30C3\\u30D7\\u30DC\\u30FC\\u30C9\\u306B\\u30B3\\u30D4\\u30FC\",\n    \"tooltip.redo\": \"\\u3084\\u308A\\u76F4\\u3057\",\n    \"tooltip.toggle virtual keyboard\": \"\\u4EEE\\u60F3\\u30AD\\u30FC\\u30DC\\u30FC\\u30C9\\u306E\\u5207\\u308A\\u66FF\\u3048\",\n    \"tooltip.undo\": \"\\u5143\\u306B\\u623B\\u3059\",\n    \"menu.insert matrix\": \"\\u30DE\\u30C8\\u30EA\\u30C3\\u30AF\\u30B9\\u3092\\u633F\\u5165\",\n    \"menu.borders\": \"\\u884C\\u5217\\u533A\\u5207\\u308A\\u6587\\u5B57\",\n    \"menu.array.add row above\": \"\\u5F8C\\u306B\\u884C\\u3092\\u8FFD\\u52A0\",\n    \"menu.array.add row below\": \"\\u524D\\u306B\\u884C\\u3092\\u8FFD\\u52A0\",\n    \"menu.array.add column after\": \"\\u5F8C\\u306B\\u5217\\u3092\\u8FFD\\u52A0\",\n    \"menu.array.add column before\": \"\\u524D\\u306B\\u5217\\u3092\\u8FFD\\u52A0\",\n    \"menu.array.delete row\": \"\\u884C\\u3092\\u524A\\u9664\",\n    \"menu.array.delete rows\": \"\\u9078\\u629E\\u3057\\u305F\\u884C\\u3092\\u524A\\u9664\\u3059\\u308B\",\n    \"menu.array.delete column\": \"\\u5217\\u3092\\u524A\\u9664\",\n    \"menu.array.delete columns\": \"\\u9078\\u629E\\u3057\\u305F\\u5217\\u3092\\u524A\\u9664\\u3059\\u308B\",\n    \"menu.mode\": \"\\u30E2\\u30FC\\u30C9\",\n    \"menu.mode-math\": \"\\u6570\\u5F0F\",\n    \"menu.mode-text\": \"\\u30C6\\u30AD\\u30B9\\u30C8\",\n    \"menu.mode-latex\": \"LaTeX\",\n    \"tooltip.blackboard\": \"\\u9ED2\\u677F\",\n    \"tooltip.bold\": \"\\u592A\\u5B57\",\n    \"tooltip.italic\": \"\\u30A4\\u30BF\\u30EA\\u30C3\\u30AF\",\n    \"tooltip.fraktur\": \"\\u30D5\\u30E9\\u30AF\\u30C8\\u30A5\\u30FC\\u30EB\",\n    \"tooltip.script\": \"\\u30B9\\u30AF\\u30EA\\u30D7\\u30C8\",\n    \"tooltip.caligraphic\": \"\\u30AB\\u30EA\\u30B0\\u30E9\\u30D5\\u30A3\\u30C3\\u30AF\",\n    \"tooltip.typewriter\": \"\\u30BF\\u30A4\\u30D7\\u30E9\\u30A4\\u30BF\\u30FC\",\n    \"tooltip.roman-upright\": \"\\u30ED\\u30FC\\u30DE\\u76F4\\u7ACB\",\n    \"tooltip.row-by-col\": \"%@ \\xD7 %@\",\n    \"menu.font-style\": \"\\u30D5\\u30A9\\u30F3\\u30C8\\u30B9\\u30BF\\u30A4\\u30EB\",\n    \"menu.accent\": \"\\u30A2\\u30AF\\u30BB\\u30F3\\u30C8\",\n    \"menu.decoration\": \"\\u88C5\\u98FE\",\n    \"menu.color\": \"\\u8272\",\n    \"menu.background-color\": \"\\u80CC\\u666F\",\n    \"menu.evaluate\": \"\\u8A55\\u4FA1\",\n    \"menu.simplify\": \"\\u7C21\\u7565\\u5316\",\n    \"menu.solve\": \"\\u89E3\\u304F\",\n    \"menu.solve-for\": \"%@ \\u3092\\u89E3\\u304F\",\n    \"menu.cut\": \"\\u5207\\u308A\\u53D6\\u308A\",\n    \"menu.copy\": \"\\u30B3\\u30D4\\u30FC\",\n    \"menu.copy-as-latex\": \"LaTeX\\u3068\\u3057\\u3066\\u30B3\\u30D4\\u30FC\",\n    \"menu.copy-as-ascii-math\": \"ASCII Math\\u3068\\u3057\\u3066\\u30B3\\u30D4\\u30FC\",\n    \"menu.copy-as-mathml\": \"MathML\\u3068\\u3057\\u3066\\u30B3\\u30D4\\u30FC\",\n    \"menu.paste\": \"\\u8CBC\\u308A\\u4ED8\\u3051\",\n    \"menu.select-all\": \"\\u3059\\u3079\\u3066\\u9078\\u629E\",\n    // Colors (accessible labels in color swatches)\n    \"color.red\": \"\\u8D64\",\n    \"color.orange\": \"\\u30AA\\u30EC\\u30F3\\u30B8\",\n    \"color.yellow\": \"\\u9EC4\\u8272\",\n    \"color.lime\": \"\\u30E9\\u30A4\\u30E0\",\n    \"color.green\": \"\\u7DD1\",\n    \"color.teal\": \"\\u30C6\\u30A3\\u30FC\\u30EB\",\n    \"color.cyan\": \"\\u30B7\\u30A2\\u30F3\",\n    \"color.blue\": \"\\u9752\",\n    \"color.indigo\": \"\\u30A4\\u30F3\\u30C7\\u30A3\\u30B4\",\n    \"color.purple\": \"\\u7D2B\",\n    \"color.magenta\": \"\\u30DE\\u30BC\\u30F3\\u30BF\",\n    \"color.black\": \"\\u9ED2\",\n    \"color.dark-grey\": \"\\u6FC3\\u3044\\u30B0\\u30EC\\u30FC\",\n    \"color.grey\": \"\\u30B0\\u30EC\\u30FC\",\n    \"color.light-grey\": \"\\u8584\\u3044\\u30B0\\u30EC\\u30FC\",\n    \"color.white\": \"\\u767D\"\n  },\n  // Korean\n  \"ko\": {\n    \"keyboard.tooltip.symbols\": \"\\uAE30\\uD638\",\n    \"keyboard.tooltip.greek\": \"\\uADF8\\uB9AC\\uC2A4 \\uBB38\\uC790\",\n    \"keyboard.tooltip.numeric\": \"\\uC22B\\uC790\",\n    \"keyboard.tooltip.alphabetic\": \"\\uB85C\\uB9C8 \\uBB38\\uC790\",\n    \"tooltip.copy to clipboard\": \"\\uD074\\uB9BD \\uBCF4\\uB4DC\\uC5D0 \\uBCF5\\uC0AC\",\n    \"tooltip.redo\": \"\\uB2E4\\uC2DC \\uD558\\uB2E4\",\n    \"tooltip.toggle virtual keyboard\": \"\\uAC00\\uC0C1 \\uD0A4\\uBCF4\\uB4DC \\uC804\\uD658\",\n    \"tooltip.undo\": \"\\uC2E4\\uD589 \\uCDE8\\uC18C\",\n    \"menu.insert matrix\": \"\\uB9E4\\uD2B8\\uB9AD\\uC2A4 \\uC0BD\\uC785\",\n    \"menu.borders\": \"\\uD589\\uB82C \\uAD6C\\uBD84 \\uAE30\\uD638\",\n    \"menu.array.add row above\": \"\\uB4A4\\uC5D0 \\uD589 \\uCD94\\uAC00\",\n    \"menu.array.add row below\": \"\\uC55E\\uC5D0 \\uD589 \\uCD94\\uAC00\",\n    \"menu.array.add column after\": \"\\uB4A4\\uC5D0 \\uC5F4 \\uCD94\\uAC00\",\n    \"menu.array.add column before\": \"\\uC55E\\uC5D0 \\uC5F4 \\uCD94\\uAC00\",\n    \"menu.array.delete row\": \"\\uD589 \\uC0AD\\uC81C\",\n    \"menu.array.delete rows\": \"\\uC120\\uD0DD\\uD55C \\uD589 \\uC0AD\\uC81C\",\n    \"menu.array.delete column\": \"\\uC5F4 \\uC0AD\\uC81C\",\n    \"menu.array.delete columns\": \"\\uC120\\uD0DD\\uD55C \\uC5F4 \\uC0AD\\uC81C\",\n    \"menu.mode\": \"\\u30E2\\u30FC\\u30C9\",\n    \"menu.mode-math\": \"\\u6570\\u5F0F\",\n    \"menu.mode-text\": \"\\u30C6\\u30AD\\u30B9\\u30C8\",\n    \"menu.mode-latex\": \"LaTeX\",\n    \"tooltip.blackboard\": \"\\uCE60\\uD310\",\n    \"tooltip.bold\": \"\\uAD75\\uAC8C\",\n    \"tooltip.italic\": \"\\uC774\\uD0E4\\uB9AD\",\n    \"tooltip.fraktur\": \"\\uD504\\uB799\\uD22C\\uC5B4\",\n    \"tooltip.script\": \"\\uC2A4\\uD06C\\uB9BD\\uD2B8\",\n    \"tooltip.caligraphic\": \"\\uCE98\\uB9AC\\uADF8\\uB798\\uD53D\",\n    \"tooltip.typewriter\": \"\\uD0C0\\uC790\\uAE30\",\n    \"tooltip.roman-upright\": \"\\uB85C\\uB9C8 \\uC9C1\\uB9BD\",\n    \"tooltip.row-by-col\": \"%@ \\xD7 %@\",\n    \"menu.font-style\": \"\\uAE00\\uAF34 \\uC2A4\\uD0C0\\uC77C\",\n    \"menu.accent\": \"\\uC545\\uC13C\\uD2B8\",\n    \"menu.decoration\": \"\\uC7A5\\uC2DD\",\n    \"menu.color\": \"\\uC0C9\\uC0C1\",\n    \"menu.background-color\": \"\\uBC30\\uACBD\",\n    \"menu.evaluate\": \"\\uD3C9\\uAC00\",\n    \"menu.simplify\": \"\\uAC04\\uC18C\\uD654\",\n    \"menu.solve\": \"\\uD574\\uACB0\",\n    \"menu.solve-for\": \"%@\\uC5D0 \\uB300\\uD574 \\uD574\\uACB0\",\n    \"menu.cut\": \"\\uC798\\uB77C\\uB0B4\\uAE30\",\n    \"menu.copy\": \"\\uBCF5\\uC0AC\",\n    \"menu.copy-as-latex\": \"LaTeX\\uB85C \\uBCF5\\uC0AC\",\n    \"menu.copy-as-ascii-math\": \"ASCII Math\\uB85C \\uBCF5\\uC0AC\",\n    \"menu.copy-as-mathml\": \"MathML\\uB85C \\uBCF5\\uC0AC\",\n    \"menu.paste\": \"\\uBD99\\uC5EC\\uB123\\uAE30\",\n    \"menu.select-all\": \"\\uBAA8\\uB450 \\uC120\\uD0DD\",\n    // Colors (accessible labels in color swatches)\n    \"color.red\": \"\\uBE68\\uAC15\",\n    \"color.orange\": \"\\uC8FC\\uD669\",\n    \"color.yellow\": \"\\uB178\\uB791\",\n    \"color.lime\": \"\\uB77C\\uC784\",\n    \"color.green\": \"\\uCD08\\uB85D\",\n    \"color.teal\": \"\\uCCAD\\uB85D\",\n    \"color.cyan\": \"\\uCCAD\\uC0C9\",\n    \"color.blue\": \"\\uD30C\\uB791\",\n    \"color.indigo\": \"\\uB0A8\\uC0C9\",\n    \"color.purple\": \"\\uBCF4\\uB77C\",\n    \"color.magenta\": \"\\uC790\\uD64D\",\n    \"color.black\": \"\\uAC80\\uC815\",\n    \"color.dark-grey\": \"\\uC9C4\\uD55C \\uD68C\\uC0C9\",\n    \"color.grey\": \"\\uD68C\\uC0C9\",\n    \"color.light-grey\": \"\\uC5F0\\uD55C \\uD68C\\uC0C9\",\n    \"color.white\": \"\\uD770\\uC0C9\"\n  },\n  // Polish\n  \"pl\": {\n    \"keyboard.tooltip.symbols\": \"Symbolika\",\n    \"keyboard.tooltip.greek\": \"Litery greckie\",\n    \"keyboard.tooltip.numeric\": \"Numeryczne\",\n    \"keyboard.tooltip.alphabetic\": \"Litery rzymskie\",\n    \"tooltip.copy to clipboard\": \"Kopiuj do Schowka\",\n    \"tooltip.redo\": \"Przywr\\xF3\\u0107\",\n    \"tooltip.toggle virtual keyboard\": \"Prze\\u0142\\u0105cz wirtualn\\u0105 klawiatur\\u0119\",\n    \"tooltip.undo\": \"Cofnij\",\n    \"menu.insert matrix\": \"Wstaw macierz\",\n    \"menu.borders\": \"Ograniczniki macierzy\",\n    \"menu.array.add row above\": \"Dodaj wiersz po\",\n    \"menu.array.add row below\": \"Dodaj wiersz przed\",\n    \"menu.array.add column after\": \"Dodaj kolumn\\u0119 po\",\n    \"menu.array.add column before\": \"Dodaj kolumn\\u0119 przed\",\n    \"menu.array.delete row\": \"Usu\\u0144 wiersz\",\n    \"menu.array.delete rows\": \"Usu\\u0144 wybrane wiersze\",\n    \"menu.array.delete column\": \"Usu\\u0144 kolumn\\u0119\",\n    \"menu.array.delete columns\": \"Usu\\u0144 wybrane kolumny\",\n    \"menu.mode\": \"Tryb\",\n    \"menu.mode-math\": \"Formu\\u0142a\",\n    \"menu.mode-text\": \"Tekst\",\n    \"menu.mode-latex\": \"LaTeX\",\n    \"tooltip.blackboard\": \"Tablica\",\n    \"tooltip.bold\": \"Pogrubienie\",\n    \"tooltip.italic\": \"Kursywa\",\n    \"tooltip.fraktur\": \"Fraktura\",\n    \"tooltip.script\": \"Skrypt\",\n    \"tooltip.caligraphic\": \"Kaligraficzny\",\n    \"tooltip.typewriter\": \"Maszynowy\",\n    \"tooltip.roman-upright\": \"Rzymski prosto\",\n    \"tooltip.row-by-col\": \"%@ \\xD7 %@\",\n    \"menu.font-style\": \"Styl czcionki\",\n    \"menu.accent\": \"Akcent\",\n    \"menu.decoration\": \"Dekoracja\",\n    \"menu.color\": \"Kolor\",\n    \"menu.background-color\": \"T\\u0142o\",\n    \"menu.evaluate\": \"Oblicz\",\n    \"menu.simplify\": \"Upro\\u015B\\u0107\",\n    \"menu.solve\": \"Rozwi\\u0105\\u017C\",\n    \"menu.solve-for\": \"Rozwi\\u0105\\u017C dla %@\",\n    \"menu.cut\": \"Wytnij\",\n    \"menu.copy\": \"Kopiuj\",\n    \"menu.copy-as-latex\": \"Kopiuj jako LaTeX\",\n    \"menu.copy-as-ascii-math\": \"Kopiuj jako ASCII Math\",\n    \"menu.copy-as-mathml\": \"Kopiuj jako MathML\",\n    \"menu.paste\": \"Wklej\",\n    \"menu.select-all\": \"Zaznacz wszystko\",\n    // Colors (accessible labels in color swatches)\n    \"color.red\": \"Czerwony\",\n    \"color.orange\": \"Pomara\\u0144czowy\",\n    \"color.yellow\": \"\\u017B\\xF3\\u0142ty\",\n    \"color.lime\": \"Limetkowy\",\n    \"color.green\": \"Zielony\",\n    \"color.teal\": \"Turkusowy\",\n    \"color.cyan\": \"Cyjan\",\n    \"color.blue\": \"Niebieski\",\n    \"color.indigo\": \"Indygo\",\n    \"color.purple\": \"Fioletowy\",\n    \"color.magenta\": \"Magenta\",\n    \"color.black\": \"Czarny\",\n    \"color.dark-grey\": \"Ciemnoszary\",\n    \"color.grey\": \"Szary\",\n    \"color.light-grey\": \"Jasnoszary\",\n    \"color.white\": \"Bia\\u0142y\"\n  },\n  // Portuguese\n  \"pt\": {\n    \"keyboard.tooltip.symbols\": \"S\\xEDmbolos\",\n    \"keyboard.tooltip.greek\": \"Letras gregas\",\n    \"keyboard.tooltip.numeric\": \"Num\\xE9rico\",\n    \"keyboard.tooltip.alphabetic\": \"Letras romanas\",\n    \"tooltip.copy to clipboard\": \"Copiar para \\xE1rea de transfer\\xEAncia\",\n    \"tooltip.redo\": \"Refazer\",\n    \"tooltip.toggle virtual keyboard\": \"Alternar teclado virtual\",\n    \"tooltip.undo\": \"Desfazer\",\n    \"menu.insert matrix\": \"Inserir Matriz\",\n    \"menu.borders\": \"Delimitadores de matriz\",\n    \"menu.array.add row above\": \"Adicionar linha depois\",\n    \"menu.array.add row below\": \"Adicionar linha antes\",\n    \"menu.array.add column after\": \"Adicionar coluna depois\",\n    \"menu.array.add column before\": \"Adicionar coluna antes\",\n    \"menu.array.delete row\": \"Excluir linha\",\n    \"menu.array.delete rows\": \"Excluir linhas selecionadas\",\n    \"menu.array.delete column\": \"Apagar Coluna\",\n    \"menu.array.delete columns\": \"Excluir Colunas Selecionadas\",\n    \"menu.mode\": \"Modo\",\n    \"menu.mode-math\": \"F\\xF3rmula\",\n    \"menu.mode-text\": \"Texto\",\n    \"menu.mode-latex\": \"LaTeX\",\n    \"tooltip.blackboard\": \"Quadro Negro\",\n    \"tooltip.bold\": \"Negrito\",\n    \"tooltip.italic\": \"It\\xE1lico\",\n    \"tooltip.fraktur\": \"Fraktur\",\n    \"tooltip.script\": \"Script\",\n    \"tooltip.caligraphic\": \"Caligr\\xE1fico\",\n    \"tooltip.typewriter\": \"M\\xE1quina de Escrever\",\n    \"tooltip.roman-upright\": \"Romano Vertical\",\n    \"tooltip.row-by-col\": \"%@ \\xD7 %@\",\n    \"menu.font-style\": \"Estilo da Fonte\",\n    \"menu.accent\": \"Acento\",\n    \"menu.decoration\": \"Decora\\xE7\\xE3o\",\n    \"menu.color\": \"Cor\",\n    \"menu.background-color\": \"Cor de Fundo\",\n    \"menu.evaluate\": \"Avaliar\",\n    \"menu.simplify\": \"Simplificar\",\n    \"menu.solve\": \"Resolver\",\n    \"menu.solve-for\": \"Resolver para %@\",\n    \"menu.cut\": \"Recortar\",\n    \"menu.copy\": \"Copiar\",\n    \"menu.copy-as-latex\": \"Copiar como LaTeX\",\n    \"menu.copy-as-ascii-math\": \"Copiar como ASCII Math\",\n    \"menu.copy-as-mathml\": \"Copiar como MathML\",\n    \"menu.paste\": \"Colar\",\n    \"menu.select-all\": \"Selecionar Tudo\",\n    // Colors (accessible labels in color swatches)\n    \"color.red\": \"Vermelho\",\n    \"color.orange\": \"Laranja\",\n    \"color.yellow\": \"Amarelo\",\n    \"color.lime\": \"Verde Lima\",\n    \"color.green\": \"Verde\",\n    \"color.teal\": \"Verde-azulado\",\n    \"color.cyan\": \"Ciano\",\n    \"color.blue\": \"Azul\",\n    \"color.indigo\": \"\\xCDndigo\",\n    \"color.purple\": \"Roxo\",\n    \"color.magenta\": \"Magenta\",\n    \"color.black\": \"Preto\",\n    \"color.dark-grey\": \"Cinza Escuro\",\n    \"color.grey\": \"Cinza\",\n    \"color.light-grey\": \"Cinza Claro\",\n    \"color.white\": \"Branco\"\n  },\n  //Ukrainian\n  \"uk\": {\n    \"keyboard.tooltip.symbols\": \"\\u0421\\u0438\\u043C\\u0432\\u043E\\u043B\\u0438\",\n    \"keyboard.tooltip.greek\": \"\\u0413\\u0440\\u0435\\u0446\\u044C\\u043A\\u0456 \\u043B\\u0456\\u0442\\u0435\\u0440\\u0438\",\n    \"keyboard.tooltip.numeric\": \"\\u0427\\u0438\\u0441\\u043B\\u043E\\u0432\\u0438\\u0439\",\n    \"keyboard.tooltip.alphabetic\": \"\\u0420\\u0438\\u043C\\u0441\\u044C\\u043A\\u0456 \\u043B\\u0456\\u0442\\u0435\\u0440\\u0438\",\n    \"tooltip.copy to clipboard\": \"\\u041A\\u043E\\u043F\\u0456\\u044E\\u0432\\u0430\\u0442\\u0438 \\u0432 \\u0431\\u0443\\u0444\\u0435\\u0440 \\u043E\\u0431\\u043C\\u0456\\u043D\\u0443\",\n    \"tooltip.redo\": \"\\u041F\\u043E\\u0432\\u0442\\u043E\\u0440\\u0438\\u0442\\u0438\",\n    \"tooltip.toggle virtual keyboard\": \"\\u041F\\u0435\\u0440\\u0435\\u043A\\u043B\\u044E\\u0447\\u0438\\u0442\\u0438 \\u0432\\u0456\\u0440\\u0442\\u0443\\u0430\\u043B\\u044C\\u043D\\u0443 \\u043A\\u043B\\u0430\\u0432\\u0456\\u0430\\u0442\\u0443\\u0440\\u0443\",\n    \"tooltip.undo\": \"\\u0421\\u043A\\u0430\\u0441\\u0443\\u0432\\u0430\\u0442\\u0438\",\n    \"menu.insert matrix\": \"\\u0412\\u0441\\u0442\\u0430\\u0432\\u0438\\u0442\\u0438 \\u043C\\u0430\\u0442\\u0440\\u0438\\u0446\\u044E\",\n    \"menu.borders\": \"\\u041C\\u0430\\u0442\\u0440\\u0438\\u0447\\u043D\\u0456 \\u0440\\u043E\\u0437\\u0434\\u0456\\u043B\\u044C\\u043D\\u0438\\u043A\\u0438\",\n    \"menu.array.add row above\": \"\\u0414\\u043E\\u0434\\u0430\\u0442\\u0438 \\u0440\\u044F\\u0434\\u043E\\u043A \\u043F\\u0456\\u0441\\u043B\\u044F\",\n    \"menu.array.add row below\": \"\\u0414\\u043E\\u0434\\u0430\\u0442\\u0438 \\u0440\\u044F\\u0434\\u043E\\u043A \\u0434\\u043E\",\n    \"menu.array.add column after\": \"\\u0414\\u043E\\u0434\\u0430\\u0442\\u0438 \\u0441\\u0442\\u043E\\u0432\\u043F\\u0435\\u0446\\u044C \\u043F\\u0456\\u0441\\u043B\\u044F\",\n    \"menu.array.add column before\": \"\\u0414\\u043E\\u0434\\u0430\\u0442\\u0438 \\u0441\\u0442\\u043E\\u0432\\u043F\\u0435\\u0446\\u044C \\u043F\\u0435\\u0440\\u0435\\u0434\",\n    \"menu.array.delete row\": \"\\u0412\\u0438\\u0434\\u0430\\u043B\\u0438\\u0442\\u0438 \\u0440\\u044F\\u0434\\u043E\\u043A\",\n    \"menu.array.delete rows\": \"\\u0412\\u0438\\u0434\\u0430\\u043B\\u0438\\u0442\\u0438 \\u0432\\u0438\\u0431\\u0440\\u0430\\u043D\\u0456 \\u0440\\u044F\\u0434\\u043A\\u0438\",\n    \"menu.array.delete column\": \"\\u0412\\u0438\\u0434\\u0430\\u043B\\u0438\\u0442\\u0438 \\u0441\\u0442\\u043E\\u0432\\u043F\\u0435\\u0446\\u044C\",\n    \"menu.array.delete columns\": \"\\u0412\\u0438\\u0434\\u0430\\u043B\\u0438\\u0442\\u0438 \\u0432\\u0438\\u0431\\u0440\\u0430\\u043D\\u0456 \\u0441\\u0442\\u043E\\u0432\\u043F\\u0446\\u0456\",\n    \"menu.mode\": \"\\u0420\\u0435\\u0436\\u0438\\u043C\",\n    \"menu.mode-math\": \"\\u041C\\u0430\\u0442\\u0435\\u043C\\u0430\\u0442\\u0438\\u043A\\u0430\",\n    \"menu.mode-text\": \"\\u0422\\u0435\\u043A\\u0441\\u0442\",\n    \"menu.mode-latex\": \"LaTeX\",\n    \"tooltip.blackboard\": \"\\u0427\\u043E\\u0440\\u043D\\u0430 \\u0434\\u043E\\u0448\\u043A\\u0430\",\n    \"tooltip.bold\": \"\\u0416\\u0438\\u0440\\u043D\\u0438\\u0439\",\n    \"tooltip.italic\": \"\\u041A\\u0443\\u0440\\u0441\\u0438\\u0432\",\n    \"tooltip.fraktur\": \"\\u0424\\u0440\\u0430\\u043A\\u0442\\u0443\\u0440\\u043D\\u0438\\u0439\",\n    \"tooltip.script\": \"\\u0421\\u043A\\u0440\\u0438\\u043F\\u0442\",\n    \"tooltip.caligraphic\": \"\\u041A\\u0430\\u043B\\u0456\\u0433\\u0440\\u0430\\u0444\\u0456\\u0447\\u043D\\u0438\\u0439\",\n    \"tooltip.typewriter\": \"\\u041C\\u0430\\u0448\\u0438\\u043D\\u043A\\u0430 \\u0434\\u043B\\u044F \\u043F\\u0438\\u0441\\u044C\\u043C\\u0430\",\n    \"tooltip.roman-upright\": \"\\u0420\\u0438\\u043C\\u0441\\u044C\\u043A\\u0438\\u0439 \\u043F\\u0440\\u044F\\u043C\\u0438\\u0439\",\n    \"tooltip.row-by-col\": \"%@ \\xD7 %@\",\n    \"menu.font-style\": \"\\u0421\\u0442\\u0438\\u043B\\u044C \\u0448\\u0440\\u0438\\u0444\\u0442\\u0443\",\n    \"menu.accent\": \"\\u0410\\u043A\\u0446\\u0435\\u043D\\u0442\",\n    \"menu.decoration\": \"\\u0414\\u0435\\u043A\\u043E\\u0440\\u0430\\u0446\\u0456\\u044F\",\n    \"menu.color\": \"\\u041A\\u043E\\u043B\\u0456\\u0440\",\n    \"menu.background-color\": \"\\u0424\\u043E\\u043D\",\n    \"menu.evaluate\": \"\\u041E\\u0431\\u0447\\u0438\\u0441\\u043B\\u0438\\u0442\\u0438\",\n    \"menu.simplify\": \"\\u0421\\u043F\\u0440\\u043E\\u0441\\u0442\\u0438\\u0442\\u0438\",\n    \"menu.solve\": \"\\u0412\\u0438\\u0440\\u0456\\u0448\\u0438\\u0442\\u0438\",\n    \"menu.solve-for\": \"\\u0412\\u0438\\u0440\\u0456\\u0448\\u0438\\u0442\\u0438 \\u0434\\u043B\\u044F %@\",\n    \"menu.cut\": \"\\u0412\\u0438\\u0440\\u0456\\u0437\\u0430\\u0442\\u0438\",\n    \"menu.copy\": \"\\u041A\\u043E\\u043F\\u0456\\u044E\\u0432\\u0430\\u0442\\u0438\",\n    \"menu.copy-as-latex\": \"\\u041A\\u043E\\u043F\\u0456\\u044E\\u0432\\u0430\\u0442\\u0438 \\u044F\\u043A LaTeX\",\n    \"menu.copy-as-ascii-math\": \"\\u041A\\u043E\\u043F\\u0456\\u044E\\u0432\\u0430\\u0442\\u0438 \\u044F\\u043A ASCII Math\",\n    \"menu.copy-as-mathml\": \"\\u041A\\u043E\\u043F\\u0456\\u044E\\u0432\\u0430\\u0442\\u0438 \\u044F\\u043A MathML\",\n    \"menu.paste\": \"\\u0412\\u0441\\u0442\\u0430\\u0432\\u0438\\u0442\\u0438\",\n    \"menu.select-all\": \"\\u0412\\u0438\\u0431\\u0440\\u0430\\u0442\\u0438 \\u0432\\u0441\\u0435\",\n    // Colors (accessible labels in color swatches)\n    \"color.red\": \"\\u0427\\u0435\\u0440\\u0432\\u043E\\u043D\\u0438\\u0439\",\n    \"color.orange\": \"\\u041F\\u043E\\u043C\\u0430\\u0440\\u0430\\u043D\\u0447\\u0435\\u0432\\u0438\\u0439\",\n    \"color.yellow\": \"\\u0416\\u043E\\u0432\\u0442\\u0438\\u0439\",\n    \"color.lime\": \"\\u041B\\u0430\\u0439\\u043C\",\n    \"color.green\": \"\\u0417\\u0435\\u043B\\u0435\\u043D\\u0438\\u0439\",\n    \"color.teal\": \"\\u0411\\u0456\\u0440\\u044E\\u0437\\u043E\\u0432\\u0438\\u0439\",\n    \"color.cyan\": \"\\u0421\\u0438\\u043D\\u044C\\u043E-\\u0437\\u0435\\u043B\\u0435\\u043D\\u0438\\u0439\",\n    \"color.blue\": \"\\u0421\\u0438\\u043D\\u0456\\u0439\",\n    \"color.indigo\": \"\\u0406\\u043D\\u0434\\u0438\\u0433\\u043E\",\n    \"color.purple\": \"\\u0424\\u0456\\u043E\\u043B\\u0435\\u0442\\u043E\\u0432\\u0438\\u0439\",\n    \"color.magenta\": \"\\u041F\\u0443\\u0440\\u043F\\u0443\\u0440\\u043D\\u0438\\u0439\",\n    \"color.black\": \"\\u0427\\u043E\\u0440\\u043D\\u0438\\u0439\",\n    \"color.dark-grey\": \"\\u0422\\u0435\\u043C\\u043D\\u043E-\\u0441\\u0456\\u0440\\u0438\\u0439\",\n    \"color.grey\": \"\\u0421\\u0456\\u0440\\u0438\\u0439\",\n    \"color.light-grey\": \"\\u0421\\u0432\\u0456\\u0442\\u043B\\u043E-\\u0441\\u0456\\u0440\\u0438\\u0439\",\n    \"color.white\": \"\\u0411\\u0456\\u043B\\u0438\\u0439\"\n  },\n  // Simplified Chinese\n  \"zh-cn\": {\n    \"keyboard.tooltip.symbols\": \"\\u7B26\\u53F7\",\n    \"keyboard.tooltip.greek\": \"\\u5E0C\\u814A\\u5B57\\u6BCD\",\n    \"keyboard.tooltip.numeric\": \"\\u6570\\u5B57\",\n    \"keyboard.tooltip.alphabetic\": \"\\u7F57\\u9A6C\\u5B57\\u6BCD\",\n    \"tooltip.copy to clipboard\": \"\\u590D\\u5236\\u5230\\u526A\\u8D34\\u677F\",\n    \"tooltip.redo\": \"\\u91CD\\u505A\",\n    \"tooltip.toggle virtual keyboard\": \"\\u5207\\u6362\\u865A\\u62DF\\u952E\\u76D8\",\n    \"tooltip.undo\": \"\\u64A4\\u6D88\",\n    \"menu.insert matrix\": \"\\u63D2\\u5165\\u77E9\\u9635\",\n    \"menu.borders\": \"\\u77E9\\u9635\\u5206\\u9694\\u7B26\",\n    \"menu.array.add row above\": \"\\u5728\\u540E\\u9762\\u6DFB\\u52A0\\u884C\",\n    \"menu.array.add row below\": \"\\u5728\\u524D\\u9762\\u6DFB\\u52A0\\u884C\",\n    \"menu.array.add column after\": \"\\u5728\\u540E\\u9762\\u6DFB\\u52A0\\u5217r\",\n    \"menu.array.add column before\": \"\\u5728\\u524D\\u9762\\u6DFB\\u52A0\\u5217\",\n    \"menu.array.delete row\": \"\\u5220\\u9664\\u884C\",\n    \"menu.array.delete rows\": \"\\u5220\\u9664\\u9009\\u5B9A\\u884C\",\n    \"menu.array.delete column\": \"\\u5220\\u9664\\u5217\",\n    \"menu.array.delete columns\": \"\\u5220\\u9664\\u9009\\u5B9A\\u7684\\u5217\",\n    \"menu.mode\": \"\\u6A21\\u5F0F\",\n    \"menu.mode-math\": \"\\u6570\\u5B66\",\n    \"menu.mode-text\": \"\\u6587\\u672C\",\n    \"menu.mode-latex\": \"LaTeX\",\n    \"tooltip.blackboard\": \"\\u9ED1\\u677F\",\n    \"tooltip.bold\": \"\\u7C97\\u4F53\",\n    \"tooltip.italic\": \"\\u659C\\u4F53\",\n    \"tooltip.fraktur\": \"Fraktur\",\n    \"tooltip.script\": \"\\u811A\\u672C\",\n    \"tooltip.caligraphic\": \"\\u8349\\u4E66\",\n    \"tooltip.typewriter\": \"\\u6253\\u5B57\\u673A\",\n    \"tooltip.roman-upright\": \"\\u7F57\\u9A6C\\u76F4\\u7ACB\",\n    \"tooltip.row-by-col\": \"%@ \\xD7 %@\",\n    \"menu.font-style\": \"\\u5B57\\u4F53\\u6837\\u5F0F\",\n    \"menu.accent\": \"\\u91CD\\u97F3\",\n    \"menu.decoration\": \"\\u88C5\\u9970\",\n    \"menu.color\": \"\\u989C\\u8272\",\n    \"menu.background-color\": \"\\u80CC\\u666F\",\n    \"menu.evaluate\": \"\\u8BA1\\u7B97\",\n    \"menu.simplify\": \"\\u7B80\\u5316\",\n    \"menu.solve\": \"\\u6C42\\u89E3\",\n    \"menu.solve-for\": \"\\u6C42\\u89E3 %@\",\n    \"menu.cut\": \"\\u526A\\u5207\",\n    \"menu.copy\": \"\\u590D\\u5236\",\n    \"menu.copy-as-latex\": \"\\u590D\\u5236\\u4E3A LaTeX\",\n    \"menu.copy-as-ascii-math\": \"\\u590D\\u5236\\u4E3A ASCII Math\",\n    \"menu.copy-as-mathml\": \"\\u590D\\u5236\\u4E3A MathML\",\n    \"menu.paste\": \"\\u7C98\\u8D34\",\n    \"menu.select-all\": \"\\u5168\\u9009\",\n    // Colors (accessible labels in color swatches)\n    \"color.red\": \"\\u7EA2\\u8272\",\n    \"color.orange\": \"\\u6A59\\u8272\",\n    \"color.yellow\": \"\\u9EC4\\u8272\",\n    \"color.lime\": \"\\u7EFF\\u9EC4\\u8272\",\n    \"color.green\": \"\\u7EFF\\u8272\",\n    \"color.teal\": \"\\u9752\\u8272\",\n    \"color.cyan\": \"\\u84DD\\u7EFF\\u8272\",\n    \"color.blue\": \"\\u84DD\\u8272\",\n    \"color.indigo\": \"\\u975B\\u84DD\\u8272\",\n    \"color.purple\": \"\\u7D2B\\u8272\",\n    \"color.magenta\": \"\\u6D0B\\u7EA2\\u8272\",\n    \"color.black\": \"\\u9ED1\\u8272\",\n    \"color.dark-grey\": \"\\u6DF1\\u7070\\u8272\",\n    \"color.grey\": \"\\u7070\\u8272\",\n    \"color.light-grey\": \"\\u6D45\\u7070\\u8272\",\n    \"color.white\": \"\\u767D\\u8272\"\n  },\n  // Traditional Chinese\n  \"zh-tw\": {\n    \"keyboard.tooltip.symbols\": \"\\u7B26\\u865F\",\n    \"keyboard.tooltip.greek\": \"\\u5E0C\\u81D8\\u5B57\\u6BCD\",\n    \"keyboard.tooltip.numeric\": \"\\u6578\\u5B57\",\n    \"keyboard.tooltip.alphabetic\": \"\\u7F85\\u99AC\\u5B57\\u6BCD\",\n    \"tooltip.copy to clipboard\": \"\\u8907\\u88FD\\u5230\\u526A\\u8CBC\\u677F\",\n    \"tooltip.redo\": \"\\u91CD\\u505A\",\n    \"tooltip.toggle virtual keyboard\": \"\\u5207\\u63DB\\u865B\\u64EC\\u9375\\u76E4\",\n    \"tooltip.undo\": \"\\u64A4\\u6D88\",\n    \"menu.insert matrix\": \"\\u63D2\\u5165\\u77E9\\u9663\",\n    \"menu.borders\": \"\\u77E9\\u9663\\u5206\\u9694\\u7B26\",\n    \"menu.array.add row above\": \"\\u5728\\u5F8C\\u9762\\u6DFB\\u52A0\\u884C\",\n    \"menu.array.add row below\": \"\\u5728\\u524D\\u9762\\u6DFB\\u52A0\\u884C\",\n    \"menu.array.add column after\": \"\\u5728\\u5F8C\\u9762\\u6DFB\\u52A0\\u5217\",\n    \"menu.array.add column before\": \"\\u5728\\u524D\\u9762\\u6DFB\\u52A0\\u5217\",\n    \"menu.array.delete row\": \"\\u522A\\u9664\\u884C\",\n    \"menu.array.delete rows\": \"\\u522A\\u9664\\u9078\\u5B9A\\u884C\",\n    \"menu.array.delete column\": \"\\u522A\\u9664\\u5217\",\n    \"menu.array.delete columns\": \"\\u522A\\u9664\\u9078\\u5B9A\\u7684\\u5217\",\n    \"menu.mode\": \"\\u6A21\\u5F0F\",\n    \"menu.mode-math\": \"\\u6578\\u5B78\",\n    \"menu.mode-text\": \"\\u6587\\u672C\",\n    \"menu.mode-latex\": \"LaTeX\",\n    \"tooltip.blackboard\": \"\\u9ED1\\u677F\",\n    \"tooltip.bold\": \"\\u7C97\\u9AD4\",\n    \"tooltip.italic\": \"\\u659C\\u9AD4\",\n    \"tooltip.fraktur\": \"Fraktur\",\n    \"tooltip.script\": \"\\u8173\\u672C\",\n    \"tooltip.caligraphic\": \"\\u8349\\u66F8\",\n    \"tooltip.typewriter\": \"\\u6253\\u5B57\\u6A5F\",\n    \"tooltip.roman-upright\": \"\\u7F85\\u99AC\\u76F4\\u7ACB\",\n    \"tooltip.row-by-col\": \"%@ \\xD7 %@\",\n    \"menu.font-style\": \"\\u5B57\\u9AD4\\u6A23\\u5F0F\",\n    \"menu.accent\": \"\\u91CD\\u97F3\",\n    \"menu.decoration\": \"\\u88DD\\u98FE\",\n    \"menu.color\": \"\\u984F\\u8272\",\n    \"menu.background-color\": \"\\u80CC\\u666F\",\n    \"menu.evaluate\": \"\\u8A08\\u7B97\",\n    \"menu.simplify\": \"\\u7C21\\u5316\",\n    \"menu.solve\": \"\\u6C42\\u89E3\",\n    \"menu.solve-for\": \"\\u6C42\\u89E3 %@\",\n    \"menu.cut\": \"\\u526A\\u4E0B\",\n    \"menu.copy\": \"\\u8907\\u88FD\",\n    \"menu.copy-as-latex\": \"\\u8907\\u88FD\\u70BA LaTeX\",\n    \"menu.copy-as-ascii-math\": \"\\u8907\\u88FD\\u70BA ASCII Math\",\n    \"menu.copy-as-mathml\": \"\\u8907\\u88FD\\u70BA MathML\",\n    \"menu.paste\": \"\\u8CBC\\u4E0A\",\n    \"menu.select-all\": \"\\u5168\\u9078\",\n    // Colors (accessible labels in color swatches)\n    \"color.red\": \"\\u7D05\\u8272\",\n    \"color.orange\": \"\\u6A59\\u8272\",\n    \"color.yellow\": \"\\u9EC3\\u8272\",\n    \"color.lime\": \"\\u7DA0\\u9EC3\\u8272\",\n    \"color.green\": \"\\u7DA0\\u8272\",\n    \"color.teal\": \"\\u9752\\u8272\",\n    \"color.cyan\": \"\\u85CD\\u7DA0\\u8272\",\n    \"color.blue\": \"\\u85CD\\u8272\",\n    \"color.indigo\": \"\\u975B\\u85CD\\u8272\",\n    \"color.purple\": \"\\u7D2B\\u8272\",\n    \"color.magenta\": \"\\u6D0B\\u7D05\\u8272\",\n    \"color.black\": \"\\u9ED1\\u8272\",\n    \"color.dark-grey\": \"\\u6DF1\\u7070\\u8272\",\n    \"color.grey\": \"\\u7070\\u8272\",\n    \"color.light-grey\": \"\\u6DFA\\u7070\\u8272\",\n    \"color.white\": \"\\u767D\\u8272\"\n  }\n};\n\n// src/ui/utils/capabilities.ts\nfunction isBrowser() {\n  return \"window\" in globalThis && \"document\" in globalThis;\n}\nfunction isTouchCapable() {\n  if (\"matchMedia\" in window)\n    return window.matchMedia(\"(pointer: coarse)\").matches;\n  return \"ontouchstart\" in window || navigator.maxTouchPoints > 0;\n}\nfunction isInIframe() {\n  try {\n    return window.self !== window.top;\n  } catch (e) {\n    return true;\n  }\n}\nfunction canVibrate() {\n  return typeof navigator.vibrate === \"function\";\n}\nfunction osPlatform() {\n  var _a3, _b3;\n  if (!isBrowser()) return \"other\";\n  const platform2 = (_b3 = (_a3 = navigator[\"userAgentData\"]) == null ? void 0 : _a3.platform) != null ? _b3 : navigator.platform;\n  if (/^mac/i.test(platform2)) {\n    if (navigator.maxTouchPoints === 5) return \"ios\";\n    return \"macos\";\n  }\n  if (/^win/i.test(platform2)) return \"windows\";\n  if (/android/i.test(navigator.userAgent)) return \"android\";\n  if (/iphone|ipod|ipad/i.test(navigator.userAgent)) return \"ios\";\n  if (/\\bcros\\b/i.test(navigator.userAgent)) return \"chromeos\";\n  return \"other\";\n}\nfunction supportRegexPropertyEscape() {\n  if (!isBrowser()) return true;\n  if (/firefox/i.test(navigator.userAgent)) {\n    const m = navigator.userAgent.match(/firefox\\/(\\d+)/i);\n    if (!m) return false;\n    const version2 = parseInt(m[1]);\n    return version2 >= 78;\n  }\n  if (/trident/i.test(navigator.userAgent)) return false;\n  if (/edge/i.test(navigator.userAgent)) {\n    const m = navigator.userAgent.match(/edg\\/(\\d+)/i);\n    if (!m) return false;\n    const version2 = parseInt(m[1]);\n    return version2 >= 79;\n  }\n  return true;\n}\nfunction supportPopover() {\n  return HTMLElement.prototype.hasOwnProperty(\"popover\");\n}\n\n// src/core/l10n.ts\nvar l10n = {\n  strings: STRINGS,\n  _locale: \"\",\n  //  Important! Set the locale to empty so it can be determined at runtime\n  _dirty: false,\n  _subscribers: [],\n  _numberFormatter: void 0,\n  get locale() {\n    if (!l10n._locale)\n      l10n._locale = isBrowser() ? navigator.language.slice(0, 5) : \"en-US\";\n    return l10n._locale;\n  },\n  set locale(value) {\n    l10n._locale = value;\n    l10n._numberFormatter = void 0;\n    l10n.dirty = true;\n  },\n  get numberFormatter() {\n    if (!l10n._numberFormatter) {\n      try {\n        l10n._numberFormatter = new Intl.NumberFormat(l10n.locale);\n      } catch (e) {\n        try {\n          l10n._numberFormatter = new Intl.NumberFormat(\n            l10n.locale.slice(0, 2)\n          );\n        } catch (e2) {\n          l10n._numberFormatter = new Intl.NumberFormat(\"en-US\");\n        }\n      }\n    }\n    return l10n._numberFormatter;\n  },\n  /*\n   * Two forms for this function:\n   * - merge(locale, strings)\n   * Merge a dictionary of keys -> values for the specified locale\n   * - merge(strings)\n   * Merge a dictionary of locale code -> dictionary of keys -> values\n   *\n   */\n  merge(locale, strings) {\n    if (typeof locale === \"string\" && strings) {\n      l10n.strings[locale] = __spreadValues(__spreadValues({}, l10n.strings[locale]), strings);\n      l10n.dirty = true;\n    } else {\n      for (const l of Object.keys(\n        locale\n      ))\n        l10n.merge(l, locale[l]);\n    }\n  },\n  get dirty() {\n    return l10n._dirty;\n  },\n  set dirty(val) {\n    if (l10n._dirty || l10n._dirty === val) return;\n    l10n._dirty = true;\n    setTimeout(() => {\n      l10n._dirty = false;\n      this._subscribers.forEach((x) => x == null ? void 0 : x());\n    }, 0);\n  },\n  subscribe(callback) {\n    l10n._subscribers.push(callback);\n    return l10n._subscribers.length - 1;\n  },\n  unsubscribe(id) {\n    if (id < 0 || id >= l10n._subscribers.length) return;\n    l10n._subscribers[id] = void 0;\n  },\n  /**\n   * Update the l10n strings in the DOM\n   */\n  update(root) {\n    let elements = root.querySelectorAll(\"[data-l10n-tooltip]\");\n    for (const element of elements) {\n      const key = element.getAttribute(\"data-l10n-tooltip\");\n      if (key) {\n        const localized = localize(key);\n        if (localized) element.setAttribute(\"data-tooltip\", localized);\n      }\n    }\n    elements = root.querySelectorAll(\"[data-l10n-arial-label]\");\n    for (const element of elements) {\n      const key = element.getAttribute(\"data-l10n-arial-label\");\n      if (key) {\n        const localized = localize(key);\n        if (localized) element.setAttribute(\"aria-label\", localized);\n      }\n    }\n  }\n};\nfunction localize(key, ...params) {\n  if (key === void 0) return void 0;\n  let result = \"\";\n  const locale = l10n.locale;\n  if (l10n.strings[locale]) result = l10n.strings[locale][key];\n  const language = locale.slice(0, 2);\n  if (!result && l10n.strings[language]) result = l10n.strings[language][key];\n  if (!result) result = l10n.strings.en[key];\n  if (!result) return void 0;\n  const regex = /(%@|%([0-9]+)\\$@)/g;\n  let match = regex.exec(result);\n  let index = 0;\n  while (match) {\n    const parameter = params[index++];\n    if (parameter) {\n      const parameterIndex = match[2] ? parseInt(match[2], 10) - 1 : index - 1;\n      let repl = params[parameterIndex];\n      if (typeof repl === \"number\") repl = l10n.numberFormatter.format(repl);\n      result = result.replace(match[1], repl);\n    }\n    match = regex.exec(result);\n  }\n  result = result.replace(/%%/g, \"%\");\n  return result;\n}\n\n// src/core/color.ts\nvar MATHEMATICA_COLORS = {\n  m0: \"#3F3D99\",\n  // Strong blue\n  m1: \"#993D71\",\n  // Strong cerise\n  m2: \"#998B3D\",\n  // Strong gold\n  m3: \"#3D9956\",\n  // Malachite green\n  m4: \"#3D5A99\",\n  // Strong cobalt blue\n  m5: \"#993D90\",\n  // Strong orchid\n  m6: \"#996D3D\",\n  // Strong orange\n  m7: \"#43993D\",\n  // Strong sap green\n  m8: \"#3D7999\",\n  // Cornflower blue\n  m9: \"#843D99\"\n  // Mulberry\n};\nvar MATLAB_COLORS = {\n  blue: \"#0072BD\",\n  // [0, 0.4470, 0.7410]             blue\n  orange: \"#D95319\",\n  // [0.8500, 0.3250, 0.0980]        orange\n  yellow: \"#EDB120\",\n  // [0.9290, 0.6940, 0.1250]       yellow\n  purple: \"#7E2F8E\",\n  // [0.4940, 0.1840, 0.5560]       purple\n  green: \"#77AC30\",\n  // [0.4660, 0.6740, 0.1880]       green\n  cyan: \"#4DBEEE\",\n  // [0.3010, 0.7450, 0.9330]       cyan\n  red: \"#A2142F\"\n  // [0.6350, 0.0780, 0.1840]\t    dark red\n};\nvar BACKGROUND_COLORS = {\n  \"red\": \"#fbbbb6\",\n  \"orange\": \"#ffe0c2\",\n  \"yellow\": \"#fff1c2\",\n  \"lime\": \"#d0e8b9\",\n  \"green\": \"#bceac4\",\n  \"teal\": \"#b9f1f1\",\n  \"cyan\": \"#b8e5c9\",\n  \"blue\": \"#b6d9fb\",\n  \"indigo\": \"#d1c2f0\",\n  \"purple\": \"#e3baf8\",\n  \"magenta\": \"#f9c8e0\",\n  \"black\": \"#353535\",\n  \"dark-grey\": \"#8C8C8C\",\n  \"grey\": \"#D0D0D0\",\n  \"light-grey\": \"#F0F0F0\",\n  \"white\": \"#ffffff\"\n};\nvar FOREGROUND_COLORS = {\n  \"red\": \"#d7170b\",\n  //<- 700, 500 ->'#f21c0d'\n  \"orange\": \"#fe8a2b\",\n  \"yellow\": \"#ffc02b\",\n  // <- 600, 500 -> '#ffcf33',\n  \"lime\": \"#63b215\",\n  \"green\": \"#21ba3a\",\n  \"teal\": \"#17cfcf\",\n  \"cyan\": \"#13a7ec\",\n  \"blue\": \"#0d80f2\",\n  \"indigo\": \"#63c\",\n  \"purple\": \"#a219e6\",\n  \"magenta\": \"#eb4799\",\n  \"black\": \"#000\",\n  \"dark-grey\": \"#666\",\n  \"grey\": \"#A6A6A6\",\n  \"light-grey\": \"#d4d5d2\",\n  \"white\": \"#ffffff\"\n};\nvar DVIPS_TO_CHROMATIC = {\n  Red: \"red\",\n  Orange: \"orange\",\n  Yellow: \"yellow\",\n  LimeGreen: \"lime\",\n  Green: \"green\",\n  TealBlue: \"teal\",\n  Blue: \"blue\",\n  Violet: \"indigo\",\n  Purple: \"purple\",\n  Magenta: \"magenta\",\n  Black: \"black\",\n  Gray: \"grey\",\n  White: \"white\"\n};\nvar DVIPS_COLORS = {\n  Apricot: \"#FBB982\",\n  Aquamarine: \"#00B5BE\",\n  Bittersweet: \"#C04F17\",\n  Black: \"#221E1F\",\n  // Indeed.\n  Blue: \"#2D2F92\",\n  BlueGreen: \"#00B3B8\",\n  BlueViolet: \"#473992\",\n  BrickRed: \"#B6321C\",\n  Brown: \"#792500\",\n  BurntOrange: \"#F7921D\",\n  CadetBlue: \"#74729A\",\n  CarnationPink: \"#F282B4\",\n  Cerulean: \"#00A2E3\",\n  CornflowerBlue: \"#41B0E4\",\n  Cyan: \"#00AEEF\",\n  Dandelion: \"#FDBC42\",\n  DarkOrchid: \"#A4538A\",\n  Emerald: \"#00A99D\",\n  ForestGreen: \"#009B55\",\n  Fuchsia: \"#8C368C\",\n  Goldenrod: \"#FFDF42\",\n  Gray: \"#949698\",\n  Green: \"#00A64F\",\n  GreenYellow: \"#DFE674\",\n  JungleGreen: \"#00A99A\",\n  Lavender: \"#F49EC4\",\n  Limegreen: \"#8DC73E\",\n  Magenta: \"#EC008C\",\n  Mahogany: \"#A9341F\",\n  Maroon: \"#AF3235\",\n  Melon: \"#F89E7B\",\n  MidnightBlue: \"#006795\",\n  Mulberry: \"#A93C93\",\n  NavyBlue: \"#006EB8\",\n  OliveGreen: \"#3C8031\",\n  Orange: \"#F58137\",\n  OrangeRed: \"#ED135A\",\n  Orchid: \"#AF72B0\",\n  Peach: \"#F7965A\",\n  Periwinkle: \"#7977B8\",\n  PineGreen: \"#008B72\",\n  Plum: \"#92268F\",\n  ProcessBlue: \"#00B0F0\",\n  Purple: \"#99479B\",\n  RawSienna: \"#974006\",\n  Red: \"#ED1B23\",\n  RedOrange: \"#F26035\",\n  RedViolet: \"#A1246B\",\n  Rhodamine: \"#EF559F\",\n  RoyalBlue: \"#0071BC\",\n  RoyalPurple: \"#613F99\",\n  RubineRed: \"#ED017D\",\n  Salmon: \"#F69289\",\n  SeaGreen: \"#3FBC9D\",\n  Sepia: \"#671800\",\n  SkyBlue: \"#46C5DD\",\n  SpringGreen: \"#C6DC67\",\n  Tan: \"#DA9D76\",\n  TealBlue: \"#00AEB3\",\n  Thistle: \"#D883B7\",\n  Turquoise: \"#00B4CE\",\n  Violet: \"#58429B\",\n  VioletRed: \"#EF58A0\",\n  White: \"#FFFFFF\",\n  WildStrawberry: \"#EE2967\",\n  Yellow: \"#FFF200\",\n  YellowGreen: \"#98CC70\",\n  YellowOrange: \"#FAA21A\"\n};\nfunction defaultColorMap(s) {\n  var _a3, _b3, _c2, _d2, _e, _f;\n  const colorSpec = s.split(\"!\");\n  let baseRed;\n  let baseGreen;\n  let baseBlue;\n  let red = 255;\n  let green = 255;\n  let blue = 255;\n  let mix = -1;\n  const complementary = colorSpec.length > 0 && colorSpec[0].startsWith(\"-\");\n  if (complementary) colorSpec[0] = colorSpec[0].slice(1);\n  for (let i = 0; i < colorSpec.length; i++) {\n    baseRed = red;\n    baseGreen = green;\n    baseBlue = blue;\n    const colorName = (_a3 = colorSpec[i].trim().match(/^([A-Za-z\\d-]+)/)) == null ? void 0 : _a3[1];\n    const lcColorName = colorName == null ? void 0 : colorName.toLowerCase();\n    const color = !colorName ? colorSpec[i].trim() : (_f = (_e = (_d2 = (_c2 = (_b3 = FOREGROUND_COLORS[lcColorName]) != null ? _b3 : FOREGROUND_COLORS[DVIPS_TO_CHROMATIC[colorName]]) != null ? _c2 : MATLAB_COLORS[colorName]) != null ? _d2 : DVIPS_COLORS[colorName]) != null ? _e : MATHEMATICA_COLORS[colorName]) != null ? _f : colorSpec[i].trim();\n    let m = color.match(/^#([\\da-f]{2})([\\da-f]{2})([\\da-f]{2})$/i);\n    if ((m == null ? void 0 : m[1]) && m[2] && m[3]) {\n      red = Math.max(0, Math.min(255, Number.parseInt(m[1], 16)));\n      green = Math.max(0, Math.min(255, Number.parseInt(m[2], 16)));\n      blue = Math.max(0, Math.min(255, Number.parseInt(m[3], 16)));\n    } else {\n      m = color.match(/^#([\\da-f]{3})$/i);\n      if (m == null ? void 0 : m[1]) {\n        const r1 = Number.parseInt(m[1][0], 16);\n        const g1 = Number.parseInt(m[1][1], 16);\n        const b1 = Number.parseInt(m[1][2], 16);\n        red = Math.max(0, Math.min(255, r1 * 16 + r1));\n        green = Math.max(0, Math.min(255, g1 * 16 + g1));\n        blue = Math.max(0, Math.min(255, b1 * 16 + b1));\n      } else {\n        m = color.match(/^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/i);\n        if ((m == null ? void 0 : m[1]) && m[2] && m[3]) {\n          red = Math.max(0, Math.min(255, Number.parseInt(m[1])));\n          green = Math.max(0, Math.min(255, Number.parseInt(m[2])));\n          blue = Math.max(0, Math.min(255, Number.parseInt(m[3])));\n        } else return void 0;\n      }\n    }\n    if (mix >= 0) {\n      red = (1 - mix) * red + mix * baseRed;\n      green = (1 - mix) * green + mix * baseGreen;\n      blue = (1 - mix) * blue + mix * baseBlue;\n      mix = -1;\n    }\n    if (i + 1 < colorSpec.length)\n      mix = Math.max(0, Math.min(100, Number.parseInt(colorSpec[++i]))) / 100;\n  }\n  if (mix >= 0) {\n    red = mix * red + (1 - mix) * baseRed;\n    green = mix * green + (1 - mix) * baseGreen;\n    blue = mix * blue + (1 - mix) * baseBlue;\n  }\n  if (complementary) {\n    red = 255 - red;\n    green = 255 - green;\n    blue = 255 - blue;\n  }\n  return \"#\" + (\"00\" + Math.round(red).toString(16)).slice(-2) + (\"00\" + Math.round(green).toString(16)).slice(-2) + (\"00\" + Math.round(blue).toString(16)).slice(-2);\n}\nfunction defaultBackgroundColorMap(s) {\n  var _a3, _b3;\n  s = s.trim();\n  return (_b3 = (_a3 = BACKGROUND_COLORS[s.toLowerCase()]) != null ? _a3 : BACKGROUND_COLORS[DVIPS_TO_CHROMATIC[s]]) != null ? _b3 : defaultColorMap(s);\n}\nfunction parseHex(hex) {\n  if (!hex) return void 0;\n  if (hex[0] !== \"#\") return void 0;\n  hex = hex.slice(1);\n  let result;\n  if (hex.length <= 4) {\n    result = {\n      r: parseInt(hex[0] + hex[0], 16),\n      g: parseInt(hex[1] + hex[1], 16),\n      b: parseInt(hex[2] + hex[2], 16)\n    };\n    if (hex.length === 4) result.a = parseInt(hex[3] + hex[3], 16) / 255;\n  } else {\n    result = {\n      r: parseInt(hex[0] + hex[1], 16),\n      g: parseInt(hex[2] + hex[3], 16),\n      b: parseInt(hex[4] + hex[5], 16)\n    };\n    if (hex.length === 8) result.a = parseInt(hex[6] + hex[7], 16) / 255;\n  }\n  if (result && result.a === void 0) result.a = 1;\n  return result;\n}\nfunction hueToRgbChannel(t1, t2, hue) {\n  if (hue < 0) hue += 6;\n  if (hue >= 6) hue -= 6;\n  if (hue < 1) return (t2 - t1) * hue + t1;\n  else if (hue < 3) return t2;\n  else if (hue < 4) return (t2 - t1) * (4 - hue) + t1;\n  return t1;\n}\nfunction hslToRgb(hsl) {\n  let [hue, sat, light] = [hsl.h, hsl.s, hsl.l];\n  hue = (hue + 360) % 360 / 60;\n  light = Math.max(0, Math.min(light, 1));\n  sat = Math.max(0, Math.min(sat, 1));\n  const t2 = light <= 0.5 ? light * (sat + 1) : light + sat - light * sat;\n  const t1 = light * 2 - t2;\n  return {\n    r: Math.round(255 * hueToRgbChannel(t1, t2, hue + 2)),\n    g: Math.round(255 * hueToRgbChannel(t1, t2, hue)),\n    b: Math.round(255 * hueToRgbChannel(t1, t2, hue - 2))\n  };\n}\nfunction clampByte(v) {\n  if (v < 0) return 0;\n  if (v > 255) return 255;\n  return Math.round(v);\n}\nfunction rgbToHexstring(rgb) {\n  const { r, g, b } = rgb;\n  let hexString = ((1 << 24) + (clampByte(r) << 16) + (clampByte(g) << 8) + clampByte(b)).toString(16).slice(1);\n  if (hexString[0] === hexString[1] && hexString[2] === hexString[3] && hexString[4] === hexString[5] && hexString[6] === hexString[7])\n    hexString = hexString[0] + hexString[2] + hexString[4];\n  return \"#\" + hexString;\n}\nfunction rgbToHsl(rgb) {\n  let { r, g, b } = rgb;\n  r = r / 255;\n  g = g / 255;\n  b = b / 255;\n  const min = Math.min(r, g, b);\n  const max = Math.max(r, g, b);\n  const delta = max - min;\n  let h;\n  let s;\n  if (max === min) h = 0;\n  else if (r === max) h = (g - b) / delta;\n  else if (g === max) h = 2 + (b - r) / delta;\n  else if (b === max) h = 4 + (r - g) / delta;\n  h = Math.min(h * 60, 360);\n  if (h < 0) h += 360;\n  const l = (min + max) / 2;\n  if (max === min) s = 0;\n  else if (l <= 0.5) s = delta / (max + min);\n  else s = delta / (2 - max - min);\n  return { h, s, l };\n}\nfunction highlight(color) {\n  let rgb = parseHex(color);\n  if (!rgb) return color;\n  let { h, s, l } = rgbToHsl(rgb);\n  s += 0.1;\n  l -= 0.1;\n  return rgbToHexstring(hslToRgb({ h, s, l }));\n}\n\n// src/core/unicode.ts\nvar UNICODE_TO_LATEX = {\n  60: \"\\\\lt\",\n  62: \"\\\\gt\",\n  111: \"o\",\n  // Also \\omicron\n  38: \"\\\\&\",\n  // Also \\And\n  123: \"\\\\lbrace\",\n  125: \"\\\\rbrace\",\n  91: \"\\\\lbrack\",\n  93: \"\\\\rbrack\",\n  58: \"\\\\colon\",\n  // Also :\n  160: \"~\",\n  // Also \\space\n  172: \"\\\\neg\",\n  // Also \\lnot\n  183: \"\\\\cdot\",\n  188: \"\\\\frac{1}{4}\",\n  189: \"\\\\frac{1}{2}\",\n  190: \"\\\\frac{3}{4}\",\n  8304: \"^{0}\",\n  8305: \"^{i}\",\n  185: \"^{1}\",\n  178: \"^{2}\",\n  // ²\n  179: \"^{3}\",\n  8224: \"\\\\dagger\",\n  // Also \\dag\n  8225: \"\\\\ddagger\",\n  // Also \\ddag\n  8230: \"\\\\ldots\",\n  // Also \\mathellipsis\n  8308: \"^{4}\",\n  8309: \"^{5}\",\n  8310: \"^{6}\",\n  8311: \"^{7}\",\n  8312: \"^{8}\",\n  8313: \"^{9}\",\n  8314: \"^{+}\",\n  8315: \"^{-}\",\n  8316: \"^{=}\",\n  8319: \"^{n}\",\n  8320: \"_{0}\",\n  8321: \"_{1}\",\n  8322: \"_{2}\",\n  8323: \"_{3}\",\n  8324: \"_{4}\",\n  8325: \"_{5}\",\n  8326: \"_{6}\",\n  8327: \"_{7}\",\n  8328: \"_{8}\",\n  8329: \"_{9}\",\n  8330: \"_{+}\",\n  8331: \"_{-}\",\n  8332: \"_{=}\",\n  8336: \"_{a}\",\n  8337: \"_{e}\",\n  8338: \"_{o}\",\n  8339: \"_{x}\",\n  8242: \"\\\\prime\",\n  39: \"\\\\prime\",\n  8592: \"\\\\gets\",\n  // Also \\leftarrow\n  8594: \"\\\\to\",\n  // Also \\rightarrow\n  9651: \"\\\\triangle\",\n  // Also \\bigtriangleup, \\vartriangle\n  9661: \"\\\\triangledown\",\n  8715: \"\\\\owns\",\n  // Also \\ni\n  8727: \"\\\\ast\",\n  // Also *\n  8739: \"\\\\vert\",\n  // Also |, \\mvert, \\lvert, \\rvert\n  8741: \"\\\\Vert\",\n  // Also \\parallel \\shortparallel\n  8743: \"\\\\land\",\n  // Also \\wedge\n  8744: \"\\\\lor\",\n  // Also \\vee\n  8901: \"\\\\cdot\",\n  // Also \\centerdot, \\cdotp\n  8904: \"\\\\bowtie\",\n  // Also \\Joint\n  8800: \"\\\\ne\",\n  // Also \\neq\n  8804: \"\\\\le\",\n  // Also \\leq\n  8805: \"\\\\ge\",\n  // Also \\geq\n  8869: \"\\\\bot\",\n  // Also \\perp\n  10231: \"\\\\biconditional\",\n  // Also \\longleftrightarrow\n  10232: \"\\\\impliedby\",\n  // Also \\Longleftarrow\n  10233: \"\\\\implies\",\n  // Also \\Longrightarrow\n  10234: \"\\\\iff\",\n  8450: \"\\\\mathbb{C}\",\n  8469: \"\\\\mathbb{N}\",\n  8473: \"\\\\mathbb{P}\",\n  8474: \"\\\\mathbb{Q}\",\n  8477: \"\\\\mathbb{R}\",\n  8484: \"\\\\mathbb{Z}\",\n  8461: \"\\\\mathbb{H}\",\n  8476: \"\\\\Re\",\n  8465: \"\\\\Im\",\n  42: \"\\\\ast\",\n  11036: \"\\\\square\",\n  9633: \"\\\\square\",\n  8720: \"\\\\coprod\",\n  8716: \"\\\\not\\\\ni\",\n  9671: \"\\\\diamond\",\n  8846: \"\\\\uplus\",\n  8851: \"\\\\sqcap\",\n  8852: \"\\\\sqcup\",\n  8768: \"\\\\wr\",\n  8750: \"\\\\oint\",\n  8226: \"\\\\textbullet\",\n  8722: \"-\",\n  978: \"\\\\Upsilon\"\n};\nvar MATH_LETTER_EXCEPTIONS = {\n  119893: 8462,\n  119965: 8492,\n  119968: 8496,\n  119969: 8497,\n  119971: 8459,\n  119972: 8464,\n  119975: 8466,\n  119976: 8499,\n  119981: 8475,\n  119994: 8495,\n  119996: 8458,\n  120004: 8500,\n  120070: 8493,\n  120075: 8460,\n  120076: 8465,\n  120085: 8476,\n  120093: 8488,\n  120122: 8450,\n  120127: 8461,\n  120133: 8469,\n  120135: 8473,\n  120136: 8474,\n  120137: 8477,\n  120145: 8484\n};\nvar MATH_UNICODE_BLOCKS = [\n  { start: 119808, len: 26, offset: 65, style: \"bold\" },\n  { start: 119834, len: 26, offset: 97, style: \"bold\" },\n  { start: 120488, len: 25, offset: 913, style: \"bold\" },\n  { start: 120514, len: 25, offset: 945, style: \"bold\" },\n  { start: 119860, len: 26, offset: 65, style: \"italic\" },\n  { start: 119886, len: 26, offset: 97, style: \"italic\" },\n  { start: 120546, len: 25, offset: 913, style: \"italic\" },\n  { start: 120572, len: 25, offset: 945, style: \"italic\" },\n  { start: 119912, len: 26, offset: 65, style: \"bolditalic\" },\n  { start: 119938, len: 26, offset: 97, style: \"bolditalic\" },\n  { start: 120604, len: 25, offset: 913, style: \"bolditalic\" },\n  { start: 120630, len: 25, offset: 945, style: \"bolditalic\" },\n  { start: 120782, len: 10, offset: 48, variant: \"main\", style: \"bold\" },\n  { start: 119964, len: 26, offset: 65, variant: \"script\" },\n  { start: 119990, len: 26, offset: 97, variant: \"script\" },\n  { start: 120016, len: 26, offset: 65, variant: \"script\", style: \"bold\" },\n  { start: 120042, len: 26, offset: 97, variant: \"script\", style: \"bold\" },\n  { start: 120068, len: 26, offset: 65, variant: \"fraktur\" },\n  { start: 120094, len: 26, offset: 97, variant: \"fraktur\" },\n  { start: 120172, len: 26, offset: 65, variant: \"fraktur\", style: \"bold\" },\n  { start: 120198, len: 26, offset: 97, variant: \"fraktur\", style: \"bold\" },\n  { start: 120120, len: 26, offset: 65, variant: \"double-struck\" },\n  { start: 120146, len: 26, offset: 97, variant: \"double-struck\" },\n  { start: 120792, len: 10, offset: 48, variant: \"double-struck\" },\n  { start: 120432, len: 26, offset: 65, variant: \"monospace\" },\n  { start: 120458, len: 26, offset: 97, variant: \"monospace\" },\n  { start: 120822, len: 10, offset: 48, variant: \"monospace\" },\n  { start: 120224, len: 26, offset: 65, variant: \"sans-serif\" },\n  { start: 120250, len: 26, offset: 97, variant: \"sans-serif\" },\n  {\n    start: 120276,\n    len: 26,\n    offset: 65,\n    variant: \"sans-serif\",\n    style: \"bold\"\n  },\n  {\n    start: 120302,\n    len: 26,\n    offset: 97,\n    variant: \"sans-serif\",\n    style: \"bold\"\n  },\n  {\n    start: 120328,\n    len: 26,\n    offset: 65,\n    variant: \"sans-serif\",\n    style: \"italic\"\n  },\n  {\n    start: 120354,\n    len: 26,\n    offset: 97,\n    variant: \"sans-serif\",\n    style: \"italic\"\n  },\n  {\n    start: 120380,\n    len: 26,\n    offset: 65,\n    variant: \"sans-serif\",\n    style: \"bolditalic\"\n  },\n  {\n    start: 120406,\n    len: 26,\n    offset: 97,\n    variant: \"sans-serif\",\n    style: \"bolditalic\"\n  },\n  {\n    start: 120662,\n    len: 25,\n    offset: 913,\n    variant: \"sans-serif\",\n    style: \"bold\"\n  },\n  {\n    start: 120688,\n    len: 25,\n    offset: 945,\n    variant: \"sans-serif\",\n    style: \"bold\"\n  },\n  {\n    start: 120720,\n    len: 25,\n    offset: 913,\n    variant: \"sans-serif\",\n    style: \"bolditalic\"\n  },\n  {\n    start: 120746,\n    len: 25,\n    offset: 945,\n    variant: \"sans-serif\",\n    style: \"bolditalic\"\n  },\n  { start: 120803, len: 10, offset: 48, variant: \"sans-serif\" },\n  {\n    start: 120812,\n    len: 10,\n    offset: 48,\n    variant: \"sans-serif\",\n    style: \"bold\"\n  }\n];\nfunction mathVariantToUnicode(char, variant, style) {\n  if (!/[A-Za-z\\d]/.test(char)) return void 0;\n  if (style === \"up\") style = void 0;\n  if (!variant && !style) return void 0;\n  const codepoint = char.codePointAt(0);\n  if (codepoint === void 0) return char;\n  for (const block of MATH_UNICODE_BLOCKS) {\n    if (!variant || block.variant === variant) {\n      if (!style || block.style === style) {\n        if (codepoint >= block.offset && codepoint < block.offset + block.len) {\n          const result = block.start + codepoint - block.offset;\n          return String.fromCodePoint(MATH_LETTER_EXCEPTIONS[result] || result);\n        }\n      }\n    }\n  }\n  return void 0;\n}\nfunction unicodeToMathVariant(codepoint) {\n  var _a3;\n  if ((codepoint < 119808 || codepoint > 120831) && (codepoint < 8448 || codepoint > 8527))\n    return { char: String.fromCodePoint(codepoint) };\n  for (const c in MATH_LETTER_EXCEPTIONS) {\n    if (MATH_LETTER_EXCEPTIONS[c] === codepoint) {\n      codepoint = (_a3 = c.codePointAt(0)) != null ? _a3 : 0;\n      break;\n    }\n  }\n  for (const block of MATH_UNICODE_BLOCKS) {\n    if (codepoint >= block.start && codepoint < block.start + block.len) {\n      return {\n        char: String.fromCodePoint(codepoint - block.start + block.offset),\n        variant: block.variant,\n        style: block.style\n      };\n    }\n  }\n  return { char: String.fromCodePoint(codepoint) };\n}\nfunction codePointToLatex(c) {\n  var _a3;\n  if (\"{}<>[]$&*#^_%:'\\u02DC\".includes(c)) return void 0;\n  if (c.length > 1) return void 0;\n  const codepoint = (_a3 = c.codePointAt(0)) != null ? _a3 : 0;\n  let latex = UNICODE_TO_LATEX[codepoint];\n  if (latex) return latex;\n  const { char, variant, style } = unicodeToMathVariant(codepoint);\n  if (!variant && !style) return void 0;\n  latex = char;\n  switch (variant) {\n    case \"double-struck\":\n      latex = `\\\\mathbb{${latex}}`;\n      break;\n    case \"fraktur\":\n      latex = `\\\\mathfrak{${latex}}`;\n      break;\n    case \"script\":\n      latex = `\\\\mathscr{${latex}}`;\n      break;\n    case \"sans-serif\":\n      latex = `\\\\mathsf{${latex}}`;\n      break;\n    case \"monospace\":\n      latex = `\\\\mathtt{${latex}}`;\n      break;\n    case \"calligraphic\":\n      latex = `\\\\mathcal{${latex}}`;\n      break;\n  }\n  switch (style) {\n    case \"bold\":\n      latex = `\\\\mathbf{${latex}}`;\n      break;\n    case \"italic\":\n      latex = `\\\\mathit{${latex}}`;\n      break;\n    case \"bolditalic\":\n      latex = `\\\\mathbfit{${latex}}`;\n      break;\n  }\n  return latex;\n}\n\n// src/latex-commands/definitions-utils.ts\nfunction argAtoms(arg) {\n  if (!arg) return [];\n  if (Array.isArray(arg)) return arg;\n  if (typeof arg === \"object\" && \"group\" in arg) return arg.group;\n  return [];\n}\nvar MATH_SYMBOLS = {};\nvar REVERSE_MATH_SYMBOLS = __spreadValues({}, UNICODE_TO_LATEX);\nvar LATEX_COMMANDS = {};\nvar ENVIRONMENTS = {};\nvar TEXVC_MACROS = {\n  //////////////////////////////////////////////////////////////////////\n  // texvc.sty\n  // The texvc package contains macros available in mediawiki pages.\n  // We omit the functions deprecated at\n  // https://en.wikipedia.org/wiki/Help:Displaying_a_formula#Deprecated_syntax\n  // We also omit texvc's \\O, which conflicts with \\text{\\O}\n  darr: \"\\\\downarrow\",\n  dArr: \"\\\\Downarrow\",\n  Darr: \"\\\\Downarrow\",\n  lang: \"\\\\langle\",\n  rang: \"\\\\rangle\",\n  uarr: \"\\\\uparrow\",\n  uArr: \"\\\\Uparrow\",\n  Uarr: \"\\\\Uparrow\",\n  N: \"\\\\mathbb{N}\",\n  R: \"\\\\mathbb{R}\",\n  Z: \"\\\\mathbb{Z}\",\n  alef: \"\\\\aleph\",\n  alefsym: \"\\\\aleph\",\n  Alpha: \"\\\\mathrm{A}\",\n  Beta: \"\\\\mathrm{B}\",\n  bull: \"\\\\bullet\",\n  Chi: \"\\\\mathrm{X}\",\n  clubs: \"\\\\clubsuit\",\n  cnums: \"\\\\mathbb{C}\",\n  Complex: \"\\\\mathbb{C}\",\n  Dagger: \"\\\\ddagger\",\n  diamonds: \"\\\\diamondsuit\",\n  empty: \"\\\\emptyset\",\n  Epsilon: \"\\\\mathrm{E}\",\n  Eta: \"\\\\mathrm{H}\",\n  exist: \"\\\\exists\",\n  harr: \"\\\\leftrightarrow\",\n  hArr: \"\\\\Leftrightarrow\",\n  Harr: \"\\\\Leftrightarrow\",\n  hearts: \"\\\\heartsuit\",\n  image: \"\\\\Im\",\n  infin: \"\\\\infty\",\n  Iota: \"\\\\mathrm{I}\",\n  isin: \"\\\\in\",\n  Kappa: \"\\\\mathrm{K}\",\n  larr: \"\\\\leftarrow\",\n  lArr: \"\\\\Leftarrow\",\n  Larr: \"\\\\Leftarrow\",\n  lrarr: \"\\\\leftrightarrow\",\n  lrArr: \"\\\\Leftrightarrow\",\n  Lrarr: \"\\\\Leftrightarrow\",\n  Mu: \"\\\\mathrm{M}\",\n  natnums: \"\\\\mathbb{N}\",\n  Nu: \"\\\\mathrm{N}\",\n  Omicron: \"\\\\mathrm{O}\",\n  plusmn: \"\\\\pm\",\n  rarr: \"\\\\rightarrow\",\n  rArr: \"\\\\Rightarrow\",\n  Rarr: \"\\\\Rightarrow\",\n  real: \"\\\\Re\",\n  reals: \"\\\\mathbb{R}\",\n  Reals: \"\\\\mathbb{R}\",\n  Rho: \"\\\\mathrm{P}\",\n  sdot: \"\\\\cdot\",\n  sect: \"\\\\S\",\n  spades: \"\\\\spadesuit\",\n  sub: \"\\\\subset\",\n  sube: \"\\\\subseteq\",\n  supe: \"\\\\supseteq\",\n  Tau: \"\\\\mathrm{T}\",\n  thetasym: \"\\\\vartheta\",\n  // TODO: varcoppa: { def: \"\\\\\\mbox{\\\\coppa}\", expand: false },\n  weierp: \"\\\\wp\",\n  Zeta: \"\\\\mathrm{Z}\"\n};\nvar AMSMATH_MACROS = {\n  // amsmath.sty\n  // http://mirrors.concertpass.com/tex-archive/macros/latex/required/amsmath/amsmath.pdf\n  // Italic Greek capital letters.  AMS defines these with \\DeclareMathSymbol,\n  // but they are equivalent to \\mathit{\\Letter}.\n  varGamma: \"\\\\mathit{\\\\Gamma}\",\n  varDelta: \"\\\\mathit{\\\\Delta}\",\n  varTheta: \"\\\\mathit{\\\\Theta}\",\n  varLambda: \"\\\\mathit{\\\\Lambda}\",\n  varXi: \"\\\\mathit{\\\\Xi}\",\n  varPi: \"\\\\mathit{\\\\Pi}\",\n  varSigma: \"\\\\mathit{\\\\Sigma}\",\n  varUpsilon: \"\\\\mathit{\\\\Upsilon}\",\n  varPhi: \"\\\\mathit{\\\\Phi}\",\n  varPsi: \"\\\\mathit{\\\\Psi}\",\n  varOmega: \"\\\\mathit{\\\\Omega}\",\n  // From http://tug.ctan.org/macros/latex/required/amsmath/amsmath.dtx\n  // > \\newcommand{\\pod}[1]{\n  // >    \\allowbreak\n  // >    \\if@display\n  // >      \\mkern18mu\n  // >    \\else\n  // >      \\mkern8mu\n  // >    \\fi\n  // >    (#1)\n  // > }\n  // 18mu = \\quad\n  // > \\renewcommand{\\pmod}[1]{\n  // >  \\pod{{\\operator@font mod}\\mkern6mu#1}\n  // > }\n  pmod: {\n    def: \"\\\\quad(\\\\operatorname{mod}\\\\ #1)\",\n    args: 1,\n    expand: false,\n    captureSelection: false\n  },\n  // > \\newcommand{\\mod}[1]{\n  // >    \\allowbreak\n  // >    \\if@display\n  // >      \\mkern18mu\n  // >    \\else\n  // >      \\mkern12mu\n  // >    \\fi\n  //>     {\\operator@font mod}\\,\\,#1}\n  mod: {\n    def: \"\\\\quad\\\\operatorname{mod}\\\\,\\\\,#1\",\n    args: 1,\n    expand: false\n  },\n  // > \\renewcommand{\\bmod}{\n  // >  \\nonscript\\mskip-\\medmuskip\\mkern5mu\n  // >  \\mathbin{\\operator@font mod}\n  // >  \\penalty900 \\mkern5mu\n  // >  \\nonscript\\mskip-\\medmuskip\n  // > }\n  // 5mu = \\;\n  bmod: {\n    def: \"\\\\;\\\\mathbin{\\\\operatorname{mod }}\",\n    expand: false\n  }\n};\nvar BRAKET_MACROS = {\n  bra: { def: \"\\\\mathinner{\\\\langle{#1}|}\", args: 1, captureSelection: false },\n  ket: { def: \"\\\\mathinner{|{#1}\\\\rangle}\", args: 1, captureSelection: false },\n  braket: {\n    def: \"\\\\mathinner{\\\\langle{#1}\\\\rangle}\",\n    args: 1,\n    captureSelection: false\n  },\n  set: {\n    def: \"\\\\mathinner{\\\\lbrace #1 \\\\rbrace}\",\n    args: 1,\n    captureSelection: false\n  },\n  Bra: { def: \"\\\\left\\\\langle #1\\\\right|\", args: 1, captureSelection: false },\n  Ket: { def: \"\\\\left|#1\\\\right\\\\rangle\", args: 1, captureSelection: false },\n  Braket: {\n    def: \"\\\\left\\\\langle{#1}\\\\right\\\\rangle\",\n    args: 1,\n    captureSelection: false\n  },\n  Set: {\n    def: \"\\\\left\\\\lbrace #1 \\\\right\\\\rbrace\",\n    args: 1,\n    captureSelection: false\n  }\n};\nvar DEFAULT_MACROS = {\n  \"iff\": {\n    primitive: true,\n    captureSelection: true,\n    def: '\\\\;\\\\char\"27FA\\\\;'\n    // >2,000 Note: additional spaces around the arrows\n  },\n  \"nicefrac\": \"^{#1}\\\\!\\\\!/\\\\!_{#2}\",\n  \"phase\": {\n    def: \"\\\\enclose{phasorangle}{#1}\",\n    args: 1,\n    captureSelection: false\n  },\n  // Proof Wiki\n  \"rd\": \"\\\\mathrm{d}\",\n  \"rD\": \"\\\\mathrm{D}\",\n  // From Wolfram Alpha\n  \"doubleStruckCapitalN\": \"\\\\mathbb{N}\",\n  \"doubleStruckCapitalR\": \"\\\\mathbb{R}\",\n  \"doubleStruckCapitalQ\": \"\\\\mathbb{Q}\",\n  \"doubleStruckCapitalZ\": \"\\\\mathbb{Z}\",\n  \"doubleStruckCapitalP\": \"\\\\mathbb{P}\",\n  \"scriptCapitalE\": \"\\\\mathscr{E}\",\n  \"scriptCapitalH\": \"\\\\mathscr{H}\",\n  \"scriptCapitalL\": \"\\\\mathscr{L}\",\n  \"gothicCapitalC\": \"\\\\mathfrak{C}\",\n  \"gothicCapitalH\": \"\\\\mathfrak{H}\",\n  \"gothicCapitalI\": \"\\\\mathfrak{I}\",\n  \"gothicCapitalR\": \"\\\\mathfrak{R}\",\n  \"imaginaryI\": \"\\\\mathrm{i}\",\n  // NOTE: set in main (upright) as per ISO 80000-2:2009.\n  \"imaginaryJ\": \"\\\\mathrm{j}\",\n  // NOTE: set in main (upright) as per ISO 80000-2:2009.\n  \"exponentialE\": \"\\\\mathrm{e}\",\n  // NOTE: set in main (upright) as per ISO 80000-2:2009.\n  \"differentialD\": \"\\\\mathrm{d}\",\n  // NOTE: set in main (upright) as per ISO 80000-2:2009.\n  \"capitalDifferentialD\": \"\\\\mathrm{D}\",\n  // NOTE: set in main (upright) as per ISO 80000-2:2009.\n  \"mathstrut\": { def: \"\\\\vphantom{(}\", primitive: true },\n  // https://ctan.math.washington.edu/tex-archive/macros/latex/contrib/actuarialangle/actuarialangle.pdf\n  \"angl\": \"\\\\enclose{actuarial}{#1}\",\n  \"angln\": \"\\\\enclose{actuarial}{n}\",\n  \"anglr\": \"\\\\enclose{actuarial}{r}\",\n  \"anglk\": \"\\\\enclose{actuarial}{k}\",\n  //////////////////////////////////////////////////////////////////////\n  // mathtools.sty\n  // In the summer of 2022, mathtools did some renaming of macros.\n  // This is the latest version, with some legacy commands.\n  \"mathtools\": {\n    primitive: true,\n    package: {\n      //\\providecommand\\ordinarycolon{:}\n      ordinarycolon: \":\",\n      //\\def\\vcentcolon{\\mathrel{\\mathop\\ordinarycolon}}\n      //TODO(edemaine): Not yet centered. Fix via \\raisebox or #726\n      vcentcolon: \"\\\\mathrel{\\\\mathop\\\\ordinarycolon}\",\n      // \\providecommand*\\dblcolon{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}\n      dblcolon: '{\\\\mathop{\\\\char\"2237}}',\n      // \\providecommand*\\coloneqq{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}\n      coloneqq: '{\\\\mathop{\\\\char\"2254}}',\n      // ≔\n      // \\providecommand*\\Coloneqq{\\dblcolon\\mathrel{\\mkern-1.2mu}=}\n      Coloneqq: '{\\\\mathop{\\\\char\"2237\\\\char\"3D}}',\n      // \\providecommand*\\coloneq{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}\n      coloneq: '{\\\\mathop{\\\\char\"3A\\\\char\"2212}}',\n      // \\providecommand*\\Coloneq{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}\n      Coloneq: '{\\\\mathop{\\\\char\"2237\\\\char\"2212}}',\n      // \\providecommand*\\eqqcolon{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}\n      eqqcolon: '{\\\\mathop{\\\\char\"2255}}',\n      // ≕\n      // \\providecommand*\\Eqqcolon{=\\mathrel{\\mkern-1.2mu}\\dblcolon}\n      Eqqcolon: '{\\\\mathop{\\\\char\"3D\\\\char\"2237}}',\n      // \\providecommand*\\eqcolon{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}\n      eqcolon: '{\\\\mathop{\\\\char\"2239}}',\n      // \\providecommand*\\Eqcolon{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}\n      Eqcolon: '{\\\\mathop{\\\\char\"2212\\\\char\"2237}}',\n      // \\providecommand*\\colonapprox{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}\n      colonapprox: '{\\\\mathop{\\\\char\"003A\\\\char\"2248}}',\n      // \\providecommand*\\Colonapprox{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}\n      Colonapprox: '{\\\\mathop{\\\\char\"2237\\\\char\"2248}}',\n      // \\providecommand*\\colonsim{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}\n      colonsim: '{\\\\mathop{\\\\char\"3A\\\\char\"223C}}',\n      // \\providecommand*\\Colonsim{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}\n      Colonsim: '{\\\\mathop{\\\\char\"2237\\\\char\"223C}}',\n      colondash: \"\\\\mathrel{\\\\vcentcolon\\\\mathrel{\\\\mkern-1.2mu}\\\\mathrel{-}}\",\n      Colondash: \"\\\\mathrel{\\\\dblcolon\\\\mathrel{\\\\mkern-1.2mu}\\\\mathrel{-}}\",\n      dashcolon: \"\\\\mathrel{\\\\mathrel{-}\\\\mathrel{\\\\mkern-1.2mu}\\\\vcentcolon}\",\n      Dashcolon: \"\\\\mathrel{\\\\mathrel{-}\\\\mathrel{\\\\mkern-1.2mu}\\\\dblcolon}\"\n      // Some Unicode characters are implemented with macros to mathtools functions.\n      // defineMacro(\"\\u2237\", \"\\\\dblcolon\");  // ::\n      // defineMacro(\"\\u2239\", \"\\\\eqcolon\");  // -:\n      // defineMacro(\"\\u2254\", \"\\\\coloneqq\");  // :=\n      // defineMacro(\"\\u2255\", \"\\\\eqqcolon\");  // =:\n      // defineMacro(\"\\u2A74\", \"\\\\Coloneqq\");  // ::=\n    }\n  },\n  //////////////////////////////////////////////////////////////////////\n  // colonequals.sty\n  // Alternate names for mathtools's macros:\n  \"ratio\": \"\\\\vcentcolon\",\n  \"coloncolon\": \"\\\\dblcolon\",\n  \"colonequals\": \"\\\\coloneq\",\n  \"coloncolonequals\": \"\\\\Coloneq\",\n  \"equalscolon\": \"\\\\eqcolon\",\n  \"equalscoloncolon\": \"\\\\Eqcolon\",\n  \"colonminus\": \"\\\\colondash\",\n  \"coloncolonminus\": \"\\\\Colondash\",\n  \"minuscolon\": \"\\\\dashcolon\",\n  \"minuscoloncolon\": \"\\\\Dashcolon\",\n  // \\colonapprox name is same in mathtools and colonequals.\n  \"coloncolonapprox\": \"\\\\Colonapprox\",\n  // \\colonsim name is same in mathtools and colonequals.\n  \"coloncolonsim\": \"\\\\Colonsim\",\n  // Additional macros, implemented by analogy with mathtools definitions:\n  \"simcolon\": \"\\\\mathrel{\\\\sim\\\\mathrel{\\\\mkern-1.2mu}\\\\vcentcolon}\",\n  \"Simcolon\": \"\\\\mathrel{\\\\sim\\\\mathrel{\\\\mkern-1.2mu}\\\\dblcolon}\",\n  \"simcoloncolon\": \"\\\\mathrel{\\\\sim\\\\mathrel{\\\\mkern-1.2mu}\\\\dblcolon}\",\n  \"approxcolon\": \"\\\\mathrel{\\\\approx\\\\mathrel{\\\\mkern-1.2mu}\\\\vcentcolon}\",\n  \"Approxcolon\": \"\\\\mathrel{\\\\approx\\\\mathrel{\\\\mkern-1.2mu}\\\\dblcolon}\",\n  \"approxcoloncolon\": \"\\\\mathrel{\\\\approx\\\\mathrel{\\\\mkern-1.2mu}\\\\dblcolon}\",\n  // Present in newtxmath, pxfonts and txfonts\n  \"notni\": \"\\\\mathrel{\\\\char`\\u220C}\",\n  \"limsup\": \"\\\\operatorname*{lim\\\\,sup}\",\n  \"liminf\": \"\\\\operatorname*{lim\\\\,inf}\",\n  //////////////////////////////////////////////////////////////////////\n  // From amsopn.sty\n  \"injlim\": \"\\\\operatorname*{inj\\\\,lim}\",\n  \"projlim\": \"\\\\operatorname*{proj\\\\,lim}\",\n  \"varlimsup\": \"\\\\operatorname*{\\\\overline{lim}}\",\n  \"varliminf\": \"\\\\operatorname*{\\\\underline{lim}}\",\n  \"varinjlim\": \"\\\\operatorname*{\\\\underrightarrow{lim}}\",\n  \"varprojlim\": \"\\\\operatorname*{\\\\underleftarrow{lim}}\",\n  //////////////////////////////////////////////////////////////////////\n  // statmath.sty\n  // https://ctan.math.illinois.edu/macros/latex/contrib/statmath/statmath.pdf\n  \"argmin\": \"\\\\operatorname*{arg\\\\,min}\",\n  \"argmax\": \"\\\\operatorname*{arg\\\\,max}\",\n  \"plim\": \"\\\\mathop{\\\\operatorname{plim}}\\\\limits\",\n  // mhchem\n  \"tripledash\": {\n    def: \"\\\\vphantom{-}\\\\raise{4mu}{\\\\mkern1.5mu\\\\rule{2mu}{1.5mu}\\\\mkern{2.25mu}\\\\rule{2mu}{1.5mu}\\\\mkern{2.25mu}\\\\rule{2mu}{1.5mu}\\\\mkern{2mu}}\",\n    expand: true\n  },\n  \"braket.sty\": { package: BRAKET_MACROS },\n  \"amsmath.sty\": {\n    package: AMSMATH_MACROS,\n    primitive: true\n  },\n  \"texvc.sty\": {\n    package: TEXVC_MACROS,\n    primitive: false\n  }\n};\nvar TEXT_SYMBOLS = {\n  \" \": 32,\n  // want that in Text mode.\n  \"\\\\!\": 33,\n  \"\\\\#\": 35,\n  \"\\\\$\": 36,\n  \"\\\\%\": 37,\n  \"\\\\&\": 38,\n  \"\\\\_\": 95,\n  \"-\": 45,\n  // In Math mode, '-' is substituted to U+2212, but we don't\n  \"\\\\textunderscore\": 95,\n  // '_'\n  \"\\\\euro\": 8364,\n  \"\\\\maltese\": 10016,\n  \"\\\\{\": 123,\n  \"\\\\}\": 125,\n  \"\\\\textbraceleft\": 123,\n  \"\\\\textbraceright\": 125,\n  \"\\\\lbrace\": 123,\n  \"\\\\rbrace\": 125,\n  \"\\\\lbrack\": 91,\n  \"\\\\rbrack\": 93,\n  \"\\\\nobreakspace\": 160,\n  \"\\\\ldots\": 8230,\n  \"\\\\textellipsis\": 8230,\n  \"\\\\backslash\": 92,\n  \"`\": 8216,\n  \"'\": 8217,\n  \"``\": 8220,\n  \"''\": 8221,\n  \"\\\\degree\": 176,\n  \"\\\\textasciicircum\": 94,\n  \"\\\\textasciitilde\": 126,\n  \"\\\\textasteriskcentered\": 42,\n  \"\\\\textbackslash\": 92,\n  // '\\'\n  \"\\\\textbullet\": 8226,\n  \"\\\\textdollar\": 36,\n  \"\\\\textsterling\": 163,\n  \"\\\\textdagger\": 8224,\n  \"\\\\textdaggerdbl\": 8225,\n  \"\\u2013\": 8211,\n  // EN DASH\n  \"\\u2014\": 8212,\n  // EM DASH\n  \"\\u2018\": 8216,\n  // LEFT SINGLE QUOTATION MARK\n  \"\\u2019\": 8217,\n  // RIGHT SINGLE QUOTATION MARK\n  \"\\u201C\": 8220,\n  // LEFT DOUBLE QUOTATION MARK\n  \"\\u201D\": 8221,\n  // RIGHT DOUBLE QUOTATION MARK\n  '\"': 8221,\n  // DOUBLE PRIME\n  \"\\\\ss\": 223,\n  // LATIN SMALL LETTER SHARP S\n  \"\\\\ae\": 230,\n  // LATIN SMALL LETTER AE\n  \"\\\\oe\": 339,\n  // LATIN SMALL LIGATURE OE\n  \"\\\\AE\": 198,\n  // LATIN CAPITAL LETTER AE\n  \"\\\\OE\": 338,\n  // LATIN CAPITAL LIGATURE OE\n  \"\\\\O\": 216,\n  // LATIN CAPITAL LETTER O WITH STROKE\n  \"\\\\i\": 305,\n  // LATIN SMALL LETTER DOTLESS I\n  \"\\\\j\": 567,\n  // LATIN SMALL LETTER DOTLESS J\n  \"\\\\aa\": 229,\n  // LATIN SMALL LETTER A WITH RING ABOVE\n  \"\\\\AA\": 197\n  // LATIN CAPITAL LETTER A WITH RING ABOVE\n};\nvar COMMAND_MODE_CHARACTERS = /[\\w!@*()-=+{}\\[\\]\\\\';:?/.,~<>`|$%#&^\" ]/;\nvar LETTER;\nvar LETTER_AND_DIGITS;\nif (supportRegexPropertyEscape()) {\n  LETTER = new RegExp(\"\\\\p{Letter}\", \"u\");\n  LETTER_AND_DIGITS = new RegExp(\"[0-9\\\\p{Letter}]\", \"u\");\n} else {\n  LETTER = /[a-zA-ZаАбБвВгГдДеЕёЁжЖзЗиИйЙкКлЛмМнНоОпПрРсСтТуУфФхХцЦчЧшШщЩъЪыЫьЬэЭюЮяĄąĆćĘęŁłŃńÓóŚśŹźŻżàâäôéèëêïîçùûüÿæœÀÂÄÔÉÈËÊÏÎŸÇÙÛÜÆŒößÖẞìíòúÌÍÒÚáñÁÑ]/;\n  LETTER_AND_DIGITS = /[\\da-zA-ZаАбБвВгГдДеЕёЁжЖзЗиИйЙкКлЛмМнНоОпПрРсСтТуУфФхХцЦчЧшШщЩъЪыЫьЬэЭюЮяĄąĆćĘęŁłŃńÓóŚśŹźŻżàâäôéèëêïîçùûüÿæœÀÂÄÔÉÈËÊÏÎŸÇÙÛÜÆŒößÖẞìíòúÌÍÒÚáñÁÑ]/;\n}\nfunction defineSymbol(symbol, codepoint, type = \"mord\", variant) {\n  if (codepoint === void 0) return;\n  MATH_SYMBOLS[symbol] = {\n    definitionType: \"symbol\",\n    type,\n    variant,\n    codepoint\n  };\n  if (!REVERSE_MATH_SYMBOLS[codepoint])\n    REVERSE_MATH_SYMBOLS[codepoint] = symbol;\n}\nfunction defineSymbols(value, inType, inVariant) {\n  if (typeof value === \"string\") {\n    for (let i = 0; i < value.length; i++) {\n      const ch = value.charAt(i);\n      defineSymbol(ch, ch.codePointAt(0));\n    }\n    return;\n  }\n  for (const [symbol, val, type, variant] of value)\n    defineSymbol(symbol, val, type != null ? type : inType, variant != null ? variant : inVariant);\n}\nfunction defineSymbolRange(from, to) {\n  for (let i = from; i <= to; i++) defineSymbol(String.fromCodePoint(i), i);\n}\nfunction getEnvironmentDefinition(name) {\n  var _a3;\n  return (_a3 = ENVIRONMENTS[name]) != null ? _a3 : null;\n}\nfunction suggest(mf, s) {\n  var _a3, _b3;\n  if (s.length === 0 || s === \"\\\\\" || !s.startsWith(\"\\\\\")) return [];\n  const result = [];\n  for (const p in LATEX_COMMANDS) {\n    if (p.startsWith(s) && !LATEX_COMMANDS[p].infix)\n      result.push({ match: p, frequency: (_a3 = LATEX_COMMANDS[p].frequency) != null ? _a3 : 0 });\n  }\n  for (const p in MATH_SYMBOLS) {\n    if (p.startsWith(s))\n      result.push({ match: p, frequency: (_b3 = MATH_SYMBOLS[p].frequency) != null ? _b3 : 0 });\n  }\n  const command = s.substring(1);\n  for (const p of Object.keys(mf.options.macros))\n    if (p.startsWith(command)) result.push({ match: \"\\\\\" + p, frequency: 0 });\n  result.sort((a, b) => {\n    var _a4, _b4;\n    if (a.frequency === b.frequency) {\n      if (a.match.length === b.match.length) return a.match < b.match ? -1 : 1;\n      return a.match.length - b.match.length;\n    }\n    return ((_a4 = b.frequency) != null ? _a4 : 0) - ((_b4 = a.frequency) != null ? _b4 : 0);\n  });\n  return result.map((x) => x.match);\n}\nfunction parseParameterTemplateArgument(argTemplate) {\n  let type = \"auto\";\n  const r = argTemplate.match(/:([^=]+)/);\n  if (r) type = r[1].trim();\n  return type;\n}\nfunction parseParameterTemplate(parameterTemplate) {\n  if (!parameterTemplate) return [];\n  const result = [];\n  let parameters = parameterTemplate.split(\"]\");\n  if (parameters[0].startsWith(\"[\")) {\n    result.push({\n      isOptional: true,\n      type: parseParameterTemplateArgument(parameters[0].slice(1))\n    });\n    for (let i = 1; i <= parameters.length; i++)\n      result.push(...parseParameterTemplate(parameters[i]));\n  } else {\n    parameters = parameterTemplate.split(\"}\");\n    if (parameters[0].startsWith(\"{\")) {\n      result.push({\n        isOptional: false,\n        type: parseParameterTemplateArgument(parameters[0].slice(1))\n      });\n      for (let i = 1; i <= parameters.length; i++)\n        result.push(...parseParameterTemplate(parameters[i]));\n    }\n  }\n  return result;\n}\nfunction parseArgAsString(atoms) {\n  if (!atoms) return \"\";\n  let result = \"\";\n  let success = true;\n  for (const atom of atoms) {\n    if (typeof atom.value === \"string\") result += atom.value;\n    else success = false;\n  }\n  return success ? result : \"\";\n}\nfunction defineEnvironment(names, createAtom) {\n  if (typeof names === \"string\") names = [names];\n  const def = {\n    tabular: false,\n    params: [],\n    createAtom\n  };\n  for (const name of names) ENVIRONMENTS[name] = def;\n}\nfunction defineTabularEnvironment(names, parameters, createAtom) {\n  if (typeof names === \"string\") names = [names];\n  const parsedParameters = parseParameterTemplate(parameters);\n  const data = {\n    tabular: true,\n    params: parsedParameters,\n    createAtom\n  };\n  for (const name of names) ENVIRONMENTS[name] = data;\n}\nfunction defineFunction(names, parameters, options) {\n  var _a3, _b3;\n  if (!options) options = {};\n  const data = {\n    definitionType: \"function\",\n    // The parameters for this function, an array of\n    // {optional, type}\n    params: parseParameterTemplate(parameters),\n    ifMode: options.ifMode,\n    isFunction: (_a3 = options.isFunction) != null ? _a3 : false,\n    applyMode: options.applyMode,\n    infix: (_b3 = options.infix) != null ? _b3 : false,\n    parse: options.parse,\n    createAtom: options.createAtom,\n    applyStyle: options.applyStyle,\n    serialize: options.serialize,\n    render: options.render\n  };\n  if (typeof names === \"string\") LATEX_COMMANDS[\"\\\\\" + names] = data;\n  else for (const name of names) LATEX_COMMANDS[\"\\\\\" + name] = data;\n}\nvar _DEFAULT_MACROS;\nfunction getMacros(otherMacros) {\n  if (!_DEFAULT_MACROS)\n    _DEFAULT_MACROS = normalizeMacroDictionary(DEFAULT_MACROS);\n  if (!otherMacros) return _DEFAULT_MACROS;\n  return normalizeMacroDictionary(__spreadValues(__spreadValues({}, _DEFAULT_MACROS), otherMacros));\n}\nfunction normalizeMacroDefinition(def, options) {\n  var _a3, _b3, _c2, _d2;\n  if (typeof def === \"string\") {\n    let argCount = 0;\n    const defString = def;\n    if (/(^|[^\\\\])#1/.test(defString)) argCount = 1;\n    if (/(^|[^\\\\])#2/.test(defString)) argCount = 2;\n    if (/(^|[^\\\\])#3/.test(defString)) argCount = 3;\n    if (/(^|[^\\\\])#4/.test(defString)) argCount = 4;\n    if (/(^|[^\\\\])#5/.test(defString)) argCount = 5;\n    if (/(^|[^\\\\])#6/.test(defString)) argCount = 6;\n    if (/(^|[^\\\\])#7/.test(defString)) argCount = 7;\n    if (/(^|[^\\\\])#8/.test(defString)) argCount = 8;\n    if (/(^|[^\\\\])#9/.test(defString)) argCount = 9;\n    return {\n      expand: (_a3 = options == null ? void 0 : options.expand) != null ? _a3 : true,\n      captureSelection: (_b3 = options == null ? void 0 : options.captureSelection) != null ? _b3 : true,\n      args: argCount,\n      def: defString\n    };\n  }\n  return __spreadValues({\n    expand: (_c2 = options == null ? void 0 : options.expand) != null ? _c2 : true,\n    captureSelection: (_d2 = options == null ? void 0 : options.captureSelection) != null ? _d2 : true,\n    args: 0\n  }, def);\n}\nfunction normalizeMacroDictionary(macros) {\n  if (!macros) return {};\n  const result = {};\n  for (const macro of Object.keys(macros)) {\n    const macroDef = macros[macro];\n    if (macroDef === void 0 || macroDef === null) delete result[macro];\n    else if (typeof macroDef === \"object\" && \"package\" in macroDef) {\n      for (const packageMacro of Object.keys(macroDef.package)) {\n        result[packageMacro] = normalizeMacroDefinition(\n          macroDef.package[packageMacro],\n          {\n            expand: !macroDef.primitive,\n            captureSelection: macroDef.captureSelection\n          }\n        );\n      }\n    } else result[macro] = normalizeMacroDefinition(macroDef);\n  }\n  return result;\n}\nfunction getDefinition(token, parseMode = \"math\") {\n  if (!token || token.length === 0) return null;\n  let info = null;\n  if (token.startsWith(\"\\\\\")) {\n    info = LATEX_COMMANDS[token];\n    if (info) {\n      if (!info.ifMode || info.ifMode === parseMode) return info;\n      return null;\n    }\n    if (parseMode === \"math\") info = MATH_SYMBOLS[token];\n    else if (TEXT_SYMBOLS[token]) {\n      info = {\n        definitionType: \"symbol\",\n        type: \"mord\",\n        codepoint: TEXT_SYMBOLS[token]\n      };\n    }\n  } else if (parseMode === \"math\") {\n    info = MATH_SYMBOLS[token];\n    if (!info && token.length === 1) {\n      const command = charToLatex(\"math\", token.codePointAt(0));\n      if (command.startsWith(\"\\\\\"))\n        return __spreadProps(__spreadValues({}, getDefinition(command, \"math\")), { command });\n      return null;\n    }\n  } else if (TEXT_SYMBOLS[token]) {\n    info = {\n      definitionType: \"symbol\",\n      type: \"mord\",\n      codepoint: TEXT_SYMBOLS[token]\n    };\n  } else if (parseMode === \"text\") {\n    info = {\n      definitionType: \"symbol\",\n      type: \"mord\",\n      codepoint: token.codePointAt(0)\n    };\n  }\n  return info != null ? info : null;\n}\nfunction getMacroDefinition(token, macros) {\n  if (!token.startsWith(\"\\\\\")) return null;\n  const command = token.slice(1);\n  return macros[command];\n}\nfunction charToLatex(parseMode, codepoint) {\n  if (codepoint === void 0) return \"\";\n  if (parseMode === \"math\" && REVERSE_MATH_SYMBOLS[codepoint])\n    return REVERSE_MATH_SYMBOLS[codepoint];\n  if (parseMode === \"text\") {\n    const textSymbol = Object.keys(TEXT_SYMBOLS).find(\n      (x) => TEXT_SYMBOLS[x] === codepoint\n    );\n    if (textSymbol) return textSymbol;\n    return String.fromCodePoint(codepoint);\n  }\n  return String.fromCodePoint(codepoint);\n}\n\n// src/core/font-metrics-data.ts\nvar M1 = [0, 0.68889, 0, 0, 0.72222];\nvar M2 = [0, 0.68889, 0, 0, 0.66667];\nvar M3 = [0, 0.68889, 0, 0, 0.77778];\nvar M4 = [0, 0.68889, 0, 0, 0.61111];\nvar M5 = [0.16667, 0.68889, 0, 0, 0.77778];\nvar M6 = [0, 0.68889, 0, 0, 0.55556];\nvar M7 = [0, 0, 0, 0, 0.25];\nvar M8 = [0, 0.825, 0, 0, 2.33334];\nvar M9 = [0, 0.9, 0, 0, 2.33334];\nvar M10 = [0, 0.68889, 0, 0, 0.54028];\nvar M11 = [-0.03598, 0.46402, 0, 0, 0.5];\nvar M12 = [-0.13313, 0.36687, 0, 0, 1];\nvar M13 = [0.01354, 0.52239, 0, 0, 1];\nvar M14 = [0.01354, 0.52239, 0, 0, 1.11111];\nvar M15 = [0, 0.54986, 0, 0, 1];\nvar M16 = [0, 0.69224, 0, 0, 0.5];\nvar M17 = [0, 0.43056, 0, 0, 1];\nvar M18 = [0.08198, 0.58198, 0, 0, 0.77778];\nvar M19 = [0.19444, 0.69224, 0, 0, 0.41667];\nvar M20 = [0.1808, 0.675, 0, 0, 1];\nvar M21 = [0.19444, 0.69224, 0, 0, 0.83334];\nvar M22 = [0.13667, 0.63667, 0, 0, 1];\nvar M23 = [-0.064, 0.437, 0, 0, 1.334];\nvar M24 = [0.08167, 0.58167, 0, 0, 0.77778];\nvar M25 = [0, 0.69224, 0, 0, 0.72222];\nvar M26 = [0, 0.69224, 0, 0, 0.66667];\nvar M27 = [-0.13313, 0.36687, 0, 0, 0.77778];\nvar M28 = [0.06062, 0.54986, 0, 0, 0.77778];\nvar M29 = [0, 0.69224, 0, 0, 0.77778];\nvar M30 = [0.25583, 0.75583, 0, 0, 0.77778];\nvar M31 = [0.25142, 0.75726, 0, 0, 0.77778];\nvar M32 = [0.20576, 0.70576, 0, 0, 0.77778];\nvar M33 = [0.30274, 0.79383, 0, 0, 0.77778];\nvar M34 = [0.22958, 0.72958, 0, 0, 0.77778];\nvar M35 = [0.1808, 0.675, 0, 0, 0.77778];\nvar M36 = [0.13667, 0.63667, 0, 0, 0.77778];\nvar M37 = [0.13597, 0.63597, 0, 0, 0.77778];\nvar M38 = [0.03517, 0.54986, 0, 0, 0.77778];\nvar M39 = [0, 0.675, 0, 0, 0.77778];\nvar M40 = [0.19444, 0.69224, 0, 0, 0.61111];\nvar M41 = [0, 0.54986, 0, 0, 0.76042];\nvar M42 = [0, 0.54986, 0, 0, 0.66667];\nvar M43 = [0.0391, 0.5391, 0, 0, 0.77778];\nvar M44 = [0.03517, 0.54986, 0, 0, 1.33334];\nvar M45 = [0.38569, 0.88569, 0, 0, 0.77778];\nvar M46 = [0.23222, 0.74111, 0, 0, 0.77778];\nvar M47 = [0.19444, 0.69224, 0, 0, 0.77778];\nvar M48 = [0, 0.37788, 0, 0, 0.5];\nvar M49 = [0, 0.54986, 0, 0, 0.72222];\nvar M50 = [0, 0.69224, 0, 0, 0.83334];\nvar M51 = [0.11111, 0.69224, 0, 0, 0.66667];\nvar M52 = [0.26167, 0.75726, 0, 0, 0.77778];\nvar M53 = [0.48256, 0.98256, 0, 0, 0.77778];\nvar M54 = [0.28481, 0.79383, 0, 0, 0.77778];\nvar M55 = [0.08167, 0.58167, 0, 0, 0.22222];\nvar M56 = [0.08167, 0.58167, 0, 0, 0.38889];\nvar M57 = [0, 0.43056, 0.04028, 0, 0.66667];\nvar M58 = [0.41951, 0.91951, 0, 0, 0.77778];\nvar M59 = [0.24982, 0.74947, 0, 0, 0.38865];\nvar M60 = [0.08319, 0.58283, 0, 0, 0.75623];\nvar M61 = [0, 0.10803, 0, 0, 0.27764];\nvar M62 = [0, 0.47534, 0, 0, 0.50181];\nvar M63 = [0.18906, 0.47534, 0, 0, 0.50181];\nvar M64 = [0, 0.69141, 0, 0, 0.50181];\nvar M65 = [0.24982, 0.74947, 0, 0, 0.27764];\nvar M66 = [0, 0.69141, 0, 0, 0.21471];\nvar M67 = [0.25, 0.75, 0, 0, 0.44722];\nvar M68 = [0, 0.64444, 0, 0, 0.575];\nvar M69 = [0.08556, 0.58556, 0, 0, 0.89444];\nvar M70 = [0, 0.69444, 0, 0, 0.89444];\nvar M71 = [0, 0.68611, 0, 0, 0.9];\nvar M72 = [0, 0.68611, 0, 0, 0.86944];\nvar M73 = [0.25, 0.75, 0, 0, 0.575];\nvar M74 = [0.25, 0.75, 0, 0, 0.31944];\nvar M75 = [0, 0.69444, 0, 0, 0.63889];\nvar M76 = [0, 0.69444, 0, 0, 0.31944];\nvar M77 = [0, 0.44444, 0, 0, 0.63889];\nvar M78 = [0, 0.44444, 0, 0, 0.51111];\nvar M79 = [0, 0.69444, 0, 0, 0.575];\nvar M80 = [0.13333, 0.63333, 0, 0, 0.89444];\nvar M81 = [0, 0.44444, 0, 0, 0.31944];\nvar M82 = [0, 0.69444, 0, 0, 0.86944];\nvar M83 = [0, 0.68611, 0, 0, 0.69166];\nvar M84 = [0, 0.68611, 0, 0, 0.83055];\nvar M85 = [0, 0.68611, 0, 0, 0.89444];\nvar M86 = [0, 0.69444, 0, 0, 0.60278];\nvar M87 = [0.19444, 0.69444, 0, 0, 0.51111];\nvar M88 = [0, 0.69444, 0, 0, 0.83055];\nvar M89 = [-0.10889, 0.39111, 0, 0, 1.14999];\nvar M90 = [0.19444, 0.69444, 0, 0, 0.575];\nvar M91 = [0.19444, 0.69444, 0, 0, 1.14999];\nvar M92 = [0.19444, 0.69444, 0, 0, 0.70277];\nvar M93 = [0.05556, 0.75, 0, 0, 0.575];\nvar M94 = [0, 0.68611, 0, 0, 0.95833];\nvar M95 = [0.08556, 0.58556, 0, 0, 0.76666];\nvar M96 = [-0.02639, 0.47361, 0, 0, 0.575];\nvar M97 = [0, 0.44444, 0, 0, 0.89444];\nvar M98 = [0, 0.55556, 0, 0, 0.76666];\nvar M99 = [-0.10889, 0.39111, 0, 0, 0.89444];\nvar M100 = [222e-5, 0.50222, 0, 0, 0.89444];\nvar M101 = [0.19667, 0.69667, 0, 0, 0.89444];\nvar M102 = [0.08556, 0.58556, 0, 0, 1.14999];\nvar M103 = [0, 0.69444, 0, 0, 0.70277];\nvar M104 = [-0.02778, 0.47222, 0, 0, 0.575];\nvar M105 = [0.25, 0.75, 0, 0, 0.51111];\nvar M106 = [-0.13889, 0.36111, 0, 0, 1.14999];\nvar M107 = [0.19444, 0.69444, 0, 0, 1.02222];\nvar M108 = [0.12963, 0.69444, 0, 0, 0.89444];\nvar M109 = [0.19444, 0.69444, 0, 0, 0.44722];\nvar M110 = [0, 0.64444, 0.13167, 0, 0.59111];\nvar M111 = [0.19444, 0.64444, 0.13167, 0, 0.59111];\nvar M112 = [0, 0.68611, 0.17208, 0, 0.8961];\nvar M113 = [0.19444, 0.44444, 0.105, 0, 0.53222];\nvar M114 = [0, 0.44444, 0.085, 0, 0.82666];\nvar M115 = [0, 0.69444, 0.06709, 0, 0.59111];\nvar M116 = [0, 0.69444, 0.12945, 0, 0.35555];\nvar M117 = [0, 0.69444, 0, 0, 0.94888];\nvar M118 = [0, 0.69444, 0.11472, 0, 0.59111];\nvar M119 = [0, 0.68611, 0.10778, 0, 0.88555];\nvar M120 = [0, 0.69444, 0.07939, 0, 0.62055];\nvar M121 = [0, 0.69444, 0.12417, 0, 0.30667];\nvar M122 = [0, 0.64444, 0.13556, 0, 0.51111];\nvar M123 = [0.19444, 0.64444, 0.13556, 0, 0.51111];\nvar M124 = [0, 0.68333, 0.16389, 0, 0.74333];\nvar M125 = [0.19444, 0.43056, 0.08847, 0, 0.46];\nvar M126 = [0, 0.43056, 0.07514, 0, 0.71555];\nvar M127 = [0, 0.69444, 0.06646, 0, 0.51111];\nvar M128 = [0, 0.69444, 0, 0, 0.83129];\nvar M129 = [0, 0.69444, 0.1225, 0, 0.51111];\nvar M130 = [0, 0.68333, 0.09403, 0, 0.76666];\nvar M131 = [0, 0.68333, 0.11111, 0, 0.76666];\nvar M132 = [0, 0.69444, 0.06961, 0, 0.51444];\nvar M133 = [0, 0.69444, 0, 0, 0.27778];\nvar M134 = [0.25, 0.75, 0, 0, 0.38889];\nvar M135 = [0, 0.64444, 0, 0, 0.5];\nvar M136 = [0, 0.69444, 0, 0, 0.77778];\nvar M137 = [0, 0.68333, 0, 0, 0.75];\nvar M138 = [0, 0.68333, 0, 0, 0.77778];\nvar M139 = [0, 0.68333, 0, 0, 0.68056];\nvar M140 = [0, 0.68333, 0, 0, 0.72222];\nvar M141 = [0.25, 0.75, 0, 0, 0.5];\nvar M142 = [0.25, 0.75, 0, 0, 0.27778];\nvar M143 = [0, 0.69444, 0, 0, 0.5];\nvar M144 = [0, 0.69444, 0, 0, 0.55556];\nvar M145 = [0, 0.43056, 0, 0, 0.44445];\nvar M146 = [0, 0.43056, 0, 0, 0.5];\nvar M147 = [0.19444, 0.43056, 0, 0, 0.55556];\nvar M148 = [0, 0.43056, 0, 0, 0.55556];\nvar M149 = [0.08333, 0.58333, 0, 0, 0.77778];\nvar M150 = [0, 0.43056, 0, 0, 0.27778];\nvar M151 = [0, 0.66786, 0, 0, 0.27778];\nvar M152 = [0, 0.69444, 0, 0, 0.75];\nvar M153 = [0, 0.66786, 0, 0, 0.5];\nvar M154 = [0, 0.68333, 0, 0, 0.625];\nvar M155 = [0.19444, 0.69444, 0, 0, 0.44445];\nvar M156 = [0, 0.69444, 0, 0, 0.72222];\nvar M157 = [0.19444, 0.69444, 0, 0, 0.5];\nvar M158 = [0.19444, 0.69444, 0, 0, 1];\nvar M159 = [0.011, 0.511, 0, 0, 1.126];\nvar M160 = [0.19444, 0.69444, 0, 0, 0.61111];\nvar M161 = [0.05556, 0.75, 0, 0, 0.5];\nvar M162 = [0, 0.68333, 0, 0, 0.83334];\nvar M163 = [0.0391, 0.5391, 0, 0, 0.66667];\nvar M164 = [-0.05555, 0.44445, 0, 0, 0.5];\nvar M165 = [0, 0.43056, 0, 0, 0.77778];\nvar M166 = [0, 0.55556, 0, 0, 0.66667];\nvar M167 = [-0.03625, 0.46375, 0, 0, 0.77778];\nvar M168 = [-0.01688, 0.48312, 0, 0, 0.77778];\nvar M169 = [0.0391, 0.5391, 0, 0, 1];\nvar M170 = [0, 0.69444, 0, 0, 0.61111];\nvar M171 = [-0.03472, 0.46528, 0, 0, 0.5];\nvar M172 = [0.25, 0.75, 0, 0, 0.44445];\nvar M173 = [-0.14236, 0.35764, 0, 0, 1];\nvar M174 = [0.244, 0.744, 0, 0, 0.412];\nvar M175 = [0.19444, 0.69444, 0, 0, 0.88889];\nvar M176 = [0.12963, 0.69444, 0, 0, 0.77778];\nvar M177 = [0.19444, 0.69444, 0, 0, 0.38889];\nvar M178 = [0.011, 0.511, 0, 0, 1.638];\nvar M179 = [0.19444, 0.69444, 0, 0, 0];\nvar M180 = [0, 0.44444, 0, 0, 0.575];\nvar M181 = [0.19444, 0.44444, 0, 0, 0.575];\nvar M182 = [0, 0.68611, 0, 0, 0.75555];\nvar M183 = [0, 0.69444, 0, 0, 0.66759];\nvar M184 = [0, 0.68611, 0, 0, 0.80555];\nvar M185 = [0, 0.68611, 0.08229, 0, 0.98229];\nvar M186 = [0, 0.68611, 0, 0, 0.76666];\nvar M187 = [0, 0.44444, 0, 0, 0.58472];\nvar M188 = [0.19444, 0.44444, 0, 0, 0.6118];\nvar M189 = [0.19444, 0.43056, 0, 0, 0.5];\nvar M190 = [0, 0.68333, 0.02778, 0.08334, 0.76278];\nvar M191 = [0, 0.68333, 0.08125, 0.05556, 0.83125];\nvar M192 = [0, 0.43056, 0, 0.05556, 0.48472];\nvar M193 = [0.19444, 0.43056, 0, 0.08334, 0.51702];\nvar M194 = [0.25, 0.75, 0, 0, 0.42778];\nvar M195 = [0, 0.69444, 0, 0, 0.55];\nvar M196 = [0, 0.69444, 0, 0, 0.73334];\nvar M197 = [0, 0.69444, 0, 0, 0.79445];\nvar M198 = [0, 0.69444, 0, 0, 0.51945];\nvar M199 = [0, 0.69444, 0, 0, 0.70278];\nvar M200 = [0, 0.69444, 0, 0, 0.76389];\nvar M201 = [0.25, 0.75, 0, 0, 0.34306];\nvar M202 = [0, 0.69444, 0, 0, 0.56111];\nvar M203 = [0, 0.69444, 0, 0, 0.25556];\nvar M204 = [0.19444, 0.45833, 0, 0, 0.56111];\nvar M205 = [0, 0.45833, 0, 0, 0.56111];\nvar M206 = [0, 0.69444, 0, 0, 0.30556];\nvar M207 = [0, 0.69444, 0, 0, 0.58056];\nvar M208 = [0, 0.69444, 0, 0, 0.67223];\nvar M209 = [0, 0.69444, 0, 0, 0.85556];\nvar M210 = [0, 0.69444, 0, 0, 0.55834];\nvar M211 = [0, 0.65556, 0.11156, 0, 0.5];\nvar M212 = [0, 0.69444, 0.08094, 0, 0.70834];\nvar M213 = [0.17014, 0, 0, 0, 0.44445];\nvar M214 = [0, 0.69444, 0.0799, 0, 0.5];\nvar M215 = [0, 0.69444, 0, 0, 0.73752];\nvar M216 = [0, 0.69444, 0.09205, 0, 0.5];\nvar M217 = [0, 0.69444, 0.09031, 0, 0.77778];\nvar M218 = [0, 0.69444, 0.07816, 0, 0.27778];\nvar M219 = [0, 0.69444, 316e-5, 0, 0.5];\nvar M220 = [0.19444, 0.69444, 0, 0, 0.83334];\nvar M221 = [0.05556, 0.75, 0, 0, 0.83334];\nvar M222 = [0, 0.75, 0, 0, 0.5];\nvar M223 = [0.125, 0.08333, 0, 0, 0.27778];\nvar M224 = [0, 0.08333, 0, 0, 0.27778];\nvar M225 = [0, 0.65556, 0, 0, 0.5];\nvar M226 = [0, 0.69444, 0, 0, 0.47222];\nvar M227 = [0, 0.69444, 0, 0, 0.66667];\nvar M228 = [0, 0.69444, 0, 0, 0.59722];\nvar M229 = [0, 0.69444, 0, 0, 0.54167];\nvar M230 = [0, 0.69444, 0, 0, 0.70834];\nvar M231 = [0.25, 0.75, 0, 0, 0.28889];\nvar M232 = [0, 0.69444, 0, 0, 0.51667];\nvar M233 = [0, 0.44444, 0, 0, 0.44445];\nvar M234 = [0.19444, 0.44444, 0, 0, 0.51667];\nvar M235 = [0, 0.44444, 0, 0, 0.38333];\nvar M236 = [0, 0.44444, 0, 0, 0.51667];\nvar M237 = [0, 0.69444, 0, 0, 0.83334];\nvar M238 = [0.35001, 0.85, 0, 0, 0.45834];\nvar M239 = [0.35001, 0.85, 0, 0, 0.57778];\nvar M240 = [0.35001, 0.85, 0, 0, 0.41667];\nvar M241 = [0.35001, 0.85, 0, 0, 0.58334];\nvar M242 = [0, 0.72222, 0, 0, 0.55556];\nvar M243 = [1e-5, 0.6, 0, 0, 0.66667];\nvar M244 = [1e-5, 0.6, 0, 0, 0.77778];\nvar M245 = [0.25001, 0.75, 0, 0, 0.94445];\nvar M246 = [0.306, 0.805, 0.19445, 0, 0.47222];\nvar M247 = [0.30612, 0.805, 0.19445, 0, 0.47222];\nvar M248 = [0.25001, 0.75, 0, 0, 0.83334];\nvar M249 = [0.35001, 0.85, 0, 0, 0.47222];\nvar M250 = [0.25001, 0.75, 0, 0, 1.11111];\nvar M251 = [0.65002, 1.15, 0, 0, 0.59722];\nvar M252 = [0.65002, 1.15, 0, 0, 0.81111];\nvar M253 = [0.65002, 1.15, 0, 0, 0.47222];\nvar M254 = [0.65002, 1.15, 0, 0, 0.66667];\nvar M255 = [0, 0.75, 0, 0, 1];\nvar M256 = [0.55001, 1.05, 0, 0, 1.27778];\nvar M257 = [0.862, 1.36, 0.44445, 0, 0.55556];\nvar M258 = [0.86225, 1.36, 0.44445, 0, 0.55556];\nvar M259 = [0.55001, 1.05, 0, 0, 1.11111];\nvar M260 = [0.65002, 1.15, 0, 0, 0.52778];\nvar M261 = [0.65002, 1.15, 0, 0, 0.61111];\nvar M262 = [0.55001, 1.05, 0, 0, 1.51112];\nvar M263 = [0.95003, 1.45, 0, 0, 0.73611];\nvar M264 = [0.95003, 1.45, 0, 0, 1.04445];\nvar M265 = [0.95003, 1.45, 0, 0, 0.52778];\nvar M266 = [0.95003, 1.45, 0, 0, 0.75];\nvar M267 = [0, 0.75, 0, 0, 1.44445];\nvar M268 = [0.95003, 1.45, 0, 0, 0.58334];\nvar M269 = [1.25003, 1.75, 0, 0, 0.79167];\nvar M270 = [1.25003, 1.75, 0, 0, 1.27778];\nvar M271 = [1.25003, 1.75, 0, 0, 0.58334];\nvar M272 = [1.25003, 1.75, 0, 0, 0.80556];\nvar M273 = [0, 0.825, 0, 0, 1.8889];\nvar M274 = [1.25003, 1.75, 0, 0, 0.63889];\nvar M275 = [0.64502, 1.155, 0, 0, 0.875];\nvar M276 = [1e-5, 0.6, 0, 0, 0.875];\nvar M277 = [-99e-5, 0.601, 0, 0, 0.66667];\nvar M278 = [0.64502, 1.155, 0, 0, 0.66667];\nvar M279 = [1e-5, 0.9, 0, 0, 0.88889];\nvar M280 = [0.65002, 1.15, 0, 0, 0.88889];\nvar M281 = [0.90001, 0, 0, 0, 0.88889];\nvar M282 = [-499e-5, 0.605, 0, 0, 1.05556];\nvar M283 = [0, 0.12, 0, 0, 0.45];\nvar M284 = [0, 0.61111, 0, 0, 0.525];\nvar M285 = [0.08333, 0.69444, 0, 0, 0.525];\nvar M286 = [-0.08056, 0.53055, 0, 0, 0.525];\nvar M287 = [-0.05556, 0.55556, 0, 0, 0.525];\nvar M288 = [0, 0.43056, 0, 0, 0.525];\nvar M289 = [0.22222, 0.43056, 0, 0, 0.525];\nvar M290 = [0, 0, 0, 0, 0.525];\nvar font_metrics_data_default = {\n  \"AMS-Regular\": {\n    32: M7,\n    // U+0020\n    65: M1,\n    // U+0041 A\n    66: M2,\n    // U+0042 B\n    67: M1,\n    // U+0043 C\n    68: M1,\n    // U+0044 D\n    69: M2,\n    // U+0045 E\n    70: M4,\n    // U+0046 F\n    71: M3,\n    // U+0047 G\n    72: M3,\n    // U+0048 H\n    73: [0, 0.68889, 0, 0, 0.38889],\n    // U+0049 I\n    74: [0.16667, 0.68889, 0, 0, 0.5],\n    // U+004a J\n    75: M3,\n    // U+004b K\n    76: M2,\n    // U+004c L\n    77: [0, 0.68889, 0, 0, 0.94445],\n    // U+004d M\n    78: M1,\n    // U+004e N\n    79: M5,\n    // U+004f O\n    80: M4,\n    // U+0050 P\n    81: M5,\n    // U+0051 Q\n    82: M1,\n    // U+0052 R\n    83: M6,\n    // U+0053 S\n    84: M2,\n    // U+0054 T\n    85: M1,\n    // U+0055 U\n    86: M1,\n    // U+0056 V\n    87: [0, 0.68889, 0, 0, 1],\n    // U+0057 W\n    88: M1,\n    // U+0058 X\n    89: M1,\n    // U+0059 Y\n    90: M2,\n    // U+005a Z\n    107: M6,\n    // U+006b k\n    160: M7,\n    // U+00a0\n    165: [0, 0.675, 0.025, 0, 0.75],\n    // U+00a5 ¥\n    174: [0.15559, 0.69224, 0, 0, 0.94666],\n    // U+00ae ®\n    240: M6,\n    // U+00f0 ð\n    295: M10,\n    // U+0127 ħ\n    710: M8,\n    // U+02c6 ˆ\n    732: M9,\n    // U+02dc ˜\n    770: M8,\n    // U+0302 ̂\n    771: M9,\n    // U+0303 ̃\n    989: M24,\n    // U+03dd ϝ\n    1008: M57,\n    // U+03f0 ϰ\n    8245: [0, 0.54986, 0, 0, 0.275],\n    // U+2035 ‵\n    8463: M10,\n    // U+210f ℏ\n    8487: M1,\n    // U+2127 ℧\n    8498: M6,\n    // U+2132 Ⅎ\n    8502: M2,\n    // U+2136 ℶ\n    8503: [0, 0.68889, 0, 0, 0.44445],\n    // U+2137 ℷ\n    8504: M2,\n    // U+2138 ℸ\n    8513: [0, 0.68889, 0, 0, 0.63889],\n    // U+2141 ⅁\n    8592: M11,\n    // U+2190 ←\n    8594: M11,\n    // U+2192 →\n    8602: M12,\n    // U+219a ↚\n    8603: M12,\n    // U+219b ↛\n    8606: M13,\n    // U+219e ↞\n    8608: M13,\n    // U+21a0 ↠\n    8610: M14,\n    // U+21a2 ↢\n    8611: M14,\n    // U+21a3 ↣\n    8619: M15,\n    // U+21ab ↫\n    8620: M15,\n    // U+21ac ↬\n    8621: [-0.13313, 0.37788, 0, 0, 1.38889],\n    // U+21ad ↭\n    8622: M12,\n    // U+21ae ↮\n    8624: M16,\n    // U+21b0 ↰\n    8625: M16,\n    // U+21b1 ↱\n    8630: M17,\n    // U+21b6 ↶\n    8631: M17,\n    // U+21b7 ↷\n    8634: M18,\n    // U+21ba ↺\n    8635: M18,\n    // U+21bb ↻\n    8638: M19,\n    // U+21be ↾\n    8639: M19,\n    // U+21bf ↿\n    8642: M19,\n    // U+21c2 ⇂\n    8643: M19,\n    // U+21c3 ⇃\n    8644: M20,\n    // U+21c4 ⇄\n    8646: M20,\n    // U+21c6 ⇆\n    8647: M20,\n    // U+21c7 ⇇\n    8648: M21,\n    // U+21c8 ⇈\n    8649: M20,\n    // U+21c9 ⇉\n    8650: M21,\n    // U+21ca ⇊\n    8651: M13,\n    // U+21cb ⇋\n    8652: M13,\n    // U+21cc ⇌\n    8653: M12,\n    // U+21cd ⇍\n    8654: M12,\n    // U+21ce ⇎\n    8655: M12,\n    // U+21cf ⇏\n    8666: M22,\n    // U+21da ⇚\n    8667: M22,\n    // U+21db ⇛\n    8669: [-0.13313, 0.37788, 0, 0, 1],\n    // U+21dd ⇝\n    8672: M23,\n    // U+21e0 ⇠\n    8674: M23,\n    // U+21e2 ⇢\n    8705: [0, 0.825, 0, 0, 0.5],\n    // U+2201 ∁\n    8708: M6,\n    // U+2204 ∄\n    8709: M24,\n    // U+2205 ∅\n    8717: [0, 0.43056, 0, 0, 0.42917],\n    // U+220d ∍\n    8722: M11,\n    // U+2212 −\n    8724: [0.08198, 0.69224, 0, 0, 0.77778],\n    // U+2214 ∔\n    8726: M24,\n    // U+2216 ∖\n    8733: M29,\n    // U+221d ∝\n    8736: M25,\n    // U+2220 ∠\n    8737: M25,\n    // U+2221 ∡\n    8738: [0.03517, 0.52239, 0, 0, 0.72222],\n    // U+2222 ∢\n    8739: M55,\n    // U+2223 ∣\n    8740: [0.25142, 0.74111, 0, 0, 0.27778],\n    // U+2224 ∤\n    8741: M56,\n    // U+2225 ∥\n    8742: [0.25142, 0.74111, 0, 0, 0.5],\n    // U+2226 ∦\n    8756: M26,\n    // U+2234 ∴\n    8757: M26,\n    // U+2235 ∵\n    8764: M27,\n    // U+223c ∼\n    8765: [-0.13313, 0.37788, 0, 0, 0.77778],\n    // U+223d ∽\n    8769: M27,\n    // U+2241 ≁\n    8770: M167,\n    // U+2242 ≂\n    8774: M33,\n    // U+2246 ≆\n    8776: M168,\n    // U+2248 ≈\n    8778: M24,\n    // U+224a ≊\n    8782: M28,\n    // U+224e ≎\n    8783: M28,\n    // U+224f ≏\n    8785: M18,\n    // U+2251 ≑\n    8786: M18,\n    // U+2252 ≒\n    8787: M18,\n    // U+2253 ≓\n    8790: M29,\n    // U+2256 ≖\n    8791: M34,\n    // U+2257 ≗\n    8796: [0.08198, 0.91667, 0, 0, 0.77778],\n    // U+225c ≜\n    8806: M30,\n    // U+2266 ≦\n    8807: M30,\n    // U+2267 ≧\n    8808: M31,\n    // U+2268 ≨\n    8809: M31,\n    // U+2269 ≩\n    8812: [0.25583, 0.75583, 0, 0, 0.5],\n    // U+226c ≬\n    8814: M32,\n    // U+226e ≮\n    8815: M32,\n    // U+226f ≯\n    8816: M33,\n    // U+2270 ≰\n    8817: M33,\n    // U+2271 ≱\n    8818: M34,\n    // U+2272 ≲\n    8819: M34,\n    // U+2273 ≳\n    8822: M35,\n    // U+2276 ≶\n    8823: M35,\n    // U+2277 ≷\n    8828: M36,\n    // U+227c ≼\n    8829: M36,\n    // U+227d ≽\n    8830: M34,\n    // U+227e ≾\n    8831: M34,\n    // U+227f ≿\n    8832: M32,\n    // U+2280 ⊀\n    8833: M32,\n    // U+2281 ⊁\n    8840: M33,\n    // U+2288 ⊈\n    8841: M33,\n    // U+2289 ⊉\n    8842: M37,\n    // U+228a ⊊\n    8843: M37,\n    // U+228b ⊋\n    8847: M38,\n    // U+228f ⊏\n    8848: M38,\n    // U+2290 ⊐\n    8858: M18,\n    // U+229a ⊚\n    8859: M18,\n    // U+229b ⊛\n    8861: M18,\n    // U+229d ⊝\n    8862: M39,\n    // U+229e ⊞\n    8863: M39,\n    // U+229f ⊟\n    8864: M39,\n    // U+22a0 ⊠\n    8865: M39,\n    // U+22a1 ⊡\n    8872: [0, 0.69224, 0, 0, 0.61111],\n    // U+22a8 ⊨\n    8873: M25,\n    // U+22a9 ⊩\n    8874: [0, 0.69224, 0, 0, 0.88889],\n    // U+22aa ⊪\n    8876: M4,\n    // U+22ac ⊬\n    8877: M4,\n    // U+22ad ⊭\n    8878: M1,\n    // U+22ae ⊮\n    8879: M1,\n    // U+22af ⊯\n    8882: M38,\n    // U+22b2 ⊲\n    8883: M38,\n    // U+22b3 ⊳\n    8884: M36,\n    // U+22b4 ⊴\n    8885: M36,\n    // U+22b5 ⊵\n    8888: [0, 0.54986, 0, 0, 1.11111],\n    // U+22b8 ⊸\n    8890: M147,\n    // U+22ba ⊺\n    8891: M40,\n    // U+22bb ⊻\n    8892: M40,\n    // U+22bc ⊼\n    8901: [0, 0.54986, 0, 0, 0.27778],\n    // U+22c5 ⋅\n    8903: M24,\n    // U+22c7 ⋇\n    8905: M24,\n    // U+22c9 ⋉\n    8906: M24,\n    // U+22ca ⋊\n    8907: M29,\n    // U+22cb ⋋\n    8908: M29,\n    // U+22cc ⋌\n    8909: [-0.03598, 0.46402, 0, 0, 0.77778],\n    // U+22cd ⋍\n    8910: M41,\n    // U+22ce ⋎\n    8911: M41,\n    // U+22cf ⋏\n    8912: M38,\n    // U+22d0 ⋐\n    8913: M38,\n    // U+22d1 ⋑\n    8914: M42,\n    // U+22d2 ⋒\n    8915: M42,\n    // U+22d3 ⋓\n    8916: M26,\n    // U+22d4 ⋔\n    8918: M43,\n    // U+22d6 ⋖\n    8919: M43,\n    // U+22d7 ⋗\n    8920: M44,\n    // U+22d8 ⋘\n    8921: M44,\n    // U+22d9 ⋙\n    8922: M45,\n    // U+22da ⋚\n    8923: M45,\n    // U+22db ⋛\n    8926: M36,\n    // U+22de ⋞\n    8927: M36,\n    // U+22df ⋟\n    8928: M33,\n    // U+22e0 ⋠\n    8929: M33,\n    // U+22e1 ⋡\n    8934: M46,\n    // U+22e6 ⋦\n    8935: M46,\n    // U+22e7 ⋧\n    8936: M46,\n    // U+22e8 ⋨\n    8937: M46,\n    // U+22e9 ⋩\n    8938: M32,\n    // U+22ea ⋪\n    8939: M32,\n    // U+22eb ⋫\n    8940: M33,\n    // U+22ec ⋬\n    8941: M33,\n    // U+22ed ⋭\n    8994: M47,\n    // U+2322 ⌢\n    8995: M47,\n    // U+2323 ⌣\n    9416: [0.15559, 0.69224, 0, 0, 0.90222],\n    // U+24c8 Ⓢ\n    9484: M16,\n    // U+250c ┌\n    9488: M16,\n    // U+2510 ┐\n    9492: M48,\n    // U+2514 └\n    9496: M48,\n    // U+2518 ┘\n    9585: [0.19444, 0.68889, 0, 0, 0.88889],\n    // U+2571 ╱\n    9586: [0.19444, 0.74111, 0, 0, 0.88889],\n    // U+2572 ╲\n    9632: M39,\n    // U+25a0 ■\n    9633: M39,\n    // U+25a1 □\n    9650: M49,\n    // U+25b2 ▲\n    9651: M49,\n    // U+25b3 △\n    9654: M38,\n    // U+25b6 ▶\n    9660: M49,\n    // U+25bc ▼\n    9661: M49,\n    // U+25bd ▽\n    9664: M38,\n    // U+25c0 ◀\n    9674: M51,\n    // U+25ca ◊\n    9733: [0.19444, 0.69224, 0, 0, 0.94445],\n    // U+2605 ★\n    10003: M50,\n    // U+2713 ✓\n    10016: M50,\n    // U+2720 ✠\n    10731: M51,\n    // U+29eb ⧫\n    10846: [0.19444, 0.75583, 0, 0, 0.61111],\n    // U+2a5e ⩞\n    10877: M36,\n    // U+2a7d ⩽\n    10878: M36,\n    // U+2a7e ⩾\n    10885: M30,\n    // U+2a85 ⪅\n    10886: M30,\n    // U+2a86 ⪆\n    10887: M37,\n    // U+2a87 ⪇\n    10888: M37,\n    // U+2a88 ⪈\n    10889: M52,\n    // U+2a89 ⪉\n    10890: M52,\n    // U+2a8a ⪊\n    10891: M53,\n    // U+2a8b ⪋\n    10892: M53,\n    // U+2a8c ⪌\n    10901: M36,\n    // U+2a95 ⪕\n    10902: M36,\n    // U+2a96 ⪖\n    10933: M31,\n    // U+2ab5 ⪵\n    10934: M31,\n    // U+2ab6 ⪶\n    10935: M52,\n    // U+2ab7 ⪷\n    10936: M52,\n    // U+2ab8 ⪸\n    10937: M52,\n    // U+2ab9 ⪹\n    10938: M52,\n    // U+2aba ⪺\n    10949: M30,\n    // U+2ac5 ⫅\n    10950: M30,\n    // U+2ac6 ⫆\n    10955: M54,\n    // U+2acb ⫋\n    10956: M54,\n    // U+2acc ⫌\n    57350: M55,\n    // U+e006 \n    57351: M56,\n    // U+e007 \n    57352: M24,\n    // U+e008 \n    57353: M57,\n    // U+e009 \n    57356: M31,\n    // U+e00c \n    57357: M31,\n    // U+e00d \n    57358: M58,\n    // U+e00e \n    57359: M33,\n    // U+e00f \n    57360: M33,\n    // U+e010 \n    57361: M58,\n    // U+e011 \n    57366: M31,\n    // U+e016 \n    57367: M31,\n    // U+e017 \n    57368: M31,\n    // U+e018 \n    57369: M31,\n    // U+e019 \n    57370: M37,\n    // U+e01a \n    57371: M37\n    // U+e01b \n  },\n  \"Caligraphic-Regular\": {\n    32: M7,\n    // U+0020\n    65: [0, 0.68333, 0, 0.19445, 0.79847],\n    // U+0041 A\n    66: [0, 0.68333, 0.03041, 0.13889, 0.65681],\n    // U+0042 B\n    67: [0, 0.68333, 0.05834, 0.13889, 0.52653],\n    // U+0043 C\n    68: [0, 0.68333, 0.02778, 0.08334, 0.77139],\n    // U+0044 D\n    69: [0, 0.68333, 0.08944, 0.11111, 0.52778],\n    // U+0045 E\n    70: [0, 0.68333, 0.09931, 0.11111, 0.71875],\n    // U+0046 F\n    71: [0.09722, 0.68333, 0.0593, 0.11111, 0.59487],\n    // U+0047 G\n    72: [0, 0.68333, 965e-5, 0.11111, 0.84452],\n    // U+0048 H\n    73: [0, 0.68333, 0.07382, 0, 0.54452],\n    // U+0049 I\n    74: [0.09722, 0.68333, 0.18472, 0.16667, 0.67778],\n    // U+004a J\n    75: [0, 0.68333, 0.01445, 0.05556, 0.76195],\n    // U+004b K\n    76: [0, 0.68333, 0, 0.13889, 0.68972],\n    // U+004c L\n    77: [0, 0.68333, 0, 0.13889, 1.2009],\n    // U+004d M\n    78: [0, 0.68333, 0.14736, 0.08334, 0.82049],\n    // U+004e N\n    79: [0, 0.68333, 0.02778, 0.11111, 0.79611],\n    // U+004f O\n    80: [0, 0.68333, 0.08222, 0.08334, 0.69556],\n    // U+0050 P\n    81: [0.09722, 0.68333, 0, 0.11111, 0.81667],\n    // U+0051 Q\n    82: [0, 0.68333, 0, 0.08334, 0.8475],\n    // U+0052 R\n    83: [0, 0.68333, 0.075, 0.13889, 0.60556],\n    // U+0053 S\n    84: [0, 0.68333, 0.25417, 0, 0.54464],\n    // U+0054 T\n    85: [0, 0.68333, 0.09931, 0.08334, 0.62583],\n    // U+0055 U\n    86: [0, 0.68333, 0.08222, 0, 0.61278],\n    // U+0056 V\n    87: [0, 0.68333, 0.08222, 0.08334, 0.98778],\n    // U+0057 W\n    88: [0, 0.68333, 0.14643, 0.13889, 0.7133],\n    // U+0058 X\n    89: [0.09722, 0.68333, 0.08222, 0.08334, 0.66834],\n    // U+0059 Y\n    90: [0, 0.68333, 0.07944, 0.13889, 0.72473],\n    // U+005a Z\n    160: M7\n    // U+00a0\n  },\n  \"Fraktur-Regular\": {\n    32: M7,\n    // U+0020\n    33: [0, 0.69141, 0, 0, 0.29574],\n    // U+0021 !\n    34: M66,\n    // U+0022 \"\n    38: [0, 0.69141, 0, 0, 0.73786],\n    // U+0026 &\n    39: [0, 0.69141, 0, 0, 0.21201],\n    // U+0027 '\n    40: M59,\n    // U+0028 (\n    41: M59,\n    // U+0029 )\n    42: [0, 0.62119, 0, 0, 0.27764],\n    // U+002a *\n    43: M60,\n    // U+002b +\n    44: M61,\n    // U+002c ,\n    45: M60,\n    // U+002d -\n    46: M61,\n    // U+002e .\n    47: [0.24982, 0.74947, 0, 0, 0.50181],\n    // U+002f /\n    48: M62,\n    // U+0030 0\n    49: M62,\n    // U+0031 1\n    50: M62,\n    // U+0032 2\n    51: M63,\n    // U+0033 3\n    52: M63,\n    // U+0034 4\n    53: M63,\n    // U+0035 5\n    54: M64,\n    // U+0036 6\n    55: M63,\n    // U+0037 7\n    56: M64,\n    // U+0038 8\n    57: M63,\n    // U+0039 9\n    58: [0, 0.47534, 0, 0, 0.21606],\n    // U+003a :\n    59: [0.12604, 0.47534, 0, 0, 0.21606],\n    // U+003b ;\n    61: [-0.13099, 0.36866, 0, 0, 0.75623],\n    // U+003d =\n    63: [0, 0.69141, 0, 0, 0.36245],\n    // U+003f ?\n    65: [0, 0.69141, 0, 0, 0.7176],\n    // U+0041 A\n    66: [0, 0.69141, 0, 0, 0.88397],\n    // U+0042 B\n    67: [0, 0.69141, 0, 0, 0.61254],\n    // U+0043 C\n    68: [0, 0.69141, 0, 0, 0.83158],\n    // U+0044 D\n    69: [0, 0.69141, 0, 0, 0.66278],\n    // U+0045 E\n    70: [0.12604, 0.69141, 0, 0, 0.61119],\n    // U+0046 F\n    71: [0, 0.69141, 0, 0, 0.78539],\n    // U+0047 G\n    72: [0.06302, 0.69141, 0, 0, 0.7203],\n    // U+0048 H\n    73: [0, 0.69141, 0, 0, 0.55448],\n    // U+0049 I\n    74: [0.12604, 0.69141, 0, 0, 0.55231],\n    // U+004a J\n    75: [0, 0.69141, 0, 0, 0.66845],\n    // U+004b K\n    76: [0, 0.69141, 0, 0, 0.66602],\n    // U+004c L\n    77: [0, 0.69141, 0, 0, 1.04953],\n    // U+004d M\n    78: [0, 0.69141, 0, 0, 0.83212],\n    // U+004e N\n    79: [0, 0.69141, 0, 0, 0.82699],\n    // U+004f O\n    80: [0.18906, 0.69141, 0, 0, 0.82753],\n    // U+0050 P\n    81: [0.03781, 0.69141, 0, 0, 0.82699],\n    // U+0051 Q\n    82: [0, 0.69141, 0, 0, 0.82807],\n    // U+0052 R\n    83: [0, 0.69141, 0, 0, 0.82861],\n    // U+0053 S\n    84: [0, 0.69141, 0, 0, 0.66899],\n    // U+0054 T\n    85: [0, 0.69141, 0, 0, 0.64576],\n    // U+0055 U\n    86: [0, 0.69141, 0, 0, 0.83131],\n    // U+0056 V\n    87: [0, 0.69141, 0, 0, 1.04602],\n    // U+0057 W\n    88: [0, 0.69141, 0, 0, 0.71922],\n    // U+0058 X\n    89: [0.18906, 0.69141, 0, 0, 0.83293],\n    // U+0059 Y\n    90: [0.12604, 0.69141, 0, 0, 0.60201],\n    // U+005a Z\n    91: M65,\n    // U+005b [\n    93: M65,\n    // U+005d ]\n    94: [0, 0.69141, 0, 0, 0.49965],\n    // U+005e ^\n    97: [0, 0.47534, 0, 0, 0.50046],\n    // U+0061 a\n    98: [0, 0.69141, 0, 0, 0.51315],\n    // U+0062 b\n    99: [0, 0.47534, 0, 0, 0.38946],\n    // U+0063 c\n    100: [0, 0.62119, 0, 0, 0.49857],\n    // U+0064 d\n    101: [0, 0.47534, 0, 0, 0.40053],\n    // U+0065 e\n    102: [0.18906, 0.69141, 0, 0, 0.32626],\n    // U+0066 f\n    103: [0.18906, 0.47534, 0, 0, 0.5037],\n    // U+0067 g\n    104: [0.18906, 0.69141, 0, 0, 0.52126],\n    // U+0068 h\n    105: [0, 0.69141, 0, 0, 0.27899],\n    // U+0069 i\n    106: [0, 0.69141, 0, 0, 0.28088],\n    // U+006a j\n    107: [0, 0.69141, 0, 0, 0.38946],\n    // U+006b k\n    108: [0, 0.69141, 0, 0, 0.27953],\n    // U+006c l\n    109: [0, 0.47534, 0, 0, 0.76676],\n    // U+006d m\n    110: [0, 0.47534, 0, 0, 0.52666],\n    // U+006e n\n    111: [0, 0.47534, 0, 0, 0.48885],\n    // U+006f o\n    112: [0.18906, 0.52396, 0, 0, 0.50046],\n    // U+0070 p\n    113: [0.18906, 0.47534, 0, 0, 0.48912],\n    // U+0071 q\n    114: [0, 0.47534, 0, 0, 0.38919],\n    // U+0072 r\n    115: [0, 0.47534, 0, 0, 0.44266],\n    // U+0073 s\n    116: [0, 0.62119, 0, 0, 0.33301],\n    // U+0074 t\n    117: [0, 0.47534, 0, 0, 0.5172],\n    // U+0075 u\n    118: [0, 0.52396, 0, 0, 0.5118],\n    // U+0076 v\n    119: [0, 0.52396, 0, 0, 0.77351],\n    // U+0077 w\n    120: [0.18906, 0.47534, 0, 0, 0.38865],\n    // U+0078 x\n    121: [0.18906, 0.47534, 0, 0, 0.49884],\n    // U+0079 y\n    122: [0.18906, 0.47534, 0, 0, 0.39054],\n    // U+007a z\n    160: M7,\n    // U+00a0\n    8216: M66,\n    // U+2018 ‘\n    8217: M66,\n    // U+2019 ’\n    58112: [0, 0.62119, 0, 0, 0.49749],\n    // U+e300 \n    58113: [0, 0.62119, 0, 0, 0.4983],\n    // U+e301 \n    58114: [0.18906, 0.69141, 0, 0, 0.33328],\n    // U+e302 \n    58115: [0.18906, 0.69141, 0, 0, 0.32923],\n    // U+e303 \n    58116: [0.18906, 0.47534, 0, 0, 0.50343],\n    // U+e304 \n    58117: [0, 0.69141, 0, 0, 0.33301],\n    // U+e305 \n    58118: [0, 0.62119, 0, 0, 0.33409],\n    // U+e306 \n    58119: [0, 0.47534, 0, 0, 0.50073]\n    // U+e307 \n  },\n  \"Main-Bold\": {\n    32: M7,\n    // U+0020\n    33: [0, 0.69444, 0, 0, 0.35],\n    // U+0021 !\n    34: M86,\n    // U+0022 \"\n    35: [0.19444, 0.69444, 0, 0, 0.95833],\n    // U+0023 #\n    36: M93,\n    // U+0024 $\n    37: [0.05556, 0.75, 0, 0, 0.95833],\n    // U+0025 %\n    38: M70,\n    // U+0026 &\n    39: M76,\n    // U+0027 '\n    40: M67,\n    // U+0028 (\n    41: M67,\n    // U+0029 )\n    42: [0, 0.75, 0, 0, 0.575],\n    // U+002a *\n    43: M80,\n    // U+002b +\n    44: [0.19444, 0.15556, 0, 0, 0.31944],\n    // U+002c ,\n    45: M235,\n    // U+002d -\n    46: [0, 0.15556, 0, 0, 0.31944],\n    // U+002e .\n    47: M73,\n    // U+002f /\n    48: M68,\n    // U+0030 0\n    49: M68,\n    // U+0031 1\n    50: M68,\n    // U+0032 2\n    51: M68,\n    // U+0033 3\n    52: M68,\n    // U+0034 4\n    53: M68,\n    // U+0035 5\n    54: M68,\n    // U+0036 6\n    55: M68,\n    // U+0037 7\n    56: M68,\n    // U+0038 8\n    57: M68,\n    // U+0039 9\n    58: M81,\n    // U+003a :\n    59: [0.19444, 0.44444, 0, 0, 0.31944],\n    // U+003b ;\n    60: M69,\n    // U+003c <\n    61: M99,\n    // U+003d =\n    62: M69,\n    // U+003e >\n    63: [0, 0.69444, 0, 0, 0.54305],\n    // U+003f ?\n    64: M70,\n    // U+0040 @\n    65: M72,\n    // U+0041 A\n    66: [0, 0.68611, 0, 0, 0.81805],\n    // U+0042 B\n    67: M84,\n    // U+0043 C\n    68: [0, 0.68611, 0, 0, 0.88194],\n    // U+0044 D\n    69: M182,\n    // U+0045 E\n    70: [0, 0.68611, 0, 0, 0.72361],\n    // U+0046 F\n    71: [0, 0.68611, 0, 0, 0.90416],\n    // U+0047 G\n    72: M71,\n    // U+0048 H\n    73: [0, 0.68611, 0, 0, 0.43611],\n    // U+0049 I\n    74: [0, 0.68611, 0, 0, 0.59444],\n    // U+004a J\n    75: [0, 0.68611, 0, 0, 0.90138],\n    // U+004b K\n    76: M83,\n    // U+004c L\n    77: [0, 0.68611, 0, 0, 1.09166],\n    // U+004d M\n    78: M71,\n    // U+004e N\n    79: [0, 0.68611, 0, 0, 0.86388],\n    // U+004f O\n    80: [0, 0.68611, 0, 0, 0.78611],\n    // U+0050 P\n    81: [0.19444, 0.68611, 0, 0, 0.86388],\n    // U+0051 Q\n    82: [0, 0.68611, 0, 0, 0.8625],\n    // U+0052 R\n    83: [0, 0.68611, 0, 0, 0.63889],\n    // U+0053 S\n    84: [0, 0.68611, 0, 0, 0.8],\n    // U+0054 T\n    85: [0, 0.68611, 0, 0, 0.88472],\n    // U+0055 U\n    86: [0, 0.68611, 0.01597, 0, 0.86944],\n    // U+0056 V\n    87: [0, 0.68611, 0.01597, 0, 1.18888],\n    // U+0057 W\n    88: M72,\n    // U+0058 X\n    89: [0, 0.68611, 0.02875, 0, 0.86944],\n    // U+0059 Y\n    90: [0, 0.68611, 0, 0, 0.70277],\n    // U+005a Z\n    91: M74,\n    // U+005b [\n    92: M73,\n    // U+005c \\\n    93: M74,\n    // U+005d ]\n    94: M79,\n    // U+005e ^\n    95: [0.31, 0.13444, 0.03194, 0, 0.575],\n    // U+005f _\n    97: [0, 0.44444, 0, 0, 0.55902],\n    // U+0061 a\n    98: M75,\n    // U+0062 b\n    99: M78,\n    // U+0063 c\n    100: M75,\n    // U+0064 d\n    101: [0, 0.44444, 0, 0, 0.52708],\n    // U+0065 e\n    102: [0, 0.69444, 0.10903, 0, 0.35139],\n    // U+0066 f\n    103: [0.19444, 0.44444, 0.01597, 0, 0.575],\n    // U+0067 g\n    104: M75,\n    // U+0068 h\n    105: M76,\n    // U+0069 i\n    106: [0.19444, 0.69444, 0, 0, 0.35139],\n    // U+006a j\n    107: [0, 0.69444, 0, 0, 0.60694],\n    // U+006b k\n    108: M76,\n    // U+006c l\n    109: [0, 0.44444, 0, 0, 0.95833],\n    // U+006d m\n    110: M77,\n    // U+006e n\n    111: M180,\n    // U+006f o\n    112: [0.19444, 0.44444, 0, 0, 0.63889],\n    // U+0070 p\n    113: [0.19444, 0.44444, 0, 0, 0.60694],\n    // U+0071 q\n    114: [0, 0.44444, 0, 0, 0.47361],\n    // U+0072 r\n    115: [0, 0.44444, 0, 0, 0.45361],\n    // U+0073 s\n    116: [0, 0.63492, 0, 0, 0.44722],\n    // U+0074 t\n    117: M77,\n    // U+0075 u\n    118: [0, 0.44444, 0.01597, 0, 0.60694],\n    // U+0076 v\n    119: [0, 0.44444, 0.01597, 0, 0.83055],\n    // U+0077 w\n    120: [0, 0.44444, 0, 0, 0.60694],\n    // U+0078 x\n    121: [0.19444, 0.44444, 0.01597, 0, 0.60694],\n    // U+0079 y\n    122: M78,\n    // U+007a z\n    123: M73,\n    // U+007b {\n    124: M74,\n    // U+007c |\n    125: M73,\n    // U+007d }\n    126: [0.35, 0.34444, 0, 0, 0.575],\n    // U+007e ~\n    160: M7,\n    // U+00a0\n    163: [0, 0.69444, 0, 0, 0.86853],\n    // U+00a3 £\n    168: M79,\n    // U+00a8 ¨\n    172: [0, 0.44444, 0, 0, 0.76666],\n    // U+00ac ¬\n    176: M82,\n    // U+00b0 °\n    177: M80,\n    // U+00b1 ±\n    184: [0.17014, 0, 0, 0, 0.51111],\n    // U+00b8 ¸\n    198: [0, 0.68611, 0, 0, 1.04166],\n    // U+00c6 Æ\n    215: M80,\n    // U+00d7 ×\n    216: [0.04861, 0.73472, 0, 0, 0.89444],\n    // U+00d8 Ø\n    223: M228,\n    // U+00df ß\n    230: [0, 0.44444, 0, 0, 0.83055],\n    // U+00e6 æ\n    247: M80,\n    // U+00f7 ÷\n    248: [0.09722, 0.54167, 0, 0, 0.575],\n    // U+00f8 ø\n    305: M81,\n    // U+0131 ı\n    338: [0, 0.68611, 0, 0, 1.16944],\n    // U+0152 Œ\n    339: M97,\n    // U+0153 œ\n    567: [0.19444, 0.44444, 0, 0, 0.35139],\n    // U+0237 ȷ\n    710: M79,\n    // U+02c6 ˆ\n    711: [0, 0.63194, 0, 0, 0.575],\n    // U+02c7 ˇ\n    713: [0, 0.59611, 0, 0, 0.575],\n    // U+02c9 ˉ\n    714: M79,\n    // U+02ca ˊ\n    715: M79,\n    // U+02cb ˋ\n    728: M79,\n    // U+02d8 ˘\n    729: M76,\n    // U+02d9 ˙\n    730: M82,\n    // U+02da ˚\n    732: M79,\n    // U+02dc ˜\n    733: M79,\n    // U+02dd ˝\n    915: M83,\n    // U+0393 Γ\n    916: M94,\n    // U+0394 Δ\n    920: M85,\n    // U+0398 Θ\n    923: M184,\n    // U+039b Λ\n    926: M186,\n    // U+039e Ξ\n    928: M71,\n    // U+03a0 Π\n    931: M84,\n    // U+03a3 Σ\n    933: M85,\n    // U+03a5 Υ\n    934: M84,\n    // U+03a6 Φ\n    936: M85,\n    // U+03a8 Ψ\n    937: M84,\n    // U+03a9 Ω\n    8211: [0, 0.44444, 0.03194, 0, 0.575],\n    // U+2013 –\n    8212: [0, 0.44444, 0.03194, 0, 1.14999],\n    // U+2014 —\n    8216: M76,\n    // U+2018 ‘\n    8217: M76,\n    // U+2019 ’\n    8220: M86,\n    // U+201c “\n    8221: M86,\n    // U+201d ”\n    8224: M87,\n    // U+2020 †\n    8225: M87,\n    // U+2021 ‡\n    8242: [0, 0.55556, 0, 0, 0.34444],\n    // U+2032 ′\n    8407: [0, 0.72444, 0.15486, 0, 0.575],\n    // U+20d7 ⃗\n    8463: M183,\n    // U+210f ℏ\n    8465: M88,\n    // U+2111 ℑ\n    8467: [0, 0.69444, 0, 0, 0.47361],\n    // U+2113 ℓ\n    8472: [0.19444, 0.44444, 0, 0, 0.74027],\n    // U+2118 ℘\n    8476: M88,\n    // U+211c ℜ\n    8501: M103,\n    // U+2135 ℵ\n    8592: M89,\n    // U+2190 ←\n    8593: M90,\n    // U+2191 ↑\n    8594: M89,\n    // U+2192 →\n    8595: M90,\n    // U+2193 ↓\n    8596: M89,\n    // U+2194 ↔\n    8597: M73,\n    // U+2195 ↕\n    8598: M91,\n    // U+2196 ↖\n    8599: M91,\n    // U+2197 ↗\n    8600: M91,\n    // U+2198 ↘\n    8601: M91,\n    // U+2199 ↙\n    8636: M89,\n    // U+21bc ↼\n    8637: M89,\n    // U+21bd ↽\n    8640: M89,\n    // U+21c0 ⇀\n    8641: M89,\n    // U+21c1 ⇁\n    8656: M89,\n    // U+21d0 ⇐\n    8657: M92,\n    // U+21d1 ⇑\n    8658: M89,\n    // U+21d2 ⇒\n    8659: M92,\n    // U+21d3 ⇓\n    8660: M89,\n    // U+21d4 ⇔\n    8661: [0.25, 0.75, 0, 0, 0.70277],\n    // U+21d5 ⇕\n    8704: M75,\n    // U+2200 ∀\n    8706: [0, 0.69444, 0.06389, 0, 0.62847],\n    // U+2202 ∂\n    8707: M75,\n    // U+2203 ∃\n    8709: M93,\n    // U+2205 ∅\n    8711: M94,\n    // U+2207 ∇\n    8712: M95,\n    // U+2208 ∈\n    8715: M95,\n    // U+220b ∋\n    8722: M80,\n    // U+2212 −\n    8723: M80,\n    // U+2213 ∓\n    8725: M73,\n    // U+2215 ∕\n    8726: M73,\n    // U+2216 ∖\n    8727: M104,\n    // U+2217 ∗\n    8728: M96,\n    // U+2218 ∘\n    8729: M96,\n    // U+2219 ∙\n    8730: [0.18, 0.82, 0, 0, 0.95833],\n    // U+221a √\n    8733: M97,\n    // U+221d ∝\n    8734: [0, 0.44444, 0, 0, 1.14999],\n    // U+221e ∞\n    8736: M25,\n    // U+2220 ∠\n    8739: M74,\n    // U+2223 ∣\n    8741: M73,\n    // U+2225 ∥\n    8743: M98,\n    // U+2227 ∧\n    8744: M98,\n    // U+2228 ∨\n    8745: M98,\n    // U+2229 ∩\n    8746: M98,\n    // U+222a ∪\n    8747: [0.19444, 0.69444, 0.12778, 0, 0.56875],\n    // U+222b ∫\n    8764: M99,\n    // U+223c ∼\n    8768: [0.19444, 0.69444, 0, 0, 0.31944],\n    // U+2240 ≀\n    8771: M100,\n    // U+2243 ≃\n    8776: [0.02444, 0.52444, 0, 0, 0.89444],\n    // U+2248 ≈\n    8781: M100,\n    // U+224d ≍\n    8801: M100,\n    // U+2261 ≡\n    8804: M101,\n    // U+2264 ≤\n    8805: M101,\n    // U+2265 ≥\n    8810: M102,\n    // U+226a ≪\n    8811: M102,\n    // U+226b ≫\n    8826: M69,\n    // U+227a ≺\n    8827: M69,\n    // U+227b ≻\n    8834: M69,\n    // U+2282 ⊂\n    8835: M69,\n    // U+2283 ⊃\n    8838: M101,\n    // U+2286 ⊆\n    8839: M101,\n    // U+2287 ⊇\n    8846: M98,\n    // U+228e ⊎\n    8849: M101,\n    // U+2291 ⊑\n    8850: M101,\n    // U+2292 ⊒\n    8851: M98,\n    // U+2293 ⊓\n    8852: M98,\n    // U+2294 ⊔\n    8853: M80,\n    // U+2295 ⊕\n    8854: M80,\n    // U+2296 ⊖\n    8855: M80,\n    // U+2297 ⊗\n    8856: M80,\n    // U+2298 ⊘\n    8857: M80,\n    // U+2299 ⊙\n    8866: M103,\n    // U+22a2 ⊢\n    8867: M103,\n    // U+22a3 ⊣\n    8868: M70,\n    // U+22a4 ⊤\n    8869: M70,\n    // U+22a5 ⊥\n    8900: M96,\n    // U+22c4 ⋄\n    8901: [-0.02639, 0.47361, 0, 0, 0.31944],\n    // U+22c5 ⋅\n    8902: M104,\n    // U+22c6 ⋆\n    8968: M105,\n    // U+2308 ⌈\n    8969: M105,\n    // U+2309 ⌉\n    8970: M105,\n    // U+230a ⌊\n    8971: M105,\n    // U+230b ⌋\n    8994: M106,\n    // U+2322 ⌢\n    8995: M106,\n    // U+2323 ⌣\n    9651: M107,\n    // U+25b3 △\n    9657: M104,\n    // U+25b9 ▹\n    9661: M107,\n    // U+25bd ▽\n    9667: M104,\n    // U+25c3 ◃\n    9711: M91,\n    // U+25ef ◯\n    9824: M108,\n    // U+2660 ♠\n    9825: M108,\n    // U+2661 ♡\n    9826: M108,\n    // U+2662 ♢\n    9827: M108,\n    // U+2663 ♣\n    9837: [0, 0.75, 0, 0, 0.44722],\n    // U+266d ♭\n    9838: M109,\n    // U+266e ♮\n    9839: M109,\n    // U+266f ♯\n    10216: M67,\n    // U+27e8 ⟨\n    10217: M67,\n    // U+27e9 ⟩\n    10815: M71,\n    // U+2a3f ⨿\n    10927: M101,\n    // U+2aaf ⪯\n    10928: M101,\n    // U+2ab0 ⪰\n    57376: M179\n    // U+e020 \n  },\n  \"Main-BoldItalic\": {\n    32: M7,\n    // U+0020\n    33: [0, 0.69444, 0.11417, 0, 0.38611],\n    // U+0021 !\n    34: M120,\n    // U+0022 \"\n    35: [0.19444, 0.69444, 0.06833, 0, 0.94444],\n    // U+0023 #\n    37: [0.05556, 0.75, 0.12861, 0, 0.94444],\n    // U+0025 %\n    38: [0, 0.69444, 0.08528, 0, 0.88555],\n    // U+0026 &\n    39: M116,\n    // U+0027 '\n    40: [0.25, 0.75, 0.15806, 0, 0.47333],\n    // U+0028 (\n    41: [0.25, 0.75, 0.03306, 0, 0.47333],\n    // U+0029 )\n    42: [0, 0.75, 0.14333, 0, 0.59111],\n    // U+002a *\n    43: [0.10333, 0.60333, 0.03306, 0, 0.88555],\n    // U+002b +\n    44: [0.19444, 0.14722, 0, 0, 0.35555],\n    // U+002c ,\n    45: [0, 0.44444, 0.02611, 0, 0.41444],\n    // U+002d -\n    46: [0, 0.14722, 0, 0, 0.35555],\n    // U+002e .\n    47: [0.25, 0.75, 0.15806, 0, 0.59111],\n    // U+002f /\n    48: M110,\n    // U+0030 0\n    49: M110,\n    // U+0031 1\n    50: M110,\n    // U+0032 2\n    51: M110,\n    // U+0033 3\n    52: M111,\n    // U+0034 4\n    53: M110,\n    // U+0035 5\n    54: M110,\n    // U+0036 6\n    55: M111,\n    // U+0037 7\n    56: M110,\n    // U+0038 8\n    57: M110,\n    // U+0039 9\n    58: [0, 0.44444, 0.06695, 0, 0.35555],\n    // U+003a :\n    59: [0.19444, 0.44444, 0.06695, 0, 0.35555],\n    // U+003b ;\n    61: [-0.10889, 0.39111, 0.06833, 0, 0.88555],\n    // U+003d =\n    63: M118,\n    // U+003f ?\n    64: [0, 0.69444, 0.09208, 0, 0.88555],\n    // U+0040 @\n    65: [0, 0.68611, 0, 0, 0.86555],\n    // U+0041 A\n    66: [0, 0.68611, 0.0992, 0, 0.81666],\n    // U+0042 B\n    67: [0, 0.68611, 0.14208, 0, 0.82666],\n    // U+0043 C\n    68: [0, 0.68611, 0.09062, 0, 0.87555],\n    // U+0044 D\n    69: [0, 0.68611, 0.11431, 0, 0.75666],\n    // U+0045 E\n    70: [0, 0.68611, 0.12903, 0, 0.72722],\n    // U+0046 F\n    71: [0, 0.68611, 0.07347, 0, 0.89527],\n    // U+0047 G\n    72: M112,\n    // U+0048 H\n    73: [0, 0.68611, 0.15681, 0, 0.47166],\n    // U+0049 I\n    74: [0, 0.68611, 0.145, 0, 0.61055],\n    // U+004a J\n    75: [0, 0.68611, 0.14208, 0, 0.89499],\n    // U+004b K\n    76: [0, 0.68611, 0, 0, 0.69777],\n    // U+004c L\n    77: [0, 0.68611, 0.17208, 0, 1.07277],\n    // U+004d M\n    78: M112,\n    // U+004e N\n    79: [0, 0.68611, 0.09062, 0, 0.85499],\n    // U+004f O\n    80: [0, 0.68611, 0.0992, 0, 0.78721],\n    // U+0050 P\n    81: [0.19444, 0.68611, 0.09062, 0, 0.85499],\n    // U+0051 Q\n    82: [0, 0.68611, 0.02559, 0, 0.85944],\n    // U+0052 R\n    83: [0, 0.68611, 0.11264, 0, 0.64999],\n    // U+0053 S\n    84: [0, 0.68611, 0.12903, 0, 0.7961],\n    // U+0054 T\n    85: [0, 0.68611, 0.17208, 0, 0.88083],\n    // U+0055 U\n    86: [0, 0.68611, 0.18625, 0, 0.86555],\n    // U+0056 V\n    87: [0, 0.68611, 0.18625, 0, 1.15999],\n    // U+0057 W\n    88: [0, 0.68611, 0.15681, 0, 0.86555],\n    // U+0058 X\n    89: [0, 0.68611, 0.19803, 0, 0.86555],\n    // U+0059 Y\n    90: [0, 0.68611, 0.14208, 0, 0.70888],\n    // U+005a Z\n    91: [0.25, 0.75, 0.1875, 0, 0.35611],\n    // U+005b [\n    93: [0.25, 0.75, 0.09972, 0, 0.35611],\n    // U+005d ]\n    94: M115,\n    // U+005e ^\n    95: [0.31, 0.13444, 0.09811, 0, 0.59111],\n    // U+005f _\n    97: [0, 0.44444, 0.09426, 0, 0.59111],\n    // U+0061 a\n    98: [0, 0.69444, 0.07861, 0, 0.53222],\n    // U+0062 b\n    99: [0, 0.44444, 0.05222, 0, 0.53222],\n    // U+0063 c\n    100: [0, 0.69444, 0.10861, 0, 0.59111],\n    // U+0064 d\n    101: [0, 0.44444, 0.085, 0, 0.53222],\n    // U+0065 e\n    102: [0.19444, 0.69444, 0.21778, 0, 0.4],\n    // U+0066 f\n    103: M113,\n    // U+0067 g\n    104: [0, 0.69444, 0.09426, 0, 0.59111],\n    // U+0068 h\n    105: [0, 0.69326, 0.11387, 0, 0.35555],\n    // U+0069 i\n    106: [0.19444, 0.69326, 0.1672, 0, 0.35555],\n    // U+006a j\n    107: [0, 0.69444, 0.11111, 0, 0.53222],\n    // U+006b k\n    108: [0, 0.69444, 0.10861, 0, 0.29666],\n    // U+006c l\n    109: [0, 0.44444, 0.09426, 0, 0.94444],\n    // U+006d m\n    110: [0, 0.44444, 0.09426, 0, 0.64999],\n    // U+006e n\n    111: [0, 0.44444, 0.07861, 0, 0.59111],\n    // U+006f o\n    112: [0.19444, 0.44444, 0.07861, 0, 0.59111],\n    // U+0070 p\n    113: M113,\n    // U+0071 q\n    114: [0, 0.44444, 0.11111, 0, 0.50167],\n    // U+0072 r\n    115: [0, 0.44444, 0.08167, 0, 0.48694],\n    // U+0073 s\n    116: [0, 0.63492, 0.09639, 0, 0.385],\n    // U+0074 t\n    117: [0, 0.44444, 0.09426, 0, 0.62055],\n    // U+0075 u\n    118: [0, 0.44444, 0.11111, 0, 0.53222],\n    // U+0076 v\n    119: [0, 0.44444, 0.11111, 0, 0.76777],\n    // U+0077 w\n    120: [0, 0.44444, 0.12583, 0, 0.56055],\n    // U+0078 x\n    121: [0.19444, 0.44444, 0.105, 0, 0.56166],\n    // U+0079 y\n    122: [0, 0.44444, 0.13889, 0, 0.49055],\n    // U+007a z\n    126: [0.35, 0.34444, 0.11472, 0, 0.59111],\n    // U+007e ~\n    160: M7,\n    // U+00a0\n    168: [0, 0.69444, 0.11473, 0, 0.59111],\n    // U+00a8 ¨\n    176: M117,\n    // U+00b0 °\n    184: [0.17014, 0, 0, 0, 0.53222],\n    // U+00b8 ¸\n    198: [0, 0.68611, 0.11431, 0, 1.02277],\n    // U+00c6 Æ\n    216: [0.04861, 0.73472, 0.09062, 0, 0.88555],\n    // U+00d8 Ø\n    223: [0.19444, 0.69444, 0.09736, 0, 0.665],\n    // U+00df ß\n    230: M114,\n    // U+00e6 æ\n    248: [0.09722, 0.54167, 0.09458, 0, 0.59111],\n    // U+00f8 ø\n    305: [0, 0.44444, 0.09426, 0, 0.35555],\n    // U+0131 ı\n    338: [0, 0.68611, 0.11431, 0, 1.14054],\n    // U+0152 Œ\n    339: M114,\n    // U+0153 œ\n    567: [0.19444, 0.44444, 0.04611, 0, 0.385],\n    // U+0237 ȷ\n    710: M115,\n    // U+02c6 ˆ\n    711: [0, 0.63194, 0.08271, 0, 0.59111],\n    // U+02c7 ˇ\n    713: [0, 0.59444, 0.10444, 0, 0.59111],\n    // U+02c9 ˉ\n    714: [0, 0.69444, 0.08528, 0, 0.59111],\n    // U+02ca ˊ\n    715: [0, 0.69444, 0, 0, 0.59111],\n    // U+02cb ˋ\n    728: [0, 0.69444, 0.10333, 0, 0.59111],\n    // U+02d8 ˘\n    729: M116,\n    // U+02d9 ˙\n    730: M117,\n    // U+02da ˚\n    732: M118,\n    // U+02dc ˜\n    733: M118,\n    // U+02dd ˝\n    915: [0, 0.68611, 0.12903, 0, 0.69777],\n    // U+0393 Γ\n    916: [0, 0.68611, 0, 0, 0.94444],\n    // U+0394 Δ\n    920: [0, 0.68611, 0.09062, 0, 0.88555],\n    // U+0398 Θ\n    923: [0, 0.68611, 0, 0, 0.80666],\n    // U+039b Λ\n    926: [0, 0.68611, 0.15092, 0, 0.76777],\n    // U+039e Ξ\n    928: M112,\n    // U+03a0 Π\n    931: [0, 0.68611, 0.11431, 0, 0.82666],\n    // U+03a3 Σ\n    933: M119,\n    // U+03a5 Υ\n    934: [0, 0.68611, 0.05632, 0, 0.82666],\n    // U+03a6 Φ\n    936: M119,\n    // U+03a8 Ψ\n    937: [0, 0.68611, 0.0992, 0, 0.82666],\n    // U+03a9 Ω\n    8211: [0, 0.44444, 0.09811, 0, 0.59111],\n    // U+2013 –\n    8212: [0, 0.44444, 0.09811, 0, 1.18221],\n    // U+2014 —\n    8216: M116,\n    // U+2018 ‘\n    8217: M116,\n    // U+2019 ’\n    8220: [0, 0.69444, 0.16772, 0, 0.62055],\n    // U+201c “\n    8221: M120\n    // U+201d ”\n  },\n  \"Main-Italic\": {\n    32: M7,\n    // U+0020\n    33: M121,\n    // U+0021 !\n    34: M132,\n    // U+0022 \"\n    35: [0.19444, 0.69444, 0.06616, 0, 0.81777],\n    // U+0023 #\n    37: [0.05556, 0.75, 0.13639, 0, 0.81777],\n    // U+0025 %\n    38: [0, 0.69444, 0.09694, 0, 0.76666],\n    // U+0026 &\n    39: M121,\n    // U+0027 '\n    40: [0.25, 0.75, 0.16194, 0, 0.40889],\n    // U+0028 (\n    41: [0.25, 0.75, 0.03694, 0, 0.40889],\n    // U+0029 )\n    42: [0, 0.75, 0.14917, 0, 0.51111],\n    // U+002a *\n    43: [0.05667, 0.56167, 0.03694, 0, 0.76666],\n    // U+002b +\n    44: [0.19444, 0.10556, 0, 0, 0.30667],\n    // U+002c ,\n    45: [0, 0.43056, 0.02826, 0, 0.35778],\n    // U+002d -\n    46: [0, 0.10556, 0, 0, 0.30667],\n    // U+002e .\n    47: [0.25, 0.75, 0.16194, 0, 0.51111],\n    // U+002f /\n    48: M122,\n    // U+0030 0\n    49: M122,\n    // U+0031 1\n    50: M122,\n    // U+0032 2\n    51: M122,\n    // U+0033 3\n    52: M123,\n    // U+0034 4\n    53: M122,\n    // U+0035 5\n    54: M122,\n    // U+0036 6\n    55: M123,\n    // U+0037 7\n    56: M122,\n    // U+0038 8\n    57: M122,\n    // U+0039 9\n    58: [0, 0.43056, 0.0582, 0, 0.30667],\n    // U+003a :\n    59: [0.19444, 0.43056, 0.0582, 0, 0.30667],\n    // U+003b ;\n    61: [-0.13313, 0.36687, 0.06616, 0, 0.76666],\n    // U+003d =\n    63: M129,\n    // U+003f ?\n    64: [0, 0.69444, 0.09597, 0, 0.76666],\n    // U+0040 @\n    65: [0, 0.68333, 0, 0, 0.74333],\n    // U+0041 A\n    66: [0, 0.68333, 0.10257, 0, 0.70389],\n    // U+0042 B\n    67: [0, 0.68333, 0.14528, 0, 0.71555],\n    // U+0043 C\n    68: [0, 0.68333, 0.09403, 0, 0.755],\n    // U+0044 D\n    69: [0, 0.68333, 0.12028, 0, 0.67833],\n    // U+0045 E\n    70: [0, 0.68333, 0.13305, 0, 0.65277],\n    // U+0046 F\n    71: [0, 0.68333, 0.08722, 0, 0.77361],\n    // U+0047 G\n    72: M124,\n    // U+0048 H\n    73: [0, 0.68333, 0.15806, 0, 0.38555],\n    // U+0049 I\n    74: [0, 0.68333, 0.14028, 0, 0.525],\n    // U+004a J\n    75: [0, 0.68333, 0.14528, 0, 0.76888],\n    // U+004b K\n    76: [0, 0.68333, 0, 0, 0.62722],\n    // U+004c L\n    77: [0, 0.68333, 0.16389, 0, 0.89666],\n    // U+004d M\n    78: M124,\n    // U+004e N\n    79: M130,\n    // U+004f O\n    80: [0, 0.68333, 0.10257, 0, 0.67833],\n    // U+0050 P\n    81: [0.19444, 0.68333, 0.09403, 0, 0.76666],\n    // U+0051 Q\n    82: [0, 0.68333, 0.03868, 0, 0.72944],\n    // U+0052 R\n    83: [0, 0.68333, 0.11972, 0, 0.56222],\n    // U+0053 S\n    84: [0, 0.68333, 0.13305, 0, 0.71555],\n    // U+0054 T\n    85: M124,\n    // U+0055 U\n    86: [0, 0.68333, 0.18361, 0, 0.74333],\n    // U+0056 V\n    87: [0, 0.68333, 0.18361, 0, 0.99888],\n    // U+0057 W\n    88: [0, 0.68333, 0.15806, 0, 0.74333],\n    // U+0058 X\n    89: [0, 0.68333, 0.19383, 0, 0.74333],\n    // U+0059 Y\n    90: [0, 0.68333, 0.14528, 0, 0.61333],\n    // U+005a Z\n    91: [0.25, 0.75, 0.1875, 0, 0.30667],\n    // U+005b [\n    93: [0.25, 0.75, 0.10528, 0, 0.30667],\n    // U+005d ]\n    94: M127,\n    // U+005e ^\n    95: [0.31, 0.12056, 0.09208, 0, 0.51111],\n    // U+005f _\n    97: [0, 0.43056, 0.07671, 0, 0.51111],\n    // U+0061 a\n    98: [0, 0.69444, 0.06312, 0, 0.46],\n    // U+0062 b\n    99: [0, 0.43056, 0.05653, 0, 0.46],\n    // U+0063 c\n    100: [0, 0.69444, 0.10333, 0, 0.51111],\n    // U+0064 d\n    101: [0, 0.43056, 0.07514, 0, 0.46],\n    // U+0065 e\n    102: [0.19444, 0.69444, 0.21194, 0, 0.30667],\n    // U+0066 f\n    103: M125,\n    // U+0067 g\n    104: [0, 0.69444, 0.07671, 0, 0.51111],\n    // U+0068 h\n    105: [0, 0.65536, 0.1019, 0, 0.30667],\n    // U+0069 i\n    106: [0.19444, 0.65536, 0.14467, 0, 0.30667],\n    // U+006a j\n    107: [0, 0.69444, 0.10764, 0, 0.46],\n    // U+006b k\n    108: [0, 0.69444, 0.10333, 0, 0.25555],\n    // U+006c l\n    109: [0, 0.43056, 0.07671, 0, 0.81777],\n    // U+006d m\n    110: [0, 0.43056, 0.07671, 0, 0.56222],\n    // U+006e n\n    111: [0, 0.43056, 0.06312, 0, 0.51111],\n    // U+006f o\n    112: [0.19444, 0.43056, 0.06312, 0, 0.51111],\n    // U+0070 p\n    113: M125,\n    // U+0071 q\n    114: [0, 0.43056, 0.10764, 0, 0.42166],\n    // U+0072 r\n    115: [0, 0.43056, 0.08208, 0, 0.40889],\n    // U+0073 s\n    116: [0, 0.61508, 0.09486, 0, 0.33222],\n    // U+0074 t\n    117: [0, 0.43056, 0.07671, 0, 0.53666],\n    // U+0075 u\n    118: [0, 0.43056, 0.10764, 0, 0.46],\n    // U+0076 v\n    119: [0, 0.43056, 0.10764, 0, 0.66444],\n    // U+0077 w\n    120: [0, 0.43056, 0.12042, 0, 0.46389],\n    // U+0078 x\n    121: [0.19444, 0.43056, 0.08847, 0, 0.48555],\n    // U+0079 y\n    122: [0, 0.43056, 0.12292, 0, 0.40889],\n    // U+007a z\n    126: [0.35, 0.31786, 0.11585, 0, 0.51111],\n    // U+007e ~\n    160: M7,\n    // U+00a0\n    168: [0, 0.66786, 0.10474, 0, 0.51111],\n    // U+00a8 ¨\n    176: M128,\n    // U+00b0 °\n    184: [0.17014, 0, 0, 0, 0.46],\n    // U+00b8 ¸\n    198: [0, 0.68333, 0.12028, 0, 0.88277],\n    // U+00c6 Æ\n    216: [0.04861, 0.73194, 0.09403, 0, 0.76666],\n    // U+00d8 Ø\n    223: [0.19444, 0.69444, 0.10514, 0, 0.53666],\n    // U+00df ß\n    230: M126,\n    // U+00e6 æ\n    248: [0.09722, 0.52778, 0.09194, 0, 0.51111],\n    // U+00f8 ø\n    338: [0, 0.68333, 0.12028, 0, 0.98499],\n    // U+0152 Œ\n    339: M126,\n    // U+0153 œ\n    710: M127,\n    // U+02c6 ˆ\n    711: [0, 0.62847, 0.08295, 0, 0.51111],\n    // U+02c7 ˇ\n    713: [0, 0.56167, 0.10333, 0, 0.51111],\n    // U+02c9 ˉ\n    714: [0, 0.69444, 0.09694, 0, 0.51111],\n    // U+02ca ˊ\n    715: [0, 0.69444, 0, 0, 0.51111],\n    // U+02cb ˋ\n    728: [0, 0.69444, 0.10806, 0, 0.51111],\n    // U+02d8 ˘\n    729: [0, 0.66786, 0.11752, 0, 0.30667],\n    // U+02d9 ˙\n    730: M128,\n    // U+02da ˚\n    732: [0, 0.66786, 0.11585, 0, 0.51111],\n    // U+02dc ˜\n    733: M129,\n    // U+02dd ˝\n    915: [0, 0.68333, 0.13305, 0, 0.62722],\n    // U+0393 Γ\n    916: [0, 0.68333, 0, 0, 0.81777],\n    // U+0394 Δ\n    920: M130,\n    // U+0398 Θ\n    923: [0, 0.68333, 0, 0, 0.69222],\n    // U+039b Λ\n    926: [0, 0.68333, 0.15294, 0, 0.66444],\n    // U+039e Ξ\n    928: M124,\n    // U+03a0 Π\n    931: [0, 0.68333, 0.12028, 0, 0.71555],\n    // U+03a3 Σ\n    933: M131,\n    // U+03a5 Υ\n    934: [0, 0.68333, 0.05986, 0, 0.71555],\n    // U+03a6 Φ\n    936: M131,\n    // U+03a8 Ψ\n    937: [0, 0.68333, 0.10257, 0, 0.71555],\n    // U+03a9 Ω\n    8211: [0, 0.43056, 0.09208, 0, 0.51111],\n    // U+2013 –\n    8212: [0, 0.43056, 0.09208, 0, 1.02222],\n    // U+2014 —\n    8216: M121,\n    // U+2018 ‘\n    8217: M121,\n    // U+2019 ’\n    8220: [0, 0.69444, 0.1685, 0, 0.51444],\n    // U+201c “\n    8221: M132,\n    // U+201d ”\n    8463: M10\n    // U+210f ℏ\n  },\n  \"Main-Regular\": {\n    32: M7,\n    // U+0020\n    33: M133,\n    // U+0021 !\n    34: M143,\n    // U+0022 \"\n    35: M220,\n    // U+0023 #\n    36: M161,\n    // U+0024 $\n    37: M221,\n    // U+0025 %\n    38: M136,\n    // U+0026 &\n    39: M133,\n    // U+0027 '\n    40: M134,\n    // U+0028 (\n    41: M134,\n    // U+0029 )\n    42: M222,\n    // U+002a *\n    43: M149,\n    // U+002b +\n    44: [0.19444, 0.10556, 0, 0, 0.27778],\n    // U+002c ,\n    45: [0, 0.43056, 0, 0, 0.33333],\n    // U+002d -\n    46: [0, 0.10556, 0, 0, 0.27778],\n    // U+002e .\n    47: M141,\n    // U+002f /\n    48: M135,\n    // U+0030 0\n    49: M135,\n    // U+0031 1\n    50: M135,\n    // U+0032 2\n    51: M135,\n    // U+0033 3\n    52: M135,\n    // U+0034 4\n    53: M135,\n    // U+0035 5\n    54: M135,\n    // U+0036 6\n    55: M135,\n    // U+0037 7\n    56: M135,\n    // U+0038 8\n    57: M135,\n    // U+0039 9\n    58: M150,\n    // U+003a :\n    59: [0.19444, 0.43056, 0, 0, 0.27778],\n    // U+003b ;\n    60: M43,\n    // U+003c <\n    61: M27,\n    // U+003d =\n    62: M43,\n    // U+003e >\n    63: M226,\n    // U+003f ?\n    64: M136,\n    // U+0040 @\n    65: M137,\n    // U+0041 A\n    66: [0, 0.68333, 0, 0, 0.70834],\n    // U+0042 B\n    67: M140,\n    // U+0043 C\n    68: [0, 0.68333, 0, 0, 0.76389],\n    // U+0044 D\n    69: M139,\n    // U+0045 E\n    70: [0, 0.68333, 0, 0, 0.65278],\n    // U+0046 F\n    71: [0, 0.68333, 0, 0, 0.78472],\n    // U+0047 G\n    72: M137,\n    // U+0048 H\n    73: [0, 0.68333, 0, 0, 0.36111],\n    // U+0049 I\n    74: [0, 0.68333, 0, 0, 0.51389],\n    // U+004a J\n    75: M138,\n    // U+004b K\n    76: M154,\n    // U+004c L\n    77: [0, 0.68333, 0, 0, 0.91667],\n    // U+004d M\n    78: M137,\n    // U+004e N\n    79: M138,\n    // U+004f O\n    80: M139,\n    // U+0050 P\n    81: [0.19444, 0.68333, 0, 0, 0.77778],\n    // U+0051 Q\n    82: [0, 0.68333, 0, 0, 0.73611],\n    // U+0052 R\n    83: [0, 0.68333, 0, 0, 0.55556],\n    // U+0053 S\n    84: M140,\n    // U+0054 T\n    85: M137,\n    // U+0055 U\n    86: [0, 0.68333, 0.01389, 0, 0.75],\n    // U+0056 V\n    87: [0, 0.68333, 0.01389, 0, 1.02778],\n    // U+0057 W\n    88: M137,\n    // U+0058 X\n    89: [0, 0.68333, 0.025, 0, 0.75],\n    // U+0059 Y\n    90: [0, 0.68333, 0, 0, 0.61111],\n    // U+005a Z\n    91: M142,\n    // U+005b [\n    92: M141,\n    // U+005c \\\n    93: M142,\n    // U+005d ]\n    94: M143,\n    // U+005e ^\n    95: [0.31, 0.12056, 0.02778, 0, 0.5],\n    // U+005f _\n    97: M146,\n    // U+0061 a\n    98: M144,\n    // U+0062 b\n    99: M145,\n    // U+0063 c\n    100: M144,\n    // U+0064 d\n    101: M145,\n    // U+0065 e\n    102: [0, 0.69444, 0.07778, 0, 0.30556],\n    // U+0066 f\n    103: [0.19444, 0.43056, 0.01389, 0, 0.5],\n    // U+0067 g\n    104: M144,\n    // U+0068 h\n    105: M151,\n    // U+0069 i\n    106: [0.19444, 0.66786, 0, 0, 0.30556],\n    // U+006a j\n    107: [0, 0.69444, 0, 0, 0.52778],\n    // U+006b k\n    108: M133,\n    // U+006c l\n    109: [0, 0.43056, 0, 0, 0.83334],\n    // U+006d m\n    110: M148,\n    // U+006e n\n    111: M146,\n    // U+006f o\n    112: M147,\n    // U+0070 p\n    113: [0.19444, 0.43056, 0, 0, 0.52778],\n    // U+0071 q\n    114: [0, 0.43056, 0, 0, 0.39167],\n    // U+0072 r\n    115: [0, 0.43056, 0, 0, 0.39445],\n    // U+0073 s\n    116: [0, 0.61508, 0, 0, 0.38889],\n    // U+0074 t\n    117: M148,\n    // U+0075 u\n    118: [0, 0.43056, 0.01389, 0, 0.52778],\n    // U+0076 v\n    119: [0, 0.43056, 0.01389, 0, 0.72222],\n    // U+0077 w\n    120: [0, 0.43056, 0, 0, 0.52778],\n    // U+0078 x\n    121: [0.19444, 0.43056, 0.01389, 0, 0.52778],\n    // U+0079 y\n    122: M145,\n    // U+007a z\n    123: M141,\n    // U+007b {\n    124: M142,\n    // U+007c |\n    125: M141,\n    // U+007d }\n    126: [0.35, 0.31786, 0, 0, 0.5],\n    // U+007e ~\n    160: M7,\n    // U+00a0\n    163: [0, 0.69444, 0, 0, 0.76909],\n    // U+00a3 £\n    167: M155,\n    // U+00a7 §\n    168: M153,\n    // U+00a8 ¨\n    172: [0, 0.43056, 0, 0, 0.66667],\n    // U+00ac ¬\n    176: M152,\n    // U+00b0 °\n    177: M149,\n    // U+00b1 ±\n    182: M160,\n    // U+00b6 ¶\n    184: M213,\n    // U+00b8 ¸\n    198: [0, 0.68333, 0, 0, 0.90278],\n    // U+00c6 Æ\n    215: M149,\n    // U+00d7 ×\n    216: [0.04861, 0.73194, 0, 0, 0.77778],\n    // U+00d8 Ø\n    223: M143,\n    // U+00df ß\n    230: [0, 0.43056, 0, 0, 0.72222],\n    // U+00e6 æ\n    247: M149,\n    // U+00f7 ÷\n    248: [0.09722, 0.52778, 0, 0, 0.5],\n    // U+00f8 ø\n    305: M150,\n    // U+0131 ı\n    338: [0, 0.68333, 0, 0, 1.01389],\n    // U+0152 Œ\n    339: M165,\n    // U+0153 œ\n    567: [0.19444, 0.43056, 0, 0, 0.30556],\n    // U+0237 ȷ\n    710: M143,\n    // U+02c6 ˆ\n    711: [0, 0.62847, 0, 0, 0.5],\n    // U+02c7 ˇ\n    713: [0, 0.56778, 0, 0, 0.5],\n    // U+02c9 ˉ\n    714: M143,\n    // U+02ca ˊ\n    715: M143,\n    // U+02cb ˋ\n    728: M143,\n    // U+02d8 ˘\n    729: M151,\n    // U+02d9 ˙\n    730: M152,\n    // U+02da ˚\n    732: M153,\n    // U+02dc ˜\n    733: M143,\n    // U+02dd ˝\n    915: M154,\n    // U+0393 Γ\n    916: M162,\n    // U+0394 Δ\n    920: M138,\n    // U+0398 Θ\n    923: [0, 0.68333, 0, 0, 0.69445],\n    // U+039b Λ\n    926: [0, 0.68333, 0, 0, 0.66667],\n    // U+039e Ξ\n    928: M137,\n    // U+03a0 Π\n    931: M140,\n    // U+03a3 Σ\n    933: M138,\n    // U+03a5 Υ\n    934: M140,\n    // U+03a6 Φ\n    936: M138,\n    // U+03a8 Ψ\n    937: M140,\n    // U+03a9 Ω\n    8211: [0, 0.43056, 0.02778, 0, 0.5],\n    // U+2013 –\n    8212: [0, 0.43056, 0.02778, 0, 1],\n    // U+2014 —\n    8216: M133,\n    // U+2018 ‘\n    8217: M133,\n    // U+2019 ’\n    8220: M143,\n    // U+201c “\n    8221: M143,\n    // U+201d ”\n    8224: M155,\n    // U+2020 †\n    8225: M155,\n    // U+2021 ‡\n    8230: [0, 0.12, 0, 0, 1.172],\n    // U+2026 …\n    8242: [0, 0.55556, 0, 0, 0.275],\n    // U+2032 ′\n    8407: [0, 0.71444, 0.15382, 0, 0.5],\n    // U+20d7 ⃗\n    8463: M10,\n    // U+210f ℏ\n    8465: M156,\n    // U+2111 ℑ\n    8467: [0, 0.69444, 0, 0.11111, 0.41667],\n    // U+2113 ℓ\n    8472: [0.19444, 0.43056, 0, 0.11111, 0.63646],\n    // U+2118 ℘\n    8476: M156,\n    // U+211c ℜ\n    8501: M170,\n    // U+2135 ℵ\n    8592: M12,\n    // U+2190 ←\n    8593: M157,\n    // U+2191 ↑\n    8594: M12,\n    // U+2192 →\n    8595: M157,\n    // U+2193 ↓\n    8596: M12,\n    // U+2194 ↔\n    8597: M141,\n    // U+2195 ↕\n    8598: M158,\n    // U+2196 ↖\n    8599: M158,\n    // U+2197 ↗\n    8600: M158,\n    // U+2198 ↘\n    8601: M158,\n    // U+2199 ↙\n    8614: [0.011, 0.511, 0, 0, 1],\n    // U+21a6 ↦\n    8617: M159,\n    // U+21a9 ↩\n    8618: M159,\n    // U+21aa ↪\n    8636: M12,\n    // U+21bc ↼\n    8637: M12,\n    // U+21bd ↽\n    8640: M12,\n    // U+21c0 ⇀\n    8641: M12,\n    // U+21c1 ⇁\n    8652: [0.011, 0.671, 0, 0, 1],\n    // U+21cc ⇌\n    8656: M12,\n    // U+21d0 ⇐\n    8657: M160,\n    // U+21d1 ⇑\n    8658: M12,\n    // U+21d2 ⇒\n    8659: M160,\n    // U+21d3 ⇓\n    8660: M12,\n    // U+21d4 ⇔\n    8661: [0.25, 0.75, 0, 0, 0.61111],\n    // U+21d5 ⇕\n    8704: M144,\n    // U+2200 ∀\n    8706: [0, 0.69444, 0.05556, 0.08334, 0.5309],\n    // U+2202 ∂\n    8707: M144,\n    // U+2203 ∃\n    8709: M161,\n    // U+2205 ∅\n    8711: M162,\n    // U+2207 ∇\n    8712: M163,\n    // U+2208 ∈\n    8715: M163,\n    // U+220b ∋\n    8722: M149,\n    // U+2212 −\n    8723: M149,\n    // U+2213 ∓\n    8725: M141,\n    // U+2215 ∕\n    8726: M141,\n    // U+2216 ∖\n    8727: M171,\n    // U+2217 ∗\n    8728: M164,\n    // U+2218 ∘\n    8729: M164,\n    // U+2219 ∙\n    8730: [0.2, 0.8, 0, 0, 0.83334],\n    // U+221a √\n    8733: M165,\n    // U+221d ∝\n    8734: M17,\n    // U+221e ∞\n    8736: M25,\n    // U+2220 ∠\n    8739: M142,\n    // U+2223 ∣\n    8741: M141,\n    // U+2225 ∥\n    8743: M166,\n    // U+2227 ∧\n    8744: M166,\n    // U+2228 ∨\n    8745: M166,\n    // U+2229 ∩\n    8746: M166,\n    // U+222a ∪\n    8747: [0.19444, 0.69444, 0.11111, 0, 0.41667],\n    // U+222b ∫\n    8764: M27,\n    // U+223c ∼\n    8768: [0.19444, 0.69444, 0, 0, 0.27778],\n    // U+2240 ≀\n    8771: M167,\n    // U+2243 ≃\n    8773: [-0.022, 0.589, 0, 0, 1],\n    // U+2245 ≅\n    8776: M168,\n    // U+2248 ≈\n    8781: M167,\n    // U+224d ≍\n    8784: [-0.133, 0.67, 0, 0, 0.778],\n    // U+2250 ≐\n    8801: M167,\n    // U+2261 ≡\n    8804: M37,\n    // U+2264 ≤\n    8805: M37,\n    // U+2265 ≥\n    8810: M169,\n    // U+226a ≪\n    8811: M169,\n    // U+226b ≫\n    8826: M43,\n    // U+227a ≺\n    8827: M43,\n    // U+227b ≻\n    8834: M43,\n    // U+2282 ⊂\n    8835: M43,\n    // U+2283 ⊃\n    8838: M37,\n    // U+2286 ⊆\n    8839: M37,\n    // U+2287 ⊇\n    8846: M166,\n    // U+228e ⊎\n    8849: M37,\n    // U+2291 ⊑\n    8850: M37,\n    // U+2292 ⊒\n    8851: M166,\n    // U+2293 ⊓\n    8852: M166,\n    // U+2294 ⊔\n    8853: M149,\n    // U+2295 ⊕\n    8854: M149,\n    // U+2296 ⊖\n    8855: M149,\n    // U+2297 ⊗\n    8856: M149,\n    // U+2298 ⊘\n    8857: M149,\n    // U+2299 ⊙\n    8866: M170,\n    // U+22a2 ⊢\n    8867: M170,\n    // U+22a3 ⊣\n    8868: M136,\n    // U+22a4 ⊤\n    8869: M136,\n    // U+22a5 ⊥\n    8872: [0.249, 0.75, 0, 0, 0.867],\n    // U+22a8 ⊨\n    8900: M164,\n    // U+22c4 ⋄\n    8901: [-0.05555, 0.44445, 0, 0, 0.27778],\n    // U+22c5 ⋅\n    8902: M171,\n    // U+22c6 ⋆\n    8904: [5e-3, 0.505, 0, 0, 0.9],\n    // U+22c8 ⋈\n    8942: [0.03, 0.9, 0, 0, 0.278],\n    // U+22ee ⋮\n    8943: [-0.19, 0.31, 0, 0, 1.172],\n    // U+22ef ⋯\n    8945: [-0.1, 0.82, 0, 0, 1.282],\n    // U+22f1 ⋱\n    8968: M172,\n    // U+2308 ⌈\n    8969: M172,\n    // U+2309 ⌉\n    8970: M172,\n    // U+230a ⌊\n    8971: M172,\n    // U+230b ⌋\n    8994: M173,\n    // U+2322 ⌢\n    8995: M173,\n    // U+2323 ⌣\n    9136: M174,\n    // U+23b0 ⎰\n    9137: M174,\n    // U+23b1 ⎱\n    9651: M175,\n    // U+25b3 △\n    9657: M171,\n    // U+25b9 ▹\n    9661: M175,\n    // U+25bd ▽\n    9667: M171,\n    // U+25c3 ◃\n    9711: M158,\n    // U+25ef ◯\n    9824: M176,\n    // U+2660 ♠\n    9825: M176,\n    // U+2661 ♡\n    9826: M176,\n    // U+2662 ♢\n    9827: M176,\n    // U+2663 ♣\n    9837: [0, 0.75, 0, 0, 0.38889],\n    // U+266d ♭\n    9838: M177,\n    // U+266e ♮\n    9839: M177,\n    // U+266f ♯\n    10216: M134,\n    // U+27e8 ⟨\n    10217: M134,\n    // U+27e9 ⟩\n    10222: M174,\n    // U+27ee ⟮\n    10223: M174,\n    // U+27ef ⟯\n    10229: [0.011, 0.511, 0, 0, 1.609],\n    // U+27f5 ⟵\n    10230: M178,\n    // U+27f6 ⟶\n    10231: [0.011, 0.511, 0, 0, 1.859],\n    // U+27f7 ⟷\n    10232: [0.024, 0.525, 0, 0, 1.609],\n    // U+27f8 ⟸\n    10233: [0.024, 0.525, 0, 0, 1.638],\n    // U+27f9 ⟹\n    10234: [0.024, 0.525, 0, 0, 1.858],\n    // U+27fa ⟺\n    10236: M178,\n    // U+27fc ⟼\n    10815: M137,\n    // U+2a3f ⨿\n    10927: M37,\n    // U+2aaf ⪯\n    10928: M37,\n    // U+2ab0 ⪰\n    57376: M179\n    // U+e020 \n  },\n  \"Math-BoldItalic\": {\n    32: M7,\n    // U+0020\n    48: M180,\n    // U+0030 0\n    49: M180,\n    // U+0031 1\n    50: M180,\n    // U+0032 2\n    51: M181,\n    // U+0033 3\n    52: M181,\n    // U+0034 4\n    53: M181,\n    // U+0035 5\n    54: M68,\n    // U+0036 6\n    55: M181,\n    // U+0037 7\n    56: M68,\n    // U+0038 8\n    57: M181,\n    // U+0039 9\n    65: M72,\n    // U+0041 A\n    66: [0, 0.68611, 0.04835, 0, 0.8664],\n    // U+0042 B\n    67: [0, 0.68611, 0.06979, 0, 0.81694],\n    // U+0043 C\n    68: [0, 0.68611, 0.03194, 0, 0.93812],\n    // U+0044 D\n    69: [0, 0.68611, 0.05451, 0, 0.81007],\n    // U+0045 E\n    70: [0, 0.68611, 0.15972, 0, 0.68889],\n    // U+0046 F\n    71: [0, 0.68611, 0, 0, 0.88673],\n    // U+0047 G\n    72: M185,\n    // U+0048 H\n    73: [0, 0.68611, 0.07778, 0, 0.51111],\n    // U+0049 I\n    74: [0, 0.68611, 0.10069, 0, 0.63125],\n    // U+004a J\n    75: [0, 0.68611, 0.06979, 0, 0.97118],\n    // U+004b K\n    76: M182,\n    // U+004c L\n    77: [0, 0.68611, 0.11424, 0, 1.14201],\n    // U+004d M\n    78: [0, 0.68611, 0.11424, 0, 0.95034],\n    // U+004e N\n    79: [0, 0.68611, 0.03194, 0, 0.83666],\n    // U+004f O\n    80: [0, 0.68611, 0.15972, 0, 0.72309],\n    // U+0050 P\n    81: [0.19444, 0.68611, 0, 0, 0.86861],\n    // U+0051 Q\n    82: [0, 0.68611, 421e-5, 0, 0.87235],\n    // U+0052 R\n    83: [0, 0.68611, 0.05382, 0, 0.69271],\n    // U+0053 S\n    84: [0, 0.68611, 0.15972, 0, 0.63663],\n    // U+0054 T\n    85: [0, 0.68611, 0.11424, 0, 0.80027],\n    // U+0055 U\n    86: [0, 0.68611, 0.25555, 0, 0.67778],\n    // U+0056 V\n    87: [0, 0.68611, 0.15972, 0, 1.09305],\n    // U+0057 W\n    88: [0, 0.68611, 0.07778, 0, 0.94722],\n    // U+0058 X\n    89: [0, 0.68611, 0.25555, 0, 0.67458],\n    // U+0059 Y\n    90: [0, 0.68611, 0.06979, 0, 0.77257],\n    // U+005a Z\n    97: [0, 0.44444, 0, 0, 0.63287],\n    // U+0061 a\n    98: [0, 0.69444, 0, 0, 0.52083],\n    // U+0062 b\n    99: [0, 0.44444, 0, 0, 0.51342],\n    // U+0063 c\n    100: [0, 0.69444, 0, 0, 0.60972],\n    // U+0064 d\n    101: [0, 0.44444, 0, 0, 0.55361],\n    // U+0065 e\n    102: [0.19444, 0.69444, 0.11042, 0, 0.56806],\n    // U+0066 f\n    103: [0.19444, 0.44444, 0.03704, 0, 0.5449],\n    // U+0067 g\n    104: M183,\n    // U+0068 h\n    105: [0, 0.69326, 0, 0, 0.4048],\n    // U+0069 i\n    106: [0.19444, 0.69326, 0.0622, 0, 0.47083],\n    // U+006a j\n    107: [0, 0.69444, 0.01852, 0, 0.6037],\n    // U+006b k\n    108: [0, 0.69444, 88e-4, 0, 0.34815],\n    // U+006c l\n    109: [0, 0.44444, 0, 0, 1.0324],\n    // U+006d m\n    110: [0, 0.44444, 0, 0, 0.71296],\n    // U+006e n\n    111: M187,\n    // U+006f o\n    112: [0.19444, 0.44444, 0, 0, 0.60092],\n    // U+0070 p\n    113: [0.19444, 0.44444, 0.03704, 0, 0.54213],\n    // U+0071 q\n    114: [0, 0.44444, 0.03194, 0, 0.5287],\n    // U+0072 r\n    115: [0, 0.44444, 0, 0, 0.53125],\n    // U+0073 s\n    116: [0, 0.63492, 0, 0, 0.41528],\n    // U+0074 t\n    117: [0, 0.44444, 0, 0, 0.68102],\n    // U+0075 u\n    118: [0, 0.44444, 0.03704, 0, 0.56666],\n    // U+0076 v\n    119: [0, 0.44444, 0.02778, 0, 0.83148],\n    // U+0077 w\n    120: [0, 0.44444, 0, 0, 0.65903],\n    // U+0078 x\n    121: [0.19444, 0.44444, 0.03704, 0, 0.59028],\n    // U+0079 y\n    122: [0, 0.44444, 0.04213, 0, 0.55509],\n    // U+007a z\n    160: M7,\n    // U+00a0\n    915: [0, 0.68611, 0.15972, 0, 0.65694],\n    // U+0393 Γ\n    916: M94,\n    // U+0394 Δ\n    920: [0, 0.68611, 0.03194, 0, 0.86722],\n    // U+0398 Θ\n    923: M184,\n    // U+039b Λ\n    926: [0, 0.68611, 0.07458, 0, 0.84125],\n    // U+039e Ξ\n    928: M185,\n    // U+03a0 Π\n    931: [0, 0.68611, 0.05451, 0, 0.88507],\n    // U+03a3 Σ\n    933: [0, 0.68611, 0.15972, 0, 0.67083],\n    // U+03a5 Υ\n    934: M186,\n    // U+03a6 Φ\n    936: [0, 0.68611, 0.11653, 0, 0.71402],\n    // U+03a8 Ψ\n    937: [0, 0.68611, 0.04835, 0, 0.8789],\n    // U+03a9 Ω\n    945: [0, 0.44444, 0, 0, 0.76064],\n    // U+03b1 α\n    946: [0.19444, 0.69444, 0.03403, 0, 0.65972],\n    // U+03b2 β\n    947: [0.19444, 0.44444, 0.06389, 0, 0.59003],\n    // U+03b3 γ\n    948: [0, 0.69444, 0.03819, 0, 0.52222],\n    // U+03b4 δ\n    949: [0, 0.44444, 0, 0, 0.52882],\n    // U+03b5 ε\n    950: [0.19444, 0.69444, 0.06215, 0, 0.50833],\n    // U+03b6 ζ\n    951: [0.19444, 0.44444, 0.03704, 0, 0.6],\n    // U+03b7 η\n    952: [0, 0.69444, 0.03194, 0, 0.5618],\n    // U+03b8 θ\n    953: [0, 0.44444, 0, 0, 0.41204],\n    // U+03b9 ι\n    954: [0, 0.44444, 0, 0, 0.66759],\n    // U+03ba κ\n    955: [0, 0.69444, 0, 0, 0.67083],\n    // U+03bb λ\n    956: [0.19444, 0.44444, 0, 0, 0.70787],\n    // U+03bc μ\n    957: [0, 0.44444, 0.06898, 0, 0.57685],\n    // U+03bd ν\n    958: [0.19444, 0.69444, 0.03021, 0, 0.50833],\n    // U+03be ξ\n    959: M187,\n    // U+03bf ο\n    960: [0, 0.44444, 0.03704, 0, 0.68241],\n    // U+03c0 π\n    961: M188,\n    // U+03c1 ρ\n    962: [0.09722, 0.44444, 0.07917, 0, 0.42361],\n    // U+03c2 ς\n    963: [0, 0.44444, 0.03704, 0, 0.68588],\n    // U+03c3 σ\n    964: [0, 0.44444, 0.13472, 0, 0.52083],\n    // U+03c4 τ\n    965: [0, 0.44444, 0.03704, 0, 0.63055],\n    // U+03c5 υ\n    966: [0.19444, 0.44444, 0, 0, 0.74722],\n    // U+03c6 φ\n    967: [0.19444, 0.44444, 0, 0, 0.71805],\n    // U+03c7 χ\n    968: [0.19444, 0.69444, 0.03704, 0, 0.75833],\n    // U+03c8 ψ\n    969: [0, 0.44444, 0.03704, 0, 0.71782],\n    // U+03c9 ω\n    977: [0, 0.69444, 0, 0, 0.69155],\n    // U+03d1 ϑ\n    981: [0.19444, 0.69444, 0, 0, 0.7125],\n    // U+03d5 ϕ\n    982: [0, 0.44444, 0.03194, 0, 0.975],\n    // U+03d6 ϖ\n    1009: M188,\n    // U+03f1 ϱ\n    1013: [0, 0.44444, 0, 0, 0.48333],\n    // U+03f5 ϵ\n    57649: [0, 0.44444, 0, 0, 0.39352],\n    // U+e131 \n    57911: [0.19444, 0.44444, 0, 0, 0.43889]\n    // U+e237 \n  },\n  \"Math-Italic\": {\n    32: M7,\n    // U+0020\n    48: M146,\n    // U+0030 0\n    49: M146,\n    // U+0031 1\n    50: M146,\n    // U+0032 2\n    51: M189,\n    // U+0033 3\n    52: M189,\n    // U+0034 4\n    53: M189,\n    // U+0035 5\n    54: M135,\n    // U+0036 6\n    55: M189,\n    // U+0037 7\n    56: M135,\n    // U+0038 8\n    57: M189,\n    // U+0039 9\n    65: [0, 0.68333, 0, 0.13889, 0.75],\n    // U+0041 A\n    66: [0, 0.68333, 0.05017, 0.08334, 0.75851],\n    // U+0042 B\n    67: [0, 0.68333, 0.07153, 0.08334, 0.71472],\n    // U+0043 C\n    68: [0, 0.68333, 0.02778, 0.05556, 0.82792],\n    // U+0044 D\n    69: [0, 0.68333, 0.05764, 0.08334, 0.7382],\n    // U+0045 E\n    70: [0, 0.68333, 0.13889, 0.08334, 0.64306],\n    // U+0046 F\n    71: [0, 0.68333, 0, 0.08334, 0.78625],\n    // U+0047 G\n    72: M191,\n    // U+0048 H\n    73: [0, 0.68333, 0.07847, 0.11111, 0.43958],\n    // U+0049 I\n    74: [0, 0.68333, 0.09618, 0.16667, 0.55451],\n    // U+004a J\n    75: [0, 0.68333, 0.07153, 0.05556, 0.84931],\n    // U+004b K\n    76: [0, 0.68333, 0, 0.02778, 0.68056],\n    // U+004c L\n    77: [0, 0.68333, 0.10903, 0.08334, 0.97014],\n    // U+004d M\n    78: [0, 0.68333, 0.10903, 0.08334, 0.80347],\n    // U+004e N\n    79: M190,\n    // U+004f O\n    80: [0, 0.68333, 0.13889, 0.08334, 0.64201],\n    // U+0050 P\n    81: [0.19444, 0.68333, 0, 0.08334, 0.79056],\n    // U+0051 Q\n    82: [0, 0.68333, 773e-5, 0.08334, 0.75929],\n    // U+0052 R\n    83: [0, 0.68333, 0.05764, 0.08334, 0.6132],\n    // U+0053 S\n    84: [0, 0.68333, 0.13889, 0.08334, 0.58438],\n    // U+0054 T\n    85: [0, 0.68333, 0.10903, 0.02778, 0.68278],\n    // U+0055 U\n    86: [0, 0.68333, 0.22222, 0, 0.58333],\n    // U+0056 V\n    87: [0, 0.68333, 0.13889, 0, 0.94445],\n    // U+0057 W\n    88: [0, 0.68333, 0.07847, 0.08334, 0.82847],\n    // U+0058 X\n    89: [0, 0.68333, 0.22222, 0, 0.58056],\n    // U+0059 Y\n    90: [0, 0.68333, 0.07153, 0.08334, 0.68264],\n    // U+005a Z\n    97: [0, 0.43056, 0, 0, 0.52859],\n    // U+0061 a\n    98: [0, 0.69444, 0, 0, 0.42917],\n    // U+0062 b\n    99: [0, 0.43056, 0, 0.05556, 0.43276],\n    // U+0063 c\n    100: [0, 0.69444, 0, 0.16667, 0.52049],\n    // U+0064 d\n    101: [0, 0.43056, 0, 0.05556, 0.46563],\n    // U+0065 e\n    102: [0.19444, 0.69444, 0.10764, 0.16667, 0.48959],\n    // U+0066 f\n    103: [0.19444, 0.43056, 0.03588, 0.02778, 0.47697],\n    // U+0067 g\n    104: [0, 0.69444, 0, 0, 0.57616],\n    // U+0068 h\n    105: [0, 0.65952, 0, 0, 0.34451],\n    // U+0069 i\n    106: [0.19444, 0.65952, 0.05724, 0, 0.41181],\n    // U+006a j\n    107: [0, 0.69444, 0.03148, 0, 0.5206],\n    // U+006b k\n    108: [0, 0.69444, 0.01968, 0.08334, 0.29838],\n    // U+006c l\n    109: [0, 0.43056, 0, 0, 0.87801],\n    // U+006d m\n    110: [0, 0.43056, 0, 0, 0.60023],\n    // U+006e n\n    111: M192,\n    // U+006f o\n    112: [0.19444, 0.43056, 0, 0.08334, 0.50313],\n    // U+0070 p\n    113: [0.19444, 0.43056, 0.03588, 0.08334, 0.44641],\n    // U+0071 q\n    114: [0, 0.43056, 0.02778, 0.05556, 0.45116],\n    // U+0072 r\n    115: [0, 0.43056, 0, 0.05556, 0.46875],\n    // U+0073 s\n    116: [0, 0.61508, 0, 0.08334, 0.36111],\n    // U+0074 t\n    117: [0, 0.43056, 0, 0.02778, 0.57246],\n    // U+0075 u\n    118: [0, 0.43056, 0.03588, 0.02778, 0.48472],\n    // U+0076 v\n    119: [0, 0.43056, 0.02691, 0.08334, 0.71592],\n    // U+0077 w\n    120: [0, 0.43056, 0, 0.02778, 0.57153],\n    // U+0078 x\n    121: [0.19444, 0.43056, 0.03588, 0.05556, 0.49028],\n    // U+0079 y\n    122: [0, 0.43056, 0.04398, 0.05556, 0.46505],\n    // U+007a z\n    160: M7,\n    // U+00a0\n    915: [0, 0.68333, 0.13889, 0.08334, 0.61528],\n    // U+0393 Γ\n    916: [0, 0.68333, 0, 0.16667, 0.83334],\n    // U+0394 Δ\n    920: M190,\n    // U+0398 Θ\n    923: [0, 0.68333, 0, 0.16667, 0.69445],\n    // U+039b Λ\n    926: [0, 0.68333, 0.07569, 0.08334, 0.74236],\n    // U+039e Ξ\n    928: M191,\n    // U+03a0 Π\n    931: [0, 0.68333, 0.05764, 0.08334, 0.77986],\n    // U+03a3 Σ\n    933: [0, 0.68333, 0.13889, 0.05556, 0.58333],\n    // U+03a5 Υ\n    934: [0, 0.68333, 0, 0.08334, 0.66667],\n    // U+03a6 Φ\n    936: [0, 0.68333, 0.11, 0.05556, 0.61222],\n    // U+03a8 Ψ\n    937: [0, 0.68333, 0.05017, 0.08334, 0.7724],\n    // U+03a9 Ω\n    945: [0, 0.43056, 37e-4, 0.02778, 0.6397],\n    // U+03b1 α\n    946: [0.19444, 0.69444, 0.05278, 0.08334, 0.56563],\n    // U+03b2 β\n    947: [0.19444, 0.43056, 0.05556, 0, 0.51773],\n    // U+03b3 γ\n    948: [0, 0.69444, 0.03785, 0.05556, 0.44444],\n    // U+03b4 δ\n    949: [0, 0.43056, 0, 0.08334, 0.46632],\n    // U+03b5 ε\n    950: [0.19444, 0.69444, 0.07378, 0.08334, 0.4375],\n    // U+03b6 ζ\n    951: [0.19444, 0.43056, 0.03588, 0.05556, 0.49653],\n    // U+03b7 η\n    952: [0, 0.69444, 0.02778, 0.08334, 0.46944],\n    // U+03b8 θ\n    953: [0, 0.43056, 0, 0.05556, 0.35394],\n    // U+03b9 ι\n    954: [0, 0.43056, 0, 0, 0.57616],\n    // U+03ba κ\n    955: [0, 0.69444, 0, 0, 0.58334],\n    // U+03bb λ\n    956: [0.19444, 0.43056, 0, 0.02778, 0.60255],\n    // U+03bc μ\n    957: [0, 0.43056, 0.06366, 0.02778, 0.49398],\n    // U+03bd ν\n    958: [0.19444, 0.69444, 0.04601, 0.11111, 0.4375],\n    // U+03be ξ\n    959: M192,\n    // U+03bf ο\n    960: [0, 0.43056, 0.03588, 0, 0.57003],\n    // U+03c0 π\n    961: M193,\n    // U+03c1 ρ\n    962: [0.09722, 0.43056, 0.07986, 0.08334, 0.36285],\n    // U+03c2 ς\n    963: [0, 0.43056, 0.03588, 0, 0.57141],\n    // U+03c3 σ\n    964: [0, 0.43056, 0.1132, 0.02778, 0.43715],\n    // U+03c4 τ\n    965: [0, 0.43056, 0.03588, 0.02778, 0.54028],\n    // U+03c5 υ\n    966: [0.19444, 0.43056, 0, 0.08334, 0.65417],\n    // U+03c6 φ\n    967: [0.19444, 0.43056, 0, 0.05556, 0.62569],\n    // U+03c7 χ\n    968: [0.19444, 0.69444, 0.03588, 0.11111, 0.65139],\n    // U+03c8 ψ\n    969: [0, 0.43056, 0.03588, 0, 0.62245],\n    // U+03c9 ω\n    977: [0, 0.69444, 0, 0.08334, 0.59144],\n    // U+03d1 ϑ\n    981: [0.19444, 0.69444, 0, 0.08334, 0.59583],\n    // U+03d5 ϕ\n    982: [0, 0.43056, 0.02778, 0, 0.82813],\n    // U+03d6 ϖ\n    1009: M193,\n    // U+03f1 ϱ\n    1013: [0, 0.43056, 0, 0.05556, 0.4059],\n    // U+03f5 ϵ\n    57649: [0, 0.43056, 0, 0.02778, 0.32246],\n    // U+e131 \n    57911: [0.19444, 0.43056, 0, 0.08334, 0.38403]\n    // U+e237 \n  },\n  \"SansSerif-Bold\": {\n    32: M7,\n    // U+0020\n    33: [0, 0.69444, 0, 0, 0.36667],\n    // U+0021 !\n    34: M210,\n    // U+0022 \"\n    35: [0.19444, 0.69444, 0, 0, 0.91667],\n    // U+0023 #\n    36: [0.05556, 0.75, 0, 0, 0.55],\n    // U+0024 $\n    37: [0.05556, 0.75, 0, 0, 1.02912],\n    // U+0025 %\n    38: [0, 0.69444, 0, 0, 0.83056],\n    // U+0026 &\n    39: M206,\n    // U+0027 '\n    40: M194,\n    // U+0028 (\n    41: M194,\n    // U+0029 )\n    42: [0, 0.75, 0, 0, 0.55],\n    // U+002a *\n    43: [0.11667, 0.61667, 0, 0, 0.85556],\n    // U+002b +\n    44: [0.10556, 0.13056, 0, 0, 0.30556],\n    // U+002c ,\n    45: [0, 0.45833, 0, 0, 0.36667],\n    // U+002d -\n    46: [0, 0.13056, 0, 0, 0.30556],\n    // U+002e .\n    47: [0.25, 0.75, 0, 0, 0.55],\n    // U+002f /\n    48: M195,\n    // U+0030 0\n    49: M195,\n    // U+0031 1\n    50: M195,\n    // U+0032 2\n    51: M195,\n    // U+0033 3\n    52: M195,\n    // U+0034 4\n    53: M195,\n    // U+0035 5\n    54: M195,\n    // U+0036 6\n    55: M195,\n    // U+0037 7\n    56: M195,\n    // U+0038 8\n    57: M195,\n    // U+0039 9\n    58: [0, 0.45833, 0, 0, 0.30556],\n    // U+003a :\n    59: [0.10556, 0.45833, 0, 0, 0.30556],\n    // U+003b ;\n    61: [-0.09375, 0.40625, 0, 0, 0.85556],\n    // U+003d =\n    63: M198,\n    // U+003f ?\n    64: M196,\n    // U+0040 @\n    65: M196,\n    // U+0041 A\n    66: M196,\n    // U+0042 B\n    67: M199,\n    // U+0043 C\n    68: M197,\n    // U+0044 D\n    69: [0, 0.69444, 0, 0, 0.64167],\n    // U+0045 E\n    70: M170,\n    // U+0046 F\n    71: M196,\n    // U+0047 G\n    72: M197,\n    // U+0048 H\n    73: [0, 0.69444, 0, 0, 0.33056],\n    // U+0049 I\n    74: M198,\n    // U+004a J\n    75: M200,\n    // U+004b K\n    76: M207,\n    // U+004c L\n    77: [0, 0.69444, 0, 0, 0.97778],\n    // U+004d M\n    78: M197,\n    // U+004e N\n    79: M197,\n    // U+004f O\n    80: M199,\n    // U+0050 P\n    81: [0.10556, 0.69444, 0, 0, 0.79445],\n    // U+0051 Q\n    82: M199,\n    // U+0052 R\n    83: M170,\n    // U+0053 S\n    84: M196,\n    // U+0054 T\n    85: M200,\n    // U+0055 U\n    86: [0, 0.69444, 0.01528, 0, 0.73334],\n    // U+0056 V\n    87: [0, 0.69444, 0.01528, 0, 1.03889],\n    // U+0057 W\n    88: M196,\n    // U+0058 X\n    89: [0, 0.69444, 0.0275, 0, 0.73334],\n    // U+0059 Y\n    90: M208,\n    // U+005a Z\n    91: M201,\n    // U+005b [\n    93: M201,\n    // U+005d ]\n    94: M195,\n    // U+005e ^\n    95: [0.35, 0.10833, 0.03056, 0, 0.55],\n    // U+005f _\n    97: [0, 0.45833, 0, 0, 0.525],\n    // U+0061 a\n    98: M202,\n    // U+0062 b\n    99: [0, 0.45833, 0, 0, 0.48889],\n    // U+0063 c\n    100: M202,\n    // U+0064 d\n    101: [0, 0.45833, 0, 0, 0.51111],\n    // U+0065 e\n    102: [0, 0.69444, 0.07639, 0, 0.33611],\n    // U+0066 f\n    103: [0.19444, 0.45833, 0.01528, 0, 0.55],\n    // U+0067 g\n    104: M202,\n    // U+0068 h\n    105: M203,\n    // U+0069 i\n    106: [0.19444, 0.69444, 0, 0, 0.28611],\n    // U+006a j\n    107: [0, 0.69444, 0, 0, 0.53056],\n    // U+006b k\n    108: M203,\n    // U+006c l\n    109: [0, 0.45833, 0, 0, 0.86667],\n    // U+006d m\n    110: M205,\n    // U+006e n\n    111: [0, 0.45833, 0, 0, 0.55],\n    // U+006f o\n    112: M204,\n    // U+0070 p\n    113: M204,\n    // U+0071 q\n    114: [0, 0.45833, 0.01528, 0, 0.37222],\n    // U+0072 r\n    115: [0, 0.45833, 0, 0, 0.42167],\n    // U+0073 s\n    116: [0, 0.58929, 0, 0, 0.40417],\n    // U+0074 t\n    117: M205,\n    // U+0075 u\n    118: [0, 0.45833, 0.01528, 0, 0.5],\n    // U+0076 v\n    119: [0, 0.45833, 0.01528, 0, 0.74445],\n    // U+0077 w\n    120: [0, 0.45833, 0, 0, 0.5],\n    // U+0078 x\n    121: [0.19444, 0.45833, 0.01528, 0, 0.5],\n    // U+0079 y\n    122: [0, 0.45833, 0, 0, 0.47639],\n    // U+007a z\n    126: [0.35, 0.34444, 0, 0, 0.55],\n    // U+007e ~\n    160: M7,\n    // U+00a0\n    168: M195,\n    // U+00a8 ¨\n    176: M196,\n    // U+00b0 °\n    180: M195,\n    // U+00b4 ´\n    184: [0.17014, 0, 0, 0, 0.48889],\n    // U+00b8 ¸\n    305: [0, 0.45833, 0, 0, 0.25556],\n    // U+0131 ı\n    567: [0.19444, 0.45833, 0, 0, 0.28611],\n    // U+0237 ȷ\n    710: M195,\n    // U+02c6 ˆ\n    711: [0, 0.63542, 0, 0, 0.55],\n    // U+02c7 ˇ\n    713: [0, 0.63778, 0, 0, 0.55],\n    // U+02c9 ˉ\n    728: M195,\n    // U+02d8 ˘\n    729: M206,\n    // U+02d9 ˙\n    730: M196,\n    // U+02da ˚\n    732: M195,\n    // U+02dc ˜\n    733: M195,\n    // U+02dd ˝\n    915: M207,\n    // U+0393 Γ\n    916: [0, 0.69444, 0, 0, 0.91667],\n    // U+0394 Δ\n    920: M209,\n    // U+0398 Θ\n    923: M208,\n    // U+039b Λ\n    926: M196,\n    // U+039e Ξ\n    928: M197,\n    // U+03a0 Π\n    931: M197,\n    // U+03a3 Σ\n    933: M209,\n    // U+03a5 Υ\n    934: M197,\n    // U+03a6 Φ\n    936: M209,\n    // U+03a8 Ψ\n    937: M197,\n    // U+03a9 Ω\n    8211: [0, 0.45833, 0.03056, 0, 0.55],\n    // U+2013 –\n    8212: [0, 0.45833, 0.03056, 0, 1.10001],\n    // U+2014 —\n    8216: M206,\n    // U+2018 ‘\n    8217: M206,\n    // U+2019 ’\n    8220: M210,\n    // U+201c “\n    8221: M210\n    // U+201d ”\n  },\n  \"SansSerif-Italic\": {\n    32: M7,\n    // U+0020\n    33: [0, 0.69444, 0.05733, 0, 0.31945],\n    // U+0021 !\n    34: M219,\n    // U+0022 \"\n    35: [0.19444, 0.69444, 0.05087, 0, 0.83334],\n    // U+0023 #\n    36: [0.05556, 0.75, 0.11156, 0, 0.5],\n    // U+0024 $\n    37: [0.05556, 0.75, 0.03126, 0, 0.83334],\n    // U+0025 %\n    38: [0, 0.69444, 0.03058, 0, 0.75834],\n    // U+0026 &\n    39: M218,\n    // U+0027 '\n    40: [0.25, 0.75, 0.13164, 0, 0.38889],\n    // U+0028 (\n    41: [0.25, 0.75, 0.02536, 0, 0.38889],\n    // U+0029 )\n    42: [0, 0.75, 0.11775, 0, 0.5],\n    // U+002a *\n    43: [0.08333, 0.58333, 0.02536, 0, 0.77778],\n    // U+002b +\n    44: M223,\n    // U+002c ,\n    45: [0, 0.44444, 0.01946, 0, 0.33333],\n    // U+002d -\n    46: M224,\n    // U+002e .\n    47: [0.25, 0.75, 0.13164, 0, 0.5],\n    // U+002f /\n    48: M211,\n    // U+0030 0\n    49: M211,\n    // U+0031 1\n    50: M211,\n    // U+0032 2\n    51: M211,\n    // U+0033 3\n    52: M211,\n    // U+0034 4\n    53: M211,\n    // U+0035 5\n    54: M211,\n    // U+0036 6\n    55: M211,\n    // U+0037 7\n    56: M211,\n    // U+0038 8\n    57: M211,\n    // U+0039 9\n    58: [0, 0.44444, 0.02502, 0, 0.27778],\n    // U+003a :\n    59: [0.125, 0.44444, 0.02502, 0, 0.27778],\n    // U+003b ;\n    61: [-0.13, 0.37, 0.05087, 0, 0.77778],\n    // U+003d =\n    63: [0, 0.69444, 0.11809, 0, 0.47222],\n    // U+003f ?\n    64: [0, 0.69444, 0.07555, 0, 0.66667],\n    // U+0040 @\n    65: M227,\n    // U+0041 A\n    66: [0, 0.69444, 0.08293, 0, 0.66667],\n    // U+0042 B\n    67: [0, 0.69444, 0.11983, 0, 0.63889],\n    // U+0043 C\n    68: [0, 0.69444, 0.07555, 0, 0.72223],\n    // U+0044 D\n    69: [0, 0.69444, 0.11983, 0, 0.59722],\n    // U+0045 E\n    70: [0, 0.69444, 0.13372, 0, 0.56945],\n    // U+0046 F\n    71: [0, 0.69444, 0.11983, 0, 0.66667],\n    // U+0047 G\n    72: M212,\n    // U+0048 H\n    73: [0, 0.69444, 0.13372, 0, 0.27778],\n    // U+0049 I\n    74: [0, 0.69444, 0.08094, 0, 0.47222],\n    // U+004a J\n    75: [0, 0.69444, 0.11983, 0, 0.69445],\n    // U+004b K\n    76: M229,\n    // U+004c L\n    77: [0, 0.69444, 0.08094, 0, 0.875],\n    // U+004d M\n    78: M212,\n    // U+004e N\n    79: [0, 0.69444, 0.07555, 0, 0.73611],\n    // U+004f O\n    80: [0, 0.69444, 0.08293, 0, 0.63889],\n    // U+0050 P\n    81: [0.125, 0.69444, 0.07555, 0, 0.73611],\n    // U+0051 Q\n    82: [0, 0.69444, 0.08293, 0, 0.64584],\n    // U+0052 R\n    83: [0, 0.69444, 0.09205, 0, 0.55556],\n    // U+0053 S\n    84: [0, 0.69444, 0.13372, 0, 0.68056],\n    // U+0054 T\n    85: [0, 0.69444, 0.08094, 0, 0.6875],\n    // U+0055 U\n    86: [0, 0.69444, 0.1615, 0, 0.66667],\n    // U+0056 V\n    87: [0, 0.69444, 0.1615, 0, 0.94445],\n    // U+0057 W\n    88: [0, 0.69444, 0.13372, 0, 0.66667],\n    // U+0058 X\n    89: [0, 0.69444, 0.17261, 0, 0.66667],\n    // U+0059 Y\n    90: [0, 0.69444, 0.11983, 0, 0.61111],\n    // U+005a Z\n    91: [0.25, 0.75, 0.15942, 0, 0.28889],\n    // U+005b [\n    93: [0.25, 0.75, 0.08719, 0, 0.28889],\n    // U+005d ]\n    94: M214,\n    // U+005e ^\n    95: [0.35, 0.09444, 0.08616, 0, 0.5],\n    // U+005f _\n    97: [0, 0.44444, 981e-5, 0, 0.48056],\n    // U+0061 a\n    98: [0, 0.69444, 0.03057, 0, 0.51667],\n    // U+0062 b\n    99: [0, 0.44444, 0.08336, 0, 0.44445],\n    // U+0063 c\n    100: [0, 0.69444, 0.09483, 0, 0.51667],\n    // U+0064 d\n    101: [0, 0.44444, 0.06778, 0, 0.44445],\n    // U+0065 e\n    102: [0, 0.69444, 0.21705, 0, 0.30556],\n    // U+0066 f\n    103: [0.19444, 0.44444, 0.10836, 0, 0.5],\n    // U+0067 g\n    104: [0, 0.69444, 0.01778, 0, 0.51667],\n    // U+0068 h\n    105: [0, 0.67937, 0.09718, 0, 0.23889],\n    // U+0069 i\n    106: [0.19444, 0.67937, 0.09162, 0, 0.26667],\n    // U+006a j\n    107: [0, 0.69444, 0.08336, 0, 0.48889],\n    // U+006b k\n    108: [0, 0.69444, 0.09483, 0, 0.23889],\n    // U+006c l\n    109: [0, 0.44444, 0.01778, 0, 0.79445],\n    // U+006d m\n    110: [0, 0.44444, 0.01778, 0, 0.51667],\n    // U+006e n\n    111: [0, 0.44444, 0.06613, 0, 0.5],\n    // U+006f o\n    112: [0.19444, 0.44444, 0.0389, 0, 0.51667],\n    // U+0070 p\n    113: [0.19444, 0.44444, 0.04169, 0, 0.51667],\n    // U+0071 q\n    114: [0, 0.44444, 0.10836, 0, 0.34167],\n    // U+0072 r\n    115: [0, 0.44444, 0.0778, 0, 0.38333],\n    // U+0073 s\n    116: [0, 0.57143, 0.07225, 0, 0.36111],\n    // U+0074 t\n    117: [0, 0.44444, 0.04169, 0, 0.51667],\n    // U+0075 u\n    118: [0, 0.44444, 0.10836, 0, 0.46111],\n    // U+0076 v\n    119: [0, 0.44444, 0.10836, 0, 0.68334],\n    // U+0077 w\n    120: [0, 0.44444, 0.09169, 0, 0.46111],\n    // U+0078 x\n    121: [0.19444, 0.44444, 0.10836, 0, 0.46111],\n    // U+0079 y\n    122: [0, 0.44444, 0.08752, 0, 0.43472],\n    // U+007a z\n    126: [0.35, 0.32659, 0.08826, 0, 0.5],\n    // U+007e ~\n    160: M7,\n    // U+00a0\n    168: [0, 0.67937, 0.06385, 0, 0.5],\n    // U+00a8 ¨\n    176: M215,\n    // U+00b0 °\n    184: M213,\n    // U+00b8 ¸\n    305: [0, 0.44444, 0.04169, 0, 0.23889],\n    // U+0131 ı\n    567: [0.19444, 0.44444, 0.04169, 0, 0.26667],\n    // U+0237 ȷ\n    710: M214,\n    // U+02c6 ˆ\n    711: [0, 0.63194, 0.08432, 0, 0.5],\n    // U+02c7 ˇ\n    713: [0, 0.60889, 0.08776, 0, 0.5],\n    // U+02c9 ˉ\n    714: M216,\n    // U+02ca ˊ\n    715: M143,\n    // U+02cb ˋ\n    728: [0, 0.69444, 0.09483, 0, 0.5],\n    // U+02d8 ˘\n    729: [0, 0.67937, 0.07774, 0, 0.27778],\n    // U+02d9 ˙\n    730: M215,\n    // U+02da ˚\n    732: [0, 0.67659, 0.08826, 0, 0.5],\n    // U+02dc ˜\n    733: M216,\n    // U+02dd ˝\n    915: [0, 0.69444, 0.13372, 0, 0.54167],\n    // U+0393 Γ\n    916: M237,\n    // U+0394 Δ\n    920: [0, 0.69444, 0.07555, 0, 0.77778],\n    // U+0398 Θ\n    923: M170,\n    // U+039b Λ\n    926: [0, 0.69444, 0.12816, 0, 0.66667],\n    // U+039e Ξ\n    928: M212,\n    // U+03a0 Π\n    931: [0, 0.69444, 0.11983, 0, 0.72222],\n    // U+03a3 Σ\n    933: M217,\n    // U+03a5 Υ\n    934: [0, 0.69444, 0.04603, 0, 0.72222],\n    // U+03a6 Φ\n    936: M217,\n    // U+03a8 Ψ\n    937: [0, 0.69444, 0.08293, 0, 0.72222],\n    // U+03a9 Ω\n    8211: [0, 0.44444, 0.08616, 0, 0.5],\n    // U+2013 –\n    8212: [0, 0.44444, 0.08616, 0, 1],\n    // U+2014 —\n    8216: M218,\n    // U+2018 ‘\n    8217: M218,\n    // U+2019 ’\n    8220: [0, 0.69444, 0.14205, 0, 0.5],\n    // U+201c “\n    8221: M219\n    // U+201d ”\n  },\n  \"SansSerif-Regular\": {\n    32: M7,\n    // U+0020\n    33: [0, 0.69444, 0, 0, 0.31945],\n    // U+0021 !\n    34: M143,\n    // U+0022 \"\n    35: M220,\n    // U+0023 #\n    36: M161,\n    // U+0024 $\n    37: M221,\n    // U+0025 %\n    38: [0, 0.69444, 0, 0, 0.75834],\n    // U+0026 &\n    39: M133,\n    // U+0027 '\n    40: M134,\n    // U+0028 (\n    41: M134,\n    // U+0029 )\n    42: M222,\n    // U+002a *\n    43: M149,\n    // U+002b +\n    44: M223,\n    // U+002c ,\n    45: [0, 0.44444, 0, 0, 0.33333],\n    // U+002d -\n    46: M224,\n    // U+002e .\n    47: M141,\n    // U+002f /\n    48: M225,\n    // U+0030 0\n    49: M225,\n    // U+0031 1\n    50: M225,\n    // U+0032 2\n    51: M225,\n    // U+0033 3\n    52: M225,\n    // U+0034 4\n    53: M225,\n    // U+0035 5\n    54: M225,\n    // U+0036 6\n    55: M225,\n    // U+0037 7\n    56: M225,\n    // U+0038 8\n    57: M225,\n    // U+0039 9\n    58: [0, 0.44444, 0, 0, 0.27778],\n    // U+003a :\n    59: [0.125, 0.44444, 0, 0, 0.27778],\n    // U+003b ;\n    61: [-0.13, 0.37, 0, 0, 0.77778],\n    // U+003d =\n    63: M226,\n    // U+003f ?\n    64: M227,\n    // U+0040 @\n    65: M227,\n    // U+0041 A\n    66: M227,\n    // U+0042 B\n    67: M75,\n    // U+0043 C\n    68: [0, 0.69444, 0, 0, 0.72223],\n    // U+0044 D\n    69: M228,\n    // U+0045 E\n    70: [0, 0.69444, 0, 0, 0.56945],\n    // U+0046 F\n    71: M227,\n    // U+0047 G\n    72: M230,\n    // U+0048 H\n    73: M133,\n    // U+0049 I\n    74: M226,\n    // U+004a J\n    75: [0, 0.69444, 0, 0, 0.69445],\n    // U+004b K\n    76: M229,\n    // U+004c L\n    77: [0, 0.69444, 0, 0, 0.875],\n    // U+004d M\n    78: M230,\n    // U+004e N\n    79: [0, 0.69444, 0, 0, 0.73611],\n    // U+004f O\n    80: M75,\n    // U+0050 P\n    81: [0.125, 0.69444, 0, 0, 0.73611],\n    // U+0051 Q\n    82: [0, 0.69444, 0, 0, 0.64584],\n    // U+0052 R\n    83: M144,\n    // U+0053 S\n    84: [0, 0.69444, 0, 0, 0.68056],\n    // U+0054 T\n    85: [0, 0.69444, 0, 0, 0.6875],\n    // U+0055 U\n    86: [0, 0.69444, 0.01389, 0, 0.66667],\n    // U+0056 V\n    87: [0, 0.69444, 0.01389, 0, 0.94445],\n    // U+0057 W\n    88: M227,\n    // U+0058 X\n    89: [0, 0.69444, 0.025, 0, 0.66667],\n    // U+0059 Y\n    90: M170,\n    // U+005a Z\n    91: M231,\n    // U+005b [\n    93: M231,\n    // U+005d ]\n    94: M143,\n    // U+005e ^\n    95: [0.35, 0.09444, 0.02778, 0, 0.5],\n    // U+005f _\n    97: [0, 0.44444, 0, 0, 0.48056],\n    // U+0061 a\n    98: M232,\n    // U+0062 b\n    99: M233,\n    // U+0063 c\n    100: M232,\n    // U+0064 d\n    101: M233,\n    // U+0065 e\n    102: [0, 0.69444, 0.06944, 0, 0.30556],\n    // U+0066 f\n    103: [0.19444, 0.44444, 0.01389, 0, 0.5],\n    // U+0067 g\n    104: M232,\n    // U+0068 h\n    105: [0, 0.67937, 0, 0, 0.23889],\n    // U+0069 i\n    106: [0.19444, 0.67937, 0, 0, 0.26667],\n    // U+006a j\n    107: [0, 0.69444, 0, 0, 0.48889],\n    // U+006b k\n    108: [0, 0.69444, 0, 0, 0.23889],\n    // U+006c l\n    109: [0, 0.44444, 0, 0, 0.79445],\n    // U+006d m\n    110: M236,\n    // U+006e n\n    111: [0, 0.44444, 0, 0, 0.5],\n    // U+006f o\n    112: M234,\n    // U+0070 p\n    113: M234,\n    // U+0071 q\n    114: [0, 0.44444, 0.01389, 0, 0.34167],\n    // U+0072 r\n    115: M235,\n    // U+0073 s\n    116: [0, 0.57143, 0, 0, 0.36111],\n    // U+0074 t\n    117: M236,\n    // U+0075 u\n    118: [0, 0.44444, 0.01389, 0, 0.46111],\n    // U+0076 v\n    119: [0, 0.44444, 0.01389, 0, 0.68334],\n    // U+0077 w\n    120: [0, 0.44444, 0, 0, 0.46111],\n    // U+0078 x\n    121: [0.19444, 0.44444, 0.01389, 0, 0.46111],\n    // U+0079 y\n    122: [0, 0.44444, 0, 0, 0.43472],\n    // U+007a z\n    126: [0.35, 0.32659, 0, 0, 0.5],\n    // U+007e ~\n    160: M7,\n    // U+00a0\n    168: [0, 0.67937, 0, 0, 0.5],\n    // U+00a8 ¨\n    176: M227,\n    // U+00b0 °\n    184: M213,\n    // U+00b8 ¸\n    305: [0, 0.44444, 0, 0, 0.23889],\n    // U+0131 ı\n    567: [0.19444, 0.44444, 0, 0, 0.26667],\n    // U+0237 ȷ\n    710: M143,\n    // U+02c6 ˆ\n    711: [0, 0.63194, 0, 0, 0.5],\n    // U+02c7 ˇ\n    713: [0, 0.60889, 0, 0, 0.5],\n    // U+02c9 ˉ\n    714: M143,\n    // U+02ca ˊ\n    715: M143,\n    // U+02cb ˋ\n    728: M143,\n    // U+02d8 ˘\n    729: [0, 0.67937, 0, 0, 0.27778],\n    // U+02d9 ˙\n    730: M227,\n    // U+02da ˚\n    732: [0, 0.67659, 0, 0, 0.5],\n    // U+02dc ˜\n    733: M143,\n    // U+02dd ˝\n    915: M229,\n    // U+0393 Γ\n    916: M237,\n    // U+0394 Δ\n    920: M136,\n    // U+0398 Θ\n    923: M170,\n    // U+039b Λ\n    926: M227,\n    // U+039e Ξ\n    928: M230,\n    // U+03a0 Π\n    931: M156,\n    // U+03a3 Σ\n    933: M136,\n    // U+03a5 Υ\n    934: M156,\n    // U+03a6 Φ\n    936: M136,\n    // U+03a8 Ψ\n    937: M156,\n    // U+03a9 Ω\n    8211: [0, 0.44444, 0.02778, 0, 0.5],\n    // U+2013 –\n    8212: [0, 0.44444, 0.02778, 0, 1],\n    // U+2014 —\n    8216: M133,\n    // U+2018 ‘\n    8217: M133,\n    // U+2019 ’\n    8220: M143,\n    // U+201c “\n    8221: M143\n    // U+201d ”\n  },\n  \"Script-Regular\": {\n    32: M7,\n    // U+0020\n    65: [0, 0.7, 0.22925, 0, 0.80253],\n    // U+0041 A\n    66: [0, 0.7, 0.04087, 0, 0.90757],\n    // U+0042 B\n    67: [0, 0.7, 0.1689, 0, 0.66619],\n    // U+0043 C\n    68: [0, 0.7, 0.09371, 0, 0.77443],\n    // U+0044 D\n    69: [0, 0.7, 0.18583, 0, 0.56162],\n    // U+0045 E\n    70: [0, 0.7, 0.13634, 0, 0.89544],\n    // U+0046 F\n    71: [0, 0.7, 0.17322, 0, 0.60961],\n    // U+0047 G\n    72: [0, 0.7, 0.29694, 0, 0.96919],\n    // U+0048 H\n    73: [0, 0.7, 0.19189, 0, 0.80907],\n    // U+0049 I\n    74: [0.27778, 0.7, 0.19189, 0, 1.05159],\n    // U+004a J\n    75: [0, 0.7, 0.31259, 0, 0.91364],\n    // U+004b K\n    76: [0, 0.7, 0.19189, 0, 0.87373],\n    // U+004c L\n    77: [0, 0.7, 0.15981, 0, 1.08031],\n    // U+004d M\n    78: [0, 0.7, 0.3525, 0, 0.9015],\n    // U+004e N\n    79: [0, 0.7, 0.08078, 0, 0.73787],\n    // U+004f O\n    80: [0, 0.7, 0.08078, 0, 1.01262],\n    // U+0050 P\n    81: [0, 0.7, 0.03305, 0, 0.88282],\n    // U+0051 Q\n    82: [0, 0.7, 0.06259, 0, 0.85],\n    // U+0052 R\n    83: [0, 0.7, 0.19189, 0, 0.86767],\n    // U+0053 S\n    84: [0, 0.7, 0.29087, 0, 0.74697],\n    // U+0054 T\n    85: [0, 0.7, 0.25815, 0, 0.79996],\n    // U+0055 U\n    86: [0, 0.7, 0.27523, 0, 0.62204],\n    // U+0056 V\n    87: [0, 0.7, 0.27523, 0, 0.80532],\n    // U+0057 W\n    88: [0, 0.7, 0.26006, 0, 0.94445],\n    // U+0058 X\n    89: [0, 0.7, 0.2939, 0, 0.70961],\n    // U+0059 Y\n    90: [0, 0.7, 0.24037, 0, 0.8212],\n    // U+005a Z\n    160: M7\n    // U+00a0\n  },\n  \"Size1-Regular\": {\n    32: M7,\n    // U+0020\n    40: M238,\n    // U+0028 (\n    41: M238,\n    // U+0029 )\n    47: M239,\n    // U+002f /\n    91: M240,\n    // U+005b [\n    92: M239,\n    // U+005c \\\n    93: M240,\n    // U+005d ]\n    123: M241,\n    // U+007b {\n    125: M241,\n    // U+007d }\n    160: M7,\n    // U+00a0\n    710: M242,\n    // U+02c6 ˆ\n    732: M242,\n    // U+02dc ˜\n    770: M242,\n    // U+0302 ̂\n    771: M242,\n    // U+0303 ̃\n    8214: [-99e-5, 0.601, 0, 0, 0.77778],\n    // U+2016 ‖\n    8593: M243,\n    // U+2191 ↑\n    8595: M243,\n    // U+2193 ↓\n    8657: M244,\n    // U+21d1 ⇑\n    8659: M244,\n    // U+21d3 ⇓\n    8719: M245,\n    // U+220f ∏\n    8720: M245,\n    // U+2210 ∐\n    8721: [0.25001, 0.75, 0, 0, 1.05556],\n    // U+2211 ∑\n    8730: [0.35001, 0.85, 0, 0, 1],\n    // U+221a √\n    8739: [-599e-5, 0.606, 0, 0, 0.33333],\n    // U+2223 ∣\n    8741: [-599e-5, 0.606, 0, 0, 0.55556],\n    // U+2225 ∥\n    8747: M247,\n    // U+222b ∫\n    8748: M246,\n    // U+222c ∬\n    8749: M246,\n    // U+222d ∭\n    8750: M247,\n    // U+222e ∮\n    8896: M248,\n    // U+22c0 ⋀\n    8897: M248,\n    // U+22c1 ⋁\n    8898: M248,\n    // U+22c2 ⋂\n    8899: M248,\n    // U+22c3 ⋃\n    8968: M249,\n    // U+2308 ⌈\n    8969: M249,\n    // U+2309 ⌉\n    8970: M249,\n    // U+230a ⌊\n    8971: M249,\n    // U+230b ⌋\n    9168: M277,\n    // U+23d0 ⏐\n    10216: M249,\n    // U+27e8 ⟨\n    10217: M249,\n    // U+27e9 ⟩\n    10752: M250,\n    // U+2a00 ⨀\n    10753: M250,\n    // U+2a01 ⨁\n    10754: M250,\n    // U+2a02 ⨂\n    10756: M248,\n    // U+2a04 ⨄\n    10758: M248\n    // U+2a06 ⨆\n  },\n  \"Size2-Regular\": {\n    32: M7,\n    // U+0020\n    40: M251,\n    // U+0028 (\n    41: M251,\n    // U+0029 )\n    47: M252,\n    // U+002f /\n    91: M253,\n    // U+005b [\n    92: M252,\n    // U+005c \\\n    93: M253,\n    // U+005d ]\n    123: M254,\n    // U+007b {\n    125: M254,\n    // U+007d }\n    160: M7,\n    // U+00a0\n    710: M255,\n    // U+02c6 ˆ\n    732: M255,\n    // U+02dc ˜\n    770: M255,\n    // U+0302 ̂\n    771: M255,\n    // U+0303 ̃\n    8719: M256,\n    // U+220f ∏\n    8720: M256,\n    // U+2210 ∐\n    8721: [0.55001, 1.05, 0, 0, 1.44445],\n    // U+2211 ∑\n    8730: [0.65002, 1.15, 0, 0, 1],\n    // U+221a √\n    8747: M258,\n    // U+222b ∫\n    8748: M257,\n    // U+222c ∬\n    8749: M257,\n    // U+222d ∭\n    8750: M258,\n    // U+222e ∮\n    8896: M259,\n    // U+22c0 ⋀\n    8897: M259,\n    // U+22c1 ⋁\n    8898: M259,\n    // U+22c2 ⋂\n    8899: M259,\n    // U+22c3 ⋃\n    8968: M260,\n    // U+2308 ⌈\n    8969: M260,\n    // U+2309 ⌉\n    8970: M260,\n    // U+230a ⌊\n    8971: M260,\n    // U+230b ⌋\n    10216: M261,\n    // U+27e8 ⟨\n    10217: M261,\n    // U+27e9 ⟩\n    10752: M262,\n    // U+2a00 ⨀\n    10753: M262,\n    // U+2a01 ⨁\n    10754: M262,\n    // U+2a02 ⨂\n    10756: M259,\n    // U+2a04 ⨄\n    10758: M259\n    // U+2a06 ⨆\n  },\n  \"Size3-Regular\": {\n    32: M7,\n    // U+0020\n    40: M263,\n    // U+0028 (\n    41: M263,\n    // U+0029 )\n    47: M264,\n    // U+002f /\n    91: M265,\n    // U+005b [\n    92: M264,\n    // U+005c \\\n    93: M265,\n    // U+005d ]\n    123: M266,\n    // U+007b {\n    125: M266,\n    // U+007d }\n    160: M7,\n    // U+00a0\n    710: M267,\n    // U+02c6 ˆ\n    732: M267,\n    // U+02dc ˜\n    770: M267,\n    // U+0302 ̂\n    771: M267,\n    // U+0303 ̃\n    8730: [0.95003, 1.45, 0, 0, 1],\n    // U+221a √\n    8968: M268,\n    // U+2308 ⌈\n    8969: M268,\n    // U+2309 ⌉\n    8970: M268,\n    // U+230a ⌊\n    8971: M268,\n    // U+230b ⌋\n    10216: M266,\n    // U+27e8 ⟨\n    10217: M266\n    // U+27e9 ⟩\n  },\n  \"Size4-Regular\": {\n    32: M7,\n    // U+0020\n    40: M269,\n    // U+0028 (\n    41: M269,\n    // U+0029 )\n    47: M270,\n    // U+002f /\n    91: M271,\n    // U+005b [\n    92: M270,\n    // U+005c \\\n    93: M271,\n    // U+005d ]\n    123: M272,\n    // U+007b {\n    125: M272,\n    // U+007d }\n    160: M7,\n    // U+00a0\n    710: M273,\n    // U+02c6 ˆ\n    732: M273,\n    // U+02dc ˜\n    770: M273,\n    // U+0302 ̂\n    771: M273,\n    // U+0303 ̃\n    8730: [1.25003, 1.75, 0, 0, 1],\n    // U+221a √\n    8968: M274,\n    // U+2308 ⌈\n    8969: M274,\n    // U+2309 ⌉\n    8970: M274,\n    // U+230a ⌊\n    8971: M274,\n    // U+230b ⌋\n    9115: M275,\n    // U+239b ⎛\n    9116: M276,\n    // U+239c ⎜\n    9117: M275,\n    // U+239d ⎝\n    9118: M275,\n    // U+239e ⎞\n    9119: M276,\n    // U+239f ⎟\n    9120: M275,\n    // U+23a0 ⎠\n    9121: M278,\n    // U+23a1 ⎡\n    9122: M277,\n    // U+23a2 ⎢\n    9123: M278,\n    // U+23a3 ⎣\n    9124: M278,\n    // U+23a4 ⎤\n    9125: M277,\n    // U+23a5 ⎥\n    9126: M278,\n    // U+23a6 ⎦\n    9127: M279,\n    // U+23a7 ⎧\n    9128: M280,\n    // U+23a8 ⎨\n    9129: M281,\n    // U+23a9 ⎩\n    9130: [0, 0.3, 0, 0, 0.88889],\n    // U+23aa ⎪\n    9131: M279,\n    // U+23ab ⎫\n    9132: M280,\n    // U+23ac ⎬\n    9133: M281,\n    // U+23ad ⎭\n    9143: [0.88502, 0.915, 0, 0, 1.05556],\n    // U+23b7 ⎷\n    10216: M272,\n    // U+27e8 ⟨\n    10217: M272,\n    // U+27e9 ⟩\n    57344: M282,\n    // U+e000 \n    57345: M282,\n    // U+e001 \n    57680: M283,\n    // U+e150 \n    57681: M283,\n    // U+e151 \n    57682: M283,\n    // U+e152 \n    57683: M283\n    // U+e153 \n  },\n  \"Typewriter-Regular\": {\n    32: M290,\n    // U+0020\n    33: M284,\n    // U+0021 !\n    34: M284,\n    // U+0022 \"\n    35: M284,\n    // U+0023 #\n    36: M285,\n    // U+0024 $\n    37: M285,\n    // U+0025 %\n    38: M284,\n    // U+0026 &\n    39: M284,\n    // U+0027 '\n    40: M285,\n    // U+0028 (\n    41: M285,\n    // U+0029 )\n    42: [0, 0.52083, 0, 0, 0.525],\n    // U+002a *\n    43: M286,\n    // U+002b +\n    44: [0.13889, 0.125, 0, 0, 0.525],\n    // U+002c ,\n    45: M286,\n    // U+002d -\n    46: [0, 0.125, 0, 0, 0.525],\n    // U+002e .\n    47: M285,\n    // U+002f /\n    48: M284,\n    // U+0030 0\n    49: M284,\n    // U+0031 1\n    50: M284,\n    // U+0032 2\n    51: M284,\n    // U+0033 3\n    52: M284,\n    // U+0034 4\n    53: M284,\n    // U+0035 5\n    54: M284,\n    // U+0036 6\n    55: M284,\n    // U+0037 7\n    56: M284,\n    // U+0038 8\n    57: M284,\n    // U+0039 9\n    58: M288,\n    // U+003a :\n    59: [0.13889, 0.43056, 0, 0, 0.525],\n    // U+003b ;\n    60: M287,\n    // U+003c <\n    61: [-0.19549, 0.41562, 0, 0, 0.525],\n    // U+003d =\n    62: M287,\n    // U+003e >\n    63: M284,\n    // U+003f ?\n    64: M284,\n    // U+0040 @\n    65: M284,\n    // U+0041 A\n    66: M284,\n    // U+0042 B\n    67: M284,\n    // U+0043 C\n    68: M284,\n    // U+0044 D\n    69: M284,\n    // U+0045 E\n    70: M284,\n    // U+0046 F\n    71: M284,\n    // U+0047 G\n    72: M284,\n    // U+0048 H\n    73: M284,\n    // U+0049 I\n    74: M284,\n    // U+004a J\n    75: M284,\n    // U+004b K\n    76: M284,\n    // U+004c L\n    77: M284,\n    // U+004d M\n    78: M284,\n    // U+004e N\n    79: M284,\n    // U+004f O\n    80: M284,\n    // U+0050 P\n    81: [0.13889, 0.61111, 0, 0, 0.525],\n    // U+0051 Q\n    82: M284,\n    // U+0052 R\n    83: M284,\n    // U+0053 S\n    84: M284,\n    // U+0054 T\n    85: M284,\n    // U+0055 U\n    86: M284,\n    // U+0056 V\n    87: M284,\n    // U+0057 W\n    88: M284,\n    // U+0058 X\n    89: M284,\n    // U+0059 Y\n    90: M284,\n    // U+005a Z\n    91: M285,\n    // U+005b [\n    92: M285,\n    // U+005c \\\n    93: M285,\n    // U+005d ]\n    94: M284,\n    // U+005e ^\n    95: [0.09514, 0, 0, 0, 0.525],\n    // U+005f _\n    96: M284,\n    // U+0060 `\n    97: M288,\n    // U+0061 a\n    98: M284,\n    // U+0062 b\n    99: M288,\n    // U+0063 c\n    100: M284,\n    // U+0064 d\n    101: M288,\n    // U+0065 e\n    102: M284,\n    // U+0066 f\n    103: M289,\n    // U+0067 g\n    104: M284,\n    // U+0068 h\n    105: M284,\n    // U+0069 i\n    106: [0.22222, 0.61111, 0, 0, 0.525],\n    // U+006a j\n    107: M284,\n    // U+006b k\n    108: M284,\n    // U+006c l\n    109: M288,\n    // U+006d m\n    110: M288,\n    // U+006e n\n    111: M288,\n    // U+006f o\n    112: M289,\n    // U+0070 p\n    113: M289,\n    // U+0071 q\n    114: M288,\n    // U+0072 r\n    115: M288,\n    // U+0073 s\n    116: [0, 0.55358, 0, 0, 0.525],\n    // U+0074 t\n    117: M288,\n    // U+0075 u\n    118: M288,\n    // U+0076 v\n    119: M288,\n    // U+0077 w\n    120: M288,\n    // U+0078 x\n    121: M289,\n    // U+0079 y\n    122: M288,\n    // U+007a z\n    123: M285,\n    // U+007b {\n    124: M285,\n    // U+007c |\n    125: M285,\n    // U+007d }\n    126: M284,\n    // U+007e ~\n    127: M284,\n    // U+007f \n    160: M290,\n    // U+00a0\n    176: M284,\n    // U+00b0 °\n    184: [0.19445, 0, 0, 0, 0.525],\n    // U+00b8 ¸\n    305: M288,\n    // U+0131 ı\n    567: M289,\n    // U+0237 ȷ\n    711: [0, 0.56597, 0, 0, 0.525],\n    // U+02c7 ˇ\n    713: [0, 0.56555, 0, 0, 0.525],\n    // U+02c9 ˉ\n    714: M284,\n    // U+02ca ˊ\n    715: M284,\n    // U+02cb ˋ\n    728: M284,\n    // U+02d8 ˘\n    730: M284,\n    // U+02da ˚\n    770: M284,\n    // U+0302 ̂\n    771: M284,\n    // U+0303 ̃\n    776: M284,\n    // U+0308 ̈\n    915: M284,\n    // U+0393 Γ\n    916: M284,\n    // U+0394 Δ\n    920: M284,\n    // U+0398 Θ\n    923: M284,\n    // U+039b Λ\n    926: M284,\n    // U+039e Ξ\n    928: M284,\n    // U+03a0 Π\n    931: M284,\n    // U+03a3 Σ\n    933: M284,\n    // U+03a5 Υ\n    934: M284,\n    // U+03a6 Φ\n    936: M284,\n    // U+03a8 Ψ\n    937: M284,\n    // U+03a9 Ω\n    8216: M284,\n    // U+2018 ‘\n    8217: M284,\n    // U+2019 ’\n    8242: M284,\n    // U+2032 ′\n    9251: [0.11111, 0.21944, 0, 0, 0.525]\n    // U+2423 ␣\n  }\n};\n\n// src/core/font-metrics.ts\nvar CJK_REGEX = /[\\u3040-\\u309F]|[\\u30A0-\\u30FF]|[\\u4E00-\\u9FAF]|[\\uAC00-\\uD7AF]/;\nvar PT_PER_EM = 10;\nvar AXIS_HEIGHT = 0.25;\nvar BASELINE_SKIP = 1.2;\nvar X_HEIGHT = 0.431;\nvar FONT_METRICS = {\n  slant: [0.25, 0.25, 0.25],\n  space: [0, 0, 0],\n  stretch: [0, 0, 0],\n  shrink: [0, 0, 0],\n  xHeight: [X_HEIGHT, X_HEIGHT, X_HEIGHT],\n  quad: [1, 1.171, 1.472],\n  extraSpace: [0, 0, 0],\n  num1: [0.5, 0.732, 0.925],\n  // Was   num1: [0.677, 0.732, 0.925],\n  num2: [0.394, 0.384, 0.5],\n  // Was   num2: [0.394, 0.384, 0.387],\n  num3: [0.444, 0.471, 0.504],\n  denom1: [0.686, 0.752, 1.025],\n  denom2: [0.345, 0.344, 0.532],\n  sup1: [0.413, 0.503, 0.504],\n  sup2: [0.363, 0.431, 0.404],\n  sup3: [0.289, 0.286, 0.294],\n  sub1: [0.15, 0.143, 0.2],\n  sub2: [0.247, 0.286, 0.4],\n  supDrop: [0.386, 0.353, 0.494],\n  subDrop: [0.05, 0.071, 0.1],\n  delim1: [2.39, 1.7, 1.98],\n  delim2: [1.01, 1.157, 1.42],\n  axisHeight: [AXIS_HEIGHT, AXIS_HEIGHT, AXIS_HEIGHT],\n  defaultRuleThickness: [0.04, 0.049, 0.049],\n  bigOpSpacing1: [0.111, 0.111, 0.111],\n  bigOpSpacing2: [0.166, 0.166, 0.166],\n  bigOpSpacing3: [0.2, 0.2, 0.2],\n  bigOpSpacing4: [0.6, 0.611, 0.611],\n  bigOpSpacing5: [0.1, 0.143, 0.143],\n  sqrtRuleThickness: [0.04, 0.04, 0.04]\n};\nvar FONT_SCALE = [\n  0,\n  // not used\n  0.5,\n  // size 1 = scriptscriptstyle\n  0.7,\n  // size 2 = scriptstyle\n  0.8,\n  0.9,\n  1,\n  // size 5 = default\n  1.2,\n  1.44,\n  1.728,\n  2.074,\n  2.488\n  //size 10\n];\nvar DEFAULT_FONT_SIZE = 5;\nvar EXTRA_CHARACTER_MAP = {\n  \"\\xA0\": \" \",\n  // NON-BREAKING SPACE is like space\n  \"\\u200B\": \" \",\n  // ZERO WIDTH SPACE is like space\n  // Latin-1\n  \"\\xC5\": \"A\",\n  \"\\xC7\": \"C\",\n  \"\\xD0\": \"D\",\n  \"\\xDE\": \"o\",\n  \"\\xE5\": \"a\",\n  \"\\xE7\": \"c\",\n  \"\\xF0\": \"d\",\n  \"\\xFE\": \"o\",\n  // Cyrillic\n  \"\\u0410\": \"A\",\n  \"\\u0411\": \"B\",\n  \"\\u0412\": \"B\",\n  \"\\u0413\": \"F\",\n  \"\\u0414\": \"A\",\n  \"\\u0415\": \"E\",\n  \"\\u0416\": \"K\",\n  \"\\u0417\": \"3\",\n  \"\\u0418\": \"N\",\n  \"\\u0419\": \"N\",\n  \"\\u041A\": \"K\",\n  \"\\u041B\": \"N\",\n  \"\\u041C\": \"M\",\n  \"\\u041D\": \"H\",\n  \"\\u041E\": \"O\",\n  \"\\u041F\": \"N\",\n  \"\\u0420\": \"P\",\n  \"\\u0421\": \"C\",\n  \"\\u0422\": \"T\",\n  \"\\u0423\": \"y\",\n  \"\\u0424\": \"O\",\n  \"\\u0425\": \"X\",\n  \"\\u0426\": \"U\",\n  \"\\u0427\": \"h\",\n  \"\\u0428\": \"W\",\n  \"\\u0429\": \"W\",\n  \"\\u042A\": \"B\",\n  \"\\u042B\": \"X\",\n  \"\\u042C\": \"B\",\n  \"\\u042D\": \"3\",\n  \"\\u042E\": \"X\",\n  \"\\u042F\": \"R\",\n  \"\\u0430\": \"a\",\n  \"\\u0431\": \"b\",\n  \"\\u0432\": \"a\",\n  \"\\u0433\": \"r\",\n  \"\\u0434\": \"y\",\n  \"\\u0435\": \"e\",\n  \"\\u0436\": \"m\",\n  \"\\u0437\": \"e\",\n  \"\\u0438\": \"n\",\n  \"\\u0439\": \"n\",\n  \"\\u043A\": \"n\",\n  \"\\u043B\": \"n\",\n  \"\\u043C\": \"m\",\n  \"\\u043D\": \"n\",\n  \"\\u043E\": \"o\",\n  \"\\u043F\": \"n\",\n  \"\\u0440\": \"p\",\n  \"\\u0441\": \"c\",\n  \"\\u0442\": \"o\",\n  \"\\u0443\": \"y\",\n  \"\\u0444\": \"b\",\n  \"\\u0445\": \"x\",\n  \"\\u0446\": \"n\",\n  \"\\u0447\": \"n\",\n  \"\\u0448\": \"w\",\n  \"\\u0449\": \"w\",\n  \"\\u044A\": \"a\",\n  \"\\u044B\": \"m\",\n  \"\\u044C\": \"a\",\n  \"\\u044D\": \"e\",\n  \"\\u044E\": \"m\",\n  \"\\u044F\": \"r\"\n};\nfunction getCharacterMetrics(codepoint, fontName) {\n  if (codepoint === void 0) codepoint = 77;\n  const metrics = font_metrics_data_default[fontName][codepoint];\n  if (metrics) {\n    return {\n      defaultMetrics: false,\n      depth: metrics[0],\n      height: metrics[1],\n      italic: metrics[2],\n      skew: metrics[3],\n      width: metrics[4]\n    };\n  }\n  if (codepoint === 11034) {\n    return {\n      defaultMetrics: true,\n      depth: 0.2,\n      height: 0.8,\n      italic: 0,\n      skew: 0,\n      width: 0.8\n    };\n  }\n  const char = String.fromCodePoint(codepoint);\n  if (char in EXTRA_CHARACTER_MAP)\n    codepoint = EXTRA_CHARACTER_MAP[char].codePointAt(0);\n  else if (CJK_REGEX.test(char)) {\n    codepoint = 77;\n    return {\n      defaultMetrics: true,\n      depth: 0.2,\n      height: 0.9,\n      italic: 0,\n      skew: 0,\n      width: 1\n    };\n  }\n  return {\n    defaultMetrics: true,\n    depth: 0.2,\n    height: 0.7,\n    italic: 0,\n    skew: 0,\n    width: 0.8\n  };\n}\n\n// src/core/svg-box.ts\nvar SVG_BODY = {\n  // Adapted from https://github.com/KaTeX/KaTeX/blob/master/src/stretchy.js\n  overrightarrow: [[\"rightarrow\"], 0.888, 522, \"xMaxYMin\"],\n  overleftarrow: [[\"leftarrow\"], 0.888, 522, \"xMinYMin\"],\n  underrightarrow: [[\"rightarrow\"], 0.888, 522, \"xMaxYMin\"],\n  underleftarrow: [[\"leftarrow\"], 0.888, 522, \"xMinYMin\"],\n  xrightarrow: [[\"rightarrow\"], 1.469, 522, \"xMaxYMin\"],\n  longrightarrow: [[\"rightarrow\"], 1.469, 522, \"xMaxYMin\"],\n  xleftarrow: [[\"leftarrow\"], 1.469, 522, \"xMinYMin\"],\n  longleftarrow: [[\"leftarrow\"], 1.469, 522, \"xMinYMin\"],\n  Overrightarrow: [[\"doublerightarrow\"], 0.888, 560, \"xMaxYMin\"],\n  xRightarrow: [[\"doublerightarrow\"], 1.526, 560, \"xMaxYMin\"],\n  xLeftarrow: [[\"doubleleftarrow\"], 1.526, 560, \"xMinYMin\"],\n  overleftharpoon: [[\"leftharpoon\"], 0.888, 522, \"xMinYMin\"],\n  xleftharpoonup: [[\"leftharpoon\"], 0.888, 522, \"xMinYMin\"],\n  xleftharpoondown: [[\"leftharpoondown\"], 0.888, 522, \"xMinYMin\"],\n  overrightharpoon: [[\"rightharpoon\"], 0.888, 522, \"xMaxYMin\"],\n  xrightharpoonup: [[\"rightharpoon\"], 0.888, 522, \"xMaxYMin\"],\n  xrightharpoondown: [[\"rightharpoondown\"], 0.888, 522, \"xMaxYMin\"],\n  xlongequal: [[\"longequal\"], 0.888, 334, \"xMinYMin\"],\n  xtwoheadleftarrow: [[\"twoheadleftarrow\"], 0.888, 334, \"xMinYMin\"],\n  xtwoheadrightarrow: [[\"twoheadrightarrow\"], 0.888, 334, \"xMaxYMin\"],\n  overleftrightarrow: [[\"leftarrow\", \"rightarrow\"], 0.888, 522],\n  overbrace: [[\"leftbrace\", \"midbrace\", \"rightbrace\"], 1.6, 548],\n  underbrace: [\n    [\"leftbraceunder\", \"midbraceunder\", \"rightbraceunder\"],\n    1.6,\n    548\n  ],\n  underleftrightarrow: [[\"leftarrow\", \"rightarrow\"], 0.888, 522],\n  xleftrightarrow: [[\"leftarrow\", \"rightarrow\"], 1.75, 522],\n  longleftrightarrow: [[\"leftarrow\", \"rightarrow\"], 1.75, 522],\n  xLeftrightarrow: [[\"doubleleftarrow\", \"doublerightarrow\"], 1.75, 560],\n  xrightleftharpoons: [[\"leftharpoondownplus\", \"rightharpoonplus\"], 1.75, 716],\n  longrightleftharpoons: [\n    [\"leftharpoondownplus\", \"rightharpoonplus\"],\n    1.75,\n    716\n  ],\n  xleftrightharpoons: [[\"leftharpoonplus\", \"rightharpoondownplus\"], 1.75, 716],\n  longleftrightharpoons: [\n    [\"leftharpoonplus\", \"rightharpoondownplus\"],\n    1.75,\n    716\n  ],\n  xhookleftarrow: [[\"leftarrow\", \"righthook\"], 1.08, 522],\n  xhookrightarrow: [[\"lefthook\", \"rightarrow\"], 1.08, 522],\n  overlinesegment: [[\"leftlinesegment\", \"rightlinesegment\"], 0.888, 522],\n  underlinesegment: [[\"leftlinesegment\", \"rightlinesegment\"], 0.888, 522],\n  overgroup: [[\"leftgroup\", \"rightgroup\"], 0.888, 342],\n  undergroup: [[\"leftgroupunder\", \"rightgroupunder\"], 0.888, 342],\n  xmapsto: [[\"leftmapsto\", \"rightarrow\"], 1.5, 522],\n  xtofrom: [[\"leftToFrom\", \"rightToFrom\"], 1.75, 528],\n  // The next three arrows are from the mhchem package.\n  // In mhchem.sty, min-length is 2.0em. But these arrows might appear in the\n  // document as \\xrightarrow or \\xrightleftharpoons. Those have\n  // min-length = 1.75em, so we set min-length on these next three to match.\n  xleftrightarrows: [[\"baraboveleftarrow\", \"rightarrowabovebar\"], 1.75, 901],\n  longleftrightarrows: [[\"baraboveleftarrow\", \"rightarrowabovebar\"], 1.75, 901],\n  xRightleftharpoons: [\n    [\"baraboveshortleftharpoon\", \"rightharpoonaboveshortbar\"],\n    1.75,\n    716\n  ],\n  longRightleftharpoons: [\n    [\"baraboveshortleftharpoon\", \"rightharpoonaboveshortbar\"],\n    1.75,\n    716\n  ],\n  xLeftrightharpoons: [\n    [\"shortbaraboveleftharpoon\", \"shortrightharpoonabovebar\"],\n    1.75,\n    716\n  ],\n  longLeftrightharpoons: [\n    [\"shortbaraboveleftharpoon\", \"shortrightharpoonabovebar\"],\n    1.75,\n    716\n  ]\n};\nvar SVG_ACCENTS = {\n  // ViewBoxWidth, viewBoxHeight, height\n  widehat1: [1062, 239, 0.24],\n  widehat2: [2364, 300, 0.3],\n  widehat3: [2364, 360, 0.36],\n  widehat4: [2364, 420, 0.42],\n  widecheck1: [1062, 239, 0.24],\n  widecheck2: [2364, 300, 0.3],\n  widecheck3: [2364, 360, 0.36],\n  widecheck4: [2364, 420, 0.42],\n  widetilde1: [600, 260, 0.26],\n  widetilde2: [1033, 286, 0.286],\n  widetilde3: [2339, 306, 0.306],\n  widetilde4: [2340, 312, 0.34],\n  overarc: [1061, 159, 0.3],\n  underarc: [1061, 159, 0.3]\n};\nvar PATHS = {\n  // The doubleleftarrow geometry is from glyph U+21D0 in the font KaTeX Main\n  doubleleftarrow: `M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z`,\n  // Doublerightarrow is from glyph U+21D2 in font KaTeX Main\n  doublerightarrow: `M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z`,\n  // Leftarrow is from glyph U+2190 in font KaTeX Main\n  leftarrow: `M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z`,\n  // Overbrace is from glyphs U+23A9/23A8/23A7 in font KaTeX_Size4-Regular\n  leftbrace: `M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z`,\n  leftbraceunder: `M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z`,\n  overarc: `M529 0c179 0 524 115 524 115 5 1 9 5 9 10 0 1-1 2-1 3l-4 22c-1 5-5 9-11 9h-2s-338-93-512-92c-174 0-513 92-513 92h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13 0 0 342-115 520-115z`,\n  underarc: `m 529 160\n  c -179 0 -524 -115 -524 -115\n  c -5 -1 -9 -5 -9 -10\n  c 0 -1 1 -2 1 -3\n  l 4 -22\n  c 1 -5 5 -9 11 -9\n  h 2\n  s 338 93 512 92\n  c 174 0 513 -92 513 -92\n  h 2\n  c 5 0 9 4 11 9\n  l 5 22\n  c 1 6 -2 12 -8 13\n  c 0 0 -342 115 -520 115\n  z\n  `,\n  // Overgroup is from the MnSymbol package (public domain)\n  leftgroup: `M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z`,\n  leftgroupunder: `M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z`,\n  // Harpoons are from glyph U+21BD in font KaTeX Main\n  leftharpoon: `M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z`,\n  leftharpoonplus: `M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z`,\n  leftharpoondown: `M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z`,\n  leftharpoondownplus: `M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z`,\n  // Hook is from glyph U+21A9 in font KaTeX Main\n  lefthook: `M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z`,\n  leftlinesegment: `M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z`,\n  leftmapsto: `M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z`,\n  // Tofrom is from glyph U+21C4 in font KaTeX AMS Regular\n  leftToFrom: `M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z`,\n  longequal: `M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z`,\n  midbrace: `M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z`,\n  midbraceunder: `M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z`,\n  oiintSize1: `M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z`,\n  oiintSize2: `M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z`,\n  oiiintSize1: `M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z`,\n  oiiintSize2: `M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z`,\n  rightarrow: `M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z`,\n  rightbrace: `M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z`,\n  rightbraceunder: `M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z`,\n  rightgroup: `M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z`,\n  rightgroupunder: `M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z`,\n  rightharpoon: `M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z`,\n  rightharpoonplus: `M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z`,\n  rightharpoondown: `M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z`,\n  rightharpoondownplus: `M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z`,\n  righthook: `M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z`,\n  rightlinesegment: `M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z`,\n  rightToFrom: `M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z`,\n  // Twoheadleftarrow is from glyph U+219E in font KaTeX AMS Regular\n  twoheadleftarrow: `M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z`,\n  twoheadrightarrow: `M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z`,\n  // Tilde1 is a modified version of a glyph from the MnSymbol package\n  widetilde1: `M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z`,\n  // Ditto tilde2, tilde3, & tilde4\n  widetilde2: `M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z`,\n  widetilde3: `M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z`,\n  widetilde4: `M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z`,\n  // Vec is from glyph U+20D7 in font KaTeX Main\n  vec: `M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z`,\n  // Widehat1 is a modified version of a glyph from the MnSymbol package\n  widehat1: `M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z`,\n  // Ditto widehat2, widehat3, & widehat4\n  widehat2: `M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z`,\n  widehat3: `M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z`,\n  widehat4: `M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z`,\n  // Widecheck paths are all inverted versions of widehat\n  widecheck1: `M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z`,\n  widecheck2: `M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z`,\n  widecheck3: `M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z`,\n  widecheck4: `M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z`,\n  // The next ten paths support reaction arrows from the mhchem package.\n  // Arrows for \\ce{<-->} are offset from xAxis by 0.22ex, per mhchem in LaTeX\n  // baraboveleftarrow is mostly from from glyph U+2190 in font KaTeX Main\n  baraboveleftarrow: `M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z`,\n  // Rightarrowabovebar is mostly from glyph U+2192, KaTeX Main\n  rightarrowabovebar: `M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z`,\n  // The short left harpoon has 0.5em (i.e. 500 units) kern on the left end.\n  // Ref from mhchem.sty: \\rlap{\\raisebox{-.22ex}{$\\kern0.5em\n  baraboveshortleftharpoon: `M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z`,\n  rightharpoonaboveshortbar: `M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z`,\n  shortbaraboveleftharpoon: `M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z`,\n  shortrightharpoonabovebar: `M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z`\n};\nfunction svgBodyToMarkup(svgBodyName) {\n  if (SVG_ACCENTS[svgBodyName]) {\n    const [vbWidth, vbHeight, height2] = SVG_ACCENTS[svgBodyName];\n    const result = `<span class=\"ML__stretchy\" style=\"height:${height2}em\"><svg width=\"100%\" height=\"${height2}em\" viewBox=\"0 0 ${vbWidth} ${vbHeight}\" preserveAspectRatio=\"none\" ><path fill=\"currentcolor\" d=\"${PATHS[svgBodyName]}\"></path></svg></span>`;\n    return `<span style=\"display:inline-block;height:${Math.floor(100 * height2 / 2) / 100}em;min-width:0\">${result}</span>`;\n  }\n  const [paths, minWidth, viewBoxHeight, align3] = SVG_BODY[svgBodyName];\n  let widthClasses;\n  let aligns;\n  const height = viewBoxHeight / 1e3;\n  if (paths.length === 3) {\n    widthClasses = [\"slice-1-of-3\", \"slice-2-of-3\", \"slice-3-of-3\"];\n    aligns = [\"xMinYMin\", \"xMidYMin\", \"xMaxYMin\"];\n  } else if (paths.length === 2) {\n    widthClasses = [\"slice-1-of-2\", \"slice-2-of-2\"];\n    aligns = [\"xMinYMin\", \"xMaxYMin\"];\n  } else {\n    widthClasses = [\"slice-1-of-1\"];\n    aligns = [align3];\n  }\n  const body = paths.map(\n    (path, i) => `<span class=\"${widthClasses[i]}\" style=height:${height}em><svg width=400em height=${height}em viewBox=\"0 0 400000 ${viewBoxHeight}\" preserveAspectRatio=\"${aligns[i]} slice\"><path fill=\"currentcolor\" d=\"${PATHS[path]}\"></path></svg></span>`\n  ).join(\"\");\n  return `<span style=\"display:inline-block;height:${height}em;min-width:${minWidth}em;\">${body}</span>`;\n}\nfunction svgBodyHeight(svgBodyName) {\n  if (SVG_BODY[svgBodyName]) return SVG_BODY[svgBodyName][2] / 1e3;\n  return SVG_ACCENTS[svgBodyName][2];\n}\n\n// src/core/grapheme-splitter.ts\nfunction stringToCodepoints(string) {\n  const result = [];\n  for (let i = 0; i < string.length; i++) {\n    let code = string.charCodeAt(i);\n    if (code === 13 && string.charCodeAt(i + 1) === 10) {\n      code = 10;\n      i++;\n    }\n    if (code === 13 || code === 12) code = 10;\n    if (code === 0) code = 65533;\n    if (code >= 55296 && code <= 56319) {\n      const nextCode = string.charCodeAt(i + 1);\n      if (nextCode >= 56320 && nextCode <= 57343) {\n        const lead = code - 55296;\n        const trail = nextCode - 56320;\n        code = 2 ** 16 + lead * 2 ** 10 + trail;\n        i++;\n      }\n    }\n    result.push(code);\n  }\n  return result;\n}\nvar ZWJ = 8205;\nvar EMOJI_COMBINATOR = [\n  [ZWJ, 1],\n  [65038, 2],\n  // VS-15: text presentation, VS-16: Emoji presentation\n  [127995, 5],\n  // EMOJI_MODIFIER_FITZPATRICK_TYPE 1-6\n  [129456, 4],\n  // Red hair..white hair\n  [917536, 96]\n  // EMOJI_TAG\n];\nvar emojiCombinator;\nvar REGIONAL_INDICATOR = [127462, 127487];\nfunction isEmojiCombinator(code) {\n  var _a3;\n  if (emojiCombinator === void 0) {\n    emojiCombinator = {};\n    for (const x of EMOJI_COMBINATOR)\n      for (let i = x[0]; i <= x[0] + x[1] - 1; i++) emojiCombinator[i] = true;\n  }\n  return (_a3 = emojiCombinator[code]) != null ? _a3 : false;\n}\nfunction isRegionalIndicator(code) {\n  return code >= REGIONAL_INDICATOR[0] && code <= REGIONAL_INDICATOR[1];\n}\nfunction splitGraphemes(string) {\n  if (/^[\\u0020-\\u00FF]*$/.test(string)) return string;\n  const result = [];\n  const codePoints = stringToCodepoints(string);\n  let index = 0;\n  while (index < codePoints.length) {\n    const code = codePoints[index++];\n    const next = codePoints[index];\n    if (next === ZWJ) {\n      const baseIndex = index - 1;\n      index += 2;\n      while (codePoints[index] === ZWJ) index += 2;\n      result.push(\n        String.fromCodePoint(\n          ...codePoints.slice(baseIndex, index - baseIndex + 1)\n        )\n      );\n    } else if (isEmojiCombinator(next)) {\n      const baseIndex = index - 1;\n      while (isEmojiCombinator(codePoints[index]))\n        index += codePoints[index] === ZWJ ? 2 : 1;\n      result.push(\n        String.fromCodePoint(\n          ...codePoints.slice(baseIndex, 2 * index - baseIndex - 1)\n        )\n      );\n    } else if (isRegionalIndicator(code)) {\n      index += 1;\n      result.push(String.fromCodePoint(...codePoints.slice(index - 2, 2)));\n    } else result.push(String.fromCodePoint(code));\n  }\n  return result;\n}\n\n// src/core/tokenizer.ts\nvar Tokenizer = class {\n  constructor(s) {\n    this.obeyspaces = false;\n    this.pos = 0;\n    this.s = splitGraphemes(s);\n  }\n  /**\n   * @return True if we reached the end of the stream\n   */\n  end() {\n    return this.pos >= this.s.length;\n  }\n  /**\n   * Return the next char and advance\n   */\n  get() {\n    return this.pos < this.s.length ? this.s[this.pos++] : \"\";\n  }\n  /**\n   * Return the next char, but do not advance\n   */\n  peek() {\n    return this.s[this.pos];\n  }\n  /**\n   * Return the next substring matching regEx and advance.\n   */\n  match(regEx) {\n    const execResult = typeof this.s === \"string\" ? regEx.exec(this.s.slice(this.pos)) : regEx.exec(this.s.slice(this.pos).join(\"\"));\n    if (execResult == null ? void 0 : execResult[0]) {\n      this.pos += execResult[0].length;\n      return execResult[0];\n    }\n    return \"\";\n  }\n  /**\n   * Return the next token, or null.\n   */\n  next() {\n    if (this.end()) return null;\n    if (!this.obeyspaces && this.match(/^[ \\f\\n\\r\\t\\v\\u00A0\\u2028\\u2029]+/)) {\n      return \"<space>\";\n    }\n    if (this.obeyspaces && this.match(/^[ \\f\\n\\r\\t\\v\\u00A0\\u2028\\u2029]/)) {\n      return \"<space>\";\n    }\n    const next = this.get();\n    if (next === \"\\\\\") {\n      if (!this.end()) {\n        let command = this.match(/^[a-zA-Z\\*]+/);\n        if (command) {\n          this.match(/^[ \\f\\n\\r\\t\\v\\u00A0\\u2028\\u2029]*/);\n        } else {\n          command = this.get();\n        }\n        return \"\\\\\" + command;\n      }\n    } else if (next === \"{\") {\n      return \"<{>\";\n    } else if (next === \"}\") {\n      return \"<}>\";\n    } else if (next === \"^\") {\n      if (this.peek() === \"^\") {\n        this.get();\n        const hex = this.match(\n          /^(\\^(\\^(\\^(\\^[\\da-f])?[\\da-f])?[\\da-f])?[\\da-f])?[\\da-f]{2}/\n        );\n        if (hex) {\n          return String.fromCodePoint(\n            Number.parseInt(hex.slice(hex.lastIndexOf(\"^\") + 1), 16)\n          );\n        }\n      }\n      return next;\n    } else if (next === \"#\") {\n      if (!this.end()) {\n        let isParameter = false;\n        if (/[\\d?@]/.test(this.peek())) {\n          isParameter = true;\n          if (this.pos + 1 < this.s.length) {\n            const after = this.s[this.pos + 1];\n            isParameter = /[^\\dA-Za-z]/.test(after);\n          }\n        }\n        if (isParameter) return \"#\" + this.get();\n        return \"#\";\n      }\n    } else if (next === \"$\") {\n      if (this.peek() === \"$\") {\n        this.get();\n        return \"<$$>\";\n      }\n      return \"<$>\";\n    }\n    return next;\n  }\n};\nfunction expand(lex, args) {\n  var _a3, _b3, _c2, _d2;\n  const result = [];\n  let token = lex.next();\n  if (token) {\n    if (token === \"\\\\relax\") {\n    } else if (token === \"\\\\noexpand\") {\n      token = lex.next();\n      if (token) result.push(token);\n    } else if (token === \"\\\\obeyspaces\") lex.obeyspaces = true;\n    else if (token === \"\\\\bgroup\") {\n      result.push(\"<{>\");\n    } else if (token === \"\\\\egroup\") {\n      result.push(\"<}>\");\n    } else if (token === \"\\\\string\") {\n      token = lex.next();\n      if (token) {\n        if (token.startsWith(\"\\\\\"))\n          for (const x of token) result.push(x === \"\\\\\" ? \"\\\\backslash\" : x);\n        else if (token === \"<{>\") result.push(\"\\\\{\");\n        else if (token === \"<space>\") result.push(\"~\");\n        else if (token === \"<}>\") result.push(\"\\\\}\");\n      }\n    } else if (token === \"\\\\csname\") {\n      while (lex.peek() === \"<space>\") lex.next();\n      let command = \"\";\n      let done = false;\n      let tokens = [];\n      do {\n        if (tokens.length === 0) {\n          if (/^#[\\d?@]$/.test(lex.peek())) {\n            const parameter = lex.get().slice(1);\n            tokens = tokenize(\n              (_b3 = (_a3 = args == null ? void 0 : args(parameter)) != null ? _a3 : args == null ? void 0 : args(\"?\")) != null ? _b3 : \"\\\\placeholder{}\",\n              args\n            );\n            token = tokens[0];\n          } else {\n            token = lex.next();\n            tokens = token ? [token] : [];\n          }\n        }\n        done = tokens.length === 0;\n        if (!done && token === \"\\\\endcsname\") {\n          done = true;\n          tokens.shift();\n        }\n        if (!done) {\n          done = token === \"<$>\" || token === \"<$$>\" || token === \"<{>\" || token === \"<}>\" || typeof token === \"string\" && token.length > 1 && token.startsWith(\"\\\\\");\n        }\n        if (!done) command += tokens.shift();\n      } while (!done);\n      if (command) result.push(\"\\\\\" + command);\n      result.push(...tokens);\n    } else if (token === \"\\\\endcsname\") {\n    } else if (token.length > 1 && token.startsWith(\"#\")) {\n      const parameter = token.slice(1);\n      result.push(\n        ...tokenize((_d2 = (_c2 = args == null ? void 0 : args(parameter)) != null ? _c2 : args == null ? void 0 : args(\"?\")) != null ? _d2 : \"\\\\placeholder{}\", args)\n      );\n    } else result.push(token);\n  }\n  return result;\n}\nfunction tokenize(s, args = null) {\n  if (!s) return [];\n  const lines = [];\n  let sep = \"\";\n  for (const line of s.toString().split(/\\r?\\n/)) {\n    if (sep) lines.push(sep);\n    sep = \" \";\n    const m = line.match(/((?:\\\\%)|[^%])*/);\n    if (m !== null) lines.push(m[0]);\n  }\n  const tokenizer = new Tokenizer(lines.join(\"\"));\n  const result = [];\n  do\n    result.push(...expand(tokenizer, args));\n  while (!tokenizer.end());\n  return result;\n}\nfunction joinLatex(segments) {\n  let sep = \"\";\n  const result = [];\n  for (const segment of segments) {\n    if (segment) {\n      if (sep && /^[a-zA-Z\\*]/.test(segment)) result.push(sep);\n      result.push(segment);\n      if (/^\\\\[a-zA-Z]+\\*?[\\\"\\'][^\\ ]+$/.test(segment)) result.push(\" \");\n      sep = /\\\\[a-zA-Z]+\\*?$/.test(segment) ? \" \" : \"\";\n    }\n  }\n  return result.join(\"\");\n}\nfunction latexCommand(command, ...args) {\n  console.assert(command.startsWith(\"\\\\\"));\n  if (args.length === 0) return command;\n  return joinLatex([command, ...args.map((x) => `{${x}}`)]);\n}\nfunction tokensToString(tokens) {\n  return joinLatex(\n    tokens.map(\n      (token) => {\n        var _a3;\n        return (_a3 = {\n          \"<space>\": \" \",\n          \"<$$>\": \"$$\",\n          \"<$>\": \"$\",\n          \"<{>\": \"{\",\n          \"<}>\": \"}\"\n        }[token]) != null ? _a3 : token;\n      }\n    )\n  );\n}\n\n// src/core/modes-utils.ts\nvar _Mode = class _Mode {\n  constructor(name) {\n    _Mode._registry[name] = this;\n  }\n  static createAtom(mode, command, style) {\n    return _Mode._registry[mode].createAtom(\n      command,\n      getDefinition(command, mode),\n      style\n    );\n  }\n  static serialize(atoms, options) {\n    var _a3;\n    if (!atoms || atoms.length === 0) return \"\";\n    if ((_a3 = options.skipStyles) != null ? _a3 : false) {\n      const body = [];\n      for (const run of getModeRuns(atoms)) {\n        const mode = _Mode._registry[run[0].mode];\n        body.push(...mode.serialize(run, options));\n      }\n      return joinLatex(body);\n    }\n    return joinLatex(emitFontSizeRun(atoms, options));\n  }\n  static getFont(mode, box, style) {\n    return _Mode._registry[mode].getFont(box, style);\n  }\n};\n_Mode._registry = {};\nvar Mode = _Mode;\nfunction getModeRuns(atoms) {\n  const result = [];\n  let run = [];\n  let currentMode = \"NONE\";\n  for (const atom of atoms) {\n    if (atom.type !== \"first\") {\n      if (atom.mode !== currentMode) {\n        if (run.length > 0) result.push(run);\n        run = [atom];\n        currentMode = atom.mode;\n      } else run.push(atom);\n    }\n  }\n  if (run.length > 0) result.push(run);\n  return result;\n}\nfunction weightString(atom) {\n  if (!atom || atom.mode !== \"math\") return \"\";\n  const { style } = atom;\n  if (!style) return \"\";\n  if (!style.variantStyle) return \"\";\n  if (style.variantStyle === \"bold\" || style.variantStyle === \"bolditalic\")\n    return \"bold\";\n  return \"\";\n}\nfunction variantString(atom) {\n  if (!atom) return \"\";\n  const { style } = atom;\n  if (!style) return \"\";\n  let result = style.variant;\n  if (result === void 0) return \"normal\";\n  if (![\n    \"calligraphic\",\n    \"fraktur\",\n    \"double-struck\",\n    \"script\",\n    \"monospace\",\n    \"sans-serif\"\n  ].includes(result) && style.variantStyle)\n    result += \"-\" + style.variantStyle;\n  return result;\n}\nfunction getPropertyRuns(atoms, property) {\n  const result = [];\n  let run = [];\n  let currentValue = void 0;\n  for (const atom of atoms) {\n    if (atom.type === \"first\") continue;\n    let value;\n    if (property === \"variant\") value = variantString(atom);\n    else if (property === \"bold\") value = weightString(atom);\n    else value = atom.style[property];\n    if (value === currentValue) {\n      run.push(atom);\n    } else {\n      if (run.length > 0) result.push(run);\n      run = [atom];\n      currentValue = value;\n    }\n  }\n  if (run.length > 0) result.push(run);\n  return result;\n}\nfunction emitColorRun(run, options) {\n  var _a3;\n  const { parent } = run[0];\n  const parentColor = parent == null ? void 0 : parent.style.color;\n  const result = [];\n  for (const modeRun of getModeRuns(run)) {\n    const mode = options.defaultMode;\n    for (const colorRun of getPropertyRuns(modeRun, \"color\")) {\n      const style = colorRun[0].style;\n      const body = Mode._registry[colorRun[0].mode].serialize(colorRun, __spreadProps(__spreadValues({}, options), {\n        defaultMode: mode === \"text\" ? \"text\" : \"math\"\n      }));\n      if (!options.skipStyles && style.color && style.color !== \"none\" && (!parent || parentColor !== style.color)) {\n        result.push(\n          latexCommand(\n            \"\\\\textcolor\",\n            (_a3 = style.verbatimColor) != null ? _a3 : style.color,\n            joinLatex(body)\n          )\n        );\n      } else result.push(joinLatex(body));\n    }\n  }\n  return result;\n}\nfunction emitBackgroundColorRun(run, options) {\n  const { parent } = run[0];\n  const parentColor = parent == null ? void 0 : parent.style.backgroundColor;\n  return getPropertyRuns(run, \"backgroundColor\").map((x) => {\n    var _a3;\n    if (x.length > 0 || x[0].type !== \"box\") {\n      const style = x[0].style;\n      if (style.backgroundColor && style.backgroundColor !== \"none\" && (!parent || parentColor !== style.backgroundColor)) {\n        return latexCommand(\n          \"\\\\colorbox\",\n          (_a3 = style.verbatimBackgroundColor) != null ? _a3 : style.backgroundColor,\n          joinLatex(emitColorRun(x, __spreadProps(__spreadValues({}, options), { defaultMode: \"text\" })))\n        );\n      }\n    }\n    return joinLatex(emitColorRun(x, options));\n  });\n}\nfunction emitFontSizeRun(run, options) {\n  if (run.length === 0) return [];\n  const { parent } = run[0];\n  const contextFontsize = parent == null ? void 0 : parent.style.fontSize;\n  const result = [];\n  for (const sizeRun of getPropertyRuns(run, \"fontSize\")) {\n    const fontsize = sizeRun[0].style.fontSize;\n    const body = emitBackgroundColorRun(sizeRun, options);\n    if (body) {\n      if (fontsize && fontsize !== \"auto\" && (!parent || contextFontsize !== fontsize)) {\n        result.push(\n          [\n            \"\",\n            \"\\\\tiny\",\n            \"\\\\scriptsize\",\n            \"\\\\footnotesize\",\n            \"\\\\small\",\n            \"\\\\normalsize\",\n            \"\\\\large\",\n            \"\\\\Large\",\n            \"\\\\LARGE\",\n            \"\\\\huge\",\n            \"\\\\Huge\"\n          ][fontsize],\n          ...body\n        );\n      } else result.push(...body);\n    }\n  }\n  return result;\n}\n\n// src/core/box.ts\nfunction boxType(type) {\n  if (!type) return void 0;\n  const result = {\n    mord: \"ord\",\n    mbin: \"bin\",\n    mop: \"op\",\n    mrel: \"rel\",\n    mopen: \"open\",\n    mclose: \"close\",\n    mpunct: \"punct\",\n    minner: \"inner\",\n    spacing: \"ignore\",\n    latex: \"latex\",\n    composition: \"inner\",\n    error: \"inner\",\n    placeholder: \"ord\",\n    supsub: \"ignore\"\n  }[type];\n  return result;\n}\nfunction atomsBoxType(atoms) {\n  if (atoms.length === 0) return \"ord\";\n  const first = boxType(atoms[0].type);\n  const last = boxType(atoms[atoms.length - 1].type);\n  if (first && first === last) return first;\n  return \"ord\";\n}\nfunction toString(arg1, arg2) {\n  if (typeof arg1 === \"string\") return arg1;\n  if (typeof arg1 === \"number\") {\n    console.assert(Number.isFinite(arg1));\n    const numValue = Math.ceil(100 * arg1) / 100;\n    if (numValue === 0) return \"0\";\n    return numValue.toString() + (arg2 != null ? arg2 : \"\");\n  }\n  return \"\";\n}\nvar Box = class _Box {\n  constructor(content, options) {\n    var _a3, _b3, _c2, _d2, _e;\n    if (typeof content === \"number\") this.value = String.fromCodePoint(content);\n    else if (typeof content === \"string\") this.value = content;\n    else if (isArray(content))\n      this.children = content.filter((x) => x !== null);\n    else if (content && content instanceof _Box) this.children = [content];\n    if (this.children) for (const child of this.children) child.parent = this;\n    this.type = (_a3 = options == null ? void 0 : options.type) != null ? _a3 : \"ignore\";\n    this.isSelected = (options == null ? void 0 : options.isSelected) === true;\n    if (options == null ? void 0 : options.caret) this.caret = options.caret;\n    this.classes = (_b3 = options == null ? void 0 : options.classes) != null ? _b3 : \"\";\n    this.isTight = (_c2 = options == null ? void 0 : options.isTight) != null ? _c2 : false;\n    if (options == null ? void 0 : options.attributes) this.attributes = options.attributes;\n    let fontName = options == null ? void 0 : options.fontFamily;\n    if ((options == null ? void 0 : options.style) && this.value) {\n      fontName = (_e = Mode.getFont((_d2 = options.mode) != null ? _d2 : \"math\", this, __spreadProps(__spreadValues({\n        variant: \"normal\"\n      }, options.style), {\n        letterShapeStyle: options.letterShapeStyle\n      }))) != null ? _e : void 0;\n    }\n    fontName || (fontName = \"Main-Regular\");\n    this._height = 0;\n    this._depth = 0;\n    this._width = 0;\n    this.hasExplicitWidth = false;\n    this.skew = 0;\n    this.italic = 0;\n    this.maxFontSize = 0;\n    this.scale = 1;\n    if ((options == null ? void 0 : options.maxFontSize) !== void 0)\n      this.maxFontSize = options.maxFontSize;\n    horizontalLayout(this, fontName);\n  }\n  set atomID(id) {\n    if (id === void 0 || id.length === 0) return;\n    this.id = id;\n  }\n  selected(isSelected) {\n    if (this.isSelected === isSelected) return;\n    this.isSelected = isSelected;\n    if (this.children)\n      for (const child of this.children) child.selected(isSelected);\n  }\n  setStyle(prop, value, unit) {\n    if (value === void 0) return;\n    const v = toString(value, unit);\n    if (v.length > 0) {\n      if (!this.cssProperties) this.cssProperties = {};\n      this.cssProperties[prop] = v;\n    }\n  }\n  setTop(top) {\n    if (Number.isFinite(top) && Math.abs(top) > 0.01) {\n      if (!this.cssProperties) this.cssProperties = {};\n      this.cssProperties.top = toString(top, \"em\");\n      this.height -= top;\n      this.depth += top;\n    }\n  }\n  get left() {\n    var _a3;\n    if ((_a3 = this.cssProperties) == null ? void 0 : _a3[\"margin-left\"])\n      return Number.parseFloat(this.cssProperties[\"margin-left\"]);\n    return 0;\n  }\n  set left(value) {\n    if (!Number.isFinite(value)) return;\n    if (value === 0) {\n      if (this.cssProperties) delete this.cssProperties[\"margin-left\"];\n    } else {\n      if (!this.cssProperties) this.cssProperties = {};\n      this.cssProperties[\"margin-left\"] = toString(value, \"em\");\n    }\n  }\n  set right(value) {\n    if (!Number.isFinite(value)) return;\n    if (value === 0) {\n      if (this.cssProperties) delete this.cssProperties[\"margin-right\"];\n    } else {\n      if (!this.cssProperties) this.cssProperties = {};\n      this.cssProperties[\"margin-right\"] = toString(value, \"em\");\n    }\n  }\n  set bottom(value) {\n    if (!Number.isFinite(value)) return;\n    if (value === 0) {\n      if (this.cssProperties) delete this.cssProperties[\"margin-bottom\"];\n    } else {\n      if (!this.cssProperties) this.cssProperties = {};\n      this.cssProperties[\"margin-bottom\"] = toString(value, \"em\");\n    }\n  }\n  get width() {\n    return this._width * this.scale;\n  }\n  set width(value) {\n    this._width = value;\n    this.hasExplicitWidth = true;\n  }\n  set softWidth(_value) {\n  }\n  get height() {\n    return this._height * this.scale;\n  }\n  set height(value) {\n    this._height = value;\n  }\n  get depth() {\n    return this._depth * this.scale;\n  }\n  set depth(value) {\n    this._depth = value;\n  }\n  /**\n   * Apply the context (color, backgroundColor, size) to the box.\n   */\n  wrap(context) {\n    const parent = context.parent;\n    if (!parent) return this;\n    if (context.isPhantom) this.setStyle(\"opacity\", 0);\n    const color = context.color;\n    if (color && color !== parent.color) this.setStyle(\"color\", color);\n    let backgroundColor = context.backgroundColor;\n    if (this.isSelected) backgroundColor = highlight(backgroundColor);\n    if (backgroundColor && backgroundColor !== parent.backgroundColor) {\n      this.setStyle(\"background-color\", backgroundColor);\n      this.setStyle(\"display\", \"inline-block\");\n    }\n    const scale = context.scalingFactor;\n    this.scale = scale;\n    this.skew *= scale;\n    this.italic *= scale;\n    return this;\n  }\n  /**\n   * Generate the HTML markup to represent this box.\n   */\n  toMarkup() {\n    var _a3, _b3, _c2, _d2;\n    let body = (_a3 = this.value) != null ? _a3 : \"\";\n    if (this.children) for (const box of this.children) body += box.toMarkup();\n    let svgMarkup = \"\";\n    if (this.svgBody) svgMarkup = svgBodyToMarkup(this.svgBody);\n    else if (this.svgOverlay) {\n      svgMarkup = '<span style=\"';\n      svgMarkup += \"display: inline-block;\";\n      svgMarkup += `height:${Math.floor(100 * (this.height + this.depth)) / 100}em;`;\n      svgMarkup += `vertical-align:${Math.floor(100 * this.depth) / 100}em;`;\n      svgMarkup += '\">';\n      svgMarkup += body;\n      svgMarkup += \"</span>\";\n      svgMarkup += '<svg style=\"position:absolute;overflow:visible;';\n      svgMarkup += `height:${Math.floor(100 * (this.height + this.depth)) / 100}em;`;\n      const padding2 = (_b3 = this.cssProperties) == null ? void 0 : _b3.padding;\n      if (padding2) {\n        svgMarkup += `top:${padding2};`;\n        svgMarkup += `left:${padding2};`;\n        svgMarkup += `width:calc(100% - 2 * ${padding2} );`;\n      } else svgMarkup += \"top:0;left:0;width:100%;\";\n      svgMarkup += \"z-index:2;\";\n      svgMarkup += '\"';\n      if (this.svgStyle) svgMarkup += this.svgStyle;\n      svgMarkup += ` viewBox=\"0 0 ${Math.floor(100 * this.width) / 100} ${Math.floor(100 * (this.height + this.depth)) / 100}\"`;\n      svgMarkup += `>${this.svgOverlay}</svg>`;\n    }\n    let props = \"\";\n    const classes = this.classes.split(\" \");\n    classes.push(\n      (_c2 = {\n        latex: \"ML__raw-latex\",\n        placeholder: \"ML__placeholder\",\n        error: \"ML__error\"\n      }[this.type]) != null ? _c2 : \"\"\n    );\n    if (this.caret === \"latex\") classes.push(\"ML__latex-caret\");\n    if (this.isSelected) classes.push(\"ML__selected\");\n    const classList = classes.length === 1 ? classes[0] : classes.filter((x, e, a) => x.length > 0 && a.indexOf(x) === e).join(\" \");\n    if (classList.length > 0) props += ` class=\"${classList}\"`;\n    if (this.id) props += ` data-atom-id=${this.id}`;\n    if (this.cssId) props += ` id=\"${this.cssId.replace(/ /g, \"-\")}\" `;\n    if (this.attributes) {\n      props += \" \" + Object.keys(this.attributes).map((x) => `${x}=\"${this.attributes[x]}\"`).join(\" \");\n    }\n    if (this.htmlData) {\n      const entries = this.htmlData.split(\",\");\n      for (const entry of entries) {\n        const matched = entry.match(/([^=]+)=(.+$)/);\n        if (matched) {\n          const key = matched[1].trim().replace(/ /g, \"-\");\n          if (key) props += ` data-${key}=\"${matched[2]}\" `;\n        } else {\n          const key = entry.trim().replace(/ /g, \"-\");\n          if (key) props += ` data-${key} `;\n        }\n      }\n    }\n    const cssProps = (_d2 = this.cssProperties) != null ? _d2 : {};\n    if (this.hasExplicitWidth) {\n      if (cssProps.width === void 0)\n        cssProps.width = `${Math.ceil(this._width * 100) / 100}em`;\n    }\n    const styles = Object.keys(cssProps).map((x) => `${x}:${cssProps[x]}`);\n    if (this.scale !== void 0 && this.scale !== 1 && (body.length > 0 || svgMarkup.length > 0))\n      styles.push(`font-size: ${Math.ceil(this.scale * 1e4) / 100}%`);\n    if (this.htmlStyle) {\n      const entries = this.htmlStyle.split(\";\");\n      let styleString = \"\";\n      for (const entry of entries) {\n        const matched = entry.match(/([^=]+):(.+$)/);\n        if (matched) {\n          const key = matched[1].trim().replace(/ /g, \"-\");\n          if (key) styleString += `${key}:${matched[2]};`;\n        }\n      }\n      if (styleString) props += ` style=\"${styleString}\"`;\n    }\n    if (styles.length > 0) props += ` style=\"${styles.join(\";\")}\"`;\n    let result = \"\";\n    if (props.length > 0 || svgMarkup.length > 0)\n      result = `<span${props}>${body}${svgMarkup}</span>`;\n    else result = body;\n    if (this.caret === \"text\") result += '<span class=\"ML__text-caret\"></span>';\n    else if (this.caret === \"math\") result += '<span class=\"ML__caret\"></span>';\n    return result;\n  }\n  /**\n   * Can this box be coalesced with 'box'?\n   * This is used to 'coalesce' (i.e. group together) a series of boxes that are\n   * identical except for their value, and to avoid generating redundant boxes.\n   * That is: '12' ->\n   *      \"<span class='crm'>12</span>\"\n   * rather than:\n   *      \"<span class='crm'>1</span><span class='crm'>2</span>\"\n   */\n  tryCoalesceWith(box) {\n    if (this.svgBody || !this.value) return false;\n    if (box.svgBody || !box.value) return false;\n    const hasChildren = this.children && this.children.length > 0;\n    const boxHasChildren = box.children && box.children.length > 0;\n    if (hasChildren || boxHasChildren) return false;\n    if (box.cssProperties || this.cssProperties) {\n      for (const prop of [\n        \"border\",\n        \"border-left\",\n        \"border-right\",\n        \"border-right-width\",\n        \"left\",\n        \"margin\",\n        \"margin-left\",\n        \"margin-right\",\n        \"padding\",\n        \"position\",\n        \"width\"\n      ]) {\n        if (box.cssProperties && prop in box.cssProperties) return false;\n        if (this.cssProperties && prop in this.cssProperties) return false;\n      }\n    }\n    const thisStyleCount = this.cssProperties ? Object.keys(this.cssProperties).length : 0;\n    const boxStyleCount = box.cssProperties ? Object.keys(box.cssProperties).length : 0;\n    if (thisStyleCount !== boxStyleCount) return false;\n    if (thisStyleCount > 0) {\n      for (const prop of Object.keys(this.cssProperties)) {\n        if (this.cssProperties[prop] !== box.cssProperties[prop])\n          return false;\n      }\n    }\n    const classes = this.classes.trim().replace(/\\s+/g, \" \").split(\" \");\n    const boxClasses = box.classes.trim().replace(/\\s+/g, \" \").split(\" \");\n    if (classes.length !== boxClasses.length) return false;\n    classes.sort();\n    boxClasses.sort();\n    for (const [i, class_] of classes.entries()) {\n      if (class_ === \"ML__vertical-separator\") return false;\n      if (class_ !== boxClasses[i]) return false;\n    }\n    this.value += box.value;\n    this.height = Math.max(this.height, box.height);\n    this.depth = Math.max(this.depth, box.depth);\n    this._width = this._width + box._width;\n    this.maxFontSize = Math.max(this.maxFontSize, box.maxFontSize);\n    this.italic = box.italic;\n    return true;\n  }\n};\nfunction coalesceRecursive(boxes) {\n  if (!boxes || boxes.length === 0) return [];\n  boxes[0].children = coalesceRecursive(boxes[0].children);\n  const result = [boxes[0]];\n  for (let i = 1; i < boxes.length; i++) {\n    if (!result[result.length - 1].tryCoalesceWith(boxes[i])) {\n      boxes[i].children = coalesceRecursive(boxes[i].children);\n      result.push(boxes[i]);\n    }\n  }\n  return result;\n}\nfunction coalesce(box) {\n  if (box.children) box.children = coalesceRecursive(box.children);\n  return box;\n}\nfunction makeStruts(content, options) {\n  if (!content) return new Box(null, options);\n  const topStrut = new Box(null, { classes: \"ML__strut\", type: \"ignore\" });\n  topStrut.setStyle(\"height\", Math.max(0, content.height), \"em\");\n  const struts = [topStrut];\n  if (content.depth !== 0) {\n    const bottomStrut = new Box(null, {\n      classes: \"ML__strut--bottom\",\n      type: \"ignore\"\n    });\n    bottomStrut.setStyle(\"height\", content.height + content.depth, \"em\");\n    bottomStrut.setStyle(\"vertical-align\", -content.depth, \"em\");\n    struts.push(bottomStrut);\n  }\n  struts.push(content);\n  return new Box(struts, __spreadProps(__spreadValues({}, options), { type: \"lift\" }));\n}\nfunction makeSVGBox(svgBodyName) {\n  const height = svgBodyHeight(svgBodyName) / 2;\n  const box = new Box(null, { maxFontSize: 0 });\n  box.height = height + 0.166;\n  box.depth = height - 0.166;\n  box.svgBody = svgBodyName;\n  return box;\n}\nfunction horizontalLayout(box, fontName) {\n  var _a3;\n  if (box.type === \"latex\") {\n    box.height = 0.9;\n    box.depth = 0.2;\n    box._width = 1;\n    return;\n  }\n  if (box.value) {\n    box.height = -Infinity;\n    box.depth = -Infinity;\n    box._width = 0;\n    box.skew = -Infinity;\n    box.italic = -Infinity;\n    for (let i = 0; i < box.value.length; i++) {\n      const metrics = getCharacterMetrics(box.value.codePointAt(i), fontName);\n      box.height = Math.max(box.height, metrics.height);\n      box.depth = Math.max(box.depth, metrics.depth);\n      box._width += metrics.width;\n      box.skew = metrics.skew;\n      box.italic = metrics.italic;\n    }\n    return;\n  }\n  if (box.children && box.children.length > 0) {\n    let height = -Infinity;\n    let depth = -Infinity;\n    let maxFontSize = 0;\n    for (const child of box.children) {\n      if (child.height > height) height = child.height;\n      if (child.depth > depth) depth = child.depth;\n      maxFontSize = Math.max(maxFontSize, (_a3 = child.maxFontSize) != null ? _a3 : 0);\n    }\n    box.height = height;\n    box.depth = depth;\n    box._width = box.children.reduce((acc, x) => acc + x.width, 0);\n    box.maxFontSize = maxFontSize;\n  }\n}\n\n// src/core/v-box.ts\nfunction getVListChildrenAndDepth(params) {\n  if (\"individualShift\" in params) {\n    const oldChildren = params.individualShift;\n    let prevChild = oldChildren[0];\n    if (prevChild == null) return [null, 0];\n    const children = [prevChild];\n    const depth = -prevChild.shift - prevChild.box.depth;\n    let currPos = depth;\n    for (let i = 1; i < oldChildren.length; i++) {\n      const child = oldChildren[i];\n      const diff = -child.shift - currPos - child.box.depth;\n      const size = diff - (prevChild.box.height + prevChild.box.depth);\n      currPos = currPos + diff;\n      children.push(size);\n      children.push(child);\n      prevChild = child;\n    }\n    return [children, depth];\n  }\n  if (\"top\" in params) {\n    let bottom = params.top;\n    for (const child of params.children) {\n      bottom -= typeof child === \"number\" ? child : child.box.height + child.box.depth;\n    }\n    return [params.children, bottom];\n  } else if (\"bottom\" in params) return [params.children, -params.bottom];\n  else if (\"firstBaseline\" in params) {\n    const firstChild = params.firstBaseline[0];\n    if (typeof firstChild === \"number\")\n      throw new Error(\"First child must be an element.\");\n    return [params.firstBaseline, -firstChild.box.depth];\n  } else if (\"shift\" in params) {\n    const firstChild = params.children[0];\n    if (typeof firstChild === \"number\")\n      throw new Error(\"First child must be an element.\");\n    return [params.children, -firstChild.box.depth - params.shift];\n  }\n  return [null, 0];\n}\nfunction makeRows(params) {\n  var _a3;\n  const [children, depth] = getVListChildrenAndDepth(params);\n  if (!children) return [[], 0, 0];\n  const pstrut = new Box(null, { classes: \"ML__pstrut\" });\n  let pstrutSize = 0;\n  for (const child of children) {\n    if (typeof child !== \"number\") {\n      const box = child.box;\n      pstrutSize = Math.max(pstrutSize, box.maxFontSize, box.height);\n    }\n  }\n  pstrutSize += 2;\n  pstrut.height = pstrutSize;\n  pstrut.setStyle(\"height\", pstrutSize, \"em\");\n  const realChildren = [];\n  let minPos = depth;\n  let maxPos = depth;\n  let currPos = depth;\n  let width = 0;\n  for (const child of children) {\n    if (typeof child === \"number\") currPos += child;\n    else {\n      const box = child.box;\n      const classes = (_a3 = child.classes) != null ? _a3 : [];\n      const childWrap = new Box([pstrut, box], {\n        classes: classes.join(\" \"),\n        style: child.style\n      });\n      box.setStyle(\"height\", box.height + box.depth, \"em\");\n      box.setStyle(\"display\", \"inline-block\");\n      childWrap.setStyle(\"top\", -pstrutSize - currPos - box.depth, \"em\");\n      if (child.marginLeft)\n        childWrap.setStyle(\"margin-left\", child.marginLeft, \"em\");\n      if (child.marginRight)\n        childWrap.setStyle(\"margin-right\", child.marginRight, \"em\");\n      realChildren.push(childWrap);\n      currPos += box.height + box.depth;\n      width = Math.max(width, childWrap.width);\n    }\n    minPos = Math.min(minPos, currPos);\n    maxPos = Math.max(maxPos, currPos);\n  }\n  realChildren.forEach((child) => {\n    child.softWidth = width;\n  });\n  const vlist = new Box(realChildren, { classes: \"ML__vlist\" });\n  vlist.softWidth = width;\n  vlist.height = maxPos;\n  vlist.setStyle(\"height\", maxPos, \"em\");\n  if (minPos >= 0)\n    return [[new Box(vlist, { classes: \"ML__vlist-r\" })], maxPos, -minPos];\n  const depthStrut = new Box(new Box(null), { classes: \"ML__vlist\" });\n  depthStrut.height = -minPos;\n  depthStrut.setStyle(\"height\", -minPos, \"em\");\n  const topStrut = new Box(8203, {\n    classes: \"ML__vlist-s\",\n    maxFontSize: 0\n  });\n  topStrut.softWidth = 0;\n  topStrut.height = 0;\n  topStrut.depth = 0;\n  return [\n    [\n      new Box([vlist, topStrut], { classes: \"ML__vlist-r\" }),\n      new Box(depthStrut, { classes: \"ML__vlist-r\" })\n    ],\n    maxPos,\n    -minPos\n  ];\n}\nvar VBox = class extends Box {\n  constructor(content, options) {\n    var _a3;\n    const [rows, height, depth] = makeRows(content);\n    super(rows.length === 1 ? rows[0] : rows, {\n      type: options == null ? void 0 : options.type,\n      classes: ((_a3 = options == null ? void 0 : options.classes) != null ? _a3 : \"\") + \" ML__vlist-t\" + (rows.length === 2 ? \" ML__vlist-t2\" : \"\")\n    });\n    this.height = height;\n    this.depth = depth;\n    this.softWidth = rows.reduce((acc, row) => Math.max(acc, row.width), 0);\n  }\n};\nfunction makeLimitsStack(context, options) {\n  var _a3, _b3, _c2, _d2, _e;\n  const metrics = context.metrics;\n  const base = new Box(options.base);\n  const baseShift = (_a3 = options.baseShift) != null ? _a3 : 0;\n  const slant = (_b3 = options.slant) != null ? _b3 : 0;\n  let aboveShift = 0;\n  let belowShift = 0;\n  if (options.above) {\n    aboveShift = (_c2 = options.aboveShift) != null ? _c2 : Math.max(\n      metrics.bigOpSpacing1,\n      metrics.bigOpSpacing3 - options.above.depth\n    );\n  }\n  if (options.below) {\n    belowShift = (_d2 = options.belowShift) != null ? _d2 : Math.max(\n      metrics.bigOpSpacing2,\n      metrics.bigOpSpacing4 - options.below.height\n    );\n  }\n  let result = null;\n  if (options.below && options.above) {\n    const bottom = metrics.bigOpSpacing5 + options.below.height + options.below.depth + belowShift + base.depth + baseShift;\n    result = new VBox({\n      bottom,\n      children: [\n        metrics.bigOpSpacing5,\n        {\n          box: options.below,\n          marginLeft: -slant,\n          classes: [\"ML__center\"]\n        },\n        belowShift,\n        //  We need to center the base to account for the case where the\n        // above/below is wider\n        { box: base, classes: [\"ML__center\"] },\n        aboveShift,\n        {\n          box: options.above,\n          marginLeft: slant,\n          classes: [\"ML__center\"]\n        },\n        metrics.bigOpSpacing5\n      ]\n    }).wrap(context);\n  } else if (options.below && !options.above) {\n    result = new VBox({\n      top: base.height - baseShift,\n      children: [\n        metrics.bigOpSpacing5,\n        {\n          box: options.below,\n          marginLeft: -slant,\n          classes: [\"ML__center\"]\n        },\n        belowShift,\n        { box: base, classes: [\"ML__center\"] }\n      ]\n    }).wrap(context);\n  } else if (!options.below && options.above) {\n    const bottom = base.depth + baseShift;\n    result = new VBox({\n      bottom,\n      children: [\n        { box: base, classes: [\"ML__center\"] },\n        aboveShift,\n        {\n          box: options.above,\n          marginLeft: slant,\n          classes: [\"ML__center\"]\n        },\n        metrics.bigOpSpacing5\n      ]\n    }).wrap(context);\n  } else {\n    const bottom = base.depth + baseShift;\n    result = new VBox({\n      bottom,\n      children: [{ box: base }, metrics.bigOpSpacing5]\n    }).wrap(context);\n  }\n  return new Box(result, { type: (_e = options.type) != null ? _e : \"op\" });\n}\n\n// src/core/mathstyle.ts\nvar D = 7;\nvar Dc = 6;\nvar T = 5;\nvar Tc = 4;\nvar S = 3;\nvar Sc = 2;\nvar SS = 1;\nvar SSc = 0;\nvar Mathstyle = class {\n  constructor(id, sizeDelta, cramped) {\n    this.id = id;\n    this.sizeDelta = sizeDelta;\n    this.cramped = cramped;\n    const metricsIndex = { \"-4\": 2, \"-3\": 1, 0: 0 }[sizeDelta];\n    this.metrics = Object.keys(FONT_METRICS).reduce((acc, x) => {\n      return __spreadProps(__spreadValues({}, acc), { [x]: FONT_METRICS[x][metricsIndex] });\n    }, {});\n  }\n  getFontSize(size) {\n    return Math.max(1, size + this.sizeDelta);\n  }\n  /**\n   * Get the style of a superscript given a base in the current style.\n   */\n  get sup() {\n    return MATHSTYLES[[SSc, SS, SSc, SS, Sc, S, Sc, S][this.id]];\n  }\n  /**\n   * Get the style of a subscript given a base in the current style.\n   */\n  get sub() {\n    return MATHSTYLES[[SSc, SSc, SSc, SSc, Sc, Sc, Sc, Sc][this.id]];\n  }\n  /**\n   * Get the style of a fraction numerator given the fraction in the current\n   * style.\n   * See TeXBook p 141.\n   */\n  get fracNum() {\n    return MATHSTYLES[[SSc, SS, SSc, SS, Sc, S, Tc, T][this.id]];\n  }\n  /**\n   * Get the style of a fraction denominator given the fraction in the current\n   * style.\n   * See TeXBook p 141.\n   */\n  get fracDen() {\n    return MATHSTYLES[[SSc, SSc, SSc, SSc, Sc, Sc, Tc, Tc][this.id]];\n  }\n  /**\n   * Get the cramped version of a style (in particular, cramping a cramped style\n   * doesn't change the style).\n   */\n  get cramp() {\n    return MATHSTYLES[[SSc, SSc, Sc, Sc, Tc, Tc, Dc, Dc][this.id]];\n  }\n  /**\n   * Return if this style is tightly spaced (scriptstyle/scriptscriptstyle)\n   */\n  get isTight() {\n    return this.sizeDelta < 0;\n  }\n};\nvar NUMERIC_MATHSTYLES = {\n  7: new Mathstyle(D, 0, false),\n  6: new Mathstyle(Dc, 0, true),\n  5: new Mathstyle(T, 0, false),\n  4: new Mathstyle(Tc, 0, true),\n  3: new Mathstyle(S, -3, false),\n  2: new Mathstyle(Sc, -3, true),\n  1: new Mathstyle(SS, -4, false),\n  0: new Mathstyle(SSc, -4, true)\n};\nvar MATHSTYLES = __spreadProps(__spreadValues({}, NUMERIC_MATHSTYLES), {\n  displaystyle: NUMERIC_MATHSTYLES[D],\n  textstyle: NUMERIC_MATHSTYLES[T],\n  scriptstyle: NUMERIC_MATHSTYLES[S],\n  scriptscriptstyle: NUMERIC_MATHSTYLES[SS]\n});\n\n// src/core/registers-utils.ts\nfunction convertDimensionToPt(value, precision) {\n  var _a3;\n  if (!value) return 0;\n  const f = {\n    pt: 1,\n    mm: 7227 / 2540,\n    cm: 7227 / 254,\n    ex: 35271 / 8192,\n    px: 3 / 4,\n    em: PT_PER_EM,\n    bp: 803 / 800,\n    dd: 1238 / 1157,\n    pc: 12,\n    in: 72.27,\n    mu: 10 / 18\n  }[(_a3 = value.unit) != null ? _a3 : \"pt\"];\n  if (Number.isFinite(precision)) {\n    const factor = 10 ** precision;\n    return Math.round(value.dimension / PT_PER_EM * f * factor) / factor;\n  }\n  return value.dimension * f;\n}\nfunction convertDimensionToEm(value, precision) {\n  if (value === null) return 0;\n  const result = convertDimensionToPt(value) / PT_PER_EM;\n  if (Number.isFinite(precision)) {\n    const factor = 10 ** precision;\n    return Math.round(result * factor) / factor;\n  }\n  return result;\n}\nfunction serializeDimension(value) {\n  var _a3;\n  return `${value.dimension}${(_a3 = value.unit) != null ? _a3 : \"pt\"}`;\n}\nfunction serializeGlue(value) {\n  let result = serializeDimension(value.glue);\n  if (value.grow && value.grow.dimension !== 0)\n    result += ` plus ${serializeDimension(value.grow)}`;\n  if (value.shrink && value.shrink.dimension !== 0)\n    result += ` minus ${serializeDimension(value.shrink)}`;\n  return result;\n}\nfunction serializeLatexValue(value) {\n  var _a3, _b3;\n  if (value === null || value === void 0) return null;\n  let result = \"\";\n  if (\"dimension\" in value) result = `${value.dimension}${(_a3 = value.unit) != null ? _a3 : \"pt\"}`;\n  if (\"glue\" in value) result = serializeGlue(value);\n  if (\"number\" in value) {\n    if (!(\"base\" in value) || value.base === \"decimal\")\n      result = Number(value.number).toString();\n    else if (value.base === \"alpha\")\n      result = `\\`${String.fromCodePoint(value.number)}`;\n    else {\n      const i = Math.round(value.number) >>> 0;\n      if (value.base === \"hexadecimal\") {\n        result = Number(i).toString(16).toUpperCase();\n        if (i <= 255) result = result.padStart(2, \"0\");\n        else if (i <= 65535) result = result.padStart(4, \"0\");\n        else if (i <= 16777215) result = result.padStart(6, \"0\");\n        else result = result.padStart(8, \"0\");\n        result = `\"${result}`;\n      } else if (value.base === \"octal\") {\n        result = Number(i).toString(8);\n        if (i <= 63) result = result.padStart(2, \"0\");\n        else if (i <= 30583) result = result.padStart(4, \"0\");\n        else result = result.padStart(8, \"0\");\n        result = `'${result}`;\n      }\n    }\n  }\n  if (\"register\" in value) {\n    if (\"factor\" in value) {\n      if (value.factor === -1) result = \"-\";\n      else if (value.factor !== 1) result = Number(value.factor).toString();\n    }\n    if (\"global\" in value && value.global) result += \"\\\\global\";\n    result += `\\\\${value.register}`;\n  }\n  if (\"string\" in value) result = value.string;\n  if ((_b3 = value.relax) != null ? _b3 : false) result += \"\\\\relax\";\n  return result;\n}\nfunction multiplyLatexValue(value, factor) {\n  if (value === null || value === void 0) return null;\n  if (\"number\" in value) return __spreadProps(__spreadValues({}, value), { number: value.number * factor });\n  if (\"register\" in value) {\n    if (\"factor\" in value && value.factor)\n      return __spreadProps(__spreadValues({}, value), { factor: value.factor * factor });\n    return __spreadProps(__spreadValues({}, value), { factor });\n  }\n  if (\"dimension\" in value)\n    return __spreadProps(__spreadValues({}, value), { dimension: value.dimension * factor });\n  if (\"glue\" in value) {\n    if (value.shrink && value.grow) {\n      return {\n        glue: multiplyLatexValue(value.glue, factor),\n        shrink: multiplyLatexValue(value.shrink, factor),\n        grow: multiplyLatexValue(value.grow, factor)\n      };\n    }\n    if (value.shrink) {\n      return {\n        glue: multiplyLatexValue(value.glue, factor),\n        shrink: multiplyLatexValue(value.shrink, factor)\n      };\n    }\n    if (value.grow) {\n      return {\n        glue: multiplyLatexValue(value.glue, factor),\n        grow: multiplyLatexValue(value.grow, factor)\n      };\n    }\n    return {\n      glue: multiplyLatexValue(value.glue, factor)\n    };\n  }\n  return null;\n}\n\n// src/core/registers.ts\nvar DEFAULT_REGISTERS = {\n  \"p@\": { dimension: 1 },\n  \"z@\": { dimension: 0 },\n  \"maxdimen\": { dimension: 16383.99999 },\n  \"hfuzz\": { dimension: 0.1 },\n  \"vfuzz\": { dimension: 0.1 },\n  \"overfullrule\": { dimension: 5 },\n  \"hsize\": { dimension: 6.5, unit: \"in\" },\n  \"vsize\": { dimension: 8.9, unit: \"in\" },\n  \"parindent\": { dimension: 20 },\n  \"maxdepth\": { dimension: 4 },\n  \"splitmaxdepth\": { register: \"maxdimen\" },\n  \"boxmaxdepth\": { register: \"maxdimen\" },\n  \"delimitershortfall\": { dimension: 5 },\n  //      @todo used in makeLeftRightDelim()\n  \"nulldelimiterspace\": { dimension: 1.2, unit: \"pt\" },\n  \"scriptspace\": { dimension: 0.5 },\n  // In pt.\n  \"topskip\": { dimension: 10 },\n  \"splittopskip\": { dimension: 10 },\n  \"normalbaselineskip\": { dimension: 12 },\n  \"normallineskip\": { dimension: 1 },\n  \"normallineskiplimit\": { dimension: 0 },\n  // The vertical space between the lines for all math expressions which\n  // allow multiple lines (see array, multline)\n  \"jot\": { dimension: 3 },\n  // The space between adjacent `|` columns in an array definition.\n  // From article.cls.txt:455\n  \"doublerulesep\": { dimension: 2 },\n  // The width of separator lines in {array} environments.\n  \"arrayrulewidth\": { dimension: 0.4 },\n  \"arraycolsep\": { dimension: 5 },\n  // Two values from LaTeX source2e:\n  \"fboxsep\": { dimension: 3 },\n  // From letter.dtx:1626\n  \"fboxrule\": { dimension: 0.4 },\n  // From letter.dtx:1627\n  \"z@skip\": {\n    glue: { dimension: 0 },\n    shrink: { dimension: 0 },\n    grow: { dimension: 0 }\n  },\n  \"hideskip\": {\n    glue: { dimension: -1e3 },\n    grow: { dimension: 1, unit: \"fill\" }\n  },\n  // LaTeX\n  \"@flushglue\": {\n    glue: { dimension: 0 },\n    grow: { dimension: 1, unit: \"fill\" }\n  },\n  // LaTeX\n  \"parskip\": {\n    glue: { dimension: 0 },\n    grow: { dimension: 1 }\n  },\n  // @todo  the \"shortskip\" are used if the formula starts to the right of the\n  // line before (i.e. centered and short line before)\n  \"abovedisplayskip\": {\n    glue: { dimension: 12 },\n    grow: { dimension: 3 },\n    shrink: { dimension: 9 }\n  },\n  \"abovedisplayshortskip\": {\n    glue: { dimension: 0 },\n    grow: { dimension: 3 }\n  },\n  \"belowdisplayskip\": {\n    glue: { dimension: 12 },\n    grow: { dimension: 3 },\n    shrink: { dimension: 9 }\n  },\n  \"belowdisplayshortskip\": {\n    glue: { dimension: 7 },\n    grow: { dimension: 3 },\n    shrink: { dimension: 4 }\n  },\n  \"parfillskip\": {\n    glue: { dimension: 0 },\n    grow: { dimension: 1, unit: \"fil\" }\n  },\n  \"thinmuskip\": { glue: { dimension: 3, unit: \"mu\" } },\n  \"medmuskip\": {\n    glue: { dimension: 4, unit: \"mu\" },\n    grow: { dimension: 2, unit: \"mu\" },\n    shrink: { dimension: 4, unit: \"mu\" }\n  },\n  \"thickmuskip\": {\n    glue: { dimension: 5, unit: \"mu\" },\n    grow: { dimension: 5, unit: \"mu\" }\n  },\n  \"smallskipamount\": {\n    glue: { dimension: 3 },\n    grow: { dimension: 1 },\n    shrink: { dimension: 1 }\n  },\n  \"medskipamount\": {\n    glue: { dimension: 6 },\n    grow: { dimension: 2 },\n    shrink: { dimension: 3 }\n  },\n  \"bigskipamount\": {\n    glue: { dimension: 12 },\n    grow: { dimension: 2 },\n    shrink: { dimension: 4 }\n  },\n  // From TeXBook p.348\n  // See also https://ctan.math.washington.edu/tex-archive/info/macros2e/macros2e.pdf\n  // 'voidb@x'\n  \"pretolerance\": 100,\n  \"tolerance\": 200,\n  \"hbadness\": 1e3,\n  \"vbadness\": 1e3,\n  \"linepenalty\": 10,\n  \"hyphenpenalty\": 50,\n  \"exhyphenpenalty\": 50,\n  \"binoppenalty\": 700,\n  \"relpenalty\": 500,\n  \"clubpenalty\": 150,\n  \"widowpenalty\": 150,\n  \"displaywidowpenalty\": 50,\n  \"brokenpenalty\": 100,\n  \"predisplaypenalty\": 1e4,\n  \"doublehyphendemerits\": 1e4,\n  \"finalhyphendemerits\": 5e3,\n  \"adjdemerits\": 1e4,\n  \"tracinglostchars\": 1,\n  \"uchyph\": 1,\n  \"delimiterfactor\": 901,\n  \"defaulthyphenchar\": \"\\\\-\",\n  \"defaultskewchar\": -1,\n  \"newlinechar\": -1,\n  \"showboxbreadth\": 5,\n  \"showboxdepth\": 3,\n  \"errorcontextlines\": 5,\n  \"interdisplaylinepenalty\": 100,\n  \"interfootnotelinepenalty\": 100,\n  \"baselineSkip\": 1.2,\n  \"arraystretch\": 1,\n  \"month\": (/* @__PURE__ */ new Date()).getMonth() + 1,\n  \"day\": (/* @__PURE__ */ new Date()).getDate(),\n  \"year\": (/* @__PURE__ */ new Date()).getFullYear()\n};\nfunction getDefaultRegisters() {\n  return __spreadValues({}, DEFAULT_REGISTERS);\n}\n\n// src/core/context-utils.ts\nfunction getDefaultContext() {\n  return {\n    registers: getDefaultRegisters(),\n    smartFence: false,\n    renderPlaceholder: void 0,\n    placeholderSymbol: \"\\u25A2\",\n    letterShapeStyle: l10n.locale.startsWith(\"fr\") ? \"french\" : \"tex\",\n    minFontScale: 0,\n    maxMatrixCols: 10,\n    colorMap: defaultColorMap,\n    backgroundColorMap: defaultBackgroundColorMap,\n    getMacro: (token) => getMacroDefinition(token, getMacros())\n  };\n}\n\n// src/core/context.ts\nvar Context = class _Context {\n  constructor(options, style) {\n    var _a3, _b3, _c2, _d2, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;\n    let template;\n    if (options == null ? void 0 : options.parent) {\n      this.parent = options.parent;\n      template = options.parent;\n      this.registers = {};\n    } else {\n      template = __spreadValues(__spreadValues({}, getDefaultContext()), (_a3 = options == null ? void 0 : options.from) != null ? _a3 : {});\n      this.registers = template.registers;\n    }\n    if (template.atomIdsSettings)\n      this.atomIdsSettings = __spreadValues({}, template.atomIdsSettings);\n    this.renderPlaceholder = template.renderPlaceholder;\n    this.isPhantom = (_d2 = (_c2 = options == null ? void 0 : options.isPhantom) != null ? _c2 : (_b3 = this.parent) == null ? void 0 : _b3.isPhantom) != null ? _d2 : false;\n    this.letterShapeStyle = template.letterShapeStyle;\n    this.minFontScale = template.minFontScale;\n    this.maxMatrixCols = template.maxMatrixCols;\n    if ((style == null ? void 0 : style.color) && style.color !== \"none\") this.color = style.color;\n    else this.color = (_f = (_e = this.parent) == null ? void 0 : _e.color) != null ? _f : \"\";\n    if ((style == null ? void 0 : style.backgroundColor) && style.backgroundColor !== \"none\")\n      this.backgroundColor = style.backgroundColor;\n    else this.backgroundColor = (_h = (_g = this.parent) == null ? void 0 : _g.backgroundColor) != null ? _h : \"\";\n    if ((style == null ? void 0 : style.fontSize) && style.fontSize !== \"auto\" && style.fontSize !== ((_i = this.parent) == null ? void 0 : _i.size))\n      this.size = style.fontSize;\n    else this.size = (_k = (_j = this.parent) == null ? void 0 : _j.size) != null ? _k : DEFAULT_FONT_SIZE;\n    let mathstyle = (_m = (_l = this.parent) == null ? void 0 : _l.mathstyle) != null ? _m : MATHSTYLES.displaystyle;\n    if (typeof (options == null ? void 0 : options.mathstyle) === \"string\") {\n      if (template instanceof _Context) {\n        switch (options.mathstyle) {\n          case \"cramp\":\n            mathstyle = mathstyle.cramp;\n            break;\n          case \"superscript\":\n            mathstyle = mathstyle.sup;\n            break;\n          case \"subscript\":\n            mathstyle = mathstyle.sub;\n            break;\n          case \"numerator\":\n            mathstyle = mathstyle.fracNum;\n            break;\n          case \"denominator\":\n            mathstyle = mathstyle.fracDen;\n            break;\n        }\n      }\n      switch (options.mathstyle) {\n        case \"textstyle\":\n          mathstyle = MATHSTYLES.textstyle;\n          break;\n        case \"displaystyle\":\n          mathstyle = MATHSTYLES.displaystyle;\n          break;\n        case \"scriptstyle\":\n          mathstyle = MATHSTYLES.scriptstyle;\n          break;\n        case \"scriptscriptstyle\":\n          mathstyle = MATHSTYLES.scriptscriptstyle;\n          break;\n        case \"\":\n        case \"auto\":\n          break;\n      }\n    }\n    this.mathstyle = mathstyle;\n    this.smartFence = template.smartFence;\n    this.placeholderSymbol = template.placeholderSymbol;\n    this.colorMap = (_n = template.colorMap) != null ? _n : (x) => x;\n    this.backgroundColorMap = (_o = template.backgroundColorMap) != null ? _o : (x) => x;\n    this.getMacro = template.getMacro;\n    console.assert(this.parent !== void 0 || this.registers !== void 0);\n  }\n  makeID() {\n    if (!this.atomIdsSettings) return void 0;\n    if (this.atomIdsSettings.overrideID) return this.atomIdsSettings.overrideID;\n    if (typeof this.atomIdsSettings.seed !== \"number\") {\n      return `${Date.now().toString(36).slice(-2)}${Math.floor(\n        Math.random() * 1e5\n      ).toString(36)}`;\n    }\n    const result = this.atomIdsSettings.seed.toString(36);\n    this.atomIdsSettings.seed += 1;\n    return result;\n  }\n  // Scale a value, in em, to account for the fontsize and mathstyle\n  // of this context\n  scale(value) {\n    return value * this.effectiveFontSize;\n  }\n  get scalingFactor() {\n    if (!this.parent) return 1;\n    return this.effectiveFontSize / this.parent.effectiveFontSize;\n  }\n  get isDisplayStyle() {\n    return this.mathstyle.id === D || this.mathstyle.id === Dc;\n  }\n  get isCramped() {\n    return this.mathstyle.cramped;\n  }\n  get isTight() {\n    return this.mathstyle.isTight;\n  }\n  get metrics() {\n    return this.mathstyle.metrics;\n  }\n  // Return the font size, in em relative to the mathfield fontsize,\n  // accounting both for the base font size and the mathstyle\n  get effectiveFontSize() {\n    return Math.max(\n      FONT_SCALE[Math.max(1, this.size + this.mathstyle.sizeDelta)],\n      this.minFontScale\n    );\n  }\n  getRegister(name) {\n    var _a3;\n    if ((_a3 = this.registers) == null ? void 0 : _a3[name]) return this.registers[name];\n    if (this.parent) return this.parent.getRegister(name);\n    return void 0;\n  }\n  getRegisterAsNumber(name) {\n    const val = this.getRegister(name);\n    if (typeof val === \"number\") return val;\n    if (typeof val === \"string\") return Number(val);\n    return void 0;\n  }\n  getRegisterAsGlue(name) {\n    var _a3;\n    if ((_a3 = this.registers) == null ? void 0 : _a3[name]) {\n      const value = this.registers[name];\n      if (typeof value === \"object\" && \"glue\" in value) return value;\n      else if (typeof value === \"object\" && \"dimension\" in value)\n        return { glue: { dimension: value.dimension } };\n      else if (typeof value === \"number\") return { glue: { dimension: value } };\n      return void 0;\n    }\n    if (this.parent) return this.parent.getRegisterAsGlue(name);\n    return void 0;\n  }\n  getRegisterAsEm(name, precision) {\n    return convertDimensionToEm(this.getRegisterAsDimension(name), precision);\n  }\n  getRegisterAsDimension(name) {\n    var _a3;\n    if ((_a3 = this.registers) == null ? void 0 : _a3[name]) {\n      const value = this.registers[name];\n      if (typeof value === \"object\" && \"glue\" in value) return value.glue;\n      else if (typeof value === \"object\" && \"dimension\" in value) return value;\n      else if (typeof value === \"number\") return { dimension: value };\n      return void 0;\n    }\n    if (this.parent) return this.parent.getRegisterAsDimension(name);\n    return void 0;\n  }\n  setRegister(name, value) {\n    if (value === void 0) {\n      delete this.registers[name];\n      return;\n    }\n    this.registers[name] = value;\n  }\n  evaluate(value) {\n    if (!value || !(\"register\" in value)) return value;\n    let context = this;\n    if (\"global\" in value && value.global)\n      while (context.parent) context = context.parent;\n    let factor = 1;\n    if (\"factor\" in value && value.factor !== 1 && value.factor !== void 0)\n      factor = value.factor;\n    const val = context.getRegister(value.register);\n    if (val === void 0) return void 0;\n    if (typeof val === \"string\")\n      return { string: Number(val).toString() + val };\n    if (typeof val === \"number\") return { number: factor * val };\n    const result = context.evaluate(val);\n    if (result === void 0) return void 0;\n    if (\"string\" in result)\n      return { string: Number(val).toString() + result.string };\n    if (\"number\" in result) return { number: factor * result.number };\n    if (\"dimension\" in result)\n      return __spreadProps(__spreadValues({}, result), { dimension: factor * result.dimension });\n    if (\"glue\" in result) {\n      return __spreadProps(__spreadValues({}, result), {\n        glue: __spreadProps(__spreadValues({}, result.glue), { dimension: factor * result.glue.dimension }),\n        shrink: result.shrink ? __spreadProps(__spreadValues({}, result.shrink), { dimension: factor * result.shrink.dimension }) : void 0,\n        grow: result.grow ? __spreadProps(__spreadValues({}, result.grow), { dimension: factor * result.grow.dimension }) : void 0\n      });\n    }\n    return value;\n  }\n  toDimension(value) {\n    const val = this.evaluate(value);\n    if (val === void 0) return null;\n    if (\"dimension\" in val) return val;\n    if (\"glue\" in val) return val.glue;\n    if (\"number\" in val) return { dimension: val.number };\n    return null;\n  }\n  toEm(value, precision) {\n    if (value === null) return 0;\n    const dimen = this.toDimension(value);\n    if (dimen === null) return 0;\n    return convertDimensionToPt(dimen, precision) / PT_PER_EM;\n  }\n  toNumber(value) {\n    if (value === null) return null;\n    const val = this.evaluate(value);\n    if (val === void 0) return null;\n    if (\"number\" in val) return val.number;\n    if (\"dimension\" in val) return val.dimension;\n    if (\"glue\" in val) return val.glue.dimension;\n    if (\"string\" in val) return Number(val.string);\n    return null;\n  }\n  toColor(value) {\n    var _a3, _b3;\n    if (value === null) return null;\n    const val = this.evaluate(value);\n    if (val === void 0) return null;\n    if (\"string\" in val) return (_b3 = (_a3 = this.colorMap) == null ? void 0 : _a3.call(this, val.string)) != null ? _b3 : val.string;\n    return null;\n  }\n  toBackgroundColor(value) {\n    var _a3, _b3;\n    if (value === null) return null;\n    const val = this.evaluate(value);\n    if (val === void 0) return null;\n    if (\"string\" in val)\n      return (_b3 = (_a3 = this.backgroundColorMap) == null ? void 0 : _a3.call(this, val.string)) != null ? _b3 : val.string;\n    return null;\n  }\n};\n\n// src/core/atom-class.ts\nvar NAMED_BRANCHES = [\n  \"body\",\n  \"above\",\n  \"below\",\n  \"superscript\",\n  \"subscript\"\n];\nfunction isNamedBranch(branch) {\n  return typeof branch === \"string\" && NAMED_BRANCHES.includes(branch);\n}\nfunction isCellBranch(branch) {\n  return branch !== void 0 && Array.isArray(branch) && branch.length === 2;\n}\nvar Atom = class _Atom {\n  constructor(options) {\n    var _a3, _b3, _c2, _d2, _e, _f, _g;\n    this.type = options.type;\n    if (typeof options.value === \"string\") this.value = options.value;\n    this.command = (_b3 = (_a3 = options.command) != null ? _a3 : this.value) != null ? _b3 : \"\";\n    this.mode = (_c2 = options.mode) != null ? _c2 : \"math\";\n    if (options.isFunction) this.isFunction = true;\n    if (options.limits) this.subsupPlacement = options.limits;\n    this.style = __spreadValues({}, (_d2 = options.style) != null ? _d2 : {});\n    this.displayContainsHighlight = (_e = options.displayContainsHighlight) != null ? _e : false;\n    this.captureSelection = (_f = options.captureSelection) != null ? _f : false;\n    this.skipBoundary = (_g = options.skipBoundary) != null ? _g : false;\n    if (options.verbatimLatex !== void 0 && options.verbatimLatex !== null)\n      this.verbatimLatex = options.verbatimLatex;\n    if (options.args) this.args = options.args;\n    if (options.body) this.body = options.body;\n    this._changeCounter = 0;\n  }\n  /**\n   * Return a list of boxes equivalent to atoms.\n   *\n   * While an atom represent an abstract element (for example 'genfrac'),\n   * a box corresponds to something to draw on screen (a character, a line,\n   * etc...).\n   *\n   * @param context Font family, variant, size, color, and other info useful\n   * to render an expression\n   */\n  static createBox(context, atoms, options) {\n    var _a3;\n    if (!atoms) return null;\n    const runs = getStyleRuns(atoms);\n    const boxes = [];\n    for (const run of runs) {\n      const style = run[0].style;\n      const box = renderStyleRun(context, run, {\n        style: {\n          color: style.color,\n          backgroundColor: style.backgroundColor,\n          fontSize: style.fontSize\n        }\n      });\n      if (box) boxes.push(box);\n    }\n    if (boxes.length === 0) return null;\n    const classes = ((_a3 = options == null ? void 0 : options.classes) != null ? _a3 : \"\").trim();\n    if (boxes.length === 1 && !classes && !(options == null ? void 0 : options.type))\n      return boxes[0].wrap(context);\n    return new Box(boxes, { classes, type: options == null ? void 0 : options.type }).wrap(context);\n  }\n  /**\n   * Given an atom or an array of atoms, return a LaTeX string representation\n   */\n  static serialize(value, options) {\n    return Mode.serialize(value, options);\n  }\n  /**\n   * The common ancestor between two atoms\n   */\n  static commonAncestor(a, b) {\n    if (a === b) return a.parent;\n    if (a.parent === b.parent) return a.parent;\n    const parents = /* @__PURE__ */ new WeakSet();\n    let { parent } = a;\n    while (parent) {\n      parents.add(parent);\n      parent = parent.parent;\n    }\n    parent = b.parent;\n    while (parent) {\n      if (parents.has(parent)) return parent;\n      parent = parent.parent;\n    }\n    console.assert(Boolean(parent));\n    return void 0;\n  }\n  static fromJson(json) {\n    if (typeof json === \"string\")\n      return new _Atom({ type: \"mord\", value: json, mode: \"math\" });\n    return new _Atom(json);\n  }\n  toJson() {\n    if (this._json) return this._json;\n    const result = {};\n    if (this.type) result.type = this.type;\n    if (this.mode !== \"math\") result.mode = this.mode;\n    if (this.command && this.command !== this.value)\n      result.command = this.command;\n    if (this.value !== void 0) result.value = this.value;\n    if (this.style && Object.keys(this.style).length > 0)\n      result.style = __spreadValues({}, this.style);\n    if (this.verbatimLatex !== void 0)\n      result.verbatimLatex = this.verbatimLatex;\n    if (this.subsupPlacement) result.subsupPlacement = this.subsupPlacement;\n    if (this.explicitSubsupPlacement) result.explicitSubsupPlacement = true;\n    if (this.isFunction) result.isFunction = true;\n    if (this.displayContainsHighlight) result.displayContainsHighlight = true;\n    if (this.skipBoundary) result.skipBoundary = true;\n    if (this.captureSelection) result.captureSelection = true;\n    if (this.args) result.args = argumentsToJson(this.args);\n    if (this._branches) {\n      for (const branch of Object.keys(this._branches)) {\n        if (this._branches[branch]) {\n          result[branch] = this._branches[branch].filter(\n            (x) => x.type !== \"first\"\n          ).map((x) => x.toJson());\n        }\n      }\n    }\n    if (result.type === \"mord\") {\n      if (Object.keys(result).length === 2 && \"value\" in result)\n        return result.value;\n    }\n    this._json = result;\n    return result;\n  }\n  // Used to detect changes and send appropriate notifications\n  get changeCounter() {\n    if (this.parent) return this.parent.changeCounter;\n    return this._changeCounter;\n  }\n  set isDirty(dirty) {\n    if (!dirty) return;\n    this._json = void 0;\n    if (!this.parent) this._changeCounter++;\n    if (\"verbatimLatex\" in this) this.verbatimLatex = void 0;\n    this._children = void 0;\n    if (this.parent) this.parent.isDirty = true;\n  }\n  /**\n   * Serialize the atom  to LaTeX.\n   * Used internally by Mode: does not serialize styling. To serialize\n   * one or more atoms, use `Atom.serialize()`\n   */\n  _serialize(options) {\n    if (!(options.expandMacro || options.skipStyles || options.skipPlaceholders) && typeof this.verbatimLatex === \"string\")\n      return this.verbatimLatex;\n    const def = getDefinition(this.command, this.mode);\n    if (def == null ? void 0 : def.serialize) return def.serialize(this, options);\n    if (this.body && this.command) {\n      return joinLatex([\n        latexCommand(this.command, this.bodyToLatex(options)),\n        this.supsubToLatex(options)\n      ]);\n    }\n    if (this.body) {\n      return joinLatex([\n        this.bodyToLatex(options),\n        this.supsubToLatex(options)\n      ]);\n    }\n    if (!this.value || this.value === \"\\u200B\") return \"\";\n    return this.command;\n  }\n  bodyToLatex(options) {\n    var _a3;\n    let defaultMode = (_a3 = options.defaultMode) != null ? _a3 : this.mode === \"math\" ? \"math\" : \"text\";\n    return Mode.serialize(this.body, __spreadProps(__spreadValues({}, options), { defaultMode }));\n  }\n  aboveToLatex(options) {\n    return Mode.serialize(this.above, options);\n  }\n  belowToLatex(options) {\n    return Mode.serialize(this.below, options);\n  }\n  supsubToLatex(options) {\n    let result = \"\";\n    options = __spreadProps(__spreadValues({}, options), { defaultMode: \"math\" });\n    if (this.branch(\"subscript\") !== void 0) {\n      const sub = Mode.serialize(this.subscript, options);\n      if (sub.length === 0) result += \"_{}\";\n      else if (sub.length === 1) {\n        if (/^[0-9]$/.test(sub)) result += `_${sub}`;\n        else result += `_{${sub}}`;\n      } else result += `_{${sub}}`;\n    }\n    if (this.branch(\"superscript\") !== void 0) {\n      const sup = Mode.serialize(this.superscript, options);\n      if (sup.length === 0) result += \"^{}\";\n      else if (sup.length === 1) {\n        if (sup === \"\\u2032\") result += \"^\\\\prime \";\n        else if (sup === \"\\u2033\") result += \"^\\\\doubleprime \";\n        else if (/^[0-9]$/.test(sup)) result += `^${sup}`;\n        else result += `^{${sup}}`;\n      } else result += `^{${sup}}`;\n    }\n    return result;\n  }\n  get treeDepth() {\n    let result = 1;\n    let atom = this.parent;\n    while (atom) {\n      atom = atom.parent;\n      result += 1;\n    }\n    return result;\n  }\n  get inCaptureSelection() {\n    let atom = this;\n    while (atom) {\n      if (atom.captureSelection) return true;\n      atom = atom.parent;\n    }\n    return false;\n  }\n  /** Return the parent editable prompt, if it exists */\n  get parentPrompt() {\n    let atom = this.parent;\n    while (atom) {\n      if (atom.type === \"prompt\" && !atom.captureSelection) return atom;\n      atom = atom.parent;\n    }\n    return null;\n  }\n  /**\n   * Return the atoms in the branch, if it exists, otherwise null\n   */\n  branch(name) {\n    if (!isNamedBranch(name)) return void 0;\n    if (!this._branches) return void 0;\n    return this._branches[name];\n  }\n  /**\n   * Return all the branches that exist.\n   * Some of them may be empty.\n   */\n  get branches() {\n    if (!this._branches) return [];\n    const result = [];\n    for (const branch of NAMED_BRANCHES)\n      if (this._branches[branch]) result.push(branch);\n    return result;\n  }\n  /**\n   * Return the atoms in the branch, if it exists, otherwise create it.\n   *\n   * Return mutable array of atoms in the branch, since isDirty is\n   * set to true\n   */\n  createBranch(name) {\n    console.assert(isNamedBranch(name));\n    if (!isNamedBranch(name)) return [];\n    if (!this._branches) {\n      this._branches = {\n        [name]: [this.makeFirstAtom(name)]\n      };\n    } else if (!this._branches[name])\n      this._branches[name] = [this.makeFirstAtom(name)];\n    this.isDirty = true;\n    return this._branches[name];\n  }\n  get row() {\n    if (!isCellBranch(this.parentBranch)) return -1;\n    return this.parentBranch[0];\n  }\n  get col() {\n    if (!isCellBranch(this.parentBranch)) return -1;\n    return this.parentBranch[1];\n  }\n  get body() {\n    var _a3;\n    return (_a3 = this._branches) == null ? void 0 : _a3.body;\n  }\n  set body(atoms) {\n    this.setChildren(atoms, \"body\");\n  }\n  get superscript() {\n    var _a3;\n    return (_a3 = this._branches) == null ? void 0 : _a3.superscript;\n  }\n  set superscript(atoms) {\n    this.setChildren(atoms, \"superscript\");\n  }\n  get subscript() {\n    var _a3;\n    return (_a3 = this._branches) == null ? void 0 : _a3.subscript;\n  }\n  set subscript(atoms) {\n    this.setChildren(atoms, \"subscript\");\n  }\n  get above() {\n    var _a3;\n    return (_a3 = this._branches) == null ? void 0 : _a3.above;\n  }\n  set above(atoms) {\n    this.setChildren(atoms, \"above\");\n  }\n  get below() {\n    var _a3;\n    return (_a3 = this._branches) == null ? void 0 : _a3.below;\n  }\n  set below(atoms) {\n    this.setChildren(atoms, \"below\");\n  }\n  applyStyle(style) {\n    this.isDirty = true;\n    this.style = __spreadValues(__spreadValues({}, this.style), style);\n    if (this.style.fontFamily === \"none\") delete this.style.fontFamily;\n    if (this.style.fontShape === \"auto\") delete this.style.fontShape;\n    if (this.style.fontSeries === \"auto\") delete this.style.fontSeries;\n    if (this.style.color === \"none\") {\n      delete this.style.color;\n      delete this.style.verbatimColor;\n    }\n    if (this.style.backgroundColor === \"none\") {\n      delete this.style.backgroundColor;\n      delete this.style.verbatimBackgroundColor;\n    }\n    if (this.style.fontSize === \"auto\") delete this.style.fontSize;\n    for (const child of this.children) child.applyStyle(style);\n  }\n  getInitialBaseElement() {\n    var _a3, _b3, _c2;\n    if (this.hasEmptyBranch(\"body\")) return this;\n    console.assert(((_a3 = this.body) == null ? void 0 : _a3[0].type) === \"first\");\n    return (_c2 = (_b3 = this.body[1]) == null ? void 0 : _b3.getInitialBaseElement()) != null ? _c2 : this;\n  }\n  getFinalBaseElement() {\n    if (this.hasEmptyBranch(\"body\")) return this;\n    return this.body[this.body.length - 1].getFinalBaseElement();\n  }\n  isCharacterBox() {\n    if (this.type === \"leftright\" || this.type === \"genfrac\" || this.type === \"subsup\" || this.type === \"delim\" || this.type === \"array\" || this.type === \"surd\")\n      return false;\n    return this.getFinalBaseElement().type === \"mord\";\n  }\n  hasEmptyBranch(branch) {\n    const atoms = this.branch(branch);\n    if (!atoms) return true;\n    console.assert(atoms.length > 0);\n    console.assert(atoms[0].type === \"first\");\n    return atoms.length === 1;\n  }\n  /*\n   * Setting `null` does nothing\n   * Setting `[]` adds an empty list (the branch is created)\n   * The children should *not* start with a `\"first\"` atom:\n   * the `first` atom will be added if necessary\n   */\n  setChildren(children, branch) {\n    var _a3;\n    if (!children) return;\n    console.assert(isNamedBranch(branch));\n    if (!isNamedBranch(branch)) return;\n    const newBranch = ((_a3 = children[0]) == null ? void 0 : _a3.type) === \"first\" ? [...children] : [this.makeFirstAtom(branch), ...children];\n    if (this._branches) this._branches[branch] = newBranch;\n    else this._branches = { [branch]: newBranch };\n    for (const child of children) {\n      child.parent = this;\n      child.parentBranch = branch;\n    }\n    this.isDirty = true;\n  }\n  makeFirstAtom(branch) {\n    const result = new _Atom({ type: \"first\", mode: this.mode });\n    result.parent = this;\n    result.parentBranch = branch;\n    return result;\n  }\n  addChild(child, branch) {\n    console.assert(child.type !== \"first\");\n    this.createBranch(branch).push(child);\n    this.isDirty = true;\n    child.parent = this;\n    child.parentBranch = branch;\n  }\n  addChildBefore(child, before) {\n    console.assert(before.parentBranch !== void 0);\n    const branch = this.createBranch(before.parentBranch);\n    branch.splice(branch.indexOf(before), 0, child);\n    this.isDirty = true;\n    child.parent = this;\n    child.parentBranch = before.parentBranch;\n  }\n  addChildAfter(child, after) {\n    console.assert(after.parentBranch !== void 0);\n    const branch = this.createBranch(after.parentBranch);\n    branch.splice(branch.indexOf(after) + 1, 0, child);\n    this.isDirty = true;\n    child.parent = this;\n    child.parentBranch = after.parentBranch;\n  }\n  addChildren(children, branchName) {\n    const branch = this.createBranch(branchName);\n    for (const child of children) {\n      child.parent = this;\n      child.parentBranch = branchName;\n      branch.push(child);\n    }\n    this.isDirty = true;\n  }\n  /**\n   * Return the last atom that was added\n   */\n  addChildrenAfter(children, after) {\n    console.assert(children.length === 0 || children[0].type !== \"first\");\n    console.assert(after.parentBranch !== void 0);\n    const branch = this.createBranch(after.parentBranch);\n    branch.splice(branch.indexOf(after) + 1, 0, ...children);\n    this.isDirty = true;\n    for (const child of children) {\n      child.parent = this;\n      child.parentBranch = after.parentBranch;\n    }\n    return children[children.length - 1];\n  }\n  removeBranch(name) {\n    const children = this.branch(name);\n    if (isNamedBranch(name)) this._branches[name] = void 0;\n    if (!children) return [];\n    for (const child of children) {\n      child.parent = void 0;\n      child.parentBranch = void 0;\n    }\n    console.assert(children[0].type === \"first\");\n    const [_first, ...rest] = children;\n    this.isDirty = true;\n    return rest;\n  }\n  removeChild(child) {\n    console.assert(child.parent === this);\n    if (child.type === \"first\") return;\n    const branch = this.branch(child.parentBranch);\n    const index = branch.indexOf(child);\n    console.assert(index >= 0);\n    branch.splice(index, 1);\n    this.isDirty = true;\n    child.parent = void 0;\n    child.parentBranch = void 0;\n  }\n  get siblings() {\n    if (!this.parent) return [];\n    return this.parent.branch(this.parentBranch);\n  }\n  get firstSibling() {\n    return this.siblings[0];\n  }\n  get lastSibling() {\n    const { siblings } = this;\n    return siblings[siblings.length - 1];\n  }\n  get isFirstSibling() {\n    return this === this.firstSibling;\n  }\n  get isLastSibling() {\n    return this === this.lastSibling;\n  }\n  get hasNoSiblings() {\n    return this.siblings.length === 1;\n  }\n  get leftSibling() {\n    console.assert(this.parent !== void 0);\n    const siblings = this.parent.branch(this.parentBranch);\n    return siblings[siblings.indexOf(this) - 1];\n  }\n  get rightSibling() {\n    console.assert(this.parent !== void 0);\n    const siblings = this.parent.branch(this.parentBranch);\n    return siblings[siblings.indexOf(this) + 1];\n  }\n  get hasChildren() {\n    return Boolean(this._branches && this.children.length > 0);\n  }\n  get firstChild() {\n    console.assert(this.hasChildren);\n    return this.children[0];\n  }\n  get lastChild() {\n    console.assert(this.hasChildren);\n    const { children } = this;\n    return children[children.length - 1];\n  }\n  /**\n   * All the children of this atom.\n   *\n   * The order of the atoms is the order in which they\n   * are navigated using the keyboard.\n   */\n  get children() {\n    if (this._children) return this._children;\n    if (!this._branches) return [];\n    const result = [];\n    for (const branchName of NAMED_BRANCHES) {\n      if (this._branches[branchName]) {\n        for (const x of this._branches[branchName]) {\n          result.push(...x.children);\n          result.push(x);\n        }\n      }\n    }\n    this._children = result;\n    return result;\n  }\n  /**\n   * Render this atom as a box.\n   *\n   * The parent context (color, size...) will be applied\n   * to the result.\n   *\n   */\n  render(parentContext) {\n    if (this.type === \"first\" && !parentContext.atomIdsSettings) return null;\n    const def = getDefinition(this.command, this.mode);\n    if (def == null ? void 0 : def.render) return def.render(this, parentContext);\n    const context = new Context({ parent: parentContext }, this.style);\n    let result = this.createBox(context, {\n      classes: !this.parent ? \"ML__base\" : \"\"\n    });\n    if (!result) return null;\n    if (!this.subsupPlacement && (this.superscript || this.subscript)) {\n      result = this.attachSupsub(context, { base: result });\n    }\n    return result.wrap(context);\n  }\n  attachSupsub(parentContext, options) {\n    var _a3;\n    const base = options.base;\n    const superscript = this.superscript;\n    const subscript = this.subscript;\n    if (!superscript && !subscript) return base;\n    let supBox = null;\n    let subBox = null;\n    const isCharacterBox = (_a3 = options.isCharacterBox) != null ? _a3 : this.isCharacterBox();\n    let supShift = 0;\n    if (superscript) {\n      const context = new Context({\n        parent: parentContext,\n        mathstyle: \"superscript\"\n      });\n      supBox = _Atom.createBox(context, superscript);\n      if (!isCharacterBox) {\n        supShift = base.height - parentContext.metrics.supDrop * context.scalingFactor;\n      }\n    }\n    let subShift = 0;\n    if (subscript) {\n      const context = new Context({\n        parent: parentContext,\n        mathstyle: \"subscript\"\n      });\n      subBox = _Atom.createBox(context, subscript);\n      if (!isCharacterBox) {\n        subShift = base.depth + parentContext.metrics.subDrop * context.scalingFactor;\n      }\n    }\n    let minSupShift;\n    if (parentContext.isDisplayStyle)\n      minSupShift = parentContext.metrics.sup1;\n    else if (parentContext.isCramped)\n      minSupShift = parentContext.metrics.sup3;\n    else minSupShift = parentContext.metrics.sup2;\n    const scriptspace = 0.5 / PT_PER_EM / parentContext.scalingFactor;\n    let supsub = null;\n    if (subBox && supBox) {\n      supShift = Math.max(\n        supShift,\n        minSupShift,\n        supBox.depth + 0.25 * parentContext.metrics.xHeight\n      );\n      subShift = Math.max(subShift, parentContext.metrics.sub2);\n      const ruleWidth = parentContext.metrics.defaultRuleThickness;\n      if (supShift - supBox.depth - (subBox.height - subShift) < 4 * ruleWidth) {\n        subShift = 4 * ruleWidth - (supShift - supBox.depth) + subBox.height;\n        const psi = 0.8 * parentContext.metrics.xHeight - (supShift - supBox.depth);\n        if (psi > 0) {\n          supShift += psi;\n          subShift -= psi;\n        }\n      }\n      const slant = this.type === \"extensible-symbol\" && base.italic ? -base.italic : 0;\n      supsub = new VBox({\n        individualShift: [\n          { box: subBox, shift: subShift, marginLeft: slant },\n          { box: supBox, shift: -supShift }\n        ]\n      }).wrap(parentContext);\n    } else if (subBox && !supBox) {\n      subShift = Math.max(\n        subShift,\n        parentContext.metrics.sub1,\n        subBox.height - 0.8 * X_HEIGHT\n      );\n      supsub = new VBox({\n        shift: subShift,\n        children: [\n          {\n            box: subBox,\n            marginRight: scriptspace,\n            marginLeft: this.isCharacterBox() ? -base.italic : 0\n          }\n        ]\n      });\n    } else if (!subBox && supBox) {\n      supShift = Math.max(\n        supShift,\n        minSupShift,\n        supBox.depth + 0.25 * X_HEIGHT\n      );\n      supsub = new VBox({\n        shift: -supShift,\n        children: [{ box: supBox, marginRight: scriptspace }]\n      });\n    }\n    return new Box(\n      [\n        base,\n        new Box(supsub, {\n          caret: this.caret,\n          isSelected: this.isSelected,\n          classes: \"ML__msubsup\"\n        })\n      ],\n      { type: options.type }\n    );\n  }\n  attachLimits(ctx, options) {\n    const above = this.superscript ? _Atom.createBox(\n      new Context({ parent: ctx, mathstyle: \"superscript\" }, this.style),\n      this.superscript\n    ) : null;\n    const below = this.subscript ? _Atom.createBox(\n      new Context({ parent: ctx, mathstyle: \"subscript\" }, this.style),\n      this.subscript\n    ) : null;\n    if (!above && !below) return options.base.wrap(ctx);\n    return makeLimitsStack(ctx, __spreadProps(__spreadValues({}, options), { above, below }));\n  }\n  bind(context, box) {\n    if (!box || context.isPhantom || this.value === \"\\u200B\") return box;\n    let parent = this.parent;\n    while (parent && !parent.captureSelection) parent = parent.parent;\n    if (parent == null ? void 0 : parent.captureSelection) return box;\n    if (!this.id) this.id = context.makeID();\n    box.atomID = this.id;\n    return box;\n  }\n  /**\n   * Create a box with the specified body.\n   */\n  createBox(context, options) {\n    var _a3, _b3, _c2, _d2;\n    const value = (_a3 = this.value) != null ? _a3 : this.body;\n    const type = (_b3 = options == null ? void 0 : options.boxType) != null ? _b3 : boxType(this.type);\n    let classes = (_c2 = options == null ? void 0 : options.classes) != null ? _c2 : \"\";\n    if (this.mode === \"text\") classes += \" ML__text\";\n    const result = typeof value === \"string\" || value === void 0 ? new Box(value != null ? value : null, {\n      type,\n      isSelected: this.isSelected,\n      mode: this.mode,\n      maxFontSize: context.scalingFactor,\n      style: __spreadProps(__spreadValues({\n        variant: \"normal\"\n      }, this.style), {\n        fontSize: Math.max(\n          1,\n          context.size + context.mathstyle.sizeDelta\n        )\n      }),\n      letterShapeStyle: context.letterShapeStyle,\n      classes\n    }) : (_d2 = _Atom.createBox(context, value, { type, classes })) != null ? _d2 : new Box(null);\n    if (context.isTight) result.isTight = true;\n    if (this.mode !== \"math\" || this.style.variant === \"main\")\n      result.italic = 0;\n    result.right = result.italic;\n    this.bind(context, result);\n    if (this.caret) {\n      if (!this.superscript && !this.subscript) result.caret = this.caret;\n    }\n    return result;\n  }\n  /** Return true if a digit, or a decimal point, or a french decimal `{,}` */\n  isDigit() {\n    var _a3;\n    if (this.type === \"mord\" && this.value) return /^[\\d,\\.]$/.test(this.value);\n    if (this.type === \"group\" && ((_a3 = this.body) == null ? void 0 : _a3.length) === 2)\n      return this.body[0].type === \"first\" && this.body[1].value === \",\";\n    return false;\n  }\n  asDigit() {\n    var _a3;\n    if (this.type === \"mord\" && this.value && /^[\\d,\\.]$/.test(this.value))\n      return this.value;\n    if (this.type === \"group\" && ((_a3 = this.body) == null ? void 0 : _a3.length) === 2) {\n      if (this.body[0].type === \"first\" && this.body[1].value === \",\")\n        return \".\";\n    }\n    return \"\";\n  }\n};\nfunction getStyleRuns(atoms) {\n  let style = void 0;\n  const runs = [];\n  let run = [];\n  for (const atom of atoms) {\n    if (atom.type === \"first\") run.push(atom);\n    if (!style && !atom.style) run.push(atom);\n    else {\n      const atomStyle = atom.style;\n      if (style && atomStyle.color === style.color && atomStyle.backgroundColor === style.backgroundColor && atomStyle.fontSize === style.fontSize) {\n        run.push(atom);\n      } else {\n        if (run.length > 0) runs.push(run);\n        run = [atom];\n        style = atomStyle;\n      }\n    }\n  }\n  if (run.length > 0) runs.push(run);\n  return runs;\n}\nfunction renderStyleRun(parentContext, atoms, options) {\n  var _a3, _b3, _c2, _d2, _e;\n  if (!atoms || atoms.length === 0) return null;\n  const context = new Context({ parent: parentContext }, options.style);\n  const displaySelection = !((_a3 = context.atomIdsSettings) == null ? void 0 : _a3.groupNumbers);\n  let boxes = [];\n  if (atoms.length === 1) {\n    const atom = atoms[0];\n    const box = atom.render(context);\n    if (box) {\n      if (displaySelection && atom.isSelected) box.selected(true);\n      boxes = [box];\n    }\n  } else {\n    let digitOrTextStringID = \"\";\n    let lastWasDigit = true;\n    for (const atom of atoms) {\n      if (((_b3 = context.atomIdsSettings) == null ? void 0 : _b3.groupNumbers) && digitOrTextStringID && (lastWasDigit && atom.isDigit() || !lastWasDigit && isText(atom)))\n        context.atomIdsSettings.overrideID = digitOrTextStringID;\n      const box = atom.render(context);\n      if (context.atomIdsSettings)\n        context.atomIdsSettings.overrideID = void 0;\n      if (box) {\n        if ((_c2 = context.atomIdsSettings) == null ? void 0 : _c2.groupNumbers) {\n          if (atom.isDigit() || isText(atom)) {\n            if (!digitOrTextStringID || lastWasDigit !== atom.isDigit()) {\n              lastWasDigit = atom.isDigit();\n              digitOrTextStringID = (_d2 = atom.id) != null ? _d2 : \"\";\n            }\n          }\n          if (digitOrTextStringID && (!(atom.isDigit() || isText(atom)) || !atom.hasEmptyBranch(\"superscript\") || !atom.hasEmptyBranch(\"subscript\"))) {\n            digitOrTextStringID = \"\";\n          }\n        }\n        if (displaySelection && atom.isSelected) box.selected(true);\n        boxes.push(box);\n      }\n    }\n  }\n  if (boxes.length === 0) return null;\n  const result = new Box(boxes, __spreadProps(__spreadValues({\n    isTight: context.isTight\n  }, options), {\n    type: (_e = options.type) != null ? _e : \"lift\"\n  }));\n  result.isSelected = boxes.every((x) => x.isSelected);\n  return result.wrap(context);\n}\nfunction isText(atom) {\n  return atom.mode === \"text\";\n}\nfunction argumentsToJson(args) {\n  return args.map((arg) => {\n    if (arg === null) return \"<null>\";\n    if (Array.isArray(arg) && arg[0] instanceof Atom)\n      return { atoms: arg.map((x) => x.toJson()) };\n    if (typeof arg === \"object\" && \"group\" in arg)\n      return { group: arg.group.map((x) => x.toJson()) };\n    return arg;\n  });\n}\n\n// src/atoms/text.ts\nvar TextAtom = class _TextAtom extends Atom {\n  constructor(command, value, style) {\n    super({\n      type: \"text\",\n      command,\n      mode: \"text\",\n      displayContainsHighlight: true\n    });\n    this.value = value;\n    this.verbatimLatex = value;\n    this.applyStyle(style);\n  }\n  static fromJson(json) {\n    return new _TextAtom(json.command, json.value, json.style);\n  }\n  render(context) {\n    const result = this.createBox(context);\n    if (this.caret) result.caret = this.caret;\n    return result;\n  }\n  _serialize(_options) {\n    var _a3;\n    return (_a3 = this.verbatimLatex) != null ? _a3 : charToLatex(\"text\", this.value.codePointAt(0));\n  }\n};\n\n// src/editor-model/selection-utils.ts\nfunction compareSelection(a, b) {\n  if (a.direction === b.direction) {\n    const l = a.ranges.length;\n    if (b.ranges.length === l) {\n      let i = 0;\n      while (i < l && compareRange(a.ranges[i], b.ranges[i]) === \"equal\") i++;\n      return i === l ? \"equal\" : \"different\";\n    }\n  }\n  return \"different\";\n}\nfunction compareRange(a, b) {\n  if (a[0] === b[0] && a[1] === b[1]) return \"equal\";\n  return \"different\";\n}\nfunction range(selection) {\n  let first = Infinity;\n  let last = -Infinity;\n  for (const range2 of selection.ranges) {\n    first = Math.min(first, range2[0], range2[1]);\n    last = Math.max(last, range2[0], range2[1]);\n  }\n  return [first, last];\n}\nfunction isOffset(value) {\n  return typeof value === \"number\" && !Number.isNaN(value);\n}\nfunction isRange(value) {\n  return Array.isArray(value) && value.length === 2;\n}\nfunction isSelection(value) {\n  return value !== void 0 && value !== null && typeof value === \"object\" && \"ranges\" in value && Array.isArray(value.ranges);\n}\nfunction getMode(model, offset) {\n  const atom = model.at(offset);\n  let result;\n  if (atom) {\n    result = atom.mode;\n    let ancestor = atom.parent;\n    while (!result && ancestor) {\n      if (ancestor) result = ancestor.mode;\n      ancestor = ancestor.parent;\n    }\n  }\n  return result;\n}\n\n// src/editor/shortcuts.ts\nfunction validateShortcut(siblings, shortcut) {\n  if (!shortcut) return \"\";\n  if (typeof shortcut === \"string\") return shortcut;\n  if (!siblings || shortcut.after === void 0) return shortcut.value;\n  let nothing = false;\n  let letter = false;\n  let digit = false;\n  let isFunction = false;\n  let frac = false;\n  let surd = false;\n  let binop = false;\n  let relop = false;\n  let operator = false;\n  let punct = false;\n  let array = false;\n  let openfence = false;\n  let closefence = false;\n  let text = false;\n  let space = false;\n  let sibling = siblings[0];\n  let index = 0;\n  while ((sibling == null ? void 0 : sibling.type) && /^(subsup|placeholder)$/.test(sibling.type)) {\n    index += 1;\n    sibling = siblings[index];\n  }\n  nothing = !sibling || sibling.type === \"first\";\n  if (sibling) {\n    text = sibling.mode === \"text\";\n    letter = !text && sibling.type === \"mord\" && LETTER.test(sibling.value);\n    digit = !text && sibling.type === \"mord\" && /\\d+$/.test(sibling.value);\n    isFunction = !text && sibling.isFunction;\n    frac = sibling.type === \"genfrac\";\n    surd = sibling.type === \"surd\";\n    binop = sibling.type === \"mbin\";\n    relop = sibling.type === \"mrel\";\n    operator = sibling.type === \"mop\" || sibling.type === \"operator\" || sibling.type === \"extensible-symbol\";\n    punct = sibling.type === \"mpunct\" || sibling.type === \"minner\";\n    array = sibling.type === \"array\";\n    openfence = sibling.type === \"mopen\";\n    closefence = sibling.type === \"mclose\" || sibling.type === \"leftright\";\n    space = sibling.type === \"space\";\n  }\n  if (shortcut.after.includes(\"nothing\") && nothing || shortcut.after.includes(\"letter\") && letter || shortcut.after.includes(\"digit\") && digit || shortcut.after.includes(\"function\") && isFunction || shortcut.after.includes(\"frac\") && frac || shortcut.after.includes(\"surd\") && surd || shortcut.after.includes(\"binop\") && binop || shortcut.after.includes(\"relop\") && relop || shortcut.after.includes(\"operator\") && operator || shortcut.after.includes(\"punct\") && punct || shortcut.after.includes(\"array\") && array || shortcut.after.includes(\"openfence\") && openfence || shortcut.after.includes(\"closefence\") && closefence || shortcut.after.includes(\"text\") && text || shortcut.after.includes(\"space\") && space)\n    return shortcut.value;\n  return \"\";\n}\nfunction getInlineShortcut(context, s, shortcuts) {\n  if (!shortcuts) return \"\";\n  return validateShortcut(context, shortcuts[s]);\n}\n\n// src/editor/shortcuts-definitions.ts\nvar INLINE_SHORTCUTS = {\n  \"&\": \"\\\\&\",\n  \"%\": \"\\\\%\",\n  \"$\": \"\\\\$\",\n  // Primes\n  \"''\": \"^{\\\\doubleprime}\",\n  \"'''\": \"^{\\\\prime\\\\prime\\\\prime}\",\n  \"''''\": \"^{\\\\prime\\\\prime\\\\prime\\\\prime}\",\n  // Greek letters\n  \"alpha\": \"\\\\alpha\",\n  \"delta\": \"\\\\delta\",\n  \"Delta\": \"\\\\Delta\",\n  \"pi\": \"\\\\pi\",\n  \"Pi\": \"\\\\Pi\",\n  \"theta\": \"\\\\theta\",\n  \"Theta\": \"\\\\Theta\",\n  // Letter-like\n  \"ii\": {\n    after: \"nothing+digit+function+frac+surd+binop+relop+punct+array+openfence+closefence+space+text\",\n    value: \"\\\\imaginaryI\"\n  },\n  \"jj\": {\n    after: \"nothing+digit+function+frac+surd+binop+relop+punct+array+openfence+closefence+space+text\",\n    value: \"\\\\imaginaryJ\"\n  },\n  \"ee\": {\n    after: \"nothing+digit+function+frac+surd+binop+relop+punct+array+openfence+closefence+space+text\",\n    value: \"\\\\exponentialE\"\n  },\n  \"nabla\": \"\\\\nabla\",\n  \"grad\": \"\\\\nabla\",\n  \"del\": \"\\\\partial\",\n  \"deg\": { after: \"digit+space\", value: \"\\\\degree\" },\n  \"infty\": \"\\\\infty\",\n  \"\\u221E\": \"\\\\infty\",\n  // @TODO: doesn't work\n  // '&infin;': '\\\\infty',\n  // '&#8734;': '\\\\infty',\n  \"oo\": {\n    after: \"nothing+digit+frac+surd+binop+relop+punct+array+openfence+closefence+space\",\n    value: \"\\\\infty\"\n  },\n  // Big operators\n  \"\\u2211\": \"\\\\sum\",\n  \"sum\": \"\\\\sum_{#?}^{#?}\",\n  \"int\": \"\\\\int_{#?}^{#?}\",\n  \"prod\": \"\\\\prod_{#?}^{#?}\",\n  \"sqrt\": \"\\\\sqrt{#?}\",\n  // '∫':                    '\\\\int',             // There's a alt-B command for this\n  \"\\u2206\": \"\\\\differentialD\",\n  // @TODO: is \\\\diffD most common?\n  \"\\u2202\": \"\\\\differentialD\",\n  // Functions\n  \"arcsin\": \"\\\\arcsin\",\n  \"arccos\": \"\\\\arccos\",\n  \"arctan\": \"\\\\arctan\",\n  \"arcsec\": \"\\\\arcsec\",\n  \"arccsc\": \"\\\\arccsc\",\n  \"arsinh\": \"\\\\arsinh\",\n  \"arcosh\": \"\\\\arcosh\",\n  \"artanh\": \"\\\\artanh\",\n  \"arcsech\": \"\\\\arcsech\",\n  \"arccsch\": \"\\\\arccsch\",\n  \"arg\": \"\\\\arg\",\n  \"ch\": \"\\\\ch\",\n  \"cosec\": \"\\\\cosec\",\n  \"cosh\": \"\\\\cosh\",\n  \"cot\": \"\\\\cot\",\n  \"cotg\": \"\\\\cotg\",\n  \"coth\": \"\\\\coth\",\n  \"csc\": \"\\\\csc\",\n  \"ctg\": \"\\\\ctg\",\n  \"cth\": \"\\\\cth\",\n  \"sec\": \"\\\\sec\",\n  \"sinh\": \"\\\\sinh\",\n  \"sh\": \"\\\\sh\",\n  \"tanh\": \"\\\\tanh\",\n  \"tg\": \"\\\\tg\",\n  \"th\": \"\\\\th\",\n  \"sin\": \"\\\\sin\",\n  \"cos\": \"\\\\cos\",\n  \"tan\": \"\\\\tan\",\n  \"lg\": \"\\\\lg\",\n  \"lb\": \"\\\\lb\",\n  \"log\": \"\\\\log\",\n  \"ln\": \"\\\\ln\",\n  \"exp\": \"\\\\exp\",\n  \"lim\": \"\\\\lim_{#?}\",\n  // Differentials\n  // According to ISO31/XI (ISO 80000-2), differentials should be upright\n  \"dx\": {\n    after: \"nothing+digit+function+frac+surd+binop+relop+punct+array+openfence+closefence+space+text\",\n    value: \"\\\\differentialD x\"\n  },\n  \"dy\": {\n    after: \"nothing+digit+function+frac+surd+binop+relop+punct+array+openfence+closefence+space+text\",\n    value: \"\\\\differentialD y\"\n  },\n  \"dt\": {\n    after: \"nothing+digit+function+frac+surd+binop+relop+punct+array+openfence+closefence+space+text\",\n    value: \"\\\\differentialD t\"\n  },\n  // Logic\n  \"AA\": \"\\\\forall\",\n  \"EE\": \"\\\\exists\",\n  \"!EE\": \"\\\\nexists\",\n  \"&&\": \"\\\\land\",\n  // The shortcut for the greek letter \"xi\" is interfering with \"x in\"\n  \"xin\": {\n    after: \"nothing+text+relop+punct+openfence+space\",\n    value: \"x \\\\in\"\n  },\n  // The shortcut for `\\int` is interfering with `\\sin x`\n  \"sint\": {\n    after: \"nothing+digit+function+frac+surd+binop+relop+punct+array+openfence+closefence+space+text\",\n    value: \"\\\\sin t\"\n  },\n  \"in\": {\n    after: \"nothing+letter+closefence\",\n    value: \"\\\\in\"\n  },\n  \"!in\": \"\\\\notin\",\n  // Sets\n  \"NN\": \"\\\\mathbb{N}\",\n  // Natural numbers\n  \"ZZ\": \"\\\\Z\",\n  // Integers\n  \"QQ\": \"\\\\Q\",\n  // Rational numbers\n  \"RR\": \"\\\\R\",\n  // Real numbers\n  \"CC\": \"\\\\C\",\n  // Complex numbers\n  // Operators\n  \"xx\": \"\\\\times\",\n  \"+-\": \"\\\\pm\",\n  // Relational operators\n  \"\\u2260\": \"\\\\ne\",\n  \"!=\": \"\\\\ne\",\n  \"\\u2265\": \"\\\\ge\",\n  \">=\": \"\\\\ge\",\n  \"\\u2264\": \"\\\\le\",\n  \"<=\": \"\\\\le\",\n  \"<<\": \"\\\\ll\",\n  \">>\": \"\\\\gg\",\n  \"~~\": \"\\\\approx\",\n  // More operators\n  \"\\u2248\": \"\\\\approx\",\n  \"?=\": \"\\\\questeq\",\n  \"\\xF7\": \"\\\\div\",\n  \"\\xAC\": \"\\\\neg\",\n  \":=\": \"\\\\coloneq\",\n  \"::\": \"\\\\Colon\",\n  // Fences\n  \"(:\": \"\\\\langle\",\n  \":)\": \"\\\\rangle\",\n  // More Greek letters\n  \"beta\": \"\\\\beta\",\n  \"chi\": \"\\\\chi\",\n  \"epsilon\": \"\\\\epsilon\",\n  \"varepsilon\": \"\\\\varepsilon\",\n  \"eta\": {\n    after: \"nothing+digit+function+frac+surd+binop+relop+punct+array+openfence+closefence+space+text\",\n    value: \"\\\\eta\"\n  },\n  \"gamma\": \"\\\\gamma\",\n  \"Gamma\": \"\\\\Gamma\",\n  \"iota\": \"\\\\iota\",\n  \"kappa\": \"\\\\kappa\",\n  \"lambda\": \"\\\\lambda\",\n  \"Lambda\": \"\\\\Lambda\",\n  \"mu\": {\n    after: \"nothing+digit+function+frac+surd+binop+relop+punct+array+openfence+closefence+space+text\",\n    value: \"\\\\mu\"\n  },\n  \"nu\": {\n    after: \"nothing+digit+function+frac+surd+binop+relop+punct+array+openfence+closefence+space+text\",\n    value: \"\\\\nu\"\n  },\n  \"\\xB5\": \"\\\\mu\",\n  // @TODO: or micro?\n  \"phi\": {\n    after: \"nothing+digit+function+frac+surd+binop+relop+punct+array+openfence+closefence+space+text\",\n    value: \"\\\\phi\"\n  },\n  \"Phi\": {\n    after: \"nothing+digit+function+frac+surd+binop+relop+punct+array+openfence+closefence+space+text\",\n    value: \"\\\\Phi\"\n  },\n  \"varphi\": \"\\\\varphi\",\n  \"psi\": {\n    after: \"nothing+digit+function+frac+surd+binop+relop+punct+array+openfence+closefence+space+text\",\n    value: \"\\\\psi\"\n  },\n  \"Psi\": {\n    after: \"nothing+digit+function+frac+surd+binop+relop+punct+array+openfence+closefence+space+text\",\n    value: \"\\\\Psi\"\n  },\n  \"rho\": {\n    after: \"nothing+digit+function+frac+surd+binop+relop+punct+array+openfence+closefence+space+text\",\n    value: \"\\\\rho\"\n  },\n  \"sigma\": \"\\\\sigma\",\n  \"Sigma\": \"\\\\Sigma\",\n  \"tau\": {\n    after: \"nothing+digit+function+frac+surd+binop+relop+punct+array+openfence+closefence+space+text\",\n    value: \"\\\\tau\"\n  },\n  \"vartheta\": \"\\\\vartheta\",\n  \"upsilon\": \"\\\\upsilon\",\n  \"xi\": {\n    after: \"nothing+digit+function+frac+surd+binop+relop+punct+array+openfence+closefence+space\",\n    value: \"\\\\xi\"\n  },\n  \"Xi\": {\n    after: \"nothing+digit+function+frac+surd+binop+relop+punct+array+openfence+closefence+space+text\",\n    value: \"\\\\Xi\"\n  },\n  \"zeta\": \"\\\\zeta\",\n  \"omega\": \"\\\\omega\",\n  \"Omega\": \"\\\\Omega\",\n  \"\\u03A9\": \"\\\\omega\",\n  // @TODO: or ohm?\n  // More Logic\n  \"forall\": \"\\\\forall\",\n  \"exists\": \"\\\\exists\",\n  \"!exists\": \"\\\\nexists\",\n  \":.\": \"\\\\therefore\",\n  // MORE FUNCTIONS\n  // 'arg': '\\\\arg',\n  \"liminf\": \"\\\\liminf_{#?}\",\n  \"limsup\": \"\\\\limsup_{#?}\",\n  \"argmin\": \"\\\\operatorname*{arg~min}_{#?}\",\n  \"argmax\": \"\\\\operatorname*{arg~max}_{#?}\",\n  \"det\": \"\\\\det\",\n  \"mod\": \"\\\\bmod{#?}\",\n  \"(mod\": \"\\\\pmod{#?}\",\n  \"max\": \"\\\\max\",\n  \"min\": \"\\\\min\",\n  \"erf\": \"\\\\operatorname{erf}\",\n  \"erfc\": \"\\\\operatorname{erfc}\",\n  \"bessel\": \"\\\\operatorname{bessel}\",\n  \"mean\": \"\\\\operatorname{mean}\",\n  \"median\": \"\\\\operatorname{median}\",\n  \"fft\": \"\\\\operatorname{fft}\",\n  \"lcm\": \"\\\\operatorname{lcm}\",\n  \"gcd\": \"\\\\operatorname{gcd}\",\n  \"randomReal\": \"\\\\operatorname{randomReal}\",\n  \"randomInteger\": \"\\\\operatorname{randomInteger}\",\n  \"Re\": \"\\\\operatorname{Re}\",\n  \"Im\": \"\\\\operatorname{Im}\",\n  // UNITS\n  \"mm\": {\n    after: \"nothing+digit+operator\",\n    value: \"\\\\operatorname{mm}\"\n    // Millimeter\n  },\n  \"cm\": {\n    after: \"nothing+digit+operator\",\n    value: \"\\\\operatorname{cm}\"\n    // Centimeter\n  },\n  \"km\": {\n    after: \"nothing+digit+operator\",\n    value: \"\\\\operatorname{km}\"\n    // Kilometer\n  },\n  \"kg\": {\n    after: \"nothing+digit+operator\",\n    value: \"\\\\operatorname{kg}\"\n    // Kilogram\n  },\n  // '||':                   '\\\\lor',\n  \"...\": \"\\\\ldots\",\n  // In general, use \\ldots\n  \"+...\": \"+\\\\cdots\",\n  // ... but use \\cdots after + ...\n  \"-...\": \"-\\\\cdots\",\n  // ... - and ...\n  \"->...\": \"\\\\to\\\\cdots\",\n  // ->\n  \"-->...\": \"\\\\longrightarrow\\\\cdots\",\n  \"->\": \"\\\\to\",\n  \"|->\": \"\\\\mapsto\",\n  \"-->\": \"\\\\longrightarrow\",\n  //    '<-':                   '\\\\leftarrow',\n  \"<--\": \"\\\\longleftarrow\",\n  \"=>\": \"\\\\Rightarrow\",\n  \"==>\": \"\\\\Longrightarrow\",\n  // '<=': '\\\\Leftarrow',     // CONFLICTS WITH LESS THAN OR EQUAL\n  \"<=>\": \"\\\\Leftrightarrow\",\n  \"<->\": \"\\\\leftrightarrow\",\n  \"(.)\": \"\\\\odot\",\n  \"(+)\": \"\\\\oplus\",\n  \"(/)\": \"\\\\oslash\",\n  \"(*)\": \"\\\\otimes\",\n  \"(-)\": \"\\\\ominus\",\n  // '(-)':                  '\\\\circleddash',\n  \"||\": \"\\\\Vert\",\n  \"*\": \"\\\\cdot\",\n  //\n  // ASCIIIMath\n  //\n  // Binary operation symbols\n  //\n  \"**\": \"\\\\star\",\n  \"***\": \"\\\\ast\",\n  \"//\": \"\\\\slash\",\n  \"\\\\\\\\\": \"\\\\backslash\",\n  \"setminus\": \"\\\\backslash\",\n  \"|><\": \"\\\\ltimes\",\n  \"><|\": \"\\\\rtimes\",\n  \"|><|\": \"\\\\bowtie\",\n  \"-:\": \"\\\\div\",\n  \"divide\": \"\\\\div\",\n  \"@\": \"\\\\circ\",\n  // 'o+': '\\\\oplus',\n  // 'ox': '\\\\otimes',\n  // 'o.': '\\\\odot',\n  \"^^\": \"\\\\wedge\",\n  \"^^^\": \"\\\\bigwedge\",\n  \"vv\": \"\\\\vee\",\n  \"vvv\": \"\\\\bigvee\",\n  \"nn\": \"\\\\cap\",\n  \"nnn\": \"\\\\bigcap\",\n  \"uu\": \"\\\\cup\",\n  \"uuu\": \"\\\\bigcup\",\n  // Binary relation symbols\n  \"-=\": \"\\\\equiv\",\n  \"~=\": \"\\\\cong\",\n  \"lt\": \"<\",\n  \"lt=\": \"\\\\leq\",\n  \"gt\": \">\",\n  \"gt=\": \"\\\\geq\",\n  \"-<\": \"\\\\prec\",\n  \"-lt\": \"\\\\prec\",\n  \"-<=\": \"\\\\preceq\",\n  // '>-':                   '\\\\succ',\n  \">-=\": \"\\\\succeq\",\n  \"prop\": \"\\\\propto\",\n  \"diamond\": \"\\\\diamond\",\n  \"square\": \"\\\\square\",\n  \"iff\": \"\\\\iff\",\n  \"sub\": \"\\\\subset\",\n  \"sup\": \"\\\\supset\",\n  \"sube\": \"\\\\subseteq\",\n  \"supe\": \"\\\\supseteq\",\n  \"uarr\": \"\\\\uparrow\",\n  \"darr\": \"\\\\downarrow\",\n  \"rarr\": \"\\\\rightarrow\",\n  \"rArr\": \"\\\\Rightarrow\",\n  \"larr\": \"\\\\leftarrow\",\n  \"lArr\": \"\\\\Leftarrow\",\n  \"harr\": \"\\\\leftrightarrow\",\n  \"hArr\": \"\\\\Leftrightarrow\",\n  \"aleph\": \"\\\\aleph\",\n  // Logic\n  \"and\": \"\\\\land\",\n  \"or\": \"\\\\lor\",\n  \"not\": \"\\\\neg\",\n  \"_|_\": \"\\\\bot\",\n  \"TT\": \"\\\\top\",\n  \"|--\": \"\\\\vdash\",\n  \"|==\": \"\\\\models\",\n  // Other functions\n  \"|__\": \"\\\\lfloor\",\n  \"__|\": \"\\\\rfloor\",\n  \"|~\": \"\\\\lceil\",\n  \"~|\": \"\\\\rceil\",\n  // Arrows\n  \">->\": \"\\\\rightarrowtail\",\n  \"->>\": \"\\\\twoheadrightarrow\",\n  // \\char\"21A0\n  \">->>\": \"\\\\twoheadrightarrowtail\",\n  // \\char\"2916\n  //\n  // Desmos Graphing Calculator\n  //\n  \"frac\": \"\\\\frac{#?}{#?}\",\n  \"cbrt\": \"\\\\sqrt[3]{#?}\",\n  \"nthroot\": \"\\\\sqrt[#?]{#?}\"\n};\n\n// src/formats/parse-math-string.ts\nfunction parseMathString(s, options) {\n  var _a3;\n  let format = (_a3 = options == null ? void 0 : options.format) != null ? _a3 : \"auto\";\n  if (format === \"auto\") [format, s] = inferFormat(s);\n  if (format === \"ascii-math\") {\n    s = s.replace(/\\u2061/gu, \"\");\n    s = s.replace(/\\u3016/gu, \"{\");\n    s = s.replace(/\\u3017/gu, \"}\");\n    s = s.replace(/([^\\\\])sinx/g, \"$1\\\\sin x\");\n    s = s.replace(/([^\\\\])cosx/g, \"$1\\\\cos x \");\n    s = s.replace(/\\u2013/g, \"-\");\n    return [\n      \"ascii-math\",\n      parseMathExpression(s, { inlineShortcuts: options == null ? void 0 : options.inlineShortcuts })\n    ];\n  }\n  return [\"latex\", s];\n}\nfunction parseMathExpression(s, options) {\n  var _a3;\n  s = s.trim();\n  if (!s) return \"\";\n  const inlineShortcuts = (_a3 = options.inlineShortcuts) != null ? _a3 : INLINE_SHORTCUTS;\n  if (s.startsWith(\"^\") || s.startsWith(\"_\")) {\n    const { match: match2, rest: rest2 } = parseMathArgument(s.slice(1), {\n      inlineShortcuts,\n      noWrap: true\n    });\n    return `${s[0]}{${match2}}${parseMathExpression(rest2, options)}`;\n  }\n  let m = s.match(/^(sqrt|\\u221A)(.*)/);\n  if (m) {\n    const { match: match2, rest: rest2 } = parseMathArgument(m[2], {\n      inlineShortcuts,\n      noWrap: true\n    });\n    return `\\\\sqrt{${match2 != null ? match2 : \"\\\\placeholder{}\"}}${parseMathExpression(\n      rest2,\n      options\n    )}`;\n  }\n  m = s.match(/^(\\\\cbrt|\\u221B)(.*)/);\n  if (m) {\n    const { match: match2, rest: rest2 } = parseMathArgument(m[2], {\n      inlineShortcuts,\n      noWrap: true\n    });\n    return `\\\\sqrt[3]{${match2 != null ? match2 : \"\\\\placeholder{}\"}}${parseMathExpression(\n      rest2,\n      options\n    )}`;\n  }\n  m = s.match(/^abs(.*)/);\n  if (m) {\n    const { match: match2, rest: rest2 } = parseMathArgument(m[1], {\n      inlineShortcuts,\n      noWrap: true\n    });\n    return `\\\\left|${match2 != null ? match2 : \"\\\\placeholder{}\"}\\\\right|${parseMathExpression(\n      rest2,\n      options\n    )}`;\n  }\n  m = s.match(/^[\"”“](.*?)[\"”“](.*)/);\n  if (m) {\n    return `\\\\text{${m[1]}}${parseMathExpression(m[2], options)}`;\n  }\n  m = s.match(/^([^a-zA-Z\\(\\{\\[\\_\\^\\\\\\s\"]+)(.*)/);\n  if (m) {\n    return `${paddedShortcut(m[1], inlineShortcuts)}${parseMathExpression(\n      m[2],\n      options\n    )}`;\n  }\n  if (/^([fgh])[^a-zA-Z]/.test(s)) {\n    const { rest: rest2, match: match2 } = parseMathArgument(s.slice(1), {\n      inlineShortcuts,\n      noWrap: true\n    });\n    let result = \"\";\n    if (s[1] === \"(\") result = `${s[0]}\\\\left(${match2}\\\\right)`;\n    else result = s[0] + match2;\n    return result + parseMathExpression(rest2, options);\n  }\n  m = s.match(/^([a-zA-Z]+)(.*)/);\n  if (m) {\n    return paddedShortcut(m[1], inlineShortcuts) + parseMathExpression(m[2], options);\n  }\n  const { match, rest } = parseMathArgument(s, {\n    inlineShortcuts,\n    noWrap: true\n  });\n  if (match && rest[0] === \"/\") {\n    const m2 = parseMathArgument(rest.slice(1), {\n      inlineShortcuts,\n      noWrap: true\n    });\n    if (m2.match) {\n      return `\\\\frac{${match}}{${m2.match}}${parseMathExpression(\n        m2.rest,\n        options\n      )}`;\n    }\n  } else {\n    return s.startsWith(\"(\") ? \"\\\\left(\" + match + \"\\\\right)\" + parseMathExpression(rest, options) : match + parseMathExpression(rest, options);\n  }\n  m = s.match(/^(\\s+)(.*)$/);\n  if (m) return \" \" + parseMathExpression(m[2], options);\n  return s;\n}\nvar FENCES = {\n  \"[\": \"\\\\lbrack\",\n  \"]\": \"\\\\rbrack\",\n  \"{\": \"\\\\lbrace\",\n  \"}\": \"\\\\rbrace\"\n};\nfunction parseMathArgument(s, options) {\n  var _a3, _b3;\n  let match = \"\";\n  s = s.trim();\n  let rest = s;\n  let lFence = s.charAt(0);\n  let rFence = { \"(\": \")\", \"{\": \"}\", \"[\": \"]\" }[lFence];\n  if (rFence) {\n    let level = 1;\n    let i = 1;\n    while (i < s.length && level > 0) {\n      if (s[i] === lFence) level++;\n      if (s[i] === rFence) level--;\n      i++;\n    }\n    if (level === 0) {\n      const body = parseMathExpression(s.substring(1, i - 1), options);\n      if (options.noWrap && lFence === \"(\") match = body;\n      else\n        match = `\\\\left${(_a3 = FENCES[lFence]) != null ? _a3 : lFence}${body}\\\\right${(_b3 = FENCES[rFence]) != null ? _b3 : rFence}`;\n      rest = s.slice(Math.max(0, i));\n    } else {\n      match = s.substring(1, i);\n      rest = \"\";\n    }\n  } else {\n    let m = s.match(/^([a-zA-Z]+)/);\n    if (m) {\n      let shortcut = getInlineShortcut(null, s, options.inlineShortcuts);\n      if (shortcut) {\n        shortcut = shortcut.replace(\"_{#?}\", \"\");\n        shortcut = shortcut.replace(\"^{#?}\", \"\");\n        return { match: shortcut, rest: s.slice(shortcut.length) };\n      }\n    }\n    m = s.match(/^([a-zA-Z])/);\n    if (m) {\n      return { match: m[1], rest: s.slice(1) };\n    }\n    m = s.match(/^(-)?\\d+(\\.\\d*)?/);\n    if (m) {\n      return { match: m[0], rest: s.slice(m[0].length) };\n    }\n    if (!/^\\\\(left|right)/.test(s)) {\n      m = s.match(/^(\\\\[a-zA-Z]+)/);\n      if (m) {\n        rest = s.slice(m[1].length);\n        match = m[1];\n      }\n    }\n  }\n  return { match, rest };\n}\nfunction paddedShortcut(s, shortcuts) {\n  let result = getInlineShortcut(null, s, shortcuts);\n  if (result) {\n    result = result.replace(\"_{#?}\", \"\");\n    result = result.replace(\"^{#?}\", \"\");\n    result += \" \";\n  } else result = s;\n  return result;\n}\nvar MODE_SHIFT_COMMANDS = [\n  [\"\\\\[\", \"\\\\]\"],\n  [\"\\\\(\", \"\\\\)\"],\n  [\"$$\", \"$$\"],\n  [\"$\", \"$\"],\n  // Must be *after* $$..$$\n  [\"\\\\begin{math}\", \"\\\\end{math}\"],\n  [\"\\\\begin{displaymath}\", \"\\\\end{displaymath}\"],\n  [\"\\\\begin{equation}\", \"\\\\end{equation}\"],\n  [\"\\\\begin{equation*}\", \"\\\\end{equation*}\"]\n];\nfunction trimModeShiftCommand(s) {\n  const trimmedString = s.trim();\n  for (const mode of MODE_SHIFT_COMMANDS) {\n    if (trimmedString.startsWith(mode[0]) && trimmedString.endsWith(mode[1])) {\n      return [\n        true,\n        trimmedString.substring(\n          mode[0].length,\n          trimmedString.length - mode[1].length\n        )\n      ];\n    }\n  }\n  return [false, s];\n}\nfunction inferFormat(s) {\n  s = s.trim();\n  if (s.length <= 1) return [\"latex\", s];\n  let hasLatexModeShiftCommand;\n  [hasLatexModeShiftCommand, s] = trimModeShiftCommand(s);\n  if (hasLatexModeShiftCommand) return [\"latex\", s];\n  if (s.startsWith(\"`\") && s.endsWith(\"`\")) {\n    s = s.substring(1, s.length - 1);\n    return [\"ascii-math\", s];\n  }\n  if (s.includes(\"\\\\\")) {\n    return [\"latex\", s];\n  }\n  if (/\\$.+\\$/.test(s)) {\n    return [\"latex\", `\\\\text{${s}}`];\n  }\n  return [void 0, s];\n}\n\n// src/editor-mathfield/mode-editor.ts\nvar CLIPBOARD_LATEX_BEGIN = \"$$\";\nvar CLIPBOARD_LATEX_END = \"$$\";\nvar defaultExportHook = (_from, latex, _range) => {\n  if (!MODE_SHIFT_COMMANDS.some(\n    (x) => latex.startsWith(x[0]) && latex.endsWith(x[1])\n  ))\n    latex = `${CLIPBOARD_LATEX_BEGIN} ${latex} ${CLIPBOARD_LATEX_END}`;\n  return latex;\n};\nvar _ModeEditor = class _ModeEditor {\n  constructor(name) {\n    _ModeEditor._modes[name] = this;\n  }\n  static onPaste(mode, mathfield, data) {\n    var _a3;\n    if (!mathfield.contentEditable && mathfield.userSelect === \"none\") {\n      mathfield.model.announce(\"plonk\");\n      return false;\n    }\n    if (typeof data === \"string\") {\n      const dataTransfer = new DataTransfer();\n      dataTransfer.setData(\"text/plain\", data);\n      data = dataTransfer;\n    }\n    const redispatchedEvent = new ClipboardEvent(\"paste\", {\n      clipboardData: data,\n      cancelable: true\n    });\n    if (!((_a3 = mathfield.host) == null ? void 0 : _a3.dispatchEvent(redispatchedEvent))) return false;\n    return _ModeEditor._modes[mode].onPaste(mathfield, data);\n  }\n  /** Call this method from a menu */\n  static copyToClipboard(mathfield, format) {\n    if (!mathfield.contentEditable && mathfield.userSelect === \"none\") {\n      mathfield.model.announce(\"plonk\");\n      return;\n    }\n    const model = mathfield.model;\n    const exportRange = model.selectionIsCollapsed ? [0, model.lastOffset] : range(model.selection);\n    const latex = model.getValue(exportRange, format);\n    navigator.clipboard.writeText(latex).then(\n      () => {\n      },\n      () => mathfield.model.announce(\"plonk\")\n    );\n  }\n  /** Call this method in response to a clipboard event */\n  static onCopy(mathfield, ev) {\n    var _a3;\n    if (!ev.clipboardData) return;\n    if (!mathfield.contentEditable && mathfield.userSelect === \"none\") {\n      mathfield.model.announce(\"plonk\");\n      return;\n    }\n    const model = mathfield.model;\n    const exportRange = model.selectionIsCollapsed ? [0, model.lastOffset] : range(model.selection);\n    let atoms = model.getAtoms(exportRange);\n    if (atoms.every((x) => x.mode === \"text\" || !x.mode)) {\n      ev.clipboardData.setData(\n        \"text/plain\",\n        atoms.filter((x) => x instanceof TextAtom).map((x) => x.value).join(\"\")\n      );\n    } else if (atoms.every((x) => x.mode === \"latex\")) {\n      ev.clipboardData.setData(\n        \"text/plain\",\n        model.getAtoms(exportRange, { includeChildren: true }).map((x) => {\n          var _a4;\n          return (_a4 = x.value) != null ? _a4 : \"\";\n        }).join(\"\")\n      );\n    } else {\n      let latex;\n      if (atoms.length === 1 && atoms[0].verbatimLatex !== void 0)\n        latex = atoms[0].verbatimLatex;\n      else latex = model.getValue(exportRange, \"latex-expanded\");\n      ev.clipboardData.setData(\"application/x-latex\", latex);\n      try {\n        ev.clipboardData.setData(\n          \"text/plain\",\n          mathfield.options.onExport(mathfield, latex, exportRange)\n        );\n      } catch (e) {\n      }\n      if (atoms.length === 1) {\n        const atom = atoms[0];\n        if (atom.type === \"root\" || atom.type === \"group\")\n          atoms = atom.body.filter((x) => x.type !== \"first\");\n      }\n      try {\n        ev.clipboardData.setData(\n          \"application/json+mathlive\",\n          JSON.stringify(atoms.map((x) => x.toJson()))\n        );\n      } catch (e) {\n      }\n      if ((_a3 = window[Symbol.for(\"io.cortexjs.compute-engine\")]) == null ? void 0 : _a3.ComputeEngine) {\n        const ce = globalThis.MathfieldElement.computeEngine;\n        if (ce) {\n          try {\n            const options = ce.jsonSerializationOptions;\n            ce.jsonSerializationOptions = { metadata: [\"latex\"] };\n            const expr = ce.parse(\n              model.getValue(exportRange, \"latex-unstyled\")\n            );\n            ce.jsonSerializationOptions = options;\n            const mathJson = JSON.stringify(expr.json);\n            if (mathJson)\n              ev.clipboardData.setData(\"application/json\", mathJson);\n          } catch (e) {\n          }\n        }\n      }\n    }\n    ev.preventDefault();\n  }\n  static insert(model, text, options = {}) {\n    var _a3;\n    const mode = options.mode === \"auto\" ? model.mode : (_a3 = options.mode) != null ? _a3 : model.mode;\n    return _ModeEditor._modes[mode].insert(model, text, options);\n  }\n  onPaste(_mathfield, _data) {\n    return false;\n  }\n  insert(_model, _text, _options) {\n    return false;\n  }\n};\n_ModeEditor._modes = {};\nvar ModeEditor = _ModeEditor;\n\n// src/editor/keybindings-definitions.ts\nvar DEFAULT_KEYBINDINGS = [\n  { key: \"left\", command: \"moveToPreviousChar\" },\n  { key: \"right\", command: \"moveToNextChar\" },\n  { key: \"up\", command: \"moveUp\" },\n  { key: \"down\", command: \"moveDown\" },\n  { key: \"shift+[ArrowLeft]\", command: \"extendSelectionBackward\" },\n  { key: \"shift+[ArrowRight]\", command: \"extendSelectionForward\" },\n  { key: \"shift+[ArrowUp]\", command: \"extendSelectionUpward\" },\n  { key: \"shift+[ArrowDown]\", command: \"extendSelectionDownward\" },\n  { key: \"[Backspace]\", command: \"deleteBackward\" },\n  { key: \"alt+[Delete]\", command: \"deleteBackward\" },\n  { key: \"[Delete]\", command: \"deleteForward\" },\n  { key: \"alt+[Backspace]\", command: \"deleteForward\" },\n  { key: \"alt+[ArrowLeft]\", command: \"moveToPreviousWord\" },\n  { key: \"alt+[ArrowRight]\", command: \"moveToNextWord\" },\n  { key: \"shift+alt+[ArrowLeft]\", command: \"extendToPreviousWord\" },\n  { key: \"shift+alt+[ArrowRight]\", command: \"extendToNextWord\" },\n  { key: \"ctrl+[ArrowLeft]\", command: \"moveToGroupStart\" },\n  { key: \"ctrl+[ArrowRight]\", command: \"moveToGroupEnd\" },\n  { key: \"shift+ctrl+[ArrowLeft]\", command: \"extendToGroupStart\" },\n  { key: \"shift+ctrl+[ArrowRight]\", command: \"extendToGroupEnd\" },\n  { key: \"[Home]\", command: \"moveToMathfieldStart\" },\n  { key: \"cmd+[ArrowLeft]\", command: \"moveToMathfieldStart\" },\n  { key: \"shift+[Home]\", command: \"extendToMathFieldStart\" },\n  { key: \"shift+cmd+[ArrowLeft]\", command: \"extendToMathFieldStart\" },\n  { key: \"[End]\", command: \"moveToMathfieldEnd\" },\n  { key: \"cmd+[ArrowRight]\", command: \"moveToMathfieldEnd\" },\n  { key: \"shift+[End]\", command: \"extendToMathFieldEnd\" },\n  { key: \"shift+cmd+[ArrowRight]\", command: \"extendToMathFieldEnd\" },\n  { key: \"[Pageup]\", command: \"moveToGroupStart\" },\n  { key: \"[Pagedown]\", command: \"moveToGroupEnd\" },\n  { key: \"[Tab]\", command: \"moveToNextGroup\" },\n  {\n    key: \"shift+[Tab]\",\n    command: \"moveToPreviousGroup\"\n  },\n  { key: \"[Escape]\", ifMode: \"math\", command: [\"switchMode\", \"latex\"] },\n  { key: \"[Escape]\", ifMode: \"text\", command: [\"switchMode\", \"latex\"] },\n  {\n    key: \"[Escape]\",\n    ifMode: \"latex\",\n    command: [\"complete\", \"complete\", { selectItem: \"true\" }]\n  },\n  // Accept the entry (without the suggestion) and select\n  {\n    key: \"\\\\\",\n    ifMode: \"math\",\n    command: [\"switchMode\", \"latex\", \"\", \"\\\\\"]\n  },\n  // { key: '[Backslash]', ifMode: 'math', command: ['switchMode', 'latex'] },\n  {\n    key: \"[IntlBackslash]\",\n    ifMode: \"math\",\n    command: [\"switchMode\", \"latex\", \"\", \"\\\\\"]\n  },\n  // On UK QWERTY keyboards\n  {\n    key: \"[Tab]\",\n    ifMode: \"latex\",\n    command: [\"complete\", \"accept-suggestion\"]\n  },\n  // Complete the suggestion\n  { key: \"[Return]\", ifMode: \"latex\", command: \"complete\" },\n  { key: \"[Enter]\", ifMode: \"latex\", command: \"complete\" },\n  {\n    key: \"shift+[Escape]\",\n    ifMode: \"latex\",\n    command: [\"complete\", \"reject\"]\n  },\n  // Some keyboards can't generate\n  // this combination, for example in 60% keyboards it is mapped to ~\n  { key: \"[ArrowDown]\", ifMode: \"latex\", command: \"nextSuggestion\" },\n  // { key: 'ios:command:[Tab]', ifMode: 'latex',command: 'nextSuggestion' },\n  { key: \"[ArrowUp]\", ifMode: \"latex\", command: \"previousSuggestion\" },\n  { key: \"ctrl+a\", ifPlatform: \"!macos\", command: \"selectAll\" },\n  { key: \"cmd+a\", command: \"selectAll\" },\n  // Rare keys on some extended keyboards\n  { key: \"[Cut]\", command: \"cutToClipboard\" },\n  { key: \"[Copy]\", command: \"copyToClipboard\" },\n  { key: \"[Paste]\", command: \"pasteFromClipboard\" },\n  { key: \"[Clear]\", command: \"deleteBackward\" },\n  { key: \"[Undo]\", command: \"undo\" },\n  { key: \"[Redo]\", command: \"redo\" },\n  { key: \"[EraseEof]\", command: \"deleteToGroupEnd\" },\n  // Safari on iOS does not send cut/copy/paste commands when the mathfield\n  // is focused, so intercept the keyboard shortcuts.\n  // This is less desirable because the full clipboard API is not accessible\n  // by this path, and user authorization is required.\n  { key: \"ctrl+x\", ifPlatform: \"ios\", command: \"cutToClipboard\" },\n  { key: \"cmd+x\", ifPlatform: \"ios\", command: \"cutToClipboard\" },\n  { key: \"ctrl+c\", ifPlatform: \"ios\", command: \"copyToClipboard\" },\n  { key: \"cmd+c\", ifPlatform: \"ios\", command: \"copyToClipboard\" },\n  { key: \"ctrl+v\", ifPlatform: \"ios\", command: \"pasteFromClipboard\" },\n  { key: \"cmd+v\", ifPlatform: \"ios\", command: \"pasteFromClipboard\" },\n  { key: \"ctrl+z\", ifPlatform: \"!macos\", command: \"undo\" },\n  { key: \"cmd+z\", command: \"undo\" },\n  { key: \"ctrl+y\", ifPlatform: \"!macos\", command: \"redo\" },\n  // ARIA recommendation\n  { key: \"shift+cmd+y\", command: \"redo\" },\n  { key: \"shift+ctrl+z\", ifPlatform: \"!macos\", command: \"redo\" },\n  { key: \"shift+cmd+z\", command: \"redo\" },\n  // EMACS/MACOS BINDINGS\n  { key: \"ctrl+b\", ifPlatform: \"macos\", command: \"moveToPreviousChar\" },\n  { key: \"ctrl+f\", ifPlatform: \"macos\", command: \"moveToNextChar\" },\n  { key: \"ctrl+p\", ifPlatform: \"macos\", command: \"moveUp\" },\n  { key: \"ctrl+n\", ifPlatform: \"macos\", command: \"moveDown\" },\n  { key: \"ctrl+a\", ifPlatform: \"macos\", command: \"moveToMathfieldStart\" },\n  { key: \"ctrl+e\", ifPlatform: \"macos\", command: \"moveToMathfieldEnd\" },\n  {\n    key: \"shift+ctrl+b\",\n    ifPlatform: \"macos\",\n    command: \"extendSelectionBackward\"\n  },\n  {\n    key: \"shift+ctrl+f\",\n    ifPlatform: \"macos\",\n    command: \"extendSelectionForward\"\n  },\n  {\n    key: \"shift+ctrl+p\",\n    ifPlatform: \"macos\",\n    command: \"extendSelectionUpward\"\n  },\n  {\n    key: \"shift+ctrl+n\",\n    ifPlatform: \"macos\",\n    command: \"extendSelectionDownward\"\n  },\n  {\n    key: \"shift+ctrl+a\",\n    ifPlatform: \"macos\",\n    command: \"extendToMathFieldStart\"\n  },\n  {\n    key: \"shift+ctrl+e\",\n    ifPlatform: \"macos\",\n    command: \"extendToMathFieldEnd\"\n  },\n  { key: \"alt+ctrl+b\", ifPlatform: \"macos\", command: \"moveToPreviousWord\" },\n  { key: \"alt+ctrl+f\", ifPlatform: \"macos\", command: \"moveToNextWord\" },\n  {\n    key: \"shift+alt+ctrl+b\",\n    ifPlatform: \"macos\",\n    command: \"extendToPreviousWord\"\n  },\n  {\n    key: \"shift+alt+ctrl+f\",\n    ifPlatform: \"macos\",\n    command: \"extendToNextWord\"\n  },\n  { key: \"ctrl+h\", ifPlatform: \"macos\", command: \"deleteBackward\" },\n  { key: \"ctrl+d\", ifPlatform: \"macos\", command: \"deleteForward\" },\n  { key: \"ctrl+l\", ifPlatform: \"macos\", command: \"scrollIntoView\" },\n  // { key: 'ctrl+t', ifPlatform: 'macos', command: 'transpose' },\n  // WOLFRAM MATHEMATICA BINDINGS\n  {\n    key: \"ctrl+[Digit2]\",\n    ifMode: \"math\",\n    command: [\"insert\", \"\\\\sqrt{#0}\"]\n  },\n  { key: \"ctrl+[Digit5]\", ifMode: \"math\", command: \"moveToOpposite\" },\n  { key: \"ctrl+[Digit6]\", ifMode: \"math\", command: \"moveToSuperscript\" },\n  { key: \"ctrl+[Return]\", ifMode: \"math\", command: \"addRowAfter\" },\n  { key: \"ctrl+[Enter]\", ifMode: \"math\", command: \"addRowAfter\" },\n  { key: \"cmd+[Return]\", ifMode: \"math\", command: \"addRowAfter\" },\n  { key: \"cmd+[Enter]\", ifMode: \"math\", command: \"addRowAfter\" },\n  // Excel keybindings:\n  // shift+space: select entire row, ctrl+space: select an entire column\n  // shift+ctrl++ or ctrl+numpad+\n  // ctrl+- to delete a row or columns\n  // MATHLIVE BINDINGS\n  { key: \"alt+p\", ifMode: \"math\", command: [\"insert\", \"\\\\pi\"] },\n  { key: \"alt+v\", ifMode: \"math\", command: [\"insert\", \"\\\\sqrt{#0}\"] },\n  { key: \"alt+o\", ifMode: \"math\", command: [\"insert\", \"\\\\emptyset\"] },\n  {\n    key: \"alt+d\",\n    ifMode: \"math\",\n    command: [\"insert\", \"\\\\differentialD\"]\n  },\n  {\n    key: \"shift+alt+o\",\n    ifMode: \"math\",\n    command: [\"insert\", \"\\\\varnothing\"]\n  },\n  {\n    key: \"shift+alt+d\",\n    ifMode: \"math\",\n    command: [\"insert\", \"\\\\partial\"]\n  },\n  {\n    key: \"alt+[Backslash]\",\n    ifMode: \"math\",\n    command: [\"insert\", \"\\\\backslash\"]\n  },\n  // \"|\" key} override command mode\n  {\n    key: \"[NumpadDivide]\",\n    ifMode: \"math\",\n    command: [\"insert\", \"\\\\frac{#@}{#?}\"]\n  },\n  // ??\n  {\n    key: \"alt+[NumpadDivide]\",\n    ifMode: \"math\",\n    command: [\"insert\", \"\\\\frac{#?}{#@}\"]\n  },\n  // ??\n  // Accessibility\n  { key: \"shift+alt+k\", command: \"toggleKeystrokeCaption\" },\n  { key: \"alt+[Space]\", command: \"toggleContextMenu\" },\n  { key: \"alt+shift+[Space]\", command: \"toggleVirtualKeyboard\" },\n  // Note: On Mac OS (as of 10.12), there is a bug/behavior that causes\n  // a beep to be generated with certain command+control key combinations.\n  // The workaround is to create a default binding file to silence them.\n  // In ~/Library/KeyBindings/DefaultKeyBinding.dict add these entries:\n  //\n  //   {\n  //      \"^@\\UF701\" = \"noop:\";\n  //    \"^@\\UF702\" = \"noop:\";\n  //      \"^@\\UF703\" = \"noop:\";\n  //  }\n  {\n    key: \"alt+ctrl+[ArrowUp]\",\n    command: [\"speak\", \"all\", { withHighlighting: false }]\n  },\n  {\n    key: \"alt+ctrl+[ArrowDown]\",\n    command: [\"speak\", \"selection\", { withHighlighting: false }]\n  },\n  //\n  // Punctuations and some non-alpha key combinations\n  // only work with specific keyboard layouts\n  //\n  {\n    key: \"shift+[Quote]\",\n    ifLayout: [\"apple.en-intl\", \"windows.en-intl\", \"linux.en\"],\n    ifMode: \"math\",\n    command: [\"switchMode\", \"text\", \"\", \"\"]\n    // command: ['switchMode', 'text', '', '«'],\n  },\n  {\n    key: \"shift+[Quote]\",\n    ifLayout: [\"apple.en-intl\", \"windows.en-intl\", \"linux.en\"],\n    ifMode: \"text\",\n    command: [\"switchMode\", \"math\", \"\", \"\"]\n    // command: ['switchMode', 'math', '»', ''],\n  },\n  {\n    key: \"shift+alt+[KeyT]\",\n    ifMode: \"math\",\n    command: [\"switchMode\", \"text\"]\n  },\n  {\n    key: \"shift+alt+[KeyT]\",\n    ifMode: \"text\",\n    command: [\"switchMode\", \"math\"]\n  },\n  {\n    key: \"/\",\n    ifMode: \"math\",\n    command: [\"insert\", \"\\\\frac{#@}{#?}\"]\n  },\n  {\n    key: \"alt+/\",\n    ifLayout: [\"apple.en-intl\", \"windows.en-intl\", \"linux.en\"],\n    ifMode: \"math\",\n    command: [\"insert\", \"/\"]\n  },\n  {\n    key: \"alt+shift+/\",\n    ifLayout: [\"apple.en-intl\", \"windows.en-intl\", \"linux.en\"],\n    ifMode: \"math\",\n    command: [\"insert\", \"/\"]\n  },\n  {\n    key: \"alt+[BracketLeft]\",\n    ifLayout: [\"apple.en-intl\", \"windows.en-intl\", \"linux.en\"],\n    ifMode: \"math\",\n    command: [\"insert\", \"\\\\left\\\\lbrack #0 \\\\right\\\\rbrack\"]\n  },\n  // ??\n  {\n    key: \"ctrl+[Minus]\",\n    ifLayout: [\"apple.en-intl\", \"windows.en-intl\", \"linux.en\"],\n    ifMode: \"math\",\n    command: \"moveToSubscript\"\n  },\n  // ??\n  {\n    key: \"shift+alt+[BracketLeft]\",\n    ifLayout: [\"apple.en-intl\", \"windows.en-intl\", \"linux.en\"],\n    ifMode: \"math\",\n    command: [\"insert\", \"\\\\left\\\\lbrace #0 \\\\right\\\\rbrace\"]\n  },\n  // ??\n  {\n    key: \"ctrl+;\",\n    ifLayout: [\"apple.en-intl\", \"windows.en-intl\", \"linux.en\"],\n    ifMode: \"math\",\n    command: \"addRowAfter\"\n  },\n  {\n    key: \"cmd+;\",\n    ifLayout: [\"apple.en-intl\", \"windows.en-intl\", \"linux.en\"],\n    ifMode: \"math\",\n    command: \"addRowAfter\"\n  },\n  {\n    key: \"shift+ctrl+;\",\n    ifLayout: [\"apple.en-intl\", \"windows.en-intl\", \"linux.en\"],\n    ifMode: \"math\",\n    command: \"addRowBefore\"\n  },\n  {\n    key: \"shift+cmd+;\",\n    ifLayout: [\"apple.en-intl\", \"windows.en-intl\", \"linux.en\"],\n    ifMode: \"math\",\n    command: \"addRowBefore\"\n  },\n  {\n    key: \"ctrl+[Backspace]\",\n    ifMode: \"math\",\n    command: \"removeRow\"\n  },\n  {\n    key: \"cmd+[Backspace]\",\n    ifMode: \"math\",\n    command: \"removeRow\"\n  },\n  // {\n  //   key: 'ctrl+[Comma]',\n  //   ifLayout: ['apple.en-intl', 'windows.en-intl', 'linux.en'],\n  //   ifMode: 'math',\n  //   command: 'addColumnAfter',\n  // },\n  // {\n  //   key: 'cmd+[Comma]',\n  //   ifLayout: ['apple.en-intl', 'windows.en-intl', 'linux.en'],\n  //   ifMode: 'math',\n  //   command: 'addColumnAfter',\n  // },\n  // {\n  //   key: 'shift+ctrl+[Comma]',\n  //   ifLayout: ['apple.en-intl', 'windows.en-intl', 'linux.en'],\n  //   ifMode: 'math',\n  //   command: 'addColumnBefore',\n  // },\n  // {\n  //   key: 'shift+cmd+[Comma]',\n  //   ifLayout: ['apple.en-intl', 'windows.en-intl', 'linux.en'],\n  //   ifMode: 'math',\n  //   command: 'addColumnBefore',\n  // },\n  { key: \"alt+[Tab]\", ifMode: \"math\", command: \"addColumnAfter\" },\n  { key: \"shift+alt+[Tab]\", ifMode: \"math\", command: \"addColumnBefore\" },\n  { key: \"alt+[Enter]\", ifMode: \"math\", command: \"addRowAfter\" },\n  { key: \"shift+alt+[Enter]\", ifMode: \"math\", command: \"addRowBefore\" },\n  { key: \"alt+[Return]\", ifMode: \"math\", command: \"addRowAfter\" },\n  { key: \"shift+alt+[Return]\", ifMode: \"math\", command: \"addRowBefore\" },\n  {\n    key: \"shift+[Backspace]\",\n    ifMode: \"math\",\n    command: \"removeColumn\"\n  },\n  {\n    key: \"alt+[Digit5]\",\n    ifLayout: [\"apple.en-intl\", \"windows.en-intl\", \"linux.en\"],\n    ifMode: \"math\",\n    command: [\"insert\", \"$\\\\infty\"]\n  },\n  // \"%\" key\n  {\n    key: \"alt+[Digit9]\",\n    ifLayout: [\"apple.en-intl\", \"windows.en-intl\", \"linux.en\"],\n    ifMode: \"math\",\n    command: [\"insert\", \"(\"]\n  },\n  // \"(\" key} override smartFence\n  {\n    key: \"alt+[Digit0]\",\n    ifLayout: [\"apple.en-intl\", \"windows.en-intl\", \"linux.en\"],\n    ifMode: \"math\",\n    command: [\"insert\", \")\"]\n  },\n  // \")\" key} override smartFence\n  {\n    key: \"alt+|\",\n    ifLayout: [\"apple.en-intl\", \"windows.en-intl\", \"linux.en\"],\n    ifMode: \"math\",\n    command: [\"insert\", \"|\"]\n  },\n  // \"|\" key} override smartFence\n  {\n    key: \"shift+[Backquote]\",\n    ifLayout: [\"apple.en-intl\", \"windows.en-intl\", \"linux.en\"],\n    ifMode: \"math\",\n    command: [\"insert\", \"\\\\~\"]\n  },\n  // ??\n  {\n    key: \"[Backquote]\",\n    ifLayout: [\"windows.french\", \"linux.french\"],\n    ifMode: \"math\",\n    command: [\"insert\", \"^2\"]\n  },\n  {\n    key: \"[Backquote]\",\n    ifLayout: [\"windows.german\", \"linux.german\"],\n    ifMode: \"math\",\n    command: [\"insert\", \"^\"]\n  },\n  {\n    key: \"[IntlBackslash]\",\n    ifLayout: [\"apple.german\"],\n    ifMode: \"math\",\n    command: [\"insert\", \"^\"]\n  }\n];\nvar REVERSE_KEYBINDINGS = {\n  \"\\\\sqrt\": [\"alt+v\", \"ctrl+[Digit2]\"],\n  \"\\\\pi\": \"alt+p\",\n  \"\\\\infty\": \"alt+[Digit5]\",\n  \"\\\\differentialD\": \"alt+d\",\n  \"\\\\partial\": \"shift+alt+d\",\n  \"\\\\frac\": \"Slash\",\n  \"\\\\emptyset\": \"alt+o\",\n  \"\\\\varnothing\": \"shift+alt+o\",\n  \"\\\\~\": \"~\"\n};\n\n// src/editor-mathfield/utils.ts\nfunction isValidMathfield(mf) {\n  var _a3;\n  return ((_a3 = mf.element) == null ? void 0 : _a3.mathfield) === mf;\n}\nfunction findElementWithCaret(element) {\n  var _a3, _b3;\n  return (_b3 = (_a3 = element.querySelector(\".ML__caret\")) != null ? _a3 : element.querySelector(\".ML__text-caret\")) != null ? _b3 : element.querySelector(\".ML__latex-caret\");\n}\nfunction getCaretPoint(element) {\n  const caret = findElementWithCaret(element);\n  if (!caret) return null;\n  const bounds = caret.getBoundingClientRect();\n  return {\n    x: bounds.right,\n    y: bounds.bottom,\n    height: bounds.height\n  };\n}\nfunction branchId(atom) {\n  var _a3;\n  if (!atom.parent) return \"root\";\n  let result = (_a3 = atom.parent.id) != null ? _a3 : \"\";\n  result += typeof atom.parentBranch === \"string\" ? \"-\" + atom.parentBranch : `-${atom.parentBranch[0]}/${atom.parentBranch[0]}`;\n  return result;\n}\nfunction adjustForScrolling(mathfield, rect, scaleFactor) {\n  if (!rect) return null;\n  const fieldRect = mathfield.field.getBoundingClientRect();\n  const w = rect.right - rect.left;\n  const h = rect.bottom - rect.top;\n  const left = Math.ceil(\n    rect.left - fieldRect.left + mathfield.field.scrollLeft * scaleFactor\n  );\n  const top = Math.ceil(rect.top - fieldRect.top);\n  return { left, right: left + w, top, bottom: top + h };\n}\nfunction getNodeBounds(node) {\n  const bounds = node.getBoundingClientRect();\n  const marginRight = parseInt(getComputedStyle(node).marginRight);\n  const result = {\n    top: bounds.top - 1,\n    bottom: bounds.bottom,\n    left: bounds.left,\n    right: bounds.right - 1 + marginRight\n  };\n  if (node.children.length === 0 || node.tagName.toUpperCase() === \"SVG\")\n    return result;\n  for (const child of node.children) {\n    if (child.nodeType === 1 && \"atomId\" in child.dataset && !child.classList.contains(\"ML__pstrut\")) {\n      const r = getNodeBounds(child);\n      result.left = Math.min(result.left, r.left);\n      result.right = Math.max(result.right, r.right);\n      result.top = Math.min(result.top, r.top);\n      result.bottom = Math.max(result.bottom, r.bottom);\n    }\n  }\n  return result;\n}\nfunction getAtomBounds(mathfield, atom) {\n  var _a3, _b3;\n  if (!atom.id) return null;\n  let result = (_b3 = (_a3 = mathfield.atomBoundsCache) == null ? void 0 : _a3.get(atom.id)) != null ? _b3 : null;\n  if (result !== null) return result;\n  const node = mathfield.field.querySelector(`[data-atom-id=\"${atom.id}\"]`);\n  result = node ? getNodeBounds(node) : null;\n  if (mathfield.atomBoundsCache) {\n    if (result) mathfield.atomBoundsCache.set(atom.id, result);\n    else mathfield.atomBoundsCache.delete(atom.id);\n  }\n  return result != null ? result : null;\n}\nfunction getRangeBounds(mathfield, range2, options) {\n  const rects = /* @__PURE__ */ new Map();\n  for (const atom of mathfield.model.getAtoms(range2, {\n    includeChildren: true\n  })) {\n    if ((options == null ? void 0 : options.excludeAtomsWithBackground) && atom.style.backgroundColor)\n      continue;\n    const field = mathfield.field;\n    const offsetWidth = field.offsetWidth;\n    const actualWidth = Math.floor(field.getBoundingClientRect().width);\n    let scaleFactor = actualWidth / offsetWidth;\n    scaleFactor = isNaN(scaleFactor) ? 1 : scaleFactor;\n    const bounds = adjustForScrolling(\n      mathfield,\n      getAtomBounds(mathfield, atom),\n      scaleFactor\n    );\n    if (bounds) {\n      const id = branchId(atom);\n      if (rects.has(id)) {\n        const r = rects.get(id);\n        rects.set(id, {\n          left: Math.min(r.left, bounds.left),\n          right: Math.max(r.right, bounds.right),\n          top: Math.min(r.top, bounds.top),\n          bottom: Math.max(r.bottom, bounds.bottom)\n        });\n      } else rects.set(id, bounds);\n    }\n  }\n  return [...rects.values()];\n}\nfunction getSelectionBounds(mathfield, options) {\n  return mathfield.model.selection.ranges.reduce(\n    (acc, x) => acc.concat(...getRangeBounds(mathfield, x, options)),\n    []\n  );\n}\nfunction validateOrigin(origin, originValidator) {\n  if (origin === \"*\" || originValidator === \"none\") return true;\n  if (originValidator === \"same-origin\")\n    return !window.origin || origin === window.origin;\n  if (typeof originValidator === \"function\") return originValidator(origin);\n  return false;\n}\nfunction getLocalDOMRect(el) {\n  let offsetTop = 0;\n  let offsetLeft = 0;\n  const width = el.offsetWidth;\n  const height = el.offsetHeight;\n  while (el instanceof HTMLElement) {\n    offsetTop += el.offsetTop;\n    offsetLeft += el.offsetLeft;\n    el = el.offsetParent;\n  }\n  return new DOMRect(offsetLeft, offsetTop, width, height);\n}\nfunction getElementInfo(mf, offset) {\n  if (!mf) return void 0;\n  const atom = mf.model.at(offset);\n  if (!atom) return void 0;\n  let result = {};\n  const bounds = getAtomBounds(mf, atom);\n  if (bounds)\n    result.bounds = new DOMRect(\n      bounds.left,\n      bounds.top,\n      bounds.right - bounds.left,\n      bounds.bottom - bounds.top\n    );\n  result.depth = atom.treeDepth - 2;\n  result.style = atom.style;\n  let a = atom;\n  while (a) {\n    if (a.command === \"\\\\htmlData\" && a.args && typeof a.args[0] === \"string\") {\n      const entries = a.args[0].split(\",\");\n      for (const entry of entries) {\n        const matched = entry.match(/([^=]+)=(.+$)/);\n        if (matched) {\n          const key = matched[1].trim().replace(/ /g, \"-\");\n          if (key) {\n            if (!result.data) result.data = {};\n            result.data[key] = matched[2];\n          }\n        } else {\n          const key = entry.trim().replace(/ /g, \"-\");\n          if (key) {\n            if (!result.data) result.data = {};\n            result.data[key] = void 0;\n          }\n        }\n      }\n    }\n    if (a.command === \"\\\\htmlId\" || a.command === \"\\\\cssId\") {\n      if (!result.id && a.args && typeof a.args[0] === \"string\") {\n        result.id = a.args[0];\n      }\n    }\n    a = a.parent;\n  }\n  if (atom.mode === \"math\" || atom.mode === \"text\")\n    result.latex = Atom.serialize([atom], { defaultMode: \"math\" });\n  return result;\n}\nfunction getHref(mf, offset) {\n  let a = mf.model.at(offset);\n  while (a) {\n    if (a.command === \"\\\\href\") {\n      const url = a.args[0];\n      if (typeof url === \"string\") return url;\n    }\n    a = a.parent;\n  }\n  return \"\";\n}\n\n// css/mathfield.less\nvar mathfield_default = `@keyframes ML__caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n.ML__container {\n  display: inline-flex;\n  flex-flow: row;\n  justify-content: space-between;\n  align-items: flex-end;\n  min-height: 39px;\n  /* Need some room for the virtual keyboard toggle */\n  width: 100%;\n  padding: 4px;\n  box-sizing: border-box;\n  /* This attribute is necessary to work around a Firefox issue where \n  where clicking multiple times on the border leads to a focused mathfield that cannot be edited until focus is lost and regained (also fixes the multiple cursor issue on firefox that can occur with the same sequence of events).\n  */\n  pointer-events: auto;\n  /* Prevent the browser from trying to interpret touch gestures in the field */\n  /* \"Disabling double-tap to zoom removes the need for browsers to\n        delay the generation of click events when the user taps the screen.\" */\n  touch-action: none;\n  --_caret-color: var(--caret-color, hsl(var(--_hue), 40%, 49%));\n  --_selection-color: var(--selection-color, #000);\n  --_selection-background-color: var(--selection-background-color, hsl(var(--_hue), 70%, 85%));\n  --_text-highlight-background-color: var(--highlight-text, hsla(var(--_hue), 40%, 50%, 0.1));\n  --_contains-highlight-background-color: var(--contains-highlight-background-color, hsl(var(--_hue), 40%, 95%));\n  --_smart-fence-color: var(--smart-fence-color, currentColor);\n  --_smart-fence-opacity: var(--smart-fence-opacity, 0.5);\n  --_latex-color: var(--latex-color, hsl(var(--_hue), 80%, 40%));\n  --_correct-color: var(--correct-color, #10a000);\n  --_incorrect-color: var(--incorrect-color, #a01b00);\n  --_composition-background-color: var(--composition-background-color, #fff1c2);\n  --_composition-text-color: var(--composition-text-color, black);\n  --_composition-underline-color: var(--composition-underline-color, transparent);\n  --_tooltip-border: var(--tooltip-border, 1px solid transparent);\n  --_tooltip-border-radius: var(--tooltip-border-radius, 8px);\n  --_tooltip-background-color: var(--tooltip-background-color, #616161);\n  --_tooltip-color: var(--tooltip-color, #fff);\n  --_tooltip-box-shadow: var(--tooltip-box-shadow, 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2));\n}\n@media (hover: none) and (pointer: coarse) {\n  :host(:not(:focus)) .ML__container {\n    pointer-events: none;\n  }\n}\n/* This is the actual field content (formula) */\n.ML__content {\n  display: flex;\n  align-items: center;\n  align-self: center;\n  position: relative;\n  overflow: hidden;\n  padding: 2px 3px 2px 1px;\n  width: 100%;\n  /* Encourage the browser to use the GPU to render the field.\n     Weirdly, this is required for prompts to be rendered correctly. \n   */\n  isolation: isolate;\n}\n.ML__virtual-keyboard-toggle,\n.ML__menu-toggle {\n  box-sizing: border-box;\n  display: flex;\n  align-self: center;\n  align-items: center;\n  flex-shrink: 0;\n  flex-direction: column;\n  justify-content: center;\n  width: 34px;\n  height: 34px;\n  padding: 0;\n  margin-right: 4px;\n  cursor: pointer;\n  /* Avoid some weird blinking with :hover */\n  border-radius: 8px;\n  border: 1px solid transparent;\n  transition: background 0.2s cubic-bezier(0.64, 0.09, 0.08, 1);\n  color: hsl(var(--_hue), 40%, 50%);\n  fill: currentColor;\n  background: transparent;\n}\n.ML__virtual-keyboard-toggle:hover,\n.ML__menu-toggle:hover {\n  background: hsla(0, 0%, 70%, 0.3);\n  color: #333;\n  fill: currentColor;\n}\n.ML__virtual-keyboard-toggle > span,\n.ML__menu-toggle > span {\n  display: flex;\n  align-self: center;\n  align-items: center;\n}\n@media (pointer: coarse) {\n  .ML__virtual-keyboard-toggle,\n  .ML__menu-toggle {\n    min-width: 60px;\n    min-height: 60px;\n  }\n}\n/* The invisible element used to capture keyboard events. We're just trying\n really hard to make sure it doesn't show. */\n.ML__keyboard-sink {\n  display: inline-block;\n  resize: none;\n  outline: none;\n  border: none;\n  /* Need these for Microsoft Edge */\n  position: fixed;\n  clip: rect(0 0 0 0);\n  /* Need this to prevent iOS Safari from auto-zooming */\n  font-size: 1em;\n  font-family: KaTeX_Main;\n  line-height: 0.5;\n  /* On Chromium, if this is 0, no keyboard events are received */\n}\n[part='placeholder'] {\n  color: var(--neutral-400);\n}\n.ML__composition {\n  background: var(--_composition-background-color);\n  color: var(--_composition-text-color);\n  text-decoration: underline var(--_composition-underline-color);\n}\n.ML__caret::after {\n  content: '';\n  visibility: hidden;\n  width: 0;\n  display: inline-block;\n  height: 0.76em;\n  --_caret-width: clamp(2px, 0.08em, 10px);\n  border: none;\n  border-radius: calc(var(--_caret-width) / 2);\n  border-right: var(--_caret-width) solid var(--_caret-color);\n  margin-right: calc(-1 * var(--_caret-width));\n  position: relative;\n  left: -0.045em;\n  bottom: -0.05em;\n  animation: ML__caret-blink 1.05s step-end forwards infinite;\n}\n.ML__text-caret::after {\n  content: '';\n  visibility: hidden;\n  width: 0;\n  display: inline-block;\n  height: 0.76em;\n  --_caret-width: clamp(2px, 0.08em, 10px);\n  border: none;\n  border-radius: calc(var(--_caret-width) / 2);\n  border-right: var(--_caret-width) solid var(--_caret-color);\n  margin-right: calc(-1 * var(--_caret-width));\n  position: relative;\n  left: -0.045em;\n  bottom: -0.05em;\n  animation: ML__caret-blink 1.05s step-end forwards infinite;\n}\n.ML__latex-caret::after {\n  content: '';\n  visibility: hidden;\n  --_caret-width: clamp(2px, 0.08em, 10px);\n  border: none;\n  border-radius: calc(var(--_caret-width) / 2);\n  border-right: var(--_caret-width) solid var(--_latex-color);\n  margin-right: calc(-1 * var(--_caret-width));\n  position: relative;\n  left: -0.019em;\n  animation: ML__caret-blink 1.05s step-end forwards infinite;\n}\n.ML__focused .ML__latex-caret::after,\n.ML__focused .ML__text-caret::after,\n.ML__focused .ML__caret::after {\n  visibility: visible;\n}\n.ML__focused .ML__text {\n  background: var(--_text-highlight-background-color);\n}\n/* When using smartFence, the anticipated closing fence is displayed\nwith this style */\n.ML__smart-fence__close {\n  opacity: var(--_smart-fence-opacity);\n  color: var(--_smart-fence-color);\n}\n.ML__selected,\n.ML__focused .ML__selected .ML__contains-caret,\n.ML__focused .ML__selected .ML__smart-fence__close,\n.ML__focused .ML__selected .ML__placeholder {\n  color: var(--_selection-color);\n  opacity: 1;\n}\n.ML__selection {\n  box-sizing: border-box;\n  background: transparent;\n}\n:host(:focus) .ML__selection {\n  background: var(--_selection-background-color) !important;\n}\n.ML__contains-caret.ML__close,\n.ML__contains-caret.ML__open,\n.ML__contains-caret > .ML__close,\n.ML__contains-caret > .ML__open,\n.ML__contains-caret .ML__sqrt-sign,\n.ML__contains-caret .ML__sqrt-line {\n  color: var(--_caret-color);\n}\n.ML__contains-highlight {\n  box-sizing: border-box;\n  background: transparent;\n}\n.ML__focused .ML__contains-highlight {\n  background: var(--_contains-highlight-background-color);\n}\n.ML__raw-latex {\n  font-family: 'Berkeley Mono', 'IBM Plex Mono', 'Source Code Pro', Consolas, 'Roboto Mono', Menlo, 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', Monaco, Courier, monospace;\n  font-weight: 400;\n  font-size: 0.8em;\n  letter-spacing: -0.05em;\n  color: var(--_latex-color);\n}\n.ML__suggestion {\n  color: var(--neutral-500);\n}\n.ML__virtual-keyboard-toggle.is-visible.is-pressed:hover {\n  background: hsl(var(--_hue), 25%, 35%);\n  color: #fafafa;\n  fill: currentColor;\n}\n.ML__virtual-keyboard-toggle.is-pressed,\n.ML__virtual-keyboard-toggle.is-active:hover,\n.ML__virtual-keyboard-toggle.is-active {\n  background: hsl(var(--_hue), 25%, 35%);\n  color: #fafafa;\n  fill: currentColor;\n}\n/* Add an attribute 'data-tooltip' to automatically show a\n   tooltip over a element on hover.\n*/\n[data-tooltip] {\n  position: relative;\n}\n[data-tooltip]::after {\n  content: attr(data-tooltip);\n  position: absolute;\n  display: block;\n  z-index: 2;\n  pointer-events: none;\n  right: auto;\n  top: calc(-100% - 4px);\n  width: max-content;\n  max-width: 200px;\n  padding: 8px 8px;\n  border-radius: 4px;\n  background: #616161;\n  color: #fff;\n  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);\n  text-align: center;\n  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n  font-style: normal;\n  font-weight: 400;\n  font-size: 13px;\n  /* Phone */\n  opacity: 0;\n  transform: scale(0.5);\n}\n@media only screen and (max-width: 767px) {\n  [data-tooltip]::after {\n    padding: 8px 16px;\n    font-size: 16px;\n  }\n}\nmenu [data-tooltip]::after {\n  left: 100%;\n  top: 0%;\n}\nmenu .ML__base {\n  cursor: default;\n}\n/** Don't display if we're tracking, i.e. have the pointer down */\n.tracking [data-tooltip]:hover::after {\n  /* Use visibility, not display. Display will remove the after from the DOM, and the override below will not work */\n  visibility: hidden;\n}\n/** But do display if tracking and inside a menu */\n.tracking menu li[data-tooltip]:hover::after,\n[data-tooltip]:hover::after {\n  visibility: visible;\n  opacity: 1;\n  transform: scale(1);\n  transition-property: opacity, scale;\n  transition-duration: 0.15s;\n  transition-delay: 1s;\n  transition-timing-function: cubic-bezier(0.4, 0, 1, 1);\n}\n.ML__prompt {\n  border-radius: 2px;\n}\n.ML__editablePromptBox {\n  outline: 1px solid #acacac;\n  border-radius: 2px;\n  z-index: -1;\n}\n.ML__focusedPromptBox {\n  outline: highlight auto 1px;\n}\n.ML__lockedPromptBox {\n  background-color: rgba(142, 142, 141, 0.4);\n  z-index: -1;\n}\n.ML__correctPromptBox {\n  outline: 1px solid var(--_correct-color);\n  box-shadow: 0 0 5px var(--_correct-color);\n}\n.ML__incorrectPromptBox {\n  outline: 1px solid var(--_incorrect-color);\n  box-shadow: 0 0 5px var(--_incorrect-color);\n}\n.variant-submenu {\n  display: flex;\n  flex-direction: column;\n  padding: 8px;\n}\n.variant-submenu [part='menu-item'].ML__xl {\n  font-size: 2rem;\n  text-align: center;\n  margin: 0;\n}\n.ML__center-menu .label {\n  text-align: center;\n}\n.insert-matrix-submenu {\n  /* Grid doesn't work on Safari */\n  --_menu-item-size: 25px;\n  width: calc(5 * var(--_menu-item-size));\n  display: flex;\n  flex-wrap: wrap;\n  padding: 8px;\n  align-content: center;\n  justify-content: center;\n}\n.insert-matrix-submenu [part='menu-item'] {\n  width: var(--_menu-item-size);\n  height: var(--_menu-item-size);\n  font-size: 21px;\n  border: none;\n  border-radius: 0;\n  line-height: 21px;\n  text-align: center;\n  padding: 0;\n  margin: 0;\n}\n.border-submenu [part='menu-item'] {\n  font-size: 2rem;\n  line-height: 1.2;\n  text-align: center;\n}\n.swatches-submenu {\n  --_swatch-size: 2rem;\n  --_columns: 4;\n  display: flex;\n  flex-flow: wrap;\n  padding: 8px;\n  max-width: calc(var(--_columns) * (var(--_swatch-size) + 18px) + 16px);\n  box-sizing: border-box;\n}\n.menu-swatch {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  box-sizing: border-box;\n  width: fit-content;\n  height: fit-content;\n  margin: 2px;\n  padding: 0;\n  background: var(--neutral-200);\n}\n.menu-swatch > .label {\n  padding: 0;\n  margin: 0;\n  line-height: 0;\n}\n.menu-swatch > .label > span {\n  display: inline-block;\n  margin: 6px;\n  min-width: var(--_swatch-size);\n  min-height: var(--_swatch-size);\n  border-radius: 50%;\n}\n.menu-swatch.active {\n  background: var(--neutral-100);\n  scale: 1.4;\n}\n.menu-swatch.active > .label > span {\n  border-radius: 2px;\n}\n.menu-swatch .ui-checkmark,\n.menu-swatch .ui-mixedmark {\n  position: absolute;\n  margin: 0;\n  padding: 0;\n  color: white;\n}\n.menu-swatch.dark-contrast .ui-checkmark,\n.menu-swatch.dark-contrast .ui-mixedmark {\n  color: #000;\n}\n.ML__insert-template {\n  font-size: 1em;\n}\n.ML__insert-label {\n  opacity: 0.5;\n  margin-left: 2ex;\n}\n`;\n\n// css/core.less\nvar core_default = \".ML__container {\\n  min-height: auto !important;\\n  --_hue: var(--hue, 212);\\n  --_placeholder-color: var(--placeholder-color, hsl(var(--_hue), 40%, 49%));\\n  --_placeholder-opacity: var(--placeholder-opacity, 0.4);\\n  --_text-font-family: var(--text-font-family, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif);\\n}\\n.ML__sr-only {\\n  position: absolute;\\n  width: 1px;\\n  height: 1px;\\n  margin: -1px;\\n  padding: 0;\\n  overflow: hidden;\\n  clip: rect(0, 0, 0, 0);\\n  clip-path: inset(50%);\\n  white-space: nowrap;\\n  border: 0;\\n}\\n.ML__is-inline {\\n  display: inline-block;\\n}\\n.ML__base {\\n  visibility: inherit;\\n  display: inline-block;\\n  position: relative;\\n  cursor: text;\\n  padding: 0;\\n  margin: 0;\\n  box-sizing: content-box;\\n  border: 0;\\n  outline: 0;\\n  vertical-align: baseline;\\n  font-weight: inherit;\\n  font-family: inherit;\\n  font-style: inherit;\\n  text-decoration: none;\\n  width: min-content;\\n}\\n.ML__strut,\\n.ML__strut--bottom {\\n  display: inline-block;\\n  min-height: 0.5em;\\n}\\n.ML__small-delim {\\n  font-family: KaTeX_Main;\\n}\\n/* Text mode */\\n.ML__text {\\n  font-family: var(--_text-font-family);\\n  white-space: pre;\\n}\\n/* Use cmr for 'math upright' */\\n.ML__cmr {\\n  font-family: KaTeX_Main;\\n  font-style: normal;\\n}\\n.ML__mathit {\\n  font-family: KaTeX_Math;\\n  /* The KaTeX_Math font is italic by default, so the font-style below is only \\n     useful when a fallback font is used\\n  */\\n  font-style: italic;\\n}\\n.ML__mathbf {\\n  font-family: KaTeX_Main;\\n  font-weight: bold;\\n}\\n/* Lowercase greek symbols should stick to math font when \\\\mathbf is applied \\n   to match TeX idiosyncratic behavior */\\n.lcGreek.ML__mathbf {\\n  font-family: KaTeX_Math;\\n}\\n.ML__mathbfit {\\n  font-family: KaTeX_Math;\\n  font-weight: bold;\\n  font-style: italic;\\n}\\n.ML__ams {\\n  font-family: KaTeX_AMS;\\n}\\n/* Blackboard */\\n.ML__bb {\\n  font-family: KaTeX_AMS;\\n}\\n.ML__cal {\\n  font-family: KaTeX_Caligraphic;\\n}\\n.ML__frak {\\n  font-family: KaTeX_Fraktur;\\n}\\n.ML__tt {\\n  font-family: KaTeX_Typewriter;\\n}\\n.ML__script {\\n  font-family: KaTeX_Script;\\n}\\n.ML__sans {\\n  font-family: KaTeX_SansSerif;\\n}\\n.ML__series_ul {\\n  font-weight: 100;\\n}\\n.ML__series_el {\\n  font-weight: 100;\\n}\\n.ML__series_l {\\n  font-weight: 200;\\n}\\n.ML__series_sl {\\n  font-weight: 300;\\n}\\n.ML__series_sb {\\n  font-weight: 500;\\n}\\n.ML__bold {\\n  font-weight: 700;\\n}\\n.ML__series_eb {\\n  font-weight: 800;\\n}\\n.ML__series_ub {\\n  font-weight: 900;\\n}\\n.ML__series_uc {\\n  font-stretch: ultra-condensed;\\n}\\n.ML__series_ec {\\n  font-stretch: extra-condensed;\\n}\\n.ML__series_c {\\n  font-stretch: condensed;\\n}\\n.ML__series_sc {\\n  font-stretch: semi-condensed;\\n}\\n.ML__series_sx {\\n  font-stretch: semi-expanded;\\n}\\n.ML__series_x {\\n  font-stretch: expanded;\\n}\\n.ML__series_ex {\\n  font-stretch: extra-expanded;\\n}\\n.ML__series_ux {\\n  font-stretch: ultra-expanded;\\n}\\n.ML__it {\\n  font-style: italic;\\n}\\n.ML__shape_ol {\\n  -webkit-text-stroke: 1px black;\\n  text-stroke: 1px black;\\n  color: transparent;\\n}\\n.ML__shape_sc {\\n  font-variant: small-caps;\\n}\\n.ML__shape_sl {\\n  font-style: oblique;\\n}\\n/* First level emphasis */\\n.ML__emph {\\n  color: #bc2612;\\n}\\n/* Second level emphasis */\\n.ML__emph .ML__emph {\\n  color: #0c7f99;\\n}\\n.ML__highlight {\\n  color: #007cb2;\\n  background: #edd1b0;\\n}\\n.ML__center {\\n  text-align: center;\\n}\\n.ML__left {\\n  text-align: left;\\n}\\n.ML__right {\\n  text-align: right;\\n}\\n.ML__label_padding {\\n  padding: 0 0.5em;\\n}\\n.ML__frac-line {\\n  width: 100%;\\n  min-height: 1px;\\n}\\n.ML__frac-line:after {\\n  content: '';\\n  display: block;\\n  margin-top: max(-1px, -0.04em);\\n  min-height: max(1px, 0.04em);\\n  /* Ensure the line is visible when printing even if \\\"turn off background images\\\" is on*/\\n  -webkit-print-color-adjust: exact;\\n  print-color-adjust: exact;\\n  /* There's a bug since Chrome 62 where \\n      sub-pixel border lines don't draw at some zoom \\n      levels (110%, 90%). \\n      Setting the min-height used to work around it, but that workaround\\n      broke in Chrome 84 or so.\\n      Setting the background (and the min-height) seems to work for now.\\n      */\\n  background: currentColor;\\n  box-sizing: content-box;\\n  /* Vuetify sets the box-sizing to inherit \\n            causes the fraction line to not draw at all sizes (see #26) */\\n  /* On some versions of Firefox on Windows, the line fails to \\n            draw at some zoom levels, but setting the transform triggers\\n            the hardware accelerated path, which works */\\n  transform: translate(0, 0);\\n}\\n.ML__sqrt {\\n  display: inline-block;\\n}\\n.ML__sqrt-sign {\\n  display: inline-block;\\n  position: relative;\\n}\\n.ML__sqrt-line {\\n  display: inline-block;\\n  height: max(1px, 0.04em);\\n  width: 100%;\\n}\\n.ML__sqrt-line:before {\\n  content: '';\\n  display: block;\\n  margin-top: min(-1px, -0.04em);\\n  min-height: max(1px, 0.04em);\\n  /* Ensure the line is visible when printing even if \\\"turn off background images\\\" is on*/\\n  -webkit-print-color-adjust: exact;\\n  print-color-adjust: exact;\\n  background: currentColor;\\n  /* On some versions of Firefox on Windows, the line fails to \\n            draw at some zoom levels, but setting the transform triggers\\n            the hardware accelerated path, which works */\\n  transform: translate(0, 0);\\n}\\n.ML__sqrt-line:after {\\n  border-bottom-width: 1px;\\n  content: ' ';\\n  display: block;\\n  margin-top: -0.1em;\\n}\\n.ML__sqrt-index {\\n  margin-left: 0.27777778em;\\n  margin-right: -0.55555556em;\\n}\\n.ML__delim-size1 {\\n  font-family: KaTeX_Size1;\\n}\\n.ML__delim-size2 {\\n  font-family: KaTeX_Size2;\\n}\\n.ML__delim-size3 {\\n  font-family: KaTeX_Size3;\\n}\\n.ML__delim-size4 {\\n  font-family: KaTeX_Size4;\\n}\\n.ML__delim-mult .delim-size1 > span {\\n  font-family: KaTeX_Size1;\\n}\\n.ML__delim-mult .delim-size4 > span {\\n  font-family: KaTeX_Size4;\\n}\\n.ML__accent-body > span {\\n  font-family: KaTeX_Main;\\n  width: 0;\\n}\\n.ML__accent-vec {\\n  position: relative;\\n  left: 0.24em;\\n}\\n/** The markup for a LaTeX formula, either in an editable mathfield or \\n    in a static display.\\n*/\\n.ML__latex {\\n  display: inline-block;\\n  direction: ltr;\\n  text-align: left;\\n  text-indent: 0;\\n  text-rendering: auto;\\n  font-family: KaTeX_Main, 'Times New Roman', serif;\\n  font-style: normal;\\n  font-size-adjust: none;\\n  font-stretch: normal;\\n  font-variant-caps: normal;\\n  letter-spacing: normal;\\n  line-height: 1.2;\\n  word-wrap: normal;\\n  word-spacing: normal;\\n  white-space: nowrap;\\n  text-shadow: none;\\n  -webkit-user-select: none;\\n  user-select: none;\\n  width: min-content;\\n}\\n.ML__latex .style-wrap {\\n  position: relative;\\n}\\n.ML__latex .ML__mfrac {\\n  display: inline-block;\\n}\\n.ML__latex .ML__left-right {\\n  display: inline-block;\\n}\\n.ML__latex .ML__vlist-t {\\n  display: inline-table;\\n  table-layout: fixed;\\n  border-collapse: collapse;\\n}\\n.ML__latex .ML__vlist-r {\\n  display: table-row;\\n}\\n.ML__latex .ML__vlist {\\n  display: table-cell;\\n  vertical-align: bottom;\\n  position: relative;\\n}\\n.ML__latex .ML__vlist > span {\\n  display: block;\\n  height: 0;\\n  position: relative;\\n}\\n.ML__latex .ML__vlist > span > span {\\n  display: inline-block;\\n}\\n.ML__latex .ML__vlist > span > .ML__pstrut {\\n  overflow: hidden;\\n  width: 0;\\n}\\n.ML__latex .ML__vlist-t2 {\\n  margin-right: -2px;\\n}\\n.ML__latex .ML__vlist-s {\\n  display: table-cell;\\n  vertical-align: bottom;\\n  font-size: 1px;\\n  width: 2px;\\n  min-width: 2px;\\n}\\n.ML__latex .ML__msubsup {\\n  text-align: left;\\n}\\n.ML__latex .ML__negativethinspace {\\n  display: inline-block;\\n  margin-left: -0.16667em;\\n  height: 0.71em;\\n}\\n.ML__latex .ML__thinspace {\\n  display: inline-block;\\n  width: 0.16667em;\\n  height: 0.71em;\\n}\\n.ML__latex .ML__mediumspace {\\n  display: inline-block;\\n  width: 0.22222em;\\n  height: 0.71em;\\n}\\n.ML__latex .ML__thickspace {\\n  display: inline-block;\\n  width: 0.27778em;\\n  height: 0.71em;\\n}\\n.ML__latex .ML__enspace {\\n  display: inline-block;\\n  width: 0.5em;\\n  height: 0.71em;\\n}\\n.ML__latex .ML__quad {\\n  display: inline-block;\\n  width: 1em;\\n  height: 0.71em;\\n}\\n.ML__latex .ML__qquad {\\n  display: inline-block;\\n  width: 2em;\\n  height: 0.71em;\\n}\\n.ML__latex .ML__llap,\\n.ML__latex .ML__rlap {\\n  width: 0;\\n  position: relative;\\n  display: inline-block;\\n}\\n.ML__latex .ML__llap > .ML__inner,\\n.ML__latex .ML__rlap > .ML__inner {\\n  position: absolute;\\n}\\n.ML__latex .ML__llap > .ML__fix,\\n.ML__latex .ML__rlap > .ML__fix {\\n  display: inline-block;\\n}\\n.ML__latex .ML__llap > .ML__inner {\\n  right: 0;\\n}\\n.ML__latex .ML__rlap > .ML__inner {\\n  left: 0;\\n}\\n.ML__latex .ML__rule {\\n  display: inline-block;\\n  border: solid 0;\\n  position: relative;\\n  box-sizing: border-box;\\n}\\n.ML__latex .overline .overline-line,\\n.ML__latex .underline .underline-line {\\n  width: 100%;\\n}\\n.ML__latex .overline .overline-line:before,\\n.ML__latex .underline .underline-line:before {\\n  content: '';\\n  border-bottom-style: solid;\\n  border-bottom-width: max(1px, 0.04em);\\n  -webkit-print-color-adjust: exact;\\n  print-color-adjust: exact;\\n  display: block;\\n}\\n.ML__latex .overline .overline-line:after,\\n.ML__latex .underline .underline-line:after {\\n  border-bottom-style: solid;\\n  border-bottom-width: max(1px, 0.04em);\\n  -webkit-print-color-adjust: exact;\\n  print-color-adjust: exact;\\n  content: '';\\n  display: block;\\n  margin-top: -1px;\\n}\\n.ML__latex .ML__stretchy {\\n  display: block;\\n  position: absolute;\\n  width: 100%;\\n  left: 0;\\n  overflow: hidden;\\n}\\n.ML__latex .ML__stretchy:before,\\n.ML__latex .ML__stretchy:after {\\n  content: '';\\n}\\n.ML__latex .ML__stretchy svg {\\n  display: block;\\n  position: absolute;\\n  width: 100%;\\n  height: inherit;\\n  fill: currentColor;\\n  stroke: currentColor;\\n  fill-rule: nonzero;\\n  fill-opacity: 1;\\n  stroke-width: 1;\\n  stroke-linecap: butt;\\n  stroke-linejoin: miter;\\n  stroke-miterlimit: 4;\\n  stroke-dasharray: none;\\n  stroke-dashoffset: 0;\\n  stroke-opacity: 1;\\n}\\n.ML__latex .slice-1-of-2 {\\n  display: inline-flex;\\n  position: absolute;\\n  left: 0;\\n  width: 50.2%;\\n  overflow: hidden;\\n}\\n.ML__latex .slice-2-of-2 {\\n  display: inline-flex;\\n  position: absolute;\\n  right: 0;\\n  width: 50.2%;\\n  overflow: hidden;\\n}\\n.ML__latex .slice-1-of-3 {\\n  display: inline-flex;\\n  position: absolute;\\n  left: 0;\\n  width: 25.1%;\\n  overflow: hidden;\\n}\\n.ML__latex .slice-2-of-3 {\\n  display: inline-flex;\\n  position: absolute;\\n  left: 25%;\\n  width: 50%;\\n  overflow: hidden;\\n}\\n.ML__latex .slice-3-of-3 {\\n  display: inline-flex;\\n  position: absolute;\\n  right: 0;\\n  width: 25.1%;\\n  overflow: hidden;\\n}\\n.ML__latex .slice-1-of-1 {\\n  display: inline-flex;\\n  position: absolute;\\n  width: 100%;\\n  left: 0;\\n  overflow: hidden;\\n}\\n.ML__latex .ML__nulldelimiter {\\n  display: inline-block;\\n}\\n.ML__latex .ML__op-group {\\n  display: inline-block;\\n}\\n.ML__latex .ML__op-symbol {\\n  position: relative;\\n}\\n.ML__latex .ML__op-symbol.ML__small-op {\\n  font-family: KaTeX_Size1;\\n}\\n.ML__latex .ML__op-symbol.ML__large-op {\\n  font-family: KaTeX_Size2;\\n}\\n.ML__latex .ML__mtable .ML__vertical-separator {\\n  display: inline-block;\\n  min-width: 1px;\\n  box-sizing: border-box;\\n}\\n.ML__latex .ML__mtable .ML__arraycolsep {\\n  display: inline-block;\\n}\\n.ML__latex .ML__mtable .col-align-m > .ML__vlist-t {\\n  text-align: center;\\n}\\n.ML__latex .ML__mtable .col-align-c > .ML__vlist-t {\\n  text-align: center;\\n}\\n.ML__latex .ML__mtable .col-align-l > .ML__vlist-t {\\n  text-align: left;\\n}\\n.ML__latex .ML__mtable .col-align-r > .ML__vlist-t {\\n  text-align: right;\\n}\\n[data-href] {\\n  cursor: pointer;\\n}\\n.ML__error {\\n  display: inline-block;\\n  background-image: radial-gradient(ellipse at center, hsl(341, 100%, 40%), rgba(0, 0, 0, 0) 70%);\\n  background-color: hsla(341, 100%, 40%, 0.1);\\n  background-repeat: repeat-x;\\n  background-size: 3px 3px;\\n  padding-bottom: 3px;\\n  background-position: 0 100%;\\n}\\n.ML__error > .ML__error {\\n  background: transparent;\\n  padding: 0;\\n}\\n.ML__placeholder {\\n  color: var(--_placeholder-color);\\n  opacity: var(--_placeholder-opacity);\\n  padding-left: 0.4ex;\\n  padding-right: 0.4ex;\\n  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\\n}\\n.ML__notation {\\n  position: absolute;\\n  box-sizing: border-box;\\n  line-height: 0;\\n}\\n/* This class is used to implement the `\\\\mathtip` and `\\\\texttip` commands\\n   For UI elements, see `[data-ML__tooltip]`\\n*/\\n.ML__tooltip-container {\\n  position: relative;\\n  transform: scale(0);\\n}\\n.ML__tooltip-container .ML__tooltip-content {\\n  position: fixed;\\n  display: inline-table;\\n  visibility: hidden;\\n  z-index: 2;\\n  width: max-content;\\n  max-width: 400px;\\n  padding: 12px 12px;\\n  border: var(--tooltip-border);\\n  border-radius: var(--tooltip-border-radius);\\n  background: var(--tooltip-background-color);\\n  --_selection-color: var(--tooltip-color);\\n  color: var(--tooltip-color);\\n  box-shadow: var(--tooltip-box-shadow);\\n  opacity: 0;\\n  transition: opacity 0.15s cubic-bezier(0.4, 0, 1, 1);\\n}\\n.ML__tooltip-container .ML__tooltip-content .ML__text {\\n  white-space: normal;\\n}\\n.ML__tooltip-container .ML__tooltip-content .ML__base {\\n  display: contents;\\n}\\n.ML__tooltip-container:hover .ML__tooltip-content {\\n  visibility: visible;\\n  opacity: 1;\\n  font-size: 0.75em;\\n  transform: scale(1) translate(0, 3em);\\n}\\n\";\n\n// css/environment-popover.less\nvar environment_popover_default = \"#mathlive-environment-popover.is-visible {\\n  visibility: visible;\\n}\\n#mathlive-environment-popover {\\n  --_environment-panel-height: var(--environment-panel-height, 70px);\\n  --_accent-color: var(--accent-color, #aaa);\\n  --_background: var(--environment-panel-background, #fff);\\n  --_button-background: var(--environment-panel-button-background, white);\\n  --_button-background-hover: var(--environment-panel-button-background-hover, #f5f5f7);\\n  --_button-background-active: var(--environment-panel-button-background-active, #f5f5f7);\\n  --_button-text: var(--environment-panel-button-text, #e3e4e8);\\n  position: absolute;\\n  width: calc(var(--_environment-panel-height) * 2);\\n  height: var(--_environment-panel-height);\\n  border-radius: 4px;\\n  border: 1.5px solid var(--_accent-color);\\n  background-color: var(--_background);\\n  box-shadow: 0 0 30px 0 var(--environment-shadow, rgba(0, 0, 0, 0.4));\\n  pointer-events: all;\\n  visibility: hidden;\\n}\\n#mathlive-environment-popover .MLEP__array-buttons {\\n  height: calc(var(--_environment-panel-height) * 5/4);\\n  width: calc(var(--_environment-panel-height) * 5/4);\\n  margin-left: calc(0px - var(--_environment-panel-height) * 0.16);\\n  margin-top: calc(0px - var(--_environment-panel-height) * 0.19);\\n}\\n#mathlive-environment-popover .MLEP__array-buttons .font {\\n  fill: white;\\n}\\n#mathlive-environment-popover .MLEP__array-buttons circle {\\n  fill: #7f7f7f;\\n  transition: fill 300ms;\\n}\\n#mathlive-environment-popover .MLEP__array-buttons .MLEP__array-insert-background {\\n  fill-opacity: 1;\\n  fill: var(--_background);\\n  stroke: var(--_accent-color);\\n  stroke-width: 3px;\\n}\\n#mathlive-environment-popover .MLEP__array-buttons line {\\n  stroke: var(--_accent-color);\\n  stroke-opacity: 0;\\n  stroke-width: 40;\\n  pointer-events: none;\\n  transition: stroke-opacity 300ms;\\n  stroke-linecap: round;\\n}\\n#mathlive-environment-popover .MLEP__array-buttons g[data-command]:hover circle {\\n  fill: var(--_accent-color);\\n}\\n#mathlive-environment-popover .MLEP__array-buttons g[data-command]:hover line {\\n  stroke-opacity: 1;\\n}\\n#mathlive-environment-popover .MLEP__environment-delimiter-controls {\\n  height: 100%;\\n  width: 50%;\\n}\\n#mathlive-environment-popover .MLEP__environment-delimiter-controls .MLEP__array-delimiter-options {\\n  width: var(--_environment-panel-height);\\n  height: var(--_environment-panel-height);\\n  display: flex;\\n  flex-wrap: wrap;\\n  flex-direction: row;\\n  justify-content: space-around;\\n}\\n#mathlive-environment-popover .MLEP__environment-delimiter-controls .MLEP__array-delimiter-options svg {\\n  pointer-events: all;\\n  margin-top: 2px;\\n  width: calc(var(--_environment-panel-height) / 3 * 28 / 24);\\n  height: calc(var(--_environment-panel-height) / 3 - 2px);\\n  border-radius: calc(var(--_environment-panel-height) / 25);\\n  background-color: var(--_button-background);\\n}\\n#mathlive-environment-popover .MLEP__environment-delimiter-controls .MLEP__array-delimiter-options svg:hover {\\n  background-color: var(--_button-background-hover);\\n}\\n#mathlive-environment-popover .MLEP__environment-delimiter-controls .MLEP__array-delimiter-options svg path,\\n#mathlive-environment-popover .MLEP__environment-delimiter-controls .MLEP__array-delimiter-options svg line {\\n  stroke: var(--_button-text);\\n  stroke-width: 2;\\n  stroke-linecap: round;\\n}\\n#mathlive-environment-popover .MLEP__environment-delimiter-controls .MLEP__array-delimiter-options svg rect,\\n#mathlive-environment-popover .MLEP__environment-delimiter-controls .MLEP__array-delimiter-options svg path {\\n  fill-opacity: 0;\\n}\\n#mathlive-environment-popover .MLEP__environment-delimiter-controls .MLEP__array-delimiter-options svg.active {\\n  pointer-events: none;\\n  background-color: var(--_button-background-active);\\n}\\n#mathlive-environment-popover .MLEP__environment-delimiter-controls .MLEP__array-delimiter-options svg.active path,\\n#mathlive-environment-popover .MLEP__environment-delimiter-controls .MLEP__array-delimiter-options svg.active line {\\n  stroke: var(--_accent-color);\\n}\\n#mathlive-environment-popover .MLEP__environment-delimiter-controls .MLEP__array-delimiter-options svg.active circle {\\n  fill: var(--_accent-color);\\n}\\n\";\n\n// css/suggestion-popover.less\nvar suggestion_popover_default = `/* The element that display info while in latex mode */\n#mathlive-suggestion-popover {\n  background-color: rgba(97, 97, 97);\n  color: #fff;\n  text-align: center;\n  border-radius: 8px;\n  position: fixed;\n  z-index: 1;\n  display: none;\n  flex-direction: column;\n  justify-content: center;\n  box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);\n}\n#mathlive-suggestion-popover.top-tip::after {\n  content: '';\n  position: absolute;\n  top: -15px;\n  left: calc(50% - 15px);\n  width: 0;\n  height: 0;\n  border-left: 15px solid transparent;\n  border-right: 15px solid transparent;\n  border-bottom: 15px solid rgba(97, 97, 97);\n  font-size: 1rem;\n}\n#mathlive-suggestion-popover.bottom-tip::after {\n  content: '';\n  position: absolute;\n  bottom: -15px;\n  left: calc(50% - 15px);\n  width: 0;\n  height: 0;\n  border-left: 15px solid transparent;\n  border-right: 15px solid transparent;\n  border-top: 15px solid rgba(97, 97, 97);\n  font-size: 1rem;\n}\n#mathlive-suggestion-popover.is-animated {\n  transition: all 0.2s cubic-bezier(0.64, 0.09, 0.08, 1);\n  animation: ML__fade-in cubic-bezier(0, 0, 0.2, 1) 0.15s;\n}\n#mathlive-suggestion-popover.is-visible {\n  display: flex;\n}\n@keyframes ML__fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n/* The wrapper class for the entire content of the popover panel */\n#mathlive-suggestion-popover ul {\n  display: flex;\n  flex-flow: column;\n  list-style: none;\n  margin: 0;\n  padding: 0;\n  align-items: flex-start;\n  max-height: 400px;\n  overflow-y: auto;\n}\n#mathlive-suggestion-popover li {\n  display: flex;\n  flex-direction: row;\n  justify-content: space-between;\n  margin: 8px;\n  padding: 8px;\n  width: calc(100% - 16px - 16px);\n  column-gap: 1em;\n  border-radius: 8px;\n  cursor: pointer;\n  /* Since the content can be clicked on, provide feedback on hover */\n}\n#mathlive-suggestion-popover li a {\n  color: #5ea6fd;\n  padding-top: 0.3em;\n  margin-top: 0.4em;\n  display: block;\n}\n#mathlive-suggestion-popover li a:hover {\n  color: #5ea6fd;\n  text-decoration: underline;\n}\n#mathlive-suggestion-popover li:hover,\n#mathlive-suggestion-popover li.is-pressed,\n#mathlive-suggestion-popover li.is-active {\n  background: rgba(255, 255, 255, 0.1);\n}\n/* The command inside a popover (inside a #mathlive-suggestion-popover) */\n.ML__popover__command {\n  font-size: 1.6rem;\n  font-family: KaTeX_Main;\n}\n.ML__popover__current {\n  background: #5ea6fd;\n  color: #fff;\n}\n.ML__popover__latex {\n  font-family: 'IBM Plex Mono', 'Source Code Pro', Consolas, 'Roboto Mono', Menlo, 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', Monaco, Courier, monospace;\n  align-self: center;\n}\n/* The keyboard shortcuts for a symbol as displayed in the popover */\n.ML__popover__keybinding {\n  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n  font-size: 0.8em;\n  opacity: 0.7;\n}\n/* Style for the character that joins the modifiers of a keyboard shortcut \n(usually a \"+\" sign)*/\n.ML__shortcut-join {\n  opacity: 0.5;\n}\n`;\n\n// css/keystroke-caption.less\nvar keystroke_caption_default = \"/* The element that displays the keys as the user type them */\\n#mathlive-keystroke-caption-panel {\\n  visibility: hidden;\\n  /*min-width: 160px;*/\\n  /*background-color: rgba(97, 97, 200, .95);*/\\n  background: var(--secondary, hsl(var(--_hue), 19%, 26%));\\n  border-color: var(--secondary-border, hsl(0, 0%, 91%));\\n  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\\n  text-align: center;\\n  border-radius: 6px;\\n  padding: 16px;\\n  position: absolute;\\n  z-index: 1;\\n  display: flex;\\n  flex-direction: row-reverse;\\n  justify-content: center;\\n  --keystroke: white;\\n  --on-keystroke: #555;\\n  --keystroke-border: #f7f7f7;\\n}\\n@media (prefers-color-scheme: dark) {\\n  body:not([theme='light']) #mathlive-keystroke-caption-panel {\\n    --keystroke: hsl(var(--_hue), 50%, 30%);\\n    --on-keystroke: hsl(0, 0%, 98%);\\n    --keystroke-border: hsl(var(--_hue), 50%, 25%);\\n  }\\n}\\nbody[theme='dark'] #mathlive-keystroke-caption-panel {\\n  --keystroke: hsl(var(--_hue), 50%, 30%);\\n  --on-keystroke: hsl(0, 0%, 98%);\\n  --keystroke-border: hsl(var(--_hue), 50%, 25%);\\n}\\n#mathlive-keystroke-caption-panel > span {\\n  min-width: 14px;\\n  /*height: 8px;*/\\n  margin: 0 8px 0 0;\\n  padding: 4px;\\n  background-color: var(--keystroke);\\n  color: var(--on-keystroke);\\n  fill: currentColor;\\n  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\\n  font-size: 1em;\\n  border-radius: 6px;\\n  border: 2px solid var(--keystroke-border);\\n  /*box-shadow: 0 7px 14px rgba(0,0,0,0.25), 0 5px 5px rgba(0,0,0,0.22);*/\\n}\\n\";\n\n// css/virtual-keyboard.less\nvar virtual_keyboard_default = `.ML__keyboard {\n  --_keyboard-height: 0;\n  --_keyboard-zindex: var(--keyboard-zindex, 105);\n  --_accent-color: var(--keyboard-accent-color, #0c75d8);\n  --_background: var(--keyboard-background, #cacfd7);\n  --_border: var(--keyboard-border, #ddd);\n  --_padding-horizontal: var(--keyboard-padding-horizontal, 0px);\n  --_padding-top: var(--keyboard-padding-top, 5px);\n  --_padding-bottom: var(--keyboard-padding-bottom, 0px);\n  --_row-padding-left: var(--keyboard-row-padding-left, 0px);\n  --_row-padding-right: var(--keyboard-row-padding-right, 0px);\n  --_toolbar-text: var(--keyboard-toolbar-text, #2c2e2f);\n  --_toolbar-text-active: var(--keyboard-toolbar-text-active, var(--_accent-color));\n  --_toolbar-background: var(--keyboard-toolbar-background, transparent);\n  --_toolbar-background-hover: var(--keyboard-toolbar-background-hover, #eee);\n  --_toolbar-background-selected: var(--keyboard-toolbar-background-selected, transparent);\n  --_toolbar-font-size: var(--keyboard-toolbar-font-size, '135%');\n  --_horizontal-rule: var(--keyboard-horizontal-rule, 1px solid #fff);\n  --_keycap-background: var(--keycap-background, #f0f0f0);\n  --_keycap-background-hover: var(--keycap-background-hover, #f5f5f7);\n  --_keycap-background-active: var(--keycap-background-active, var(--_accent-color));\n  --_keycap-background-pressed: var(--keycap-background-pressed, var(--_accent-color));\n  --_keycap-border: var(--keycap-border, #e5e6e9);\n  --_keycap-border-bottom: var(--keycap-border-bottom, #8d8f92);\n  --_keycap-text: var(--keycap-text, #000);\n  --_keycap-text-active: var(--keycap-text-active, #fff);\n  --_keycap-text-hover: var(--keycap-text-hover, var(--_keycap-text));\n  --_keycap-text-pressed: var(--keycap-text-pressed, #fff);\n  --_keycap-shift-text: var(--keycap-shift-text, var(--_accent-color));\n  --_keycap-primary-background: var(--keycap-primary-background, var(--_accent-color));\n  --_keycap-primary-text: var(--keycap-primary-text, #ddd);\n  --_keycap-primary-background-hover: var(--keycap-primary-background-hover, #0d80f2);\n  --_keycap-secondary-background: var(--keycap-secondary-background, #a0a9b8);\n  --_keycap-secondary-background-hover: var(--keycap-secondary-background-hover, #7d8795);\n  --_keycap-secondary-text: var(--keycap-secondary-text, #060707);\n  --_keycap-secondary-border: var(--keycap-secondary-border, #c5c9d0);\n  --_keycap-secondary-border-bottom: var(--keycap-secondary-border-bottom, #989da6);\n  --_keycap-height: var(--keycap-height, 60px);\n  /* Keycap width (incl. margin) */\n  --_keycap-max-width: var(--keycap-max-width, 100px);\n  --_keycap-gap: var(--keycap-gap, 8px);\n  --_keycap-font-size: var(--keycap-font-size, clamp(16px, 4cqw, 24px));\n  --_keycap-small-font-size: var(--keycap-small-font-size, calc(var(--keycap-font-size) * 0.8));\n  --_keycap-extra-small-font-size: var(--keycap-extra-small-font-size, calc(var(--keycap-font-size) / 1.42));\n  --_variant-panel-background: var(--variant-panel-background, #f0f0f0);\n  --_variant-keycap-text: var(--variant-keycap-text, var(--_keycap-text));\n  --_variant-keycap-text-active: var(--variant-keycap-text-active, var(--_keycap-text-active));\n  --_variant-keycap-background-active: var(--variant-keycap-background-active, var(--_accent-color));\n  --_variant-keycap-length: var(--variant-keycap-length, 70px);\n  --_variant-keycap-font-size: var(--variant-keycap-font-size, 30px);\n  --_variant-keycap-aside-font-size: var(--variant-keycap-aside-font-size, 12px);\n  --_keycap-shift-font-size: var(--keycap-shift-font-size, 16px);\n  --_keycap-shift-color: var(--keycap-shift-color, var(--_accent-color));\n  --_box-placeholder-color: var(--box-placeholder-color, var(--_accent-color));\n  --_box-placeholder-pressed-color: var(--box-placeholder-pressed-color, var(--keycap-text-pressed));\n  --_keycap-glyph-size: var(--keycap-glyph-size, 20px);\n  --_keycap-glyph-size-lg: var(--keycap-glyph-size-lg, 24px);\n  --_keycap-glyph-size-xl: var(--keycap-glyph-size-xl, 50px);\n}\n.is-math-mode .MLK__rows .if-text-mode,\n.is-text-mode .MLK__rows .if-math-mode {\n  display: none;\n}\n.if-can-undo,\n.if-can-redo,\n.if-can-copy,\n.if-can-cut,\n.if-can-paste {\n  opacity: 0.4;\n  pointer-events: none;\n}\n.can-undo .if-can-undo,\n.can-redo .if-can-redo,\n.can-copy .if-can-copy,\n.can-cut .if-can-cut,\n.can-paste .if-can-paste {\n  opacity: 1;\n  pointer-events: all;\n}\nbody > .ML__keyboard {\n  position: fixed;\n  --_padding-bottom: calc(var(--keyboard-padding-bottom, 0px) + env(safe-area-inset-bottom, 0));\n}\nbody > .ML__keyboard.is-visible > .MLK__backdrop {\n  box-shadow: 0 -5px 6px rgba(0, 0, 0, 0.08);\n  border-top: 1px solid var(--_border);\n}\nbody > .ML__keyboard.backdrop-is-transparent.is-visible > .MLK__backdrop {\n  box-shadow: none;\n  border: none;\n}\nbody > .ML__keyboard.is-visible.animate > .MLK__backdrop {\n  transition: 0.28s cubic-bezier(0, 0, 0.2, 1);\n  transition-property: transform, opacity;\n  transition-timing-function: cubic-bezier(0.4, 0, 1, 1);\n}\n.ML__keyboard {\n  position: relative;\n  overflow: hidden;\n  top: 0;\n  left: 0;\n  height: 100%;\n  width: 100%;\n  z-index: var(--_keyboard-zindex);\n  box-sizing: border-box;\n  outline: none;\n  border: none;\n  margin: 0;\n  padding: 0;\n  line-height: 1;\n  overflow-wrap: unset;\n  text-align: left;\n  vertical-align: baseline;\n  cursor: auto;\n  white-space: pre;\n  box-shadow: none;\n  opacity: 1;\n  transform: none;\n  pointer-events: none;\n}\n.ML__keyboard :where(div) {\n  box-sizing: border-box;\n  outline: none;\n  border: none;\n  margin: 0;\n  padding: 0;\n  line-height: 1;\n  overflow-wrap: unset;\n  text-align: left;\n  vertical-align: baseline;\n  cursor: auto;\n  white-space: pre;\n  box-shadow: none;\n  transform: none;\n}\n.MLK__backdrop {\n  position: absolute;\n  bottom: calc(-1 * var(--_keyboard-height));\n  width: 100%;\n  height: var(--_keyboard-height);\n  box-sizing: border-box;\n  padding-top: var(--_padding-top);\n  padding-bottom: var(--_padding-bottom);\n  padding-left: var(--_padding-horizontal);\n  padding-right: var(--_padding-horizontal);\n  opacity: 0;\n  visibility: hidden;\n  transform: translate(0, 0);\n  background: var(--_background);\n}\n.backdrop-is-transparent .MLK__backdrop {\n  background: transparent;\n}\n/* If a custom layout has a custom container/backdrop\n  (backdrop-is-transparent), make sure to let pointer event go through. */\n.backdrop-is-transparent .MLK__plate {\n  background: transparent;\n  pointer-events: none;\n}\n/* If a custom layout has a custom container/backdrop, make sure to \n   allow pointer events on it. */\n.backdrop-is-transparent .MLK__layer > div > div {\n  pointer-events: all;\n}\n.ML__keyboard.is-visible > .MLK__backdrop {\n  transform: translate(0, calc(-1 * var(--_keyboard-height)));\n  opacity: 1;\n  visibility: visible;\n}\n.caps-lock-indicator {\n  display: none;\n  width: 8px;\n  height: 8px;\n  background: #0cbc0c;\n  box-shadow: inset 0 0 4px 0 #13ca13, 0 0 4px 0 #a9ef48;\n  border-radius: 8px;\n  right: 8px;\n  top: 8px;\n  position: absolute;\n}\n.ML__keyboard.is-caps-lock .caps-lock-indicator {\n  display: block;\n}\n.ML__keyboard.is-caps-lock .shift {\n  background: var(--_keycap-background-active);\n  color: var(--_keycap-text-active);\n}\n.MLK__plate {\n  position: absolute;\n  top: var(--_padding-top);\n  left: var(--_padding-horizontal);\n  width: calc(100% - 2 * var(--_padding-horizontal));\n  margin: 0;\n  padding: 0;\n  box-sizing: border-box;\n  container-type: inline-size;\n  touch-action: none;\n  -webkit-user-select: none;\n  user-select: none;\n  pointer-events: all;\n  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n  font-size: 16px;\n  /* Size of toolbar labels */\n  font-weight: 400;\n  text-shadow: none;\n}\n.ML__box-placeholder {\n  color: var(--_box-placeholder-color);\n}\n.MLK__tex {\n  font-family: KaTeX_Main, KaTeX_Math, 'Cambria Math', 'Asana Math', OpenSymbol, Symbola, STIX, Times, serif !important;\n}\n.MLK__tex-math {\n  font-family: KaTeX_Math, KaTeX_Main, 'Cambria Math', 'Asana Math', OpenSymbol, Symbola, STIX, Times, serif !important;\n  font-style: italic;\n}\n.MLK__layer {\n  display: none;\n  outline: none;\n}\n.MLK__layer.is-visible {\n  display: flex;\n  flex-flow: column;\n}\n/* Keyboard layouts are made or rows of keys... */\n.MLK__rows {\n  --_keycap-width: var(--keycap-width, min(var(--_keycap-max-width), 10cqw));\n  display: flex;\n  flex-flow: column;\n  align-items: center;\n  border-collapse: separate;\n  clear: both;\n  border: 0;\n  margin: 0;\n  margin-bottom: var(--_keycap-gap);\n  gap: var(--_keycap-gap);\n  /* If the styling include, e.g., some shadows, they will be\n  cut off by the overflow. In that case, set the padding to \n  compensate. */\n  padding-left: var(--_row-padding-left);\n  padding-right: var(--_row-padding-right);\n  overflow: visible;\n  touch-action: none;\n}\n.MLK__rows > .MLK__row {\n  display: flex;\n  flex-flow: row;\n  justify-content: center;\n  width: 100%;\n  gap: var(--_keycap-gap);\n  margin: 0;\n  padding: 0;\n  /* For the alignment of the text on some modifiers (e.g. shift) */\n  /* Extra spacing between two adjacent keys */\n}\n.MLK__rows > .MLK__row .tex {\n  font-family: KaTeX_Math, KaTeX_Main, 'Cambria Math', 'Asana Math', OpenSymbol, Symbola, STIX, Times, serif !important;\n}\n.MLK__rows > .MLK__row .tex-math {\n  font-family: KaTeX_Math, 'Cambria Math', 'Asana Math', OpenSymbol, Symbola, STIX, Times, serif !important;\n}\n.MLK__rows > .MLK__row .big-op {\n  font-size: calc(1.25 * var(--_keycap-font-size));\n}\n.MLK__rows > .MLK__row .small {\n  font-size: var(--_keycap-small-font-size);\n}\n.MLK__rows > .MLK__row .bottom {\n  justify-content: flex-end;\n}\n.MLK__rows > .MLK__row .left {\n  align-items: flex-start;\n  padding-left: 12px;\n}\n.MLK__rows > .MLK__row .right {\n  align-items: flex-end;\n  padding-right: 12px;\n}\n.MLK__rows > .MLK__row .w0 {\n  width: 0;\n}\n.MLK__rows > .MLK__row .w5 {\n  width: calc(0.5 * var(--_keycap-width) - var(--_keycap-gap));\n}\n.MLK__rows > .MLK__row .w15 {\n  width: calc(1.5 * var(--_keycap-width) - var(--_keycap-gap));\n}\n.MLK__rows > .MLK__row .w20 {\n  width: calc(2 * var(--_keycap-width) - var(--_keycap-gap));\n}\n.MLK__rows > .MLK__row .w40 {\n  width: calc(4 * var(--_keycap-width) - var(--_keycap-gap));\n}\n.MLK__rows > .MLK__row .w50 {\n  width: calc(5 * var(--_keycap-width) - var(--_keycap-gap));\n}\n.MLK__rows > .MLK__row .MLK__keycap.w50 {\n  font-size: 80%;\n  padding-top: 10px;\n  font-weight: 100;\n}\n.MLK__rows > .MLK__row .separator {\n  background: transparent;\n  border: none;\n  pointer-events: none;\n}\n.MLK__rows > .MLK__row .horizontal-rule {\n  height: 6px;\n  margin-top: 3px;\n  margin-bottom: 0;\n  width: 100%;\n  border-radius: 0;\n  border-top: var(--_horizontal-rule);\n}\n.MLK__rows > .MLK__row .ghost {\n  background: var(--_toolbar-background);\n  border: none;\n  color: var(--_toolbar-text);\n}\n.MLK__rows > .MLK__row .ghost:hover {\n  background: var(--_toolbar-background-hover);\n}\n.MLK__rows > .MLK__row .bigfnbutton {\n  font-size: var(--_keycap-extra-small-font-size);\n}\n.MLK__rows > .MLK__row .shift,\n.MLK__rows > .MLK__row .action {\n  color: var(--_keycap-secondary-text);\n  background: var(--_keycap-secondary-background);\n  border-color: var(--_keycap-secondary-border);\n  border-bottom-color: var(--_keycap-secondary-border-bottom);\n  line-height: 0.8;\n  font-size: min(1rem, var(--_keycap-small-font-size));\n  font-weight: 600;\n  padding: 8px 12px 8px 12px;\n}\n.MLK__rows > .MLK__row .shift:hover,\n.MLK__rows > .MLK__row .action:hover {\n  background: var(--_keycap-secondary-background-hover);\n}\n.MLK__rows > .MLK__row .action.primary {\n  background: var(--_keycap-primary-background);\n  color: var(--_keycap-primary-text);\n}\n.MLK__rows > .MLK__row .action.primary:hover {\n  background: var(--_keycap-primary-background-hover);\n  color: var(--_keycap-primary-text);\n}\n.MLK__rows > .MLK__row .shift.selected,\n.MLK__rows > .MLK__row .action.selected {\n  color: var(--_toolbar-text-active);\n}\n.MLK__rows > .MLK__row .shift.selected.is-pressed,\n.MLK__rows > .MLK__row .action.selected.is-pressed,\n.MLK__rows > .MLK__row .shift.selected.is-active,\n.MLK__rows > .MLK__row .action.selected.is-active {\n  color: white;\n}\n.MLK__rows > .MLK__row .warning {\n  background: #cd0030;\n  color: white;\n}\n.MLK__rows > .MLK__row .warning svg.svg-glyph {\n  width: var(--_keycap-glyph-size-lg);\n  height: var(--_keycap-glyph-size-lg);\n  min-height: var(--_keycap-glyph-size-lg);\n}\n/** A regular keycap\n * Use the :where() pseudo-class to give it a very low specifity, \n * so that it can be overriden by custom style.\n */\n:where(.MLK__rows > .MLK__row  div) {\n  display: flex;\n  flex-flow: column;\n  align-items: center;\n  justify-content: space-evenly;\n  width: calc(var(--_keycap-width) - var(--_keycap-gap));\n  height: var(--_keycap-height);\n  box-sizing: border-box;\n  padding: 0;\n  vertical-align: top;\n  text-align: center;\n  float: left;\n  color: var(--_keycap-text);\n  fill: currentColor;\n  font-size: var(--_keycap-font-size);\n  background: var(--_keycap-background);\n  border: 1px solid var(--_keycap-border);\n  border-bottom-color: var(--_keycap-border-bottom);\n  border-radius: 6px;\n  cursor: pointer;\n  touch-action: none;\n  /* Keys with a variants panel */\n  position: relative;\n  overflow: hidden;\n  -webkit-user-select: none;\n  user-select: none;\n  -webkit-tap-highlight-color: transparent;\n}\n:where(.MLK__rows > .MLK__row  div):hover {\n  overflow: visible;\n  background: var(--_keycap-background-hover);\n}\n:where(.MLK__rows > .MLK__row  div) .ML__latex {\n  pointer-events: none;\n  touch-action: none;\n}\n:where(.MLK__rows > .MLK__row  div) svg.svg-glyph {\n  margin: 8px 0;\n  width: var(--_keycap-glyph-size);\n  height: var(--_keycap-glyph-size);\n  min-height: var(--_keycap-glyph-size);\n}\n:where(.MLK__rows > .MLK__row  div) svg.svg-glyph-lg {\n  margin: 8px 0;\n  width: var(--_keycap-glyph-size-lg);\n  height: var(--_keycap-glyph-size-lg);\n  min-height: var(--_keycap-glyph-size-lg);\n}\n:where(.MLK__rows > .MLK__row  div).MLK__tex-math {\n  font-size: 25px;\n}\n:where(.MLK__rows > .MLK__row  div).is-pressed {\n  background: var(--_keycap-background-pressed);\n  color: var(--_keycap-text-pressed);\n  --_box-placeholder-color: var(--_box-placeholder-pressed-color);\n}\n:where(.MLK__rows > .MLK__row  div).MLK__keycap.is-active,\n:where(.MLK__rows > .MLK__row  div).action.is-active,\n:where(.MLK__rows > .MLK__row  div).MLK__keycap.is-pressed,\n:where(.MLK__rows > .MLK__row  div).action.is-pressed {\n  z-index: calc(var(--_keyboard-zindex) - 5);\n}\n:where(.MLK__rows > .MLK__row  div).MLK__keycap.is-active aside,\n:where(.MLK__rows > .MLK__row  div).action.is-active aside,\n:where(.MLK__rows > .MLK__row  div).MLK__keycap.is-pressed aside,\n:where(.MLK__rows > .MLK__row  div).action.is-pressed aside {\n  display: none;\n}\n:where(.MLK__rows > .MLK__row  div).MLK__keycap.is-active .MLK__shift,\n:where(.MLK__rows > .MLK__row  div).action.is-active .MLK__shift,\n:where(.MLK__rows > .MLK__row  div).MLK__keycap.is-pressed .MLK__shift,\n:where(.MLK__rows > .MLK__row  div).action.is-pressed .MLK__shift {\n  display: none;\n}\n:where(.MLK__rows > .MLK__row  div).shift.is-pressed,\n:where(.MLK__rows > .MLK__row  div).MLK__keycap.is-pressed,\n:where(.MLK__rows > .MLK__row  div).action.is-pressed {\n  background: var(--_keycap-background-pressed);\n  color: var(--_keycap-text-pressed);\n}\n:where(.MLK__rows > .MLK__row  div).shift.is-active,\n:where(.MLK__rows > .MLK__row  div).MLK__keycap.is-active,\n:where(.MLK__rows > .MLK__row  div).action.is-active {\n  background: var(--_keycap-background-active);\n  color: var(--_keycap-text-active);\n  --_box-placeholder-color: var(--_box-placeholder-pressed-color);\n}\n:where(.MLK__rows > .MLK__row  div) small {\n  color: var(--_keycap-secondary-text);\n}\n:where(.MLK__rows > .MLK__row  div) aside {\n  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n  font-size: 10px;\n  line-height: 10px;\n  color: var(--_keycap-secondary-text);\n}\n/* Add an attribute 'data-tooltip' to display a tooltip on hover.\nNote there are a different set of tooltip rules for the keyboard toggle\n(it's in a different CSS tree) */\n.ML__keyboard [data-tooltip] {\n  position: relative;\n}\n.ML__keyboard [data-tooltip]::after {\n  position: absolute;\n  display: inline-table;\n  content: attr(data-tooltip);\n  top: inherit;\n  bottom: 100%;\n  width: max-content;\n  max-width: 200px;\n  padding: 8px 8px;\n  background: #616161;\n  color: #fff;\n  text-align: center;\n  z-index: 2;\n  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);\n  border-radius: 2px;\n  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n  font-weight: 400;\n  font-size: 12px;\n  transition: all 0.15s cubic-bezier(0.4, 0, 1, 1) 1s;\n  opacity: 0;\n  transform: scale(0.5);\n}\n.ML__keyboard [data-tooltip]:hover {\n  position: relative;\n}\n.ML__keyboard [data-tooltip]:hover::after {\n  opacity: 1;\n  transform: scale(1);\n}\n.MLK__toolbar {\n  align-self: center;\n  display: flex;\n  flex-flow: row;\n  justify-content: space-between;\n  width: 100%;\n  max-width: 996px;\n  min-height: 32px;\n  /* Icons for undo/redo, etc. */\n}\n.MLK__toolbar svg {\n  height: 20px;\n  width: 20px;\n}\n.MLK__toolbar > .left {\n  position: relative;\n  display: flex;\n  justify-content: flex-start;\n  flex-flow: row;\n}\n.MLK__toolbar > .right {\n  display: flex;\n  justify-content: flex-end;\n  flex-flow: row;\n}\n.MLK__toolbar > div > div {\n  /* \"button\" in the toolbar */\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  color: var(--_toolbar-text);\n  fill: currentColor;\n  background: var(--_toolbar-background);\n  font-size: var(--_toolbar-font-size);\n  padding: 4px 15px;\n  cursor: pointer;\n  width: max-content;\n  min-width: 42px;\n  min-height: 34px;\n  border: none;\n  padding-left: 10px;\n  padding-right: 10px;\n  padding-bottom: 8px;\n  padding-top: 8px;\n  margin-top: 0;\n  margin-bottom: 4px;\n  margin-left: 4px;\n  margin-right: 4px;\n  border-radius: 8px;\n  box-shadow: none;\n  border-bottom: 2px solid transparent;\n}\n.MLK__toolbar > div > div:not(.disabled):not(.selected):hover {\n  background: var(--_toolbar-background-hover);\n}\n.MLK__toolbar > div > div.disabled svg,\n.MLK__toolbar > div > div.disabled:hover svg,\n.MLK__toolbar > div > div.disabled.is-pressed svg {\n  color: var(--_toolbar-text);\n  opacity: 0.2;\n}\n.MLK__toolbar > div > div:hover,\n.MLK__toolbar > div > div:active,\n.MLK__toolbar > div > div.is-pressed,\n.MLK__toolbar > div > div.is-active {\n  color: var(--_toolbar-text-active);\n}\n.MLK__toolbar > div > div.selected {\n  color: var(--_toolbar-text-active);\n  background: var(--_toolbar-background-selected);\n  border-radius: 0;\n  border-bottom-color: var(--_toolbar-text-active);\n  padding-bottom: 4px;\n  margin-bottom: 8px;\n}\n/* This is the element that displays variants on press+hold */\n.MLK__variant-panel {\n  visibility: hidden;\n  position: fixed;\n  display: flex;\n  flex-flow: row wrap-reverse;\n  justify-content: center;\n  align-content: center;\n  margin: 0;\n  padding: 0;\n  bottom: auto;\n  top: 0;\n  box-sizing: content-box;\n  transform: none;\n  z-index: calc(var(--_keyboard-zindex) + 1);\n  touch-action: none;\n  max-width: 350px;\n  background: var(--_variant-panel-background);\n  text-align: center;\n  border-radius: 6px;\n  padding: 6px;\n  box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);\n  transition: none;\n}\n.MLK__variant-panel.is-visible {\n  visibility: visible;\n}\n.MLK__variant-panel.compact {\n  --_variant-keycap-length: var(--variant-keycap-length, 50px);\n  --_variant-keycap-font-size: var(--variant-keycap-font-size, 24px);\n  --_variant-keycap-aside-font-size: var(--variant-keycap-aside-font-size, 10px);\n}\n.MLK__variant-panel .item {\n  display: flex;\n  flex-flow: column;\n  align-items: center;\n  justify-content: center;\n  font-size: var(--_variant-keycap-font-size);\n  height: var(--_variant-keycap-length);\n  width: var(--_variant-keycap-length);\n  margin: 0;\n  box-sizing: border-box;\n  border-radius: 5px;\n  border: 1px solid transparent;\n  background: transparent;\n  pointer-events: all;\n  cursor: pointer;\n  color: var(--_variant-keycap-text);\n  fill: currentColor;\n}\n@media (max-height: 412px) {\n  .MLK__variant-panel .item {\n    --_variant-keycap-font-size: var(--variant-keycap-font-size, 24px);\n    --_variant-keycap-length: var(--variant-keycap-length, 50px);\n  }\n}\n.MLK__variant-panel .item .ML__latex {\n  pointer-events: none;\n}\n.MLK__variant-panel .item.is-active {\n  background: var(--_variant-keycap-background-active);\n  color: var(--_variant-keycap-text-active);\n  --_box-placeholder-color: var(--_box-placeholder-pressed-color);\n}\n.MLK__variant-panel .item.is-pressed {\n  background: var(--_variant-keycap-background-pressed);\n  color: var(--_variant-keycap-text-pressed);\n  --_box-placeholder-color: var(--_box-placeholder-pressed-color);\n}\n.MLK__variant-panel .item.small {\n  font-size: var(--_keycap-small-font-size);\n}\n.MLK__variant-panel .item.swatch-button {\n  box-sizing: border-box;\n  background: #fbfbfb;\n}\n.MLK__variant-panel .item.swatch-button > span {\n  display: inline-block;\n  margin: 6px;\n  width: calc(100% - 12px);\n  height: calc(100% - 12px);\n  border-radius: 50%;\n}\n.MLK__variant-panel .item.swatch-button:hover {\n  background: #f0f0f0;\n}\n.MLK__variant-panel .item.swatch-button:hover > span {\n  border-radius: 2px;\n}\n.MLK__variant-panel .item.box > div,\n.MLK__variant-panel .item.box > span {\n  border: 1px dashed rgba(0, 0, 0, 0.24);\n}\n.MLK__variant-panel .item .warning {\n  min-height: 60px;\n  min-width: 60px;\n  background: #cd0030;\n  color: white;\n  padding: 5px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  border-radius: 5px;\n}\n.MLK__variant-panel .item .warning.is-pressed,\n.MLK__variant-panel .item .warning.is-active {\n  background: red;\n}\n.MLK__variant-panel .item .warning svg.svg-glyph {\n  width: var(--_keycap-glyph-size-xl);\n  height: var(--_keycap-glyph-size-xl);\n}\n.MLK__variant-panel .item aside {\n  font-size: var(--_variant-keycap-aside-font-size);\n  line-height: 12px;\n  opacity: 0.78;\n  padding-top: 2px;\n}\n.MLK__keycap {\n  position: relative;\n}\n.MLK__shift {\n  display: block;\n  position: absolute;\n  right: 4px;\n  top: 4px;\n  font-size: var(--_keycap-shift-font-size);\n  color: var(--_keycap-shift-color);\n}\n.hide-shift .MLK__shift {\n  display: none;\n}\n@media (max-width: 414px) {\n  .MLK__variant-panel {\n    max-width: 350px;\n    --_variant-keycap-font-size: var(--variant-keycap-font-size, 24px);\n    --_variant-keycap-length: var(--variant-keycap-length, 50px);\n  }\n}\n/* @xs breakpoint: iPhone 5 */\n@container (max-width: 414px) {\n  .MLK__rows {\n    --_keycap-gap: max(var(--_keycap-gap, 2px), 2px);\n    --_keycap-height: max(var(--_keycap-height), 42px);\n    --_keycap-width: var(--keycap-width, min(min(var(--_keycap-max-width)), 10cqw), 62px));\n  }\n  .MLK__toolbar > div > div {\n    font-size: 100%;\n    margin-left: 2px;\n    margin-right: 2px;\n  }\n  .MLK__rows .shift,\n  .MLK__rows .action {\n    font-size: 65%;\n  }\n  .MLK__rows .warning svg.svg-glyph {\n    width: 14px;\n    height: 14px;\n    min-height: 14px;\n  }\n}\n@container (max-width: 744px) {\n  .MLK__rows {\n    --_keycap-gap: max(var(--keycap-gap, 2px), 2px);\n    --_keycap-height: max(var(--keycap-height, 52px), 52px);\n    --_keycap-width: var(--keycap-width, min(min(var(--_keycap-max-width), 10cqw), 62px));\n  }\n  .MLK__toolbar > div > div {\n    padding-left: 0;\n    padding-right: 0;\n  }\n  .MLK__tooltip::after {\n    padding: 8px 16px;\n    font-size: 16px;\n  }\n  .MLK__rows > .MLK__row > div.fnbutton {\n    font-size: 16px;\n  }\n  .MLK__rows > .MLK__row > div.bigfnbutton {\n    font-size: calc(var(--_keycap-extra-small-font-size) / 1.55);\n  }\n  .MLK__rows > .MLK__row > div.small {\n    font-size: 13px;\n  }\n  .MLK__rows > .MLK__row > div > aside {\n    display: none;\n  }\n  .MLK__shift {\n    display: none;\n  }\n}\n/* Medium breakpoint: larger phones */\n@container (max-width: 768px) {\n  .MLK__rows {\n    --_keycap-height: max(var(--keycap-height, 42px), 42px);\n  }\n  .MLK__rows > .MLK__row > div > small {\n    font-size: 14px;\n  }\n}\n@media (max-height: 768px) {\n  .MLK__rows {\n    --_keycap-height: max(var(--keycap-height, 42px), 42px);\n  }\n  .MLK__rows > .MLK__row > div > small {\n    font-size: 14px;\n  }\n}\n@container (max-width: 1444px) {\n  .MLK__rows .if-wide {\n    display: none;\n  }\n}\n@media (prefers-color-scheme: dark) {\n  .ML__keyboard {\n    --_accent-color: var(--keyboard-accent-color, #0b5c9c);\n    --_background: var(--keyboard-background, #151515);\n    --_border: var(--keyboard-border, transparent);\n    --_toolbar-text: var(--keyboard-toolbar-text, #e3e4e8);\n    --_toolbar-background-hover: var(--keyboard-toolbar-background-hover, #303030);\n    --keyboard-toolbar-background-hover: #303030;\n    --_horizontal-rule: var(--keyboard-horizontal-rule, 1px solid #303030);\n    --_keycap-background: var(--keycap-background, #1f2022);\n    --_keycap-background-hover: var(--keycap-background-hover, #2f3032);\n    --_keycap-border: var(--_keycap-border, transparent);\n    --_keycap-border-bottom: var(--_keycap-border-bottom, transparent);\n    --_keycap-text: var(--keycap-text, #e3e4e8);\n    --_keycap-secondary-background: var(--keycap-secondary-background, #3d4144);\n    --_keycap-secondary-background-hover: var(--keycap-secondary-background-hover, #4d5154);\n    --_keycap-secondary-text: var(--keycap-secondary-text, #e7ebee);\n    --keycap-secondary-border: transparent;\n    --keycap-secondary-border-bottom: transparent;\n    --_keycap-secondary-border: var(--keycap-secondary-border, transparent);\n    --_keycap-secondary-border-bottom: var(--keycap-secondary-border-bottom, transparent);\n    --_variant-panel-background: var(--variant-panel-background, #303030);\n    --_variant-keycap-text-active: var(--variant-keycap-text-active, #fff);\n  }\n}\n/* Same as the media query, but with a class */\n[theme='dark'] .ML__keyboard {\n  --_accent-color: var(--keyboard-accent-color, #0b5c9c);\n  --_background: var(--keyboard-background, #151515);\n  --_border: var(--keyboard-border, transparent);\n  --_toolbar-text: var(--keyboard-toolbar-text, #e3e4e8);\n  --_toolbar-background-hover: var(--keyboard-toolbar-background-hover, #303030);\n  --keyboard-toolbar-background-hover: #303030;\n  --_horizontal-rule: var(--keyboard-horizontal-rule, 1px solid #303030);\n  --_keycap-background: var(--keycap-background, #1f2022);\n  --_keycap-background-hover: var(--keycap-background-hover, #2f3032);\n  --_keycap-border: var(--_keycap-border, transparent);\n  --_keycap-border-bottom: var(--_keycap-border-bottom, transparent);\n  --_keycap-text: var(--keycap-text, #e3e4e8);\n  --_keycap-secondary-background: var(--keycap-secondary-background, #3d4144);\n  --_keycap-secondary-background-hover: var(--keycap-secondary-background-hover, #4d5154);\n  --_keycap-secondary-text: var(--keycap-secondary-text, #e7ebee);\n  --keycap-secondary-border: transparent;\n  --keycap-secondary-border-bottom: transparent;\n  --_keycap-secondary-border: var(--keycap-secondary-border, transparent);\n  --_keycap-secondary-border-bottom: var(--keycap-secondary-border-bottom, transparent);\n  --_variant-panel-background: var(--variant-panel-background, #303030);\n  --_variant-keycap-text-active: var(--variant-keycap-text-active, #fff);\n}\n[theme='light'] .ML__keyboard {\n  --_accent-color: var(--keyboard-accent-color, #0c75d8);\n  --_background: var(--keyboard-background, #cacfd7);\n  --_border: var(--keyboard-border, #ddd);\n  --_toolbar-text: var(--keyboard-toolbar-text, #2c2e2f);\n  --_toolbar-background: var(--keyboard-toolbar-background, transparent);\n  --_toolbar-background-hover: var(--keyboard-toolbar-background-hover, #eee);\n  --_toolbar-background-selected: var(--keyboard-toolbar-background-selected, transparent);\n  --_horizontal-rule: var(--keyboard-horizontal-rule, 1px solid #fff);\n  --_keycap-background: var(--keycap-background, white);\n  --_keycap-background-hover: var(--keycap-background-hover, #f5f5f7);\n  --_keycap-background-active: var(--keycap-background-active, var(--_accent-color));\n  --_keycap-background-pressed: var(--keycap-background-pressed, var(--_accent-color));\n  --_keycap-border: var(--_keycap-border, #e5e6e9);\n  --_keycap-border-bottom: var(--_keycap-border-bottom, #8d8f92);\n  --_keycap-text: var(--keycap-text, #000);\n  --_keycap-text-active: var(--keycap-text-active, #fff);\n  --_keycap-text-hover: var(--keycap-text-hover, var(--_keycap-text));\n  --_keycap-text-pressed: var(--keycap-text-pressed, #fff);\n  --_keycap-shift-text: var(--keycap-shift-text, var(--_accent-color));\n  --_keycap-secondary-background: var(--keycap-secondary-background, #a0a9b8);\n  --_keycap-secondary-background-hover: var(--keycap-secondary-background-hover, #7d8795);\n  --_keycap-secondary-text: var(--keycap-secondary-text, #060707);\n  --_keycap-secondary-border: var(--keycap-secondary-border, #c5c9d0);\n  --_keycap-secondary-border-bottom: var(--keycap-secondary-border-bottom, #989da6);\n  --_variant-panel-background: var(--variant-panel-background, #f0f0f0);\n  --_variant-keycap-text: var(--variant-keycap-textvar, var(--_keycap-text));\n  --_variant-keycap-text-active: var(--variant-keycap-text-active, var(--_keycap-text-active));\n  --_variant-keycap-background-active: var(--variant-keycap-background-active, var(--_accent-color));\n}\n`;\n\n// src/ui/style.less\nvar style_default = \":host {\\n  --primary-color: #5898ff;\\n  --primary-color-dimmed: #c0c0f0;\\n  --primary-color-dark: var(--blue-500);\\n  --primary-color-light: var(--blue-100);\\n  --primary-color-reverse: #ffffff;\\n  --secondary-color: #ff8a65;\\n  --secondary-color-dimmed: #f0d5c5;\\n  --secondary-color-dark: var(--orange-500);\\n  --secondary-color-light: var(--orange-100);\\n  --secondary-color-reverse: #ffffff;\\n  --link-color: #5898ff;\\n  --link-color-dimmed: #c5c5c5;\\n  --link-color-dark: #121212;\\n  --link-color-light: #e2e2e2;\\n  --link-color-reverse: #ffffff;\\n  --semantic-blue: var(--blue-700);\\n  --semantic-red: var(--red-400);\\n  --semantic-orange: var(--orange-400);\\n  --semantic-green: var(--green-700);\\n  --neutral-100: #f5f5f5;\\n  --neutral-200: #eeeeee;\\n  --neutral-300: #e0e0e0;\\n  --neutral-400: #bdbdbd;\\n  --neutral-500: #9e9e9e;\\n  --neutral-600: #757575;\\n  --neutral-700: #616161;\\n  --neutral-800: #424242;\\n  --neutral-900: #212121;\\n  --red-25: #fff8f7;\\n  --red-50: #fff1ef;\\n  --red-100: #ffeae6;\\n  --red-200: #ffcac1;\\n  --red-300: #ffa495;\\n  --red-400: #ff7865;\\n  --red-500: #f21c0d;\\n  --red-600: #e50018;\\n  --red-700: #d30024;\\n  --red-800: #bd002c;\\n  --red-900: #a1002f;\\n  --orange-25: #fffbf8;\\n  --orange-50: #fff7f1;\\n  --orange-100: #fff3ea;\\n  --orange-200: #ffe1c9;\\n  --orange-300: #ffcca2;\\n  --orange-400: #ffb677;\\n  --orange-500: #fe9310;\\n  --orange-600: #f58700;\\n  --orange-700: #ea7c00;\\n  --orange-800: #dc6d00;\\n  --orange-900: #ca5b00;\\n  --brown-25: #fff8ef;\\n  --brown-50: #fff1df;\\n  --brown-100: #ffe9ce;\\n  --brown-200: #ebcca6;\\n  --brown-300: #cdaf8a;\\n  --brown-400: #af936f;\\n  --brown-500: #856a47;\\n  --brown-600: #7f5e34;\\n  --brown-700: #78511f;\\n  --brown-800: #6e4200;\\n  --brown-900: #593200;\\n  --yellow-25: #fffdf9;\\n  --yellow-50: #fffcf2;\\n  --yellow-100: #fffaec;\\n  --yellow-200: #fff2ce;\\n  --yellow-300: #ffe8ab;\\n  --yellow-400: #ffdf85;\\n  --yellow-500: #ffcf33;\\n  --yellow-600: #f1c000;\\n  --yellow-700: #dfb200;\\n  --yellow-800: #c9a000;\\n  --yellow-900: #ad8a00;\\n  --lime-25: #f4ffee;\\n  --lime-50: #e9ffdd;\\n  --lime-100: #ddffca;\\n  --lime-200: #a8fb6f;\\n  --lime-300: #94e659;\\n  --lime-400: #80d142;\\n  --lime-500: #63b215;\\n  --lime-600: #45a000;\\n  --lime-700: #268e00;\\n  --lime-800: #007417;\\n  --lime-900: #005321;\\n  --green-25: #f5fff5;\\n  --green-50: #ebffea;\\n  --green-100: #e0ffdf;\\n  --green-200: #a7ffa7;\\n  --green-300: #5afa65;\\n  --green-400: #45e953;\\n  --green-500: #17cf36;\\n  --green-600: #00b944;\\n  --green-700: #00a34a;\\n  --green-800: #008749;\\n  --green-900: #00653e;\\n  --teal-25: #f3ffff;\\n  --teal-50: #e6fffe;\\n  --teal-100: #d9fffe;\\n  --teal-200: #8dfffe;\\n  --teal-300: #57f4f4;\\n  --teal-400: #43e5e5;\\n  --teal-500: #17cfcf;\\n  --teal-600: #00c2c0;\\n  --teal-700: #00b5b1;\\n  --teal-800: #00a49e;\\n  --teal-900: #009087;\\n  --cyan-25: #f7fcff;\\n  --cyan-50: #eff8ff;\\n  --cyan-100: #e7f5ff;\\n  --cyan-200: #c2e6ff;\\n  --cyan-300: #95d5ff;\\n  --cyan-400: #61c4ff;\\n  --cyan-500: #13a7ec;\\n  --cyan-600: #069eda;\\n  --cyan-700: #0095c9;\\n  --cyan-800: #0088b2;\\n  --cyan-900: #0a7897;\\n  --blue-25: #f7faff;\\n  --blue-50: #eef5ff;\\n  --blue-100: #e5f1ff;\\n  --blue-200: #bfdbff;\\n  --blue-300: #92c2ff;\\n  --blue-400: #63a8ff;\\n  --blue-500: #0d80f2;\\n  --blue-600: #0077db;\\n  --blue-700: #006dc4;\\n  --blue-800: #0060a7;\\n  --blue-900: #005086;\\n  --indigo-25: #f8f7ff;\\n  --indigo-50: #f1efff;\\n  --indigo-100: #eae7ff;\\n  --indigo-200: #ccc3ff;\\n  --indigo-300: #ac99ff;\\n  --indigo-400: #916aff;\\n  --indigo-500: #63c;\\n  --indigo-600: #5a21b2;\\n  --indigo-700: #4e0b99;\\n  --indigo-800: #3b0071;\\n  --indigo-900: #220040;\\n  --purple-25: #fbf7ff;\\n  --purple-50: #f8f0ff;\\n  --purple-100: #f4e8ff;\\n  --purple-200: #e4c4ff;\\n  --purple-300: #d49aff;\\n  --purple-400: #c36aff;\\n  --purple-500: #a219e6;\\n  --purple-600: #9000c4;\\n  --purple-700: #7c009f;\\n  --purple-800: #600073;\\n  --purple-900: #3d0043;\\n  --magenta-25: #fff8fb;\\n  --magenta-50: #fff2f6;\\n  --magenta-100: #ffebf2;\\n  --magenta-200: #ffcddf;\\n  --magenta-300: #ffa8cb;\\n  --magenta-400: #ff7fb7;\\n  --magenta-500: #eb4799;\\n  --magenta-600: #da3689;\\n  --magenta-700: #c82179;\\n  --magenta-800: #b00065;\\n  --magenta-900: #8a004c;\\n}\\n@media (prefers-color-scheme: dark) {\\n  :host {\\n    --semantic-blue: var(--blue-700);\\n    --semantic-red: var(--red-400);\\n    --semantic-orange: var(--orange-400);\\n    --semantic-green: var(--green-700);\\n    --semantic-bg-blue: var(--blue-25);\\n    --semantic-bg-red: var(--red-25);\\n    --semantic-bg-orange: var(--orange-25);\\n    --semantic-bg-green: var(--green-25);\\n    --neutral-100: #121212;\\n    --neutral-200: #424242;\\n    --neutral-300: #616161;\\n    --neutral-400: #757575;\\n    --neutral-500: #9e9e9e;\\n    --neutral-600: #bdbdbd;\\n    --neutral-700: #e0e0e0;\\n    --neutral-800: #eeeeee;\\n    --neutral-900: #f5f5f5;\\n  }\\n}\\n:host([theme='dark']) {\\n  --semantic-blue: var(--blue-700);\\n  --semantic-red: var(--red-400);\\n  --semantic-orange: var(--orange-400);\\n  --semantic-green: var(--green-700);\\n  --semantic-bg-blue: var(--blue-25);\\n  --semantic-bg-red: var(--red-25);\\n  --semantic-bg-orange: var(--orange-25);\\n  --semantic-bg-green: var(--green-25);\\n  --neutral-100: #121212;\\n  --neutral-200: #424242;\\n  --neutral-300: #616161;\\n  --neutral-400: #757575;\\n  --neutral-500: #9e9e9e;\\n  --neutral-600: #bdbdbd;\\n  --neutral-700: #e0e0e0;\\n  --neutral-800: #eeeeee;\\n  --neutral-900: #f5f5f5;\\n}\\n/* @media (prefers-color-scheme: dark) {\\n  :host {\\n      --label-color: #fff;\\n      --active-label-color: #000;\\n      --menu-bg: #525252;\\n      --active-bg: #5898ff;\\n      --active-bg-dimmed: #5c5c5c;\\n  }\\n} */\\n:host {\\n  --ui-font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont,\\n    'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji',\\n    'Segoe UI Emoji', 'Segoe UI Symbol';\\n  --ui-font-size: 14px;\\n  --ui-line-height: 1.5;\\n  --ui-letter-spacing: 0.007em;\\n  --mono-font-family: 'Berkeley Mono', 'JetBrains Mono', 'IBM Plex Mono',\\n    'Source Code Pro', Menlo, Monaco, 'Courier New', monospace;\\n  --ui-layer-1: var(--neutral-100);\\n  --ui-layer-2: var(--neutral-200);\\n  --ui-layer-3: var(--neutral-300);\\n  --ui-layer-4: var(--neutral-400);\\n  --ui-layer-5: var(--neutral-500);\\n  --ui-layer-6: var(--neutral-600);\\n  --ui-border-color: var(--primary-color);\\n  --ui-border-radius: 4px;\\n  --ui-text: var(--neutral-900);\\n  --ui-text-secondary: var(--neutral-700);\\n  --ui-text-placeholder: var(--neutral-500);\\n  --ui-text-muted: var(--neutral-300);\\n  /** A field is a UI element in which a user can type data, for\\n  * example an input or textarea element.\\n  */\\n  --ui-field-bg: var(--neutral-100);\\n  --ui-field-bg-hover: var(--neutral-100);\\n  --ui-field-bg-disabled: var(--neutral-300);\\n  --ui-field-bg-invalid: var(--red-100);\\n  --ui-field-bg-focus: var(--neutral-100);\\n  --ui-field-border: 0.5px solid var(--border-color);\\n  --ui-field-border-hover: 0.5px solid var(--border-color);\\n  --ui-field-border-disabled: 0.5px solid var(--border-color);\\n  --ui-field-border-invalid: 0.5px solid var(--border-color);\\n  --ui-field-border-focus: 0.5px solid var(--border-color);\\n  --ui-menu-bg: var(--neutral-100);\\n  --ui-menu-text: var(--neutral-900);\\n  --ui-menu-bg-hover: var(--neutral-200);\\n  --ui-menu-text-hover: var(--neutral-900);\\n  /** The `active` state is used for the state of menu items\\n  * when they are selected.\\n  */\\n  --ui-menu-bg-active: var(--primary-color);\\n  --ui-menu-text-active: var(--primary-color-reverse);\\n  /** The `active-muted` set is used for the state of\\n  * submenus when they are open.\\n  */\\n  --ui-menu-bg-active-muted: var(--neutral-300);\\n  --ui-menu-text-active-muted: var(--neutral-900);\\n  /* --ui-menu-shadow: 0 1px 2px 0 rgba(60, 64, 67, 0.302),\\n0 2px 6px 2px rgba(60, 64, 67, 0.149); */\\n  --ui-menu-shadow: 0 0 2px rgba(0, 0, 0, 0.5), 0 0 20px rgba(0, 0, 0, 0.2);\\n  --ui-menu-divider: 0.5px solid #c7c7c7;\\n  /* var(--neutral-300); */\\n  --ui-menu-z-index: 10000;\\n  --page-bg: var(--neutral-100);\\n  --content-bg: var(--neutral-200);\\n}\\n@media (prefers-color-scheme: dark) {\\n  :host {\\n    --ui-menu-bg: var(--neutral-200);\\n  }\\n}\\n:host([theme='dark']) {\\n  --ui-menu-bg: var(--neutral-200);\\n}\\n/* PingFang SC is a macOS font. Microsoft Yahei is a Windows font. \\n  Noto  is a Linux/Android font.\\n*/\\n:lang(zh-cn),\\n:lang(zh-sg),\\n:lang(zh-my),\\n:lang(zh) {\\n  --ui-font-family: -apple-system, system-ui, 'PingFang SC', 'Hiragino Sans GB',\\n    'Noto Sans CJK SC', 'Noto Sans SC', 'Noto Sans', 'Microsoft Yahei UI',\\n    'Microsoft YaHei New', 'Microsoft Yahei', '\\u5FAE\\u8F6F\\u96C5\\u9ED1', SimSun, '\\u5B8B\\u4F53',\\n    STXihei, '\\u534E\\u6587\\u7EC6\\u9ED1', sans-serif;\\n}\\n:lang(zh-tw),\\n:lang(zh-hk),\\n:lang(zh-mo) {\\n  --ui-font-family: -apple-system, system-ui, 'Noto Sans',\\n    'Microsoft JhengHei UI', 'Microsoft JhengHei', '\\u5FAE\\u8EDF\\u6B63\\u9ED1\\u9AD4', '\\u65B0\\u7D30\\u660E\\u9AD4',\\n    'PMingLiU', '\\u7D30\\u660E\\u9AD4', 'MingLiU', sans-serif;\\n}\\n:lang(ja),\\n:lang(ja-jp),\\n:lang(ja-jp-mac) {\\n  --ui-font-family: -apple-system, system-ui, 'Hiragino Sans',\\n    'Hiragino Kaku Gothic ProN', 'Noto Sans CJK JP', 'Noto Sans JP', 'Noto Sans',\\n    '\\u6E38\\u30B4\\u30B7\\u30C3\\u30AF', '\\u6E38\\u30B4\\u30B7\\u30C3\\u30AF\\u4F53', YuGothic, 'Yu Gothic', '\\u30E1\\u30A4\\u30EA\\u30AA', Meiryo,\\n    '\\uFF2D\\uFF33 \\uFF30\\u30B4\\u30B7\\u30C3\\u30AF', 'MS PGothic', sans-serif;\\n}\\n:lang(ko),\\n:lang(ko-kr),\\n:lang(ko-kr-std) {\\n  --ui-font-family: -apple-system, system-ui, 'Noto Sans CJK KR', 'Noto Sans KR',\\n    'Noto Sans', 'Malgun Gothic', '\\uB9D1\\uC740 \\uACE0\\uB515', 'Apple SD Gothic Neo',\\n    '\\uC560\\uD50C SD \\uC0B0\\uB3CC\\uACE0\\uB515 Neo', 'Apple SD \\uC0B0\\uB3CC\\uACE0\\uB515 Neo', '\\uB3CB\\uC6C0', Dotum, sans-serif;\\n}\\n:lang(ko-kr-apple) {\\n  --ui-font-family: -apple-system, system-ui, 'Noto Sans CJK KR', 'Noto Sans KR',\\n    'Noto Sans', 'Apple SD Gothic Neo', '\\uC560\\uD50C SD \\uC0B0\\uB3CC\\uACE0\\uB515 Neo',\\n    'Apple SD \\uC0B0\\uB3CC\\uACE0\\uB515 Neo', '\\uB3CB\\uC6C0', Dotum, sans-serif;\\n}\\n:lang(zh-cn),\\n:lang(zh-sg),\\n:lang(zh-my),\\n:lang(zh),\\n:lang(zh-tw),\\n:lang(zh-hk),\\n:lang(zh-mo),\\n:lang(ja),\\n:lang(ja-jp),\\n:lang(ja-jp-mac),\\n:lang(ko),\\n:lang(ko-kr),\\n:lang(ko-kr-std),\\n:lang(ko-kr-apple) {\\n  --ui-font-size: 1rem;\\n  --ui-line-height: 1.7;\\n  --ui-letter-spacing: 0;\\n}\\n:dir(rtl) {\\n  --ui-line-height: auto;\\n  --ui-letter-spacing: 0;\\n}\\n\";\n\n// src/ui/menu/style.less\nvar style_default2 = \".ui-menu *,\\n.ui-menu ::before,\\n.ui-menu ::after {\\n  box-sizing: border-box;\\n}\\n.ui-menu {\\n  display: none;\\n  color-scheme: light dark;\\n  -webkit-user-select: none;\\n  /* Important: Safari iOS doesn't respect user-select */\\n  user-select: none;\\n  cursor: default;\\n  -webkit-touch-callout: none;\\n  -webkit-tap-highlight-color: rgba(0 0 0 0);\\n  --active-label-color: #fff;\\n  /* ui-menu-text-active */\\n  --label-color: #121212;\\n  /* ui-menu-text */\\n  --menu-bg: #e2e2e2;\\n  /* ui-menu-background */\\n  --active-bg: #5898ff;\\n  /* ui-menu-background-active */\\n  --active-bg-dimmed: #c5c5c5;\\n  /* ui-menu-background-active-muted */\\n}\\n/** Use the :where pseudo selector to make the specificity of the\\n * selector 0, so that it can be overridden by the user.\\n */\\n:where(.ui-menu-container) {\\n  position: absolute;\\n  overflow: visible;\\n  width: auto;\\n  height: auto;\\n  z-index: 10000;\\n  border-radius: 8px;\\n  background: var(--ui-menu-bg);\\n  box-shadow: var(--ui-menu-shadow);\\n  list-style: none;\\n  padding: 6px 0 6px 0;\\n  margin: 0;\\n  user-select: none;\\n  cursor: default;\\n  color: var(--ui-menu-text);\\n  font-weight: normal;\\n  font-style: normal;\\n  text-shadow: none;\\n  text-transform: none;\\n  letter-spacing: 0;\\n  outline: none;\\n  opacity: 1;\\n  /* The [popover] elements have a 1px solid black border. Ugh. */\\n  border: none;\\n  width: fit-content;\\n  height: fit-content;\\n}\\n:where(.ui-menu-container > li) {\\n  display: flex;\\n  flex-flow: row;\\n  align-items: center;\\n  padding: 1px 7px 1px 7px;\\n  margin-top: 0;\\n  margin-left: 6px;\\n  margin-right: 6px;\\n  border-radius: 4px;\\n  white-space: nowrap;\\n  position: relative;\\n  outline: none;\\n  fill: currentColor;\\n  user-select: none;\\n  cursor: default;\\n  text-align: left;\\n  color: inherit;\\n  font-family: var(--ui-font-family);\\n  font-size: var(--ui-font-size);\\n  line-height: var(--ui-line-height);\\n  letter-spacing: var(--ui-letter-spacing);\\n}\\n:where(.ui-menu-container > li > .label) {\\n  display: flex;\\n  align-items: center;\\n  justify-content: space-between;\\n  appearance: none;\\n  background: none;\\n  outline: none;\\n  width: 100%;\\n  margin: 0;\\n  padding: 1px 2px 1px 1px;\\n  overflow: visible;\\n  border: 1px solid transparent;\\n  white-space: nowrap;\\n  text-align: start;\\n  align-content: center;\\n}\\n:where(.ui-menu-container > li:has(.heading)) {\\n  margin-top: 0.5em;\\n}\\n:where(.ui-menu-container > li > .label.heading) {\\n  font-weight: bold;\\n  opacity: 0.4;\\n}\\n:where(.ui-menu-container > li.indent > .label) {\\n  margin-inline-start: 12px;\\n}\\n:where(.ui-menu-container > li > .label.indent) {\\n  margin-inline-start: 12px;\\n}\\n:where(.ui-menu-container > li[role='divider']) {\\n  border-bottom: 1px solid var(--ui-menu-divider);\\n  border-radius: 0;\\n  padding: 0;\\n  margin-left: 15px;\\n  margin-right: 15px;\\n  padding-top: 5px;\\n  margin-bottom: 5px;\\n  width: calc(100% - 30px);\\n  /** 100% - (margin-left + margin-right) */\\n}\\n:where(.ui-menu-container > li[aria-disabled='true']) {\\n  opacity: 0.5;\\n}\\n:where(.ui-menu-container > li.active) {\\n  background: var(--ui-menu-bg-active);\\n  background: -apple-system-control-accent;\\n  color: var(--ui-menu-text-active);\\n}\\n:where(.ui-menu-container > li.active.is-submenu-open) {\\n  background: var(--ui-menu-bg-active-muted);\\n  color: inherit;\\n}\\n:where(.ui-menu-container > li[aria-haspopup='true'] > .label) {\\n  padding-inline-end: 0;\\n}\\n:where(.ui-menu-container > li[aria-haspopup='true'].active::after) {\\n  color: var(--ui-menu-text-active);\\n}\\n/** Keyboard shortcut */\\n:where(.ui-menu-container > li > kbd) {\\n  font-family: var(--ui-font-family);\\n  margin-inline-start: 12px;\\n  opacity: 0.4;\\n}\\n:where(.ui-menu-container > li.active > kbd) {\\n  opacity: 0.85;\\n}\\n.ui-trailing-chevron {\\n  display: flex;\\n  margin-inline-start: 24px;\\n  width: 10px;\\n  height: 10px;\\n  margin-bottom: 4px;\\n}\\n.ui-trailing-chevron:dir(rtl) {\\n  transform: scaleX(-1);\\n}\\n.ui-checkmark {\\n  display: flex;\\n  margin-inline-end: -11px;\\n  margin-inline-start: -4px;\\n  margin-top: 2px;\\n  width: 16px;\\n  height: 16px;\\n}\\n.ui-mixedmark {\\n  display: flex;\\n  margin-inline-end: -11px;\\n  margin-inline-start: -4px;\\n  margin-top: 2px;\\n  width: 16px;\\n  height: 16px;\\n}\\n\";\n\n// src/common/stylesheet.ts\nvar gStylesheets;\nfunction getStylesheetContent(id) {\n  let content = \"\";\n  switch (id) {\n    case \"mathfield-element\":\n      content = `\n    :host { display: inline-block; background-color: field; color: fieldtext; border-width: 1px; border-style: solid; border-color: #acacac; border-radius: 2px;}\n    :host([hidden]) { display: none; }\n    :host([disabled]), :host([disabled]:focus), :host([disabled]:focus-within) { outline: none; opacity:  .5; }\n    :host(:focus), :host(:focus-within) {\n      outline: Highlight auto 1px;    /* For Firefox */\n      outline: -webkit-focus-ring-color auto 1px;\n    }\n    :host([readonly]:focus), :host([readonly]:focus-within),\n    :host([read-only]:focus), :host([read-only]:focus-within) {\n      outline: none;\n    }`;\n      break;\n    case \"core\":\n      content = core_default;\n      break;\n    case \"mathfield\":\n      content = mathfield_default;\n      break;\n    case \"environment-popover\":\n      content = environment_popover_default;\n      break;\n    case \"suggestion-popover\":\n      content = suggestion_popover_default;\n      break;\n    case \"keystroke-caption\":\n      content = keystroke_caption_default;\n      break;\n    case \"virtual-keyboard\":\n      content = virtual_keyboard_default;\n      break;\n    case \"ui\":\n      content = style_default;\n      break;\n    case \"menu\":\n      content = style_default2;\n      break;\n    default:\n      debugger;\n  }\n  return content;\n}\nfunction getStylesheet(id) {\n  if (!gStylesheets) gStylesheets = {};\n  if (gStylesheets[id]) return gStylesheets[id];\n  gStylesheets[id] = new CSSStyleSheet();\n  gStylesheets[id].replaceSync(getStylesheetContent(id));\n  return gStylesheets[id];\n}\nvar gInjectedStylesheets;\nfunction injectStylesheet(id) {\n  var _a3;\n  if (!(\"adoptedStyleSheets\" in document)) {\n    if (window.document.getElementById(`mathlive-style-${id}`)) return;\n    const styleNode = window.document.createElement(\"style\");\n    styleNode.id = `mathlive-style-${id}`;\n    styleNode.append(window.document.createTextNode(getStylesheetContent(id)));\n    window.document.head.appendChild(styleNode);\n    return;\n  }\n  if (!gInjectedStylesheets) gInjectedStylesheets = {};\n  if (((_a3 = gInjectedStylesheets[id]) != null ? _a3 : 0) !== 0) gInjectedStylesheets[id] += 1;\n  else {\n    const stylesheet = getStylesheet(id);\n    document.adoptedStyleSheets = [...document.adoptedStyleSheets, stylesheet];\n    gInjectedStylesheets[id] = 1;\n  }\n}\nfunction releaseStylesheet(id) {\n  if (!(\"adoptedStyleSheets\" in document)) return;\n  if (!(gInjectedStylesheets == null ? void 0 : gInjectedStylesheets[id])) return;\n  gInjectedStylesheets[id] -= 1;\n  if (gInjectedStylesheets[id] <= 0) {\n    const stylesheet = gStylesheets[id];\n    document.adoptedStyleSheets = document.adoptedStyleSheets.filter(\n      (x) => x !== stylesheet\n    );\n  }\n}\n\n// src/atoms/accent.ts\nvar AccentAtom = class _AccentAtom extends Atom {\n  constructor(options) {\n    var _a3;\n    super(__spreadProps(__spreadValues({}, options), { type: \"accent\", body: (_a3 = options.body) != null ? _a3 : void 0 }));\n    if (options.accentChar) this.accent = options.accentChar;\n    else this.svgAccent = options == null ? void 0 : options.svgAccent;\n    this.skipBoundary = true;\n    this.captureSelection = true;\n  }\n  static fromJson(json) {\n    return new _AccentAtom(json);\n  }\n  toJson() {\n    return __spreadProps(__spreadValues({}, super.toJson()), {\n      accentChar: this.accent,\n      svgAccent: this.svgAccent\n    });\n  }\n  render(parentContext) {\n    var _a3;\n    const context = new Context(\n      { parent: parentContext, mathstyle: \"cramp\" },\n      this.style\n    );\n    const base = (_a3 = Atom.createBox(context, this.body)) != null ? _a3 : new Box(\"\\u25A2\", { style: this.style });\n    let skew = 0;\n    if (!this.hasEmptyBranch(\"body\") && this.body.length === 2 && this.body[1].isCharacterBox())\n      skew = base.skew;\n    let clearance = Math.min(base.height, X_HEIGHT);\n    let accentBox;\n    if (this.svgAccent) {\n      accentBox = makeSVGBox(this.svgAccent);\n      clearance = context.metrics.bigOpSpacing1 - clearance;\n    } else if (this.accent) {\n      const accent = new Box(this.accent, { fontFamily: \"Main-Regular\" });\n      accent.italic = 0;\n      const vecClass = this.accent === 8407 ? \" ML__accent-vec\" : \"\";\n      accentBox = new Box(new Box(accent), {\n        classes: \"ML__accent-body\" + vecClass\n      });\n    }\n    accentBox = new VBox({\n      shift: 0,\n      children: [\n        { box: new Box(base) },\n        -clearance,\n        {\n          box: accentBox,\n          marginLeft: base.left + 2 * skew,\n          classes: [\"ML__center\"]\n        }\n      ]\n    });\n    const result = new Box(accentBox, { type: \"lift\" });\n    if (this.caret) result.caret = this.caret;\n    this.bind(context, result.wrap(context));\n    return this.attachSupsub(context, { base: result });\n  }\n};\n\n// src/core/delimiters.ts\nvar RIGHT_DELIM = {\n  \"(\": \")\",\n  \"{\": \"}\",\n  \"[\": \"]\",\n  \"|\": \"|\",\n  \"\\\\lbrace\": \"\\\\rbrace\",\n  \"\\\\lparen\": \"\\\\rparen\",\n  \"\\\\{\": \"\\\\}\",\n  \"\\\\langle\": \"\\\\rangle\",\n  \"\\\\lfloor\": \"\\\\rfloor\",\n  \"\\\\lceil\": \"\\\\rceil\",\n  \"\\\\vert\": \"\\\\vert\",\n  \"\\\\lvert\": \"\\\\rvert\",\n  \"\\\\Vert\": \"\\\\Vert\",\n  \"\\\\lVert\": \"\\\\rVert\",\n  \"\\\\lbrack\": \"\\\\rbrack\",\n  \"\\\\ulcorner\": \"\\\\urcorner\",\n  \"\\\\llcorner\": \"\\\\lrcorner\",\n  \"\\\\lgroup\": \"\\\\rgroup\",\n  \"\\\\lmoustache\": \"\\\\rmoustache\"\n};\nvar LEFT_DELIM = Object.fromEntries(\n  Object.entries(RIGHT_DELIM).map(([leftDelim, rightDelim]) => [\n    rightDelim,\n    leftDelim\n  ])\n);\nfunction getSymbolValue(symbol) {\n  var _a3;\n  return (_a3 = {\n    \"[\": 91,\n    // '[',\n    \"]\": 93,\n    // ']',\n    \"(\": 40,\n    // '(',\n    \")\": 41,\n    // ')',\n    \"\\\\mid\": 8739,\n    \"|\": 8739,\n    \"\\u2223\": 8739,\n    // DIVIDES\n    \"\\u2225\": 8741,\n    // PARALLEL TO\n    \"\\\\|\": 8739,\n    \"\\\\{\": 123,\n    // '{',\n    \"\\\\}\": 125,\n    // '}',\n    \"\\\\lbrace\": 123,\n    // '{',\n    \"\\\\rbrace\": 125,\n    // '}',\n    \"\\\\lparen\": 40,\n    // '('\n    \"\\\\rparen\": 41,\n    // ')'\n    \"\\\\lbrack\": 91,\n    // '[',\n    \"\\\\rbrack\": 93,\n    // ']',\n    \"\\\\vert\": 8739,\n    \"\\\\lvert\": 8739,\n    \"\\\\mvert\": 8739,\n    \"\\\\rvert\": 8739,\n    \"\\\\Vert\": 8741,\n    \"\\\\lVert\": 8741,\n    \"\\\\mVert\": 8741,\n    \"\\\\rVert\": 8741,\n    \"\\\\parallel\": 8741,\n    \"\\\\shortparallel\": 8741,\n    \"\\\\langle\": 10216,\n    \"\\\\rangle\": 10217,\n    \"\\\\lfloor\": 8970,\n    \"\\\\rfloor\": 8971,\n    \"\\\\lceil\": 8968,\n    \"\\\\rceil\": 8969,\n    \"\\\\ulcorner\": 9484,\n    \"\\\\urcorner\": 9488,\n    \"\\\\llcorner\": 9492,\n    \"\\\\lrcorner\": 9496,\n    \"\\\\lgroup\": 10222,\n    \"\\\\rgroup\": 10223,\n    \"\\\\lmoustache\": 9136,\n    \"\\\\rmoustache\": 9137,\n    \"\\\\surd\": 8730\n  }[symbol]) != null ? _a3 : symbol.codePointAt(0);\n}\nfunction makeSmallDelim(delim, context, center, options) {\n  var _a3;\n  const text = new Box(getSymbolValue(delim), {\n    fontFamily: \"Main-Regular\",\n    isSelected: options.isSelected,\n    classes: \"ML__small-delim \" + ((_a3 = options.classes) != null ? _a3 : \"\")\n  });\n  const box = text.wrap(context);\n  if (center) box.setTop((1 - context.scalingFactor) * AXIS_HEIGHT);\n  return box;\n}\nfunction makeLargeDelim(delim, size, center, parentContext, options) {\n  var _a3, _b3;\n  const context = new Context(\n    { parent: parentContext, mathstyle: \"textstyle\" },\n    options == null ? void 0 : options.style\n  );\n  const result = new Box(getSymbolValue(delim), {\n    fontFamily: `Size${size}-Regular`,\n    isSelected: options.isSelected,\n    classes: ((_a3 = options.classes) != null ? _a3 : \"\") + ` ML__delim-size${size}`,\n    type: (_b3 = options.type) != null ? _b3 : \"ignore\"\n  }).wrap(context);\n  if (center) result.setTop((1 - context.scalingFactor) * AXIS_HEIGHT);\n  return result;\n}\nfunction makeStackedDelim(delim, heightTotal, center, context, options) {\n  var _a3;\n  let top;\n  let middle;\n  let repeat;\n  let bottom;\n  top = repeat = bottom = getSymbolValue(delim);\n  middle = null;\n  let fontFamily = \"Size1-Regular\";\n  if (delim === \"\\\\vert\" || delim === \"\\\\lvert\" || delim === \"\\\\rvert\" || delim === \"\\\\mvert\" || delim === \"\\\\mid\")\n    repeat = top = bottom = 8739;\n  else if (delim === \"\\\\Vert\" || delim === \"\\\\lVert\" || delim === \"\\\\rVert\" || delim === \"\\\\mVert\" || delim === \"\\\\|\")\n    repeat = top = bottom = 8741;\n  else if (delim === \"\\\\uparrow\") repeat = bottom = 9168;\n  else if (delim === \"\\\\Uparrow\") repeat = bottom = 8214;\n  else if (delim === \"\\\\downarrow\") top = repeat = 9168;\n  else if (delim === \"\\\\Downarrow\") top = repeat = 8214;\n  else if (delim === \"\\\\updownarrow\") {\n    top = 8593;\n    repeat = 9168;\n    bottom = 8595;\n  } else if (delim === \"\\\\Updownarrow\") {\n    top = 8657;\n    repeat = 8214;\n    bottom = 8659;\n  } else if (delim === \"[\" || delim === \"\\\\lbrack\") {\n    top = 9121;\n    repeat = 9122;\n    bottom = 9123;\n    fontFamily = \"Size4-Regular\";\n  } else if (delim === \"]\" || delim === \"\\\\rbrack\") {\n    top = 9124;\n    repeat = 9125;\n    bottom = 9126;\n    fontFamily = \"Size4-Regular\";\n  } else if (delim === \"\\\\lfloor\" || delim === \"\\u230A\") {\n    repeat = top = 9122;\n    bottom = 9123;\n    fontFamily = \"Size4-Regular\";\n  } else if (delim === \"\\\\lceil\" || delim === \"\\u2308\") {\n    top = 9121;\n    repeat = bottom = 9122;\n    fontFamily = \"Size4-Regular\";\n  } else if (delim === \"\\\\rfloor\" || delim === \"\\u230B\") {\n    repeat = top = 9125;\n    bottom = 9126;\n    fontFamily = \"Size4-Regular\";\n  } else if (delim === \"\\\\rceil\" || delim === \"\\u2309\") {\n    top = 9124;\n    repeat = bottom = 9125;\n    fontFamily = \"Size4-Regular\";\n  } else if (delim === \"(\" || delim === \"\\\\lparen\") {\n    top = 9115;\n    repeat = 9116;\n    bottom = 9117;\n    fontFamily = \"Size4-Regular\";\n  } else if (delim === \")\" || delim === \"\\\\rparen\") {\n    top = 9118;\n    repeat = 9119;\n    bottom = 9120;\n    fontFamily = \"Size4-Regular\";\n  } else if (delim === \"\\\\{\" || delim === \"\\\\lbrace\") {\n    top = 9127;\n    middle = 9128;\n    bottom = 9129;\n    repeat = 9130;\n    fontFamily = \"Size4-Regular\";\n  } else if (delim === \"\\\\}\" || delim === \"\\\\rbrace\") {\n    top = 9131;\n    middle = 9132;\n    bottom = 9133;\n    repeat = 9130;\n    fontFamily = \"Size4-Regular\";\n  } else if (delim === \"\\\\lgroup\" || delim === \"\\u27EE\") {\n    top = 9127;\n    bottom = 9129;\n    repeat = 9130;\n    fontFamily = \"Size4-Regular\";\n  } else if (delim === \"\\\\rgroup\" || delim === \"\\u27EF\") {\n    top = 9131;\n    bottom = 9133;\n    repeat = 9130;\n    fontFamily = \"Size4-Regular\";\n  } else if (delim === \"\\\\lmoustache\" || delim === \"\\u23B0\") {\n    top = 9127;\n    bottom = 9133;\n    repeat = 9130;\n    fontFamily = \"Size4-Regular\";\n  } else if (delim === \"\\\\rmoustache\" || delim === \"\\u23B1\") {\n    top = 9131;\n    bottom = 9129;\n    repeat = 9130;\n    fontFamily = \"Size4-Regular\";\n  } else if (delim === \"\\\\surd\") {\n    top = 57345;\n    bottom = 9143;\n    repeat = 57344;\n    fontFamily = \"Size4-Regular\";\n  } else if (delim === \"\\\\ulcorner\") {\n    top = 9484;\n    repeat = bottom = 32;\n  } else if (delim === \"\\\\urcorner\") {\n    top = 9488;\n    repeat = bottom = 32;\n  } else if (delim === \"\\\\llcorner\") {\n    bottom = 9492;\n    repeat = top = 32;\n  } else if (delim === \"\\\\lrcorner\") {\n    top = 9496;\n    repeat = top = 32;\n  }\n  const topMetrics = getCharacterMetrics(top, fontFamily);\n  const topHeightTotal = topMetrics.height + topMetrics.depth;\n  const repeatMetrics = getCharacterMetrics(repeat, fontFamily);\n  const repeatHeightTotal = repeatMetrics.height + repeatMetrics.depth;\n  const bottomMetrics = getCharacterMetrics(bottom, fontFamily);\n  const bottomHeightTotal = bottomMetrics.height + bottomMetrics.depth;\n  let middleHeightTotal = 0;\n  let middleFactor = 1;\n  if (middle !== null) {\n    const middleMetrics = getCharacterMetrics(middle, fontFamily);\n    middleHeightTotal = middleMetrics.height + middleMetrics.depth;\n    middleFactor = 2;\n  }\n  const minHeight = topHeightTotal + bottomHeightTotal + middleHeightTotal;\n  const repeatCount = Math.max(\n    0,\n    Math.ceil((heightTotal - minHeight) / (middleFactor * repeatHeightTotal))\n  );\n  const realHeightTotal = minHeight + repeatCount * middleFactor * repeatHeightTotal;\n  let axisHeight = AXIS_HEIGHT;\n  if (center) axisHeight = axisHeight * context.scalingFactor;\n  const depth = realHeightTotal / 2 - axisHeight;\n  const OVERLAP = 8e-3;\n  const stack = [];\n  stack.push({ box: new Box(bottom, { fontFamily }) });\n  stack.push(-OVERLAP);\n  const repeatBox = new Box(repeat, { fontFamily });\n  if (middle === null) {\n    for (let i = 0; i < repeatCount; i++) stack.push({ box: repeatBox });\n  } else {\n    for (let i = 0; i < repeatCount; i++) stack.push({ box: repeatBox });\n    stack.push(-OVERLAP);\n    stack.push({ box: new Box(middle, { fontFamily }) });\n    stack.push(-OVERLAP);\n    for (let i = 0; i < repeatCount; i++) stack.push({ box: repeatBox });\n  }\n  stack.push(-OVERLAP);\n  stack.push({ box: new Box(top, { fontFamily }) });\n  let sizeClass = \"\";\n  if (fontFamily === \"Size1-Regular\") sizeClass = \" delim-size1\";\n  else if (fontFamily === \"Size4-Regular\") sizeClass = \" delim-size4\";\n  const inner = new VBox(\n    {\n      bottom: depth,\n      children: stack\n    },\n    { classes: sizeClass }\n  );\n  const result = new Box(inner, __spreadProps(__spreadValues({}, options != null ? options : {}), {\n    classes: ((_a3 = options == null ? void 0 : options.classes) != null ? _a3 : \"\") + \" ML__delim-mult\"\n  }));\n  return result;\n}\nvar stackLargeDelimiters = /* @__PURE__ */ new Set([\n  \"(\",\n  \")\",\n  \"\\\\lparen\",\n  \"\\\\rparen\",\n  \"[\",\n  \"]\",\n  \"\\\\lbrack\",\n  \"\\\\rbrack\",\n  \"\\\\{\",\n  \"\\\\}\",\n  \"\\\\lbrace\",\n  \"\\\\rbrace\",\n  \"\\\\lfloor\",\n  \"\\\\rfloor\",\n  \"\\\\lceil\",\n  \"\\\\rceil\",\n  \"\\\\surd\",\n  \"\\u230A\",\n  \"\\u230B\",\n  \"\\u2308\",\n  \"\\u2309\"\n]);\nvar stackAlwaysDelimiters = /* @__PURE__ */ new Set([\n  \"\\\\uparrow\",\n  \"\\\\downarrow\",\n  \"\\\\updownarrow\",\n  \"\\\\Uparrow\",\n  \"\\\\Downarrow\",\n  \"\\\\Updownarrow\",\n  \"|\",\n  \"\\\\|\",\n  \"\\\\vert\",\n  \"\\\\Vert\",\n  \"\\\\lvert\",\n  \"\\\\rvert\",\n  \"\\\\lVert\",\n  \"\\\\rVert\",\n  \"\\\\mvert\",\n  \"\\\\mid\",\n  \"\\\\lgroup\",\n  \"\\\\rgroup\",\n  \"\\\\lmoustache\",\n  \"\\\\rmoustache\",\n  \"\\u27EE\",\n  \"\\u27EF\",\n  \"\\u23B0\",\n  \"\\u23B1\"\n]);\nvar stackNeverDelimiters = /* @__PURE__ */ new Set([\n  \"<\",\n  \">\",\n  \"\\\\langle\",\n  \"\\\\rangle\",\n  \"/\",\n  \"\\\\backslash\",\n  \"\\\\lt\",\n  \"\\\\gt\"\n]);\nvar sizeToMaxHeight = [0, 1.2, 1.8, 2.4, 3];\nfunction makeSizedDelim(delim, size, context, options) {\n  if (delim === void 0 || delim === \".\")\n    return makeNullDelimiter(context, options.classes);\n  if (delim === \"<\" || delim === \"\\\\lt\" || delim === \"\\u27E8\")\n    delim = \"\\\\langle\";\n  else if (delim === \">\" || delim === \"\\\\gt\" || delim === \"\\u27E9\")\n    delim = \"\\\\rangle\";\n  if (stackLargeDelimiters.has(delim) || stackNeverDelimiters.has(delim))\n    return makeLargeDelim(delim, size, false, context, options);\n  if (stackAlwaysDelimiters.has(delim)) {\n    return makeStackedDelim(\n      delim,\n      sizeToMaxHeight[size],\n      false,\n      context,\n      options\n    );\n  }\n  console.assert(false, \"Unknown delimiter '\" + delim + \"'\");\n  return null;\n}\nvar stackNeverDelimiterSequence = [\n  { type: \"small\", mathstyle: \"scriptscriptstyle\" },\n  { type: \"small\", mathstyle: \"scriptstyle\" },\n  { type: \"small\", mathstyle: \"textstyle\" },\n  { type: \"large\", size: 1 },\n  { type: \"large\", size: 2 },\n  { type: \"large\", size: 3 },\n  { type: \"large\", size: 4 }\n];\nvar stackAlwaysDelimiterSequence = [\n  { type: \"small\", mathstyle: \"scriptscriptstyle\" },\n  { type: \"small\", mathstyle: \"scriptscriptstyle\" },\n  { type: \"small\", mathstyle: \"textstyle\" },\n  { type: \"stack\" }\n];\nvar stackLargeDelimiterSequence = [\n  { type: \"small\", mathstyle: \"scriptscriptstyle\" },\n  { type: \"small\", mathstyle: \"scriptstyle\" },\n  { type: \"small\", mathstyle: \"textstyle\" },\n  { type: \"large\", size: 1 },\n  { type: \"large\", size: 2 },\n  { type: \"large\", size: 3 },\n  { type: \"large\", size: 4 },\n  { type: \"stack\" }\n];\nfunction delimTypeToFont(info) {\n  if (info.type === \"small\") return \"Main-Regular\";\n  if (info.type === \"large\")\n    return \"Size\" + info.size + \"-Regular\";\n  console.assert(info.type === \"stack\");\n  return \"Size4-Regular\";\n}\nfunction traverseSequence(delim, height, sequence, context) {\n  const start = { \"-4\": 0, \"-3\": 1, \"0\": 2 }[context.mathstyle.sizeDelta];\n  for (let i = start; i < sequence.length; i++) {\n    if (sequence[i].type === \"stack\") {\n      break;\n    }\n    const metrics = getCharacterMetrics(delim, delimTypeToFont(sequence[i]));\n    if (metrics.defaultMetrics) {\n      return { type: \"small\", mathstyle: \"scriptstyle\" };\n    }\n    let heightDepth = metrics.height + metrics.depth;\n    if (sequence[i].type === \"small\") {\n      if (sequence[i].mathstyle === \"scriptscriptstyle\") {\n        heightDepth *= Math.max(\n          FONT_SCALE[Math.max(1, context.size - 2)],\n          context.minFontScale\n        );\n      } else if (sequence[i].mathstyle === \"scriptstyle\") {\n        heightDepth *= Math.max(\n          FONT_SCALE[Math.max(1, context.size - 1)],\n          context.minFontScale\n        );\n      }\n    }\n    if (heightDepth > height) return sequence[i];\n  }\n  return sequence[sequence.length - 1];\n}\nfunction makeCustomSizedDelim(type, delim, height, center, context, options) {\n  if (!delim || delim.length === 0 || delim === \".\")\n    return makeNullDelimiter(context);\n  if (delim === \"<\" || delim === \"\\\\lt\") delim = \"\\\\langle\";\n  else if (delim === \">\" || delim === \"\\\\gt\") delim = \"\\\\rangle\";\n  let sequence;\n  if (stackNeverDelimiters.has(delim)) sequence = stackNeverDelimiterSequence;\n  else if (stackLargeDelimiters.has(delim))\n    sequence = stackLargeDelimiterSequence;\n  else sequence = stackAlwaysDelimiterSequence;\n  const delimType = traverseSequence(\n    getSymbolValue(delim),\n    height,\n    sequence,\n    context\n  );\n  const ctx = new Context(\n    { parent: context, mathstyle: delimType.mathstyle },\n    options == null ? void 0 : options.style\n  );\n  if (delimType.type === \"small\")\n    return makeSmallDelim(delim, ctx, center, __spreadProps(__spreadValues({}, options), { type }));\n  if (delimType.type === \"large\") {\n    return makeLargeDelim(delim, delimType.size, center, ctx, __spreadProps(__spreadValues({}, options), {\n      type\n    }));\n  }\n  console.assert(delimType.type === \"stack\");\n  return makeStackedDelim(delim, height, center, ctx, __spreadProps(__spreadValues({}, options), { type }));\n}\nfunction makeLeftRightDelim(type, delim, height, depth, context, options) {\n  if (delim === \".\") return makeNullDelimiter(context, options == null ? void 0 : options.classes);\n  const axisHeight = AXIS_HEIGHT * context.scalingFactor;\n  const delimiterFactor = 901;\n  const delimiterExtend = 5 / PT_PER_EM;\n  const maxDistFromAxis = Math.max(height - axisHeight, depth + axisHeight);\n  const totalHeight = Math.max(\n    maxDistFromAxis / 500 * delimiterFactor,\n    2 * maxDistFromAxis - delimiterExtend\n  );\n  return makeCustomSizedDelim(type, delim, totalHeight, true, context, options);\n}\nfunction makeNullDelimiter(parent, classes) {\n  const box = new Box(null, {\n    classes: \" ML__nulldelimiter \" + (classes != null ? classes : \"\"),\n    type: \"ignore\"\n  });\n  box.width = parent.getRegisterAsEm(\"nulldelimiterspace\");\n  return box.wrap(new Context({ parent, mathstyle: \"textstyle\" }));\n}\n\n// src/atoms/placeholder.ts\nvar PlaceholderAtom = class _PlaceholderAtom extends Atom {\n  constructor(options) {\n    var _a3;\n    super({\n      type: \"placeholder\",\n      command: \"\\\\placeholder\",\n      mode: (_a3 = options == null ? void 0 : options.mode) != null ? _a3 : \"math\",\n      style: options == null ? void 0 : options.style\n    });\n    this.captureSelection = true;\n  }\n  static fromJson(json) {\n    return new _PlaceholderAtom(json);\n  }\n  toJson() {\n    return super.toJson();\n  }\n  render(context) {\n    let result;\n    this.value = context.placeholderSymbol;\n    if (typeof context.renderPlaceholder === \"function\")\n      result = context.renderPlaceholder(context);\n    else result = this.createBox(context);\n    if (this.caret) result.classes += \" ML__placeholder-selected\";\n    return result;\n  }\n  _serialize(options) {\n    if (options.skipPlaceholders) return \"\";\n    return \"\\\\placeholder{}\";\n  }\n};\n\n// src/latex-commands/environment-types.ts\nvar matrices = [\n  \"matrix\",\n  \"matrix*\",\n  \"pmatrix\",\n  \"pmatrix*\",\n  \"bmatrix\",\n  \"bmatrix*\",\n  \"Bmatrix\",\n  \"Bmatrix*\",\n  \"vmatrix\",\n  \"vmatrix*\",\n  \"Vmatrix\",\n  \"Vmatrix*\"\n];\nvar cases = [\"cases\", \"dcases\", \"rcases\"];\nvar align = [\n  \"align\",\n  \"align*\",\n  \"aligned\",\n  \"gather\",\n  \"gather*\",\n  \"gathered\",\n  \"split\"\n];\nvar otherTabular = [\"array\", \"subequations\", \"eqnarray\"];\nfunction isTabularEnvironment(environment) {\n  return otherTabular.concat(align).concat(cases).concat(matrices).includes(environment);\n}\nfunction isMatrixEnvironment(environment) {\n  return matrices.includes(environment);\n}\nfunction isCasesEnvironment(environment) {\n  return cases.includes(environment);\n}\nfunction isAlignEnvironment(environment) {\n  return align.includes(environment);\n}\n\n// src/atoms/array.ts\nfunction normalizeArray(atom, array, colFormat) {\n  let maxColCount = 0;\n  for (const colSpec of colFormat) if (\"align\" in colSpec) maxColCount += 1;\n  let colCount = 0;\n  const rows = [];\n  for (const row of array) {\n    let colIndex2 = 0;\n    colCount = Math.max(colCount, Math.min(row.length, maxColCount));\n    while (colIndex2 < row.length) {\n      const newRow = [];\n      const lastCol = Math.min(row.length, colIndex2 + maxColCount);\n      while (colIndex2 < lastCol) {\n        const cell = row[colIndex2];\n        if (cell.length === 0)\n          newRow.push([new Atom({ type: \"first\", mode: atom.mode })]);\n        else if (cell[0].type !== \"first\")\n          newRow.push([new Atom({ type: \"first\", mode: atom.mode }), ...cell]);\n        else {\n          console.assert(!cell.slice(1).some((x) => x.type === \"first\"));\n          newRow.push(cell);\n        }\n        colIndex2 += 1;\n      }\n      rows.push(newRow);\n    }\n  }\n  if (rows.length > 0 && rows[rows.length - 1].length === 1 && rows[rows.length - 1][0].length === 1 && rows[rows.length - 1][0][0].type === \"first\")\n    rows.pop();\n  const result = [];\n  for (const row of rows) {\n    if (row.length !== colCount) {\n      for (let i = row.length; i < colCount; i++) {\n        row.push([\n          new Atom({ type: \"first\", mode: atom.mode }),\n          new PlaceholderAtom()\n        ]);\n      }\n    }\n    result.push(row);\n  }\n  let rowIndex = 0;\n  let colIndex = 0;\n  for (const row of result) {\n    colIndex = 0;\n    for (const cell of row) {\n      for (const element of cell) {\n        element.parent = atom;\n        element.parentBranch = [rowIndex, colIndex];\n      }\n      colIndex += 1;\n    }\n    rowIndex += 1;\n  }\n  atom.isDirty = true;\n  return result;\n}\nvar ArrayAtom = class _ArrayAtom extends Atom {\n  constructor(envName, array, rowGaps, options = {}) {\n    var _a3;\n    super({ type: \"array\" });\n    this.environmentName = envName;\n    this.rowGaps = rowGaps;\n    if (options.mathstyleName) this.mathstyleName = options.mathstyleName;\n    if (options.columns) {\n      if (options.columns.length === 0) this.colFormat = [{ align: \"l\" }];\n      else this.colFormat = options.columns;\n    }\n    if (!this.colFormat) {\n      this.colFormat = [\n        { align: \"l\" },\n        { align: \"l\" },\n        { align: \"l\" },\n        { align: \"l\" },\n        { align: \"l\" },\n        { align: \"l\" },\n        { align: \"l\" },\n        { align: \"l\" },\n        { align: \"l\" },\n        { align: \"l\" }\n      ];\n    }\n    this.array = normalizeArray(this, array, this.colFormat);\n    if (options.leftDelim) this.leftDelim = options.leftDelim;\n    if (options.rightDelim) this.rightDelim = options.rightDelim;\n    if (options.arraycolsep !== void 0)\n      this.arraycolsep = options.arraycolsep;\n    this.colSeparationType = options.colSeparationType;\n    if (options.arraystretch !== void 0)\n      this.arraystretch = options.arraystretch;\n    this.minColumns = (_a3 = options.minColumns) != null ? _a3 : 1;\n  }\n  static fromJson(json) {\n    return new _ArrayAtom(\n      json.environmentName,\n      json.array,\n      json.rowGaps,\n      json\n    );\n  }\n  toJson() {\n    const result = __spreadProps(__spreadValues({}, super.toJson()), {\n      environmentName: this.environmentName,\n      array: this.array.map(\n        (row) => row.map((col) => col.map((x) => x.toJson()))\n      ),\n      rowGaps: this.rowGaps,\n      columns: this.colFormat,\n      colSeparationType: this.colSeparationType\n    });\n    if (this.arraystretch !== void 0)\n      result.arraystretch = this.arraystretch;\n    if (this.arraycolsep !== void 0) result.arraycolsep = this.arraycolsep;\n    if (this.leftDelim) result.leftDelim = this.leftDelim;\n    if (this.rightDelim) result.rightDelim = this.rightDelim;\n    return result;\n  }\n  branch(cell) {\n    var _a3;\n    if (!isCellBranch(cell)) return void 0;\n    return (_a3 = this.array[cell[0]][cell[1]]) != null ? _a3 : void 0;\n  }\n  createBranch(cell) {\n    var _a3;\n    if (!isCellBranch(cell)) return [];\n    this.isDirty = true;\n    return (_a3 = this.branch(cell)) != null ? _a3 : [];\n  }\n  get rowCount() {\n    return this.array.length;\n  }\n  get colCount() {\n    return this.array[0].length;\n  }\n  get maxColumns() {\n    return this.colFormat.filter((col) => Boolean(col[\"align\"])).length;\n  }\n  removeBranch(name) {\n    if (isNamedBranch(name)) return super.removeBranch(name);\n    const [_first, ...children] = this.branch(name);\n    console.assert(_first.type === \"first\");\n    this.array[name[0]][name[1]] = void 0;\n    children.forEach((x) => {\n      x.parent = void 0;\n      x.parentBranch = void 0;\n    });\n    this.isDirty = true;\n    return children;\n  }\n  get hasChildren() {\n    return this.children.length > 0;\n  }\n  get children() {\n    const result = [];\n    for (const row of this.array) {\n      for (const cell of row) {\n        if (cell) {\n          for (const atom of cell) {\n            result.push(...atom.children);\n            result.push(atom);\n          }\n        }\n      }\n    }\n    return [...result, ...super.children];\n  }\n  render(context) {\n    var _a3, _b3, _c2, _d2, _e, _f;\n    const innerContext = new Context(\n      { parent: context, mathstyle: this.mathstyleName },\n      this.style\n    );\n    const arrayRuleWidth = innerContext.getRegisterAsEm(\"arrayrulewidth\");\n    const arrayColSep = innerContext.getRegisterAsEm(\"arraycolsep\");\n    const doubleRuleSep = innerContext.getRegisterAsEm(\"doublerulesep\");\n    const arraystretch = (_b3 = (_a3 = this.arraystretch) != null ? _a3 : innerContext.getRegisterAsNumber(\"arraystretch\")) != null ? _b3 : 1;\n    let arraycolsep = typeof this.arraycolsep === \"number\" ? this.arraycolsep : arrayColSep;\n    if (this.colSeparationType === \"small\") {\n      const localMultiplier = new Context({\n        parent: context,\n        mathstyle: \"scriptstyle\"\n      }).scalingFactor;\n      arraycolsep = 0.2778 * (localMultiplier / context.scalingFactor);\n    }\n    const arrayskip = arraystretch * BASELINE_SKIP;\n    const arstrutHeight = 0.7 * arrayskip;\n    const arstrutDepth = 0.3 * arrayskip;\n    let totalHeight = 0;\n    const body = [];\n    let nc = 0;\n    const nr = this.array.length;\n    for (let r = 0; r < nr; ++r) {\n      const inrow = this.array[r];\n      nc = Math.max(nc, inrow.length);\n      const cellContext = new Context(\n        { parent: innerContext, mathstyle: this.mathstyleName },\n        this.style\n      );\n      let height = arstrutHeight / cellContext.scalingFactor;\n      let depth = arstrutDepth / cellContext.scalingFactor;\n      const outrow = { cells: [], height: 0, depth: 0, pos: 0 };\n      for (const element of inrow) {\n        const elt = (_c2 = Atom.createBox(cellContext, element, { type: \"ignore\" })) != null ? _c2 : new Box(null, { type: \"ignore\" });\n        depth = Math.max(depth, elt.depth);\n        height = Math.max(height, elt.height);\n        outrow.cells.push(elt);\n      }\n      let gap = (_d2 = convertDimensionToEm(this.rowGaps[r])) != null ? _d2 : 0;\n      if (gap > 0) {\n        gap += arstrutDepth;\n        depth = Math.max(depth, gap);\n        gap = 0;\n      }\n      if (r < nr - 1 && !isMatrixEnvironment(this.environmentName) && this.environmentName !== \"cases\" && this.environmentName !== \"array\")\n        depth += innerContext.getRegisterAsEm(\"jot\");\n      outrow.height = height;\n      outrow.depth = depth;\n      totalHeight += height;\n      outrow.pos = totalHeight;\n      totalHeight += depth + gap;\n      body.push(outrow);\n    }\n    const offset = totalHeight / 2 + AXIS_HEIGHT;\n    const contentCols = [];\n    for (let colIndex = 0; colIndex < nc; colIndex++) {\n      const stack = [];\n      for (const row of body) {\n        const element = row.cells[colIndex];\n        element.depth = row.depth;\n        element.height = row.height;\n        stack.push({ box: element, shift: row.pos - offset });\n      }\n      if (stack.length > 0)\n        contentCols.push(new VBox({ individualShift: stack }));\n    }\n    const cols = [];\n    let previousColContent = false;\n    let previousColRule = false;\n    let currentContentCol = 0;\n    let firstColumn = !this.leftDelim;\n    const { colFormat } = this;\n    for (const colDesc of colFormat) {\n      if (\"align\" in colDesc && currentContentCol >= contentCols.length) {\n        break;\n      }\n      if (\"align\" in colDesc) {\n        if (previousColContent) {\n          cols.push(makeColGap(2 * arraycolsep));\n        } else if (previousColRule || firstColumn) {\n          cols.push(makeColGap(arraycolsep));\n        }\n        cols.push(\n          new Box(contentCols[currentContentCol], {\n            classes: \"col-align-\" + colDesc.align\n          })\n        );\n        currentContentCol++;\n        previousColContent = true;\n        previousColRule = false;\n        firstColumn = false;\n      } else if (\"gap\" in colDesc) {\n        if (typeof colDesc.gap === \"number\") {\n          cols.push(makeColGap(colDesc.gap));\n        } else {\n          const col = makeColOfRepeatingElements(\n            context,\n            body,\n            offset,\n            colDesc.gap\n          );\n          if (col) cols.push(col);\n        }\n        previousColContent = false;\n        previousColRule = false;\n        firstColumn = false;\n      } else if (\"separator\" in colDesc) {\n        const separator = new Box(null, { classes: \"ML__vertical-separator\" });\n        separator.height = totalHeight;\n        separator.setStyle(\"height\", totalHeight, \"em\");\n        separator.setStyle(\n          \"border-right\",\n          `${arrayRuleWidth}em ${colDesc.separator} currentColor`\n        );\n        separator.setStyle(\"vertical-align\", -(totalHeight - offset), \"em\");\n        let gap = 0;\n        if (previousColRule) gap = doubleRuleSep - arrayRuleWidth;\n        else if (previousColContent) gap = arraycolsep - arrayRuleWidth;\n        separator.left = gap;\n        cols.push(separator);\n        previousColContent = false;\n        previousColRule = true;\n        firstColumn = false;\n      }\n    }\n    if (previousColContent && !this.rightDelim) {\n      cols.push(makeColGap(arraycolsep));\n    }\n    const inner = new Box(cols, { classes: \"ML__mtable\" });\n    if ((!this.leftDelim || this.leftDelim === \".\") && (!this.rightDelim || this.rightDelim === \".\")) {\n      if (this.caret) inner.caret = this.caret;\n      return this.bind(context, inner);\n    }\n    const innerHeight = inner.height;\n    const innerDepth = inner.depth;\n    const base = this.bind(\n      context,\n      new Box(\n        [\n          this.bind(\n            context,\n            makeLeftRightDelim(\n              \"open\",\n              (_e = this.leftDelim) != null ? _e : \".\",\n              innerHeight,\n              innerDepth,\n              innerContext,\n              { isSelected: this.isSelected }\n            )\n          ),\n          inner,\n          this.bind(\n            context,\n            makeLeftRightDelim(\n              \"close\",\n              (_f = this.rightDelim) != null ? _f : \".\",\n              innerHeight,\n              innerDepth,\n              innerContext,\n              { isSelected: this.isSelected }\n            )\n          )\n        ],\n        { type: \"ord\" }\n      )\n    );\n    if (!base) return null;\n    base.setStyle(\"display\", \"inline-block\");\n    if (this.caret) base.caret = this.caret;\n    return this.bind(context, this.attachSupsub(context, { base }));\n  }\n  _serialize(options) {\n    var _a3;\n    const result = [];\n    if (this.environmentName === \"lines\") result.push(`{\\\\displaylines`);\n    else result.push(`\\\\begin{${this.environmentName}}`);\n    if (this.environmentName === \"array\") {\n      result.push(\"{\");\n      if (this.colFormat !== void 0) {\n        for (const format of this.colFormat) {\n          if (\"align\" in format && typeof format.align === \"string\")\n            result.push(format.align);\n          else if (\"separator\" in format && format.separator === \"solid\")\n            result.push(\"|\");\n          else if (\"separator\" in format && format.separator === \"dashed\")\n            result.push(\":\");\n        }\n      }\n      result.push(\"}\");\n    }\n    for (let row = 0; row < this.array.length; row++) {\n      for (let col = 0; col < this.array[row].length; col++) {\n        if (col > 0) result.push(\" & \");\n        result.push(Atom.serialize(this.array[row][col], options));\n      }\n      if (row < this.array.length - 1) {\n        const gap = this.rowGaps[row];\n        if (gap == null ? void 0 : gap.dimension)\n          result.push(`\\\\\\\\[${gap.dimension} ${(_a3 = gap.unit) != null ? _a3 : \"pt\"}] `);\n        else result.push(\"\\\\\\\\ \");\n      }\n    }\n    if (this.environmentName === \"lines\") result.push(`}`);\n    else result.push(`\\\\end{${this.environmentName}}`);\n    return joinLatex(result);\n  }\n  forEachCell(callback) {\n    for (let i = 0; i < this.rowCount; i++)\n      for (let j = 0; j < this.colCount; j++) callback(this.array[i][j], i, j);\n  }\n  getCell(row, col) {\n    return this.array[row][col];\n  }\n  setCell(row, column, value) {\n    console.assert(\n      this.type === \"array\" && Array.isArray(this.array) && this.array[row][column] !== void 0\n    );\n    for (const atom of this.array[row][column]) {\n      atom.parent = void 0;\n      atom.parentBranch = void 0;\n    }\n    let atoms = value;\n    if (value.length === 0 || value[0].type !== \"first\")\n      atoms = [new Atom({ type: \"first\", mode: this.mode }), ...value];\n    this.array[row][column] = atoms;\n    for (const atom of atoms) {\n      atom.parent = this;\n      atom.parentBranch = [row, column];\n    }\n    this.isDirty = true;\n  }\n  addRowBefore(row) {\n    console.assert(this.type === \"array\" && Array.isArray(this.array));\n    const newRow = [];\n    for (let i = 0; i < this.colCount; i++)\n      newRow.push(makePlaceholderCell(this));\n    this.array.splice(row, 0, newRow);\n    for (let i = row; i < this.rowCount; i++) {\n      for (let j = 0; j < this.colCount; j++) {\n        const atoms = this.array[i][j];\n        if (atoms) for (const atom of atoms) atom.parentBranch = [i, j];\n      }\n    }\n    this.isDirty = true;\n  }\n  addRowAfter(row) {\n    console.assert(this.type === \"array\" && Array.isArray(this.array));\n    const newRow = [];\n    for (let i = 0; i < this.colCount; i++)\n      newRow.push(makePlaceholderCell(this));\n    this.array.splice(row + 1, 0, newRow);\n    for (let i = row + 1; i < this.rowCount; i++) {\n      for (let j = 0; j < this.colCount; j++) {\n        const atoms = this.array[i][j];\n        if (atoms) for (const atom of atoms) atom.parentBranch = [i, j];\n      }\n    }\n    this.isDirty = true;\n  }\n  removeRow(row) {\n    console.assert(\n      this.type === \"array\" && Array.isArray(this.array) && this.rowCount > row\n    );\n    const deleted = this.array.splice(row, 1);\n    for (const column of deleted) {\n      for (const cell of column) {\n        if (cell) {\n          for (const child of cell) {\n            child.parent = void 0;\n            child.parentBranch = void 0;\n          }\n        }\n      }\n    }\n    for (let i = row; i < this.rowCount; i++) {\n      for (let j = 0; j < this.colCount; j++) {\n        const atoms = this.array[i][j];\n        if (atoms) for (const atom of atoms) atom.parentBranch = [i, j];\n      }\n    }\n    this.isDirty = true;\n  }\n  addColumnBefore(col) {\n    console.assert(this.type === \"array\" && Array.isArray(this.array));\n    for (const row of this.array) row.splice(col, 0, makePlaceholderCell(this));\n    for (let i = 0; i < this.rowCount; i++) {\n      for (let j = col; j < this.colCount; j++) {\n        const atoms = this.array[i][j];\n        if (atoms) for (const atom of atoms) atom.parentBranch = [i, j];\n      }\n    }\n    this.isDirty = true;\n  }\n  addColumnAfter(col) {\n    console.assert(this.type === \"array\" && Array.isArray(this.array));\n    for (const row of this.array)\n      row.splice(col + 1, 0, makePlaceholderCell(this));\n    for (let i = 0; i < this.rowCount; i++) {\n      for (let j = col + 1; j < this.colCount; j++) {\n        const atoms = this.array[i][j];\n        if (atoms) for (const atom of atoms) atom.parentBranch = [i, j];\n      }\n    }\n    this.isDirty = true;\n  }\n  addColumn() {\n    this.addColumnAfter(this.colCount - 1);\n  }\n  removeColumn(col) {\n    console.assert(\n      this.type === \"array\" && Array.isArray(this.array) && this.colCount > col\n    );\n    for (const row of this.array) {\n      const deleted = row.splice(col, 1);\n      for (const cell of deleted) {\n        if (cell) {\n          for (const child of cell) {\n            child.parent = void 0;\n            child.parentBranch = void 0;\n          }\n        }\n      }\n    }\n    for (let i = 0; i < this.rowCount; i++) {\n      for (let j = col; j < this.colCount; j++) {\n        const atoms = this.array[i][j];\n        if (atoms) for (const atom of atoms) atom.parentBranch = [i, j];\n      }\n    }\n    this.isDirty = true;\n  }\n  get cells() {\n    const result = [];\n    for (const row of this.array) {\n      for (const cell of row)\n        if (cell) result.push(cell.filter((x) => x.type !== \"first\"));\n    }\n    return result;\n  }\n};\nfunction makePlaceholderCell(parent) {\n  const first = new Atom({ type: \"first\", mode: parent.mode });\n  first.parent = parent;\n  const placeholder = new PlaceholderAtom();\n  placeholder.parent = parent;\n  return [first, placeholder];\n}\nfunction makeColGap(width) {\n  const result = new Box(null, { classes: \"ML__arraycolsep\" });\n  result.width = width;\n  return result;\n}\nfunction makeColOfRepeatingElements(context, rows, offset, element) {\n  if (!element) return null;\n  const col = [];\n  for (const row of rows) {\n    const cell = Atom.createBox(context, element, { type: \"ignore\" });\n    if (cell) {\n      cell.depth = row.depth;\n      cell.height = row.height;\n      col.push({ box: cell, shift: row.pos - offset });\n    }\n  }\n  return new VBox({ individualShift: col }).wrap(context);\n}\n\n// src/atoms/box.ts\nvar BoxAtom = class _BoxAtom extends Atom {\n  constructor(options) {\n    super({\n      mode: options.mode,\n      command: options.command,\n      style: options.style,\n      body: options.body,\n      type: \"box\"\n    });\n    this.framecolor = options.framecolor;\n    this.backgroundcolor = options.backgroundcolor;\n    this.padding = options.padding;\n    this.offset = options.offset;\n    this.border = options.border;\n  }\n  static fromJson(json) {\n    return new _BoxAtom(json);\n  }\n  toJson() {\n    return __spreadProps(__spreadValues({}, super.toJson()), {\n      framecolor: this.framecolor,\n      backgroundcolor: this.backgroundcolor,\n      padding: this.padding,\n      offset: this.offset,\n      border: this.border\n    });\n  }\n  render(parentContext) {\n    var _a3, _b3, _c2, _d2;\n    const base = Atom.createBox(parentContext, this.body, { type: \"lift\" });\n    if (!base) return null;\n    const offset = parentContext.toEm((_a3 = this.offset) != null ? _a3 : { dimension: 0 });\n    base.depth += offset;\n    base.setStyle(\"display\", \"inline-block\");\n    base.setStyle(\"position\", \"relative\");\n    base.setStyle(\n      \"height\",\n      Math.floor(100 * base.height + base.depth) / 100,\n      \"em\"\n    );\n    base.setStyle(\"vertical-align\", -Math.floor(100 * base.height) / 100, \"em\");\n    const context = new Context({ parent: parentContext }, this.style);\n    const padding2 = context.toEm((_b3 = this.padding) != null ? _b3 : { register: \"fboxsep\" });\n    const box = new Box(null, { classes: \"ML__box\" });\n    box.height = base.height + padding2;\n    box.depth = base.depth + padding2;\n    box.setStyle(\"box-sizing\", \"border-box\");\n    box.setStyle(\"position\", \"absolute\");\n    box.setStyle(\"top\", -padding2 + 0.3, \"em\");\n    box.setStyle(\"left\", 0);\n    box.setStyle(\"height\", box.height + box.depth, \"em\");\n    box.setStyle(\"width\", \"100%\");\n    if (this.backgroundcolor) {\n      box.setStyle(\n        \"background-color\",\n        (_c2 = context.toColor(this.backgroundcolor)) != null ? _c2 : \"transparent\"\n      );\n    }\n    if (this.framecolor) {\n      box.setStyle(\n        \"border\",\n        `${context.getRegisterAsEm(\"fboxrule\", 2)}em solid ${(_d2 = context.toColor(this.framecolor)) != null ? _d2 : \"black\"}`\n      );\n    }\n    if (this.border) box.setStyle(\"border\", this.border);\n    const result = new Box([box, base], { type: \"lift\" });\n    result.setStyle(\"display\", \"inline-block\");\n    result.setStyle(\"position\", \"relative\");\n    result.setStyle(\"line-height\", 0);\n    result.height = base.height + padding2 + (offset > 0 ? offset : 0);\n    result.depth = base.depth + padding2 + (offset < 0 ? -offset : 0);\n    result.setStyle(\"padding-left\", padding2, \"em\");\n    result.setStyle(\"padding-right\", padding2, \"em\");\n    result.setStyle(\n      \"height\",\n      Math.floor(\n        100 * (base.height + base.depth + 2 * padding2 + Math.abs(offset))\n      ) / 100,\n      \"em\"\n    );\n    result.setStyle(\"margin-top\", -padding2, \"em\");\n    result.setStyle(\n      \"top\",\n      Math.floor(100 * (base.depth - base.height + 2 * padding2 - offset)) / 100,\n      \"em\"\n    );\n    result.setStyle(\n      \"vertical-align\",\n      Math.floor(100 * (base.depth + 2 * padding2)) / 100,\n      \"em\"\n    );\n    if (this.caret) result.caret = this.caret;\n    return this.attachSupsub(parentContext, { base: result });\n  }\n  _serialize(options) {\n    if (!options.skipStyles) return super._serialize(options);\n    return joinLatex([this.bodyToLatex(options), this.supsubToLatex(options)]);\n  }\n};\n\n// src/atoms/composition.ts\nvar CompositionAtom = class _CompositionAtom extends Atom {\n  constructor(value, options) {\n    var _a3;\n    super({ type: \"composition\", mode: (_a3 = options == null ? void 0 : options.mode) != null ? _a3 : \"math\", value });\n  }\n  static fromJson(json) {\n    return new _CompositionAtom(json.value, json);\n  }\n  toJson() {\n    return super.toJson();\n  }\n  render(context) {\n    const result = new Box(this.value, {\n      classes: \"ML__composition\",\n      type: \"composition\"\n    });\n    this.bind(context, result);\n    if (this.caret) result.caret = this.caret;\n    return result;\n  }\n  _serialize(_options) {\n    return \"\";\n  }\n};\n\n// src/atoms/error.ts\nvar ErrorAtom = class _ErrorAtom extends Atom {\n  constructor(value) {\n    super({ type: \"error\", value, command: value, mode: \"math\" });\n    this.verbatimLatex = value;\n  }\n  static fromJson(json) {\n    return new _ErrorAtom(json.command);\n  }\n  toJson() {\n    return super.toJson();\n  }\n  render(context) {\n    const result = this.createBox(context, { classes: \"ML__error\" });\n    if (this.caret) result.caret = this.caret;\n    return result;\n  }\n};\n\n// src/atoms/group.ts\nvar GroupAtom = class _GroupAtom extends Atom {\n  constructor(arg, mode) {\n    super({ type: \"group\", mode });\n    this.body = arg;\n    this.boxType = arg.length > 1 ? \"ord\" : \"ignore\";\n    this.skipBoundary = true;\n    this.displayContainsHighlight = false;\n    if (arg && arg.length === 1 && arg[0].command === \",\")\n      this.captureSelection = true;\n  }\n  static fromJson(json) {\n    return new _GroupAtom(json.body, json.mode);\n  }\n  render(context) {\n    const box = Atom.createBox(context, this.body, { type: this.boxType });\n    if (!box) return null;\n    if (this.caret) box.caret = this.caret;\n    return this.bind(context, box);\n  }\n  _serialize(options) {\n    if (!(options.expandMacro || options.skipStyles || options.skipPlaceholders) && typeof this.verbatimLatex === \"string\")\n      return this.verbatimLatex;\n    const def = getDefinition(this.command, this.mode);\n    if (def == null ? void 0 : def.serialize) return def.serialize(this, options);\n    return `{${this.bodyToLatex(options)}}`;\n  }\n};\n\n// src/atoms/leftright.ts\nvar LeftRightAtom = class _LeftRightAtom extends Atom {\n  constructor(variant, body, options) {\n    super({\n      type: \"leftright\",\n      style: options.style,\n      displayContainsHighlight: true\n    });\n    this.variant = variant;\n    this.body = body;\n    this.leftDelim = options.leftDelim;\n    this.rightDelim = options.rightDelim;\n  }\n  static fromJson(json) {\n    var _a3;\n    return new _LeftRightAtom((_a3 = json.variant) != null ? _a3 : \"\", json.body, json);\n  }\n  toJson() {\n    const result = super.toJson();\n    if (this.variant) result.variant = this.variant;\n    if (this.leftDelim) result.leftDelim = this.leftDelim;\n    if (this.rightDelim) result.rightDelim = this.rightDelim;\n    return result;\n  }\n  _serialize(options) {\n    var _a3, _b3;\n    const rightDelim = this.matchingRightDelim();\n    if (this.variant === \"left...right\") {\n      return joinLatex([\n        \"\\\\left\",\n        (_a3 = this.leftDelim) != null ? _a3 : \".\",\n        this.bodyToLatex(options),\n        \"\\\\right\",\n        rightDelim\n      ]);\n    }\n    if (this.variant === \"mleft...mright\") {\n      return joinLatex([\n        \"\\\\mleft\",\n        (_b3 = this.leftDelim) != null ? _b3 : \".\",\n        this.bodyToLatex(options),\n        \"\\\\mright\",\n        rightDelim\n      ]);\n    }\n    return joinLatex([\n      !this.leftDelim || this.leftDelim === \".\" ? \"\" : this.leftDelim,\n      this.bodyToLatex(options),\n      rightDelim\n    ]);\n  }\n  matchingRightDelim() {\n    var _a3, _b3;\n    if (this.rightDelim && this.rightDelim !== \"?\") return this.rightDelim;\n    const leftDelim = (_a3 = this.leftDelim) != null ? _a3 : \".\";\n    return (_b3 = RIGHT_DELIM[leftDelim]) != null ? _b3 : leftDelim;\n  }\n  render(parentContext) {\n    var _a3, _b3;\n    const context = new Context({ parent: parentContext }, this.style);\n    console.assert(this.body !== void 0);\n    const delimContext = new Context(\n      { parent: parentContext, mathstyle: \"textstyle\" },\n      this.style\n    );\n    const inner = (_a3 = Atom.createBox(context, this.body, { type: \"inner\" })) != null ? _a3 : new Box(null, { type: \"inner\" });\n    const innerHeight = inner.height / delimContext.scalingFactor;\n    const innerDepth = inner.depth / delimContext.scalingFactor;\n    const boxes = [];\n    if (this.leftDelim) {\n      boxes.push(\n        this.bind(\n          delimContext,\n          makeLeftRightDelim(\n            \"open\",\n            this.leftDelim,\n            innerHeight,\n            innerDepth,\n            delimContext,\n            {\n              isSelected: this.isSelected,\n              classes: \"ML__open\" + (this.containsCaret ? \" ML__contains-caret\" : \"\"),\n              mode: this.mode,\n              style: this.style\n            }\n          )\n        )\n      );\n    }\n    if (inner) {\n      upgradeMiddle(inner.children, this, context, innerHeight, innerDepth);\n      boxes.push(inner);\n    }\n    if (this.rightDelim) {\n      let classes = this.containsCaret ? \" ML__contains-caret\" : \"\";\n      let delim = this.rightDelim;\n      if (delim === \"?\") {\n        if (context.smartFence) {\n          delim = this.matchingRightDelim();\n          classes += \" ML__smart-fence__close\";\n        } else delim = \".\";\n      }\n      boxes.push(\n        this.bind(\n          delimContext,\n          makeLeftRightDelim(\n            \"close\",\n            delim,\n            innerHeight,\n            innerDepth,\n            delimContext,\n            {\n              isSelected: this.isSelected,\n              classes: classes + \" ML__close\",\n              mode: this.mode,\n              style: this.style\n            }\n          )\n        )\n      );\n    }\n    let tightSpacing = this.variant === \"mleft...mright\";\n    const sibling = this.leftSibling;\n    if (sibling) {\n      if (!tightSpacing && sibling.isFunction) tightSpacing = true;\n      if (!tightSpacing && sibling.type === \"subsup\" && ((_b3 = sibling.leftSibling) == null ? void 0 : _b3.isFunction))\n        tightSpacing = true;\n    }\n    const result = new Box(boxes, {\n      type: tightSpacing ? \"close\" : \"inner\",\n      classes: \"ML__left-right\"\n    });\n    result.setStyle(\"margin-top\", `${-inner.depth}em`);\n    result.setStyle(\"height\", `${inner.height + inner.depth}em`);\n    if (this.caret) result.caret = this.caret;\n    return this.bind(context, result.wrap(context));\n  }\n};\nfunction upgradeMiddle(boxes, atom, context, height, depth) {\n  if (!boxes) return;\n  for (let i = 0; i < boxes.length; i++) {\n    const child = boxes[i];\n    if (child.type === \"middle\") {\n      boxes[i] = atom.bind(\n        context,\n        makeLeftRightDelim(\"inner\", child.value, height, depth, context, {\n          isSelected: atom.isSelected\n        })\n      );\n      boxes[i].caret = child.caret;\n      boxes[i].isSelected = child.isSelected;\n      boxes[i].cssId = child.cssId;\n      boxes[i].htmlData = child.htmlData;\n      boxes[i].htmlStyle = child.htmlStyle;\n      boxes[i].attributes = child.attributes;\n      boxes[i].cssProperties = child.cssProperties;\n    } else if (child.children)\n      upgradeMiddle(child.children, atom, context, height, depth);\n  }\n}\n\n// src/atoms/macro.ts\nvar MacroAtom = class _MacroAtom extends Atom {\n  constructor(macro, options) {\n    var _a3;\n    super({ type: \"macro\", command: macro, style: options.style });\n    this.body = options.body;\n    if (options.captureSelection === void 0) {\n      if (options.args) this.captureSelection = false;\n      else this.captureSelection = true;\n    } else this.captureSelection = options.captureSelection;\n    this.macroArgs = options.args;\n    this.expand = (_a3 = options.expand) != null ? _a3 : false;\n  }\n  static fromJson(json) {\n    return new _MacroAtom(json.command, json);\n  }\n  toJson() {\n    const options = super.toJson();\n    if (this.expand) options.expand = true;\n    if (this.captureSelection !== void 0)\n      options.captureSelection = this.captureSelection;\n    if (this.macroArgs) options.args = this.macroArgs;\n    return options;\n  }\n  _serialize(options) {\n    var _a3;\n    return options.expandMacro && this.expand ? this.bodyToLatex(options) : this.command + ((_a3 = this.macroArgs) != null ? _a3 : \"\");\n  }\n  render(context) {\n    const result = Atom.createBox(context, this.body, { type: \"lift\" });\n    if (!result) return null;\n    if (this.caret) result.caret = this.caret;\n    return this.bind(context, result);\n  }\n};\nvar MacroArgumentAtom = class _MacroArgumentAtom extends Atom {\n  constructor() {\n    super({ type: \"macro-argument\" });\n  }\n  static fromJson(_json) {\n    return new _MacroArgumentAtom();\n  }\n  toJson() {\n    const options = super.toJson();\n    return options;\n  }\n  _serialize(_options) {\n    return \"\";\n  }\n  render(_context) {\n    return null;\n  }\n};\n\n// src/atoms/prompt.ts\nvar PromptAtom = class _PromptAtom extends Atom {\n  constructor(placeholderId, correctness, locked = false, body, options) {\n    var _a3;\n    super({\n      type: \"prompt\",\n      mode: (_a3 = options == null ? void 0 : options.mode) != null ? _a3 : \"math\",\n      style: options == null ? void 0 : options.style,\n      command: \"\\\\placeholder\"\n    });\n    this.body = body;\n    this.correctness = correctness;\n    this.placeholderId = placeholderId;\n    this.locked = locked;\n    this.captureSelection = this.locked;\n  }\n  static fromJson(json) {\n    return new _PromptAtom(\n      json.placeholderId,\n      json.correctness,\n      json.locked,\n      json.body,\n      json\n    );\n  }\n  toJson() {\n    const result = super.toJson();\n    if (this.placeholderId) result.placeholderId = this.placeholderId;\n    if (!this.body) delete result.body;\n    if (this.body) {\n      result.body = this.body.filter((x) => x.type !== \"first\").map((x) => x.toJson());\n    }\n    if (this.correctness) result.correctness = this.correctness;\n    result.locked = this.locked;\n    return result;\n  }\n  render(parentContext) {\n    const context = new Context({ parent: parentContext });\n    const fboxsep = context.getRegisterAsEm(\"fboxsep\");\n    const hPadding = fboxsep;\n    const vPadding = fboxsep;\n    const content = Atom.createBox(parentContext, this.body);\n    if (!content) return null;\n    if (!content.height) content.height = context.metrics.xHeight;\n    content.setStyle(\"vertical-align\", -content.height, \"em\");\n    if (this.correctness === \"correct\") {\n      content.setStyle(\n        \"color\",\n        \"var(--correct-color, var(--ML__correct-color))\"\n      );\n    } else if (this.correctness === \"incorrect\") {\n      content.setStyle(\n        \"color\",\n        \"var(--incorrect-color, var(--ML__incorrect-color))\"\n      );\n    }\n    const base = new Box(content, { type: \"ord\" });\n    base.setStyle(\"display\", \"inline-block\");\n    base.setStyle(\"height\", content.height + content.depth, \"em\");\n    base.setStyle(\"vertical-align\", -vPadding, \"em\");\n    let boxClasses = \"ML__prompt \";\n    if (this.locked) {\n      boxClasses += \" ML__lockedPromptBox \";\n    } else boxClasses += \" ML__editablePromptBox \";\n    if (this.correctness === \"correct\") boxClasses += \" ML__correctPromptBox \";\n    else if (this.correctness === \"incorrect\")\n      boxClasses += \" ML__incorrectPromptBox \";\n    if (this.containsCaret) boxClasses += \" ML__focusedPromptBox \";\n    const box = new Box(null, {\n      classes: boxClasses,\n      attributes: { part: \"prompt\" }\n    });\n    box.height = base.height + vPadding;\n    box.depth = base.depth + vPadding;\n    box.width = base.width + 2 * hPadding;\n    box.setStyle(\"position\", \"absolute\");\n    box.setStyle(\n      \"height\",\n      `calc(${base.height + base.depth + 2 * vPadding}em - 2px)`\n    );\n    if (hPadding === 0) box.setStyle(\"width\", \"100%\");\n    if (hPadding !== 0) {\n      box.setStyle(\"width\", `calc(100% + ${2 * hPadding}em)`);\n      box.setStyle(\"top\", fboxsep, \"em\");\n      box.setStyle(\"left\", -hPadding, \"em\");\n    }\n    if (!this.body || this.body.length === 1) {\n      box.width = 3 * hPadding;\n      box.setStyle(\"width\", `calc(100% + ${3 * hPadding}em)`);\n      box.setStyle(\"left\", -1.5 * hPadding, \"em\");\n    }\n    let svg = \"\";\n    if (this.correctness === \"incorrect\") {\n      svg += '<line x1=\"3%\"  y1=\"97%\" x2=\"97%\" y2=\"3%\" stroke-width=\"0.5\" stroke=\"var(--incorrect-color, var(--ML__incorrect-color))\" stroke-linecap=\"round\" />';\n    }\n    if (svg) box.svgOverlay = svg;\n    const result = new Box([box, base], { classes: \"ML__prompt-atom\" });\n    base.setStyle(\"line-height\", 1);\n    result.setStyle(\"position\", \"relative\");\n    result.setStyle(\"display\", \"inline-block\");\n    result.setStyle(\"line-height\", 0);\n    result.height = base.height + vPadding + 0.2;\n    result.depth = base.depth + vPadding;\n    result.left = hPadding;\n    result.right = hPadding;\n    result.setStyle(\"height\", base.height + vPadding, \"em\");\n    result.setStyle(\"top\", base.depth - base.height, \"em\");\n    result.setStyle(\"vertical-align\", base.depth + vPadding, \"em\");\n    result.setStyle(\"margin-left\", 0.5, \"em\");\n    result.setStyle(\"margin-right\", 0.5, \"em\");\n    if (this.caret) result.caret = this.caret;\n    return this.bind(\n      context,\n      this.attachSupsub(parentContext, { base: result })\n    );\n  }\n  _serialize(options) {\n    var _a3;\n    const value = (_a3 = this.bodyToLatex(options)) != null ? _a3 : \"\";\n    if (options.skipPlaceholders) return value;\n    let command = \"\\\\placeholder\";\n    if (this.placeholderId) command += `[${this.placeholderId}]`;\n    if (this.correctness === \"correct\") command += \"[correct]\";\n    else if (this.correctness === \"incorrect\") command += \"[incorrect]\";\n    if (this.locked) command += \"[locked]\";\n    return latexCommand(command, value);\n  }\n};\n\n// src/atoms/subsup.ts\nvar SubsupAtom = class _SubsupAtom extends Atom {\n  constructor(options) {\n    super({ type: \"subsup\", style: options == null ? void 0 : options.style });\n    this.subsupPlacement = \"auto\";\n  }\n  static fromJson(json) {\n    const result = new _SubsupAtom(json);\n    for (const branch of NAMED_BRANCHES)\n      if (json[branch]) result.setChildren(json[branch], branch);\n    return result;\n  }\n  render(context) {\n    var _a3;\n    const phantomCtx = new Context({ parent: context, isPhantom: true });\n    const leftSibling = this.leftSibling;\n    const base = (_a3 = leftSibling.render(phantomCtx)) != null ? _a3 : new Box(null);\n    const phantom = new Box(null);\n    phantom.height = base.height;\n    phantom.depth = base.depth;\n    return this.attachSupsub(context, {\n      base: phantom,\n      isCharacterBox: leftSibling.isCharacterBox(),\n      // Set to 'ignore' so that it is ignored during inter-box spacing\n      // adjustment.\n      type: \"ignore\"\n    });\n  }\n  _serialize(options) {\n    return this.supsubToLatex(options);\n  }\n};\n\n// src/core/parser.ts\nfunction isLiteral(token) {\n  if (!token) return false;\n  return !/^(<$$>|<$>|<space>|<{>|<}>|#[0-9\\?]|\\\\.+)$/.test(token);\n}\nvar Parser = class {\n  /**\n   * @param tokens - An array of tokens generated by the lexer.\n   *\n   * Note: smartFence and registers are usually defined by the GloablContext.\n   * However, in some cases they need to be overridden.\n   *\n   */\n  constructor(tokens, context, options) {\n    // Accumulated errors encountered while parsing\n    this.errors = [];\n    // The current token to be parsed: index in `this.tokens`\n    this.index = 0;\n    // Counter to prevent deadlock. If `end()` is called too many\n    // times (1,000) in a row for the same token, bail.\n    this.endCount = 0;\n    var _a3, _b3, _c2, _d2;\n    options != null ? options : options = {};\n    this.tokens = tokens;\n    this.context = context instanceof Context && !(options == null ? void 0 : options.parseMode) && !options.mathstyle ? context : new Context(\n      { from: context, mathstyle: options.mathstyle },\n      options.style\n    );\n    this.args = (_a3 = options.args) != null ? _a3 : void 0;\n    this.smartFence = this.context.smartFence;\n    this.parsingContext = {\n      parent: void 0,\n      mathlist: [],\n      style: (_b3 = options.style) != null ? _b3 : {},\n      parseMode: (_c2 = options.parseMode) != null ? _c2 : \"math\",\n      mathstyle: (_d2 = options.mathstyle) != null ? _d2 : \"displaystyle\",\n      tabular: false\n    };\n  }\n  beginContext(options) {\n    var _a3, _b3, _c2;\n    const current = this.parsingContext;\n    const newContext = {\n      parent: current,\n      mathlist: [],\n      style: __spreadValues({}, current.style),\n      parseMode: (_a3 = options == null ? void 0 : options.mode) != null ? _a3 : current.parseMode,\n      mathstyle: (_b3 = options == null ? void 0 : options.mathstyle) != null ? _b3 : current.mathstyle,\n      tabular: (_c2 = options == null ? void 0 : options.tabular) != null ? _c2 : false\n    };\n    this.parsingContext = newContext;\n  }\n  endContext() {\n    this.parsingContext = this.parsingContext.parent;\n  }\n  onError(err) {\n    this.errors.push(__spreadValues({\n      before: tokensToString(this.tokens.slice(this.index, this.index + 10)),\n      after: tokensToString(\n        this.tokens.slice(Math.max(0, this.index - 10), this.index)\n      )\n    }, err));\n  }\n  get mathlist() {\n    return this.parsingContext.mathlist;\n  }\n  set mathlist(value) {\n    this.parsingContext.mathlist = value;\n  }\n  get parseMode() {\n    return this.parsingContext.parseMode;\n  }\n  set parseMode(value) {\n    this.parsingContext.parseMode = value;\n  }\n  get tabularMode() {\n    return this.parsingContext.tabular;\n  }\n  get style() {\n    let context = this.parsingContext;\n    while (context) {\n      if (context.style) return __spreadValues({}, context.style);\n      context = context.parent;\n    }\n    return {};\n  }\n  set style(value) {\n    this.parsingContext.style = value;\n  }\n  /**\n   * True if we've reached the end of the token stream\n   */\n  end() {\n    this.endCount++;\n    return this.index >= this.tokens.length || this.endCount > 1e3;\n  }\n  next() {\n    this.index += 1;\n  }\n  get() {\n    this.endCount = 0;\n    return this.index < this.tokens.length ? this.tokens[this.index++] : \"\";\n  }\n  peek() {\n    return this.tokens[this.index];\n  }\n  // If the next token is a Unicode character such as ² or ℂ,\n  // expand it with an equivalent LaTeX command.\n  expandUnicode() {\n    if (!this.peek()) return;\n    if (this.parseMode !== \"math\") return;\n    const latex = codePointToLatex(this.peek());\n    if (latex) this.tokens.splice(this.index, 1, ...tokenize(latex));\n  }\n  /**\n   * @return True if the next token matches the input, and advance\n   */\n  match(input) {\n    if (this.tokens[this.index] === input) {\n      this.index++;\n      return true;\n    }\n    return false;\n  }\n  /**\n   * Return the last atom in the mathlisst that can have a\n   * subscript/superscript attached to it.\n   * If there isn't one, insert a `SubsupAtom` and return it.\n   */\n  lastSubsupAtom() {\n    let atom;\n    if (this.mathlist.length > 0) {\n      atom = this.mathlist[this.mathlist.length - 1];\n      if (atom.type === \"subsup\") return atom;\n      if (atom.subsupPlacement !== void 0) return atom;\n    }\n    atom = new SubsupAtom({ style: this.style });\n    this.mathlist.push(atom);\n    return atom;\n  }\n  /**\n   * @return True if the next token matches the specified regular expression pattern.\n   */\n  hasPattern(pattern) {\n    return pattern.test(this.tokens[this.index]);\n  }\n  hasInfixCommand() {\n    var _a3;\n    const { index } = this;\n    if (index < this.tokens.length && this.tokens[index].startsWith(\"\\\\\")) {\n      const info = getDefinition(this.tokens[index], this.parseMode);\n      if (!info || info.definitionType === \"symbol\") return false;\n      if (info.ifMode && !info.ifMode.includes(this.parseMode)) return false;\n      return (_a3 = info.infix) != null ? _a3 : false;\n    }\n    return false;\n  }\n  matchColumnSeparator() {\n    if (!this.tabularMode) return false;\n    const peek = this.peek();\n    if (peek !== \"&\") return false;\n    this.index++;\n    return true;\n  }\n  matchRowSeparator() {\n    if (!this.tabularMode) return false;\n    const peek = this.peek();\n    if (peek !== \"\\\\\\\\\" && peek !== \"\\\\cr\" && peek !== \"\\\\tabularnewline\")\n      return false;\n    this.index++;\n    return true;\n  }\n  /**\n   * Return the appropriate value for a placeholder, either a default\n   * one, or if a value was provided for #? via args, that value.\n   */\n  placeholder() {\n    var _a3;\n    const placeHolderArg = (_a3 = this.args) == null ? void 0 : _a3.call(this, \"?\");\n    if (!placeHolderArg)\n      return [new PlaceholderAtom({ mode: this.parseMode, style: this.style })];\n    return parseLatex(placeHolderArg, {\n      parseMode: this.parseMode,\n      mathstyle: \"textstyle\"\n    });\n  }\n  skipWhitespace() {\n    while (this.match(\"<space>\")) {\n    }\n  }\n  skipUntilToken(input) {\n    let token = this.tokens[this.index];\n    while (token && token !== input) token = this.tokens[++this.index];\n    if (token === input) this.index++;\n  }\n  skipFiller() {\n    while (this.match(\"\\\\relax\") || this.match(\"<space>\")) {\n    }\n  }\n  /**\n   * Keywords are used to specify dimensions, and for various other\n   * syntactic constructs.\n   *\n   * Unlike commands, they are not case sensitive.\n   *\n   * There are 25 keywords:\n   *\n   * at by bp cc cm dd depth em ex fil fill filll height in minus\n   * mm mu pc plus pt sp spread to true width\n   *\n   * TeX: 8212\n   * @return true if the expected keyword is present\n   */\n  matchKeyword(keyword) {\n    const savedIndex = this.index;\n    let done = this.end();\n    let value = \"\";\n    while (!done) {\n      const token = this.get();\n      if (isLiteral(token)) {\n        value += token;\n        done = this.end() || value.length >= keyword.length;\n      } else done = true;\n    }\n    const hasKeyword = keyword.toUpperCase() === value.toUpperCase();\n    if (!hasKeyword) this.index = savedIndex;\n    return hasKeyword;\n  }\n  /**\n   * Return a sequence of characters as a string.\n   * i.e. 'abcd' returns 'abcd'.\n   * Terminates on the first non-literal token encountered\n   * e.g. '<{>', '<}>' etc...\n   * Will also terminate on character literal ']'\n   */\n  scanString() {\n    let result = \"\";\n    while (!this.end()) {\n      const token = this.peek();\n      if (token === \"]\") return result;\n      if (token === \"<space>\") result += \" \";\n      else if (token.startsWith(\"\\\\\")) {\n        this.onError({ code: \"unexpected-command-in-string\" });\n        result += token.substring(1);\n      } else if (isLiteral(token)) result += token;\n      else {\n        return result;\n      }\n      this.next();\n    }\n    return result;\n  }\n  /**\n   * Return a sequence of characters as a string.\n   * Terminates on a balanced closing bracket\n   * This is used by the `\\ce` command\n   */\n  scanBalancedString() {\n    let result = \"\";\n    let done = this.end();\n    let level = 1;\n    while (!done) {\n      const token = this.get();\n      if (token === \"<space>\") result += \" \";\n      else if (token === \"<{>\") {\n        result += \"{\";\n        level += 1;\n      } else if (token === \"<}>\") {\n        level -= 1;\n        if (level > 0) result += \"}\";\n        else this.index -= 1;\n      } else if (token === \"<$>\") result += \"$\";\n      else if (token === \"<$$>\") result += \"$$\";\n      else result += token;\n      done = level === 0 || this.end();\n    }\n    return result;\n  }\n  /**\n   * Return the literal tokens, as a string, until a matching closing \"}\"\n   * Used when handling macros\n   */\n  scanLiteralGroup() {\n    var _a3;\n    if (!this.match(\"<{>\")) return \"\";\n    let result = \"\";\n    let level = 1;\n    while (level > 0 && !this.end()) {\n      const token = this.get();\n      if (token === \"<}>\") {\n        level -= 1;\n        if (level > 0) result += \"}\";\n      } else if (token === \"<{>\") {\n        level += 1;\n        result += \"{\";\n      } else {\n        if (/\\\\[a-zA-Z]+$/.test(result) && /^[a-zA-Z]/.test(token))\n          result += \" \";\n        result += (_a3 = {\n          \"<space>\": \" \",\n          \"<$$>\": \"$$\",\n          \"<$>\": \"$\"\n        }[token]) != null ? _a3 : token;\n      }\n    }\n    return result;\n  }\n  /**\n   * Return as a number a group of characters representing a\n   * numerical quantity.\n   *\n   * From TeX:8695 (scan_int):\n   * > An integer number can be preceded by any number of spaces and `+' or\n   * > `-' signs. Then comes either a decimal constant (i.e., radix 10), an\n   * > octal constant (i.e., radix 8, preceded by '), a hexadecimal constant\n   * > (radix 16, preceded by \"), an alphabetic constant (preceded by `), or\n   * > an internal variable.\n   */\n  scanNumber(isInteger = true) {\n    var _a3, _b3;\n    let negative = false;\n    let token = this.peek();\n    while (token === \"<space>\" || token === \"+\" || token === \"-\") {\n      this.get();\n      if (token === \"-\") negative = !negative;\n      token = this.peek();\n    }\n    isInteger = Boolean(isInteger);\n    let radix = 10;\n    let digits = /\\d/;\n    if (this.match(\"'\")) {\n      radix = 8;\n      digits = /[0-7]/;\n      isInteger = true;\n    } else if (this.match('\"')) {\n      radix = 16;\n      digits = /[\\dA-F]/;\n      isInteger = true;\n    } else if (this.match(\"x\")) {\n      radix = 16;\n      digits = /[\\dA-Fa-f]/;\n      isInteger = true;\n    } else if (this.match(\"`\")) {\n      token = this.get();\n      if (token) {\n        if (token.length === 2 && token.startsWith(\"\\\\\")) {\n          return {\n            number: (negative ? -1 : 1) * ((_a3 = token.codePointAt(1)) != null ? _a3 : 0),\n            base: \"alpha\"\n          };\n        }\n        return {\n          number: (negative ? -1 : 1) * ((_b3 = token.codePointAt(0)) != null ? _b3 : 0),\n          base: \"alpha\"\n        };\n      }\n      return null;\n    }\n    let value = \"\";\n    while (this.hasPattern(digits)) value += this.get();\n    if (!isInteger && (this.match(\".\") || this.match(\",\"))) {\n      value += \".\";\n      while (this.hasPattern(digits)) value += this.get();\n    }\n    const result = isInteger ? Number.parseInt(value, radix) : Number.parseFloat(value);\n    if (Number.isNaN(result)) return null;\n    return {\n      number: negative ? -result : result,\n      base: radix === 16 ? \"hexadecimal\" : radix === 8 ? \"octal\" : \"decimal\"\n    };\n  }\n  scanRegister() {\n    var _a3;\n    const index = this.index;\n    const number = this.scanNumber(false);\n    this.skipWhitespace();\n    if (this.match(\"\\\\relax\")) return number;\n    let negative = false;\n    if (number === null) {\n      while (true) {\n        const s = this.peek();\n        if (s === \"-\") negative = !negative;\n        else if (s !== \"+\") break;\n        this.next();\n        this.skipWhitespace();\n      }\n    }\n    if (this.match(\"\\\\global\")) {\n      this.skipWhitespace();\n      const register4 = this.get();\n      if (register4.startsWith(\"\\\\\")) {\n        if (number) {\n          return {\n            register: register4,\n            global: true,\n            factor: (negative ? -1 : 1) * number.number\n          };\n        }\n        if (negative) return { register: register4, global: true, factor: -1 };\n        return { register: register4, global: true };\n      }\n      this.index = index;\n      return null;\n    }\n    let register3 = this.get();\n    if (!(register3 == null ? void 0 : register3.startsWith(\"\\\\\"))) {\n      this.index = index;\n      return null;\n    }\n    register3 = register3.substring(1);\n    if (!this.context.registers[register3]) {\n      this.index = index;\n      return null;\n    }\n    if (!negative || number !== null) {\n      return {\n        register: register3,\n        factor: (negative ? -1 : 1) * ((_a3 = number == null ? void 0 : number.number) != null ? _a3 : 1)\n      };\n    }\n    return { register: register3 };\n  }\n  scanValue() {\n    const register3 = this.scanRegister();\n    if (register3) return register3;\n    const index = this.index;\n    const glue = this.scanGlueOrDimen();\n    if (glue && (\"unit\" in glue || \"glue\" in glue && \"unit\" in glue.glue))\n      return glue;\n    this.index = index;\n    const number = this.scanNumber();\n    if (number) return number;\n    if (this.end() || !isLiteral(this.peek())) return null;\n    const s = this.scanString();\n    if (s.length > 0) return { string: s };\n    return null;\n  }\n  /**\n   * Return a dimension\n   *\n   * See TeX:8831\n   */\n  scanDimen() {\n    const value = this.scanNumber(false);\n    if (value === null) return null;\n    const dimension = value.number;\n    this.skipWhitespace();\n    this.matchKeyword(\"true\");\n    this.skipWhitespace();\n    let unit;\n    if (this.matchKeyword(\"pt\")) unit = \"pt\";\n    else if (this.matchKeyword(\"mm\")) unit = \"mm\";\n    else if (this.matchKeyword(\"cm\")) unit = \"cm\";\n    else if (this.matchKeyword(\"ex\")) unit = \"ex\";\n    else if (this.matchKeyword(\"px\")) unit = \"px\";\n    else if (this.matchKeyword(\"em\")) unit = \"em\";\n    else if (this.matchKeyword(\"bp\")) unit = \"bp\";\n    else if (this.matchKeyword(\"dd\")) unit = \"dd\";\n    else if (this.matchKeyword(\"pc\")) unit = \"pc\";\n    else if (this.matchKeyword(\"in\")) unit = \"in\";\n    else if (this.matchKeyword(\"mu\")) unit = \"mu\";\n    return unit ? { dimension, unit } : { dimension };\n  }\n  scanGlueOrDimen() {\n    const dimen = this.scanDimen();\n    if (dimen === null) return null;\n    this.skipWhitespace();\n    if (this.match(\"\\\\relax\")) return dimen;\n    const result = { glue: dimen };\n    if (this.matchKeyword(\"plus\")) {\n      const grow = this.scanDimen();\n      if (grow) result.grow = grow;\n      else return result;\n    }\n    this.skipWhitespace();\n    if (this.match(\"\\\\relax\")) return result;\n    this.skipWhitespace();\n    if (this.matchKeyword(\"minus\")) {\n      const shrink = this.scanDimen();\n      if (shrink) result.shrink = shrink;\n      else return result;\n    }\n    if (!result.grow && !result.shrink) return dimen;\n    return result;\n  }\n  scanColspec() {\n    this.skipWhitespace();\n    const result = [];\n    while (!this.end() && !(this.peek() === \"<}>\" || this.peek() === \"]\")) {\n      const literal = this.get();\n      if (literal === \"c\" || literal === \"r\" || literal === \"l\")\n        result.push({ align: literal });\n      else if (literal === \"|\") result.push({ separator: \"solid\" });\n      else if (literal === \":\") result.push({ separator: \"dashed\" });\n      else if (literal === \"@\") {\n        if (this.match(\"<{>\")) {\n          this.beginContext({ mode: \"math\" });\n          result.push({\n            gap: this.scan((token) => token === \"<}>\")\n          });\n          this.endContext();\n        }\n        if (!this.match(\"<}>\")) this.onError({ code: \"unbalanced-braces\" });\n      }\n    }\n    return result;\n  }\n  /**\n   * Scan a `\\(...\\)` or `\\[...\\]` sequence\n   * @return group for the sequence or null\n   */\n  scanModeSet() {\n    let mathstyle = void 0;\n    if (this.match(\"\\\\(\")) mathstyle = \"textstyle\";\n    if (!mathstyle && this.match(\"\\\\[\")) mathstyle = \"displaystyle\";\n    if (!mathstyle) return null;\n    this.beginContext({ mode: \"math\", mathstyle });\n    const result = this.scan(\n      (token) => token === (mathstyle === \"displaystyle\" ? \"\\\\]\" : \"\\\\)\")\n    );\n    if (!this.match(mathstyle === \"displaystyle\" ? \"\\\\]\" : \"\\\\)\"))\n      this.onError({ code: \"unbalanced-mode-shift\" });\n    this.endContext();\n    return result;\n  }\n  /**\n   * Scan a `$...$` or `$$...$$` sequence\n   */\n  scanModeShift() {\n    let final = \"\";\n    if (this.match(\"<$>\")) final = \"<$>\";\n    if (!final && this.match(\"<$$>\")) final = \"<$$>\";\n    if (!final) return null;\n    this.beginContext({\n      mode: \"math\",\n      mathstyle:  true ? \"textstyle\" : 0\n    });\n    const result = this.scan((token) => token === final);\n    if (!this.match(final)) this.onError({ code: \"unbalanced-mode-shift\" });\n    this.endContext();\n    return result;\n  }\n  /**\n   * Scan a \\begin{env}...\\end{end} sequence\n   */\n  scanEnvironment() {\n    if (!this.match(\"\\\\begin\")) return null;\n    const envName = this.scanArgument(\"string\");\n    if (!envName) return null;\n    const def = getEnvironmentDefinition(envName);\n    if (!def) {\n      this.onError({\n        code: \"unknown-environment\",\n        arg: envName\n      });\n      return null;\n    }\n    const args = [];\n    if (def.params) {\n      for (const parameter of def.params) {\n        if (parameter.isOptional) {\n          args.push(this.scanOptionalArgument(parameter.type));\n        } else {\n          const arg = this.scanArgument(parameter.type);\n          if (!arg) this.onError({ code: \"missing-argument\", arg: envName });\n          args.push(arg);\n        }\n      }\n    }\n    this.beginContext({ tabular: def.tabular });\n    const array = [];\n    const rowGaps = [];\n    let row = [];\n    let done = false;\n    do {\n      if (this.end()) {\n        this.onError({ code: \"unbalanced-environment\", arg: envName });\n        done = true;\n      }\n      if (!done && this.match(\"\\\\end\")) {\n        if (this.scanArgument(\"string\") !== envName) {\n          this.onError({\n            code: \"unbalanced-environment\",\n            arg: envName\n          });\n        }\n        done = true;\n      }\n      if (!done) {\n        if (this.matchColumnSeparator()) {\n          row.push(this.mathlist);\n          this.mathlist = [];\n        } else if (this.matchRowSeparator()) {\n          row.push(this.mathlist);\n          this.mathlist = [];\n          let gap = null;\n          this.skipWhitespace();\n          if (this.match(\"[\")) {\n            gap = this.scanDimen();\n            this.skipWhitespace();\n            this.match(\"]\");\n          }\n          rowGaps.push(gap != null ? gap : { dimension: 0 });\n          array.push(row);\n          row = [];\n        } else {\n          this.mathlist.push(\n            ...this.scan(\n              (token) => [\n                \"<}>\",\n                \"&\",\n                \"\\\\end\",\n                \"\\\\cr\",\n                \"\\\\\\\\\",\n                \"\\\\tabularnewline\"\n              ].includes(token)\n            )\n          );\n        }\n      }\n    } while (!done);\n    row.push(this.mathlist);\n    if (row.length > 0) array.push(row);\n    this.endContext();\n    return def.createAtom(\n      envName,\n      array,\n      rowGaps,\n      args,\n      this.context.maxMatrixCols\n    );\n  }\n  /**\n   * Parse an expression: a literal, or a command and its arguments\n   */\n  scanExpression() {\n    const savedList = this.mathlist;\n    this.mathlist = [];\n    if (this.parseExpression()) {\n      const result = this.mathlist;\n      this.mathlist = savedList;\n      return result;\n    }\n    this.mathlist = savedList;\n    return null;\n  }\n  /**\n   * Parse a sequence until a group end marker, such as\n   * `}`, `\\end`, `&`, etc...\n   *\n   * Returns an array of atoms or an empty array if the sequence\n   * terminates right away.\n   *\n   * @param done - A predicate indicating if a token signals the end of a\n   * group\n   */\n  scan(done) {\n    this.beginContext();\n    if (!done) done = (token) => token === \"<}>\";\n    let infix = \"\";\n    let infixInfo = null;\n    let infixArgs = [];\n    let prefix = null;\n    while (!this.end() && !done(this.peek())) {\n      if (this.hasInfixCommand() && !infix) {\n        infix = this.get();\n        infixInfo = getDefinition(infix, \"math\");\n        if (infixInfo) infixArgs = this.scanArguments(infixInfo)[1];\n        prefix = this.mathlist;\n        this.mathlist = [];\n      } else this.parseExpression();\n    }\n    let result;\n    if (infix) {\n      console.assert(Boolean(infixInfo));\n      infixArgs.unshift(this.mathlist);\n      if (prefix) infixArgs.unshift(prefix);\n      result = [\n        infixInfo.createAtom({\n          command: infix,\n          args: infixArgs,\n          style: this.style,\n          mode: this.parseMode\n        })\n      ];\n    } else result = this.mathlist;\n    this.endContext();\n    return result;\n  }\n  /**\n   * Parse a group enclosed in a pair of braces: `{...}`.\n   *\n   * Return either a group Atom or null if not a group.\n   *\n   * Return a group Atom with an empty body if an empty\n   * group (i.e. `{}`).\n   *\n   * If the group only contains a placeholder, return a placeholder,\n   */\n  scanGroup() {\n    const initialIndex = this.index;\n    if (!this.match(\"<{>\")) return null;\n    const body = this.scan((token) => token === \"<}>\");\n    if (!this.match(\"<}>\")) this.onError({ code: \"unbalanced-braces\" });\n    if (body.length === 1 && body[0].type === \"placeholder\") return body[0];\n    const result = new GroupAtom(body, this.parseMode);\n    result.verbatimLatex = tokensToString(\n      this.tokens.slice(initialIndex, this.index)\n    );\n    return result;\n  }\n  scanSmartFence() {\n    this.skipWhitespace();\n    if (!this.match(\"(\")) return null;\n    this.beginContext();\n    let nestLevel = 1;\n    while (!this.end() && nestLevel !== 0) {\n      if (this.match(\"(\")) nestLevel += 1;\n      if (this.match(\")\")) nestLevel -= 1;\n      if (nestLevel !== 0) this.parseExpression();\n    }\n    const result = new LeftRightAtom(\"\", this.mathlist, {\n      leftDelim: \"(\",\n      rightDelim: nestLevel === 0 ? \")\" : \"?\"\n    });\n    this.endContext();\n    return result;\n  }\n  /**\n   * Scan a delimiter, e.g. '(', '|', '\\vert', '\\ulcorner'\n   *\n   * @return The delimiter (as a character or command) or null\n   */\n  scanDelim() {\n    this.skipWhitespace();\n    const token = this.peek();\n    if (!token) {\n      this.onError({ code: \"unexpected-end-of-string\" });\n      return null;\n    }\n    if (!isLiteral(token) && !token.startsWith(\"\\\\\")) return null;\n    this.next();\n    const info = getDefinition(token, \"math\");\n    if (!info) {\n      this.onError({ code: \"unknown-command\", arg: token });\n      return null;\n    }\n    if (info.definitionType === \"function\" && info.ifMode && !info.ifMode.includes(this.parseMode)) {\n      this.onError({ code: \"unexpected-delimiter\", arg: token });\n      return null;\n    }\n    if (info.definitionType === \"symbol\" && (info.type === \"mopen\" || info.type === \"mclose\"))\n      return token;\n    if (/^(\\.|\\?|\\||<|>|\\\\vert|\\\\Vert|\\\\\\||\\\\surd|\\\\uparrow|\\\\downarrow|\\\\Uparrow|\\\\Downarrow|\\\\updownarrow|\\\\Updownarrow|\\\\mid|\\\\mvert|\\\\mVert)$/.test(\n      token\n    ))\n      return token;\n    this.onError({ code: \"unexpected-delimiter\", arg: token });\n    return null;\n  }\n  /**\n   * Parse a `/left.../right` sequence.\n   *\n   * Note: the `/middle` command can occur multiple times inside a\n   * `/left.../right` sequence, and is handled separately.\n   *\n   * Return either an atom of type `\"leftright\"` or null\n   */\n  scanLeftRight() {\n    var _a3;\n    if (this.match(\"\\\\right\")) {\n      this.onError({ code: \"unbalanced-braces\" });\n      return new ErrorAtom(\"\\\\right\");\n    }\n    if (this.match(\"\\\\mright\")) {\n      this.onError({ code: \"unbalanced-braces\" });\n      return new ErrorAtom(\"\\\\mright\");\n    }\n    let close = \"\\\\right\";\n    if (!this.match(\"\\\\left\")) {\n      if (!this.match(\"\\\\mleft\")) return null;\n      close = \"\\\\mright\";\n    }\n    const leftDelim = this.scanDelim();\n    if (!leftDelim) {\n      this.onError({ code: \"unexpected-delimiter\" });\n      return new ErrorAtom(close === \"\\\\right\" ? \"\\\\left\" : \"\\\\mleft\");\n    }\n    this.beginContext();\n    while (!this.end() && !this.match(close)) this.parseExpression();\n    const body = this.mathlist;\n    this.endContext();\n    const rightDelim = (_a3 = this.scanDelim()) != null ? _a3 : \".\";\n    return new LeftRightAtom(\n      close === \"\\\\right\" ? \"left...right\" : \"mleft...mright\",\n      body,\n      {\n        leftDelim,\n        rightDelim,\n        style: this.style\n      }\n    );\n  }\n  /**\n   * Parse a subscript/superscript: `^` and `_`.\n   *\n   * Modify the last atom accordingly, or create a new 'subsup' carrier.\n   *\n   */\n  parseSupSub() {\n    if (this.parseMode !== \"math\") return false;\n    let token = this.peek();\n    if (token !== \"^\" && token !== \"_\" && token !== \"'\") return false;\n    const target = this.lastSubsupAtom();\n    while (token === \"^\" || token === \"_\" || token === \"'\") {\n      if (this.match(\"'\")) {\n        if (this.match(\"'\")) {\n          target.addChild(\n            new Atom({\n              type: \"mord\",\n              command: \"\\\\doubleprime\",\n              mode: \"math\",\n              value: \"\\u2032\\u2032\"\n              // \"\\u2033\" displays too high\n            }),\n            \"superscript\"\n          );\n        } else {\n          target.addChild(\n            new Atom({\n              type: \"mord\",\n              command: \"\\\\prime\",\n              mode: \"math\",\n              value: \"\\u2032\"\n            }),\n            \"superscript\"\n          );\n        }\n      } else if (this.match(\"^\") || this.match(\"_\")) {\n        target.addChildren(\n          argAtoms(this.scanArgument(\"expression\")),\n          token === \"_\" ? \"subscript\" : \"superscript\"\n        );\n      }\n      token = this.peek();\n    }\n    return true;\n  }\n  /**\n   * Parse a `\\limits` or `\\nolimits` command.\n   *\n   * This will change the placement of limits to be either above or below\n   * (if `\\limits`) or in the superscript/subscript position (if `\\nolimits`).\n   *\n   * This overrides the calculation made for the placement, which is usually\n   * dependent on the displaystyle (`textstyle` prefers `\\nolimits`, while\n   * `displaystyle` prefers `\\limits`).\n   */\n  parseLimits() {\n    if (this.parseMode !== \"math\") return false;\n    const isLimits = this.match(\"\\\\limits\");\n    const isNoLimits = !isLimits && this.match(\"\\\\nolimits\");\n    const isDisplayLimits = !isNoLimits && !isLimits && this.match(\"\\\\displaylimits\");\n    if (!isLimits && !isNoLimits && !isDisplayLimits) return false;\n    const opAtom = this.mathlist.length > 0 ? this.mathlist[this.mathlist.length - 1] : null;\n    if (opAtom === null) return false;\n    opAtom.explicitSubsupPlacement = true;\n    if (isLimits) opAtom.subsupPlacement = \"over-under\";\n    if (isNoLimits) opAtom.subsupPlacement = \"adjacent\";\n    if (isDisplayLimits) opAtom.subsupPlacement = \"auto\";\n    return true;\n  }\n  scanArguments(info) {\n    if (!(info == null ? void 0 : info.params)) return [void 0, []];\n    let deferredArg = void 0;\n    const args = [];\n    let i = info.infix ? 2 : 0;\n    while (i < info.params.length) {\n      const parameter = info.params[i];\n      if (parameter.type === \"rest\") {\n        args.push(\n          this.scan(\n            (token) => [\n              \"<}>\",\n              \"&\",\n              \"\\\\end\",\n              \"\\\\cr\",\n              \"\\\\\\\\\",\n              \"\\\\tabularnewline\",\n              \"\\\\right\"\n            ].includes(token)\n          )\n        );\n      } else if (parameter.isOptional)\n        args.push(this.scanOptionalArgument(parameter.type));\n      else if (parameter.type.endsWith(\"*\")) {\n        deferredArg = parameter.type.slice(0, -1);\n      } else args.push(this.scanArgument(parameter.type));\n      i += 1;\n    }\n    return [deferredArg, args];\n  }\n  /**\n   * This function is similar to `scanSymbolOrCommand` but is is invoked\n   * from a context where commands with arguments are not allowed, specifically\n   * when parsing an unbraced argument, i.e. `\\frac1\\alpha`.\n   *\n   */\n  scanSymbolOrLiteral() {\n    const token = this.peek();\n    if (!token) return null;\n    this.next();\n    let result;\n    if (isLiteral(token)) {\n      const result2 = Mode.createAtom(this.parseMode, token, __spreadValues({}, this.style));\n      return result2 ? [result2] : null;\n    }\n    result = this.scanMacro(token);\n    if (result) return [result];\n    if (token.startsWith(\"\\\\\")) {\n      const def = getDefinition(token, this.parseMode);\n      if (!def) {\n        this.onError({ code: \"unknown-command\", arg: token });\n        return [new ErrorAtom(token)];\n      }\n      if (def.definitionType === \"symbol\") {\n        const style = __spreadValues({}, this.style);\n        if (def.variant) style.variant = def.variant;\n        result = new Atom({\n          type: def.type,\n          command: token,\n          style,\n          value: String.fromCodePoint(def.codepoint),\n          mode: this.parseMode,\n          verbatimLatex: token\n        });\n      } else if (def.applyMode || def.applyStyle || def.infix) {\n        this.onError({ code: \"invalid-command\", arg: token });\n        return [new ErrorAtom(token)];\n      } else if (def.createAtom) {\n        result = def.createAtom({\n          command: token,\n          args: [],\n          style: this.style,\n          mode: this.parseMode\n        });\n      }\n    }\n    return result ? [result] : null;\n  }\n  scanArgument(type) {\n    var _a3;\n    this.skipFiller();\n    const mode = this.parseMode;\n    if (type === \"auto\") type = mode;\n    if (!this.match(\"<{>\")) {\n      if (type === \"string\") return this.scanString();\n      if (type === \"value\") return this.scanValue();\n      if (type === \"delim\") return (_a3 = this.scanDelim()) != null ? _a3 : \".\";\n      if (type === \"expression\") return this.scanExpression();\n      if (type === \"math\") {\n        if (type !== mode) this.beginContext({ mode: \"math\" });\n        const result2 = this.scanSymbolOrLiteral();\n        if (type !== mode) this.endContext();\n        return result2;\n      }\n      if (type === \"text\") {\n        if (type !== mode) this.beginContext({ mode: \"text\" });\n        const result2 = this.scanSymbolOrLiteral();\n        if (type !== mode) this.endContext();\n        return result2;\n      }\n      if (type === \"balanced-string\") return null;\n      if (type === \"rest\") {\n        return this.scan(\n          (token) => [\n            \"<}>\",\n            \"&\",\n            \"\\\\end\",\n            \"\\\\cr\",\n            \"\\\\\\\\\",\n            \"\\\\tabularnewline\",\n            \"\\\\right\"\n          ].includes(token)\n        );\n      }\n      console.assert(false);\n      return null;\n    }\n    if (type === \"text\") {\n      this.beginContext({ mode: \"text\" });\n      do\n        this.mathlist.push(...this.scan());\n      while (!this.match(\"<}>\") && !this.end());\n      const atoms = this.mathlist;\n      this.endContext();\n      return { group: atoms };\n    }\n    if (type === \"math\") {\n      this.beginContext({ mode: \"math\" });\n      do\n        this.mathlist.push(...this.scan());\n      while (!this.match(\"<}>\") && !this.end());\n      const atoms = this.mathlist;\n      this.endContext();\n      return { group: atoms };\n    }\n    let result = null;\n    if (type === \"expression\") {\n      this.beginContext({ mode: \"math\" });\n      do\n        this.mathlist.push(...this.scan());\n      while (!this.match(\"<}>\") && !this.end());\n      const atoms = this.mathlist;\n      this.endContext();\n      return { group: atoms };\n    }\n    if (type === \"string\") result = this.scanString();\n    else if (type === \"balanced-string\") result = this.scanBalancedString();\n    else if (type === \"colspec\") result = this.scanColspec();\n    else if (type === \"value\") result = this.scanValue();\n    this.skipUntilToken(\"<}>\");\n    return result;\n  }\n  scanOptionalArgument(argType) {\n    argType = argType === \"auto\" ? this.parseMode : argType;\n    this.skipFiller();\n    if (!this.match(\"[\")) return null;\n    let result = null;\n    while (!this.end() && !this.match(\"]\")) {\n      if (argType === \"string\") result = this.scanString();\n      else if (argType === \"value\") result = this.scanValue();\n      else if (argType === \"colspec\") result = this.scanColspec();\n      else if (argType === \"bbox\") {\n        const bboxParameter = {};\n        const list = this.scanString().toLowerCase().trim().split(/,(?![^(]*\\)(?:(?:[^(]*\\)){2})*[^\"]*$)/);\n        for (const element of list) {\n          const m = element.match(/^\\s*([\\d.]+)\\s*([a-z]{2})/);\n          if (m) {\n            bboxParameter.padding = {\n              dimension: parseInt(m[1]),\n              unit: m[2]\n            };\n          } else {\n            const m2 = element.match(/^\\s*border\\s*:\\s*(.*)/);\n            if (m2) bboxParameter.border = m2[1];\n            else bboxParameter.backgroundcolor = { string: element };\n          }\n        }\n        result = bboxParameter;\n      } else if (argType === \"math\") {\n        this.beginContext({ mode: \"math\" });\n        result = this.mathlist.concat(this.scan((token) => token === \"]\"));\n        this.endContext();\n      }\n    }\n    return result;\n  }\n  /** Parse a symbol or a command and its arguments\n   * See also `scanSymbolOrLiteral` which is invoked from a context where\n   * commands with arguments are not allowed, specifically when parsing an\n   * unbraced argument, i.e. `\\frac1\\alpha`.\n   */\n  scanSymbolOrCommand(command) {\n    var _a3, _b3, _c2;\n    if (command === \"\\\\placeholder\") {\n      const id = this.scanOptionalArgument(\"string\");\n      const defaultValue = this.scanOptionalArgument(\"math\");\n      const defaultAsString = Atom.serialize(defaultValue, {\n        defaultMode: \"math\"\n      });\n      let defaultAtoms = [];\n      let correctness;\n      if (!correctness && defaultAsString === \"correct\")\n        correctness = \"correct\";\n      else if (!correctness && defaultAsString === \"incorrect\")\n        correctness = \"incorrect\";\n      else if (defaultAsString !== \"\") defaultAtoms = defaultValue;\n      const locked = this.scanOptionalArgument(\"string\") === \"locked\";\n      const value = this.scanArgument(\"auto\");\n      let body;\n      if (value && Array.isArray(value) && value.length > 0) body = value;\n      else if (value && typeof value === \"object\" && \"group\" in value)\n        body = value.group;\n      else body = defaultAtoms;\n      if (id) {\n        return [\n          new PromptAtom(id, correctness, locked, body != null ? body : defaultAtoms, {\n            mode: this.parseMode,\n            style: this.style\n          })\n        ];\n      }\n      return [new PlaceholderAtom({ mode: this.parseMode, style: this.style })];\n    }\n    if (command === \"\\\\renewcommand\" || command === \"\\\\newcommand\" || command === \"\\\\providecommand\" || command === \"\\\\def\") {\n      const index = this.index;\n      const cmd = this.scanLiteralGroup() || this.next();\n      if (!cmd) return null;\n      if (this.context.registers[cmd.substring(1)]) {\n        const value = this.scanArgument(\"string\");\n        if (value !== null) this.context.registers[cmd.substring(1)] = value;\n        const verbatimLatex = joinLatex([\n          command,\n          tokensToString(this.tokens.slice(index, this.index))\n        ]);\n        return [new Atom({ type: \"text\", value: \"\", verbatimLatex })];\n      }\n    }\n    let result = this.scanMacro(command);\n    if (result) return [result];\n    const info = getDefinition(command, this.parseMode);\n    if (!info) {\n      if (this.parseMode === \"text\") {\n        if (/[a-zA-Z]/.test((_a3 = this.peek()) != null ? _a3 : \"\")) {\n          command += \" \";\n        }\n        return [...command].map(\n          (c) => new Atom({\n            type: \"text\",\n            value: c,\n            mode: \"text\",\n            style: this.style\n          })\n        );\n      }\n      this.onError({ code: \"unknown-command\", arg: command });\n      return [new ErrorAtom(command)];\n    }\n    const initialIndex = this.index;\n    if (info.definitionType === \"symbol\") {\n      const style = __spreadValues({}, this.style);\n      if (info.variant) style.variant = info.variant;\n      result = new Atom({\n        type: info.type,\n        command,\n        style,\n        value: String.fromCodePoint(info.codepoint),\n        mode: this.parseMode\n      });\n    } else {\n      if (info.ifMode && !info.ifMode.includes(this.parseMode)) {\n        return [];\n      }\n      const savedMode = this.parseMode;\n      if (info.applyMode) this.parseMode = info.applyMode;\n      let deferredArg = void 0;\n      let args = [];\n      if (info.parse) args = info.parse(this);\n      else [deferredArg, args] = this.scanArguments(info);\n      this.parseMode = savedMode;\n      if (info.applyMode && !info.applyStyle && !info.createAtom)\n        return argAtoms(args[0]);\n      if (info.infix) {\n        this.onError({\n          code: \"too-many-infix-commands\",\n          arg: command\n        });\n        return null;\n      }\n      if (typeof info.createAtom === \"function\") {\n        result = info.createAtom({\n          command,\n          args,\n          style: this.style,\n          mode: this.parseMode\n        });\n        if (deferredArg)\n          result.body = argAtoms(this.scanArgument(deferredArg));\n      } else if (typeof info.applyStyle === \"function\") {\n        const style = info.applyStyle(this.style, command, args, this.context);\n        const savedMode2 = this.parseMode;\n        if (info.applyMode) this.parseMode = info.applyMode;\n        if (deferredArg) {\n          const saveStyle = this.style;\n          this.style = style;\n          const atoms = this.scanArgument(deferredArg);\n          this.style = saveStyle;\n          this.parseMode = savedMode2;\n          return argAtoms(atoms);\n        }\n        this.style = style;\n      } else {\n        result = new Atom({\n          type: \"mord\",\n          command: (_b3 = info.command) != null ? _b3 : command,\n          style: __spreadValues({}, this.style),\n          value: command,\n          mode: (_c2 = info.applyMode) != null ? _c2 : this.parseMode\n        });\n      }\n    }\n    if (!result) return null;\n    if (result instanceof Atom && result.verbatimLatex === void 0 && !/^\\\\(llap|rlap|class|cssId|htmlData)$/.test(command)) {\n      const verbatim = joinLatex([\n        command,\n        tokensToString(this.tokens.slice(initialIndex, this.index))\n      ]);\n      if (verbatim) result.verbatimLatex = verbatim;\n    }\n    if (result.verbatimLatex === null) result.verbatimLatex = void 0;\n    if (result.isFunction && this.smartFence) {\n      const smartFence = this.scanSmartFence();\n      if (smartFence) return [result, smartFence];\n    }\n    return [result];\n  }\n  scanSymbolCommandOrLiteral() {\n    this.expandUnicode();\n    const token = this.get();\n    if (!token) return null;\n    if (isLiteral(token)) {\n      const result = Mode.createAtom(this.parseMode, token, __spreadValues({}, this.style));\n      if (!result) return null;\n      if (result.isFunction && this.smartFence) {\n        const smartFence = this.scanSmartFence();\n        if (smartFence) return [result, smartFence];\n      }\n      return [result];\n    }\n    if (token.startsWith(\"\\\\\")) return this.scanSymbolOrCommand(token);\n    if (token === \"<space>\") {\n      if (this.parseMode === \"text\")\n        return [new TextAtom(\" \", \" \", this.style)];\n      return null;\n    }\n    if (token === \"<}>\") this.onError({ latex: \"\", code: \"unbalanced-braces\" });\n    else {\n      this.onError({\n        latex: \"\",\n        code: \"unexpected-token\",\n        arg: token\n      });\n    }\n    return null;\n  }\n  /**\n   * Scan the macro name and its arguments and return a macro atom\n   */\n  scanMacro(macro) {\n    var _a3;\n    const def = this.context.getMacro(macro);\n    if (!def) return null;\n    const initialIndex = this.index;\n    const argCount = def.args;\n    const args = { \"?\": (_a3 = this.args) == null ? void 0 : _a3.call(this, \"?\") };\n    for (let i = 1; i <= argCount; i++) {\n      let arg = this.scanLiteralGroup();\n      if (!arg) {\n        const index = this.index;\n        this.scanExpression();\n        arg = tokensToString(this.tokens.slice(index, this.index));\n      }\n      args[i] = arg;\n    }\n    return new MacroAtom(macro, {\n      expand: def.expand,\n      captureSelection: def.captureSelection,\n      args: initialIndex === this.index ? null : tokensToString(this.tokens.slice(initialIndex, this.index)),\n      style: this.parsingContext.style,\n      body: parseLatex(def.def, {\n        context: this.context,\n        parseMode: this.parseMode,\n        args: (arg) => args[arg],\n        mathstyle: this.parsingContext.mathstyle,\n        style: this.parsingContext.style\n      })\n    });\n  }\n  /**\n   * Make an atom for the current token or token group and\n   * add it to the parser's mathlist.\n   * If the token is a command with arguments, will also parse the\n   * arguments.\n   */\n  parseExpression() {\n    var _a3, _b3, _c2, _d2;\n    let result = (_d2 = (_c2 = (_b3 = (_a3 = this.scanEnvironment()) != null ? _a3 : this.scanModeShift()) != null ? _b3 : this.scanModeSet()) != null ? _c2 : this.scanGroup()) != null ? _d2 : this.scanLeftRight();\n    if (result === null) {\n      if (this.parseSupSub()) return true;\n      if (this.parseLimits()) return true;\n      result = this.scanSymbolCommandOrLiteral();\n    }\n    if (!result) return false;\n    if (isArray(result)) this.mathlist.push(...result);\n    else this.mathlist.push(result);\n    return true;\n  }\n};\nfunction parseLatex(s, options) {\n  var _a3, _b3, _c2, _d2;\n  const args = (_a3 = options == null ? void 0 : options.args) != null ? _a3 : void 0;\n  const parser = new Parser(tokenize(s, args), options == null ? void 0 : options.context, {\n    args,\n    mathstyle: (_b3 = options == null ? void 0 : options.mathstyle) != null ? _b3 : \"displaystyle\",\n    parseMode: (_c2 = options == null ? void 0 : options.parseMode) != null ? _c2 : \"math\",\n    style: (_d2 = options == null ? void 0 : options.style) != null ? _d2 : {}\n  });\n  const atoms = [];\n  while (!parser.end()) atoms.push(...parser.scan(() => false));\n  return atoms;\n}\nfunction validateLatex(s, options) {\n  var _a3;\n  const parser = new Parser(tokenize(s, null), options == null ? void 0 : options.context, {\n    mathstyle: \"displaystyle\",\n    parseMode: (_a3 = options == null ? void 0 : options.parseMode) != null ? _a3 : \"math\"\n  });\n  while (!parser.end()) parser.scan();\n  return parser.errors;\n}\n\n// src/latex-commands/mhchem.ts\nvar ChemAtom = class _ChemAtom extends Atom {\n  constructor(command, arg) {\n    super({ type: \"chem\" }, { command, mode: \"math\" });\n    const tex = texify.go(\n      mhchemParser.go(arg, command === \"\\\\pu\" ? \"pu\" : \"ce\"),\n      false\n    );\n    this.body = parseLatex(tex);\n    this._verbatimLatex = command + \"{\" + arg + \"}\";\n    this.arg = arg;\n    this.captureSelection = true;\n  }\n  static fromJson(json) {\n    return new _ChemAtom(json.command, json.arg);\n  }\n  // We do not allow resetting the verbatimLatex for 'chem' atoms:\n  // once it is set in the ctor, it is immutable.\n  set verbatimLatex(_latex) {\n  }\n  get verbatimLatex() {\n    return this._verbatimLatex;\n  }\n  toJson() {\n    return __spreadProps(__spreadValues({}, super.toJson()), { arg: this.arg });\n  }\n  render(context) {\n    const box = Atom.createBox(context, this.body, { type: \"inner\" });\n    if (this.caret) box.caret = this.caret;\n    return this.bind(context, box);\n  }\n  _serialize(_options) {\n    console.assert(this.verbatimLatex !== void 0);\n    return this.verbatimLatex;\n  }\n};\ndefineFunction([\"ce\", \"pu\"], \"{chemformula:balanced-string}\", {\n  createAtom: (options) => {\n    var _a3;\n    return new ChemAtom(options.command, (_a3 = options.args[0]) != null ? _a3 : \"\");\n  }\n});\nvar mhchemParser = {\n  //\n  // Parses mchem \\ce syntax\n  //\n  // Call like\n  //   go(\"H2O\");\n  //\n  go: function(input, stateMachine) {\n    if (!input) {\n      return [];\n    }\n    if (stateMachine === void 0) {\n      stateMachine = \"ce\";\n    }\n    var state = \"0\";\n    var buffer = {};\n    buffer[\"parenthesisLevel\"] = 0;\n    input = input.replace(/\\n/g, \" \");\n    input = input.replace(/[\\u2212\\u2013\\u2014\\u2010]/g, \"-\");\n    input = input.replace(/[\\u2026]/g, \"...\");\n    var lastInput;\n    var watchdog = 10;\n    var output = [];\n    while (true) {\n      if (lastInput !== input) {\n        watchdog = 10;\n        lastInput = input;\n      } else {\n        watchdog--;\n      }\n      var machine = mhchemParser.stateMachines[stateMachine];\n      var t = machine.transitions[state] || machine.transitions[\"*\"];\n      iterateTransitions: for (var i = 0; i < t.length; i++) {\n        var matches = mhchemParser.patterns.match_(t[i].pattern, input);\n        if (matches) {\n          var task = t[i].task;\n          for (var iA = 0; iA < task.action_.length; iA++) {\n            var o;\n            if (machine.actions[task.action_[iA].type_]) {\n              o = machine.actions[task.action_[iA].type_](\n                buffer,\n                matches.match_,\n                task.action_[iA].option\n              );\n            } else if (mhchemParser.actions[task.action_[iA].type_]) {\n              o = mhchemParser.actions[task.action_[iA].type_](\n                buffer,\n                matches.match_,\n                task.action_[iA].option\n              );\n            } else {\n              throw [\n                \"MhchemBugA\",\n                \"mhchem bug A. Please report. (\" + task.action_[iA].type_ + \")\"\n              ];\n            }\n            mhchemParser.concatArray(output, o);\n          }\n          state = task.nextState || state;\n          if (input.length > 0) {\n            if (!task.revisit) {\n              input = matches.remainder;\n            }\n            if (!task.toContinue) {\n              break iterateTransitions;\n            }\n          } else {\n            return output;\n          }\n        }\n      }\n      if (watchdog <= 0) {\n        throw [\"MhchemBugU\", \"mhchem bug U. Please report.\"];\n      }\n    }\n  },\n  concatArray: function(a, b) {\n    if (b) {\n      if (Object.prototype.toString.call(b) === \"[object Array]\") {\n        for (var iB = 0; iB < b.length; iB++) {\n          a.push(b[iB]);\n        }\n      } else {\n        a.push(b);\n      }\n    }\n  },\n  patterns: {\n    //\n    // Matching patterns\n    // either regexps or function that return null or {match_:\"a\", remainder:\"bc\"}\n    //\n    patterns: {\n      // property names must not look like integers (\"2\") for correct property traversal order, later on\n      \"empty\": /^$/,\n      \"else\": /^./,\n      \"else2\": /^./,\n      \"space\": /^\\s/,\n      \"space A\": /^\\s(?=[A-Z\\\\$])/,\n      \"space$\": /^\\s$/,\n      \"a-z\": /^[a-z]/,\n      \"x\": /^x/,\n      \"x$\": /^x$/,\n      \"i$\": /^i$/,\n      \"letters\": /^(?:[a-zA-Z\\u03B1-\\u03C9\\u0391-\\u03A9?@]|(?:\\\\(?:alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|psi|omega|Gamma|Delta|Theta|Lambda|Xi|Pi|Sigma|Upsilon|Phi|Psi|Omega)(?:\\s+|\\{\\}|(?![a-zA-Z]))))+/,\n      \"\\\\greek\": /^\\\\(?:alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|psi|omega|Gamma|Delta|Theta|Lambda|Xi|Pi|Sigma|Upsilon|Phi|Psi|Omega)(?:\\s+|\\{\\}|(?![a-zA-Z]))/,\n      \"one lowercase latin letter $\": /^(?:([a-z])(?:$|[^a-zA-Z]))$/,\n      \"$one lowercase latin letter$ $\": /^\\$(?:([a-z])(?:$|[^a-zA-Z]))\\$$/,\n      \"one lowercase greek letter $\": /^(?:\\$?[\\u03B1-\\u03C9]\\$?|\\$?\\\\(?:alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|psi|omega)\\s*\\$?)(?:\\s+|\\{\\}|(?![a-zA-Z]))$/,\n      \"digits\": /^[0-9]+/,\n      \"-9.,9\": /^[+\\-]?(?:[0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\\.[0-9]+))/,\n      \"-9.,9 no missing 0\": /^[+\\-]?[0-9]+(?:[.,][0-9]+)?/,\n      \"(-)(9.,9)(e)(99)\": function(input) {\n        var m = input.match(\n          /^(\\+\\-|\\+\\/\\-|\\+|\\-|\\\\pm\\s?)?([0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\\.[0-9]+))?(\\((?:[0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\\.[0-9]+))\\))?(?:(?:([eE])|\\s*(\\*|x|\\\\times|\\u00D7)\\s*10\\^)([+\\-]?[0-9]+|\\{[+\\-]?[0-9]+\\}))?/\n        );\n        if (m && m[0]) {\n          return { match_: m.slice(1), remainder: input.substr(m[0].length) };\n        }\n        return null;\n      },\n      \"(-)(9)^(-9)\": function(input) {\n        var m = input.match(\n          /^(\\+\\-|\\+\\/\\-|\\+|\\-|\\\\pm\\s?)?([0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\\.[0-9]+)?)\\^([+\\-]?[0-9]+|\\{[+\\-]?[0-9]+\\})/\n        );\n        if (m && m[0]) {\n          return { match_: m.slice(1), remainder: input.substr(m[0].length) };\n        }\n        return null;\n      },\n      \"state of aggregation $\": function(input) {\n        var a = mhchemParser.patterns.findObserveGroups(\n          input,\n          \"\",\n          /^\\([a-z]{1,3}(?=[\\),])/,\n          \")\",\n          \"\"\n        );\n        if (a && a.remainder.match(/^($|[\\s,;\\)\\]\\}])/)) {\n          return a;\n        }\n        var m = input.match(/^(?:\\((?:\\\\ca\\s?)?\\$[amothc]\\$\\))/);\n        if (m) {\n          return { match_: m[0], remainder: input.substr(m[0].length) };\n        }\n        return null;\n      },\n      \"_{(state of aggregation)}$\": /^_\\{(\\([a-z]{1,3}\\))\\}/,\n      \"{[(\": /^(?:\\\\\\{|\\[|\\()/,\n      \")]}\": /^(?:\\)|\\]|\\\\\\})/,\n      \", \": /^[,;]\\s*/,\n      \",\": /^[,;]/,\n      \".\": /^[.]/,\n      \". \": /^([.\\u22C5\\u00B7\\u2022])\\s*/,\n      \"...\": /^\\.\\.\\.(?=$|[^.])/,\n      \"* \": /^([*])\\s*/,\n      \"^{(...)}\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(\n          input,\n          \"^{\",\n          \"\",\n          \"\",\n          \"}\"\n        );\n      },\n      \"^($...$)\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(\n          input,\n          \"^\",\n          \"$\",\n          \"$\",\n          \"\"\n        );\n      },\n      \"^a\": /^\\^([0-9]+|[^\\\\_])/,\n      \"^\\\\x{}{}\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(\n          input,\n          \"^\",\n          /^\\\\[a-zA-Z]+\\{/,\n          \"}\",\n          \"\",\n          \"\",\n          \"{\",\n          \"}\",\n          \"\",\n          true\n        );\n      },\n      \"^\\\\x{}\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(\n          input,\n          \"^\",\n          /^\\\\[a-zA-Z]+\\{/,\n          \"}\",\n          \"\"\n        );\n      },\n      \"^\\\\x\": /^\\^(\\\\[a-zA-Z]+)\\s*/,\n      \"^(-1)\": /^\\^(-?\\d+)/,\n      \"'\": /^'/,\n      \"_{(...)}\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(\n          input,\n          \"_{\",\n          \"\",\n          \"\",\n          \"}\"\n        );\n      },\n      \"_($...$)\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(\n          input,\n          \"_\",\n          \"$\",\n          \"$\",\n          \"\"\n        );\n      },\n      \"_9\": /^_([+\\-]?[0-9]+|[^\\\\])/,\n      \"_\\\\x{}{}\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(\n          input,\n          \"_\",\n          /^\\\\[a-zA-Z]+\\{/,\n          \"}\",\n          \"\",\n          \"\",\n          \"{\",\n          \"}\",\n          \"\",\n          true\n        );\n      },\n      \"_\\\\x{}\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(\n          input,\n          \"_\",\n          /^\\\\[a-zA-Z]+\\{/,\n          \"}\",\n          \"\"\n        );\n      },\n      \"_\\\\x\": /^_(\\\\[a-zA-Z]+)\\s*/,\n      \"^_\": /^(?:\\^(?=_)|\\_(?=\\^)|[\\^_]$)/,\n      \"{}\": /^\\{\\}/,\n      \"{...}\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(input, \"\", \"{\", \"}\", \"\");\n      },\n      \"{(...)}\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(input, \"{\", \"\", \"\", \"}\");\n      },\n      \"$...$\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(input, \"\", \"$\", \"$\", \"\");\n      },\n      \"${(...)}$\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(\n          input,\n          \"${\",\n          \"\",\n          \"\",\n          \"}$\"\n        );\n      },\n      \"$(...)$\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(input, \"$\", \"\", \"\", \"$\");\n      },\n      \"=<>\": /^[=<>]/,\n      \"#\": /^[#\\u2261]/,\n      \"+\": /^\\+/,\n      \"-$\": /^-(?=[\\s_},;\\]/]|$|\\([a-z]+\\))/,\n      // -space -, -; -] -/ -$ -state-of-aggregation\n      \"-9\": /^-(?=[0-9])/,\n      \"- orbital overlap\": /^-(?=(?:[spd]|sp)(?:$|[\\s,;\\)\\]\\}]))/,\n      \"-\": /^-/,\n      \"pm-operator\": /^(?:\\\\pm|\\$\\\\pm\\$|\\+-|\\+\\/-)/,\n      \"operator\": /^(?:\\+|(?:[\\-=<>]|<<|>>|\\\\approx|\\$\\\\approx\\$)(?=\\s|$|-?[0-9]))/,\n      \"arrowUpDown\": /^(?:v|\\(v\\)|\\^|\\(\\^\\))(?=$|[\\s,;\\)\\]\\}])/,\n      \"\\\\bond{(...)}\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(\n          input,\n          \"\\\\bond{\",\n          \"\",\n          \"\",\n          \"}\"\n        );\n      },\n      \"->\": /^(?:<->|<-->|->|<-|<=>>|<<=>|<=>|[\\u2192\\u27F6\\u21CC])/,\n      \"CMT\": /^[CMT](?=\\[)/,\n      \"[(...)]\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(input, \"[\", \"\", \"\", \"]\");\n      },\n      \"1st-level escape\": /^(&|\\\\\\\\|\\\\hline)\\s*/,\n      \"\\\\,\": /^(?:\\\\[,\\ ;:])/,\n      // \\\\x - but output no space before\n      \"\\\\x{}{}\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(\n          input,\n          \"\",\n          /^\\\\[a-zA-Z]+\\{/,\n          \"}\",\n          \"\",\n          \"\",\n          \"{\",\n          \"}\",\n          \"\",\n          true\n        );\n      },\n      \"\\\\x{}\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(\n          input,\n          \"\",\n          /^\\\\[a-zA-Z]+\\{/,\n          \"}\",\n          \"\"\n        );\n      },\n      \"\\\\ca\": /^\\\\ca(?:\\s+|(?![a-zA-Z]))/,\n      \"\\\\x\": /^(?:\\\\[a-zA-Z]+\\s*|\\\\[_&{}%])/,\n      \"orbital\": /^(?:[0-9]{1,2}[spdfgh]|[0-9]{0,2}sp)(?=$|[^a-zA-Z])/,\n      // only those with numbers in front, because the others will be formatted correctly anyway\n      \"others\": /^[\\/~|]/,\n      \"\\\\frac{(...)}\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(\n          input,\n          \"\\\\frac{\",\n          \"\",\n          \"\",\n          \"}\",\n          \"{\",\n          \"\",\n          \"\",\n          \"}\"\n        );\n      },\n      \"\\\\overset{(...)}\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(\n          input,\n          \"\\\\overset{\",\n          \"\",\n          \"\",\n          \"}\",\n          \"{\",\n          \"\",\n          \"\",\n          \"}\"\n        );\n      },\n      \"\\\\underset{(...)}\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(\n          input,\n          \"\\\\underset{\",\n          \"\",\n          \"\",\n          \"}\",\n          \"{\",\n          \"\",\n          \"\",\n          \"}\"\n        );\n      },\n      \"\\\\underbrace{(...)}\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(\n          input,\n          \"\\\\underbrace{\",\n          \"\",\n          \"\",\n          \"}_\",\n          \"{\",\n          \"\",\n          \"\",\n          \"}\"\n        );\n      },\n      \"\\\\color{(...)}0\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(\n          input,\n          \"\\\\color{\",\n          \"\",\n          \"\",\n          \"}\"\n        );\n      },\n      \"\\\\color{(...)}{(...)}1\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(\n          input,\n          \"\\\\color{\",\n          \"\",\n          \"\",\n          \"}\",\n          \"{\",\n          \"\",\n          \"\",\n          \"}\"\n        );\n      },\n      \"\\\\color(...){(...)}2\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(\n          input,\n          \"\\\\color\",\n          \"\\\\\",\n          \"\",\n          /^(?=\\{)/,\n          \"{\",\n          \"\",\n          \"\",\n          \"}\"\n        );\n      },\n      \"\\\\ce{(...)}\": function(input) {\n        return mhchemParser.patterns.findObserveGroups(\n          input,\n          \"\\\\ce{\",\n          \"\",\n          \"\",\n          \"}\"\n        );\n      },\n      \"oxidation$\": /^(?:[+-][IVX]+|\\\\pm\\s*0|\\$\\\\pm\\$\\s*0)$/,\n      \"d-oxidation$\": /^(?:[+-]?\\s?[IVX]+|\\\\pm\\s*0|\\$\\\\pm\\$\\s*0)$/,\n      // 0 could be oxidation or charge\n      \"roman numeral\": /^[IVX]+/,\n      \"1/2$\": /^[+\\-]?(?:[0-9]+|\\$[a-z]\\$|[a-z])\\/[0-9]+(?:\\$[a-z]\\$|[a-z])?$/,\n      \"amount\": function(input) {\n        var match;\n        match = input.match(\n          /^(?:(?:(?:\\([+\\-]?[0-9]+\\/[0-9]+\\)|[+\\-]?(?:[0-9]+|\\$[a-z]\\$|[a-z])\\/[0-9]+|[+\\-]?[0-9]+[.,][0-9]+|[+\\-]?\\.[0-9]+|[+\\-]?[0-9]+)(?:[a-z](?=\\s*[A-Z]))?)|[+\\-]?[a-z](?=\\s*[A-Z])|\\+(?!\\s))/\n        );\n        if (match) {\n          return { match_: match[0], remainder: input.substr(match[0].length) };\n        }\n        var a = mhchemParser.patterns.findObserveGroups(\n          input,\n          \"\",\n          \"$\",\n          \"$\",\n          \"\"\n        );\n        if (a) {\n          match = a.match_.match(\n            /^\\$(?:\\(?[+\\-]?(?:[0-9]*[a-z]?[+\\-])?[0-9]*[a-z](?:[+\\-][0-9]*[a-z]?)?\\)?|\\+|-)\\$$/\n          );\n          if (match) {\n            return {\n              match_: match[0],\n              remainder: input.substr(match[0].length)\n            };\n          }\n        }\n        return null;\n      },\n      \"amount2\": function(input) {\n        return this[\"amount\"](input);\n      },\n      \"(KV letters),\": /^(?:[A-Z][a-z]{0,2}|i)(?=,)/,\n      \"formula$\": function(input) {\n        if (input.match(/^\\([a-z]+\\)$/)) {\n          return null;\n        }\n        var match = input.match(\n          /^(?:[a-z]|(?:[0-9\\ \\+\\-\\,\\.\\(\\)]+[a-z])+[0-9\\ \\+\\-\\,\\.\\(\\)]*|(?:[a-z][0-9\\ \\+\\-\\,\\.\\(\\)]+)+[a-z]?)$/\n        );\n        if (match) {\n          return { match_: match[0], remainder: input.substr(match[0].length) };\n        }\n        return null;\n      },\n      \"uprightEntities\": /^(?:pH|pOH|pC|pK|iPr|iBu)(?=$|[^a-zA-Z])/,\n      \"/\": /^\\s*(\\/)\\s*/,\n      \"//\": /^\\s*(\\/\\/)\\s*/,\n      \"*\": /^\\s*[*.]\\s*/\n    },\n    findObserveGroups: function(input, begExcl, begIncl, endIncl, endExcl, beg2Excl, beg2Incl, end2Incl, end2Excl, combine) {\n      var _match = function(input2, pattern) {\n        if (typeof pattern === \"string\") {\n          if (input2.indexOf(pattern) !== 0) {\n            return null;\n          }\n          return pattern;\n        } else {\n          var match2 = input2.match(pattern);\n          if (!match2) {\n            return null;\n          }\n          return match2[0];\n        }\n      };\n      var _findObserveGroups = function(input2, i, endChars) {\n        var braces = 0;\n        while (i < input2.length) {\n          var a = input2.charAt(i);\n          var match2 = _match(input2.substr(i), endChars);\n          if (match2 !== null && braces === 0) {\n            return { endMatchBegin: i, endMatchEnd: i + match2.length };\n          } else if (a === \"{\") {\n            braces++;\n          } else if (a === \"}\") {\n            if (braces === 0) {\n              throw [\n                \"ExtraCloseMissingOpen\",\n                \"Extra close brace or missing open brace\"\n              ];\n            } else {\n              braces--;\n            }\n          }\n          i++;\n        }\n        if (braces > 0) {\n          return null;\n        }\n        return null;\n      };\n      var match = _match(input, begExcl);\n      if (match === null) {\n        return null;\n      }\n      input = input.substr(match.length);\n      match = _match(input, begIncl);\n      if (match === null) {\n        return null;\n      }\n      var e = _findObserveGroups(input, match.length, endIncl || endExcl);\n      if (e === null) {\n        return null;\n      }\n      var match1 = input.substring(\n        0,\n        endIncl ? e.endMatchEnd : e.endMatchBegin\n      );\n      if (!(beg2Excl || beg2Incl)) {\n        return {\n          match_: match1,\n          remainder: input.substr(e.endMatchEnd)\n        };\n      } else {\n        var group2 = this.findObserveGroups(\n          input.substr(e.endMatchEnd),\n          beg2Excl,\n          beg2Incl,\n          end2Incl,\n          end2Excl\n        );\n        if (group2 === null) {\n          return null;\n        }\n        var matchRet = [match1, group2.match_];\n        return {\n          match_: combine ? matchRet.join(\"\") : matchRet,\n          remainder: group2.remainder\n        };\n      }\n    },\n    //\n    // Matching function\n    // e.g. match(\"a\", input) will look for the regexp called \"a\" and see if it matches\n    // returns null or {match_:\"a\", remainder:\"bc\"}\n    //\n    match_: function(m, input) {\n      var pattern = mhchemParser.patterns.patterns[m];\n      if (pattern === void 0) {\n        throw [\"MhchemBugP\", \"mhchem bug P. Please report. (\" + m + \")\"];\n      } else if (typeof pattern === \"function\") {\n        return mhchemParser.patterns.patterns[m](input);\n      } else {\n        var match = input.match(pattern);\n        if (match) {\n          var mm;\n          if (match[2]) {\n            mm = [match[1], match[2]];\n          } else if (match[1]) {\n            mm = match[1];\n          } else {\n            mm = match[0];\n          }\n          return { match_: mm, remainder: input.substr(match[0].length) };\n        }\n        return null;\n      }\n    }\n  },\n  //\n  // Generic state machine actions\n  //\n  actions: {\n    \"a=\": function(buffer, m) {\n      buffer.a = (buffer.a || \"\") + m;\n    },\n    \"b=\": function(buffer, m) {\n      buffer.b = (buffer.b || \"\") + m;\n    },\n    \"p=\": function(buffer, m) {\n      buffer.p = (buffer.p || \"\") + m;\n    },\n    \"o=\": function(buffer, m) {\n      buffer.o = (buffer.o || \"\") + m;\n    },\n    \"q=\": function(buffer, m) {\n      buffer.q = (buffer.q || \"\") + m;\n    },\n    \"d=\": function(buffer, m) {\n      buffer.d = (buffer.d || \"\") + m;\n    },\n    \"rm=\": function(buffer, m) {\n      buffer.rm = (buffer.rm || \"\") + m;\n    },\n    \"text=\": function(buffer, m) {\n      buffer.text_ = (buffer.text_ || \"\") + m;\n    },\n    \"insert\": function(buffer, m, a) {\n      return { type_: a };\n    },\n    \"insert+p1\": function(buffer, m, a) {\n      return { type_: a, p1: m };\n    },\n    \"insert+p1+p2\": function(buffer, m, a) {\n      return { type_: a, p1: m[0], p2: m[1] };\n    },\n    \"copy\": function(buffer, m) {\n      return m;\n    },\n    \"rm\": function(buffer, m) {\n      return { type_: \"rm\", p1: m || \"\" };\n    },\n    \"text\": function(buffer, m) {\n      return mhchemParser.go(m, \"text\");\n    },\n    \"{text}\": function(buffer, m) {\n      var ret = [\"{\"];\n      mhchemParser.concatArray(ret, mhchemParser.go(m, \"text\"));\n      ret.push(\"}\");\n      return ret;\n    },\n    \"tex-math\": function(buffer, m) {\n      return mhchemParser.go(m, \"tex-math\");\n    },\n    \"tex-math tight\": function(buffer, m) {\n      return mhchemParser.go(m, \"tex-math tight\");\n    },\n    \"bond\": function(buffer, m, k) {\n      return { type_: \"bond\", kind_: k || m };\n    },\n    \"color0-output\": function(buffer, m) {\n      return { type_: \"color0\", color: m[0] };\n    },\n    \"ce\": function(buffer, m) {\n      return mhchemParser.go(m);\n    },\n    \"1/2\": function(buffer, m) {\n      var ret = [];\n      if (m.match(/^[+\\-]/)) {\n        ret.push(m.substr(0, 1));\n        m = m.substr(1);\n      }\n      var n = m.match(/^([0-9]+|\\$[a-z]\\$|[a-z])\\/([0-9]+)(\\$[a-z]\\$|[a-z])?$/);\n      n[1] = n[1].replace(/\\$/g, \"\");\n      ret.push({ type_: \"frac\", p1: n[1], p2: n[2] });\n      if (n[3]) {\n        n[3] = n[3].replace(/\\$/g, \"\");\n        ret.push({ type_: \"tex-math\", p1: n[3] });\n      }\n      return ret;\n    },\n    \"9,9\": function(buffer, m) {\n      return mhchemParser.go(m, \"9,9\");\n    }\n  },\n  //\n  // createTransitions\n  // convert  { 'letter': { 'state': { action_: 'output' } } }  to  { 'state' => [ { pattern: 'letter', task: { action_: [{type_: 'output'}] } } ] }\n  // with expansion of 'a|b' to 'a' and 'b' (at 2 places)\n  //\n  createTransitions: function(o) {\n    var pattern, state;\n    var stateArray;\n    var i;\n    var transitions = {};\n    for (pattern in o) {\n      for (state in o[pattern]) {\n        stateArray = state.split(\"|\");\n        o[pattern][state].stateArray = stateArray;\n        for (i = 0; i < stateArray.length; i++) {\n          transitions[stateArray[i]] = [];\n        }\n      }\n    }\n    for (pattern in o) {\n      for (state in o[pattern]) {\n        stateArray = o[pattern][state].stateArray || [];\n        for (i = 0; i < stateArray.length; i++) {\n          var p = o[pattern][state];\n          if (p.action_) {\n            p.action_ = [].concat(p.action_);\n            for (var k = 0; k < p.action_.length; k++) {\n              if (typeof p.action_[k] === \"string\") {\n                p.action_[k] = { type_: p.action_[k] };\n              }\n            }\n          } else {\n            p.action_ = [];\n          }\n          var patternArray = pattern.split(\"|\");\n          for (var j = 0; j < patternArray.length; j++) {\n            if (stateArray[i] === \"*\") {\n              for (var t in transitions) {\n                transitions[t].push({ pattern: patternArray[j], task: p });\n              }\n            } else {\n              transitions[stateArray[i]].push({\n                pattern: patternArray[j],\n                task: p\n              });\n            }\n          }\n        }\n      }\n    }\n    return transitions;\n  },\n  stateMachines: {}\n};\nmhchemParser.stateMachines = {\n  //\n  // \\ce state machines\n  //\n  //#region ce\n  \"ce\": {\n    // main parser\n    transitions: mhchemParser.createTransitions({\n      \"empty\": {\n        \"*\": { action_: \"output\" }\n      },\n      \"else\": {\n        \"0|1|2\": {\n          action_: \"beginsWithBond=false\",\n          revisit: true,\n          toContinue: true\n        }\n      },\n      \"oxidation$\": {\n        \"0\": { action_: \"oxidation-output\" }\n      },\n      \"CMT\": {\n        r: { action_: \"rdt=\", nextState: \"rt\" },\n        rd: { action_: \"rqt=\", nextState: \"rdt\" }\n      },\n      \"arrowUpDown\": {\n        \"0|1|2|as\": {\n          action_: [\"sb=false\", \"output\", \"operator\"],\n          nextState: \"1\"\n        }\n      },\n      \"uprightEntities\": {\n        \"0|1|2\": { action_: [\"o=\", \"output\"], nextState: \"1\" }\n      },\n      \"orbital\": {\n        \"0|1|2|3\": { action_: \"o=\", nextState: \"o\" }\n      },\n      \"->\": {\n        \"0|1|2|3\": { action_: \"r=\", nextState: \"r\" },\n        \"a|as\": { action_: [\"output\", \"r=\"], nextState: \"r\" },\n        \"*\": { action_: [\"output\", \"r=\"], nextState: \"r\" }\n      },\n      \"+\": {\n        \"o\": { action_: \"d= kv\", nextState: \"d\" },\n        \"d|D\": { action_: \"d=\", nextState: \"d\" },\n        \"q\": { action_: \"d=\", nextState: \"qd\" },\n        \"qd|qD\": { action_: \"d=\", nextState: \"qd\" },\n        \"dq\": { action_: [\"output\", \"d=\"], nextState: \"d\" },\n        \"3\": { action_: [\"sb=false\", \"output\", \"operator\"], nextState: \"0\" }\n      },\n      \"amount\": {\n        \"0|2\": { action_: \"a=\", nextState: \"a\" }\n      },\n      \"pm-operator\": {\n        \"0|1|2|a|as\": {\n          action_: [\n            \"sb=false\",\n            \"output\",\n            { type_: \"operator\", option: \"\\\\pm\" }\n          ],\n          nextState: \"0\"\n        }\n      },\n      \"operator\": {\n        \"0|1|2|a|as\": {\n          action_: [\"sb=false\", \"output\", \"operator\"],\n          nextState: \"0\"\n        }\n      },\n      \"-$\": {\n        \"o|q\": { action_: [\"charge or bond\", \"output\"], nextState: \"qd\" },\n        \"d\": { action_: \"d=\", nextState: \"d\" },\n        \"D\": {\n          action_: [\"output\", { type_: \"bond\", option: \"-\" }],\n          nextState: \"3\"\n        },\n        \"q\": { action_: \"d=\", nextState: \"qd\" },\n        \"qd\": { action_: \"d=\", nextState: \"qd\" },\n        \"qD|dq\": {\n          action_: [\"output\", { type_: \"bond\", option: \"-\" }],\n          nextState: \"3\"\n        }\n      },\n      \"-9\": {\n        \"3|o\": {\n          action_: [\"output\", { type_: \"insert\", option: \"hyphen\" }],\n          nextState: \"3\"\n        }\n      },\n      \"- orbital overlap\": {\n        o: {\n          action_: [\"output\", { type_: \"insert\", option: \"hyphen\" }],\n          nextState: \"2\"\n        },\n        d: {\n          action_: [\"output\", { type_: \"insert\", option: \"hyphen\" }],\n          nextState: \"2\"\n        }\n      },\n      \"-\": {\n        \"0|1|2\": {\n          action_: [\n            { type_: \"output\", option: 1 },\n            \"beginsWithBond=true\",\n            { type_: \"bond\", option: \"-\" }\n          ],\n          nextState: \"3\"\n        },\n        \"3\": { action_: { type_: \"bond\", option: \"-\" } },\n        \"a\": {\n          action_: [\"output\", { type_: \"insert\", option: \"hyphen\" }],\n          nextState: \"2\"\n        },\n        \"as\": {\n          action_: [\n            { type_: \"output\", option: 2 },\n            { type_: \"bond\", option: \"-\" }\n          ],\n          nextState: \"3\"\n        },\n        \"b\": { action_: \"b=\" },\n        \"o\": {\n          action_: { type_: \"- after o/d\", option: false },\n          nextState: \"2\"\n        },\n        \"q\": {\n          action_: { type_: \"- after o/d\", option: false },\n          nextState: \"2\"\n        },\n        \"d|qd|dq\": {\n          action_: { type_: \"- after o/d\", option: true },\n          nextState: \"2\"\n        },\n        \"D|qD|p\": {\n          action_: [\"output\", { type_: \"bond\", option: \"-\" }],\n          nextState: \"3\"\n        }\n      },\n      \"amount2\": {\n        \"1|3\": { action_: \"a=\", nextState: \"a\" }\n      },\n      \"letters\": {\n        \"0|1|2|3|a|as|b|p|bp|o\": { action_: \"o=\", nextState: \"o\" },\n        \"q|dq\": { action_: [\"output\", \"o=\"], nextState: \"o\" },\n        \"d|D|qd|qD\": { action_: \"o after d\", nextState: \"o\" }\n      },\n      \"digits\": {\n        \"o\": { action_: \"q=\", nextState: \"q\" },\n        \"d|D\": { action_: \"q=\", nextState: \"dq\" },\n        \"q\": { action_: [\"output\", \"o=\"], nextState: \"o\" },\n        \"a\": { action_: \"o=\", nextState: \"o\" }\n      },\n      \"space A\": {\n        \"b|p|bp\": {}\n      },\n      \"space\": {\n        \"a\": { nextState: \"as\" },\n        \"0\": { action_: \"sb=false\" },\n        \"1|2\": { action_: \"sb=true\" },\n        \"r|rt|rd|rdt|rdq\": { action_: \"output\", nextState: \"0\" },\n        \"*\": { action_: [\"output\", \"sb=true\"], nextState: \"1\" }\n      },\n      \"1st-level escape\": {\n        \"1|2\": {\n          action_: [\n            \"output\",\n            { type_: \"insert+p1\", option: \"1st-level escape\" }\n          ]\n        },\n        \"*\": {\n          action_: [\n            \"output\",\n            { type_: \"insert+p1\", option: \"1st-level escape\" }\n          ],\n          nextState: \"0\"\n        }\n      },\n      \"[(...)]\": {\n        \"r|rt\": { action_: \"rd=\", nextState: \"rd\" },\n        \"rd|rdt\": { action_: \"rq=\", nextState: \"rdq\" }\n      },\n      \"...\": {\n        \"o|d|D|dq|qd|qD\": {\n          action_: [\"output\", { type_: \"bond\", option: \"...\" }],\n          nextState: \"3\"\n        },\n        \"*\": {\n          action_: [\n            { type_: \"output\", option: 1 },\n            { type_: \"insert\", option: \"ellipsis\" }\n          ],\n          nextState: \"1\"\n        }\n      },\n      \". |* \": {\n        \"*\": {\n          action_: [\"output\", { type_: \"insert\", option: \"addition compound\" }],\n          nextState: \"1\"\n        }\n      },\n      \"state of aggregation $\": {\n        \"*\": { action_: [\"output\", \"state of aggregation\"], nextState: \"1\" }\n      },\n      \"{[(\": {\n        \"a|as|o\": {\n          action_: [\"o=\", \"output\", \"parenthesisLevel++\"],\n          nextState: \"2\"\n        },\n        \"0|1|2|3\": {\n          action_: [\"o=\", \"output\", \"parenthesisLevel++\"],\n          nextState: \"2\"\n        },\n        \"*\": {\n          action_: [\"output\", \"o=\", \"output\", \"parenthesisLevel++\"],\n          nextState: \"2\"\n        }\n      },\n      \")]}\": {\n        \"0|1|2|3|b|p|bp|o\": {\n          action_: [\"o=\", \"parenthesisLevel--\"],\n          nextState: \"o\"\n        },\n        \"a|as|d|D|q|qd|qD|dq\": {\n          action_: [\"output\", \"o=\", \"parenthesisLevel--\"],\n          nextState: \"o\"\n        }\n      },\n      \", \": {\n        \"*\": { action_: [\"output\", \"comma\"], nextState: \"0\" }\n      },\n      \"^_\": {\n        // ^ and _ without a sensible argument\n        \"*\": {}\n      },\n      \"^{(...)}|^($...$)\": {\n        \"0|1|2|as\": { action_: \"b=\", nextState: \"b\" },\n        \"p\": { action_: \"b=\", nextState: \"bp\" },\n        \"3|o\": { action_: \"d= kv\", nextState: \"D\" },\n        \"q\": { action_: \"d=\", nextState: \"qD\" },\n        \"d|D|qd|qD|dq\": { action_: [\"output\", \"d=\"], nextState: \"D\" }\n      },\n      \"^a|^\\\\x{}{}|^\\\\x{}|^\\\\x|'\": {\n        \"0|1|2|as\": { action_: \"b=\", nextState: \"b\" },\n        \"p\": { action_: \"b=\", nextState: \"bp\" },\n        \"3|o\": { action_: \"d= kv\", nextState: \"d\" },\n        \"q\": { action_: \"d=\", nextState: \"qd\" },\n        \"d|qd|D|qD\": { action_: \"d=\" },\n        \"dq\": { action_: [\"output\", \"d=\"], nextState: \"d\" }\n      },\n      \"_{(state of aggregation)}$\": {\n        \"d|D|q|qd|qD|dq\": { action_: [\"output\", \"q=\"], nextState: \"q\" }\n      },\n      \"_{(...)}|_($...$)|_9|_\\\\x{}{}|_\\\\x{}|_\\\\x\": {\n        \"0|1|2|as\": { action_: \"p=\", nextState: \"p\" },\n        \"b\": { action_: \"p=\", nextState: \"bp\" },\n        \"3|o\": { action_: \"q=\", nextState: \"q\" },\n        \"d|D\": { action_: \"q=\", nextState: \"dq\" },\n        \"q|qd|qD|dq\": { action_: [\"output\", \"q=\"], nextState: \"q\" }\n      },\n      \"=<>\": {\n        \"0|1|2|3|a|as|o|q|d|D|qd|qD|dq\": {\n          action_: [{ type_: \"output\", option: 2 }, \"bond\"],\n          nextState: \"3\"\n        }\n      },\n      \"#\": {\n        \"0|1|2|3|a|as|o\": {\n          action_: [\n            { type_: \"output\", option: 2 },\n            { type_: \"bond\", option: \"#\" }\n          ],\n          nextState: \"3\"\n        }\n      },\n      \"{}\": {\n        \"*\": { action_: { type_: \"output\", option: 1 }, nextState: \"1\" }\n      },\n      \"{...}\": {\n        \"0|1|2|3|a|as|b|p|bp\": { action_: \"o=\", nextState: \"o\" },\n        \"o|d|D|q|qd|qD|dq\": { action_: [\"output\", \"o=\"], nextState: \"o\" }\n      },\n      \"$...$\": {\n        \"a\": { action_: \"a=\" },\n        // 2$n$\n        \"0|1|2|3|as|b|p|bp|o\": { action_: \"o=\", nextState: \"o\" },\n        // not 'amount'\n        \"as|o\": { action_: \"o=\" },\n        \"q|d|D|qd|qD|dq\": { action_: [\"output\", \"o=\"], nextState: \"o\" }\n      },\n      \"\\\\bond{(...)}\": {\n        \"*\": {\n          action_: [{ type_: \"output\", option: 2 }, \"bond\"],\n          nextState: \"3\"\n        }\n      },\n      \"\\\\frac{(...)}\": {\n        \"*\": {\n          action_: [{ type_: \"output\", option: 1 }, \"frac-output\"],\n          nextState: \"3\"\n        }\n      },\n      \"\\\\overset{(...)}\": {\n        \"*\": {\n          action_: [{ type_: \"output\", option: 2 }, \"overset-output\"],\n          nextState: \"3\"\n        }\n      },\n      \"\\\\underset{(...)}\": {\n        \"*\": {\n          action_: [{ type_: \"output\", option: 2 }, \"underset-output\"],\n          nextState: \"3\"\n        }\n      },\n      \"\\\\underbrace{(...)}\": {\n        \"*\": {\n          action_: [{ type_: \"output\", option: 2 }, \"underbrace-output\"],\n          nextState: \"3\"\n        }\n      },\n      \"\\\\color{(...)}{(...)}1|\\\\color(...){(...)}2\": {\n        \"*\": {\n          action_: [{ type_: \"output\", option: 2 }, \"color-output\"],\n          nextState: \"3\"\n        }\n      },\n      \"\\\\color{(...)}0\": {\n        \"*\": { action_: [{ type_: \"output\", option: 2 }, \"color0-output\"] }\n      },\n      \"\\\\ce{(...)}\": {\n        \"*\": {\n          action_: [{ type_: \"output\", option: 2 }, \"ce\"],\n          nextState: \"3\"\n        }\n      },\n      \"\\\\,\": {\n        \"*\": {\n          action_: [{ type_: \"output\", option: 1 }, \"copy\"],\n          nextState: \"1\"\n        }\n      },\n      \"\\\\x{}{}|\\\\x{}|\\\\x\": {\n        \"0|1|2|3|a|as|b|p|bp|o|c0\": {\n          action_: [\"o=\", \"output\"],\n          nextState: \"3\"\n        },\n        \"*\": { action_: [\"output\", \"o=\", \"output\"], nextState: \"3\" }\n      },\n      \"others\": {\n        \"*\": {\n          action_: [{ type_: \"output\", option: 1 }, \"copy\"],\n          nextState: \"3\"\n        }\n      },\n      \"else2\": {\n        \"a\": { action_: \"a to o\", nextState: \"o\", revisit: true },\n        \"as\": { action_: [\"output\", \"sb=true\"], nextState: \"1\", revisit: true },\n        \"r|rt|rd|rdt|rdq\": {\n          action_: [\"output\"],\n          nextState: \"0\",\n          revisit: true\n        },\n        \"*\": { action_: [\"output\", \"copy\"], nextState: \"3\" }\n      }\n    }),\n    actions: {\n      \"o after d\": function(buffer, m) {\n        var ret;\n        if ((buffer.d || \"\").match(/^[0-9]+$/)) {\n          var tmp = buffer.d;\n          buffer.d = void 0;\n          ret = this[\"output\"](buffer);\n          buffer.b = tmp;\n        } else {\n          ret = this[\"output\"](buffer);\n        }\n        mhchemParser.actions[\"o=\"](buffer, m);\n        return ret;\n      },\n      \"d= kv\": function(buffer, m) {\n        buffer.d = m;\n        buffer.dType = \"kv\";\n      },\n      \"charge or bond\": function(buffer, m) {\n        if (buffer[\"beginsWithBond\"]) {\n          var ret = [];\n          mhchemParser.concatArray(ret, this[\"output\"](buffer));\n          mhchemParser.concatArray(\n            ret,\n            mhchemParser.actions[\"bond\"](buffer, m, \"-\")\n          );\n          return ret;\n        } else {\n          buffer.d = m;\n        }\n      },\n      \"- after o/d\": function(buffer, m, isAfterD) {\n        var c1 = mhchemParser.patterns.match_(\"orbital\", buffer.o || \"\");\n        var c2 = mhchemParser.patterns.match_(\n          \"one lowercase greek letter $\",\n          buffer.o || \"\"\n        );\n        var c3 = mhchemParser.patterns.match_(\n          \"one lowercase latin letter $\",\n          buffer.o || \"\"\n        );\n        var c4 = mhchemParser.patterns.match_(\n          \"$one lowercase latin letter$ $\",\n          buffer.o || \"\"\n        );\n        var hyphenFollows = m === \"-\" && (c1 && c1.remainder === \"\" || c2 || c3 || c4);\n        if (hyphenFollows && !buffer.a && !buffer.b && !buffer.p && !buffer.d && !buffer.q && !c1 && c3) {\n          buffer.o = \"$\" + buffer.o + \"$\";\n        }\n        var ret = [];\n        if (hyphenFollows) {\n          mhchemParser.concatArray(ret, this[\"output\"](buffer));\n          ret.push({ type_: \"hyphen\" });\n        } else {\n          c1 = mhchemParser.patterns.match_(\"digits\", buffer.d || \"\");\n          if (isAfterD && c1 && c1.remainder === \"\") {\n            mhchemParser.concatArray(\n              ret,\n              mhchemParser.actions[\"d=\"](buffer, m)\n            );\n            mhchemParser.concatArray(ret, this[\"output\"](buffer));\n          } else {\n            mhchemParser.concatArray(ret, this[\"output\"](buffer));\n            mhchemParser.concatArray(\n              ret,\n              mhchemParser.actions[\"bond\"](buffer, m, \"-\")\n            );\n          }\n        }\n        return ret;\n      },\n      \"a to o\": function(buffer) {\n        buffer.o = buffer.a;\n        buffer.a = void 0;\n      },\n      \"sb=true\": function(buffer) {\n        buffer.sb = true;\n      },\n      \"sb=false\": function(buffer) {\n        buffer.sb = false;\n      },\n      \"beginsWithBond=true\": function(buffer) {\n        buffer[\"beginsWithBond\"] = true;\n      },\n      \"beginsWithBond=false\": function(buffer) {\n        buffer[\"beginsWithBond\"] = false;\n      },\n      \"parenthesisLevel++\": function(buffer) {\n        buffer[\"parenthesisLevel\"]++;\n      },\n      \"parenthesisLevel--\": function(buffer) {\n        buffer[\"parenthesisLevel\"]--;\n      },\n      \"state of aggregation\": function(buffer, m) {\n        return { type_: \"state of aggregation\", p1: mhchemParser.go(m, \"o\") };\n      },\n      \"comma\": function(buffer, m) {\n        var a = m.replace(/\\s*$/, \"\");\n        var withSpace = a !== m;\n        if (withSpace && buffer[\"parenthesisLevel\"] === 0) {\n          return { type_: \"comma enumeration L\", p1: a };\n        } else {\n          return { type_: \"comma enumeration M\", p1: a };\n        }\n      },\n      \"output\": function(buffer, m, entityFollows) {\n        var ret;\n        if (!buffer.r) {\n          ret = [];\n          if (!buffer.a && !buffer.b && !buffer.p && !buffer.o && !buffer.q && !buffer.d && !entityFollows) {\n          } else {\n            if (buffer.sb) {\n              ret.push({ type_: \"entitySkip\" });\n            }\n            if (!buffer.o && !buffer.q && !buffer.d && !buffer.b && !buffer.p && entityFollows !== 2) {\n              buffer.o = buffer.a;\n              buffer.a = void 0;\n            } else if (!buffer.o && !buffer.q && !buffer.d && (buffer.b || buffer.p)) {\n              buffer.o = buffer.a;\n              buffer.d = buffer.b;\n              buffer.q = buffer.p;\n              buffer.a = buffer.b = buffer.p = void 0;\n            } else {\n              if (buffer.o && buffer.dType === \"kv\" && mhchemParser.patterns.match_(\"d-oxidation$\", buffer.d || \"\")) {\n                buffer.dType = \"oxidation\";\n              } else if (buffer.o && buffer.dType === \"kv\" && !buffer.q) {\n                buffer.dType = void 0;\n              }\n            }\n            ret.push({\n              type_: \"chemfive\",\n              a: mhchemParser.go(buffer.a, \"a\"),\n              b: mhchemParser.go(buffer.b, \"bd\"),\n              p: mhchemParser.go(buffer.p, \"pq\"),\n              o: mhchemParser.go(buffer.o, \"o\"),\n              q: mhchemParser.go(buffer.q, \"pq\"),\n              d: mhchemParser.go(\n                buffer.d,\n                buffer.dType === \"oxidation\" ? \"oxidation\" : \"bd\"\n              ),\n              dType: buffer.dType\n            });\n          }\n        } else {\n          var rd;\n          if (buffer.rdt === \"M\") {\n            rd = mhchemParser.go(buffer.rd, \"tex-math\");\n          } else if (buffer.rdt === \"T\") {\n            rd = [{ type_: \"text\", p1: buffer.rd || \"\" }];\n          } else {\n            rd = mhchemParser.go(buffer.rd);\n          }\n          var rq;\n          if (buffer.rqt === \"M\") {\n            rq = mhchemParser.go(buffer.rq, \"tex-math\");\n          } else if (buffer.rqt === \"T\") {\n            rq = [{ type_: \"text\", p1: buffer.rq || \"\" }];\n          } else {\n            rq = mhchemParser.go(buffer.rq);\n          }\n          ret = {\n            type_: \"arrow\",\n            r: buffer.r,\n            rd,\n            rq\n          };\n        }\n        for (var p in buffer) {\n          if (p !== \"parenthesisLevel\" && p !== \"beginsWithBond\") {\n            delete buffer[p];\n          }\n        }\n        return ret;\n      },\n      \"oxidation-output\": function(buffer, m) {\n        var ret = [\"{\"];\n        mhchemParser.concatArray(ret, mhchemParser.go(m, \"oxidation\"));\n        ret.push(\"}\");\n        return ret;\n      },\n      \"frac-output\": function(buffer, m) {\n        return {\n          type_: \"frac-ce\",\n          p1: mhchemParser.go(m[0]),\n          p2: mhchemParser.go(m[1])\n        };\n      },\n      \"overset-output\": function(buffer, m) {\n        return {\n          type_: \"overset\",\n          p1: mhchemParser.go(m[0]),\n          p2: mhchemParser.go(m[1])\n        };\n      },\n      \"underset-output\": function(buffer, m) {\n        return {\n          type_: \"underset\",\n          p1: mhchemParser.go(m[0]),\n          p2: mhchemParser.go(m[1])\n        };\n      },\n      \"underbrace-output\": function(buffer, m) {\n        return {\n          type_: \"underbrace\",\n          p1: mhchemParser.go(m[0]),\n          p2: mhchemParser.go(m[1])\n        };\n      },\n      \"color-output\": function(buffer, m) {\n        return { type_: \"color\", color1: m[0], color2: mhchemParser.go(m[1]) };\n      },\n      \"r=\": function(buffer, m) {\n        buffer.r = m;\n      },\n      \"rdt=\": function(buffer, m) {\n        buffer.rdt = m;\n      },\n      \"rd=\": function(buffer, m) {\n        buffer.rd = m;\n      },\n      \"rqt=\": function(buffer, m) {\n        buffer.rqt = m;\n      },\n      \"rq=\": function(buffer, m) {\n        buffer.rq = m;\n      },\n      \"operator\": function(buffer, m, p1) {\n        return { type_: \"operator\", kind_: p1 || m };\n      }\n    }\n  },\n  \"a\": {\n    transitions: mhchemParser.createTransitions({\n      \"empty\": {\n        \"*\": {}\n      },\n      \"1/2$\": {\n        \"0\": { action_: \"1/2\" }\n      },\n      \"else\": {\n        \"0\": { nextState: \"1\", revisit: true }\n      },\n      \"$(...)$\": {\n        \"*\": { action_: \"tex-math tight\", nextState: \"1\" }\n      },\n      \",\": {\n        \"*\": { action_: { type_: \"insert\", option: \"commaDecimal\" } }\n      },\n      \"else2\": {\n        \"*\": { action_: \"copy\" }\n      }\n    }),\n    actions: {}\n  },\n  \"o\": {\n    transitions: mhchemParser.createTransitions({\n      \"empty\": {\n        \"*\": {}\n      },\n      \"1/2$\": {\n        \"0\": { action_: \"1/2\" }\n      },\n      \"else\": {\n        \"0\": { nextState: \"1\", revisit: true }\n      },\n      \"letters\": {\n        \"*\": { action_: \"rm\" }\n      },\n      \"\\\\ca\": {\n        \"*\": { action_: { type_: \"insert\", option: \"circa\" } }\n      },\n      \"\\\\x{}{}|\\\\x{}|\\\\x\": {\n        \"*\": { action_: \"copy\" }\n      },\n      \"${(...)}$|$(...)$\": {\n        \"*\": { action_: \"tex-math\" }\n      },\n      \"{(...)}\": {\n        \"*\": { action_: \"{text}\" }\n      },\n      \"else2\": {\n        \"*\": { action_: \"copy\" }\n      }\n    }),\n    actions: {}\n  },\n  \"text\": {\n    transitions: mhchemParser.createTransitions({\n      \"empty\": {\n        \"*\": { action_: \"output\" }\n      },\n      \"{...}\": {\n        \"*\": { action_: \"text=\" }\n      },\n      \"${(...)}$|$(...)$\": {\n        \"*\": { action_: \"tex-math\" }\n      },\n      \"\\\\greek\": {\n        \"*\": { action_: [\"output\", \"rm\"] }\n      },\n      \"\\\\,|\\\\x{}{}|\\\\x{}|\\\\x\": {\n        \"*\": { action_: [\"output\", \"copy\"] }\n      },\n      \"else\": {\n        \"*\": { action_: \"text=\" }\n      }\n    }),\n    actions: {\n      output: function(buffer) {\n        if (buffer.text_) {\n          var ret = { type_: \"text\", p1: buffer.text_ };\n          for (var p in buffer) {\n            delete buffer[p];\n          }\n          return ret;\n        }\n      }\n    }\n  },\n  \"pq\": {\n    transitions: mhchemParser.createTransitions({\n      \"empty\": {\n        \"*\": {}\n      },\n      \"state of aggregation $\": {\n        \"*\": { action_: \"state of aggregation\" }\n      },\n      \"i$\": {\n        \"0\": { nextState: \"!f\", revisit: true }\n      },\n      \"(KV letters),\": {\n        \"0\": { action_: \"rm\", nextState: \"0\" }\n      },\n      \"formula$\": {\n        \"0\": { nextState: \"f\", revisit: true }\n      },\n      \"1/2$\": {\n        \"0\": { action_: \"1/2\" }\n      },\n      \"else\": {\n        \"0\": { nextState: \"!f\", revisit: true }\n      },\n      \"${(...)}$|$(...)$\": {\n        \"*\": { action_: \"tex-math\" }\n      },\n      \"{(...)}\": {\n        \"*\": { action_: \"text\" }\n      },\n      \"a-z\": {\n        f: { action_: \"tex-math\" }\n      },\n      \"letters\": {\n        \"*\": { action_: \"rm\" }\n      },\n      \"-9.,9\": {\n        \"*\": { action_: \"9,9\" }\n      },\n      \",\": {\n        \"*\": { action_: { type_: \"insert+p1\", option: \"comma enumeration S\" } }\n      },\n      \"\\\\color{(...)}{(...)}1|\\\\color(...){(...)}2\": {\n        \"*\": { action_: \"color-output\" }\n      },\n      \"\\\\color{(...)}0\": {\n        \"*\": { action_: \"color0-output\" }\n      },\n      \"\\\\ce{(...)}\": {\n        \"*\": { action_: \"ce\" }\n      },\n      \"\\\\,|\\\\x{}{}|\\\\x{}|\\\\x\": {\n        \"*\": { action_: \"copy\" }\n      },\n      \"else2\": {\n        \"*\": { action_: \"copy\" }\n      }\n    }),\n    actions: {\n      \"state of aggregation\": function(buffer, m) {\n        return {\n          type_: \"state of aggregation subscript\",\n          p1: mhchemParser.go(m, \"o\")\n        };\n      },\n      \"color-output\": function(buffer, m) {\n        return {\n          type_: \"color\",\n          color1: m[0],\n          color2: mhchemParser.go(m[1], \"pq\")\n        };\n      }\n    }\n  },\n  \"bd\": {\n    transitions: mhchemParser.createTransitions({\n      \"empty\": {\n        \"*\": {}\n      },\n      \"x$\": {\n        \"0\": { nextState: \"!f\", revisit: true }\n      },\n      \"formula$\": {\n        \"0\": { nextState: \"f\", revisit: true }\n      },\n      \"else\": {\n        \"0\": { nextState: \"!f\", revisit: true }\n      },\n      \"-9.,9 no missing 0\": {\n        \"*\": { action_: \"9,9\" }\n      },\n      \".\": {\n        \"*\": { action_: { type_: \"insert\", option: \"electron dot\" } }\n      },\n      \"a-z\": {\n        f: { action_: \"tex-math\" }\n      },\n      \"x\": {\n        \"*\": { action_: { type_: \"insert\", option: \"KV x\" } }\n      },\n      \"letters\": {\n        \"*\": { action_: \"rm\" }\n      },\n      \"'\": {\n        \"*\": { action_: { type_: \"insert\", option: \"prime\" } }\n      },\n      \"${(...)}$|$(...)$\": {\n        \"*\": { action_: \"tex-math\" }\n      },\n      \"{(...)}\": {\n        \"*\": { action_: \"text\" }\n      },\n      \"\\\\color{(...)}{(...)}1|\\\\color(...){(...)}2\": {\n        \"*\": { action_: \"color-output\" }\n      },\n      \"\\\\color{(...)}0\": {\n        \"*\": { action_: \"color0-output\" }\n      },\n      \"\\\\ce{(...)}\": {\n        \"*\": { action_: \"ce\" }\n      },\n      \"\\\\,|\\\\x{}{}|\\\\x{}|\\\\x\": {\n        \"*\": { action_: \"copy\" }\n      },\n      \"else2\": {\n        \"*\": { action_: \"copy\" }\n      }\n    }),\n    actions: {\n      \"color-output\": function(buffer, m) {\n        return {\n          type_: \"color\",\n          color1: m[0],\n          color2: mhchemParser.go(m[1], \"bd\")\n        };\n      }\n    }\n  },\n  \"oxidation\": {\n    transitions: mhchemParser.createTransitions({\n      \"empty\": {\n        \"*\": {}\n      },\n      \"roman numeral\": {\n        \"*\": { action_: \"roman-numeral\" }\n      },\n      \"${(...)}$|$(...)$\": {\n        \"*\": { action_: \"tex-math\" }\n      },\n      \"else\": {\n        \"*\": { action_: \"copy\" }\n      }\n    }),\n    actions: {\n      \"roman-numeral\": function(buffer, m) {\n        return { type_: \"roman numeral\", p1: m || \"\" };\n      }\n    }\n  },\n  \"tex-math\": {\n    transitions: mhchemParser.createTransitions({\n      \"empty\": {\n        \"*\": { action_: \"output\" }\n      },\n      \"\\\\ce{(...)}\": {\n        \"*\": { action_: [\"output\", \"ce\"] }\n      },\n      \"{...}|\\\\,|\\\\x{}{}|\\\\x{}|\\\\x\": {\n        \"*\": { action_: \"o=\" }\n      },\n      \"else\": {\n        \"*\": { action_: \"o=\" }\n      }\n    }),\n    actions: {\n      output: function(buffer) {\n        if (buffer.o) {\n          var ret = { type_: \"tex-math\", p1: buffer.o };\n          for (var p in buffer) {\n            delete buffer[p];\n          }\n          return ret;\n        }\n      }\n    }\n  },\n  \"tex-math tight\": {\n    transitions: mhchemParser.createTransitions({\n      \"empty\": {\n        \"*\": { action_: \"output\" }\n      },\n      \"\\\\ce{(...)}\": {\n        \"*\": { action_: [\"output\", \"ce\"] }\n      },\n      \"{...}|\\\\,|\\\\x{}{}|\\\\x{}|\\\\x\": {\n        \"*\": { action_: \"o=\" }\n      },\n      \"-|+\": {\n        \"*\": { action_: \"tight operator\" }\n      },\n      \"else\": {\n        \"*\": { action_: \"o=\" }\n      }\n    }),\n    actions: {\n      \"tight operator\": function(buffer, m) {\n        buffer.o = (buffer.o || \"\") + \"{\" + m + \"}\";\n      },\n      \"output\": function(buffer) {\n        if (buffer.o) {\n          var ret = { type_: \"tex-math\", p1: buffer.o };\n          for (var p in buffer) {\n            delete buffer[p];\n          }\n          return ret;\n        }\n      }\n    }\n  },\n  \"9,9\": {\n    transitions: mhchemParser.createTransitions({\n      \"empty\": {\n        \"*\": {}\n      },\n      \",\": {\n        \"*\": { action_: \"comma\" }\n      },\n      \"else\": {\n        \"*\": { action_: \"copy\" }\n      }\n    }),\n    actions: {\n      comma: function() {\n        return { type_: \"commaDecimal\" };\n      }\n    }\n  },\n  //#endregion\n  //\n  // \\pu state machines\n  //\n  //#region pu\n  \"pu\": {\n    transitions: mhchemParser.createTransitions({\n      \"empty\": {\n        \"*\": { action_: \"output\" }\n      },\n      \"space$\": {\n        \"*\": { action_: [\"output\", \"space\"] }\n      },\n      \"{[(|)]}\": {\n        \"0|a\": { action_: \"copy\" }\n      },\n      \"(-)(9)^(-9)\": {\n        \"0\": { action_: \"number^\", nextState: \"a\" }\n      },\n      \"(-)(9.,9)(e)(99)\": {\n        \"0\": { action_: \"enumber\", nextState: \"a\" }\n      },\n      \"space\": {\n        \"0|a\": {}\n      },\n      \"pm-operator\": {\n        \"0|a\": {\n          action_: { type_: \"operator\", option: \"\\\\pm\" },\n          nextState: \"0\"\n        }\n      },\n      \"operator\": {\n        \"0|a\": { action_: \"copy\", nextState: \"0\" }\n      },\n      \"//\": {\n        d: { action_: \"o=\", nextState: \"/\" }\n      },\n      \"/\": {\n        d: { action_: \"o=\", nextState: \"/\" }\n      },\n      \"{...}|else\": {\n        \"0|d\": { action_: \"d=\", nextState: \"d\" },\n        \"a\": { action_: [\"space\", \"d=\"], nextState: \"d\" },\n        \"/|q\": { action_: \"q=\", nextState: \"q\" }\n      }\n    }),\n    actions: {\n      \"enumber\": function(buffer, m) {\n        var ret = [];\n        if (m[0] === \"+-\" || m[0] === \"+/-\") {\n          ret.push(\"\\\\pm \");\n        } else if (m[0]) {\n          ret.push(m[0]);\n        }\n        if (m[1]) {\n          mhchemParser.concatArray(ret, mhchemParser.go(m[1], \"pu-9,9\"));\n          if (m[2]) {\n            if (m[2].match(/[,.]/)) {\n              mhchemParser.concatArray(ret, mhchemParser.go(m[2], \"pu-9,9\"));\n            } else {\n              ret.push(m[2]);\n            }\n          }\n          if (m[3] || m[4]) {\n            if (m[3] === \"e\" || m[4] === \"*\") {\n              ret.push({ type_: \"cdot\" });\n            } else {\n              ret.push({ type_: \"times\" });\n            }\n          }\n        }\n        if (m[5]) {\n          ret.push(\"10^{\" + m[5] + \"}\");\n        }\n        return ret;\n      },\n      \"number^\": function(buffer, m) {\n        var ret = [];\n        if (m[0] === \"+-\" || m[0] === \"+/-\") {\n          ret.push(\"\\\\pm \");\n        } else if (m[0]) {\n          ret.push(m[0]);\n        }\n        mhchemParser.concatArray(ret, mhchemParser.go(m[1], \"pu-9,9\"));\n        ret.push(\"^{\" + m[2] + \"}\");\n        return ret;\n      },\n      \"operator\": function(buffer, m, p1) {\n        return { type_: \"operator\", kind_: p1 || m };\n      },\n      \"space\": function() {\n        return { type_: \"pu-space-1\" };\n      },\n      \"output\": function(buffer) {\n        var ret;\n        var md = mhchemParser.patterns.match_(\"{(...)}\", buffer.d || \"\");\n        if (md && md.remainder === \"\") {\n          buffer.d = md.match_;\n        }\n        var mq = mhchemParser.patterns.match_(\"{(...)}\", buffer.q || \"\");\n        if (mq && mq.remainder === \"\") {\n          buffer.q = mq.match_;\n        }\n        if (buffer.d) {\n          buffer.d = buffer.d.replace(/\\u00B0C|\\^oC|\\^{o}C/g, \"{}^{\\\\circ}C\");\n          buffer.d = buffer.d.replace(/\\u00B0F|\\^oF|\\^{o}F/g, \"{}^{\\\\circ}F\");\n        }\n        if (buffer.q) {\n          buffer.q = buffer.q.replace(/\\u00B0C|\\^oC|\\^{o}C/g, \"{}^{\\\\circ}C\");\n          buffer.q = buffer.q.replace(/\\u00B0F|\\^oF|\\^{o}F/g, \"{}^{\\\\circ}F\");\n          var b5 = {\n            d: mhchemParser.go(buffer.d, \"pu\"),\n            q: mhchemParser.go(buffer.q, \"pu\")\n          };\n          if (buffer.o === \"//\") {\n            ret = { type_: \"pu-frac\", p1: b5.d, p2: b5.q };\n          } else {\n            ret = b5.d;\n            if (b5.d.length > 1 || b5.q.length > 1) {\n              ret.push({ type_: \" / \" });\n            } else {\n              ret.push({ type_: \"/\" });\n            }\n            mhchemParser.concatArray(ret, b5.q);\n          }\n        } else {\n          ret = mhchemParser.go(buffer.d, \"pu-2\");\n        }\n        for (var p in buffer) {\n          delete buffer[p];\n        }\n        return ret;\n      }\n    }\n  },\n  \"pu-2\": {\n    transitions: mhchemParser.createTransitions({\n      \"empty\": {\n        \"*\": { action_: \"output\" }\n      },\n      \"*\": {\n        \"*\": { action_: [\"output\", \"cdot\"], nextState: \"0\" }\n      },\n      \"\\\\x\": {\n        \"*\": { action_: \"rm=\" }\n      },\n      \"space\": {\n        \"*\": { action_: [\"output\", \"space\"], nextState: \"0\" }\n      },\n      \"^{(...)}|^(-1)\": {\n        \"1\": { action_: \"^(-1)\" }\n      },\n      \"-9.,9\": {\n        \"0\": { action_: \"rm=\", nextState: \"0\" },\n        \"1\": { action_: \"^(-1)\", nextState: \"0\" }\n      },\n      \"{...}|else\": {\n        \"*\": { action_: \"rm=\", nextState: \"1\" }\n      }\n    }),\n    actions: {\n      \"cdot\": function() {\n        return { type_: \"tight cdot\" };\n      },\n      \"^(-1)\": function(buffer, m) {\n        buffer.rm += \"^{\" + m + \"}\";\n      },\n      \"space\": function() {\n        return { type_: \"pu-space-2\" };\n      },\n      \"output\": function(buffer) {\n        var ret = [];\n        if (buffer.rm) {\n          var mrm = mhchemParser.patterns.match_(\"{(...)}\", buffer.rm || \"\");\n          if (mrm && mrm.remainder === \"\") {\n            ret = mhchemParser.go(mrm.match_, \"pu\");\n          } else {\n            ret = { type_: \"rm\", p1: buffer.rm };\n          }\n        }\n        for (var p in buffer) {\n          delete buffer[p];\n        }\n        return ret;\n      }\n    }\n  },\n  \"pu-9,9\": {\n    transitions: mhchemParser.createTransitions({\n      \"empty\": {\n        \"0\": { action_: \"output-0\" },\n        \"o\": { action_: \"output-o\" }\n      },\n      \",\": {\n        \"0\": { action_: [\"output-0\", \"comma\"], nextState: \"o\" }\n      },\n      \".\": {\n        \"0\": { action_: [\"output-0\", \"copy\"], nextState: \"o\" }\n      },\n      \"else\": {\n        \"*\": { action_: \"text=\" }\n      }\n    }),\n    actions: {\n      \"comma\": function() {\n        return { type_: \"commaDecimal\" };\n      },\n      \"output-0\": function(buffer) {\n        var ret = [];\n        buffer.text_ = buffer.text_ || \"\";\n        if (buffer.text_.length > 4) {\n          var a = buffer.text_.length % 3;\n          if (a === 0) {\n            a = 3;\n          }\n          for (var i = buffer.text_.length - 3; i > 0; i -= 3) {\n            ret.push(buffer.text_.substr(i, 3));\n            ret.push({ type_: \"1000 separator\" });\n          }\n          ret.push(buffer.text_.substr(0, a));\n          ret.reverse();\n        } else {\n          ret.push(buffer.text_);\n        }\n        for (var p in buffer) {\n          delete buffer[p];\n        }\n        return ret;\n      },\n      \"output-o\": function(buffer) {\n        var ret = [];\n        buffer.text_ = buffer.text_ || \"\";\n        if (buffer.text_.length > 4) {\n          var a = buffer.text_.length - 3;\n          for (var i = 0; i < a; i += 3) {\n            ret.push(buffer.text_.substr(i, 3));\n            ret.push({ type_: \"1000 separator\" });\n          }\n          ret.push(buffer.text_.substr(i));\n        } else {\n          ret.push(buffer.text_);\n        }\n        for (var p in buffer) {\n          delete buffer[p];\n        }\n        return ret;\n      }\n    }\n  }\n  //#endregion\n};\nvar texify = {\n  go: function(input, isInner) {\n    if (!input) {\n      return \"\";\n    }\n    var res = \"\";\n    var cee = false;\n    for (var i = 0; i < input.length; i++) {\n      var inputi = input[i];\n      if (typeof inputi === \"string\") {\n        res += inputi;\n      } else {\n        res += texify._go2(inputi);\n        if (inputi.type_ === \"1st-level escape\") {\n          cee = true;\n        }\n      }\n    }\n    if (!isInner && !cee && res) {\n      res = \"{\" + res + \"}\";\n    }\n    return res;\n  },\n  _goInner: function(input) {\n    if (!input) {\n      return input;\n    }\n    return texify.go(input, true);\n  },\n  _go2: function(buf) {\n    var res;\n    switch (buf.type_) {\n      case \"chemfive\":\n        res = \"\";\n        var b5 = {\n          a: texify._goInner(buf.a),\n          b: texify._goInner(buf.b),\n          p: texify._goInner(buf.p),\n          o: texify._goInner(buf.o),\n          q: texify._goInner(buf.q),\n          d: texify._goInner(buf.d)\n        };\n        if (b5.a) {\n          if (b5.a.match(/^[+\\-]/)) {\n            b5.a = \"{\" + b5.a + \"}\";\n          }\n          res += b5.a + \"\\\\,\";\n        }\n        if (b5.b || b5.p) {\n          res += \"{\\\\vphantom{X}}\";\n          res += \"^{\\\\hphantom{\" + (b5.b || \"\") + \"}}_{\\\\hphantom{\" + (b5.p || \"\") + \"}}\";\n          res += \"{\\\\vphantom{X}}\";\n          res += \"^{\\\\smash[t]{\\\\vphantom{2}}\\\\llap{\" + (b5.b || \"\") + \"}}\";\n          res += \"_{\\\\vphantom{2}\\\\llap{\\\\smash[t]{\" + (b5.p || \"\") + \"}}}\";\n        }\n        if (b5.o) {\n          if (b5.o.match(/^[+\\-]/)) {\n            b5.o = \"{\" + b5.o + \"}\";\n          }\n          res += b5.o;\n        }\n        if (buf.dType === \"kv\") {\n          if (b5.d || b5.q) {\n            res += \"{\\\\vphantom{X}}\";\n          }\n          if (b5.d) {\n            res += \"^{\" + b5.d + \"}\";\n          }\n          if (b5.q) {\n            res += \"_{\\\\smash[t]{\" + b5.q + \"}}\";\n          }\n        } else if (buf.dType === \"oxidation\") {\n          if (b5.d) {\n            res += \"{\\\\vphantom{X}}\";\n            res += \"^{\" + b5.d + \"}\";\n          }\n          if (b5.q) {\n            res += \"{\\\\vphantom{X}}\";\n            res += \"_{\\\\smash[t]{\" + b5.q + \"}}\";\n          }\n        } else {\n          if (b5.q) {\n            res += \"{\\\\vphantom{X}}\";\n            res += \"_{\\\\smash[t]{\" + b5.q + \"}}\";\n          }\n          if (b5.d) {\n            res += \"{\\\\vphantom{X}}\";\n            res += \"^{\" + b5.d + \"}\";\n          }\n        }\n        break;\n      case \"rm\":\n        res = \"\\\\mathrm{\" + buf.p1 + \"}\";\n        break;\n      case \"text\":\n        if (buf.p1.match(/[\\^_]/)) {\n          buf.p1 = buf.p1.replace(\" \", \"~\").replace(\"-\", \"\\\\text{-}\");\n          res = \"\\\\mathrm{\" + buf.p1 + \"}\";\n        } else {\n          res = \"\\\\text{\" + buf.p1 + \"}\";\n        }\n        break;\n      case \"roman numeral\":\n        res = \"\\\\mathrm{\" + buf.p1 + \"}\";\n        break;\n      case \"state of aggregation\":\n        res = \"\\\\mskip2mu \" + texify._goInner(buf.p1);\n        break;\n      case \"state of aggregation subscript\":\n        res = \"\\\\mskip1mu \" + texify._goInner(buf.p1);\n        break;\n      case \"bond\":\n        res = texify._getBond(buf.kind_);\n        if (!res) {\n          throw [\n            \"MhchemErrorBond\",\n            \"mhchem Error. Unknown bond type (\" + buf.kind_ + \")\"\n          ];\n        }\n        break;\n      case \"frac\":\n        var c = \"\\\\frac{\" + buf.p1 + \"}{\" + buf.p2 + \"}\";\n        res = \"\\\\mathchoice{\\\\textstyle\" + c + \"}{\" + c + \"}{\" + c + \"}{\" + c + \"}\";\n        break;\n      case \"pu-frac\":\n        var d = \"\\\\frac{\" + texify._goInner(buf.p1) + \"}{\" + texify._goInner(buf.p2) + \"}\";\n        res = \"\\\\mathchoice{\\\\textstyle\" + d + \"}{\" + d + \"}{\" + d + \"}{\" + d + \"}\";\n        break;\n      case \"tex-math\":\n        res = buf.p1 + \" \";\n        break;\n      case \"frac-ce\":\n        res = \"\\\\frac{\" + texify._goInner(buf.p1) + \"}{\" + texify._goInner(buf.p2) + \"}\";\n        break;\n      case \"overset\":\n        res = \"\\\\overset{\" + texify._goInner(buf.p1) + \"}{\" + texify._goInner(buf.p2) + \"}\";\n        break;\n      case \"underset\":\n        res = \"\\\\underset{\" + texify._goInner(buf.p1) + \"}{\" + texify._goInner(buf.p2) + \"}\";\n        break;\n      case \"underbrace\":\n        res = \"\\\\underbrace{\" + texify._goInner(buf.p1) + \"}_{\" + texify._goInner(buf.p2) + \"}\";\n        break;\n      case \"color\":\n        res = \"{\\\\color{\" + buf.color1 + \"}{\" + texify._goInner(buf.color2) + \"}}\";\n        break;\n      case \"color0\":\n        res = \"\\\\color{\" + buf.color + \"}\";\n        break;\n      case \"arrow\":\n        var b6 = {\n          rd: texify._goInner(buf.rd),\n          rq: texify._goInner(buf.rq)\n        };\n        var arrow = texify._getArrow(buf.r);\n        if (b6.rd || b6.rq) {\n          if (buf.r === \"<=>\" || buf.r === \"<=>>\" || buf.r === \"<<=>\" || buf.r === \"<-->\") {\n            arrow = \"\\\\long\" + arrow;\n            if (b6.rd) {\n              arrow = \"\\\\overset{\" + b6.rd + \"}{\" + arrow + \"}\";\n            }\n            if (b6.rq) {\n              if (buf.r === \"<-->\") {\n                arrow = \"\\\\underset{\\\\lower2mu{\" + b6.rq + \"}}{\" + arrow + \"}\";\n              } else {\n                arrow = \"\\\\underset{\\\\lower6mu{\" + b6.rq + \"}}{\" + arrow + \"}\";\n              }\n            }\n            arrow = \" {}\\\\mathrel{\" + arrow + \"}{} \";\n          } else {\n            if (b6.rq) {\n              arrow += \"[{\" + b6.rq + \"}]\";\n            }\n            arrow += \"{\" + b6.rd + \"}\";\n            arrow = \" {}\\\\mathrel{\\\\x\" + arrow + \"}{} \";\n          }\n        } else {\n          arrow = \" {}\\\\mathrel{\\\\long\" + arrow + \"}{} \";\n        }\n        res = arrow;\n        break;\n      case \"operator\":\n        res = texify._getOperator(buf.kind_);\n        break;\n      case \"1st-level escape\":\n        res = buf.p1 + \" \";\n        break;\n      case \"space\":\n        res = \" \";\n        break;\n      case \"entitySkip\":\n        res = \"~\";\n        break;\n      case \"pu-space-1\":\n        res = \"~\";\n        break;\n      case \"pu-space-2\":\n        res = \"\\\\mkern3mu \";\n        break;\n      case \"1000 separator\":\n        res = \"\\\\mkern2mu \";\n        break;\n      case \"commaDecimal\":\n        res = \"{,}\";\n        break;\n      case \"comma enumeration L\":\n        res = \"{\" + buf.p1 + \"}\\\\mkern6mu \";\n        break;\n      case \"comma enumeration M\":\n        res = \"{\" + buf.p1 + \"}\\\\mkern3mu \";\n        break;\n      case \"comma enumeration S\":\n        res = \"{\" + buf.p1 + \"}\\\\mkern1mu \";\n        break;\n      case \"hyphen\":\n        res = \"\\\\text{-}\";\n        break;\n      case \"addition compound\":\n        res = \"\\\\,{\\\\cdot}\\\\,\";\n        break;\n      case \"electron dot\":\n        res = \"\\\\mkern1mu \\\\bullet\\\\mkern1mu \";\n        break;\n      case \"KV x\":\n        res = \"{\\\\times}\";\n        break;\n      case \"prime\":\n        res = \"\\\\prime \";\n        break;\n      case \"cdot\":\n        res = \"\\\\cdot \";\n        break;\n      case \"tight cdot\":\n        res = \"\\\\mkern1mu{\\\\cdot}\\\\mkern1mu \";\n        break;\n      case \"times\":\n        res = \"\\\\times \";\n        break;\n      case \"circa\":\n        res = \"{\\\\sim}\";\n        break;\n      case \"^\":\n        res = \"uparrow\";\n        break;\n      case \"v\":\n        res = \"downarrow\";\n        break;\n      case \"ellipsis\":\n        res = \"\\\\ldots \";\n        break;\n      case \"/\":\n        res = \"/\";\n        break;\n      case \" / \":\n        res = \"\\\\,/\\\\,\";\n        break;\n      default:\n        assertNever(buf);\n        throw [\"MhchemBugT\", \"mhchem bug T. Please report.\"];\n    }\n    assertString(res);\n    return res;\n  },\n  _getArrow: function(a) {\n    switch (a) {\n      case \"->\":\n        return \"rightarrow\";\n      case \"\\u2192\":\n        return \"rightarrow\";\n      case \"\\u27F6\":\n        return \"rightarrow\";\n      case \"<-\":\n        return \"leftarrow\";\n      case \"<->\":\n        return \"leftrightarrow\";\n      case \"<-->\":\n        return \"leftrightarrows\";\n      case \"<=>\":\n        return \"rightleftharpoons\";\n      case \"\\u21CC\":\n        return \"rightleftharpoons\";\n      case \"<=>>\":\n        return \"Rightleftharpoons\";\n      case \"<<=>\":\n        return \"Leftrightharpoons\";\n      default:\n        assertNever(a);\n        throw [\"MhchemBugT\", \"mhchem bug T. Please report.\"];\n    }\n  },\n  _getBond: function(a) {\n    switch (a) {\n      case \"-\":\n        return \"{-}\";\n      case \"1\":\n        return \"{-}\";\n      case \"=\":\n        return \"{=}\";\n      case \"2\":\n        return \"{=}\";\n      case \"#\":\n        return \"{\\\\equiv}\";\n      case \"3\":\n        return \"{\\\\equiv}\";\n      case \"~\":\n        return \"{\\\\tripledash}\";\n      case \"~-\":\n        return \"{\\\\rlap{\\\\lower.1em{-}}\\\\raise.1em{\\\\tripledash}}\";\n      case \"~=\":\n        return \"{\\\\rlap{\\\\lower.2em{-}}\\\\rlap{\\\\raise.2em{\\\\tripledash}}-}\";\n      case \"~--\":\n        return \"{\\\\rlap{\\\\lower.2em{-}}\\\\rlap{\\\\raise.2em{\\\\tripledash}}-}\";\n      case \"-~-\":\n        return \"{\\\\rlap{\\\\lower.2em{-}}\\\\rlap{\\\\raise.2em{-}}\\\\tripledash}\";\n      case \"...\":\n        return \"{{\\\\cdot}{\\\\cdot}{\\\\cdot}}\";\n      case \"....\":\n        return \"{{\\\\cdot}{\\\\cdot}{\\\\cdot}{\\\\cdot}}\";\n      case \"->\":\n        return \"{\\\\rightarrow}\";\n      case \"<-\":\n        return \"{\\\\leftarrow}\";\n      case \"<\":\n        return \"{<}\";\n      case \">\":\n        return \"{>}\";\n      default:\n        assertNever(a);\n        throw [\"MhchemBugT\", \"mhchem bug T. Please report.\"];\n    }\n  },\n  _getOperator: function(a) {\n    switch (a) {\n      case \"+\":\n        return \" {}+{} \";\n      case \"-\":\n        return \" {}-{} \";\n      case \"=\":\n        return \" {}={} \";\n      case \"<\":\n        return \" {}<{} \";\n      case \">\":\n        return \" {}>{} \";\n      case \"<<\":\n        return \" {}\\\\ll{} \";\n      case \">>\":\n        return \" {}\\\\gg{} \";\n      case \"\\\\pm\":\n        return \" {}\\\\pm{} \";\n      case \"\\\\approx\":\n        return \" {}\\\\approx{} \";\n      case \"$\\\\approx$\":\n        return \" {}\\\\approx{} \";\n      case \"v\":\n        return \" \\\\downarrow{} \";\n      case \"(v)\":\n        return \" \\\\downarrow{} \";\n      case \"^\":\n        return \" \\\\uparrow{} \";\n      case \"(^)\":\n        return \" \\\\uparrow{} \";\n      default:\n        assertNever(a);\n        throw [\"MhchemBugT\", \"mhchem bug T. Please report.\"];\n    }\n  }\n};\nfunction assertNever(a) {\n}\nfunction assertString(a) {\n}\n\n// src/atoms/delim.ts\nvar MiddleDelimAtom = class _MiddleDelimAtom extends Atom {\n  constructor(options) {\n    super(__spreadProps(__spreadValues({}, options), { type: \"delim\" }));\n    this.value = options.delim;\n    this.size = options.size;\n  }\n  static fromJson(json) {\n    return new _MiddleDelimAtom(json);\n  }\n  toJson() {\n    return __spreadProps(__spreadValues({}, super.toJson()), { delim: this.value, size: this.size });\n  }\n  render(_context) {\n    return new Box(this.value, { type: \"middle\" });\n  }\n  _serialize(options) {\n    if (!(options.expandMacro || options.skipStyles || options.skipPlaceholders) && typeof this.verbatimLatex === \"string\")\n      return this.verbatimLatex;\n    const def = getDefinition(this.command, this.mode);\n    if (def == null ? void 0 : def.serialize) return def.serialize(this, options);\n    return latexCommand(this.command, this.value);\n  }\n};\nvar SizedDelimAtom = class _SizedDelimAtom extends Atom {\n  constructor(options) {\n    super(__spreadProps(__spreadValues({}, options), { type: \"sizeddelim\", value: options.delim }));\n    this.delimType = options.delimType;\n    this.size = options.size;\n  }\n  static fromJson(json) {\n    return new _SizedDelimAtom(json);\n  }\n  toJson() {\n    return __spreadProps(__spreadValues({}, super.toJson()), {\n      delim: this.value,\n      size: this.size,\n      delimType: this.delimType\n    });\n  }\n  render(context) {\n    let result = makeSizedDelim(this.value, this.size, context, {\n      classes: { open: \"ML__open\", close: \"ML__close\" }[this.delimType],\n      type: this.delimType,\n      isSelected: this.isSelected\n    });\n    if (!result) return null;\n    result = this.bind(context, result);\n    if (this.caret) result.caret = this.caret;\n    return result;\n  }\n  _serialize(options) {\n    if (!(options.expandMacro || options.skipStyles || options.skipPlaceholders) && typeof this.verbatimLatex === \"string\")\n      return this.verbatimLatex;\n    const def = getDefinition(this.command, this.mode);\n    if (def == null ? void 0 : def.serialize) return def.serialize(this, options);\n    return latexCommand(this.command, this.value);\n  }\n};\n\n// src/atoms/enclose.ts\nvar EncloseAtom = class _EncloseAtom extends Atom {\n  constructor(command, body, notation, options) {\n    var _a3, _b3;\n    super({ type: \"enclose\", command, style: options.style });\n    this.body = body;\n    this.backgroundcolor = options.backgroundcolor;\n    if (notation.updiagonalarrow) notation.updiagonalstrike = false;\n    if (notation.box) {\n      notation.left = false;\n      notation.right = false;\n      notation.bottom = false;\n      notation.top = false;\n    }\n    this.notation = notation;\n    this.shadow = (_a3 = options.shadow) != null ? _a3 : \"none\";\n    this.strokeWidth = (_b3 = options.strokeWidth) != null ? _b3 : \"0.06em\";\n    if (!this.strokeWidth) this.strokeWidth = \"0.06em\";\n    this.strokeStyle = options.strokeStyle;\n    this.svgStrokeStyle = options.svgStrokeStyle;\n    this.strokeColor = options.strokeColor;\n    this.borderStyle = options.borderStyle;\n    this.padding = options.padding;\n    this.captureSelection = false;\n  }\n  static fromJson(json) {\n    return new _EncloseAtom(\n      json.command,\n      json.body,\n      json.notation,\n      json\n    );\n  }\n  toJson() {\n    return __spreadProps(__spreadValues({}, super.toJson()), {\n      notation: this.notation,\n      shadow: this.shadow,\n      strokeWidth: this.strokeWidth,\n      strokeStyle: this.strokeStyle,\n      svgStrokeStyle: this.svgStrokeStyle,\n      strokeColor: this.strokeColor,\n      borderStyle: this.borderStyle,\n      padding: this.padding\n    });\n  }\n  _serialize(options) {\n    var _a3;\n    if (!(options.expandMacro || options.skipStyles || options.skipPlaceholders) && typeof this.verbatimLatex === \"string\")\n      return this.verbatimLatex;\n    const def = getDefinition(this.command, this.mode);\n    if (def == null ? void 0 : def.serialize) return def.serialize(this, options);\n    let command = (_a3 = this.command) != null ? _a3 : \"\";\n    if (this.command === \"\\\\enclose\") {\n      command += \"{\" + Object.keys(this.notation).join(\" \") + \"}\";\n      let style = \"\";\n      let sep = \"\";\n      if (this.backgroundcolor && this.backgroundcolor !== \"transparent\") {\n        style += sep + 'mathbackground=\"' + this.backgroundcolor + '\"';\n        sep = \",\";\n      }\n      if (this.shadow && this.shadow !== \"auto\") {\n        style += sep + 'shadow=\"' + this.shadow + '\"';\n        sep = \",\";\n      }\n      if (this.strokeWidth || this.strokeStyle !== \"solid\") {\n        style += sep + this.borderStyle;\n        sep = \",\";\n      } else if (this.strokeColor && this.strokeColor !== \"currentColor\") {\n        style += sep + 'mathcolor=\"' + this.strokeColor + '\"';\n        sep = \",\";\n      }\n      if (style) command += `[${style}]`;\n    }\n    return latexCommand(command, this.bodyToLatex(options));\n  }\n  render(parentContext) {\n    const context = new Context({ parent: parentContext }, this.style);\n    const base = Atom.createBox(context, this.body);\n    if (!base) return null;\n    const borderWidth = borderDim(this.borderStyle);\n    const padding2 = context.toEm(\n      !this.padding || this.padding === \"auto\" ? { register: \"fboxsep\" } : { string: this.padding }\n    );\n    base.setStyle(\"position\", \"relative\");\n    base.setStyle(\"display\", \"inline-block\");\n    base.setStyle(\"top\", padding2, \"em\");\n    base.setStyle(\"height\", base.height + base.depth, \"em\");\n    base.setStyle(\"width\", base.width, \"em\");\n    const notation = new Box(null, { classes: \"ML__notation\" });\n    let h = base.height + base.depth + 2 * padding2;\n    const w = base.width + 2 * padding2;\n    let svg = \"\";\n    if (this.notation.horizontalstrike) svg += this.line(3, 50, 97, 50);\n    if (this.notation.verticalstrike) svg += this.line(50, 3, 50, 97);\n    if (this.notation.updiagonalstrike) svg += this.line(3, 97, 97, 3);\n    if (this.notation.downdiagonalstrike) svg += this.line(3, 3, 97, 97);\n    if (this.notation.updiagonalarrow) {\n      svg += this.line(\n        padding2.toString(),\n        (padding2 + base.depth + base.height).toString(),\n        (padding2 + base.width).toString(),\n        padding2.toString()\n      );\n      const t = 1;\n      const length = Math.sqrt(w * w + h * h);\n      const f = 0.03 * length * t;\n      const wf = base.width * f;\n      const hf = (base.depth + base.height) * f;\n      const x = padding2 + base.width;\n      let y = padding2;\n      if (y + hf - 0.4 * wf < 0) y = 0.4 * wf - hf;\n      svg += '<polygon points=\"';\n      svg += `${x},${y} ${x - wf - 0.4 * hf},${y + hf - 0.4 * wf} `;\n      svg += `${x - 0.7 * wf},${y + 0.7 * hf} ${x - wf + 0.4 * hf},${y + hf + 0.4 * wf} `;\n      svg += `${x},${y}`;\n      svg += `\" stroke='none' fill=\"${this.strokeColor}\"`;\n      svg += \"/>\";\n    }\n    let wDelta = 0;\n    if (this.notation.phasorangle) {\n      const clearance = getClearance(context);\n      const bot = (base.height + base.depth + 2 * clearance + padding2).toString();\n      const angleWidth = (base.height + base.depth) / 2;\n      svg += this.line(\n        padding2.toString(),\n        bot,\n        (padding2 + angleWidth + base.width).toString(),\n        bot\n      );\n      svg += this.line(\n        padding2.toString(),\n        bot,\n        (padding2 + angleWidth).toString(),\n        (padding2 - clearance).toString()\n      );\n      h += clearance;\n      wDelta = angleWidth;\n      base.left += h / 2 - padding2;\n    }\n    if (this.notation.longdiv) {\n      const clearance = getClearance(context);\n      h += clearance;\n      svg += this.line(\n        padding2.toString(),\n        padding2.toString(),\n        (padding2 + base.width).toString(),\n        padding2.toString()\n      );\n      const surdWidth = 0.3;\n      wDelta = surdWidth + clearance;\n      base.left += surdWidth + clearance;\n      base.setTop(padding2 + clearance);\n      svg += '<path d=\"';\n      svg += `M ${padding2} ${padding2}  a${surdWidth} ${(base.depth + base.height + 2 * clearance) / 2}, 0, 1, 1, 0 ${base.depth + base.height + 2 * clearance} \"`;\n      svg += ` stroke-width=\"${getRuleThickness(context)}\" stroke=\"${this.strokeColor}\" fill=\"none\"`;\n      svg += \"/>\";\n    }\n    notation.width = base.width + 2 * padding2 + wDelta;\n    notation.height = base.height + padding2;\n    notation.depth = base.depth + padding2;\n    notation.setStyle(\"box-sizing\", \"border-box\");\n    notation.setStyle(\"left\", `calc(-${borderWidth} / 2 )`);\n    notation.setStyle(\"height\", `${Math.floor(100 * h) / 100}em`);\n    notation.setStyle(\"top\", `calc(${borderWidth} / 2 )`);\n    if (this.backgroundcolor)\n      notation.setStyle(\"background-color\", this.backgroundcolor);\n    if (this.notation.box) notation.setStyle(\"border\", \"1px solid red\");\n    if (this.notation.actuarial) {\n      notation.setStyle(\"border-top\", this.borderStyle);\n      notation.setStyle(\"border-right\", this.borderStyle);\n    }\n    if (this.notation.madruwb) {\n      notation.setStyle(\"border-bottom\", this.borderStyle);\n      notation.setStyle(\"border-right\", this.borderStyle);\n    }\n    if (this.notation.roundedbox) {\n      notation.setStyle(\"border-radius\", \"8px\");\n      notation.setStyle(\"border\", this.borderStyle);\n    }\n    if (this.notation.circle) {\n      notation.setStyle(\"border-radius\", \"50%\");\n      notation.setStyle(\"border\", this.borderStyle);\n    }\n    if (this.notation.top) notation.setStyle(\"border-top\", this.borderStyle);\n    if (this.notation.left) notation.setStyle(\"border-left\", this.borderStyle);\n    if (this.notation.right)\n      notation.setStyle(\"border-right\", this.borderStyle);\n    if (this.notation.bottom)\n      notation.setStyle(\"border-bottom\", this.borderStyle);\n    if (svg) {\n      let svgStyle = \"\";\n      if (this.shadow === \"auto\") {\n        svgStyle += \"filter: drop-shadow(0 0 .5px rgba(255, 255, 255, .7)) drop-shadow(1px 1px 2px #333)\";\n      }\n      if (this.shadow !== \"none\")\n        svgStyle += `filter: drop-shadow(${this.shadow})`;\n      svgStyle += ` stroke-width=\"${this.strokeWidth}\" stroke=\"${this.strokeColor}\"`;\n      svgStyle += ' stroke-linecap=\"round\"';\n      if (this.svgStrokeStyle)\n        svgStyle += ` stroke-dasharray=\"${this.svgStrokeStyle}\"`;\n      notation.svgStyle = svgStyle;\n      notation.svgOverlay = svg;\n    }\n    const result = new Box([notation, base]);\n    result.setStyle(\"position\", \"relative\");\n    result.setStyle(\"vertical-align\", padding2, \"em\");\n    result.setStyle(\n      \"height\",\n      `${Math.floor(100 * (base.height + base.depth + 2 * padding2)) / 100}em`\n    );\n    result.setStyle(\"display\", \"inline-block\");\n    result.height = notation.height;\n    result.depth = notation.depth;\n    result.width = notation.width - 2 * padding2;\n    result.left = padding2;\n    result.right = padding2;\n    if (this.caret) result.caret = this.caret;\n    return result.wrap(context);\n  }\n  line(x1, y1, x2, y2) {\n    return `<line x1=\"${coord(x1)}\"  y1=\"${coord(y1)}\" x2=\"${coord(\n      x2\n    )}\" y2=\"${coord(y2)}\" vector-effect=\"non-scaling-stroke\"></line>`;\n  }\n};\nfunction coord(c) {\n  if (typeof c === \"number\") return `${Math.floor(100 * c) / 100}%`;\n  return c;\n}\nfunction borderDim(s) {\n  if (!s) return \"1px\";\n  const m = s.match(/([0-9][a-zA-Z\\%]+)/);\n  if (m === null) return \"1px\";\n  return m[1];\n}\nfunction getRuleThickness(ctx) {\n  return (Math.floor(100 * ctx.metrics.sqrtRuleThickness / ctx.scalingFactor) / 100 / 10).toString() + \"em\";\n}\nfunction getClearance(ctx) {\n  const phi = ctx.isDisplayStyle ? X_HEIGHT : ctx.metrics.defaultRuleThickness;\n  return ctx.metrics.defaultRuleThickness + ctx.scalingFactor * phi / 4;\n}\n\n// src/atoms/genfrac.ts\nvar GenfracAtom = class _GenfracAtom extends Atom {\n  constructor(above, below, options) {\n    var _a3, _b3, _c2;\n    super(__spreadProps(__spreadValues({}, options), {\n      type: \"genfrac\",\n      displayContainsHighlight: true\n    }));\n    this.above = above;\n    this.below = below;\n    this.hasBarLine = (_a3 = options == null ? void 0 : options.hasBarLine) != null ? _a3 : true;\n    this.continuousFraction = (_b3 = options == null ? void 0 : options.continuousFraction) != null ? _b3 : false;\n    this.align = (_c2 = options == null ? void 0 : options.align) != null ? _c2 : \"center\";\n    this.numerPrefix = options == null ? void 0 : options.numerPrefix;\n    this.denomPrefix = options == null ? void 0 : options.denomPrefix;\n    this.mathstyleName = options == null ? void 0 : options.mathstyleName;\n    this.leftDelim = options == null ? void 0 : options.leftDelim;\n    this.rightDelim = options == null ? void 0 : options.rightDelim;\n    this.fractionNavigationOrder = options == null ? void 0 : options.fractionNavigationOrder;\n  }\n  static fromJson(json) {\n    return new _GenfracAtom(\n      json.above,\n      json.below,\n      json\n    );\n  }\n  toJson() {\n    const options = {};\n    if (this.continuousFraction) options.continuousFraction = true;\n    if (this.align !== \"center\") options.align = this.align;\n    if (this.numerPrefix) options.numerPrefix = this.numerPrefix;\n    if (this.denomPrefix) options.denomPrefix = this.denomPrefix;\n    if (this.leftDelim) options.leftDelim = this.leftDelim;\n    if (this.rightDelim) options.rightDelim = this.rightDelim;\n    if (!this.hasBarLine) options.hasBarLine = false;\n    if (this.mathstyleName) options.mathstyleName = this.mathstyleName;\n    if (this.fractionNavigationOrder)\n      options.fractionNavigationOrder = this.fractionNavigationOrder;\n    return __spreadValues(__spreadValues({}, super.toJson()), options);\n  }\n  // The order of the children, which is used for keyboard navigation order,\n  // may be customized for fractions...\n  get children() {\n    if (this._children) return this._children;\n    const result = [];\n    if (this.fractionNavigationOrder === \"denominator-numerator\") {\n      for (const x of this.below) {\n        result.push(...x.children);\n        result.push(x);\n      }\n      for (const x of this.above) {\n        result.push(...x.children);\n        result.push(x);\n      }\n    } else {\n      for (const x of this.above) {\n        result.push(...x.children);\n        result.push(x);\n      }\n      for (const x of this.below) {\n        result.push(...x.children);\n        result.push(x);\n      }\n    }\n    this._children = result;\n    return result;\n  }\n  render(context) {\n    var _a3, _b3;\n    const fracContext = new Context(\n      { parent: context, mathstyle: this.mathstyleName },\n      this.style\n    );\n    const metrics = fracContext.metrics;\n    const numContext = new Context(\n      {\n        parent: fracContext,\n        mathstyle: this.continuousFraction ? \"\" : \"numerator\"\n      },\n      this.style\n    );\n    const numerBox = this.numerPrefix ? new Box(\n      [new Box(this.numerPrefix), Atom.createBox(numContext, this.above)],\n      { isTight: numContext.isTight, type: \"ignore\" }\n    ) : (_a3 = Atom.createBox(numContext, this.above, { type: \"ignore\" })) != null ? _a3 : new Box(null, { type: \"ignore\" });\n    const denomContext = new Context(\n      {\n        parent: fracContext,\n        mathstyle: this.continuousFraction ? \"\" : \"denominator\"\n      },\n      this.style\n    );\n    const denomBox = this.denomPrefix ? new Box([\n      new Box(this.denomPrefix),\n      Atom.createBox(denomContext, this.below, { type: \"ignore\" })\n    ]) : (_b3 = Atom.createBox(denomContext, this.below, { type: \"ignore\" })) != null ? _b3 : new Box(null, { type: \"ignore\" });\n    const ruleThickness = this.hasBarLine ? metrics.defaultRuleThickness : 0;\n    let numerShift;\n    let clearance = 0;\n    let denomShift;\n    if (fracContext.isDisplayStyle) {\n      numerShift = numContext.metrics.num1;\n      clearance = ruleThickness > 0 ? 3 * ruleThickness : 7 * ruleThickness;\n      denomShift = denomContext.metrics.denom1;\n    } else {\n      if (ruleThickness > 0) {\n        numerShift = numContext.metrics.num2;\n        clearance = ruleThickness;\n      } else {\n        numerShift = numContext.metrics.num3;\n        clearance = 3 * metrics.defaultRuleThickness;\n      }\n      denomShift = denomContext.metrics.denom2;\n    }\n    const classes = [];\n    if (this.isSelected) classes.push(\"ML__selected\");\n    const numerDepth = numerBox.depth;\n    const denomHeight = denomBox.height;\n    let frac;\n    if (ruleThickness <= 0) {\n      const candidateClearance = numerShift - numerDepth - (denomHeight - denomShift);\n      if (candidateClearance < clearance) {\n        numerShift += (clearance - candidateClearance) / 2;\n        denomShift += (clearance - candidateClearance) / 2;\n      }\n      frac = new VBox({\n        individualShift: [\n          {\n            box: numerBox,\n            shift: -numerShift,\n            classes: [...classes, align2(this.align)]\n          },\n          {\n            box: denomBox,\n            shift: denomShift,\n            classes: [...classes, align2(this.align)]\n          }\n        ]\n      }).wrap(fracContext);\n    } else {\n      const fracLine = new Box(null, {\n        classes: \"ML__frac-line\",\n        mode: this.mode,\n        style: this.style\n      });\n      fracLine.softWidth = Math.max(numerBox.width, denomBox.width);\n      fracLine.height = ruleThickness / 2;\n      fracLine.depth = ruleThickness / 2;\n      const numerLine = AXIS_HEIGHT + ruleThickness / 2;\n      if (numerShift < clearance + numerDepth + numerLine)\n        numerShift = clearance + numerDepth + numerLine;\n      const denomLine = AXIS_HEIGHT - ruleThickness / 2;\n      if (denomShift < clearance + denomHeight - denomLine)\n        denomShift = clearance + denomHeight - denomLine;\n      frac = new VBox({\n        individualShift: [\n          {\n            box: denomBox,\n            shift: denomShift,\n            classes: [...classes, align2(this.align)]\n          },\n          { box: fracLine, shift: -denomLine, classes },\n          {\n            box: numerBox,\n            shift: -numerShift,\n            classes: [...classes, align2(this.align)]\n          }\n        ]\n      }).wrap(fracContext);\n    }\n    const delimSize = fracContext.isDisplayStyle ? metrics.delim1 : metrics.delim2;\n    const leftDelim = this.leftDelim ? this.bind(\n      context,\n      makeCustomSizedDelim(\n        \"open\",\n        this.leftDelim,\n        delimSize,\n        true,\n        context,\n        { style: this.style, mode: this.mode, isSelected: this.isSelected }\n      )\n    ) : makeNullDelimiter(fracContext, \"ML__open\");\n    let rightDelim = null;\n    if (this.continuousFraction) {\n      rightDelim = new Box(null, { type: \"close\" });\n    } else if (!this.rightDelim)\n      rightDelim = makeNullDelimiter(fracContext, \"ML__close\");\n    else {\n      rightDelim = this.bind(\n        context,\n        makeCustomSizedDelim(\n          \"close\",\n          this.rightDelim,\n          delimSize,\n          true,\n          context,\n          { style: this.style, mode: this.mode, isSelected: this.isSelected }\n        )\n      );\n    }\n    const mfrac = new Box([leftDelim, frac, rightDelim], {\n      isTight: fracContext.isTight,\n      type: \"inner\",\n      classes: \"ML__mfrac\"\n    });\n    const result = this.bind(context, mfrac);\n    if (this.caret) result.caret = this.caret;\n    return this.attachSupsub(context, { base: result });\n  }\n};\nfunction align2(v) {\n  var _a3;\n  return (_a3 = {\n    left: \"ML__left\",\n    right: \"ML__right\",\n    center: \"ML__center\"\n  }[v]) != null ? _a3 : \"ML__center\";\n}\n\n// src/atoms/latex.ts\nvar LatexAtom = class _LatexAtom extends Atom {\n  // Display errors with wavy red line\n  constructor(value, options) {\n    var _a3;\n    super({ type: \"latex\", value, mode: \"latex\" });\n    this.isSuggestion = (_a3 = options == null ? void 0 : options.isSuggestion) != null ? _a3 : false;\n    this.isError = false;\n  }\n  static fromJson(json) {\n    const result = new _LatexAtom(json.value);\n    if (json.isSuggestion) result.isSuggestion = true;\n    if (json.isError) result.isError = true;\n    return result;\n  }\n  toJson() {\n    const options = {};\n    if (this.isSuggestion) options.isSuggestion = true;\n    if (this.isError) options.isError = true;\n    return __spreadValues({ type: \"latex\", value: this.value }, options);\n  }\n  render(context) {\n    const result = new Box(this.value, {\n      classes: this.isSuggestion ? \"ML__suggestion\" : this.isError ? \"ML__error\" : \"\",\n      type: \"latex\",\n      maxFontSize: 1\n    });\n    if (!result) return null;\n    if (this.caret) result.caret = this.caret;\n    return this.bind(context, result);\n  }\n};\nvar LatexGroupAtom = class _LatexGroupAtom extends Atom {\n  constructor(latex = \"\") {\n    super({ type: \"latexgroup\", mode: \"latex\" });\n    this.body = [...latex].map((c) => new LatexAtom(c));\n    this.skipBoundary = true;\n  }\n  static fromJson(_json) {\n    return new _LatexGroupAtom();\n  }\n  toJson() {\n    return super.toJson();\n  }\n  render(context) {\n    const box = Atom.createBox(context, this.body);\n    if (!box) return null;\n    if (this.caret) box.caret = this.caret;\n    return this.bind(context, box);\n  }\n  _serialize(_options) {\n    var _a3, _b3;\n    return (_b3 = (_a3 = this.body) == null ? void 0 : _a3.map((x) => x.value).join(\"\")) != null ? _b3 : \"\";\n  }\n};\n\n// src/atoms/extensible-symbol.ts\nvar ExtensibleSymbolAtom = class _ExtensibleSymbolAtom extends Atom {\n  constructor(symbol, options) {\n    super(__spreadProps(__spreadValues({}, options), {\n      type: \"extensible-symbol\",\n      isFunction: options == null ? void 0 : options.isFunction\n    }));\n    this.value = symbol;\n    this.variant = options == null ? void 0 : options.variant;\n    this.subsupPlacement = options == null ? void 0 : options.limits;\n  }\n  static fromJson(json) {\n    return new _ExtensibleSymbolAtom(json.symbol, json);\n  }\n  toJson() {\n    const result = super.toJson();\n    if (this.variant) result.variant = this.variant;\n    if (this.subsupPlacement) result.limits = this.subsupPlacement;\n    if (this.value) result.symbol = this.value;\n    return result;\n  }\n  render(context) {\n    var _a3;\n    const large = context.isDisplayStyle && this.value !== \"\\\\smallint\";\n    const base = new Box(this.value, {\n      fontFamily: large ? \"Size2-Regular\" : \"Size1-Regular\",\n      classes: \"ML__op-symbol \" + (large ? \"ML__large-op\" : \"ML__small-op\"),\n      type: \"op\",\n      maxFontSize: context.scalingFactor,\n      isSelected: this.isSelected\n    });\n    if (!base) return null;\n    base.right = base.italic;\n    const baseShift = (base.height - base.depth) / 2 - AXIS_HEIGHT * context.scalingFactor;\n    const slant = base.italic;\n    base.setTop(baseShift);\n    let result = base;\n    if (this.superscript || this.subscript) {\n      let limits = (_a3 = this.subsupPlacement) != null ? _a3 : \"auto\";\n      if (limits === \"auto\" && context.isDisplayStyle) limits = \"over-under\";\n      result = limits === \"over-under\" ? this.attachLimits(context, { base, baseShift, slant }) : this.attachSupsub(context, { base });\n    }\n    return new Box(this.bind(context, result), {\n      type: \"op\",\n      caret: this.caret,\n      isSelected: this.isSelected,\n      classes: \"ML__op-group\"\n    }).wrap(context);\n  }\n  _serialize(options) {\n    if (!(options.expandMacro || options.skipStyles || options.skipPlaceholders) && typeof this.verbatimLatex === \"string\")\n      return this.verbatimLatex;\n    const def = getDefinition(this.command, this.mode);\n    if (def == null ? void 0 : def.serialize) return def.serialize(this, options);\n    const result = [];\n    result.push(this.command);\n    if (this.explicitSubsupPlacement) {\n      if (this.subsupPlacement === \"over-under\") result.push(\"\\\\limits\");\n      if (this.subsupPlacement === \"adjacent\") result.push(\"\\\\nolimits\");\n      if (this.subsupPlacement === \"auto\") result.push(\"\\\\displaylimits\");\n    }\n    result.push(this.supsubToLatex(options));\n    return joinLatex(result);\n  }\n};\n\n// src/atoms/overlap.ts\nvar OverlapAtom = class _OverlapAtom extends Atom {\n  constructor(options) {\n    const body = options.body;\n    super(__spreadProps(__spreadValues({}, options), {\n      type: \"overlap\",\n      body: typeof body === \"string\" ? [new Atom({ value: body })] : body,\n      style: options == null ? void 0 : options.style\n    }));\n    this.skipBoundary = true;\n    this.align = options == null ? void 0 : options.align;\n    this.boxType = options == null ? void 0 : options.boxType;\n  }\n  static fromJson(json) {\n    return new _OverlapAtom(json);\n  }\n  toJson() {\n    const options = {};\n    if (this.align) options.align = this.align;\n    if (this.boxType) options.boxType = this.boxType;\n    return __spreadValues(__spreadValues({}, super.toJson()), options);\n  }\n  render(context) {\n    const inner = Atom.createBox(context, this.body, { classes: \"ML__inner\" });\n    if (!inner) return null;\n    if (this.caret) inner.caret = this.caret;\n    return this.bind(\n      context,\n      new Box([inner, new Box(null, { classes: \"ML__fix\" })], {\n        classes: this.align === \"right\" ? \"ML__rlap\" : \"ML__llap\",\n        type: this.boxType\n      })\n    );\n  }\n};\n\n// src/atoms/overunder.ts\nvar OverunderAtom = class _OverunderAtom extends Atom {\n  constructor(options) {\n    var _a3, _b3, _c2, _d2;\n    super({\n      type: \"overunder\",\n      command: options.command,\n      style: options.style,\n      mode: options.mode,\n      body: options.body,\n      skipBoundary: (_a3 = options.skipBoundary) != null ? _a3 : true\n    });\n    this.subsupPlacement = options.supsubPlacement;\n    this.svgAbove = options.svgAbove;\n    this.svgBelow = options.svgBelow;\n    this.svgBody = options.svgBody;\n    this.above = options.above;\n    this.below = options.below;\n    this.boxType = (_b3 = options.boxType) != null ? _b3 : \"ord\";\n    this.paddedBody = (_c2 = options.paddedBody) != null ? _c2 : false;\n    this.paddedLabels = (_d2 = options.paddedLabels) != null ? _d2 : false;\n  }\n  static fromJson(json) {\n    return new _OverunderAtom(json);\n  }\n  toJson() {\n    const json = super.toJson();\n    if (!this.skipBoundary) json.skipBoundary = false;\n    if (this.subsupPlacement) json.subsupPlacement = this.subsupPlacement;\n    if (this.svgAbove) json.svgAbove = this.svgAbove;\n    if (this.svgBelow) json.svgBelow = this.svgBelow;\n    if (this.svgBody) json.svgBody = this.svgBody;\n    if (this.boxType !== \"ord\") json.boxType = this.boxType;\n    if (this.paddedBody) json.paddedBody = true;\n    if (this.paddedLabels) json.paddedLabels = true;\n    return json;\n  }\n  /**\n   * Combine a base with an atom above and an atom below.\n   *\n   * See http://tug.ctan.org/macros/latex/required/amsmath/amsmath.dtx\n   *\n   * > \\newcommand{\\overset}[2]{\\binrel@{#2}%\n   * > \\binrel@@{\\mathop{\\kern\\z@#2}\\limits^{#1}}}\n   *\n   */\n  render(parentContext) {\n    let body = this.svgBody ? makeSVGBox(this.svgBody) : Atom.createBox(parentContext, this.body, { type: \"ignore\" });\n    const annotationContext = new Context(\n      { parent: parentContext, mathstyle: \"scriptstyle\" },\n      this.style\n    );\n    let above = null;\n    if (this.svgAbove) above = makeSVGBox(this.svgAbove);\n    else if (this.above)\n      above = Atom.createBox(annotationContext, this.above, { type: \"ignore\" });\n    let below = null;\n    if (this.svgBelow) below = makeSVGBox(this.svgBelow);\n    else if (this.below)\n      below = Atom.createBox(annotationContext, this.below, { type: \"ignore\" });\n    if (this.paddedBody) {\n      body = new Box(\n        [\n          makeNullDelimiter(parentContext, \"ML__open\"),\n          body,\n          makeNullDelimiter(parentContext, \"ML__close\")\n        ],\n        { type: \"ignore\" }\n      );\n    }\n    let base = makeOverunderStack(parentContext, {\n      base: body,\n      above,\n      below,\n      type: this.boxType === \"bin\" || this.boxType === \"rel\" ? this.boxType : \"ord\",\n      paddedAboveBelow: this.paddedLabels\n    });\n    if (!base) return null;\n    if (this.subsupPlacement === \"over-under\")\n      base = this.attachLimits(parentContext, { base, type: base.type });\n    else base = this.attachSupsub(parentContext, { base });\n    if (this.caret) base.caret = this.caret;\n    return this.bind(parentContext, base);\n  }\n};\nfunction makeOverunderStack(context, options) {\n  if (!options.base) return null;\n  if (!options.above && !options.below) {\n    const box = new Box(options.base, { type: options.type });\n    box.setStyle(\"position\", \"relative\");\n    return box;\n  }\n  let aboveShift = 0;\n  if (options.above) aboveShift = context.metrics.bigOpSpacing5;\n  let result = null;\n  const base = options.base;\n  const baseShift = 0;\n  const classes = [\"ML__center\"];\n  if (options.paddedAboveBelow) classes.push(\"ML__label_padding\");\n  if (options.below && options.above) {\n    const bottom = context.metrics.bigOpSpacing5 + options.below.height + options.below.depth + base.depth + baseShift;\n    result = new VBox({\n      bottom,\n      children: [\n        context.metrics.bigOpSpacing5,\n        { box: options.below, classes },\n        { box: base, classes: [\"ML__center\"] },\n        aboveShift,\n        { box: options.above, classes },\n        context.metrics.bigOpSpacing5\n      ]\n    });\n  } else if (options.below) {\n    result = new VBox({\n      top: base.height - baseShift,\n      children: [\n        context.metrics.bigOpSpacing5,\n        { box: options.below, classes },\n        { box: base, classes: [\"ML__center\"] }\n      ]\n    });\n  } else if (options.above) {\n    result = new VBox({\n      bottom: base.depth + baseShift,\n      children: [\n        // base.depth,\n        { box: base, classes: [\"ML__center\"] },\n        aboveShift,\n        { box: options.above, classes },\n        context.metrics.bigOpSpacing5\n      ]\n    });\n  }\n  return new Box(result, { type: options.type });\n}\n\n// src/atoms/phantom.ts\nvar PhantomAtom = class _PhantomAtom extends Atom {\n  constructor(options) {\n    var _a3, _b3, _c2, _d2;\n    super(__spreadProps(__spreadValues({}, options), { type: \"phantom\" }));\n    this.captureSelection = true;\n    this.isInvisible = (_a3 = options.isInvisible) != null ? _a3 : false;\n    this.smashDepth = (_b3 = options.smashDepth) != null ? _b3 : false;\n    this.smashHeight = (_c2 = options.smashHeight) != null ? _c2 : false;\n    this.smashWidth = (_d2 = options.smashWidth) != null ? _d2 : false;\n  }\n  static fromJson(json) {\n    return new _PhantomAtom(json);\n  }\n  toJson() {\n    const options = {};\n    if (this.isInvisible) options.isInvisible = true;\n    if (this.smashDepth) options.smashDepth = true;\n    if (this.smashHeight) options.smashHeight = true;\n    if (this.smashWidth) options.smashWidth = true;\n    return __spreadValues(__spreadValues({}, super.toJson()), options);\n  }\n  render(context) {\n    const phantom = new Context({ parent: context, isPhantom: true });\n    if (!this.smashDepth && !this.smashHeight && !this.smashWidth) {\n      console.assert(this.isInvisible);\n      return Atom.createBox(phantom, this.body, { classes: \"ML__inner\" });\n    }\n    const content = Atom.createBox(\n      this.isInvisible ? phantom : context,\n      this.body\n    );\n    if (!content) return null;\n    if (this.smashWidth) {\n      const fix = new Box(null, { classes: \"ML__fix\" });\n      return new Box([content, fix], { classes: \"ML__rlap\" }).wrap(context);\n    }\n    if (!this.smashHeight && !this.smashDepth) return content;\n    if (this.smashHeight) content.height = 0;\n    if (this.smashDepth) content.depth = 0;\n    if (content.children) {\n      for (const box of content.children) {\n        if (this.smashHeight) box.height = 0;\n        if (this.smashDepth) box.depth = 0;\n      }\n    }\n    return new VBox(\n      { firstBaseline: [{ box: content }] },\n      { type: content.type }\n    ).wrap(context);\n  }\n};\n\n// src/atoms/spacing.ts\nvar SpacingAtom = class _SpacingAtom extends Atom {\n  constructor(options) {\n    var _a3;\n    super(__spreadValues({ type: \"spacing\" }, options));\n    this.width = options == null ? void 0 : options.width;\n    this._braced = (_a3 = options == null ? void 0 : options.braced) != null ? _a3 : false;\n  }\n  static fromJson(json) {\n    return new _SpacingAtom(json);\n  }\n  toJson() {\n    const json = super.toJson();\n    if (this.width !== void 0) json.width = this.width;\n    if (this._braced) json.braced = true;\n    return json;\n  }\n  render(context) {\n    var _a3;\n    if (this.command === \"space\")\n      return new Box(this.mode === \"math\" ? null : \" \");\n    let result;\n    if (this.width !== void 0) {\n      result = new Box(null, { classes: \"ML__mspace\" });\n      result.left = context.toEm(this.width);\n    } else {\n      const spacingCls = (_a3 = {\n        \"\\\\qquad\": \"ML__qquad\",\n        \"\\\\quad\": \"ML__quad\",\n        \"\\\\enspace\": \"ML__enspace\",\n        \"\\\\;\": \"ML__thickspace\",\n        \"\\\\:\": \"ML__mediumspace\",\n        \"\\\\>\": \"ML__mediumspace\",\n        \"\\\\,\": \"ML__thinspace\",\n        \"\\\\!\": \"ML__negativethinspace\"\n      }[this.command]) != null ? _a3 : \"ML__mediumspace\";\n      result = new Box(null, { classes: spacingCls });\n    }\n    result = this.bind(context, result);\n    if (this.caret) result.caret = this.caret;\n    return result;\n  }\n  _serialize(options) {\n    var _a3;\n    if (!options.expandMacro && typeof this.verbatimLatex === \"string\")\n      return this.verbatimLatex;\n    const def = getDefinition(this.command, this.mode);\n    if (def == null ? void 0 : def.serialize) return def.serialize(this, options);\n    const command = (_a3 = this.command) != null ? _a3 : \"\";\n    if (this.width === void 0) return command;\n    if (this._braced && !(\"register\" in this.width))\n      return `${command}{${serializeLatexValue(this.width)}}`;\n    return `${command}${serializeLatexValue(this.width)}`;\n  }\n};\n\n// src/atoms/surd.ts\nvar SurdAtom = class _SurdAtom extends Atom {\n  constructor(options) {\n    var _a3;\n    super(__spreadProps(__spreadValues({}, options), {\n      type: \"surd\",\n      mode: (_a3 = options.mode) != null ? _a3 : \"math\",\n      style: options.style,\n      displayContainsHighlight: true,\n      body: options.body\n    }));\n    this.above = options.index;\n  }\n  static fromJson(json) {\n    return new _SurdAtom(__spreadProps(__spreadValues({}, json), {\n      index: json.above\n    }));\n  }\n  _serialize(options) {\n    if (!(options.expandMacro || options.skipStyles || options.skipPlaceholders) && typeof this.verbatimLatex === \"string\")\n      return this.verbatimLatex;\n    const def = getDefinition(this.command, this.mode);\n    if (def == null ? void 0 : def.serialize) return def.serialize(this, options);\n    const command = this.command;\n    const body = this.bodyToLatex(options);\n    if (this.above && !this.hasEmptyBranch(\"above\"))\n      return latexCommand(`${command}[${this.aboveToLatex(options)}]`, body);\n    if (/^[0-9]$/.test(body)) return `${command}${body}`;\n    return latexCommand(command, body);\n  }\n  // Custom implementation so that the navigation of the index feels natural\n  get children() {\n    if (this._children) return this._children;\n    const result = [];\n    if (this.above) {\n      for (const x of this.above) {\n        result.push(...x.children);\n        result.push(x);\n      }\n    }\n    if (this.body) {\n      for (const x of this.body) {\n        result.push(...x.children);\n        result.push(x);\n      }\n    }\n    this._children = result;\n    return result;\n  }\n  render(context) {\n    var _a3;\n    const innerContext = new Context(\n      { parent: context, mathstyle: \"cramp\" },\n      this.style\n    );\n    const innerBox = (_a3 = Atom.createBox(innerContext, this.body, { type: \"inner\" })) != null ? _a3 : new Box(null);\n    const factor = innerContext.scalingFactor;\n    const ruleWidth = innerContext.metrics.defaultRuleThickness / factor;\n    const phi = context.isDisplayStyle ? X_HEIGHT : ruleWidth;\n    const line = new Box(null, { classes: \"ML__sqrt-line\", style: this.style });\n    line.height = ruleWidth;\n    line.softWidth = innerBox.width;\n    let lineClearance = factor * (ruleWidth + phi / 4);\n    const innerTotalHeight = Math.max(\n      factor * 2 * phi,\n      innerBox.height + innerBox.depth\n    );\n    const minDelimiterHeight = innerTotalHeight + lineClearance + ruleWidth;\n    const delimContext = new Context({ parent: context }, this.style);\n    const delimBox = this.bind(\n      delimContext,\n      new Box(\n        makeCustomSizedDelim(\n          \"inner\",\n          // @todo not sure if that's the right type\n          \"\\\\surd\",\n          minDelimiterHeight,\n          false,\n          delimContext,\n          { isSelected: this.isSelected }\n        ),\n        {\n          isSelected: this.isSelected,\n          classes: \"ML__sqrt-sign\",\n          style: this.style\n        }\n      )\n    );\n    if (!delimBox) return null;\n    const delimDepth = delimBox.height + delimBox.depth - ruleWidth;\n    if (delimDepth > innerBox.height + innerBox.depth + lineClearance) {\n      lineClearance = (lineClearance + delimDepth - (innerBox.height + innerBox.depth)) / 2;\n    }\n    delimBox.setTop(delimBox.height - innerBox.height - lineClearance);\n    const bodyBox = this.bind(\n      context,\n      new VBox({\n        firstBaseline: [\n          { box: new Box(innerBox) },\n          // Need to wrap the inner for proper selection bound calculation\n          lineClearance - 2 * ruleWidth,\n          { box: line },\n          ruleWidth\n        ]\n      })\n    );\n    const indexBox = Atom.createBox(\n      new Context({ parent: context, mathstyle: \"scriptscriptstyle\" }),\n      this.above,\n      { type: \"ignore\" }\n    );\n    if (!indexBox) {\n      const result2 = new Box([delimBox, bodyBox], {\n        classes: this.containsCaret ? \"ML__contains-caret\" : \"\",\n        type: \"inner\"\n      });\n      result2.setStyle(\"display\", \"inline-block\");\n      result2.setStyle(\"height\", result2.height + result2.depth, \"em\");\n      if (this.caret) result2.caret = this.caret;\n      return this.bind(context, result2);\n    }\n    const indexStack = new VBox({\n      shift: -0.6 * (Math.max(delimBox.height, bodyBox.height) - Math.max(delimBox.depth, bodyBox.depth)),\n      children: [{ box: indexBox }]\n    });\n    const result = new Box(\n      [\n        new Box(indexStack, { classes: \"ML__sqrt-index\", type: \"ignore\" }),\n        delimBox,\n        bodyBox\n      ],\n      {\n        type: \"inner\",\n        classes: this.containsCaret ? \"ML__contains-caret\" : \"\"\n      }\n    );\n    result.height = delimBox.height;\n    result.depth = delimBox.depth;\n    if (this.caret) result.caret = this.caret;\n    return this.bind(context, result);\n  }\n};\n\n// src/core/skip-box.ts\nvar SkipBox = class extends Box {\n  constructor(width) {\n    super(null, { type: \"skip\" });\n    this._width = width;\n  }\n  toMarkup() {\n    return `<span style=\"display:inline-block;width:${Math.ceil(this.width * 100) / 100}em\"></span>`;\n  }\n};\nfunction addSkipBefore(box, width) {\n  if (!box.parent) return;\n  const siblings = box.parent.children;\n  const i = siblings.indexOf(box);\n  let j = i - 1;\n  while (j >= 0) {\n    if (siblings[j].type === \"ignore\") j -= 1;\n    else break;\n  }\n  if (j < 0 && box.parent.parent && box.parent.type === \"lift\") {\n    addSkipBefore(box.parent, width);\n    return;\n  }\n  if (i > 0 && siblings[i - 1].type === \"skip\") siblings[i - 1].width += width;\n  else siblings.splice(i, 0, new SkipBox(width));\n}\n\n// src/core/inter-box-spacing.ts\nvar INTER_BOX_SPACING = {\n  ord: { op: 3, bin: 4, rel: 5, inner: 3 },\n  op: { ord: 3, op: 3, rel: 5, inner: 3 },\n  bin: { ord: 4, op: 4, open: 4, inner: 4 },\n  rel: { ord: 5, op: 5, open: 5, inner: 5 },\n  close: { op: 3, bin: 4, rel: 5, inner: 3 },\n  punct: { ord: 3, op: 3, rel: 3, open: 3, punct: 3, inner: 3 },\n  inner: { ord: 3, op: 3, bin: 4, rel: 5, open: 3, punct: 3, inner: 3 }\n};\nvar INTER_BOX_TIGHT_SPACING = {\n  ord: { op: 3 },\n  op: { ord: 3, op: 3 },\n  close: { op: 3 },\n  inner: { op: 3 }\n};\nfunction adjustType(boxes) {\n  traverseBoxes(boxes, (prev, cur) => {\n    if (cur.type === \"bin\" && (!prev || /^(middle|bin|op|rel|open|punct)$/.test(prev.type)))\n      cur.type = \"ord\";\n    if ((prev == null ? void 0 : prev.type) === \"bin\" && /^(rel|close|punct)$/.test(cur.type))\n      prev.type = \"ord\";\n    if (cur.type !== \"ignore\") prev = cur;\n  });\n}\nfunction applyInterBoxSpacing(root, context) {\n  if (!root.children) return root;\n  const boxes = root.children;\n  adjustType(boxes);\n  const thin = context.getRegisterAsEm(\"thinmuskip\");\n  const med = context.getRegisterAsEm(\"medmuskip\");\n  const thick = context.getRegisterAsEm(\"thickmuskip\");\n  traverseBoxes(boxes, (prev, cur) => {\n    var _a3, _b3, _c2;\n    if (!prev) return;\n    const prevType = prev.type;\n    const table = cur.isTight ? (_a3 = INTER_BOX_TIGHT_SPACING[prevType]) != null ? _a3 : null : (_b3 = INTER_BOX_SPACING[prevType]) != null ? _b3 : null;\n    const hskip = (_c2 = table == null ? void 0 : table[cur.type]) != null ? _c2 : null;\n    if (hskip === 3) addSkipBefore(cur, thin);\n    if (hskip === 4) addSkipBefore(cur, med);\n    if (hskip === 5) addSkipBefore(cur, thick);\n  });\n  return root;\n}\nfunction traverseBoxes(boxes, f, prev = void 0) {\n  if (!boxes) return prev;\n  boxes = [...boxes];\n  for (const cur of boxes) {\n    if (cur.type === \"lift\") prev = traverseBoxes(cur.children, f, prev);\n    else if (cur.type === \"ignore\") traverseBoxes(cur.children, f);\n    else {\n      f(prev, cur);\n      traverseBoxes(cur.children, f);\n      prev = cur;\n    }\n  }\n  return prev;\n}\n\n// src/atoms/tooltip.ts\nvar TooltipAtom = class _TooltipAtom extends Atom {\n  constructor(options) {\n    super({\n      type: \"tooltip\",\n      command: options.command,\n      mode: options.mode,\n      style: options.style,\n      body: options.body,\n      displayContainsHighlight: true\n    });\n    this.tooltip = new Atom({\n      type: \"root\",\n      mode: options.content,\n      body: options.tooltip,\n      style: {}\n    });\n    this.skipBoundary = true;\n    this.captureSelection = false;\n  }\n  static fromJson(json) {\n    return new _TooltipAtom(__spreadProps(__spreadValues({}, json), {\n      tooltip: fromJson(json.tooltip)\n    }));\n  }\n  toJson() {\n    var _a3;\n    const tooltip = (_a3 = this.tooltip.body) == null ? void 0 : _a3.filter((x) => x.type !== \"first\").map((x) => x.toJson());\n    return __spreadProps(__spreadValues({}, super.toJson()), { tooltip });\n  }\n  render(context) {\n    const body = Atom.createBox(new Context(), this.body);\n    if (!body) return null;\n    const tooltipContext = new Context(\n      { parent: context, mathstyle: \"displaystyle\" },\n      { fontSize: DEFAULT_FONT_SIZE }\n    );\n    const tooltip = coalesce(\n      applyInterBoxSpacing(\n        new Box(this.tooltip.render(tooltipContext), {\n          classes: \"ML__tooltip-content\"\n        }),\n        tooltipContext\n      )\n    );\n    const box = new Box([tooltip, body], { classes: \"ML__tooltip-container\" });\n    if (this.caret) box.caret = this.caret;\n    return this.bind(context, box);\n  }\n};\n\n// src/atoms/operator.ts\nvar OperatorAtom = class _OperatorAtom extends Atom {\n  constructor(symbol, options) {\n    super(__spreadProps(__spreadValues({}, options), {\n      type: \"operator\",\n      isFunction: options == null ? void 0 : options.isFunction\n    }));\n    this.value = symbol;\n    this.variant = options == null ? void 0 : options.variant;\n    this.variantStyle = options == null ? void 0 : options.variantStyle;\n    this.subsupPlacement = options == null ? void 0 : options.limits;\n  }\n  static fromJson(json) {\n    return new _OperatorAtom(json.symbol, json);\n  }\n  toJson() {\n    const result = super.toJson();\n    if (this.variant) result.variant = this.variant;\n    if (this.variantStyle) result.variantStyle = this.variantStyle;\n    if (this.subsupPlacement) result.limits = this.subsupPlacement;\n    if (this.value) result.symbol = this.value;\n    return result;\n  }\n  render(context) {\n    var _a3;\n    const base = new Box(this.value, {\n      type: \"op\",\n      mode: \"math\",\n      maxFontSize: context.scalingFactor,\n      style: {\n        variant: this.variant,\n        variantStyle: this.variantStyle\n      },\n      isSelected: this.isSelected,\n      letterShapeStyle: context.letterShapeStyle\n    });\n    let result = base;\n    if (this.superscript || this.subscript) {\n      const limits = (_a3 = this.subsupPlacement) != null ? _a3 : \"auto\";\n      result = limits === \"over-under\" || limits === \"auto\" && context.isDisplayStyle ? this.attachLimits(context, { base }) : this.attachSupsub(context, { base });\n    }\n    return new Box(this.bind(context, result), {\n      type: \"op\",\n      caret: this.caret,\n      isSelected: this.isSelected,\n      classes: \"ML__op-group\"\n    }).wrap(context);\n  }\n  _serialize(options) {\n    if (!(options.expandMacro || options.skipStyles || options.skipPlaceholders) && typeof this.verbatimLatex === \"string\")\n      return this.verbatimLatex;\n    const def = getDefinition(this.command, this.mode);\n    if (def == null ? void 0 : def.serialize) return def.serialize(this, options);\n    const result = [this.command];\n    if (this.explicitSubsupPlacement) {\n      if (this.subsupPlacement === \"over-under\") result.push(\"\\\\limits\");\n      if (this.subsupPlacement === \"adjacent\") result.push(\"\\\\nolimits\");\n      if (this.subsupPlacement === \"auto\") result.push(\"\\\\displaylimits\");\n    }\n    result.push(this.supsubToLatex(options));\n    return joinLatex(result);\n  }\n};\n\n// src/core/atom.ts\nfunction fromJson(json) {\n  if (isArray(json)) return json.map((x) => fromJson(x));\n  if (typeof json === \"string\") return Atom.fromJson(json);\n  json = __spreadValues({}, json);\n  for (const branch of NAMED_BRANCHES)\n    if (json[branch]) json[branch] = fromJson(json[branch]);\n  if (json.args) json.args = argumentsFromJson(json.args);\n  if (json.array) json.array = fromJson(json.array);\n  const type = json.type;\n  let result = void 0;\n  if (type === \"accent\") result = AccentAtom.fromJson(json);\n  if (type === \"array\") result = ArrayAtom.fromJson(json);\n  if (type === \"box\") result = BoxAtom.fromJson(json);\n  if (type === \"chem\") result = ChemAtom.fromJson(json);\n  if (type === \"composition\") result = CompositionAtom.fromJson(json);\n  if (type === \"delim\") result = MiddleDelimAtom.fromJson(json);\n  if (type === \"enclose\") result = EncloseAtom.fromJson(json);\n  if (type === \"error\") result = ErrorAtom.fromJson(json);\n  if (type === \"extensible-symbol\")\n    result = ExtensibleSymbolAtom.fromJson(json);\n  if (type === \"genfrac\") result = GenfracAtom.fromJson(json);\n  if (type === \"group\") result = GroupAtom.fromJson(json);\n  if (type === \"latex\") result = LatexAtom.fromJson(json);\n  if (type === \"latexgroup\") result = LatexGroupAtom.fromJson(json);\n  if (type === \"leftright\") result = LeftRightAtom.fromJson(json);\n  if (type === \"macro\") result = MacroAtom.fromJson(json);\n  if (type === \"macro-argument\") result = MacroArgumentAtom.fromJson(json);\n  if (type === \"operator\") result = OperatorAtom.fromJson(json);\n  if (type === \"overlap\") result = OverlapAtom.fromJson(json);\n  if (type === \"overunder\") result = OverunderAtom.fromJson(json);\n  if (type === \"placeholder\") result = PlaceholderAtom.fromJson(json);\n  if (type === \"prompt\") result = PromptAtom.fromJson(json);\n  if (type === \"phantom\") result = PhantomAtom.fromJson(json);\n  if (type === \"sizeddelim\") result = SizedDelimAtom.fromJson(json);\n  if (type === \"spacing\") result = SpacingAtom.fromJson(json);\n  if (type === \"subsup\") result = SubsupAtom.fromJson(json);\n  if (type === \"surd\") result = SurdAtom.fromJson(json);\n  if (type === \"text\") result = TextAtom.fromJson(json);\n  if (type === \"tooltip\") result = TooltipAtom.fromJson(json);\n  if (!result) {\n    console.assert(\n      !type || [\n        \"first\",\n        \"mbin\",\n        \"mrel\",\n        \"mclose\",\n        \"minner\",\n        \"mop\",\n        \"mopen\",\n        \"mord\",\n        \"mpunct\",\n        \"root\",\n        \"space\"\n      ].includes(type),\n      `MathLive 0.101.0: an unexpected atom type \"${type}\" was encountered. Add new atom constructors to \\`fromJson()\\` in \"atom.ts\"`\n    );\n    result = Atom.fromJson(json);\n  }\n  for (const branch of NAMED_BRANCHES)\n    if (json[branch]) result.setChildren(json[branch], branch);\n  if (json.verbatimLatex !== void 0)\n    result.verbatimLatex = json.verbatimLatex;\n  if (json.subsupPlacement) result.subsupPlacement = json.subsupPlacement;\n  if (json.explicitSubsupPlacement) result.explicitSubsupPlacement = true;\n  if (json.isFunction) result.isFunction = true;\n  if (json.skipBoundary) result.skipBoundary = true;\n  if (json.captureSelection) result.captureSelection = true;\n  return result;\n}\nfunction argumentsFromJson(json) {\n  if (!json) return void 0;\n  if (!Array.isArray(json)) return void 0;\n  return json.map((arg) => {\n    if (arg === \"<null>\") return null;\n    if (typeof arg === \"object\" && \"group\" in arg)\n      return { group: arg.group.map((x) => fromJson(x)) };\n    if (typeof arg === \"object\" && \"atoms\" in arg)\n      return arg.atoms.map((x) => fromJson(x));\n    return arg;\n  });\n}\n\n// src/editor-model/styling.ts\nfunction applyStyleToUnstyledAtoms(atom, style) {\n  if (!atom || !style) return;\n  if (isArray(atom)) {\n    atom.forEach((x) => applyStyleToUnstyledAtoms(x, style));\n  } else if (typeof atom === \"object\") {\n    if (!atom.style.color && !atom.style.backgroundColor && !atom.style.fontFamily && !atom.style.fontShape && !atom.style.fontSeries && !atom.style.fontSize && !atom.style.variant && !atom.style.variantStyle) {\n      atom.applyStyle(style);\n      applyStyleToUnstyledAtoms(atom.body, style);\n      applyStyleToUnstyledAtoms(atom.above, style);\n      applyStyleToUnstyledAtoms(atom.below, style);\n      applyStyleToUnstyledAtoms(atom.subscript, style);\n      applyStyleToUnstyledAtoms(atom.superscript, style);\n    }\n  }\n}\nfunction applyStyle(model, range2, style, options) {\n  function everyStyle(property, value) {\n    for (const atom of atoms) if (atom.style[property] !== value) return false;\n    return true;\n  }\n  range2 = model.normalizeRange(range2);\n  if (range2[0] === range2[1]) return false;\n  const atoms = model.getAtoms(range2, { includeChildren: true });\n  if (options.operation === \"toggle\") {\n    if (style.color && everyStyle(\"color\", style.color)) {\n      style.color = \"none\";\n      delete style.verbatimColor;\n    }\n    if (style.backgroundColor && everyStyle(\"backgroundColor\", style.backgroundColor)) {\n      style.backgroundColor = \"none\";\n      delete style.verbatimBackgroundColor;\n    }\n    if (style.fontFamily && everyStyle(\"fontFamily\", style.fontFamily)) {\n      style.fontFamily = \"none\";\n    }\n    if (style.fontSeries && everyStyle(\"fontSeries\", style.fontSeries)) {\n      style.fontSeries = \"auto\";\n    }\n    if (style.fontShape && everyStyle(\"fontShape\", style.fontShape)) {\n      style.fontShape = \"auto\";\n    }\n    if (style.fontSize && everyStyle(\"fontSize\", style.fontSize)) {\n      style.fontSize = DEFAULT_FONT_SIZE;\n    }\n    if (style.variant && everyStyle(\"variant\", style.variant)) {\n      style.variant = \"normal\";\n    }\n    if (style.variantStyle && everyStyle(\"variantStyle\", style.variantStyle)) {\n      style.variantStyle = \"\";\n    }\n  }\n  for (const atom of atoms) atom.applyStyle(style);\n  return true;\n}\nfunction addItalic(v) {\n  return {\n    \"up\": \"italic\",\n    \"bold\": \"bolditalic\",\n    \"italic\": \"italic\",\n    \"bolditalic\": \"bolditalic\",\n    \"\": \"italic\"\n  }[v != null ? v : \"\"];\n}\nfunction removeItalic(v) {\n  return {\n    \"up\": \"up\",\n    \"bold\": \"bold\",\n    \"italic\": void 0,\n    \"bolditalic\": \"bold\",\n    \"\": void 0\n  }[v != null ? v : \"\"];\n}\n\n// src/core/modes-math.ts\nvar VARIANTS = {\n  // Handle some special characters which are only available in \"main\" font (not \"math\")\n  \"main\": [\"Main-Regular\", \"ML__cmr\"],\n  \"main-italic\": [\"Main-Italic\", \"ML__cmr ML__it\"],\n  \"main-bold\": [\"Main-Bold\", \"ML__cmr ML__bold\"],\n  \"main-bolditalic\": [\"Main-BoldItalic\", \"ML__cmr ML__bold ML__it\"],\n  \"normal\": [\"Main-Regular\", \"ML__cmr\"],\n  // 'main' font. There is no 'math' regular (upright)\n  \"normal-bold\": [\"Main-Bold\", \"ML__mathbf\"],\n  // 'main' font. There is no 'math' bold\n  \"normal-italic\": [\"Math-Italic\", \"ML__mathit\"],\n  // Special metrics for 'math'\n  \"normal-bolditalic\": [\"Math-BoldItalic\", \"ML__mathbfit\"],\n  // Special metrics for 'math'\n  // Extended math symbols, arrows, etc.. at their standard Unicode codepoints\n  \"ams\": [\"AMS-Regular\", \"ML__ams\"],\n  \"ams-bold\": [\"AMS-Regular\", \"ML__ams ML__bold\"],\n  \"ams-italic\": [\"AMS-Regular\", \"ML__ams ML__it\"],\n  \"ams-bolditalic\": [\"AMS-Regular\", \"ML__ams ML__bold ML__it\"],\n  \"sans-serif\": [\"SansSerif-Regular\", \"ML__sans\"],\n  \"sans-serif-bold\": [\"SansSerif-Regular\", \"ML__sans ML__bold\"],\n  \"sans-serif-italic\": [\"SansSerif-Regular\", \"ML__sans ML__it\"],\n  \"sans-serif-bolditalic\": [\"SansSerif-Regular\", \"ML__sans ML__bold ML__it\"],\n  \"calligraphic\": [\"Caligraphic-Regular\", \"ML__cal\"],\n  \"calligraphic-bold\": [\"Caligraphic-Regular\", \"ML__cal ML__bold\"],\n  \"calligraphic-italic\": [\"Caligraphic-Regular\", \"ML__cal ML__it\"],\n  \"calligraphic-bolditalic\": [\"Caligraphic-Regular\", \"ML__cal ML__bold ML__it\"],\n  \"script\": [\"Script-Regular\", \"ML__script\"],\n  \"script-bold\": [\"Script-Regular\", \"ML__script ML__bold\"],\n  \"script-italic\": [\"Script-Regular\", \"ML__script ML__it\"],\n  \"script-bolditalic\": [\"Script-Regular\", \"ML__script ML__bold ML__it\"],\n  \"fraktur\": [\"Fraktur-Regular\", \"ML__frak\"],\n  \"fraktur-bold\": [\"Fraktur-Regular\", \"ML__frak ML__bold\"],\n  \"fraktur-italic\": [\"Fraktur-Regular\", \"ML__frak ML__it\"],\n  \"fraktur-bolditalic\": [\"Fraktur-Regular\", \"ML__frak ML__bold ML__it\"],\n  \"monospace\": [\"Typewriter-Regular\", \"ML__tt\"],\n  \"monospace-bold\": [\"Typewriter-Regular\", \"ML__tt ML__bold\"],\n  \"monospace-italic\": [\"Typewriter-Regular\", \"ML__tt ML__it\"],\n  \"monospace-bolditalic\": [\"Typewriter-Regular\", \"ML__tt ML__bold ML__it\"],\n  // Blackboard characters are 'A-Z' in the AMS font\n  \"double-struck\": [\"AMS-Regular\", \"ML__bb\"],\n  \"double-struck-bold\": [\"AMS-Regular\", \"ML__bb ML__bold\"],\n  \"double-struck-italic\": [\"AMS-Regular\", \"ML__bb ML_italic\"],\n  \"double-struck-bolditalic\": [\"AMS-Regular\", \"ML__bb ML_bolditalic\"]\n};\nvar VARIANT_REPERTOIRE = {\n  \"double-struck\": /^[A-Z ]$/,\n  \"script\": /^[A-Z ]$/,\n  \"calligraphic\": /^[\\dA-Z ]$/,\n  \"fraktur\": /^[\\dA-Za-z ]$|^[!\"#$%&'()*+,\\-./:;=?[]^’‘]$/,\n  \"monospace\": /^[\\dA-Za-z ]$|^[!\"&'()*+,\\-./:;=?@[\\]^_~\\u0131\\u0237\\u0393\\u0394\\u0398\\u039B\\u039E\\u03A0\\u03A3\\u03A5\\u03A8\\u03A9]$/,\n  \"sans-serif\": /^[\\dA-Za-z ]$|^[!\"&'()*+,\\-./:;=?@[\\]^_~\\u0131\\u0237\\u0393\\u0394\\u0398\\u039B\\u039E\\u03A0\\u03A3\\u03A5\\u03A8\\u03A9]$/\n};\nvar GREEK_LOWERCASE = /^[\\u03B1-\\u03C9]|\\u03D1|\\u03D5|\\u03D6|\\u03F1|\\u03F5]$/;\nvar GREEK_UPPERCASE = /^[\\u0393|\\u0394\\u0398\\u039B\\u039E\\u03A0\\u03A3\\u03A5\\u03A6\\u03A8\\u03A9]$/;\nvar LETTER_SHAPE_RANGES = [\n  /^[a-z]$/,\n  // Lowercase latin\n  /^[A-Z]$/,\n  // Uppercase latin\n  GREEK_LOWERCASE,\n  GREEK_UPPERCASE\n];\nvar LETTER_SHAPE_MODIFIER = {\n  iso: [\"it\", \"it\", \"it\", \"it\"],\n  tex: [\"it\", \"it\", \"it\", \"up\"],\n  french: [\"it\", \"up\", \"up\", \"up\"],\n  upright: [\"up\", \"up\", \"up\", \"up\"]\n};\nvar MathMode = class extends Mode {\n  constructor() {\n    super(\"math\");\n  }\n  createAtom(command, info, style) {\n    var _a3, _b3, _c2, _d2, _e, _f;\n    if (info === null) {\n      return new Atom({\n        type: \"mord\",\n        mode: \"math\",\n        command,\n        value: command,\n        style\n      });\n    }\n    let isFunction;\n    try {\n      isFunction = (_c2 = (_b3 = globalThis.MathfieldElement) == null ? void 0 : _b3.isFunction((_a3 = info.command) != null ? _a3 : command)) != null ? _c2 : false;\n    } catch (e) {\n      isFunction = false;\n    }\n    if (info.definitionType === \"symbol\") {\n      const result2 = new Atom({\n        type: (_d2 = info.type) != null ? _d2 : \"mord\",\n        mode: \"math\",\n        command: (_e = info.command) != null ? _e : command,\n        value: String.fromCodePoint(info.codepoint),\n        isFunction,\n        style\n      });\n      if (command.startsWith(\"\\\\\")) result2.verbatimLatex = command;\n      return result2;\n    }\n    const result = new Atom({\n      type: \"mord\",\n      mode: \"math\",\n      command: (_f = info.command) != null ? _f : command,\n      value: command,\n      isFunction,\n      style\n    });\n    if (command.startsWith(\"\\\\\")) result.verbatimLatex = command;\n    return result;\n  }\n  serialize(run, options) {\n    const result = emitBoldRun(run, __spreadProps(__spreadValues({}, options), { defaultMode: \"math\" }));\n    if (result.length === 0 || options.defaultMode !== \"text\") return result;\n    return [\"$ \", ...result, \" $\"];\n  }\n  getFont(box, style) {\n    var _a3, _b3;\n    console.assert(style.variant !== void 0);\n    if (style.fontFamily) {\n      const [fontName2, classes2] = VARIANTS[style.fontFamily];\n      if (classes2) box.classes += \" \" + classes2;\n      return fontName2;\n    }\n    let { variant } = style;\n    let { variantStyle } = style;\n    if (variant === \"normal\" && !variantStyle && /[\\u00A3\\u0131\\u0237]/.test(box.value)) {\n      variant = \"main\";\n      variantStyle = \"italic\";\n    }\n    if (variant === \"normal\" && !variantStyle && box.value.length === 1) {\n      let italicize = false;\n      LETTER_SHAPE_RANGES.forEach((x, i) => {\n        var _a4;\n        if (x.test(box.value) && LETTER_SHAPE_MODIFIER[(_a4 = style.letterShapeStyle) != null ? _a4 : \"tex\"][i] === \"it\")\n          italicize = true;\n      });\n      if (italicize) variantStyle = addItalic(variantStyle);\n    }\n    if (variantStyle === \"up\") variantStyle = void 0;\n    const styledVariant = variantStyle ? variant + \"-\" + variantStyle : variant;\n    console.assert(VARIANTS[styledVariant] !== void 0);\n    const [fontName, classes] = VARIANTS[styledVariant];\n    if (VARIANT_REPERTOIRE[variant] && !VARIANT_REPERTOIRE[variant].test(box.value)) {\n      let v = mathVariantToUnicode(box.value, variant, variantStyle);\n      if (!v) {\n        v = (_a3 = mathVariantToUnicode(box.value, variant)) != null ? _a3 : box.value;\n        box.classes += (_b3 = {\n          \"bold\": \" ML__bold\",\n          \"italic\": \" ML__it\",\n          \"bold-italic\": \" ML__bold ML__it\"\n        }[variantStyle != null ? variantStyle : \"\"]) != null ? _b3 : \"\";\n      }\n      box.value = v;\n      return null;\n    }\n    if (GREEK_LOWERCASE.test(box.value)) box.classes += \" lcGreek\";\n    if (classes) box.classes += \" \" + classes;\n    return fontName;\n  }\n};\nfunction emitBoldRun(run, options) {\n  return getPropertyRuns(run, \"bold\").map((x) => {\n    const weight = weightString(x[0]);\n    if (weight !== \"bold\") return joinLatex(emitVariantRun(x, options));\n    if (weightString(x[0].parent) === \"bold\")\n      return joinLatex(emitVariantRun(x, options));\n    const value = joinLatex(x.map((x2) => {\n      var _a3;\n      return (_a3 = x2.value) != null ? _a3 : \"\";\n    }));\n    if (/^[a-zA-Z0-9]+$/.test(value)) {\n      return latexCommand(\"\\\\mathbf\", joinLatex(emitVariantRun(x, options)));\n    }\n    return latexCommand(\"\\\\bm\", joinLatex(emitVariantRun(x, options)));\n  });\n}\nfunction emitVariantRun(run, options) {\n  const { parent } = run[0];\n  const contextVariant = variantString(parent);\n  return getPropertyRuns(run, \"variant\").map((x) => {\n    const variant = variantString(x[0]);\n    let command = \"\";\n    if (variant && variant !== contextVariant) {\n      command = {\n        \"calligraphic\": \"\\\\mathcal\",\n        \"calligraphic-uo\": \"\\\\mathcal\",\n        \"fraktur\": \"\\\\mathfrak\",\n        \"fraktur-uo\": \"\\\\mathfrak\",\n        \"double-struck\": \"\\\\mathbb\",\n        \"double-struck-uo\": \"\\\\mathbb\",\n        \"script\": \"\\\\mathscr\",\n        \"script-uo\": \"\\\\mathscr\",\n        \"monospace\": \"\\\\mathtt\",\n        \"monospace-uo\": \"\\\\mathtt\",\n        \"sans-serif\": \"\\\\mathsf\",\n        \"sans-serif-uo\": \"\\\\mathsf\",\n        \"normal\": \"\",\n        \"normal-up\": \"\\\\mathrm\",\n        \"normal-italic\": \"\\\\mathnormal\",\n        \"normal-bold\": \"\",\n        \"normal-bolditalic\": \"\\\\mathbfit\",\n        \"ams\": \"\",\n        \"ams-up\": \"\\\\mathrm\",\n        \"ams-italic\": \"\\\\mathit\",\n        \"ams-bold\": \"\",\n        \"ams-bolditalic\": \"\\\\mathbfit\",\n        \"main\": \"\",\n        \"main-up\": \"\\\\mathrm\",\n        \"main-italic\": \"\\\\mathit\",\n        \"main-bold\": \"\",\n        \"main-bolditalic\": \"\\\\mathbfit\"\n        // There are a few rare font families possible, which\n        // are not supported:\n        // mathbbm, mathbbmss, mathbbmtt, mathds, swab, goth\n        // In addition, the 'main' and 'math' font technically\n        // map to \\mathnormal{}\n      }[variant];\n      console.assert(command !== void 0);\n    }\n    const arg = joinLatex(x.map((x2) => x2._serialize(options)));\n    return !command ? arg : latexCommand(command, arg);\n  });\n}\nnew MathMode();\n\n// src/core/modes-text.ts\nfunction emitStringTextRun(run, options) {\n  return run.map((x) => x._serialize(options));\n}\nfunction emitFontShapeTextRun(run, options) {\n  return getPropertyRuns(run, \"fontShape\").map((x) => {\n    const s = emitStringTextRun(x, options);\n    const { fontShape } = x[0].style;\n    let command = \"\";\n    if (fontShape === \"it\") command = \"\\\\textit\";\n    if (fontShape === \"sl\") command = \"\\\\textsl\";\n    if (fontShape === \"sc\") command = \"\\\\textsc\";\n    if (fontShape === \"n\") command = \"\\\\textup\";\n    if (!command && fontShape)\n      return `{${latexCommand(\"\\\\fontshape\", fontShape)}${joinLatex(s)}}`;\n    return command ? latexCommand(command, joinLatex(s)) : joinLatex(s);\n  });\n}\nfunction emitFontSeriesTextRun(run, options) {\n  return getPropertyRuns(run, \"fontSeries\").map((x) => {\n    const s = emitFontShapeTextRun(x, options);\n    const { fontSeries } = x[0].style;\n    let command = \"\";\n    if (fontSeries === \"b\") command = \"\\\\textbf\";\n    if (fontSeries === \"l\") command = \"\\\\textlf\";\n    if (fontSeries === \"m\") command = \"\\\\textmd\";\n    if (fontSeries && !command)\n      return `{${latexCommand(\"\\\\fontseries\", fontSeries)}${joinLatex(s)}}`;\n    return command ? latexCommand(command, joinLatex(s)) : joinLatex(s);\n  });\n}\nfunction emitSizeTextRun(run, options) {\n  return getPropertyRuns(run, \"fontSize\").map((x) => {\n    var _a3, _b3;\n    const s = emitFontSeriesTextRun(x, options);\n    const command = (_b3 = [\n      \"\",\n      \"\\\\tiny\",\n      \"\\\\scriptsize\",\n      \"\\\\footnotesize\",\n      \"\\\\small\",\n      \"\\\\normalsize\",\n      \"\\\\large\",\n      \"\\\\Large\",\n      \"\\\\LARGE\",\n      \"\\\\huge\",\n      \"\\\\Huge\"\n    ][(_a3 = x[0].style.fontSize) != null ? _a3 : \"\"]) != null ? _b3 : \"\";\n    return command ? `${command} ${joinLatex(s)}` : joinLatex(s);\n  });\n}\nfunction emitFontFamilyTextRun(run, options, needsWrap) {\n  return getPropertyRuns(run, \"fontFamily\").map((x) => {\n    var _a3;\n    needsWrap = needsWrap && !x.every(\n      (x2) => x2.style.fontFamily || x2.style.fontShape || x2.style.fontSeries || x2.style.fontSize\n    );\n    const s = emitSizeTextRun(x, options);\n    const { fontFamily } = x[0].style;\n    const command = (_a3 = {\n      \"roman\": \"textrm\",\n      \"monospace\": \"texttt\",\n      \"sans-serif\": \"textsf\"\n    }[fontFamily != null ? fontFamily : \"\"]) != null ? _a3 : \"\";\n    if (command) return `\\\\${command}{${joinLatex(s)}}`;\n    if (fontFamily)\n      return `{\\\\fontfamily{${x[0].style.fontFamily}} ${joinLatex(s)}}`;\n    if (needsWrap) return `\\\\text{${joinLatex(s)}}`;\n    return joinLatex(s);\n  });\n}\nvar TEXT_FONT_CLASS = {\n  \"roman\": \"\",\n  \"sans-serif\": \"ML__sans\",\n  \"monospace\": \"ML__tt\"\n};\nvar TextMode = class extends Mode {\n  constructor() {\n    super(\"text\");\n  }\n  createAtom(command, info, style) {\n    if (!info) return null;\n    if (info.definitionType === \"symbol\") {\n      return new TextAtom(\n        command,\n        String.fromCodePoint(info.codepoint),\n        style != null ? style : {}\n      );\n    }\n    return null;\n  }\n  serialize(run, options) {\n    return emitFontFamilyTextRun(\n      run,\n      __spreadProps(__spreadValues({}, options), {\n        defaultMode: \"text\"\n      }),\n      options.defaultMode !== \"text\"\n    );\n  }\n  /**\n   * Return the font-family name\n   */\n  getFont(box, style) {\n    var _a3, _b3, _c2, _d2, _e;\n    const { fontFamily } = style;\n    if (TEXT_FONT_CLASS[fontFamily])\n      box.classes += \" \" + TEXT_FONT_CLASS[fontFamily];\n    else if (fontFamily) {\n      box.setStyle(\"font-family\", fontFamily);\n    }\n    if (style.fontShape) {\n      box.classes += \" \";\n      box.classes += (_a3 = {\n        it: \"ML__it\",\n        sl: \"ML__shape_sl\",\n        // Slanted\n        sc: \"ML__shape_sc\",\n        // Small caps\n        ol: \"ML__shape_ol\"\n        // Outline\n      }[style.fontShape]) != null ? _a3 : \"\";\n    }\n    if (style.fontSeries) {\n      const m = style.fontSeries.match(/(.?[lbm])?(.?[cx])?/);\n      if (m) {\n        box.classes += \" \";\n        box.classes += (_c2 = {\n          ul: \"ML__series_ul\",\n          el: \"ML__series_el\",\n          l: \"ML__series_l\",\n          sl: \"ML__series_sl\",\n          m: \"\",\n          // Medium (default)\n          sb: \"ML__series_sb\",\n          b: \"ML__bold\",\n          eb: \"ML__series_eb\",\n          ub: \"ML__series_ub\"\n        }[(_b3 = m[1]) != null ? _b3 : \"\"]) != null ? _c2 : \"\";\n        box.classes += \" \";\n        box.classes += (_e = {\n          uc: \"ML__series_uc\",\n          ec: \"ML__series_ec\",\n          c: \"ML__series_c\",\n          sc: \"ML__series_sc\",\n          n: \"\",\n          // Normal (default)\n          sx: \"ML__series_sx\",\n          x: \"ML__series_x\",\n          ex: \"ML__series_ex\",\n          ux: \"ML__series_ux\"\n        }[(_d2 = m[2]) != null ? _d2 : \"\"]) != null ? _e : \"\";\n      }\n    }\n    return \"Main-Regular\";\n  }\n};\nnew TextMode();\n\n// src/core/modes-latex.ts\nvar LatexMode = class extends Mode {\n  constructor() {\n    super(\"latex\");\n  }\n  createAtom(command) {\n    return new LatexAtom(command);\n  }\n  serialize(run, _options) {\n    return run.filter((x) => x instanceof LatexAtom && !x.isSuggestion).map((x) => x.value);\n  }\n  getFont() {\n    return null;\n  }\n};\nnew LatexMode();\n\n// src/editor/keyboard-layouts/dvorak.ts\nvar DVORAK = {\n  id: \"dvorak\",\n  locale: \"en\",\n  displayName: \"Dvorak\",\n  virtualLayout: \"dvorak\",\n  platform: \"\",\n  score: 0,\n  mapping: {\n    KeyA: [\"a\", \"A\", \"\\xE5\", \"\\xC5\"],\n    KeyB: [\"x\", \"X\", \"\\u2248\", \"\\u02DB\"],\n    KeyC: [\"j\", \"J\", \"\\u2206\", \"\\xD4\"],\n    KeyD: [\"e\", \"E\", \"\\xB4\", \"\\xB4\"],\n    KeyE: [\".\", \">\", \"\\u2265\", \"\\u02D8\"],\n    KeyF: [\"u\", \"U\", \"\\xA8\", \"\\xA8\"],\n    KeyG: [\"i\", \"I\", \"\\u02C6\", \"\\u02C6\"],\n    KeyH: [\"d\", \"D\", \"\\u2202\", \"\\xCE\"],\n    KeyI: [\"c\", \"C\", \"\\xE7\", \"\\xC7\"],\n    KeyJ: [\"h\", \"H\", \"\\u02D9\", \"\\xD3\"],\n    KeyK: [\"t\", \"T\", \"\\u2020\", \"\\u02C7\"],\n    KeyL: [\"n\", \"N\", \"\\u02DC\", \"\\u02DC\"],\n    KeyM: [\"m\", \"M\", \"\\xB5\", \"\\xC2\"],\n    KeyN: [\"b\", \"B\", \"\\u222B\", \"\\u0131\"],\n    KeyO: [\"r\", \"R\", \"\\xAE\", \"\\u2030\"],\n    KeyP: [\"l\", \"L\", \"\\xAC\", \"\\xD2\"],\n    KeyQ: [\"'\", '\"', \"\\xE6\", \"\\xC6\"],\n    KeyR: [\"p\", \"P\", \"\\u03C0\", \"\\u220F\"],\n    KeyS: [\"o\", \"O\", \"\\xF8\", \"\\xD8\"],\n    KeyT: [\"y\", \"Y\", \"\\xA5\", \"\\xC1\"],\n    KeyU: [\"g\", \"G\", \"\\xA9\", \"\\u02DD\"],\n    KeyV: [\"k\", \"K\", \"\\u02DA\", \"\\uF8FF\"],\n    KeyW: [\",\", \"<\", \"\\u2264\", \"\\xAF\"],\n    KeyX: [\"q\", \"Q\", \"\\u0153\", \"\\u0152\"],\n    KeyY: [\"f\", \"F\", \"\\u0192\", \"\\xCF\"],\n    KeyZ: [\";\", \":\", \"\\u2026\", \"\\xDA\"],\n    Digit1: [\"1\", \"!\", \"\\xA1\", \"\\u2044\"],\n    Digit2: [\"2\", \"@\", \"\\u2122\", \"\\u20AC\"],\n    Digit3: [\"3\", \"#\", \"\\xA3\", \"\\u2039\"],\n    Digit4: [\"4\", \"$\", \"\\xA2\", \"\\u203A\"],\n    Digit5: [\"5\", \"%\", \"\\u221E\", \"\\uFB01\"],\n    Digit6: [\"6\", \"^\", \"\\xA7\", \"\\uFB02\"],\n    Digit7: [\"7\", \"&\", \"\\xB6\", \"\\u2021\"],\n    Digit8: [\"8\", \"*\", \"\\u2022\", \"\\xB0\"],\n    Digit9: [\"9\", \"(\", \"\\xAA\", \"\\xB7\"],\n    Digit0: [\"0\", \")\", \"\\xBA\", \"\\u201A\"],\n    Space: [\" \", \" \", \" \", \" \"],\n    Minus: [\"[\", \"{\", \"\\u201C\", \"\\u201D\"],\n    Equal: [\"]\", \"}\", \"\\u2018\", \"\\u2019\"],\n    BracketLeft: [\"/\", \"?\", \"\\xF7\", \"\\xBF\"],\n    BracketRight: [\"=\", \"+\", \"\\u2260\", \"\\xB1\"],\n    Backslash: [\"\\\\\", \"|\", \"\\xAB\", \"\\xBB\"],\n    Semicolon: [\"s\", \"S\", \"\\xDF\", \"\\xCD\"],\n    Quote: [\"-\", \"_\", \"\\u2013\", \"\\u2014\"],\n    Backquote: [\"`\", \"~\", \"`\", \"`\"],\n    Comma: [\"w\", \"W\", \"\\u2211\", \"\\u201E\"],\n    Period: [\"v\", \"V\", \"\\u221A\", \"\\u25CA\"],\n    Slash: [\"z\", \"Z\", \"\\u03A9\", \"\\xB8\"],\n    NumpadDivide: [\"/\", \"/\", \"/\", \"/\"],\n    NumpadMultiply: [\"*\", \"*\", \"*\", \"*\"],\n    NumpadSubtract: [\"-\", \"-\", \"-\", \"-\"],\n    NumpadAdd: [\"+\", \"+\", \"+\", \"+\"],\n    Numpad1: [\"1\", \"1\", \"1\", \"1\"],\n    Numpad2: [\"2\", \"2\", \"2\", \"2\"],\n    Numpad3: [\"3\", \"3\", \"3\", \"3\"],\n    Numpad4: [\"4\", \"4\", \"4\", \"4\"],\n    Numpad5: [\"5\", \"5\", \"5\", \"5\"],\n    Numpad6: [\"6\", \"6\", \"6\", \"6\"],\n    Numpad7: [\"7\", \"7\", \"7\", \"7\"],\n    Numpad8: [\"8\", \"8\", \"8\", \"8\"],\n    Numpad9: [\"9\", \"9\", \"9\", \"9\"],\n    Numpad0: [\"0\", \"0\", \"0\", \"0\"],\n    NumpadDecimal: [\".\", \".\", \".\", \".\"],\n    IntlBackslash: [\"\\xA7\", \"\\xB1\", \"\\xA7\", \"\\xB1\"],\n    NumpadEqual: [\"=\", \"=\", \"=\", \"=\"],\n    AudioVolumeUp: [\"\", \"=\", \"\", \"=\"]\n  }\n};\n\n// src/editor/keyboard-layouts/english.ts\nvar APPLE_ENGLISH = {\n  id: \"apple.en-intl\",\n  displayName: \"English (international)\",\n  virtualLayout: \"qwerty\",\n  platform: \"apple\",\n  locale: \"en\",\n  score: 0,\n  mapping: {\n    KeyA: [\"a\", \"A\", \"\\xE5\", \"\\xC5\"],\n    KeyB: [\"b\", \"B\", \"\\u222B\", \"\\u0131\"],\n    KeyC: [\"c\", \"C\", \"\\xE7\", \"\\xC7\"],\n    KeyD: [\"d\", \"D\", \"\\u2202\", \"\\xCE\"],\n    KeyE: [\"e\", \"E\", \"\\xB4\", \"\\xB4\"],\n    KeyF: [\"f\", \"F\", \"\\u0192\", \"\\xCF\"],\n    KeyG: [\"g\", \"G\", \"\\xA9\", \"\\u02DD\"],\n    KeyH: [\"h\", \"H\", \"\\u02D9\", \"\\xD3\"],\n    KeyI: [\"i\", \"I\", \"\\u02C6\", \"\\u02C6\"],\n    KeyJ: [\"j\", \"J\", \"\\u2206\", \"\\xD4\"],\n    KeyK: [\"k\", \"K\", \"\\u02DA\", \"\\uF8FF\"],\n    KeyL: [\"l\", \"L\", \"\\xAC\", \"\\xD2\"],\n    KeyM: [\"m\", \"M\", \"\\xB5\", \"\\xC2\"],\n    KeyN: [\"n\", \"N\", \"\\u02DC\", \"\\u02DC\"],\n    KeyO: [\"o\", \"O\", \"\\xF8\", \"\\xD8\"],\n    KeyP: [\"p\", \"P\", \"\\u03C0\", \"\\u220F\"],\n    KeyQ: [\"q\", \"Q\", \"\\u0153\", \"\\u0152\"],\n    KeyR: [\"r\", \"R\", \"\\xAE\", \"\\u2030\"],\n    KeyS: [\"s\", \"S\", \"\\xDF\", \"\\xCD\"],\n    KeyT: [\"t\", \"T\", \"\\u2020\", \"\\u02C7\"],\n    KeyU: [\"u\", \"U\", \"\\xA8\", \"\\xA8\"],\n    KeyV: [\"v\", \"V\", \"\\u221A\", \"\\u25CA\"],\n    KeyW: [\"w\", \"W\", \"\\u2211\", \"\\u201E\"],\n    KeyX: [\"x\", \"X\", \"\\u2248\", \"\\u02DB\"],\n    KeyY: [\"y\", \"Y\", \"\\xA5\", \"\\xC1\"],\n    KeyZ: [\"z\", \"Z\", \"\\u03A9\", \"\\xB8\"],\n    Digit1: [\"1\", \"!\", \"\\xA1\", \"\\u2044\"],\n    Digit2: [\"2\", \"@\", \"\\u2122\", \"\\u20AC\"],\n    Digit3: [\"3\", \"#\", \"\\xA3\", \"\\u2039\"],\n    Digit4: [\"4\", \"$\", \"\\xA2\", \"\\u203A\"],\n    Digit5: [\"5\", \"%\", \"\\u221E\", \"\\uFB01\"],\n    Digit6: [\"6\", \"^\", \"\\xA7\", \"\\uFB02\"],\n    Digit7: [\"7\", \"&\", \"\\xB6\", \"\\u2021\"],\n    Digit8: [\"8\", \"*\", \"\\u2022\", \"\\xB0\"],\n    Digit9: [\"9\", \"(\", \"\\xAA\", \"\\xB7\"],\n    Digit0: [\"0\", \")\", \"\\xBA\", \"\\u201A\"],\n    Space: [\" \", \" \", \" \", \" \"],\n    Minus: [\"-\", \"_\", \"\\u2013\", \"\\u2014\"],\n    Equal: [\"=\", \"+\", \"\\u2260\", \"\\xB1\"],\n    BracketLeft: [\"[\", \"{\", \"\\u201C\", \"\\u201D\"],\n    BracketRight: [\"]\", \"}\", \"\\u2018\", \"\\u2019\"],\n    Backslash: [\"\\\\\", \"|\", \"\\xAB\", \"\\xBB\"],\n    Semicolon: [\";\", \":\", \"\\u2026\", \"\\xDA\"],\n    Quote: [\"'\", '\"', \"\\xE6\", \"\\xC6\"],\n    Backquote: [\"`\", \"\\u02DC\", \"`\", \"`\"],\n    Comma: [\",\", \"<\", \"\\u2264\", \"\\xAF\"],\n    Period: [\".\", \">\", \"\\u2265\", \"\\u02D8\"],\n    Slash: [\"/\", \"?\", \"\\xF7\", \"\\xBF\"],\n    NumpadDivide: [\"/\", \"/\", \"/\", \"/\"],\n    NumpadMultiply: [\"*\", \"*\", \"*\", \"*\"],\n    NumpadSubtract: [\"-\", \"-\", \"-\", \"-\"],\n    NumpadAdd: [\"+\", \"+\", \"+\", \"+\"],\n    Numpad1: [\"1\", \"1\", \"1\", \"1\"],\n    Numpad2: [\"2\", \"2\", \"2\", \"2\"],\n    Numpad3: [\"3\", \"3\", \"3\", \"3\"],\n    Numpad4: [\"4\", \"4\", \"4\", \"4\"],\n    Numpad5: [\"5\", \"5\", \"5\", \"5\"],\n    Numpad6: [\"6\", \"6\", \"6\", \"6\"],\n    Numpad7: [\"7\", \"7\", \"7\", \"7\"],\n    Numpad8: [\"8\", \"8\", \"8\", \"8\"],\n    Numpad9: [\"9\", \"9\", \"9\", \"9\"],\n    Numpad0: [\"0\", \"0\", \"0\", \"0\"],\n    NumpadDecimal: [\".\", \".\", \".\", \".\"],\n    IntlBackslash: [\"\\xA7\", \"\\xB1\", \"\\xA7\", \"\\xB1\"],\n    NumpadEqual: [\"=\", \"=\", \"=\", \"=\"],\n    AudioVolumeUp: [\"\", \"=\", \"\", \"=\"]\n  }\n};\nvar WINDOWS_ENGLISH = {\n  id: \"windows.en-intl\",\n  displayName: \"English (international)\",\n  platform: \"windows\",\n  virtualLayout: \"qwerty\",\n  locale: \"en\",\n  score: 0,\n  mapping: {\n    KeyA: [\"a\", \"A\", \"\\xE1\", \"\\xC1\"],\n    KeyB: [\"b\", \"B\", \"\", \"\"],\n    KeyC: [\"c\", \"C\", \"\\xA9\", \"\\xA2\"],\n    KeyD: [\"d\", \"D\", \"\\xF0\", \"\\xD0\"],\n    KeyE: [\"e\", \"E\", \"\\xE9\", \"\\xC9\"],\n    KeyF: [\"f\", \"F\", \"\", \"\"],\n    KeyG: [\"g\", \"G\", \"\", \"\"],\n    KeyH: [\"h\", \"H\", \"\", \"\"],\n    KeyI: [\"i\", \"I\", \"\\xED\", \"\\xCD\"],\n    KeyJ: [\"j\", \"J\", \"\", \"\"],\n    KeyK: [\"k\", \"K\", \"\", \"\"],\n    KeyL: [\"l\", \"L\", \"\\xF8\", \"\\xD8\"],\n    KeyM: [\"m\", \"M\", \"\\xB5\", \"\"],\n    KeyN: [\"n\", \"N\", \"\\xF1\", \"\\xD1\"],\n    KeyO: [\"o\", \"O\", \"\\xF3\", \"\\xD3\"],\n    KeyP: [\"p\", \"P\", \"\\xF6\", \"\\xD6\"],\n    KeyQ: [\"q\", \"Q\", \"\\xE4\", \"\\xC4\"],\n    KeyR: [\"r\", \"R\", \"\\xAE\", \"\"],\n    KeyS: [\"s\", \"S\", \"\\xDF\", \"\\xA7\"],\n    KeyT: [\"t\", \"T\", \"\\xFE\", \"\\xDE\"],\n    KeyU: [\"u\", \"U\", \"\\xFA\", \"\\xDA\"],\n    KeyV: [\"v\", \"V\", \"\", \"\"],\n    KeyW: [\"w\", \"W\", \"\\xE5\", \"\\xC5\"],\n    KeyX: [\"x\", \"X\", \"\", \"\"],\n    KeyY: [\"y\", \"Y\", \"\\xFC\", \"\\xDC\"],\n    KeyZ: [\"z\", \"Z\", \"\\xE6\", \"\\xC6\"],\n    Digit1: [\"1\", \"!\", \"\\xA1\", \"\\xB9\"],\n    Digit2: [\"2\", \"@\", \"\\xB2\", \"\"],\n    Digit3: [\"3\", \"#\", \"\\xB3\", \"\"],\n    Digit4: [\"4\", \"$\", \"\\xA4\", \"\\xA3\"],\n    Digit5: [\"5\", \"%\", \"\\u20AC\", \"\"],\n    Digit6: [\"6\", \"^\", \"\\xBC\", \"\"],\n    Digit7: [\"7\", \"&\", \"\\xBD\", \"\"],\n    Digit8: [\"8\", \"*\", \"\\xBE\", \"\"],\n    Digit9: [\"9\", \"(\", \"\\u2018\", \"\"],\n    Digit0: [\"0\", \")\", \"\\u2019\", \"\"],\n    Space: [\" \", \" \", \"\", \"\"],\n    Minus: [\"-\", \"_\", \"\\xA5\", \"\"],\n    Equal: [\"=\", \"+\", \"\\xD7\", \"\\xF7\"],\n    BracketLeft: [\"[\", \"{\", \"\\xAB\", \"\"],\n    BracketRight: [\"]\", \"}\", \"\\xBB\", \"\"],\n    Backslash: [\"\\\\\", \"|\", \"\\xAC\", \"\\xA6\"],\n    Semicolon: [\";\", \":\", \"\\xB6\", \"\\xB0\"],\n    Quote: [\"'\", '\"', \"\\xB4\", \"\\xA8\"],\n    Backquote: [\"`\", \"~\", \"\", \"\"],\n    Comma: [\",\", \"<\", \"\\xE7\", \"\\xC7\"],\n    Period: [\".\", \">\", \"\", \"\"],\n    Slash: [\"/\", \"?\", \"\\xBF\", \"\"],\n    NumpadDivide: [\"/\", \"/\", \"\", \"\"],\n    NumpadMultiply: [\"*\", \"*\", \"\", \"\"],\n    NumpadSubtract: [\"-\", \"-\", \"\", \"\"],\n    NumpadAdd: [\"+\", \"+\", \"\", \"\"],\n    IntlBackslash: [\"\\\\\", \"|\", \"\", \"\"]\n  }\n};\nvar LINUX_ENGLISH = {\n  id: \"linux.en\",\n  displayName: \"English\",\n  platform: \"linux\",\n  virtualLayout: \"qwerty\",\n  locale: \"en\",\n  score: 0,\n  mapping: {\n    KeyA: [\"a\", \"A\", \"a\", \"A\"],\n    KeyB: [\"b\", \"B\", \"b\", \"B\"],\n    KeyC: [\"c\", \"C\", \"c\", \"C\"],\n    KeyD: [\"d\", \"D\", \"d\", \"D\"],\n    KeyE: [\"e\", \"E\", \"e\", \"E\"],\n    KeyF: [\"f\", \"F\", \"f\", \"F\"],\n    KeyG: [\"g\", \"G\", \"g\", \"G\"],\n    KeyH: [\"h\", \"H\", \"h\", \"H\"],\n    KeyI: [\"i\", \"I\", \"i\", \"I\"],\n    KeyJ: [\"j\", \"J\", \"j\", \"J\"],\n    KeyK: [\"k\", \"K\", \"k\", \"K\"],\n    KeyL: [\"l\", \"L\", \"l\", \"L\"],\n    KeyM: [\"m\", \"M\", \"m\", \"M\"],\n    KeyN: [\"n\", \"N\", \"n\", \"N\"],\n    KeyO: [\"o\", \"O\", \"o\", \"O\"],\n    KeyP: [\"p\", \"P\", \"p\", \"P\"],\n    KeyQ: [\"q\", \"Q\", \"q\", \"Q\"],\n    KeyR: [\"r\", \"R\", \"r\", \"R\"],\n    KeyS: [\"s\", \"S\", \"s\", \"S\"],\n    KeyT: [\"t\", \"T\", \"t\", \"T\"],\n    KeyU: [\"u\", \"U\", \"u\", \"U\"],\n    KeyV: [\"v\", \"V\", \"v\", \"V\"],\n    KeyW: [\"w\", \"W\", \"w\", \"W\"],\n    KeyX: [\"x\", \"X\", \"x\", \"X\"],\n    KeyY: [\"y\", \"Y\", \"y\", \"Y\"],\n    KeyZ: [\"z\", \"Z\", \"z\", \"Z\"],\n    Digit1: [\"1\", \"!\", \"1\", \"!\"],\n    Digit2: [\"2\", \"@\", \"2\", \"@\"],\n    Digit3: [\"3\", \"#\", \"3\", \"#\"],\n    Digit4: [\"4\", \"$\", \"4\", \"$\"],\n    Digit5: [\"5\", \"%\", \"5\", \"%\"],\n    Digit6: [\"6\", \"^\", \"6\", \"^\"],\n    Digit7: [\"7\", \"&\", \"7\", \"&\"],\n    Digit8: [\"8\", \"*\", \"8\", \"*\"],\n    Digit9: [\"9\", \"(\", \"9\", \"(\"],\n    Digit0: [\"0\", \")\", \"0\", \")\"],\n    Space: [\" \", \" \", \" \", \" \"],\n    Minus: [\"-\", \"_\", \"-\", \"_\"],\n    Equal: [\"=\", \"+\", \"=\", \"+\"],\n    BracketLeft: [\"[\", \"{\", \"[\", \"{\"],\n    BracketRight: [\"]\", \"}\", \"]\", \"}\"],\n    Backslash: [\"\\\\\", \"|\", \"\\\\\", \"|\"],\n    Semicolon: [\";\", \":\", \";\", \":\"],\n    Quote: [\"'\", '\"', \"'\", '\"'],\n    Backquote: [\"`\", \"~\", \"`\", \"~\"],\n    Comma: [\",\", \"<\", \",\", \"<\"],\n    Period: [\".\", \">\", \".\", \">\"],\n    Slash: [\"/\", \"?\", \"/\", \"?\"],\n    NumpadDivide: [\"/\", \"/\", \"/\", \"/\"],\n    NumpadMultiply: [\"*\", \"*\", \"*\", \"*\"],\n    NumpadSubtract: [\"-\", \"-\", \"-\", \"-\"],\n    NumpadAdd: [\"+\", \"+\", \"+\", \"+\"],\n    Numpad1: [\"1\", \"1\", \"1\", \"1\"],\n    Numpad2: [\"2\", \"2\", \"2\", \"2\"],\n    Numpad3: [\"3\", \"3\", \"3\", \"3\"],\n    Numpad4: [\"4\", \"4\", \"4\", \"4\"],\n    Numpad5: [\"5\", \"5\", \"5\", \"5\"],\n    Numpad6: [\"6\", \"6\", \"6\", \"6\"],\n    Numpad7: [\"7\", \"7\", \"7\", \"7\"],\n    Numpad8: [\"8\", \"8\", \"8\", \"8\"],\n    Numpad9: [\"9\", \"9\", \"9\", \"9\"],\n    Numpad0: [\"0\", \"0\", \"0\", \"0\"],\n    NumpadDecimal: [\"\", \".\", \"\", \".\"],\n    IntlBackslash: [\"<\", \">\", \"|\", \"\\xA6\"],\n    NumpadEqual: [\"=\", \"=\", \"=\", \"=\"],\n    NumpadComma: [\".\", \".\", \".\", \".\"],\n    NumpadParenLeft: [\"(\", \"(\", \"(\", \"(\"],\n    NumpadParenRight: [\")\", \")\", \")\", \")\"]\n  }\n};\n\n// src/editor/keyboard-layouts/french.ts\nvar APPLE_FRENCH = {\n  id: \"apple.french\",\n  locale: \"fr\",\n  displayName: \"French\",\n  platform: \"apple\",\n  virtualLayout: \"azerty\",\n  score: 0,\n  mapping: {\n    KeyA: [\"q\", \"Q\", \"\\u2021\", \"\\u03A9\"],\n    KeyB: [\"b\", \"B\", \"\\xDF\", \"\\u222B\"],\n    KeyC: [\"c\", \"C\", \"\\xA9\", \"\\xA2\"],\n    KeyD: [\"d\", \"D\", \"\\u2202\", \"\\u2206\"],\n    KeyE: [\"e\", \"E\", \"\\xEA\", \"\\xCA\"],\n    KeyF: [\"f\", \"F\", \"\\u0192\", \"\\xB7\"],\n    KeyG: [\"g\", \"G\", \"\\uFB01\", \"\\uFB02\"],\n    KeyH: [\"h\", \"H\", \"\\xCC\", \"\\xCE\"],\n    KeyI: [\"i\", \"I\", \"\\xEE\", \"\\xEF\"],\n    KeyJ: [\"j\", \"J\", \"\\xCF\", \"\\xCD\"],\n    KeyK: [\"k\", \"K\", \"\\xC8\", \"\\xCB\"],\n    KeyL: [\"l\", \"L\", \"\\xAC\", \"|\"],\n    KeyM: [\",\", \"?\", \"\\u221E\", \"\\xBF\"],\n    KeyN: [\"n\", \"N\", \"~\", \"\\u0131\"],\n    KeyO: [\"o\", \"O\", \"\\u0153\", \"\\u0152\"],\n    KeyP: [\"p\", \"P\", \"\\u03C0\", \"\\u220F\"],\n    KeyQ: [\"a\", \"A\", \"\\xE6\", \"\\xC6\"],\n    KeyR: [\"r\", \"R\", \"\\xAE\", \"\\u201A\"],\n    KeyS: [\"s\", \"S\", \"\\xD2\", \"\\u2211\"],\n    KeyT: [\"t\", \"T\", \"\\u2020\", \"\\u2122\"],\n    KeyU: [\"u\", \"U\", \"\\xBA\", \"\\xAA\"],\n    KeyV: [\"v\", \"V\", \"\\u25CA\", \"\\u221A\"],\n    KeyW: [\"z\", \"Z\", \"\\xC2\", \"\\xC5\"],\n    KeyX: [\"x\", \"X\", \"\\u2248\", \"\\u2044\"],\n    KeyY: [\"y\", \"Y\", \"\\xDA\", \"\\u0178\"],\n    KeyZ: [\"w\", \"W\", \"\\u2039\", \"\\u203A\"],\n    Digit1: [\"&\", \"1\", \"\\uF8FF\", \"\\xB4\"],\n    Digit2: [\"\\xE9\", \"2\", \"\\xEB\", \"\\u201E\"],\n    Digit3: ['\"', \"3\", \"\\u201C\", \"\\u201D\"],\n    Digit4: [\"'\", \"4\", \"\\u2018\", \"\\u2019\"],\n    Digit5: [\"(\", \"5\", \"{\", \"[\"],\n    Digit6: [\"\\xA7\", \"6\", \"\\xB6\", \"\\xE5\"],\n    Digit7: [\"\\xE8\", \"7\", \"\\xAB\", \"\\xBB\"],\n    Digit8: [\"!\", \"8\", \"\\xA1\", \"\\xDB\"],\n    Digit9: [\"\\xE7\", \"9\", \"\\xC7\", \"\\xC1\"],\n    Digit0: [\"\\xE0\", \"0\", \"\\xF8\", \"\\xD8\"],\n    Space: [\" \", \" \", \" \", \" \"],\n    Minus: [\")\", \"\\xB0\", \"}\", \"]\"],\n    Equal: [\"-\", \"_\", \"\\u2014\", \"\\u2013\"],\n    BracketLeft: [\"^\", \"\\xA8\", \"\\xF4\", \"\\xD4\"],\n    BracketRight: [\"$\", \"*\", \"\\u20AC\", \"\\xA5\"],\n    Backslash: [\"`\", \"\\xA3\", \"@\", \"#\"],\n    Semicolon: [\"m\", \"M\", \"\\xB5\", \"\\xD3\"],\n    Quote: [\"\\xF9\", \"%\", \"\\xD9\", \"\\u2030\"],\n    Backquote: [\"<\", \">\", \"\\u2264\", \"\\u2265\"],\n    Comma: [\";\", \".\", \"\\u2026\", \"\\u2022\"],\n    Period: [\":\", \"/\", \"\\xF7\", \"\\\\\"],\n    Slash: [\"=\", \"+\", \"\\u2260\", \"\\xB1\"],\n    NumpadDivide: [\"/\", \"/\", \"/\", \"/\"],\n    NumpadMultiply: [\"*\", \"*\", \"*\", \"*\"],\n    NumpadSubtract: [\"-\", \"-\", \"-\", \"-\"],\n    NumpadAdd: [\"+\", \"+\", \"+\", \"+\"],\n    NumpadDecimal: [\",\", \".\", \",\", \".\"],\n    IntlBackslash: [\"@\", \"#\", \"\\u2022\", \"\\u0178\"],\n    NumpadEqual: [\"=\", \"=\", \"=\", \"=\"]\n  }\n};\nvar WINDOWS_FRENCH = {\n  id: \"windows.french\",\n  locale: \"fr\",\n  displayName: \"French\",\n  virtualLayout: \"azerty\",\n  platform: \"windows\",\n  score: 0,\n  mapping: {\n    KeyA: [\"q\", \"Q\", \"\", \"\"],\n    KeyB: [\"b\", \"B\", \"\", \"\"],\n    KeyC: [\"c\", \"C\", \"\", \"\"],\n    KeyD: [\"d\", \"D\", \"\", \"\"],\n    KeyE: [\"e\", \"E\", \"\\u20AC\", \"\"],\n    KeyF: [\"f\", \"F\", \"\", \"\"],\n    KeyG: [\"g\", \"G\", \"\", \"\"],\n    KeyH: [\"h\", \"H\", \"\", \"\"],\n    KeyI: [\"i\", \"I\", \"\", \"\"],\n    KeyJ: [\"j\", \"J\", \"\", \"\"],\n    KeyK: [\"k\", \"K\", \"\", \"\"],\n    KeyL: [\"l\", \"L\", \"\", \"\"],\n    KeyM: [\",\", \"?\", \"\", \"\"],\n    KeyN: [\"n\", \"N\", \"\", \"\"],\n    KeyO: [\"o\", \"O\", \"\", \"\"],\n    KeyP: [\"p\", \"P\", \"\", \"\"],\n    KeyQ: [\"a\", \"A\", \"\", \"\"],\n    KeyR: [\"r\", \"R\", \"\", \"\"],\n    KeyS: [\"s\", \"S\", \"\", \"\"],\n    KeyT: [\"t\", \"T\", \"\", \"\"],\n    KeyU: [\"u\", \"U\", \"\", \"\"],\n    KeyV: [\"v\", \"V\", \"\", \"\"],\n    KeyW: [\"z\", \"Z\", \"\", \"\"],\n    KeyX: [\"x\", \"X\", \"\", \"\"],\n    KeyY: [\"y\", \"Y\", \"\", \"\"],\n    KeyZ: [\"w\", \"W\", \"\", \"\"],\n    Digit1: [\"&\", \"1\", \"\", \"\"],\n    Digit2: [\"\\xE9\", \"2\", \"~\", \"\"],\n    Digit3: ['\"', \"3\", \"#\", \"\"],\n    Digit4: [\"'\", \"4\", \"{\", \"\"],\n    Digit5: [\"(\", \"5\", \"[\", \"\"],\n    Digit6: [\"-\", \"6\", \"|\", \"\"],\n    Digit7: [\"\\xE8\", \"7\", \"`\", \"\"],\n    Digit8: [\"_\", \"8\", \"\\\\\", \"\"],\n    Digit9: [\"\\xE7\", \"9\", \"^\", \"\"],\n    Digit0: [\"\\xE0\", \"0\", \"@\", \"\"],\n    Space: [\" \", \" \", \"\", \"\"],\n    Minus: [\")\", \"\\xB0\", \"]\", \"\"],\n    Equal: [\"=\", \"+\", \"}\", \"\"],\n    BracketLeft: [\"^\", \"\\xA8\", \"\", \"\"],\n    BracketRight: [\"$\", \"\\xA3\", \"\\xA4\", \"\"],\n    Backslash: [\"*\", \"\\xB5\", \"\", \"\"],\n    Semicolon: [\"m\", \"M\", \"\", \"\"],\n    Quote: [\"\\xF9\", \"%\", \"\", \"\"],\n    Backquote: [\"\\xB2\", \"\", \"\", \"\"],\n    Comma: [\";\", \".\", \"\", \"\"],\n    Period: [\":\", \"/\", \"\", \"\"],\n    Slash: [\"!\", \"\\xA7\", \"\", \"\"],\n    NumpadDivide: [\"/\", \"/\", \"\", \"\"],\n    NumpadMultiply: [\"*\", \"*\", \"\", \"\"],\n    NumpadSubtract: [\"-\", \"-\", \"\", \"\"],\n    NumpadAdd: [\"+\", \"+\", \"\", \"\"],\n    IntlBackslash: [\"<\", \">\", \"\", \"\"]\n  }\n};\nvar LINUX_FRENCH = {\n  id: \"linux.french\",\n  locale: \"fr\",\n  displayName: \"French\",\n  virtualLayout: \"azerty\",\n  platform: \"linux\",\n  score: 0,\n  mapping: {\n    KeyA: [\"q\", \"Q\", \"@\", \"\\u03A9\"],\n    KeyB: [\"b\", \"B\", \"\\u201D\", \"\\u2019\"],\n    KeyC: [\"c\", \"C\", \"\\xA2\", \"\\xA9\"],\n    KeyD: [\"d\", \"D\", \"\\xF0\", \"\\xD0\"],\n    KeyE: [\"e\", \"E\", \"\\u20AC\", \"\\xA2\"],\n    KeyF: [\"f\", \"F\", \"\\u0111\", \"\\xAA\"],\n    KeyG: [\"g\", \"G\", \"\\u014B\", \"\\u014A\"],\n    KeyH: [\"h\", \"H\", \"\\u0127\", \"\\u0126\"],\n    KeyI: [\"i\", \"I\", \"\\u2192\", \"\\u0131\"],\n    KeyJ: [\"j\", \"J\", \"\\u0309\", \"\\u031B\"],\n    KeyK: [\"k\", \"K\", \"\\u0138\", \"&\"],\n    KeyL: [\"l\", \"L\", \"\\u0142\", \"\\u0141\"],\n    KeyM: [\",\", \"?\", \"\\u0301\", \"\\u030B\"],\n    KeyN: [\"n\", \"N\", \"n\", \"N\"],\n    KeyO: [\"o\", \"O\", \"\\xF8\", \"\\xD8\"],\n    KeyP: [\"p\", \"P\", \"\\xFE\", \"\\xDE\"],\n    KeyQ: [\"a\", \"A\", \"\\xE6\", \"\\xC6\"],\n    KeyR: [\"r\", \"R\", \"\\xB6\", \"\\xAE\"],\n    KeyS: [\"s\", \"S\", \"\\xDF\", \"\\xA7\"],\n    KeyT: [\"t\", \"T\", \"\\u0167\", \"\\u0166\"],\n    KeyU: [\"u\", \"U\", \"\\u2193\", \"\\u2191\"],\n    KeyV: [\"v\", \"V\", \"\\u201C\", \"\\u2018\"],\n    KeyW: [\"z\", \"Z\", \"\\xAB\", \"<\"],\n    KeyX: [\"x\", \"X\", \"\\xBB\", \">\"],\n    KeyY: [\"y\", \"Y\", \"\\u2190\", \"\\xA5\"],\n    KeyZ: [\"w\", \"W\", \"\\u0142\", \"\\u0141\"],\n    Digit1: [\"&\", \"1\", \"\\xB9\", \"\\xA1\"],\n    Digit2: [\"\\xE9\", \"2\", \"~\", \"\\u215B\"],\n    Digit3: ['\"', \"3\", \"#\", \"\\xA3\"],\n    Digit4: [\"'\", \"4\", \"{\", \"$\"],\n    Digit5: [\"(\", \"5\", \"[\", \"\\u215C\"],\n    Digit6: [\"-\", \"6\", \"|\", \"\\u215D\"],\n    Digit7: [\"\\xE8\", \"7\", \"`\", \"\\u215E\"],\n    Digit8: [\"_\", \"8\", \"\\\\\", \"\\u2122\"],\n    Digit9: [\"\\xE7\", \"9\", \"^\", \"\\xB1\"],\n    Digit0: [\"\\xE0\", \"0\", \"@\", \"\\xB0\"],\n    Enter: [\"\\r\", \"\\r\", \"\\r\", \"\\r\"],\n    Escape: [\"\\x1B\", \"\\x1B\", \"\\x1B\", \"\\x1B\"],\n    Backspace: [\"\\b\", \"\\b\", \"\\b\", \"\\b\"],\n    Tab: [\"\t\", \"\", \"\t\", \"\"],\n    Space: [\" \", \" \", \" \", \" \"],\n    Minus: [\")\", \"\\xB0\", \"]\", \"\\xBF\"],\n    Equal: [\"=\", \"+\", \"}\", \"\\u0328\"],\n    BracketLeft: [\"\\u0302\", \"\\u0308\", \"\\u0308\", \"\\u030A\"],\n    BracketRight: [\"$\", \"\\xA3\", \"\\xA4\", \"\\u0304\"],\n    Backslash: [\"*\", \"\\xB5\", \"\\u0300\", \"\\u0306\"],\n    Semicolon: [\"m\", \"M\", \"\\xB5\", \"\\xBA\"],\n    Quote: [\"\\xF9\", \"%\", \"\\u0302\", \"\\u030C\"],\n    Backquote: [\"\\xB2\", \"~\", \"\\xAC\", \"\\xAC\"],\n    Comma: [\";\", \".\", \"\\u2500\", \"\\xD7\"],\n    Period: [\":\", \"/\", \"\\xB7\", \"\\xF7\"],\n    Slash: [\"!\", \"\\xA7\", \"\\u0323\", \"\\u0307\"],\n    NumpadMultiply: [\"*\", \"*\", \"*\", \"*\"],\n    NumpadSubtract: [\"-\", \"-\", \"-\", \"-\"],\n    NumpadAdd: [\"+\", \"+\", \"+\", \"+\"],\n    NumpadDecimal: [\"\", \".\", \"\", \".\"],\n    IntlBackslash: [\"<\", \">\", \"|\", \"\\xA6\"]\n  }\n};\n\n// src/editor/keyboard-layouts/german.ts\nvar APPLE_GERMAN = {\n  id: \"apple.german\",\n  locale: \"de\",\n  displayName: \"German\",\n  virtualLayout: \"qwertz\",\n  platform: \"apple\",\n  score: 0,\n  mapping: {\n    KeyA: [\"a\", \"A\", \"\\xE5\", \"\\xC5\"],\n    KeyB: [\"b\", \"B\", \"\\u222B\", \"\\u2039\"],\n    KeyC: [\"c\", \"C\", \"\\xE7\", \"\\xC7\"],\n    KeyD: [\"d\", \"D\", \"\\u2202\", \"\\u2122\"],\n    KeyE: [\"e\", \"E\", \"\\u20AC\", \"\\u2030\"],\n    KeyF: [\"f\", \"F\", \"\\u0192\", \"\\xCF\"],\n    KeyG: [\"g\", \"G\", \"\\xA9\", \"\\xCC\"],\n    KeyH: [\"h\", \"H\", \"\\xAA\", \"\\xD3\"],\n    KeyI: [\"i\", \"I\", \"\\u2044\", \"\\xDB\"],\n    KeyJ: [\"j\", \"J\", \"\\xBA\", \"\\u0131\"],\n    KeyK: [\"k\", \"K\", \"\\u2206\", \"\\u02C6\"],\n    KeyL: [\"l\", \"L\", \"@\", \"\\uFB02\"],\n    KeyM: [\"m\", \"M\", \"\\xB5\", \"\\u02D8\"],\n    KeyN: [\"n\", \"N\", \"~\", \"\\u203A\"],\n    KeyO: [\"o\", \"O\", \"\\xF8\", \"\\xD8\"],\n    KeyP: [\"p\", \"P\", \"\\u03C0\", \"\\u220F\"],\n    KeyQ: [\"q\", \"Q\", \"\\xAB\", \"\\xBB\"],\n    KeyR: [\"r\", \"R\", \"\\xAE\", \"\\xB8\"],\n    KeyS: [\"s\", \"S\", \"\\u201A\", \"\\xCD\"],\n    KeyT: [\"t\", \"T\", \"\\u2020\", \"\\u02DD\"],\n    KeyU: [\"u\", \"U\", \"\\xA8\", \"\\xC1\"],\n    KeyV: [\"v\", \"V\", \"\\u221A\", \"\\u25CA\"],\n    KeyW: [\"w\", \"W\", \"\\u2211\", \"\\u201E\"],\n    KeyX: [\"x\", \"X\", \"\\u2248\", \"\\xD9\"],\n    KeyY: [\"z\", \"Z\", \"\\u03A9\", \"\\u02C7\"],\n    KeyZ: [\"y\", \"Y\", \"\\xA5\", \"\\u2021\"],\n    Digit1: [\"1\", \"!\", \"\\xA1\", \"\\xAC\"],\n    Digit2: [\"2\", '\"', \"\\u201C\", \"\\u201D\"],\n    Digit3: [\"3\", \"\\xA7\", \"\\xB6\", \"#\"],\n    Digit4: [\"4\", \"$\", \"\\xA2\", \"\\xA3\"],\n    Digit5: [\"5\", \"%\", \"[\", \"\\uFB01\"],\n    Digit6: [\"6\", \"&\", \"]\", \"^\"],\n    Digit7: [\"7\", \"/\", \"|\", \"\\\\\"],\n    Digit8: [\"8\", \"(\", \"{\", \"\\u02DC\"],\n    Digit9: [\"9\", \")\", \"}\", \"\\xB7\"],\n    Digit0: [\"0\", \"=\", \"\\u2260\", \"\\xAF\"],\n    Space: [\" \", \" \", \" \", \" \"],\n    Minus: [\"\\xDF\", \"?\", \"\\xBF\", \"\\u02D9\"],\n    Equal: [\"\\xB4\", \"`\", \"'\", \"\\u02DA\"],\n    BracketLeft: [\"\\xFC\", \"\\xDC\", \"\\u2022\", \"\\xB0\"],\n    BracketRight: [\"+\", \"*\", \"\\xB1\", \"\\uF8FF\"],\n    Backslash: [\"#\", \"'\", \"\\u2018\", \"\\u2019\"],\n    Semicolon: [\"\\xF6\", \"\\xD6\", \"\\u0153\", \"\\u0152\"],\n    Quote: [\"\\xE4\", \"\\xC4\", \"\\xE6\", \"\\xC6\"],\n    Backquote: [\"<\", \">\", \"\\u2264\", \"\\u2265\"],\n    Comma: [\",\", \";\", \"\\u221E\", \"\\u02DB\"],\n    Period: [\".\", \":\", \"\\u2026\", \"\\xF7\"],\n    Slash: [\"-\", \"_\", \"\\u2013\", \"\\u2014\"],\n    NumpadDivide: [\"/\", \"/\", \"/\", \"/\"],\n    NumpadMultiply: [\"*\", \"*\", \"*\", \"*\"],\n    NumpadSubtract: [\"-\", \"-\", \"-\", \"-\"],\n    NumpadAdd: [\"+\", \"+\", \"+\", \"+\"],\n    NumpadDecimal: [\",\", \",\", \".\", \".\"],\n    IntlBackslash: [\"^\", \"\\xB0\", \"\\u201E\", \"\\u201C\"],\n    NumpadEqual: [\"=\", \"=\", \"=\", \"=\"]\n  }\n};\nvar WINDOWS_GERMAN = {\n  id: \"windows.german\",\n  locale: \"de\",\n  displayName: \"German\",\n  platform: \"windows\",\n  virtualLayout: \"qwertz\",\n  score: 0,\n  mapping: {\n    KeyA: [\"a\", \"A\", \"\", \"\"],\n    KeyB: [\"b\", \"B\", \"\", \"\"],\n    KeyC: [\"c\", \"C\", \"\", \"\"],\n    KeyD: [\"d\", \"D\", \"\", \"\"],\n    KeyE: [\"e\", \"E\", \"\\u20AC\", \"\"],\n    KeyF: [\"f\", \"F\", \"\", \"\"],\n    KeyG: [\"g\", \"G\", \"\", \"\"],\n    KeyH: [\"h\", \"H\", \"\", \"\"],\n    KeyI: [\"i\", \"I\", \"\", \"\"],\n    KeyJ: [\"j\", \"J\", \"\", \"\"],\n    KeyK: [\"k\", \"K\", \"\", \"\"],\n    KeyL: [\"l\", \"L\", \"\", \"\"],\n    KeyM: [\"m\", \"M\", \"\\xB5\", \"\"],\n    KeyN: [\"n\", \"N\", \"\", \"\"],\n    KeyO: [\"o\", \"O\", \"\", \"\"],\n    KeyP: [\"p\", \"P\", \"\", \"\"],\n    KeyQ: [\"q\", \"Q\", \"@\", \"\"],\n    KeyR: [\"r\", \"R\", \"\", \"\"],\n    KeyS: [\"s\", \"S\", \"\", \"\"],\n    KeyT: [\"t\", \"T\", \"\", \"\"],\n    KeyU: [\"u\", \"U\", \"\", \"\"],\n    KeyV: [\"v\", \"V\", \"\", \"\"],\n    KeyW: [\"w\", \"W\", \"\", \"\"],\n    KeyX: [\"x\", \"X\", \"\", \"\"],\n    KeyY: [\"z\", \"Z\", \"\", \"\"],\n    KeyZ: [\"y\", \"Y\", \"\", \"\"],\n    Digit1: [\"1\", \"!\", \"\", \"\"],\n    Digit2: [\"2\", '\"', \"\\xB2\", \"\"],\n    Digit3: [\"3\", \"\\xA7\", \"\\xB3\", \"\"],\n    Digit4: [\"4\", \"$\", \"\", \"\"],\n    Digit5: [\"5\", \"%\", \"\", \"\"],\n    Digit6: [\"6\", \"&\", \"\", \"\"],\n    Digit7: [\"7\", \"/\", \"{\", \"\"],\n    Digit8: [\"8\", \"(\", \"[\", \"\"],\n    Digit9: [\"9\", \")\", \"]\", \"\"],\n    Digit0: [\"0\", \"=\", \"}\", \"\"],\n    Space: [\" \", \" \", \"\", \"\"],\n    Minus: [\"\\xDF\", \"?\", \"\\\\\", \"\\u1E9E\"],\n    Equal: [\"\\xB4\", \"`\", \"\", \"\"],\n    BracketLeft: [\"\\xFC\", \"\\xDC\", \"\", \"\"],\n    BracketRight: [\"+\", \"*\", \"~\", \"\"],\n    Backslash: [\"#\", \"'\", \"\", \"\"],\n    Semicolon: [\"\\xF6\", \"\\xD6\", \"\", \"\"],\n    Quote: [\"\\xE4\", \"\\xC4\", \"\", \"\"],\n    Backquote: [\"^\", \"\\xB0\", \"\", \"\"],\n    Comma: [\",\", \";\", \"\", \"\"],\n    Period: [\".\", \":\", \"\", \"\"],\n    Slash: [\"-\", \"_\", \"\", \"\"],\n    NumpadDivide: [\"/\", \"/\", \"\", \"\"],\n    NumpadMultiply: [\"*\", \"*\", \"\", \"\"],\n    NumpadSubtract: [\"-\", \"-\", \"\", \"\"],\n    NumpadAdd: [\"+\", \"+\", \"\", \"\"],\n    IntlBackslash: [\"<\", \">\", \"|\", \"\"]\n  }\n};\nvar LINUX_GERMAN = {\n  id: \"linux.german\",\n  locale: \"de\",\n  displayName: \"German\",\n  platform: \"windows\",\n  virtualLayout: \"qwertz\",\n  score: 0,\n  mapping: {\n    KeyA: [\"a\", \"A\", \"\\xE6\", \"\\xC6\"],\n    KeyB: [\"b\", \"B\", \"\\u201C\", \"\\u2018\"],\n    KeyC: [\"c\", \"C\", \"\\xA2\", \"\\xA9\"],\n    KeyD: [\"d\", \"D\", \"\\xF0\", \"\\xD0\"],\n    KeyE: [\"e\", \"E\", \"\\u20AC\", \"\\u20AC\"],\n    KeyF: [\"f\", \"F\", \"\\u0111\", \"\\xAA\"],\n    KeyG: [\"g\", \"G\", \"\\u014B\", \"\\u014A\"],\n    KeyH: [\"h\", \"H\", \"\\u0127\", \"\\u0126\"],\n    KeyI: [\"i\", \"I\", \"\\u2192\", \"\\u0131\"],\n    KeyJ: [\"j\", \"J\", \"\\u0323\", \"\\u0307\"],\n    KeyK: [\"k\", \"K\", \"\\u0138\", \"&\"],\n    KeyL: [\"l\", \"L\", \"\\u0142\", \"\\u0141\"],\n    KeyM: [\"m\", \"M\", \"\\xB5\", \"\\xBA\"],\n    KeyN: [\"n\", \"N\", \"\\u201D\", \"\\u2019\"],\n    KeyO: [\"o\", \"O\", \"\\xF8\", \"\\xD8\"],\n    KeyP: [\"p\", \"P\", \"\\xFE\", \"\\xDE\"],\n    KeyQ: [\"q\", \"Q\", \"@\", \"\\u03A9\"],\n    KeyR: [\"r\", \"R\", \"\\xB6\", \"\\xAE\"],\n    KeyS: [\"s\", \"S\", \"\\u017F\", \"\\u1E9E\"],\n    KeyT: [\"t\", \"T\", \"\\u0167\", \"\\u0166\"],\n    KeyU: [\"u\", \"U\", \"\\u2193\", \"\\u2191\"],\n    KeyV: [\"v\", \"V\", \"\\u201E\", \"\\u201A\"],\n    KeyW: [\"w\", \"W\", \"\\u0142\", \"\\u0141\"],\n    KeyX: [\"x\", \"X\", \"\\xAB\", \"\\u2039\"],\n    KeyY: [\"z\", \"Z\", \"\\u2190\", \"\\xA5\"],\n    KeyZ: [\"y\", \"Y\", \"\\xBB\", \"\\u203A\"],\n    Digit1: [\"1\", \"!\", \"\\xB9\", \"\\xA1\"],\n    Digit2: [\"2\", '\"', \"\\xB2\", \"\\u215B\"],\n    Digit3: [\"3\", \"\\xA7\", \"\\xB3\", \"\\xA3\"],\n    Digit4: [\"4\", \"$\", \"\\xBC\", \"\\xA4\"],\n    Digit5: [\"5\", \"%\", \"\\xBD\", \"\\u215C\"],\n    Digit6: [\"6\", \"&\", \"\\xAC\", \"\\u215D\"],\n    Digit7: [\"7\", \"/\", \"{\", \"\\u215E\"],\n    Digit8: [\"8\", \"(\", \"[\", \"\\u2122\"],\n    Digit9: [\"9\", \")\", \"]\", \"\\xB1\"],\n    Digit0: [\"0\", \"=\", \"}\", \"\\xB0\"],\n    Enter: [\"\\r\", \"\\r\", \"\\r\", \"\\r\"],\n    Escape: [\"\\x1B\", \"\\x1B\", \"\\x1B\", \"\\x1B\"],\n    Backspace: [\"\\b\", \"\\b\", \"\\b\", \"\\b\"],\n    Tab: [\"\t\", \"\", \"\t\", \"\"],\n    Space: [\" \", \" \", \" \", \" \"],\n    Minus: [\"\\xDF\", \"?\", \"\\\\\", \"\\xBF\"],\n    Equal: [\"\\u0301\", \"\\u0300\", \"\\u0327\", \"\\u0328\"],\n    BracketLeft: [\"\\xFC\", \"\\xDC\", \"\\u0308\", \"\\u030A\"],\n    BracketRight: [\"+\", \"*\", \"~\", \"\\xAF\"],\n    Backslash: [\"#\", \"'\", \"\\u2019\", \"\\u0306\"],\n    Semicolon: [\"\\xF6\", \"\\xD6\", \"\\u030B\", \"\\u0323\"],\n    Quote: [\"\\xE4\", \"\\xC4\", \"\\u0302\", \"\\u030C\"],\n    Backquote: [\"\\u0302\", \"\\xB0\", \"\\u2032\", \"\\u2033\"],\n    Comma: [\",\", \";\", \"\\xB7\", \"\\xD7\"],\n    Period: [\".\", \":\", \"\\u2026\", \"\\xF7\"],\n    Slash: [\"-\", \"_\", \"\\u2013\", \"\\u2014\"],\n    PrintScreen: [\"\", \"\", \"\", \"\"],\n    PageUp: [\"/\", \"/\", \"/\", \"/\"],\n    NumpadMultiply: [\"*\", \"*\", \"*\", \"*\"],\n    NumpadSubtract: [\"-\", \"-\", \"-\", \"-\"],\n    NumpadAdd: [\"+\", \"+\", \"+\", \"+\"],\n    Numpad1: [\"\", \"1\", \"\", \"1\"],\n    Numpad2: [\"\", \"2\", \"\", \"2\"],\n    Numpad3: [\"\", \"3\", \"\", \"3\"],\n    Numpad4: [\"\", \"4\", \"\", \"4\"],\n    Numpad5: [\"\", \"5\", \"\", \"5\"],\n    Numpad6: [\"\", \"6\", \"\", \"6\"],\n    Numpad7: [\"\", \"7\", \"\", \"7\"],\n    Numpad8: [\"\", \"8\", \"\", \"8\"],\n    Numpad9: [\"\", \"9\", \"\", \"9\"],\n    Numpad0: [\"\", \"0\", \"\", \"0\"],\n    NumpadDecimal: [\"\", \",\", \"\", \",\"],\n    IntlBackslash: [\"<\", \">\", \"|\", \"\\u0331\"],\n    AltRight: [\"\\r\", \"\\r\", \"\\r\", \"\\r\"],\n    MetaRight: [\".\", \".\", \".\", \".\"]\n  }\n};\n\n// src/editor/keyboard-layouts/spanish.ts\nvar APPLE_SPANISH = {\n  id: \"apple.spanish\",\n  locale: \"es\",\n  displayName: \"Spanish ISO\",\n  platform: \"apple\",\n  virtualLayout: \"qwerty\",\n  score: 0,\n  mapping: {\n    KeyA: [\"a\", \"A\", \"\\xE5\", \"\\xC5\"],\n    KeyB: [\"b\", \"B\", \"\\xDF\", \"\"],\n    KeyC: [\"c\", \"C\", \"\\xA9\", \" \"],\n    KeyD: [\"d\", \"D\", \"\\u2202\", \"\\u2206\"],\n    KeyE: [\"e\", \"E\", \"\\u20AC\", \"\\u20AC\"],\n    KeyF: [\"f\", \"F\", \"\\u0192\", \"\\uFB01\"],\n    KeyG: [\"g\", \"G\", \"\\uF8FF\", \"\\uFB02\"],\n    KeyH: [\"h\", \"H\", \"\\u2122\", \" \"],\n    KeyI: [\"i\", \"I\", \" \", \" \"],\n    KeyJ: [\"j\", \"J\", \"\\xB6\", \"\\xAF\"],\n    KeyK: [\"k\", \"K\", \"\\xA7\", \"\\u02C7\"],\n    KeyL: [\"l\", \"L\", \" \", \"\\u02D8\"],\n    KeyM: [\"m\", \"M\", \"\\xB5\", \"\\u02DA\"],\n    KeyN: [\"n\", \"N\", \" \", \"\\u02D9\"],\n    KeyO: [\"o\", \"O\", \"\\xF8\", \"\\xD8\"],\n    KeyP: [\"p\", \"P\", \"\\u03C0\", \"\\u220F\"],\n    KeyQ: [\"q\", \"Q\", \"\\u0153\", \"\\u0152\"],\n    KeyR: [\"r\", \"R\", \"\\xAE\", \" \"],\n    KeyS: [\"s\", \"S\", \"\\u222B\", \" \"],\n    KeyT: [\"t\", \"T\", \"\\u2020\", \"\\u2021\"],\n    KeyU: [\"u\", \"U\", \" \", \" \"],\n    KeyV: [\"v\", \"V\", \"\\u221A\", \"\\u25CA\"],\n    KeyW: [\"w\", \"W\", \"\\xE6\", \"\\xC6\"],\n    KeyX: [\"x\", \"X\", \"\\u2211\", \"\\u203A\"],\n    KeyY: [\"y\", \"Y\", \"\\xA5\", \" \"],\n    KeyZ: [\"z\", \"Z\", \"\\u03A9\", \"\\u2039\"],\n    Digit1: [\"1\", \"!\", \"|\", \"\\u0131\"],\n    Digit2: [\"2\", '\"', \"@\", \"\\u02DD\"],\n    Digit3: [\"3\", \"\\xB7\", \"#\", \"\\u2022\"],\n    Digit4: [\"4\", \"$\", \"\\xA2\", \"\\xA3\"],\n    Digit5: [\"5\", \"%\", \"\\u221E\", \"\\u2030\"],\n    Digit6: [\"6\", \"&\", \"\\xAC\", \" \"],\n    Digit7: [\"7\", \"/\", \"\\xF7\", \"\\u2044\"],\n    Digit8: [\"8\", \"(\", \"\\u201C\", \"\\u2018\"],\n    Digit9: [\"9\", \")\", \"\\u201D\", \"\\u2019\"],\n    Digit0: [\"0\", \"=\", \"\\u2260\", \"\\u2248\"],\n    Space: [\" \", \" \", \" \", \" \"],\n    Minus: [\"'\", \"?\", \"\\xB4\", \"\\xB8\"],\n    Equal: [\"\\xA1\", \"\\xBF\", \"\\u201A\", \"\\u02DB\"],\n    BracketLeft: [\"`\", \"^\", \"[\", \"\\u02C6\"],\n    BracketRight: [\"+\", \"*\", \"]\", \"\\xB1\"],\n    Backslash: [\"\\xE7\", \"\\xC7\", \"}\", \"\\xBB\"],\n    Semicolon: [\"\\xF1\", \"\\xD1\", \"~\", \"\\u02DC\"],\n    Quote: [\"\\xB4\", \"\\xA8\", \"{\", \"\\xAB\"],\n    Backquote: [\"<\", \">\", \"\\u2264\", \"\\u2265\"],\n    Comma: [\",\", \";\", \"\\u201E\", \"\"],\n    Period: [\".\", \":\", \"\\u2026\", \"\\u2026\"],\n    Slash: [\"-\", \"_\", \"\\u2013\", \"\\u2014\"],\n    NumpadDivide: [\"/\", \"/\", \"/\", \"/\"],\n    NumpadMultiply: [\"*\", \"*\", \"*\", \"*\"],\n    NumpadSubtract: [\"-\", \"-\", \"-\", \"-\"],\n    NumpadAdd: [\"+\", \"+\", \"+\", \"+\"],\n    Numpad1: [\"1\", \"1\", \"1\", \"1\"],\n    Numpad2: [\"2\", \"2\", \"2\", \"2\"],\n    Numpad3: [\"3\", \"3\", \"3\", \"3\"],\n    Numpad4: [\"4\", \"4\", \"4\", \"4\"],\n    Numpad5: [\"5\", \"5\", \"5\", \"5\"],\n    Numpad6: [\"6\", \"6\", \"6\", \"6\"],\n    Numpad7: [\"7\", \"7\", \"7\", \"7\"],\n    Numpad8: [\"8\", \"8\", \"8\", \"8\"],\n    Numpad9: [\"9\", \"9\", \"9\", \"9\"],\n    Numpad0: [\"0\", \"0\", \"0\", \"0\"],\n    NumpadDecimal: [\",\", \",\", \",\", \",\"],\n    IntlBackslash: [\"\\xBA\", \"\\xAA\", \"\\\\\", \"\\xB0\"]\n  }\n};\nvar WINDOWS_SPANISH = {\n  id: \"windows.spanish\",\n  locale: \"es\",\n  displayName: \"Spanish\",\n  platform: \"windows\",\n  virtualLayout: \"qwerty\",\n  score: 0,\n  mapping: {\n    KeyA: [\"a\", \"A\", \"\", \"\"],\n    KeyB: [\"b\", \"B\", \"\", \"\"],\n    KeyC: [\"c\", \"C\", \"\", \"\"],\n    KeyD: [\"d\", \"D\", \"\", \"\"],\n    KeyE: [\"e\", \"E\", \"\\u20AC\", \"\"],\n    KeyF: [\"f\", \"F\", \"\", \"\"],\n    KeyG: [\"g\", \"G\", \"\", \"\"],\n    KeyH: [\"h\", \"H\", \"\", \"\"],\n    KeyI: [\"i\", \"I\", \"\", \"\"],\n    KeyJ: [\"j\", \"J\", \"\", \"\"],\n    KeyK: [\"k\", \"K\", \"\", \"\"],\n    KeyL: [\"l\", \"L\", \"\", \"\"],\n    KeyM: [\"m\", \"M\", \"\", \"\"],\n    KeyN: [\"n\", \"N\", \"\", \"\"],\n    KeyO: [\"o\", \"O\", \"\", \"\"],\n    KeyP: [\"p\", \"P\", \"\", \"\"],\n    KeyQ: [\"q\", \"Q\", \"\", \"\"],\n    KeyR: [\"r\", \"R\", \"\", \"\"],\n    KeyS: [\"s\", \"S\", \"\", \"\"],\n    KeyT: [\"t\", \"T\", \"\", \"\"],\n    KeyU: [\"u\", \"U\", \"\", \"\"],\n    KeyV: [\"v\", \"V\", \"\", \"\"],\n    KeyW: [\"w\", \"W\", \"\", \"\"],\n    KeyX: [\"x\", \"X\", \"\", \"\"],\n    KeyY: [\"y\", \"Y\", \"\", \"\"],\n    KeyZ: [\"z\", \"Z\", \"\", \"\"],\n    Digit1: [\"1\", \"!\", \"|\", \"\"],\n    Digit2: [\"2\", '\"', \"@\", \"\"],\n    Digit3: [\"3\", \"\\xB7\", \"#\", \"\"],\n    Digit4: [\"4\", \"$\", \"~\", \"\"],\n    Digit5: [\"5\", \"%\", \"\\u20AC\", \"\"],\n    Digit6: [\"6\", \"&\", \"\\xAC\", \"\"],\n    Digit7: [\"7\", \"/\", \"\", \"\"],\n    Digit8: [\"8\", \"(\", \"\", \"\"],\n    Digit9: [\"9\", \")\", \"\", \"\"],\n    Digit0: [\"0\", \"=\", \"\", \"\"],\n    Space: [\" \", \" \", \"\", \"\"],\n    Minus: [\"'\", \"?\", \"\", \"\"],\n    Equal: [\"\\xA1\", \"\\xBF\", \"\", \"\"],\n    BracketLeft: [\"`\", \"^\", \"[\", \"\"],\n    BracketRight: [\"+\", \"*\", \"]\", \"\"],\n    Backslash: [\"\\xE7\", \"\\xC7\", \"}\", \"\"],\n    Semicolon: [\"\\xF1\", \"\\xD1\", \"\", \"\"],\n    Quote: [\"\\xB4\", \"\\xA8\", \"{\", \"\"],\n    Backquote: [\"\\xBA\", \"\\xAA\", \"\\\\\", \"\"],\n    Comma: [\",\", \";\", \"\", \"\"],\n    Period: [\".\", \":\", \"\", \"\"],\n    Slash: [\"-\", \"_\", \"\", \"\"],\n    NumpadDivide: [\"/\", \"/\", \"\", \"\"],\n    NumpadMultiply: [\"*\", \"*\", \"\", \"\"],\n    NumpadSubtract: [\"-\", \"-\", \"\", \"\"],\n    NumpadAdd: [\"+\", \"+\", \"\", \"\"],\n    IntlBackslash: [\"<\", \">\", \"\", \"\"]\n  }\n};\nvar LINUX_SPANISH = {\n  id: \"linux.spanish\",\n  locale: \"es\",\n  displayName: \"Spanish\",\n  platform: \"linux\",\n  virtualLayout: \"qwerty\",\n  score: 0,\n  mapping: {\n    KeyA: [\"a\", \"A\", \"\\xE6\", \"\\xC6\"],\n    KeyB: [\"b\", \"B\", \"\\u201D\", \"\\u2019\"],\n    KeyC: [\"c\", \"C\", \"\\xA2\", \"\\xA9\"],\n    KeyD: [\"d\", \"D\", \"\\xF0\", \"\\xD0\"],\n    KeyE: [\"e\", \"E\", \"\\u20AC\", \"\\xA2\"],\n    KeyF: [\"f\", \"F\", \"\\u0111\", \"\\xAA\"],\n    KeyG: [\"g\", \"G\", \"\\u014B\", \"\\u014A\"],\n    KeyH: [\"h\", \"H\", \"\\u0127\", \"\\u0126\"],\n    KeyI: [\"i\", \"I\", \"\\u2192\", \"\\u0131\"],\n    KeyJ: [\"j\", \"J\", \"\\u0309\", \"\\u031B\"],\n    KeyK: [\"k\", \"K\", \"\\u0138\", \"&\"],\n    KeyL: [\"l\", \"L\", \"\\u0142\", \"\\u0141\"],\n    KeyM: [\"m\", \"M\", \"\\xB5\", \"\\xBA\"],\n    KeyN: [\"n\", \"N\", \"n\", \"N\"],\n    KeyO: [\"o\", \"O\", \"\\xF8\", \"\\xD8\"],\n    KeyP: [\"p\", \"P\", \"\\xFE\", \"\\xDE\"],\n    KeyQ: [\"q\", \"Q\", \"@\", \"\\u03A9\"],\n    KeyR: [\"r\", \"R\", \"\\xB6\", \"\\xAE\"],\n    KeyS: [\"s\", \"S\", \"\\xDF\", \"\\xA7\"],\n    KeyT: [\"t\", \"T\", \"\\u0167\", \"\\u0166\"],\n    KeyU: [\"u\", \"U\", \"\\u2193\", \"\\u2191\"],\n    KeyV: [\"v\", \"V\", \"\\u201C\", \"\\u2018\"],\n    KeyW: [\"w\", \"W\", \"\\u0142\", \"\\u0141\"],\n    KeyX: [\"x\", \"X\", \"\\xBB\", \">\"],\n    KeyY: [\"y\", \"Y\", \"\\u2190\", \"\\xA5\"],\n    KeyZ: [\"z\", \"Z\", \"\\xAB\", \"<\"],\n    Digit1: [\"1\", \"!\", \"|\", \"\\xA1\"],\n    Digit2: [\"2\", '\"', \"@\", \"\\u215B\"],\n    Digit3: [\"3\", \"\\xB7\", \"#\", \"\\xA3\"],\n    Digit4: [\"4\", \"$\", \"~\", \"$\"],\n    Digit5: [\"5\", \"%\", \"\\xBD\", \"\\u215C\"],\n    Digit6: [\"6\", \"&\", \"\\xAC\", \"\\u215D\"],\n    Digit7: [\"7\", \"/\", \"{\", \"\\u215E\"],\n    Digit8: [\"8\", \"(\", \"[\", \"\\u2122\"],\n    Digit9: [\"9\", \")\", \"]\", \"\\xB1\"],\n    Digit0: [\"0\", \"=\", \"}\", \"\\xB0\"],\n    Enter: [\"\\r\", \"\\r\", \"\\r\", \"\\r\"],\n    Escape: [\"\\x1B\", \"\\x1B\", \"\\x1B\", \"\\x1B\"],\n    Backspace: [\"\\b\", \"\\b\", \"\\b\", \"\\b\"],\n    Tab: [\"\t\", \"\", \"\t\", \"\"],\n    Space: [\" \", \" \", \" \", \" \"],\n    Minus: [\"'\", \"?\", \"\\\\\", \"\\xBF\"],\n    Equal: [\"\\xA1\", \"\\xBF\", \"\\u0303\", \"~\"],\n    BracketLeft: [\"\\u0300\", \"\\u0302\", \"[\", \"\\u030A\"],\n    BracketRight: [\"+\", \"*\", \"]\", \"\\u0304\"],\n    Backslash: [\"\\xE7\", \"\\xC7\", \"}\", \"\\u0306\"],\n    Semicolon: [\"\\xF1\", \"\\xD1\", \"~\", \"\\u030B\"],\n    Quote: [\"\\u0301\", \"\\u0308\", \"{\", \"{\"],\n    Backquote: [\"\\xBA\", \"\\xAA\", \"\\\\\", \"\\\\\"],\n    Comma: [\",\", \";\", \"\\u2500\", \"\\xD7\"],\n    Period: [\".\", \":\", \"\\xB7\", \"\\xF7\"],\n    Slash: [\"-\", \"_\", \"\\u0323\", \"\\u0307\"],\n    NumpadDivide: [\"/\", \"/\", \"/\", \"/\"],\n    NumpadMultiply: [\"*\", \"*\", \"*\", \"*\"],\n    NumpadSubtract: [\"-\", \"-\", \"-\", \"-\"],\n    NumpadAdd: [\"+\", \"+\", \"+\", \"+\"],\n    NumpadEnter: [\"\\r\", \"\\r\", \"\\r\", \"\\r\"],\n    Numpad1: [\"\", \"1\", \"\", \"1\"],\n    Numpad2: [\"\", \"2\", \"\", \"2\"],\n    Numpad3: [\"\", \"3\", \"\", \"3\"],\n    Numpad4: [\"\", \"4\", \"\", \"4\"],\n    Numpad5: [\"\", \"5\", \"\", \"5\"],\n    Numpad6: [\"\", \"6\", \"\", \"6\"],\n    Numpad7: [\"\", \"7\", \"\", \"7\"],\n    Numpad8: [\"\", \"8\", \"\", \"8\"],\n    Numpad9: [\"\", \"9\", \"\", \"9\"],\n    Numpad0: [\"\", \"0\", \"\", \"0\"],\n    NumpadDecimal: [\"\", \".\", \"\", \".\"],\n    IntlBackslash: [\"<\", \">\", \"|\", \"\\xA6\"],\n    NumpadEqual: [\"=\", \"=\", \"=\", \"=\"],\n    NumpadComma: [\".\", \".\", \".\", \".\"],\n    NumpadParenLeft: [\"(\", \"(\", \"(\", \"(\"],\n    NumpadParenRight: [\")\", \")\", \")\", \")\"]\n  }\n};\n\n// src/editor/keyboard-layout.ts\nfunction keystrokeModifiersFromString(key) {\n  const segments = key.split(\"+\");\n  const result = {\n    shift: false,\n    alt: false,\n    cmd: false,\n    win: false,\n    meta: false,\n    ctrl: false,\n    key: segments.pop()\n  };\n  if (segments.includes(\"shift\")) result.shift = true;\n  if (segments.includes(\"alt\")) result.alt = true;\n  if (segments.includes(\"ctrl\")) result.ctrl = true;\n  if (segments.includes(\"cmd\")) result.cmd = true;\n  if (segments.includes(\"win\")) result.win = true;\n  if (segments.includes(\"meta\")) result.meta = true;\n  return result;\n}\nfunction keystrokeModifiersToString(key) {\n  let result = \"\";\n  if (key.shift) result += \"shift+\";\n  if (key.alt) result += \"alt+\";\n  if (key.ctrl) result += \"ctrl+\";\n  if (key.cmd) result += \"cmd+\";\n  if (key.win) result += \"win+\";\n  if (key.meta) result += \"meta+\";\n  return result + key.key;\n}\nvar BASE_LAYOUT_MAPPING = {\n  enter: \"[Enter]\",\n  escape: \"[Escape]\",\n  backspace: \"[Backspace]\",\n  tab: \"[Tab]\",\n  space: \"[Space]\",\n  pausebreak: \"[Pause]\",\n  insert: \"[Insert]\",\n  home: \"[Home]\",\n  pageup: \"[PageUp]\",\n  delete: \"[Delete]\",\n  end: \"[End]\",\n  pagedown: \"[PageDown]\",\n  right: \"[ArrowRight]\",\n  left: \"[ArrowLeft]\",\n  down: \"[ArrowDown]\",\n  up: \"[ArrowUp]\",\n  numpad0: \"[Numpad0]\",\n  numpad1: \"[Numpad1]\",\n  numpad2: \"[Numpad2]\",\n  numpad3: \"[Numpad3]\",\n  numpad4: \"[Numpad4]\",\n  numpad5: \"[Numpad5]\",\n  numpad6: \"[Numpad6]\",\n  numpad7: \"[Numpad7]\",\n  numpad8: \"[Numpad8]\",\n  numpad9: \"[Numpad9]\",\n  \"numpad_divide\": \"[NumpadDivide]\",\n  \"numpad_multiply\": \"[NumpadMultiply]\",\n  \"numpad_subtract\": \"[NumpadSubtract]\",\n  \"numpad_add\": \"[NumpadAdd]\",\n  \"numpad_decimal\": \"[NumpadDecimal]\",\n  \"numpad_separator\": \"[NumpadComma]\",\n  capslock: \"[Capslock]\",\n  f1: \"[F1]\",\n  f2: \"[F2]\",\n  f3: \"[F3]\",\n  f4: \"[F4]\",\n  f5: \"[F5]\",\n  f6: \"[F6]\",\n  f7: \"[F7]\",\n  f8: \"[F8]\",\n  f9: \"[F9]\",\n  f10: \"[F10]\",\n  f11: \"[F11]\",\n  f12: \"[F12]\",\n  f13: \"[F13]\",\n  f14: \"[F14]\",\n  f15: \"[F15]\",\n  f16: \"[F16]\",\n  f17: \"[F17]\",\n  f18: \"[F18]\",\n  f19: \"[F19]\"\n};\nvar gKeyboardLayouts = [];\nvar gKeyboardLayout;\nfunction platform() {\n  switch (osPlatform()) {\n    case \"macos\":\n    case \"ios\":\n      return \"apple\";\n    case \"windows\":\n      return \"windows\";\n  }\n  return \"linux\";\n}\nfunction register(layout) {\n  if (!layout.platform || layout.platform === platform())\n    gKeyboardLayouts.push(layout);\n}\nfunction getCodeForKey(k, layout) {\n  var _a3;\n  const result = {\n    shift: false,\n    alt: false,\n    cmd: false,\n    win: false,\n    meta: false,\n    ctrl: false,\n    key: \"\"\n  };\n  if (!k) return result;\n  for (const [key, value] of Object.entries(layout.mapping)) {\n    if (value[0] === k) {\n      result.key = `[${key}]`;\n      return result;\n    }\n    if (value[1] === k) {\n      result.shift = true;\n      result.key = `[${key}]`;\n      return result;\n    }\n    if (value[2] === k) {\n      result.alt = true;\n      result.key = `[${key}]`;\n      return result;\n    }\n    if (value[3] === k) {\n      result.shift = true;\n      result.alt = true;\n      result.key = `[${key}]`;\n      return result;\n    }\n  }\n  result.key = (_a3 = BASE_LAYOUT_MAPPING[k]) != null ? _a3 : \"\";\n  return result;\n}\nfunction normalizeKeyboardEvent(evt) {\n  if (evt.code) return evt;\n  const mapping = Object.entries(getActiveKeyboardLayout().mapping);\n  let altKey = false;\n  let shiftKey = false;\n  let code = \"\";\n  for (let index = 0; index < 4; index++) {\n    for (const [key, value] of mapping) {\n      if (value[index] === evt.key) {\n        code = key;\n        if (index === 3) {\n          altKey = true;\n          shiftKey = true;\n        } else if (index === 2) altKey = true;\n        else if (index === 1) shiftKey = true;\n        break;\n      }\n    }\n    if (code) break;\n  }\n  return new KeyboardEvent(evt.type, __spreadProps(__spreadValues({}, evt), { altKey, shiftKey, code }));\n}\nfunction validateKeyboardLayout(evt) {\n  var _a3, _b3;\n  if (!evt) return;\n  if (evt.key === \"Unidentified\") return;\n  if (evt.key === \"Dead\") return;\n  const index = evt.shiftKey && evt.altKey ? 3 : evt.altKey ? 2 : evt.shiftKey ? 1 : 0;\n  for (const layout of gKeyboardLayouts) {\n    if (((_a3 = layout.mapping[evt.code]) == null ? void 0 : _a3[index]) === evt.key) {\n      layout.score += 1;\n    } else if ((_b3 = layout.mapping[evt.code]) == null ? void 0 : _b3[index]) {\n      layout.score = 0;\n    }\n  }\n  gKeyboardLayouts.sort((a, b) => b.score - a.score);\n}\nfunction setKeyboardLayoutLocale(locale) {\n  gKeyboardLayout = gKeyboardLayouts.find((x) => locale.startsWith(x.locale));\n}\nfunction getActiveKeyboardLayout() {\n  return gKeyboardLayout != null ? gKeyboardLayout : gKeyboardLayouts[0];\n}\nfunction getDefaultKeyboardLayout() {\n  switch (platform()) {\n    case \"apple\":\n      return APPLE_ENGLISH;\n    case \"windows\":\n      return WINDOWS_ENGLISH;\n    case \"linux\":\n      return LINUX_ENGLISH;\n  }\n  return APPLE_ENGLISH;\n}\nswitch (platform()) {\n  case \"apple\":\n    register(APPLE_ENGLISH);\n    register(APPLE_FRENCH);\n    register(APPLE_SPANISH);\n    register(APPLE_GERMAN);\n    break;\n  case \"windows\":\n    register(WINDOWS_ENGLISH);\n    register(WINDOWS_FRENCH);\n    register(WINDOWS_SPANISH);\n    register(WINDOWS_GERMAN);\n    break;\n  case \"linux\":\n    register(LINUX_ENGLISH);\n    register(LINUX_FRENCH);\n    register(LINUX_SPANISH);\n    register(LINUX_GERMAN);\n    break;\n}\nregister(DVORAK);\n\n// src/ui/events/keyboard.ts\nfunction getKeybindingMarkup(keybinding) {\n  var _a3;\n  const useGlyph = /macos|ios/.test(osPlatform());\n  const segments = keybinding.split(\"+\");\n  let result = \"\";\n  for (const segment of segments) {\n    if (result) {\n      result += useGlyph ? \"\\u2009\" : '<span class=\"ML__shortcut-join\">+</span>';\n    }\n    if (segment.startsWith(\"[Key\")) result += segment.slice(4, 5);\n    else if (segment.startsWith(\"Key\")) result += segment.slice(3, 4);\n    else if (segment.startsWith(\"[Digit\")) result += segment.slice(6, 7);\n    else if (segment.startsWith(\"Digit\")) result += segment.slice(5, 6);\n    else {\n      result += (_a3 = {\n        \"cmd\": \"\\u2318\",\n        \"meta\": useGlyph ? \"\\u2318\" : \"Ctrl\",\n        \"shift\": useGlyph ? \"\\u21E7\" : \"Shift\",\n        \"alt\": useGlyph ? \"\\u2325\" : \"Alt\",\n        \"ctrl\": useGlyph ? \"\\u2303\" : \"Ctrl\",\n        \"\\n\": useGlyph ? \"\\u23CE\" : \"Return\",\n        \"[return]\": useGlyph ? \"\\u23CE\" : \"Return\",\n        \"[enter]\": useGlyph ? \"\\u2324\" : \"Enter\",\n        \"[tab]\": useGlyph ? \"\\u21E5\" : \"Tab\",\n        // 'Esc':          useSymbol ? '\\u238b' : 'esc',\n        \"[escape]\": \"Esc\",\n        \"[backspace]\": useGlyph ? \"\\u232B\" : \"Backspace\",\n        \"[delete]\": useGlyph ? \"\\u2326\" : \"Del\",\n        \"[pageup]\": useGlyph ? \"\\u21DE\" : \"Page Up\",\n        \"[pagedown]\": useGlyph ? \"\\u21DF\" : \"Page Down\",\n        \"[home]\": useGlyph ? \"\\u2912\" : \"Home\",\n        \"[end]\": useGlyph ? \"\\u2913\" : \"End\",\n        \"[space]\": \"Space\",\n        \"[equal]\": \"=\",\n        \"[minus]\": \"-\",\n        \"[comma]\": \",\",\n        \"[slash]\": \"/\",\n        \"[backslash]\": \"\\\\\",\n        \"[bracketleft]\": \"[\",\n        \"[bracketright]\": \"]\",\n        \"semicolon\": \";\",\n        \"period\": \".\",\n        \"comma\": \",\",\n        \"minus\": \"-\",\n        \"equal\": \"=\",\n        \"quote\": \"'\",\n        \"backslash\": \"\\\\\",\n        \"intlbackslash\": \"\\\\\",\n        \"backquote\": \"`\",\n        \"slash\": \"/\",\n        \"numpadmultiply\": \"* &#128290;\",\n        \"numpaddivide\": \"/ &#128290;\",\n        // Numeric keypad\n        \"numpadsubtract\": \"- &#128290;\",\n        \"numpadadd\": \"+ &#128290;\",\n        \"numpaddecimal\": \". &#128290;\",\n        \"numpadcomma\": \", &#128290;\",\n        \"help\": \"help\",\n        \"left\": \"\\u21E0\",\n        \"up\": \"\\u21E1\",\n        \"right\": \"\\u21E2\",\n        \"down\": \"\\u21E3\",\n        \"[arrowleft]\": \"\\u21E0\",\n        \"[arrowup]\": \"\\u21E1\",\n        \"[arrowright]\": \"\\u21E2\",\n        \"[arrowdown]\": \"\\u21E3\"\n      }[segment.toLowerCase()]) != null ? _a3 : segment.toUpperCase();\n    }\n  }\n  return result;\n}\n\n// src/ui/events/utils.ts\nfunction eventLocation(evt) {\n  if (evt instanceof MouseEvent || evt instanceof PointerEvent)\n    return { x: evt.clientX, y: evt.clientY };\n  if (typeof TouchEvent !== \"undefined\" && evt instanceof TouchEvent) {\n    const result = [...evt.touches].reduce(\n      (acc, x) => ({ x: acc.x + x.clientX, y: acc.y + x.clientY }),\n      { x: 0, y: 0 }\n    );\n    const l = evt.touches.length;\n    return { x: result.x / l, y: result.y / l };\n  }\n  return void 0;\n}\nfunction keyboardModifiersFromEvent(ev) {\n  const result = {\n    alt: false,\n    control: false,\n    shift: false,\n    meta: false\n  };\n  if (ev instanceof MouseEvent || ev instanceof PointerEvent || typeof TouchEvent !== \"undefined\" && ev instanceof TouchEvent || ev instanceof KeyboardEvent) {\n    if (ev.altKey) result.alt = true;\n    if (ev.ctrlKey) result.control = true;\n    if (ev.metaKey) result.meta = true;\n    if (ev.shiftKey) result.shift = true;\n  }\n  return result;\n}\nfunction equalKeyboardModifiers(a, b) {\n  if (!a && b || a && !b) return false;\n  if (!a || !b) return true;\n  return a.alt === b.alt && a.control === b.control && a.shift === b.shift && a.meta === b.meta;\n}\nvar PRINTABLE_KEYCODE = /* @__PURE__ */ new Set([\n  \"Backquote\",\n  // Japanese keyboard: hankaku/zenkaku/kanji key, which is non-printable\n  \"Digit0\",\n  \"Digit1\",\n  \"Digit2\",\n  \"Digit3\",\n  \"Digit4\",\n  \"Digit5\",\n  \"Digit6\",\n  \"Digit7\",\n  \"Digit8\",\n  \"Digit9\",\n  \"Minus\",\n  \"Equal\",\n  \"IntlYen\",\n  // Japanese Keyboard. Russian keyboard: \\/\n  \"KeyQ\",\n  // AZERTY keyboard: labeled 'a'\n  \"KeyW\",\n  // AZERTY keyboard: labeled 'z'\n  \"KeyE\",\n  \"KeyR\",\n  \"KeyT\",\n  \"KeyY\",\n  // QWERTZ keyboard: labeled 'z'\n  \"KeyU\",\n  \"KeyI\",\n  \"KeyO\",\n  \"KeyP\",\n  \"BracketLeft\",\n  \"BracketRight\",\n  \"Backslash\",\n  // May be labeled #~ on UK 102 keyboard\n  \"KeyA\",\n  // AZERTY keyboard: labeled 'q'\n  \"KeyS\",\n  \"KeyD\",\n  \"KeyF\",\n  \"KeyG\",\n  \"KeyH\",\n  \"KeyJ\",\n  \"KeyK\",\n  \"KeyL\",\n  \"Semicolon\",\n  \"Quote\",\n  \"IntlBackslash\",\n  // QWERTZ keyboard '><'\n  \"KeyZ\",\n  // AZERTY: 'w', QWERTZ: 'y'\n  \"KeyX\",\n  \"KeyC\",\n  \"KeyV\",\n  \"KeyB\",\n  \"KeyN\",\n  \"KeyM\",\n  \"Comma\",\n  \"Period\",\n  \"Slash\",\n  \"IntlRo\",\n  // Japanse keyboard '\\ろ'\n  \"Space\",\n  \"Numpad0\",\n  \"Numpad1\",\n  \"Numpad2\",\n  \"Numpad3\",\n  \"Numpad4\",\n  \"Numpad5\",\n  \"Numpad6\",\n  \"Numpad7\",\n  \"Numpad8\",\n  \"Numpad9\",\n  \"NumpadAdd\",\n  \"NumpadComma\",\n  \"NumpadDecimal\",\n  \"NumpadDivide\",\n  \"NumpadEqual\",\n  \"NumpadHash\",\n  \"NumpadMultiply\",\n  \"NumpadParenLeft\",\n  \"NumpadParenRight\",\n  \"NumpadStar\",\n  \"NumpadSubstract\"\n]);\nfunction mightProducePrintableCharacter(evt) {\n  if (evt.ctrlKey || evt.metaKey) return false;\n  if ([\"Dead\", \"Process\"].includes(evt.key)) return false;\n  if (evt.code === \"\") return true;\n  return PRINTABLE_KEYCODE.has(evt.code);\n}\nfunction deepActiveElement() {\n  var _a3;\n  let a = document.activeElement;\n  while ((_a3 = a == null ? void 0 : a.shadowRoot) == null ? void 0 : _a3.activeElement) a = a.shadowRoot.activeElement;\n  return a;\n}\n\n// src/ui/utils/scrim.ts\nvar Scrim = class _Scrim {\n  static get scrim() {\n    if (!_Scrim._scrim) _Scrim._scrim = new _Scrim();\n    return _Scrim._scrim;\n  }\n  static open(options) {\n    _Scrim.scrim.open(options);\n  }\n  static close() {\n    _Scrim.scrim.close();\n  }\n  static get state() {\n    return _Scrim.scrim.state;\n  }\n  static get element() {\n    return _Scrim.scrim.element;\n  }\n  /**\n   * - If `lightDismiss` is true, the scrim is closed if the\n   * user clicks on the scrim. That's the behavior for menus, for example.\n   * When you need a fully modal situation until the user has made an\n   * explicit choice (validating cookie usage, for example), set\n   * `lightDismiss` to fallse.\n   */\n  constructor(options) {\n    var _a3, _b3;\n    this.lightDismiss = (_a3 = options == null ? void 0 : options.lightDismiss) != null ? _a3 : true;\n    this.translucent = (_b3 = options == null ? void 0 : options.translucent) != null ? _b3 : false;\n    this.state = \"closed\";\n  }\n  get element() {\n    if (this._element) return this._element;\n    const element = document.createElement(\"div\");\n    element.setAttribute(\"role\", \"presentation\");\n    element.style.position = \"fixed\";\n    element.style.contain = \"content\";\n    element.style.top = \"0\";\n    element.style.left = \"0\";\n    element.style.right = \"0\";\n    element.style.bottom = \"0\";\n    element.style.zIndex = \"var(--scrim-zindex, 10099)\";\n    element.style.outline = \"none\";\n    if (this.translucent) {\n      element.style.background = \"rgba(255, 255, 255, .2)\";\n      element.style[\"backdropFilter\"] = \"contrast(40%)\";\n    } else element.style.background = \"transparent\";\n    this._element = element;\n    return element;\n  }\n  open(options) {\n    var _a3;\n    if (this.state !== \"closed\") return;\n    this.state = \"opening\";\n    this.onDismiss = options == null ? void 0 : options.onDismiss;\n    this.savedActiveElement = deepActiveElement();\n    const { element } = this;\n    ((_a3 = options == null ? void 0 : options.root) != null ? _a3 : document.body).appendChild(element);\n    element.addEventListener(\"click\", this);\n    document.addEventListener(\"touchmove\", this, false);\n    document.addEventListener(\"scroll\", this, false);\n    const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;\n    this.savedMarginRight = document.body.style.marginRight;\n    this.savedOverflow = document.body.style.overflow;\n    document.body.style.overflow = \"hidden\";\n    const marginRight = Number.parseFloat(\n      getComputedStyle(document.body).marginRight\n    );\n    document.body.style.marginRight = `${marginRight + scrollbarWidth}px`;\n    if (options == null ? void 0 : options.child) element.append(options.child);\n    this.state = \"open\";\n  }\n  close() {\n    var _a3, _b3, _c2, _d2;\n    if (this.state !== \"open\") {\n      console.assert(this.element.parentElement !== null);\n      return;\n    }\n    this.state = \"closing\";\n    if (typeof this.onDismiss === \"function\") this.onDismiss();\n    this.onDismiss = void 0;\n    const { element } = this;\n    element.removeEventListener(\"click\", this);\n    document.removeEventListener(\"touchmove\", this, false);\n    document.removeEventListener(\"scroll\", this, false);\n    element.remove();\n    document.body.style.overflow = (_a3 = this.savedOverflow) != null ? _a3 : \"\";\n    document.body.style.marginRight = (_b3 = this.savedMarginRight) != null ? _b3 : \"\";\n    if (deepActiveElement() !== this.savedActiveElement)\n      (_d2 = (_c2 = this.savedActiveElement) == null ? void 0 : _c2.focus) == null ? void 0 : _d2.call(_c2);\n    element.innerHTML = \"\";\n    this.state = \"closed\";\n  }\n  handleEvent(ev) {\n    if (this.lightDismiss) {\n      if (ev.target === this._element && ev.type === \"click\") {\n        this.close();\n        ev.preventDefault();\n        ev.stopPropagation();\n      } else if (ev.target === document && (ev.type === \"touchmove\" || ev.type === \"scroll\")) {\n        this.close();\n        ev.preventDefault();\n        ev.stopPropagation();\n      }\n    }\n  }\n};\n\n// src/editor/keyboard.ts\nfunction delegateKeyboardEvents(keyboardSink, element, delegate) {\n  let keydownEvent = null;\n  let keypressEvent = null;\n  let compositionInProgress = false;\n  let focusInProgress = false;\n  let blurInProgress = false;\n  const controller = new AbortController();\n  const signal = controller.signal;\n  keyboardSink.addEventListener(\n    \"keydown\",\n    (event) => {\n      if (compositionInProgress || event.key === \"Process\" || event.code === \"CapsLock\" || /(Control|Meta|Alt|Shift)(Left|Right)/.test(event.code)) {\n        keydownEvent = null;\n        return;\n      }\n      keydownEvent = event;\n      keypressEvent = null;\n      if (!delegate.onKeystroke(event)) keydownEvent = null;\n      else keyboardSink.textContent = \"\";\n    },\n    { capture: true, signal }\n  );\n  keyboardSink.addEventListener(\n    \"keypress\",\n    (event) => {\n      if (compositionInProgress) return;\n      if (keydownEvent && keypressEvent) delegate.onKeystroke(keydownEvent);\n      keypressEvent = event;\n    },\n    { capture: true, signal }\n  );\n  keyboardSink.addEventListener(\n    \"compositionstart\",\n    (event) => {\n      keyboardSink.textContent = \"\";\n      compositionInProgress = true;\n      delegate.onCompositionStart(event.data);\n    },\n    { capture: true, signal }\n  );\n  keyboardSink.addEventListener(\n    \"compositionupdate\",\n    (ev) => {\n      if (!compositionInProgress) return;\n      delegate.onCompositionUpdate(ev.data);\n    },\n    { capture: true, signal }\n  );\n  keyboardSink.addEventListener(\n    \"compositionend\",\n    (ev) => {\n      keyboardSink.textContent = \"\";\n      if (!compositionInProgress) return;\n      compositionInProgress = false;\n      delegate.onCompositionEnd(ev.data);\n    },\n    { capture: true, signal }\n  );\n  keyboardSink.addEventListener(\n    \"beforeinput\",\n    (ev) => ev.stopImmediatePropagation(),\n    { signal }\n  );\n  keyboardSink.addEventListener(\n    \"input\",\n    (ev) => {\n      var _a3;\n      if (compositionInProgress) return;\n      keyboardSink.textContent = \"\";\n      if (ev.inputType === \"insertCompositionText\") return;\n      if (ev.inputType === \"insertFromPaste\") {\n        ev.preventDefault();\n        ev.stopPropagation();\n        return;\n      }\n      delegate.onInput((_a3 = ev.data) != null ? _a3 : \"\");\n      ev.preventDefault();\n      ev.stopPropagation();\n    },\n    { signal }\n  );\n  keyboardSink.addEventListener(\n    \"paste\",\n    (event) => {\n      keyboardSink.focus({ preventScroll: true });\n      keyboardSink.textContent = \"\";\n      if (!delegate.onPaste(event)) event.preventDefault();\n      event.stopImmediatePropagation();\n    },\n    { signal }\n  );\n  keyboardSink.addEventListener(\"cut\", (ev) => delegate.onCut(ev), {\n    capture: true,\n    signal\n  });\n  keyboardSink.addEventListener(\"copy\", (ev) => delegate.onCopy(ev), {\n    capture: true,\n    signal\n  });\n  keyboardSink.addEventListener(\n    \"blur\",\n    (event) => {\n      var _a3, _b3;\n      if (((_b3 = (_a3 = event[\"relatedTarget\"]) == null ? void 0 : _a3[\"_mathfield\"]) == null ? void 0 : _b3[\"element\"]) === element) {\n        keyboardSink.focus({ preventScroll: true });\n        event.preventDefault();\n        event.stopPropagation();\n        return;\n      }\n      let isInsideKeyboard = false;\n      let target = event.relatedTarget;\n      while (target) {\n        if (target.classList.contains(\"ML__keyboard\")) {\n          isInsideKeyboard = true;\n          break;\n        }\n        target = target.parentElement;\n      }\n      if (isInsideKeyboard) {\n        keyboardSink.focus({ preventScroll: true });\n        event.preventDefault();\n        event.stopPropagation();\n        return;\n      }\n      const scrimState = Scrim.state;\n      if (scrimState === \"open\" || scrimState === \"opening\") {\n        event.preventDefault();\n        event.stopPropagation();\n        return;\n      }\n      if (event.relatedTarget === event.target.getRootNode().host) {\n        event.preventDefault();\n        event.stopPropagation();\n        return;\n      }\n      if (blurInProgress || focusInProgress) return;\n      blurInProgress = true;\n      keydownEvent = null;\n      keypressEvent = null;\n      delegate.onBlur();\n      blurInProgress = false;\n    },\n    { capture: true, signal }\n  );\n  keyboardSink.addEventListener(\n    \"focus\",\n    (_evt) => {\n      if (blurInProgress || focusInProgress) return;\n      focusInProgress = true;\n      delegate.onFocus();\n      focusInProgress = false;\n    },\n    { capture: true, signal }\n  );\n  return {\n    dispose: () => controller.abort(),\n    cancelComposition: () => {\n      if (!compositionInProgress) return;\n      keyboardSink.blur();\n      requestAnimationFrame(() => keyboardSink.focus({ preventScroll: true }));\n    },\n    blur: () => {\n      if (typeof keyboardSink.blur === \"function\") keyboardSink.blur();\n    },\n    focus: () => {\n      if (!focusInProgress && typeof keyboardSink.focus === \"function\")\n        keyboardSink.focus({ preventScroll: true });\n    },\n    hasFocus: () => {\n      return deepActiveElement() === keyboardSink;\n    },\n    setAriaLabel: (value) => keyboardSink.setAttribute(\"aria-label\", value),\n    setValue: (value) => {\n      var _a3;\n      if (keyboardSink.textContent === value) return;\n      keyboardSink.textContent = value;\n      keyboardSink.style.left = `-1000px`;\n      (_a3 = window.getSelection()) == null ? void 0 : _a3.selectAllChildren(keyboardSink);\n    },\n    moveTo: (x, y) => {\n      keyboardSink.style.top = `${y}px`;\n      keyboardSink.style.left = `${x}px`;\n    }\n  };\n}\nfunction keyboardEventToChar(evt) {\n  var _a3;\n  if (!evt || !mightProducePrintableCharacter(evt)) return \"\";\n  let result;\n  if (evt.key === \"Unidentified\") {\n    if (evt.target) result = evt.target.value;\n  }\n  result = (_a3 = result != null ? result : evt.key) != null ? _a3 : evt.code;\n  if (/^(Dead|Return|Enter|Tab|Escape|Delete|PageUp|PageDown|Home|End|Help|ArrowLeft|ArrowRight|ArrowUp|ArrowDown)$/.test(\n    result\n  ))\n    result = \"\";\n  return result;\n}\nfunction keyboardEventToString(evt) {\n  evt = normalizeKeyboardEvent(evt);\n  const modifiers = [];\n  if (evt.ctrlKey) modifiers.push(\"ctrl\");\n  if (evt.metaKey) modifiers.push(\"meta\");\n  if (evt.altKey) modifiers.push(\"alt\");\n  if (evt.shiftKey) modifiers.push(\"shift\");\n  if (modifiers.length === 0) return `[${evt.code}]`;\n  modifiers.push(`[${evt.code}]`);\n  return modifiers.join(\"+\");\n}\n\n// src/editor/keybindings.ts\nfunction matchPlatform(p) {\n  if (isBrowser()) {\n    const plat = osPlatform();\n    const isNeg = p.startsWith(\"!\");\n    const isMatch = p.endsWith(plat);\n    if (isNeg && !isMatch) return true;\n    if (!isNeg && isMatch) return true;\n  }\n  if (p === \"!other\") return false;\n  return p === \"other\";\n}\nfunction getCommandForKeybinding(keybindings, mode, evt) {\n  if (keybindings.length === 0) return \"\";\n  const keystroke = keystrokeModifiersToString(\n    keystrokeModifiersFromString(keyboardEventToString(evt))\n  );\n  const altKeystroke = keystrokeModifiersToString({\n    key: evt.key,\n    shift: evt.shiftKey,\n    alt: evt.altKey,\n    ctrl: evt.ctrlKey,\n    meta: evt.metaKey || evt.ctrlKey && /macos|ios/.test(osPlatform()),\n    cmd: false,\n    win: false\n  });\n  for (let i = keybindings.length - 1; i >= 0; i--) {\n    if (keybindings[i].key === keystroke || keybindings[i].key === altKeystroke) {\n      if (!keybindings[i].ifMode || keybindings[i].ifMode === mode)\n        return keybindings[i].command;\n    }\n  }\n  return \"\";\n}\nfunction commandToString(command) {\n  let result = command;\n  if (isArray(result)) {\n    result = result.length > 0 ? result[0] + \"(\" + result.slice(1).join(\"\") + \")\" : \"\";\n  }\n  return result;\n}\nfunction getKeybindingsForCommand(keybindings, command) {\n  let result = [];\n  if (typeof command === \"string\") {\n    const candidate = REVERSE_KEYBINDINGS[command];\n    if (isArray(candidate)) result = candidate.slice();\n    else if (candidate) result.push(candidate);\n  }\n  const normalizedCommand = commandToString(command);\n  const regex = new RegExp(\n    \"^\" + normalizedCommand.replace(\"\\\\\", \"\\\\\\\\\").replace(\"|\", \"\\\\|\").replace(\"*\", \"\\\\*\").replace(\"$\", \"\\\\$\").replace(\"^\", \"\\\\^\") + \"([^*a-zA-Z]|$)\"\n  );\n  for (const keybinding of keybindings) {\n    if (regex.test(commandToString(keybinding.command)))\n      result.push(keybinding.key);\n  }\n  return result.map(getKeybindingMarkup);\n}\nfunction normalizeKeybinding(keybinding, layout) {\n  if (keybinding.ifPlatform && !/^!?(macos|windows|android|ios|chromeos|other)$/.test(\n    keybinding.ifPlatform\n  )) {\n    throw new Error(\n      `Unexpected platform \"${keybinding.ifPlatform}\" for keybinding ${keybinding.key}`\n    );\n  }\n  if (keybinding.ifLayout !== void 0 && (layout.score === 0 || !keybinding.ifLayout.includes(layout.id)))\n    return void 0;\n  const modifiers = keystrokeModifiersFromString(keybinding.key);\n  let platform2 = keybinding.ifPlatform;\n  if (modifiers.cmd) {\n    if (platform2 && platform2 !== \"macos\" && platform2 !== \"ios\") {\n      throw new Error(\n        'Unexpected \"cmd\" modifier with platform \"' + platform2 + '\"\\n\"cmd\" modifier can only be used with macOS or iOS platform.'\n      );\n    }\n    if (!platform2) platform2 = osPlatform() === \"ios\" ? \"ios\" : \"macos\";\n    modifiers.win = false;\n    modifiers.cmd = false;\n    modifiers.meta = true;\n  }\n  if (modifiers.win) {\n    if (platform2 && platform2 !== \"windows\") {\n      throw new Error(\n        'Unexpected \"win\" modifier with platform \"' + platform2 + '\"\\n\"win\" modifier can only be used with Windows platform.'\n      );\n    }\n    platform2 = \"windows\";\n    modifiers.win = false;\n    modifiers.cmd = false;\n    modifiers.meta = true;\n  }\n  if (platform2 && !matchPlatform(platform2)) return void 0;\n  if (/^\\[.+\\]$/.test(modifiers.key))\n    return __spreadProps(__spreadValues({}, keybinding), { key: keystrokeModifiersToString(modifiers) });\n  const code = getCodeForKey(modifiers.key, layout);\n  if (!code)\n    return __spreadProps(__spreadValues({}, keybinding), { key: keystrokeModifiersToString(modifiers) });\n  if (code.shift && modifiers.shift || code.alt && modifiers.alt) {\n    throw new Error(\n      `The keybinding ${keybinding.key} (${selectorToString(\n        keybinding.command\n      )}) is conflicting with the key combination ${keystrokeModifiersToString(\n        code\n      )} using the ${layout.displayName} keyboard layout`\n    );\n  }\n  code.shift = code.shift || modifiers.shift;\n  code.alt = code.alt || modifiers.alt;\n  code.meta = modifiers.meta;\n  code.ctrl = modifiers.ctrl;\n  return __spreadProps(__spreadValues({}, keybinding), { key: keystrokeModifiersToString(code) });\n}\nfunction selectorToString(selector) {\n  if (Array.isArray(selector)) {\n    const sel = [...selector];\n    return sel.shift() + \"(\" + sel.map((x) => typeof x === \"string\" ? `\"${x}\"` : x.toString()).join(\", \") + \")\";\n  }\n  return selector;\n}\nfunction normalizeKeybindings(keybindings, layout) {\n  const errors = [];\n  const result = [];\n  for (const x of keybindings) {\n    try {\n      const binding = normalizeKeybinding(x, layout);\n      if (!binding) continue;\n      const conflict = result.find(\n        (x2) => x2.key === binding.key && x2.ifMode === binding.ifMode\n      );\n      if (conflict) {\n        throw new Error(\n          `Ambiguous key binding ${x.key} (${selectorToString(\n            x.command\n          )}) matches ${conflict.key} (${selectorToString(\n            conflict.command\n          )}) with the ${layout.displayName} keyboard layout`\n        );\n      }\n      result.push(binding);\n    } catch (error) {\n      if (error instanceof Error) errors.push(error.message);\n    }\n  }\n  return [result, errors];\n}\n\n// src/editor-mathfield/mode-editor-latex.ts\nvar LatexModeEditor = class extends ModeEditor {\n  constructor() {\n    super(\"latex\");\n  }\n  createAtom(command) {\n    return new LatexAtom(command);\n  }\n  onPaste(mathfield, data) {\n    if (!data) return false;\n    const text = typeof data === \"string\" ? data : data.getData(\"application/x-latex\") || data.getData(\"text/plain\");\n    if (text && mathfield.model.contentWillChange({\n      inputType: \"insertFromPaste\",\n      data: text\n    })) {\n      mathfield.stopCoalescingUndo();\n      mathfield.stopRecording();\n      if (this.insert(mathfield.model, text)) {\n        mathfield.startRecording();\n        mathfield.snapshot(\"paste\");\n        mathfield.model.contentDidChange({ inputType: \"insertFromPaste\" });\n        requestUpdate(mathfield);\n      }\n      mathfield.startRecording();\n      return true;\n    }\n    return false;\n  }\n  insert(model, text, options) {\n    if (!model.contentWillChange({ data: text, inputType: \"insertText\" }))\n      return false;\n    if (!options) options = {};\n    if (!options.insertionMode) options.insertionMode = \"replaceSelection\";\n    if (!options.selectionMode) options.selectionMode = \"placeholder\";\n    const { silenceNotifications } = model;\n    if (options.silenceNotifications) model.silenceNotifications = true;\n    const saveSilenceNotifications = model.silenceNotifications;\n    model.silenceNotifications = true;\n    if (options.insertionMode === \"replaceSelection\" && !model.selectionIsCollapsed)\n      model.deleteAtoms(range(model.selection));\n    else if (options.insertionMode === \"replaceAll\") {\n      model.root.setChildren([], \"body\");\n      model.position = 0;\n    } else if (options.insertionMode === \"insertBefore\")\n      model.collapseSelection(\"backward\");\n    else if (options.insertionMode === \"insertAfter\")\n      model.collapseSelection(\"forward\");\n    const newAtoms = [];\n    for (const c of text)\n      if (COMMAND_MODE_CHARACTERS.test(c)) newAtoms.push(new LatexAtom(c));\n    let cursor = model.at(model.position);\n    if (cursor instanceof LatexGroupAtom) cursor = cursor.lastChild;\n    if (!(cursor.parent instanceof LatexGroupAtom)) {\n      const group = new LatexGroupAtom();\n      cursor.parent.addChildAfter(group, cursor);\n      cursor = group.firstChild;\n    }\n    const lastNewAtom = cursor.parent.addChildrenAfter(newAtoms, cursor);\n    model.silenceNotifications = saveSilenceNotifications;\n    if (options.selectionMode === \"before\") {\n    } else if (options.selectionMode === \"item\")\n      model.setSelection(model.anchor, model.offsetOf(lastNewAtom));\n    else if (lastNewAtom) model.position = model.offsetOf(lastNewAtom);\n    model.contentDidChange({ data: text, inputType: \"insertText\" });\n    model.silenceNotifications = silenceNotifications;\n    return true;\n  }\n};\nfunction getLatexGroup(model) {\n  return model.atoms.find((x) => x.type === \"latexgroup\");\n}\nfunction getLatexGroupBody(model) {\n  var _a3, _b3;\n  const atom = getLatexGroup(model);\n  return (_b3 = (_a3 = atom == null ? void 0 : atom.body) == null ? void 0 : _a3.filter((x) => x.type === \"latex\")) != null ? _b3 : [];\n}\nfunction getCommandSuggestionRange(model, options) {\n  var _a3;\n  let start = 0;\n  let found = false;\n  const last = Number.isFinite(options == null ? void 0 : options.before) ? (_a3 = options == null ? void 0 : options.before) != null ? _a3 : 0 : model.lastOffset;\n  while (start <= last && !found) {\n    const atom = model.at(start);\n    found = atom instanceof LatexAtom && atom.isSuggestion;\n    if (!found) start++;\n  }\n  if (!found) return [void 0, void 0];\n  let end = start;\n  let done = false;\n  while (end <= last && !done) {\n    const atom = model.at(end);\n    done = !(atom instanceof LatexAtom && atom.isSuggestion);\n    if (!done) end++;\n  }\n  return [start - 1, end - 1];\n}\nnew LatexModeEditor();\n\n// src/editor-mathfield/autocomplete.ts\nfunction removeSuggestion(mathfield) {\n  const group = getLatexGroupBody(mathfield.model).filter(\n    (x) => x.isSuggestion\n  );\n  if (group.length === 0) return;\n  mathfield.model.position = mathfield.model.offsetOf(group[0].leftSibling);\n  for (const atom of group) atom.parent.removeChild(atom);\n}\nfunction updateAutocomplete(mathfield, options) {\n  var _a3;\n  const { model } = mathfield;\n  removeSuggestion(mathfield);\n  for (const atom2 of getLatexGroupBody(model)) atom2.isError = false;\n  if (!model.selectionIsCollapsed || mathfield.options.popoverPolicy === \"off\") {\n    hideSuggestionPopover(mathfield);\n    return;\n  }\n  const commandAtoms = [];\n  let atom = model.at(model.position);\n  while (atom && atom instanceof LatexAtom && /^[a-zA-Z\\*]$/.test(atom.value))\n    atom = atom.leftSibling;\n  if (atom && atom instanceof LatexAtom && atom.value === \"\\\\\") {\n    commandAtoms.push(atom);\n    atom = atom.rightSibling;\n    while (atom && atom instanceof LatexAtom && /^[a-zA-Z\\*]$/.test(atom.value)) {\n      commandAtoms.push(atom);\n      atom = atom.rightSibling;\n    }\n  }\n  const command = commandAtoms.map((x) => x.value).join(\"\");\n  const suggestions = suggest(mathfield, command);\n  if (suggestions.length === 0) {\n    if (/^\\\\[a-zA-Z\\*]+$/.test(command))\n      for (const atom2 of commandAtoms) atom2.isError = true;\n    hideSuggestionPopover(mathfield);\n    return;\n  }\n  const index = (_a3 = options == null ? void 0 : options.atIndex) != null ? _a3 : 0;\n  mathfield.suggestionIndex = index < 0 ? suggestions.length - 1 : index % suggestions.length;\n  const suggestion = suggestions[mathfield.suggestionIndex];\n  if (suggestion !== command) {\n    const lastAtom = commandAtoms[commandAtoms.length - 1];\n    lastAtom.parent.addChildrenAfter(\n      [...suggestion.slice(command.length - suggestion.length)].map(\n        (x) => new LatexAtom(x, { isSuggestion: true })\n      ),\n      lastAtom\n    );\n    render(mathfield, { interactive: true });\n  }\n  showSuggestionPopover(mathfield, suggestions);\n}\nfunction acceptCommandSuggestion(model) {\n  const [from, to] = getCommandSuggestionRange(model, {\n    before: model.position\n  });\n  if (from === void 0 || to === void 0) return false;\n  let result = false;\n  model.getAtoms([from, to]).forEach((x) => {\n    if (x.isSuggestion) {\n      x.isSuggestion = false;\n      result = true;\n    }\n  });\n  return result;\n}\nfunction complete(mathfield, completion = \"accept\", options) {\n  var _a3, _b3;\n  hideSuggestionPopover(mathfield);\n  const latexGroup = getLatexGroup(mathfield.model);\n  if (!latexGroup) return false;\n  if (completion === \"accept-suggestion\" || completion === \"accept-all\") {\n    const suggestions = getLatexGroupBody(mathfield.model).filter(\n      (x) => x.isSuggestion\n    );\n    if (suggestions.length !== 0) {\n      for (const suggestion of suggestions) suggestion.isSuggestion = false;\n      mathfield.model.position = mathfield.model.offsetOf(\n        suggestions[suggestions.length - 1]\n      );\n    }\n    if (completion === \"accept-suggestion\") return suggestions.length !== 0;\n  }\n  const body = getLatexGroupBody(mathfield.model).filter(\n    (x) => !x.isSuggestion\n  );\n  const latex = body.map((x) => x.value).join(\"\");\n  const newPos = latexGroup.leftSibling;\n  latexGroup.parent.removeChild(latexGroup);\n  mathfield.model.position = mathfield.model.offsetOf(newPos);\n  mathfield.switchMode((_a3 = options == null ? void 0 : options.mode) != null ? _a3 : \"math\");\n  if (completion === \"reject\") return true;\n  ModeEditor.insert(mathfield.model, latex, {\n    selectionMode: ((_b3 = options == null ? void 0 : options.selectItem) != null ? _b3 : false) ? \"item\" : \"placeholder\",\n    format: \"latex\",\n    mode: \"math\"\n  });\n  mathfield.snapshot();\n  mathfield.model.announce(\"replacement\");\n  mathfield.switchMode(\"math\");\n  return true;\n}\n\n// src/common/shared-element.ts\nfunction getSharedElement(id) {\n  var _a3;\n  let result = document.getElementById(id);\n  if (result) {\n    result.dataset.refcount = Number(\n      Number.parseInt((_a3 = result.dataset.refcount) != null ? _a3 : \"0\") + 1\n    ).toString();\n  } else {\n    result = document.createElement(\"div\");\n    result.setAttribute(\"aria-hidden\", \"true\");\n    result.dataset.refcount = \"1\";\n    result.id = id;\n    document.body.append(result);\n  }\n  return result;\n}\nfunction releaseSharedElement(id) {\n  var _a3;\n  const element = document.getElementById(id);\n  if (!element) return;\n  const refcount = Number.parseInt(\n    (_a3 = element.getAttribute(\"data-refcount\")) != null ? _a3 : \"0\"\n  );\n  if (refcount <= 1) element.remove();\n  else element.dataset.refcount = Number(refcount - 1).toString();\n}\n\n// src/editor/suggestion-popover.ts\nfunction latexToMarkup(mf, latex) {\n  const context = new Context({ from: mf.context });\n  const root = new Atom({\n    mode: \"math\",\n    type: \"root\",\n    body: parseLatex(latex, { context })\n  });\n  const box = coalesce(\n    applyInterBoxSpacing(\n      new Box(root.render(context), { classes: \"ML__base\" }),\n      context\n    )\n  );\n  return makeStruts(box, { classes: \"ML__latex\" }).toMarkup();\n}\nfunction showSuggestionPopover(mf, suggestions) {\n  var _a3;\n  if (suggestions.length === 0) {\n    hideSuggestionPopover(mf);\n    return;\n  }\n  let template = \"\";\n  for (const [i, suggestion] of suggestions.entries()) {\n    const command = suggestion;\n    const commandMarkup = latexToMarkup(mf, suggestion);\n    const keybinding = getKeybindingsForCommand(mf.keybindings, command).join(\n      \"<br>\"\n    );\n    template += `<li role=\"button\" data-command=\"${command}\" ${i === mf.suggestionIndex ? \"class=ML__popover__current\" : \"\"}><span class=\"ML__popover__latex\">${command}</span><span class=\"ML__popover__command\">${commandMarkup}</span>`;\n    if (keybinding)\n      template += `<span class=\"ML__popover__keybinding\">${keybinding}</span>`;\n    template += \"</li>\";\n  }\n  const panel = createSuggestionPopover(mf, `<ul>${template}</ul>`);\n  if (isSuggestionPopoverVisible()) {\n    (_a3 = panel.querySelector(\".ML__popover__current\")) == null ? void 0 : _a3.scrollIntoView({ block: \"nearest\", inline: \"nearest\" });\n  }\n  setTimeout(() => {\n    var _a4;\n    if (panel && !isSuggestionPopoverVisible()) {\n      panel.classList.add(\"is-visible\");\n      updateSuggestionPopoverPosition(mf);\n      (_a4 = panel.querySelector(\".ML__popover__current\")) == null ? void 0 : _a4.scrollIntoView({ block: \"nearest\", inline: \"nearest\" });\n    }\n  }, 32);\n}\nfunction isSuggestionPopoverVisible() {\n  const panel = document.getElementById(\"mathlive-suggestion-popover\");\n  if (!panel) return false;\n  return panel.classList.contains(\"is-visible\");\n}\nfunction updateSuggestionPopoverPosition(mf, options) {\n  var _a3, _b3, _c2;\n  if (!mf.element || mf.element.mathfield !== mf) return;\n  if (!isSuggestionPopoverVisible()) return;\n  if (((_a3 = mf.model.at(mf.model.position)) == null ? void 0 : _a3.type) !== \"latex\") {\n    hideSuggestionPopover(mf);\n    return;\n  }\n  if (options == null ? void 0 : options.deferred) {\n    setTimeout(() => updateSuggestionPopoverPosition(mf), 32);\n    return;\n  }\n  const position = getCaretPoint(mf.field);\n  if (!position) return;\n  const viewportHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;\n  const viewportWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n  const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;\n  const scrollbarHeight = window.innerHeight - document.documentElement.clientHeight;\n  const virtualkeyboardHeight = (_c2 = (_b3 = window.mathVirtualKeyboard) == null ? void 0 : _b3.boundingRect.height) != null ? _c2 : 0;\n  const panel = document.getElementById(\"mathlive-suggestion-popover\");\n  if (position.x + panel.offsetWidth / 2 > viewportWidth - scrollbarWidth) {\n    panel.style.left = `${viewportWidth - panel.offsetWidth - scrollbarWidth}px`;\n  } else if (position.x - panel.offsetWidth / 2 < 0) panel.style.left = \"0\";\n  else panel.style.left = `${position.x - panel.offsetWidth / 2}px`;\n  const spaceAbove = position.y - position.height;\n  const spaceBelow = viewportHeight - scrollbarHeight - virtualkeyboardHeight - position.y;\n  if (spaceBelow < spaceAbove) {\n    panel.classList.add(\"ML__popover--reverse-direction\");\n    panel.classList.remove(\"top-tip\");\n    panel.classList.add(\"bottom-tip\");\n    panel.style.top = `${position.y - position.height - panel.offsetHeight - 15}px`;\n  } else {\n    panel.classList.remove(\"ML__popover--reverse-direction\");\n    panel.classList.add(\"top-tip\");\n    panel.classList.remove(\"bottom-tip\");\n    panel.style.top = `${position.y + 15}px`;\n  }\n}\nfunction hideSuggestionPopover(mf) {\n  mf.suggestionIndex = 0;\n  const panel = document.getElementById(\"mathlive-suggestion-popover\");\n  if (panel) {\n    panel.classList.remove(\"is-visible\");\n    panel.innerHTML = \"\";\n  }\n}\nfunction createSuggestionPopover(mf, html) {\n  let panel = document.getElementById(\"mathlive-suggestion-popover\");\n  if (!panel) {\n    panel = getSharedElement(\"mathlive-suggestion-popover\");\n    injectStylesheet(\"suggestion-popover\");\n    injectStylesheet(\"core\");\n    panel.addEventListener(\"pointerdown\", (ev) => ev.preventDefault());\n    panel.addEventListener(\"click\", (ev) => {\n      let el = ev.target;\n      while (el && !el.dataset.command) el = el.parentElement;\n      if (!el) return;\n      complete(mf, \"reject\");\n      ModeEditor.insert(mf.model, el.dataset.command, {\n        selectionMode: \"placeholder\",\n        format: \"latex\",\n        mode: \"math\"\n      });\n      mf.dirty = true;\n      mf.focus();\n    });\n  }\n  panel.innerHTML = globalThis.MathfieldElement.createHTML(html);\n  return panel;\n}\nfunction disposeSuggestionPopover() {\n  if (!document.getElementById(\"mathlive-suggestion-popover\")) return;\n  releaseSharedElement(\"mathlive-suggestion-popover\");\n  releaseStylesheet(\"suggestion-popover\");\n  releaseStylesheet(\"core\");\n}\n\n// src/common/script-url.ts\nfunction getFileUrl() {\n  const stackTraceFrames = String(new Error().stack).replace(/^Error.*\\n/, \"\").split(\"\\n\");\n  if (stackTraceFrames.length === 0) {\n    console.error(\n      `Can't use relative paths to specify assets location because the sourcefile location could not be determined (unexpected stack trace format \"${new Error().stack}\").`\n    );\n    return \"\";\n  }\n  let callerFrame = stackTraceFrames[1];\n  let m = callerFrame.match(/http.*\\.ts[\\?:]/);\n  if (m) {\n    callerFrame = stackTraceFrames[2];\n  }\n  m = callerFrame.match(/(https?:.*):[0-9]+:[0-9]+/);\n  if (!m) {\n    m = callerFrame.match(/at (.*(\\.ts))[\\?:]/);\n    if (!m) m = callerFrame.match(/at (.*(\\.mjs|\\.js))[\\?:]/);\n  }\n  if (!m) {\n    console.error(stackTraceFrames);\n    console.error(\n      `Can't use relative paths to specify assets location because the source file location could not be determined (unexpected location \"${callerFrame}\").`\n    );\n    return \"\";\n  }\n  return m[1];\n}\nvar gResolvedScriptUrl = null;\nvar _a, _b;\nvar gScriptUrl = ((_b = (_a = globalThis == null ? void 0 : globalThis.document) == null ? void 0 : _a.currentScript) == null ? void 0 : _b.src) || getFileUrl();\nasync function resolveUrl(url) {\n  if (/^(?:[a-z+]+:)?\\/\\//i.test(url)) {\n    try {\n      return new URL(url).href;\n    } catch (e) {\n    }\n    if (url.startsWith(\"//\")) {\n      try {\n        return new URL(`${window.location.protocol}${url}`).href;\n      } catch (e) {\n      }\n    }\n    return url;\n  }\n  if (gResolvedScriptUrl === null) {\n    try {\n      const response = await fetch(gScriptUrl, { method: \"HEAD\" });\n      if (response.status === 200) gResolvedScriptUrl = response.url;\n    } catch (e) {\n      console.error(`Invalid URL \"${url}\" (relative to \"${gScriptUrl}\")`);\n    }\n  }\n  return new URL(url, gResolvedScriptUrl != null ? gResolvedScriptUrl : gScriptUrl).href;\n}\n\n// src/core/fonts.ts\nfunction makeFontFace(name, source, descriptors = {}) {\n  return new FontFace(\n    name,\n    `url(${source}.woff2) format('woff2')`,\n    descriptors\n  );\n}\nvar gFontsState = \"not-loaded\";\nasync function reloadFonts() {\n  gFontsState = \"not-loaded\";\n  return loadFonts();\n}\nasync function loadFonts() {\n  var _a3;\n  if (gFontsState !== \"not-loaded\") return;\n  gFontsState = \"loading\";\n  const useStaticFonts = (_a3 = getComputedStyle(document.documentElement).getPropertyValue(\n    \"--ML__static-fonts\"\n  )) != null ? _a3 : false;\n  if (useStaticFonts) {\n    gFontsState = \"ready\";\n    return;\n  }\n  document.body.classList.remove(\"ML__fonts-did-not-load\");\n  if (\"fonts\" in document) {\n    const fontFamilies = [\n      \"KaTeX_Main\",\n      \"KaTeX_Math\",\n      \"KaTeX_AMS\",\n      \"KaTeX_Caligraphic\",\n      \"KaTeX_Fraktur\",\n      \"KaTeX_SansSerif\",\n      \"KaTeX_Script\",\n      \"KaTeX_Typewriter\",\n      \"KaTeX_Size1\",\n      \"KaTeX_Size2\",\n      \"KaTeX_Size3\",\n      \"KaTeX_Size4\"\n    ];\n    const fontsInDocument = Array.from(document.fonts).map((f) => f.family);\n    if (fontFamilies.every((x) => fontsInDocument.includes(x))) {\n      gFontsState = \"ready\";\n      return;\n    }\n    if (!globalThis.MathfieldElement.fontsDirectory) {\n      gFontsState = \"not-loaded\";\n      return;\n    }\n    const fontsFolder = await resolveUrl(\n      globalThis.MathfieldElement.fontsDirectory\n    );\n    if (!fontsFolder) {\n      document.body.classList.add(\"ML__fonts-did-not-load\");\n      gFontsState = \"error\";\n      return;\n    }\n    const fonts = [\n      [\"KaTeX_Main-Regular\"],\n      [\"KaTeX_Main-BoldItalic\", { style: \"italic\", weight: \"bold\" }],\n      [\"KaTeX_Main-Bold\", { weight: \"bold\" }],\n      [\"KaTeX_Main-Italic\", { style: \"italic\" }],\n      [\"KaTeX_Math-Italic\", { style: \"italic\" }],\n      [\"KaTeX_Math-BoldItalic\", { style: \"italic\", weight: \"bold\" }],\n      [\"KaTeX_AMS-Regular\"],\n      [\"KaTeX_Caligraphic-Regular\"],\n      [\"KaTeX_Caligraphic-Bold\", { weight: \"bold\" }],\n      [\"KaTeX_Fraktur-Regular\"],\n      [\"KaTeX_Fraktur-Bold\", { weight: \"bold\" }],\n      [\"KaTeX_SansSerif-Regular\"],\n      [\"KaTeX_SansSerif-Bold\", { weight: \"bold\" }],\n      [\"KaTeX_SansSerif-Italic\", { style: \"italic\" }],\n      [\"KaTeX_Script-Regular\"],\n      [\"KaTeX_Typewriter-Regular\"],\n      [\"KaTeX_Size1-Regular\"],\n      [\"KaTeX_Size2-Regular\"],\n      [\"KaTeX_Size3-Regular\"],\n      [\"KaTeX_Size4-Regular\"]\n    ].map(\n      (x) => makeFontFace(\n        x[0].replace(/-[a-zA-Z]+$/, \"\"),\n        `${fontsFolder}/${x[0]}`,\n        x[1]\n      )\n    );\n    try {\n      const loadedFonts = await Promise.all(\n        fonts.map((x) => {\n          try {\n            return x.load();\n          } catch (e) {\n          }\n          return void 0;\n        })\n      );\n      loadedFonts.forEach((font) => document.fonts.add(font));\n      gFontsState = \"ready\";\n      return;\n    } catch (error) {\n      console.error(\n        `MathLive 0.101.0: The math fonts could not be loaded from \"${fontsFolder}\"`,\n        { cause: error }\n      );\n      document.body.classList.add(\"ML__fonts-did-not-load\");\n    }\n    gFontsState = \"error\";\n  }\n}\n\n// src/common/hash-code.ts\nfunction hashCode(str, seed = 0) {\n  let h1 = 3735928559 ^ seed;\n  let h2 = 1103547991 ^ seed;\n  for (let i = 0; i < str.length; i++) {\n    const ch = str.charCodeAt(i);\n    h1 = Math.imul(h1 ^ ch, 2654435761);\n    h2 = Math.imul(h2 ^ ch, 1597334677);\n  }\n  h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507);\n  h1 ^= Math.imul(h2 ^ h2 >>> 13, 3266489909);\n  h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507);\n  h2 ^= Math.imul(h1 ^ h1 >>> 13, 3266489909);\n  return 4294967296 * (2097151 & h2) + (h1 >>> 0);\n}\n\n// src/editor-mathfield/render.ts\nfunction requestUpdate(mathfield, options) {\n  if (!mathfield || mathfield.dirty) return;\n  mathfield.resizeObserver.unobserve(mathfield.field);\n  mathfield.dirty = true;\n  requestAnimationFrame(() => {\n    if (isValidMathfield(mathfield) && mathfield.dirty) {\n      mathfield.atomBoundsCache = /* @__PURE__ */ new Map();\n      render(mathfield, options);\n      mathfield.atomBoundsCache = void 0;\n      mathfield.resizeObserver.observe(mathfield.field);\n      mathfield.resizeObserverStarted = true;\n    }\n  });\n}\nfunction makeBox(mathfield, renderOptions) {\n  var _a3;\n  renderOptions = renderOptions != null ? renderOptions : {};\n  const context = new Context({\n    from: __spreadProps(__spreadValues({}, mathfield.context), {\n      atomIdsSettings: {\n        // Using the hash as a seed for the ID\n        // keeps the IDs the same until the content of the field changes.\n        seed: renderOptions.forHighlighting ? hashCode(\n          Atom.serialize([mathfield.model.root], {\n            expandMacro: false,\n            defaultMode: mathfield.options.defaultMode\n          })\n        ) : \"random\",\n        // The `groupNumbers` flag indicates that extra boxes should be generated\n        // to represent group of atoms, for example, a box to group\n        // consecutive digits to represent a number.\n        groupNumbers: (_a3 = renderOptions.forHighlighting) != null ? _a3 : false\n      },\n      letterShapeStyle: mathfield.options.letterShapeStyle\n    }),\n    mathstyle: mathfield.options.defaultMode === \"inline-math\" ? \"textstyle\" : \"displaystyle\"\n  });\n  const base = mathfield.model.root.render(context);\n  const wrapper = makeStruts(applyInterBoxSpacing(base, context), {\n    classes: mathfield.hasEditablePrompts ? \"ML__latex ML__prompting\" : \"ML__latex\",\n    attributes: {\n      // Sometimes Google Translate kicks in an attempts to 'translate' math\n      // This doesn't work very well, so turn off translate\n      \"translate\": \"no\",\n      // Hint to screen readers to not attempt to read this <span>.\n      // They should use instead the 'aria-label' attribute.\n      \"aria-hidden\": \"true\"\n    }\n  });\n  return wrapper;\n}\nfunction contentMarkup(mathfield, renderOptions) {\n  const { model } = mathfield;\n  model.root.caret = void 0;\n  model.root.isSelected = false;\n  model.root.containsCaret = true;\n  for (const atom of model.atoms) {\n    atom.caret = void 0;\n    atom.isSelected = false;\n    atom.containsCaret = false;\n  }\n  if (model.selectionIsCollapsed) {\n    const atom = model.at(model.position);\n    atom.caret = mathfield.model.mode;\n    let ancestor = atom.parent;\n    while (ancestor) {\n      ancestor.containsCaret = true;\n      ancestor = ancestor.parent;\n    }\n  } else {\n    const atoms = model.getAtoms(model.selection, { includeChildren: true });\n    for (const atom of atoms) atom.isSelected = true;\n  }\n  const box = makeBox(mathfield, renderOptions);\n  return box.toMarkup();\n}\nfunction render(mathfield, renderOptions) {\n  if (!isValidMathfield(mathfield)) return;\n  renderOptions != null ? renderOptions : renderOptions = {};\n  const keyboardToggle = mathfield.element.querySelector(\n    \"[part=virtual-keyboard-toggle]\"\n  );\n  if (keyboardToggle)\n    keyboardToggle.style.display = mathfield.hasEditableContent ? \"\" : \"none\";\n  const field = mathfield.field;\n  if (!field) return;\n  const hasFocus = mathfield.isSelectionEditable && mathfield.hasFocus();\n  const isFocused = field.classList.contains(\"ML__focused\");\n  if (isFocused && !hasFocus) field.classList.remove(\"ML__focused\");\n  else if (!isFocused && hasFocus) field.classList.add(\"ML__focused\");\n  let content = contentMarkup(mathfield, renderOptions);\n  const menuToggle = mathfield.element.querySelector(\"[part=menu-toggle]\");\n  if (menuToggle) {\n    let hideMenu = false;\n    if (mathfield.disabled || mathfield.readOnly && !mathfield.hasEditableContent || mathfield.userSelect === \"none\")\n      hideMenu = true;\n    if (!hideMenu && field.offsetWidth < 50) {\n      hideMenu = true;\n    }\n    menuToggle.style.display = hideMenu ? \"none\" : \"\";\n  }\n  if (mathfield.model.atoms.length <= 1) {\n    const placeholder = mathfield.options.contentPlaceholder;\n    if (placeholder) {\n      content += `<span part=placeholder class=\"ML__content-placeholder\">${convertLatexToMarkup(\n        placeholder\n      )}</span>`;\n    }\n  }\n  field.innerHTML = globalThis.MathfieldElement.createHTML(content);\n  renderSelection(mathfield, renderOptions.interactive);\n  mathfield.dirty = false;\n}\nfunction renderSelection(mathfield, interactive) {\n  const field = mathfield.field;\n  if (!field) return;\n  for (const element of field.querySelectorAll(\n    \".ML__selection, .ML__contains-highlight\"\n  ))\n    element.remove();\n  if (!(interactive != null ? interactive : false) && gFontsState !== \"error\" && gFontsState !== \"ready\") {\n    setTimeout(() => {\n      if (gFontsState === \"ready\") renderSelection(mathfield);\n      else setTimeout(() => renderSelection(mathfield), 128);\n    }, 32);\n    return;\n  }\n  const model = mathfield.model;\n  let _scaleFactor;\n  const scaleFactor = () => {\n    if (_scaleFactor !== void 0) return _scaleFactor;\n    const offsetWidth = field.offsetWidth;\n    const actualWidth = field.getBoundingClientRect().width;\n    _scaleFactor = Math.floor(actualWidth) / offsetWidth;\n    if (isNaN(_scaleFactor)) _scaleFactor = 1;\n    return _scaleFactor;\n  };\n  if (model.selectionIsCollapsed) {\n    updateSuggestionPopoverPosition(mathfield, { deferred: true });\n    let atom = model.at(model.position);\n    while (atom && atom.type !== \"prompt\" && !(atom.containsCaret && atom.displayContainsHighlight))\n      atom = atom.parent;\n    if ((atom == null ? void 0 : atom.containsCaret) && atom.displayContainsHighlight) {\n      const s = scaleFactor();\n      const bounds = adjustForScrolling(\n        mathfield,\n        getAtomBounds(mathfield, atom),\n        s\n      );\n      if (bounds) {\n        bounds.left /= s;\n        bounds.right /= s;\n        bounds.top /= s;\n        bounds.bottom /= s;\n        const element = document.createElement(\"div\");\n        element.classList.add(\"ML__contains-highlight\");\n        element.style.position = \"absolute\";\n        element.style.left = `${bounds.left + 1}px`;\n        element.style.top = `${Math.ceil(bounds.top)}px`;\n        element.style.width = `${Math.ceil(bounds.right - bounds.left)}px`;\n        element.style.height = `${Math.ceil(bounds.bottom - bounds.top)}px`;\n        field.insertBefore(element, field.childNodes[0]);\n      }\n    }\n    return;\n  }\n  for (const x of unionRects(\n    getSelectionBounds(mathfield, { excludeAtomsWithBackground: true })\n  )) {\n    const s = scaleFactor();\n    x.left /= s;\n    x.right /= s;\n    x.top /= s;\n    x.bottom /= s;\n    const selectionElement = document.createElement(\"div\");\n    selectionElement.classList.add(\"ML__selection\");\n    selectionElement.style.position = \"absolute\";\n    selectionElement.style.left = `${x.left}px`;\n    selectionElement.style.top = `${x.top}px`;\n    selectionElement.style.width = `${Math.ceil(x.right - x.left)}px`;\n    selectionElement.style.height = `${Math.ceil(x.bottom - x.top - 1)}px`;\n    field.insertBefore(selectionElement, field.childNodes[0]);\n  }\n}\nfunction unionRects(rects) {\n  let result = [];\n  for (const rect of rects) {\n    let found = false;\n    for (const rect2 of result) {\n      if (rect.left === rect2.left && rect.right === rect2.right && rect.top === rect2.top && rect.bottom === rect2.bottom) {\n        found = true;\n        break;\n      }\n    }\n    if (!found) result.push(rect);\n  }\n  rects = result;\n  result = [];\n  for (const rect of rects) {\n    let count = 0;\n    for (const rect2 of rects) {\n      if (rect.left >= rect2.left && rect.right <= rect2.right && rect.top >= rect2.top && rect.bottom <= rect2.bottom) {\n        count += 1;\n        if (count > 1) break;\n      }\n    }\n    if (count === 1) result.push(rect);\n  }\n  return result;\n}\nfunction reparse(mathfield) {\n  if (!mathfield) return;\n  const model = mathfield.model;\n  const selection = model.selection;\n  const content = Atom.serialize([model.root], {\n    expandMacro: false,\n    defaultMode: mathfield.options.defaultMode\n  });\n  ModeEditor.insert(model, content, {\n    insertionMode: \"replaceAll\",\n    selectionMode: \"after\",\n    format: \"latex\",\n    silenceNotifications: true,\n    mode: \"math\"\n  });\n  const wasSilent = model.silenceNotifications;\n  model.silenceNotifications = true;\n  model.selection = selection;\n  model.silenceNotifications = wasSilent;\n  requestUpdate(mathfield);\n}\n\n// src/editor/commands.ts\nvar HAPTIC_FEEDBACK_DURATION = 3;\nvar COMMANDS;\nfunction register2(commands, options) {\n  options = __spreadValues({\n    target: \"mathfield\",\n    canUndo: false,\n    audioFeedback: void 0,\n    changeContent: false,\n    changeSelection: false\n  }, options != null ? options : {});\n  if (!COMMANDS) COMMANDS = {};\n  for (const selector of Object.keys(commands)) {\n    console.assert(!COMMANDS[selector], \"Selector already defined: \", selector);\n    COMMANDS[selector] = __spreadProps(__spreadValues({}, options), { fn: commands[selector] });\n  }\n}\nfunction getCommandInfo(command) {\n  let selector;\n  if (Array.isArray(command)) {\n    if (command[0] === \"performWithFeedback\") return getCommandInfo(command[1]);\n    selector = command[0];\n  } else selector = command;\n  return COMMANDS[selector];\n}\nfunction getCommandTarget(command) {\n  var _a3;\n  return (_a3 = getCommandInfo(command)) == null ? void 0 : _a3.target;\n}\nfunction perform(mathfield, command) {\n  var _a3, _b3;\n  command = parseCommand(command);\n  if (!command) return false;\n  let selector;\n  let args = [];\n  let handled = false;\n  let dirty = false;\n  if (isArray(command)) {\n    selector = command[0];\n    args = command.slice(1);\n  } else selector = command;\n  const info = COMMANDS[selector];\n  const commandTarget = info == null ? void 0 : info.target;\n  if (commandTarget === \"model\") {\n    if (!mathfield.isSelectionEditable && (info == null ? void 0 : info.changeContent)) {\n      mathfield.model.announce(\"plonk\");\n      return false;\n    }\n    if (/^(delete|add)/.test(selector)) {\n      if (selector !== \"deleteBackward\") mathfield.flushInlineShortcutBuffer();\n      mathfield.snapshot(selector);\n    }\n    if (!/^complete/.test(selector)) removeSuggestion(mathfield);\n    COMMANDS[selector].fn(mathfield.model, ...args);\n    updateAutocomplete(mathfield);\n    dirty = true;\n    handled = true;\n  } else if (commandTarget === \"virtual-keyboard\") {\n    dirty = (_b3 = (_a3 = window.mathVirtualKeyboard) == null ? void 0 : _a3.executeCommand(command)) != null ? _b3 : false;\n    handled = true;\n  } else if (COMMANDS[selector]) {\n    if (!mathfield.isSelectionEditable && (info == null ? void 0 : info.changeContent)) {\n      mathfield.model.announce(\"plonk\");\n      return false;\n    }\n    if (/^(undo|redo)/.test(selector)) mathfield.flushInlineShortcutBuffer();\n    dirty = COMMANDS[selector].fn(mathfield, ...args);\n    handled = true;\n  } else throw new Error(`Unknown command \"${selector}\"`);\n  if (commandTarget !== \"virtual-keyboard\") {\n    if (!mathfield.model.selectionIsCollapsed || (info == null ? void 0 : info.changeSelection) && selector !== \"deleteBackward\") {\n      mathfield.flushInlineShortcutBuffer();\n      if (!(info == null ? void 0 : info.changeContent)) mathfield.stopCoalescingUndo();\n      mathfield.defaultStyle = {};\n    }\n  }\n  if (dirty) requestUpdate(mathfield);\n  return handled;\n}\nfunction performWithFeedback(mathfield, selector) {\n  var _a3;\n  if (!mathfield) return false;\n  mathfield.focus();\n  if (mathfield_element_default.keypressVibration && canVibrate())\n    navigator.vibrate(HAPTIC_FEEDBACK_DURATION);\n  const info = getCommandInfo(selector);\n  globalThis.MathfieldElement.playSound((_a3 = info == null ? void 0 : info.audioFeedback) != null ? _a3 : \"keypress\");\n  const result = mathfield.executeCommand(selector);\n  mathfield.scrollIntoView();\n  return result;\n}\nregister2({\n  performWithFeedback: (mathfield, command) => performWithFeedback(mathfield, command)\n});\nfunction nextSuggestion(mathfield) {\n  updateAutocomplete(mathfield, { atIndex: mathfield.suggestionIndex + 1 });\n  return false;\n}\nfunction previousSuggestion(mathfield) {\n  updateAutocomplete(mathfield, { atIndex: mathfield.suggestionIndex - 1 });\n  return false;\n}\nregister2(\n  { complete },\n  {\n    target: \"mathfield\",\n    audioFeedback: \"return\",\n    canUndo: true,\n    changeContent: true,\n    changeSelection: true\n  }\n);\nregister2(\n  {\n    dispatchEvent: (mathfield, event, detail) => {\n      var _a3, _b3;\n      return (_b3 = (_a3 = mathfield.host) == null ? void 0 : _a3.dispatchEvent(new CustomEvent(event, { detail }))) != null ? _b3 : false;\n    }\n  },\n  { target: \"mathfield\" }\n);\nregister2(\n  { nextSuggestion, previousSuggestion },\n  {\n    target: \"mathfield\",\n    audioFeedback: \"keypress\",\n    changeSelection: true\n  }\n);\nfunction parseCommand(command) {\n  if (!command) return void 0;\n  if (isArray(command) && command.length > 0) {\n    let selector2 = command[0];\n    selector2.replace(/-\\w/g, (m) => m[1].toUpperCase());\n    if (selector2 === \"performWithFeedback\" && command.length === 2) {\n      return [selector2, parseCommand(command[1])];\n    }\n    return [selector2, ...command.slice(1)];\n  }\n  if (typeof command !== \"string\") return void 0;\n  const match = command.trim().match(/^([a-zA-Z0-9-]+)\\((.*)\\)$/);\n  if (match) {\n    const selector2 = match[1];\n    selector2.replace(/-\\w/g, (m) => m[1].toUpperCase());\n    let args = match[2].split(\",\").map((x) => x.trim());\n    return [\n      selector2,\n      ...args.map((arg) => {\n        if (/\"[^\"]*\"/.test(arg)) return arg.slice(1, -1);\n        if (/'[^']*'/.test(arg)) return arg.slice(1, -1);\n        if (/^true$/.test(arg)) return true;\n        if (/^false$/.test(arg)) return false;\n        if (/^[-]?\\d+$/.test(arg)) return parseInt(arg, 10);\n        if (/^\\{.*\\}$/.test(arg)) {\n          try {\n            return JSON.parse(arg);\n          } catch (e) {\n            console.error(\"Invalid argument:\", arg);\n            return arg;\n          }\n        }\n        return parseCommand(arg);\n      })\n    ];\n  }\n  let selector = command;\n  selector.replace(/-\\w/g, (m) => m[1].toUpperCase());\n  return selector;\n}\n\n// src/virtual-keyboard/proxy.ts\nvar VIRTUAL_KEYBOARD_MESSAGE = \"mathlive#virtual-keyboard-message\";\nfunction isVirtualKeyboardMessage(evt) {\n  var _a3;\n  if (evt.type !== \"message\") return false;\n  const msg = evt;\n  return ((_a3 = msg.data) == null ? void 0 : _a3.type) === VIRTUAL_KEYBOARD_MESSAGE;\n}\nvar VirtualKeyboardProxy = class _VirtualKeyboardProxy {\n  constructor() {\n    this.targetOrigin = window.origin;\n    this.originValidator = \"none\";\n    this._boundingRect = new DOMRect(0, 0, 0, 0);\n    this._isShifted = false;\n    window.addEventListener(\"message\", this);\n    this.sendMessage(\"proxy-created\");\n    this.listeners = {};\n  }\n  static get singleton() {\n    if (!this._singleton) this._singleton = new _VirtualKeyboardProxy();\n    return this._singleton;\n  }\n  getKeycap(keycap) {\n    return void 0;\n  }\n  setKeycap(keycap, value) {\n    this.sendMessage(\"update-setting\", { setKeycap: { keycap, value } });\n  }\n  set alphabeticLayout(value) {\n    this.sendMessage(\"update-setting\", { alphabeticLayout: value });\n  }\n  set layouts(value) {\n    this.sendMessage(\"update-setting\", { layouts: value });\n  }\n  get normalizedLayouts() {\n    return [];\n  }\n  set editToolbar(value) {\n    this.sendMessage(\"update-setting\", { editToolbar: value });\n  }\n  set container(value) {\n    throw new Error(\"Container inside an iframe cannot be changed\");\n  }\n  show(options) {\n    const success = this.dispatchEvent(\n      new CustomEvent(\"before-virtual-keyboard-toggle\", {\n        detail: { visible: true },\n        bubbles: true,\n        cancelable: true,\n        composed: true\n      })\n    );\n    if (success) {\n      this.sendMessage(\"show\", options);\n      this.dispatchEvent(new Event(\"virtual-keyboard-toggle\"));\n    }\n  }\n  hide(options) {\n    const success = this.dispatchEvent(\n      new CustomEvent(\"before-virtual-keyboard-toggle\", {\n        detail: { visible: false },\n        bubbles: true,\n        cancelable: true,\n        composed: true\n      })\n    );\n    if (success) {\n      this.sendMessage(\"hide\", options);\n      this.dispatchEvent(new Event(\"virtual-keyboard-toggle\"));\n    }\n  }\n  get isShifted() {\n    return this._isShifted;\n  }\n  get visible() {\n    return this._boundingRect.height > 0;\n  }\n  set visible(value) {\n    if (value) this.show();\n    else this.hide();\n  }\n  get boundingRect() {\n    return this._boundingRect;\n  }\n  executeCommand(command) {\n    this.sendMessage(\"execute-command\", { command });\n    return true;\n  }\n  updateToolbar(mf) {\n    this.sendMessage(\"update-toolbar\", mf);\n  }\n  update(mf) {\n    this.sendMessage(\"update-setting\", mf);\n  }\n  connect() {\n    this.sendMessage(\"connect\");\n  }\n  disconnect() {\n    this.sendMessage(\"disconnect\");\n  }\n  addEventListener(type, callback, _options) {\n    if (!this.listeners[type]) this.listeners[type] = /* @__PURE__ */ new Set();\n    if (!this.listeners[type].has(callback)) this.listeners[type].add(callback);\n  }\n  dispatchEvent(event) {\n    if (!this.listeners[event.type] || this.listeners[event.type].size === 0)\n      return true;\n    this.listeners[event.type].forEach((x) => {\n      if (typeof x === \"function\") x(event);\n      else x == null ? void 0 : x.handleEvent(event);\n    });\n    return !event.defaultPrevented;\n  }\n  removeEventListener(type, callback, _options) {\n    if (this.listeners[type]) this.listeners[type].delete(callback);\n  }\n  handleEvent(evt) {\n    if (isVirtualKeyboardMessage(evt)) {\n      if (!validateOrigin(evt.origin, this.originValidator)) {\n        throw new DOMException(\n          `Message from unknown origin (${evt.origin}) cannot be handled`,\n          \"SecurityError\"\n        );\n      }\n      this.handleMessage(evt.data);\n    }\n  }\n  handleMessage(msg) {\n    const { action } = msg;\n    if (action === \"execute-command\") {\n      const { command } = msg;\n      const commandTarget = getCommandTarget(command);\n      if (commandTarget === \"virtual-keyboard\") this.executeCommand(command);\n      return;\n    }\n    if (action === \"synchronize-proxy\") {\n      this._boundingRect = msg.boundingRect;\n      this._isShifted = msg.isShifted;\n      return;\n    }\n    if (action === \"geometry-changed\") {\n      this._boundingRect = msg.boundingRect;\n      this.dispatchEvent(new Event(\"geometrychange\"));\n      return;\n    }\n  }\n  sendMessage(action, payload = {}) {\n    if (!window.top) {\n      throw new DOMException(\n        `A frame does not have access to the top window and can\\u2018t communicate with the keyboard. Review virtualKeyboardTargetOrigin and originValidator on mathfields embedded in an iframe`,\n        \"SecurityError\"\n      );\n    }\n    window.top.postMessage(\n      __spreadValues({\n        type: VIRTUAL_KEYBOARD_MESSAGE,\n        action\n      }, payload),\n      this.targetOrigin\n    );\n  }\n};\n\n// src/virtual-keyboard/data.ts\nvar LAYOUTS = {\n  \"numeric\": {\n    label: \"123\",\n    labelClass: \"MLK__tex-math\",\n    tooltip: \"keyboard.tooltip.numeric\",\n    rows: [\n      [\n        {\n          latex: \"x\",\n          shift: \"y\",\n          variants: [\n            \"y\",\n            \"z\",\n            \"t\",\n            \"r\",\n            \"x^2\",\n            \"x^n\",\n            \"x^{#?}\",\n            \"x_n\",\n            \"x_i\",\n            \"x_{#?}\",\n            { latex: \"f(#?)\", class: \"small\" },\n            { latex: \"g(#?)\", class: \"small\" }\n          ]\n        },\n        { latex: \"n\", shift: \"a\", variants: [\"i\", \"j\", \"p\", \"k\", \"a\", \"u\"] },\n        \"[separator-5]\",\n        \"[7]\",\n        \"[8]\",\n        \"[9]\",\n        \"[/]\",\n        \"[separator-5]\",\n        {\n          latex: \"\\\\exponentialE\",\n          shift: \"\\\\ln\",\n          variants: [\"\\\\exp\", \"\\\\times 10^{#?}\", \"\\\\ln\", \"\\\\log_{10}\", \"\\\\log\"]\n        },\n        {\n          latex: \"\\\\imaginaryI\",\n          variants: [\"\\\\Re\", \"\\\\Im\", \"\\\\imaginaryJ\", \"\\\\Vert #0 \\\\Vert\"]\n        },\n        {\n          latex: \"\\\\pi\",\n          shift: \"\\\\sin\",\n          variants: [\n            \"\\\\prod\",\n            { latex: \"\\\\theta\", aside: \"theta\" },\n            { latex: \"\\\\rho\", aside: \"rho\" },\n            { latex: \"\\\\tau\", aside: \"tau\" },\n            \"\\\\sin\",\n            \"\\\\cos\",\n            \"\\\\tan\"\n          ]\n        }\n      ],\n      [\n        {\n          label: \"<\",\n          latex: \"<\",\n          class: \"hide-shift\",\n          shift: { latex: \"\\\\le\", label: \"\\u2264\" }\n        },\n        {\n          label: \">\",\n          latex: \">\",\n          class: \"hide-shift\",\n          shift: { latex: \"\\\\ge\", label: \"\\u2265\" }\n        },\n        \"[separator-5]\",\n        \"[4]\",\n        \"[5]\",\n        \"[6]\",\n        \"[*]\",\n        \"[separator-5]\",\n        {\n          class: \"hide-shift\",\n          latex: \"#@^2}\",\n          shift: \"#@^{\\\\prime}}\"\n        },\n        {\n          latex: \"#@^{#0}}\",\n          class: \"hide-shift\",\n          shift: \"#@_{#?}\"\n        },\n        {\n          class: \"hide-shift\",\n          latex: \"\\\\sqrt{#0}\",\n          shift: { latex: \"\\\\sqrt[#0]{#?}}\" }\n        }\n      ],\n      [\n        \"[(]\",\n        \"[)]\",\n        \"[separator-5]\",\n        \"[1]\",\n        \"[2]\",\n        \"[3]\",\n        \"[-]\",\n        \"[separator-5]\",\n        {\n          latex: \"\\\\int^{\\\\infty}_{0}\\\\!#?\\\\,\\\\mathrm{d}x\",\n          class: \"small hide-shift\",\n          shift: \"\\\\int\",\n          variants: [\n            { latex: \"\\\\int_{#?}^{#?}\", class: \"small\" },\n            { latex: \"\\\\int\", class: \"small\" },\n            { latex: \"\\\\iint\", class: \"small\" },\n            { latex: \"\\\\iiint\", class: \"small\" },\n            { latex: \"\\\\oint\", class: \"small\" },\n            \"\\\\mathrm{d}x\",\n            { latex: \"\\\\dfrac{\\\\mathrm{d}}{\\\\mathrm{d} x}\", class: \"small\" },\n            { latex: \"\\\\frac{\\\\partial}{\\\\partial x}\", class: \"small\" },\n            \"\\\\partial\"\n          ]\n        },\n        {\n          class: \"hide-shift\",\n          latex: \"\\\\forall\",\n          shift: \"\\\\exists\"\n        },\n        { label: \"[backspace]\", width: 1 }\n      ],\n      [\n        { label: \"[shift]\", width: 2 },\n        \"[separator-5]\",\n        \"[0]\",\n        \"[.]\",\n        \"[=]\",\n        \"[+]\",\n        \"[separator-5]\",\n        \"[left]\",\n        \"[right]\",\n        { label: \"[action]\", width: 1 }\n      ]\n    ]\n  },\n  \"greek\": {\n    label: \"&alpha;&beta;&gamma;\",\n    labelClass: \"MLK__tex-math\",\n    tooltip: \"keyboard.tooltip.greek\",\n    rows: [\n      [\n        {\n          label: \"<i>&#x03c6;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\varphi\",\n          aside: \"phi var.\",\n          shift: \"\\\\Phi\"\n        },\n        {\n          label: \"<i>&#x03c2;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\varsigma\",\n          aside: \"sigma var.\",\n          shift: \"\\\\Sigma\"\n        },\n        {\n          label: \"<i>&#x03f5;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\epsilon\",\n          aside: \"epsilon\",\n          shift: '\\\\char\"0190'\n        },\n        {\n          label: \"<i>&rho;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\rho\",\n          aside: \"rho\",\n          shift: '\\\\char\"3A1'\n        },\n        {\n          label: \"<i>&tau;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\tau\",\n          aside: \"tau\",\n          shift: '\\\\char\"3A4'\n        },\n        {\n          label: \"<i>&upsilon;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\upsilon\",\n          aside: \"upsilon\",\n          shift: \"\\\\Upsilon\"\n        },\n        {\n          label: \"<i>&theta;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\theta\",\n          aside: \"theta\",\n          shift: \"\\\\Theta\"\n        },\n        {\n          label: \"<i>&iota;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\iota\",\n          aside: \"iota\",\n          shift: '\\\\char\"399'\n        },\n        {\n          label: \"<i>&omicron;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\omicron\",\n          aside: \"omicron\",\n          shift: '\\\\char\"39F'\n        },\n        {\n          label: \"<i>&pi;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\pi\",\n          aside: \"pi\",\n          shift: \"\\\\Pi\"\n        }\n      ],\n      [\n        \"[separator-5]\",\n        {\n          label: \"<i>&alpha;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\alpha\",\n          aside: \"alpha\",\n          shift: '\\\\char\"391'\n        },\n        {\n          label: \"<i>&sigma;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\sigma\",\n          aside: \"sigma\",\n          shift: \"\\\\Sigma\"\n        },\n        {\n          label: \"<i>&delta;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\delta\",\n          aside: \"delta\",\n          shift: \"\\\\Delta\"\n        },\n        {\n          latex: \"\\\\phi\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\phi\",\n          aside: \"phi\",\n          shift: \"\\\\Phi\"\n        },\n        {\n          label: \"<i>&gamma;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\gamma\",\n          aside: \"gamma\",\n          shift: \"\\\\Gamma\"\n        },\n        {\n          label: \"<i>&eta;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\eta\",\n          aside: \"eta\",\n          shift: '\\\\char\"397'\n        },\n        {\n          label: \"<i>&xi;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\xi\",\n          aside: \"xi\",\n          shift: \"\\\\Xi\"\n        },\n        {\n          label: \"<i>&kappa;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\kappa\",\n          aside: \"kappa\",\n          shift: \"\\\\Kappa\"\n        },\n        {\n          label: \"<i>&lambda;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\lambda\",\n          aside: \"lambda\",\n          shift: \"\\\\Lambda\"\n        },\n        \"[separator-5]\"\n      ],\n      [\n        \"[shift]\",\n        {\n          label: \"<i>&zeta;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\zeta\",\n          aside: \"zeta\",\n          shift: '\\\\char\"396'\n        },\n        {\n          label: \"<i>&chi;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\chi\",\n          aside: \"chi\",\n          shift: '\\\\char\"3A7'\n        },\n        {\n          label: \"<i>&psi;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\psi\",\n          aside: \"zeta\",\n          shift: \"\\\\Psi\"\n        },\n        {\n          label: \"<i>&omega;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\omega\",\n          aside: \"omega\",\n          shift: \"\\\\Omega\"\n        },\n        {\n          label: \"<i>&beta;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\beta\",\n          aside: \"beta\",\n          shift: '\\\\char\"392'\n        },\n        {\n          label: \"<i>&nu;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\nu\",\n          aside: \"nu\",\n          shift: '\\\\char\"39D'\n        },\n        {\n          label: \"<i>&mu;</i>\",\n          class: \"MLK__tex hide-shift\",\n          insert: \"\\\\mu\",\n          aside: \"mu\",\n          shift: '\\\\char\"39C'\n        },\n        \"[backspace]\"\n      ],\n      [\n        \"[separator]\",\n        {\n          label: \"<i>&#x03b5;</i>\",\n          class: \"MLK__tex\",\n          insert: \"\\\\varepsilon\",\n          aside: \"epsilon var.\"\n        },\n        {\n          label: \"<i>&#x03d1;</i>\",\n          class: \"MLK__tex\",\n          insert: \"\\\\vartheta\",\n          aside: \"theta var.\"\n        },\n        {\n          label: \"<i>&#x3f0;</i>\",\n          class: \"MLK__tex\",\n          insert: \"\\\\varkappa\",\n          aside: \"kappa var.\"\n        },\n        {\n          label: \"<i>&#x03d6;</i>\",\n          class: \"MLK__tex\",\n          insert: \"\\\\varpi\",\n          aside: \"pi var.\"\n        },\n        {\n          label: \"<i>&#x03f1;</i>\",\n          class: \"MLK__tex\",\n          insert: \"\\\\varrho\",\n          aside: \"rho var.\"\n        },\n        \"[left]\",\n        \"[right]\",\n        \"[action]\"\n      ]\n    ]\n  },\n  \"symbols\": {\n    label: \"&infin;\\u2260\\u2208\",\n    labelClass: \"MLK__tex\",\n    tooltip: \"keyboard.tooltip.symbols\",\n    rows: [\n      [\n        {\n          latex: \"\\\\sin\",\n          shift: \"\\\\sin^{-1}\",\n          variants: [\n            { class: \"small\", latex: \"\\\\sinh\" },\n            { class: \"small\", latex: \"\\\\sin^{-1}\" },\n            { class: \"small\", latex: \"\\\\arsinh\" }\n          ]\n        },\n        \"\\\\ln\",\n        {\n          latex: \"\\\\mathrm{abs}\",\n          insert: \"\\\\mathrm{abs}\\\\left(#0\\\\right)\"\n        },\n        {\n          latex: \"\\\\rarr\",\n          shift: \"\\\\rArr\",\n          variants: [\n            { latex: \"\\\\implies\", aside: \"implies\" },\n            { latex: \"\\\\to\", aside: \"to\" },\n            \"\\\\dashv\",\n            { latex: \"\\\\roundimplies\", aside: \"round implies\" }\n          ]\n        },\n        {\n          latex: \"\\\\exists\",\n          variants: [\"\\\\nexists\"],\n          shift: \"\\\\nexists\"\n        },\n        { latex: \"\\\\in\", shift: \"\\\\notin\", variants: [\"\\\\notin\", \"\\\\owns\"] },\n        \"\\\\cup\",\n        {\n          latex: \"\\\\overrightarrow{#@}\",\n          shift: \"\\\\overleftarrow{#@}\",\n          variants: [\n            \"\\\\overleftarrow{#@}\",\n            \"\\\\bar{#@}\",\n            \"\\\\vec{#@}\",\n            \"\\\\hat{#@}\",\n            \"\\\\check{#@}\",\n            \"\\\\dot{#@}\",\n            \"\\\\ddot{#@}\",\n            \"\\\\mathring{#@}\",\n            \"\\\\breve{#@}\",\n            \"\\\\acute{#@}\",\n            \"\\\\tilde{#@}\",\n            \"\\\\grave{#@}\"\n          ]\n        },\n        {\n          class: \"small hide-shift\",\n          latex: \"\\\\lim_{#?}\",\n          shift: \"\\\\lim_{x\\\\to\\\\infty}\",\n          variants: [\n            { class: \"small\", latex: \"\\\\liminf_{#?}\" },\n            { class: \"small\", latex: \"\\\\limsup_{#?}\" }\n          ]\n        },\n        \"\\\\exponentialE\"\n      ],\n      [\n        {\n          latex: \"\\\\cos\",\n          shift: \"\\\\cos^{-1}\",\n          variants: [\n            { class: \"small\", latex: \"\\\\cosh\" },\n            { class: \"small\", latex: \"\\\\cos^{-1}\" },\n            { class: \"small\", latex: \"\\\\arcosh\" }\n          ]\n        },\n        {\n          latex: \"\\\\log\",\n          shift: \"\\\\log_{10}\",\n          variants: [\"\\\\log_{#0}\", \"\\\\log_{10}\"]\n        },\n        \"\\\\left\\\\vert#0\\\\right\\\\vert\",\n        {\n          latex: \"\\\\larr\",\n          shift: \"\\\\lArr\",\n          variants: [\n            { latex: \"\\\\impliedby\", aside: \"implied by\" },\n            { latex: \"\\\\gets\", aside: \"gets\" },\n            \"\\\\lArr\",\n            \"\\\\vdash\",\n            { latex: \"\\\\models\", aside: \"models\" }\n          ]\n        },\n        {\n          latex: \"\\\\forall\",\n          shift: \"\\\\lnot\",\n          variants: [\n            { latex: \"\\\\land\", aside: \"and\" },\n            { latex: \"\\\\lor\", aside: \"or\" },\n            { latex: \"\\\\oplus\", aside: \"xor\" },\n            { latex: \"\\\\lnot\", aside: \"not\" },\n            { latex: \"\\\\downarrow\", aside: \"nor\" },\n            { latex: \"\\\\uparrow\", aside: \"nand\" },\n            { latex: \"\\\\curlywedge\", aside: \"nor\" },\n            { latex: \"\\\\bar\\\\curlywedge\", aside: \"nand\" }\n            // {latex:'\\\\barwedge', aside:'bar wedge'},\n            // {latex:'\\\\curlyvee', aside:'curly vee'},\n            // {latex:'\\\\veebar', aside:'vee bar'},\n          ]\n        },\n        { latex: \"\\\\ni\", shift: \"\\\\not\\\\owns\" },\n        \"\\\\cap\",\n        {\n          latex: \"\\\\overline{#@}\",\n          shift: \"\\\\underline{#@}\",\n          variants: [\n            \"\\\\overbrace{#@}\",\n            \"\\\\overlinesegment{#@}\",\n            \"\\\\overleftrightarrow{#@}\",\n            \"\\\\overrightarrow{#@}\",\n            \"\\\\overleftarrow{#@}\",\n            \"\\\\overgroup{#@}\",\n            \"\\\\underbrace{#@}\",\n            \"\\\\underlinesegment{#@}\",\n            \"\\\\underleftrightarrow{#@}\",\n            \"\\\\underrightarrow{#@}\",\n            \"\\\\underleftarrow{#@}\",\n            \"\\\\undergroup{#@}\"\n          ]\n        },\n        {\n          class: \"hide-shift small\",\n          latex: \"\\\\int\",\n          shift: \"\\\\iint\",\n          variants: [\n            { latex: \"\\\\int_{#?}^{#?}\", class: \"small\" },\n            { latex: \"\\\\int\", class: \"small\" },\n            { latex: \"\\\\smallint\", class: \"small\" },\n            { latex: \"\\\\iint\", class: \"small\" },\n            { latex: \"\\\\iiint\", class: \"small\" },\n            { latex: \"\\\\oint\", class: \"small\" },\n            \"\\\\intop\",\n            \"\\\\iiint\",\n            \"\\\\oiint\",\n            \"\\\\oiiint\",\n            \"\\\\intclockwise\",\n            \"\\\\varointclockwise\",\n            \"\\\\ointctrclockwise\",\n            \"\\\\intctrclockwise\"\n          ]\n        },\n        { latex: \"\\\\pi\", shift: \"\\\\tau\", variants: [\"\\\\tau\"] }\n      ],\n      [\n        {\n          latex: \"\\\\tan\",\n          shift: \"\\\\tan^{-1}\",\n          variants: [\n            { class: \"small\", latex: \"\\\\tanh\" },\n            { class: \"small\", latex: \"\\\\tan^{-1}\" },\n            { class: \"small\", latex: \"\\\\artanh\" },\n            { class: \"small\", latex: \"\\\\arctan\" },\n            { class: \"small\", latex: \"\\\\arctg\" },\n            { class: \"small\", latex: \"\\\\tg\" }\n          ]\n        },\n        {\n          latex: \"\\\\exp\",\n          insert: \"\\\\exp\\\\left(#0\\\\right)\",\n          variants: [\"\\\\exponentialE^{#0}\"]\n        },\n        \"\\\\left\\\\Vert#0\\\\right\\\\Vert\",\n        {\n          latex: \"\\\\lrArr\",\n          shift: \"\\\\leftrightarrow\",\n          variants: [\n            { latex: \"\\\\iff\", aside: \"if and only if\" },\n            \"\\\\leftrightarrow\",\n            \"\\\\leftrightarrows\",\n            \"\\\\Leftrightarrow\",\n            { latex: \"^\\\\biconditional\", aside: \"biconditional\" }\n          ]\n        },\n        { latex: \"\\\\vert\", shift: \"!\" },\n        {\n          latex: \"#@^{\\\\complement}\",\n          aside: \"complement\",\n          variants: [\n            { latex: \"\\\\setminus\", aside: \"set minus\" },\n            { latex: \"\\\\smallsetminus\", aside: \"small set minus\" }\n          ]\n        },\n        {\n          latex: \"\\\\subset\",\n          shift: \"\\\\subseteq\",\n          variants: [\n            \"\\\\subset\",\n            \"\\\\subseteq\",\n            \"\\\\subsetneq\",\n            \"\\\\varsubsetneq\",\n            \"\\\\subsetneqq\",\n            \"\\\\nsubset\",\n            \"\\\\nsubseteq\",\n            \"\\\\supset\",\n            \"\\\\supseteq\",\n            \"\\\\supsetneq\",\n            \"\\\\supsetneqq\",\n            \"\\\\nsupset\",\n            \"\\\\nsupseteq\"\n          ]\n        },\n        {\n          latex: \"#@^{\\\\prime}\",\n          shift: \"#@^{\\\\doubleprime}\",\n          variants: [\"#@^{\\\\doubleprime}\", \"#@\\\\degree\"]\n        },\n        {\n          latex: \"\\\\mathrm{d}\",\n          shift: \"\\\\partial\",\n          variants: [\n            \"\\\\mathrm{d}x\",\n            { latex: \"\\\\dfrac{\\\\mathrm{d}}{\\\\mathrm{d} x}\", class: \"small\" },\n            { latex: \"\\\\frac{\\\\partial}{\\\\partial x}\", class: \"small\" },\n            \"\\\\partial\"\n          ]\n        },\n        {\n          latex: \"\\\\infty\",\n          variants: [\"\\\\aleph_0\", \"\\\\aleph_1\", \"\\\\omega\", \"\\\\mathfrak{m}\"]\n        }\n      ],\n      [\n        { label: \"[shift]\", width: 2 },\n        {\n          class: \"box\",\n          latex: \",\",\n          shift: \";\",\n          variants: [\";\", \"?\"]\n        },\n        {\n          class: \"box\",\n          latex: \"\\\\colon\",\n          shift: \"\\\\Colon\",\n          variants: [\n            { latex: \"\\\\Colon\", aside: \"such that\", class: \"box\" },\n            { latex: \":\", aside: \"ratio\", class: \"box\" },\n            { latex: \"\\\\vdots\", aside: \"\", class: \"box\" },\n            { latex: \"\\\\ddots\", aside: \"\", class: \"box\" },\n            { latex: \"\\\\ldotp\", aside: \"low dot\", class: \"box\" },\n            { latex: \"\\\\cdotp\", aside: \"center dot\", class: \"box\" },\n            { latex: \"\\\\ldots\", aside: \"low ellipsis\", class: \"box\" },\n            { latex: \"\\\\cdots\", aside: \"center ellipsis\", class: \"box\" },\n            { latex: \"\\\\therefore\", aside: \"therefore\", class: \"box\" },\n            { latex: \"\\\\because\", aside: \"because\", class: \"box\" }\n          ]\n        },\n        {\n          class: \"box\",\n          latex: \"\\\\cdot\",\n          aside: \"centered dot\",\n          shift: \"\\\\ast\",\n          variants: [\n            \"\\\\circ\",\n            \"\\\\bigcirc\",\n            \"\\\\bullet\",\n            \"\\\\odot\",\n            \"\\\\oslash\",\n            \"\\\\circledcirc\",\n            \"\\\\ast\",\n            \"\\\\star\",\n            \"\\\\times\",\n            \"\\\\doteq\",\n            \"\\\\doteqdot\"\n          ]\n        },\n        \"[separator]\",\n        \"[left]\",\n        \"[right]\",\n        {\n          label: \"[backspace]\",\n          width: 1,\n          class: \"action hide-shift\"\n        },\n        { label: \"[action]\", width: 1 }\n      ]\n    ]\n  },\n  \"compact\": {\n    label: \"compact\",\n    rows: [\n      [\n        \"[+]\",\n        \"[-]\",\n        \"[*]\",\n        \"[/]\",\n        \"[=]\",\n        \"[.]\",\n        \"[(]\",\n        \"[)]\",\n        \"\\\\sqrt{#0}\",\n        \"#@^{#?}\"\n      ],\n      [\"[1]\", \"[2]\", \"[3]\", \"[4]\", \"[5]\", \"[6]\", \"[7]\", \"[8]\", \"[9]\", \"[0]\"],\n      [\"[hr]\"],\n      [\n        \"[undo]\",\n        \"[redo]\",\n        \"[separator]\",\n        \"[separator]\",\n        \"[separator]\",\n        \"[left]\",\n        \"[right]\",\n        { label: \"[backspace]\", class: \"action hide-shift\" },\n        \"[hide-keyboard]\"\n      ]\n    ]\n  },\n  \"minimalist\": {\n    label: \"minimalist\",\n    layers: [\n      {\n        style: `\n          .minimalist-backdrop {\n            display: flex;\n            justify-content: center;\n          }          \n          .minimalist-container {\n            --keycap-height: 40px;\n            --keycap-max-width: 53px;\n            --keycap-small-font-size: 12px;\n            background: var(--keyboard-background);\n            padding: 20px;\n            border-top-left-radius: 8px;\n            border-top-right-radius: 8px;\n            border: 1px solid var(--keyboard-border);\n            box-shadow: 0 0 32px rgb(0 0 0 / 30%);\n          }        \n        `,\n        backdrop: \"minimalist-backdrop\",\n        container: \"minimalist-container\",\n        rows: [\n          [\n            \"+\",\n            \"-\",\n            \"\\\\times\",\n            { latex: \"\\\\frac{#@}{#0}\", class: \"small\" },\n            \"=\",\n            \"[.]\",\n            \"(\",\n            \")\",\n            { latex: \"\\\\sqrt{#0}\", class: \"small\" },\n            { latex: \"#@^{#?}\", class: \"small\" }\n          ],\n          [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"0\"],\n          [\"[hr]\"],\n          [\n            \"[undo]\",\n            \"[redo]\",\n            \"[separator]\",\n            \"[separator]\",\n            \"[separator]\",\n            \"[left]\",\n            \"[right]\",\n            { label: \"[backspace]\", class: \"action hide-shift\" },\n            \"[hide-keyboard]\"\n          ]\n        ]\n      }\n    ]\n  },\n  \"numeric-only\": {\n    label: \"123\",\n    labelClass: \"MLK__tex-math\",\n    tooltip: \"keyboard.tooltip.numeric\",\n    id: \"numeric-only\",\n    rows: [\n      [\"7\", \"8\", \"9\", \"[separator]\", { label: \"[backspace]\", width: 2 }],\n      [\"4\", \"5\", \"6\", \"[separator]\", \"[separator]\", \"[separator]\"],\n      [\"1\", \"2\", \"3\", \"[separator]\", \"[separator]\", \"[separator]\"],\n      [\n        \"0\",\n        { label: \"[.]\", variants: [] },\n        \"-\",\n        \"[separator]\",\n        \"[left]\",\n        \"[right]\"\n      ]\n    ]\n  }\n};\n\n// src/virtual-keyboard/variants.ts\nvar VARIANTS2 = {\n  // '0-extended': [\n  //   '\\\\emptyset',\n  //   '\\\\varnothing',\n  //   '\\\\infty',\n  //   { latex: '#?_0', insert: '#@_0' },\n  //   '\\\\circ',\n  //   '\\\\bigcirc',\n  //   '\\\\bullet',\n  // ],\n  \"0\": [\"\\\\varnothing\", \"\\\\infty\"],\n  \"1\": [\"\\\\frac{1}{#@}\", \"#@^{-1}\", \"\\\\times 10^{#?}\", \"\\\\phi\", \"\\\\imaginaryI\"],\n  \"2\": [\"\\\\frac{1}{2}\", \"#@^2\", \"\\\\sqrt2\", \"\\\\exponentialE\"],\n  \"3\": [\"\\\\frac{1}{3}\", \"#@^3\", \"\\\\sqrt3\", \"\\\\pi\"],\n  \"4\": [\"\\\\frac{1}{4}\", \"#@^4\"],\n  \"5\": [\"\\\\frac{1}{5}\", \"#@^5\", \"\\\\sqrt5\"],\n  \"6\": [\"\\\\frac{1}{6}\", \"#@^6\"],\n  \"7\": [\"\\\\frac{1}{7}\", \"#@^7\"],\n  \"8\": [\"\\\\frac{1}{8}\", \"#@^8\"],\n  \"9\": [\"\\\\frac{1}{9}\", \"#@^9\"],\n  \".\": [\".\", \",\", \";\", \"\\\\colon\"],\n  \",\": [\"{,}\", \".\", \";\", \"\\\\colon\"],\n  \"a\": [\n    { latex: \"\\\\aleph\", aside: \"aleph\" },\n    { latex: \"\\\\forall\", aside: \"for all\" },\n    \"\\xE5\",\n    \"\\xE0\",\n    \"\\xE1\",\n    \"\\xE2\",\n    \"\\xE4\",\n    \"\\xE6\"\n  ],\n  \"A\": [\n    { latex: \"\\\\aleph\", aside: \"aleph\" },\n    { latex: \"\\\\forall\", aside: \"for all\" },\n    \"\\xC5\",\n    \"\\xC0\",\n    \"\\xC1\",\n    \"\\xC2\",\n    \"\\xC4\",\n    \"\\xC6\"\n  ],\n  \"b\": [{ latex: \"\\\\beth\", aside: \"beth\" }],\n  \"c\": [{ latex: \"\\\\C\", aside: \"set of complex numbers\" }, \"\\xE7\"],\n  \"d\": [{ latex: \"\\\\daleth\", aside: \"daleth\" }],\n  \"e\": [\n    { latex: \"\\\\exponentialE\", aside: \"exponential e\" },\n    { latex: \"\\\\exists\", aside: \"there is\" },\n    { latex: \"\\\\nexists\", aside: \"there isn\\u2019t\" },\n    \"\\xE8\",\n    \"\\xE9\",\n    \"\\xEA\",\n    \"\\xEB\"\n  ],\n  \"E\": [\n    { latex: \"\\\\exponentialE\", aside: \"exponential e\" },\n    { latex: \"\\\\exists\", aside: \"there is\" },\n    { latex: \"\\\\nexists\", aside: \"there isn\\u2019t\" },\n    \"\\xC8\",\n    \"\\xC9\",\n    \"\\xCA\",\n    \"\\xCB\"\n  ],\n  \"g\": [{ latex: \"\\\\gimel\", aside: \"gimel\" }],\n  \"h\": [\n    { latex: \"\\\\hbar\", aside: \"h bar\" },\n    { latex: \"\\\\hslash\", aside: \"h slash\" }\n  ],\n  \"i\": [{ latex: \"\\\\imaginaryI\", aside: \"imaginary i\" }, \"\\xEC\", \"\\xED\", \"\\xEE\", \"\\xEF\"],\n  \"I\": [{ latex: \"\\\\imaginaryI\", aside: \"imaginary i\" }, \"\\xCC\", \"\\xCD\", \"\\xCE\", \"\\xCF\"],\n  \"j\": [{ latex: \"\\\\imaginaryJ\", aside: \"imaginary j\" }],\n  \"l\": [{ latex: \"\\\\ell\", aside: \"ell\" }],\n  \"n\": [{ latex: \"\\\\mathbb{N}\", aside: \"set of natural numbers\" }, \"\\xF1\"],\n  \"o\": [\"\\xF8\", \"\\u0153\", \"\\xF2\", \"\\xF3\", \"\\xF4\", \"\\xF6\"],\n  \"O\": [\"\\xF8\", \"\\u0152\", \"\\xD2\", \"\\xD3\", \"\\xD4\", \"\\xD6\"],\n  \"p\": [{ latex: \"\\\\mathbb{P}\", aside: \"set of primes\" }],\n  \"q\": [{ latex: \"\\\\mathbb{Q}\", aside: \"set of rational numbers\" }],\n  \"r\": [{ latex: \"\\\\mathbb{R}\", aside: \"set of real numbers\" }],\n  \"u\": [\"\\xF9\", \"\\xFA\", \"\\xFB\", \"\\xFC\"],\n  \"U\": [\"\\xD9\", \"\\xDA\", \"\\xDB\", \"\\xDC\"],\n  \"z\": [{ latex: \"\\\\mathbb{Z}\", aside: \"set of integers\" }],\n  \"y\": [\"\\xFD\", \"\\xFF\"],\n  \"Y\": [\"\\u0178\"],\n  \"space\": [\n    {\n      latex: '\\\\char\"203A\\\\!\\\\char\"2039',\n      insert: \"\\\\!\",\n      aside: \"negative thin space<br>\\u207B\\xB3\\u29F8\\u2081\\u2088 em\"\n    },\n    {\n      latex: '\\\\char\"203A\\\\,\\\\char\"2039',\n      insert: \"\\\\,\",\n      aside: \"thin space<br>\\xB3\\u29F8\\u2081\\u2088 em\"\n    },\n    {\n      latex: '\\\\char\"203A\\\\:\\\\char\"2039',\n      insert: \"\\\\:\",\n      aside: \"medium space<br>\\u2074\\u29F8\\u2081\\u2088 em\"\n    },\n    {\n      latex: '\\\\char\"203A\\\\;\\\\char\"2039',\n      insert: \"\\\\;\",\n      aside: \"thick space<br>\\u2075\\u29F8\\u2081\\u2088 em\"\n    },\n    {\n      latex: '\\\\char\"203A\\\\ \\\\char\"2039',\n      insert: \"\\\\ \",\n      aside: \"\\u2153 em\"\n    },\n    {\n      latex: '\\\\char\"203A\\\\enspace\\\\char\"2039',\n      insert: \"\\\\enspace\",\n      aside: \"\\xBD em\"\n    },\n    {\n      latex: '\\\\char\"203A\\\\quad\\\\char\"2039',\n      insert: \"\\\\quad\",\n      aside: \"1 em\"\n    },\n    {\n      latex: '\\\\char\"203A\\\\qquad\\\\char\"2039',\n      insert: \"\\\\qquad\",\n      aside: \"2 em\"\n    }\n  ]\n};\nvar gVariantPanelController;\nfunction showVariantsPanel(element, onClose) {\n  var _a3, _b3, _c2, _d2, _e;\n  const keyboard = VirtualKeyboard.singleton;\n  if (!keyboard) return;\n  const keycap = parentKeycap(element);\n  let variantDef = \"\";\n  if (window.mathVirtualKeyboard.isShifted) {\n    const shiftedDefinition = (_a3 = keyboard.getKeycap(keycap == null ? void 0 : keycap.id)) == null ? void 0 : _a3.shift;\n    if (typeof shiftedDefinition === \"object\" && \"variants\" in shiftedDefinition) {\n      variantDef = (_b3 = shiftedDefinition.variants) != null ? _b3 : \"\";\n    }\n  } else variantDef = (_d2 = (_c2 = keyboard.getKeycap(keycap == null ? void 0 : keycap.id)) == null ? void 0 : _c2.variants) != null ? _d2 : \"\";\n  if (typeof variantDef === \"string\" && !hasVariants(variantDef) || Array.isArray(variantDef) && variantDef.length === 0) {\n    onClose == null ? void 0 : onClose();\n    return;\n  }\n  const variants = {};\n  let markup = \"\";\n  for (const variant of getVariants(variantDef)) {\n    const keycap2 = normalizeKeycap(variant);\n    const id = Date.now().toString(36).slice(-2) + Math.floor(Math.random() * 1e5).toString(36);\n    variants[id] = keycap2;\n    const [keycapMarkup, keycapCls] = renderKeycap(keycap2);\n    markup += `<div id=${id} class=\"item ${keycapCls}\">${keycapMarkup}</div>`;\n  }\n  const variantPanel = document.createElement(\"div\");\n  variantPanel.setAttribute(\"aria-hidden\", \"true\");\n  variantPanel.className = \"MLK__variant-panel\";\n  variantPanel.style.height = \"auto\";\n  const l = Object.keys(variants).length;\n  let w = 5;\n  if (l === 1) w = 1;\n  else if (l === 2 || l === 4) w = 2;\n  else if (l === 3 || l === 5 || l === 6) w = 3;\n  else if (l >= 7 && l < 14) w = 4;\n  variantPanel.style.width = `calc(var(--variant-keycap-length) * ${w} + 12px)`;\n  variantPanel.innerHTML = mathfield_element_default.createHTML(markup);\n  Scrim.open({\n    root: (_e = keyboard == null ? void 0 : keyboard.container) == null ? void 0 : _e.querySelector(\".ML__keyboard\"),\n    child: variantPanel\n  });\n  gVariantPanelController = new AbortController();\n  const { signal } = gVariantPanelController;\n  const position = element == null ? void 0 : element.getBoundingClientRect();\n  if (position) {\n    if (position.top - variantPanel.clientHeight < 0) {\n      variantPanel.style.width = \"auto\";\n      if (l <= 6)\n        variantPanel.style.height = \"56px\";\n      else if (l <= 12)\n        variantPanel.style.height = \"108px\";\n      else if (l <= 18)\n        variantPanel.style.height = \"205px\";\n      else variantPanel.classList.add(\"compact\");\n    }\n    const left = Math.max(\n      0,\n      Math.min(\n        window.innerWidth - variantPanel.offsetWidth,\n        (position.left + position.right - variantPanel.offsetWidth) / 2\n      )\n    );\n    const top = position.top - variantPanel.clientHeight + 5;\n    console.log(\"left: \", left);\n    variantPanel.style.left = `${left}px`;\n    variantPanel.style.top = `${top}px`;\n    variantPanel.classList.add(\"is-visible\");\n    requestAnimationFrame(() => {\n      variantPanel.addEventListener(\n        \"pointerup\",\n        (ev) => {\n          const target = parentKeycap(ev.target);\n          if (!(target == null ? void 0 : target.id) || !variants[target.id]) return;\n          executeKeycapCommand(variants[target.id]);\n          hideVariantsPanel();\n          onClose == null ? void 0 : onClose();\n          ev.preventDefault();\n        },\n        { capture: true, passive: false, signal }\n      );\n      variantPanel.addEventListener(\n        \"pointerenter\",\n        (ev) => {\n          const target = parentKeycap(ev.target);\n          if (!(target == null ? void 0 : target.id) || !variants[target.id]) return;\n          target.classList.add(\"is-active\");\n        },\n        { capture: true, signal }\n      );\n      variantPanel.addEventListener(\n        \"pointerleave\",\n        (ev) => {\n          const target = parentKeycap(ev.target);\n          if (!(target == null ? void 0 : target.id) || !variants[target.id]) return;\n          target.classList.remove(\"is-active\");\n        },\n        { capture: true, signal }\n      );\n      window.addEventListener(\n        \"pointercancel\",\n        () => {\n          hideVariantsPanel();\n          onClose == null ? void 0 : onClose();\n        },\n        { signal }\n      );\n      window.addEventListener(\n        \"pointerup\",\n        () => {\n          hideVariantsPanel();\n          onClose == null ? void 0 : onClose();\n        },\n        { signal }\n      );\n    });\n  }\n  return;\n}\nfunction hideVariantsPanel() {\n  gVariantPanelController == null ? void 0 : gVariantPanelController.abort();\n  gVariantPanelController = null;\n  if (Scrim.state === \"open\") Scrim.close();\n}\nfunction makeVariants(id) {\n  if (id === \"foreground-color\") {\n    const result = [];\n    for (const color of Object.keys(FOREGROUND_COLORS)) {\n      result.push({\n        class: \"swatch-button\",\n        label: '<span style=\"border: 3px solid ' + FOREGROUND_COLORS[color] + '\"></span>',\n        command: [\"applyStyle\", { color }]\n      });\n    }\n    return result;\n  }\n  if (id === \"background-color\") {\n    const result = [];\n    for (const color of Object.keys(BACKGROUND_COLORS)) {\n      result.push({\n        class: \"swatch-button\",\n        label: '<span style=\"background:' + BACKGROUND_COLORS[color] + '\"></span>',\n        command: [\"applyStyle\", { backgroundColor: color }]\n      });\n    }\n    return result;\n  }\n  return void 0;\n}\nfunction hasVariants(id) {\n  return VARIANTS2[id] !== void 0;\n}\nfunction getVariants(id) {\n  var _a3;\n  if (typeof id !== \"string\") return id;\n  if (!VARIANTS2[id]) VARIANTS2[id] = (_a3 = makeVariants(id)) != null ? _a3 : [];\n  return VARIANTS2[id];\n}\n\n// src/virtual-keyboard/utils.ts\nfunction jsonToCssProps(json) {\n  if (typeof json === \"string\") return json;\n  return Object.entries(json).map(([k, v]) => `${k}:${v} !important`).join(\";\");\n}\nfunction jsonToCss(json) {\n  return Object.keys(json).map((k) => {\n    return `${k} {${jsonToCssProps(json[k])}}`;\n  }).join(\"\");\n}\nfunction latexToMarkup2(latex) {\n  if (!latex) return \"\";\n  const context = new Context();\n  const root = new Atom({\n    mode: \"math\",\n    type: \"root\",\n    body: parseLatex(latex, {\n      context,\n      args: (arg) => arg === \"@\" ? \"{\\\\class{ML__box-placeholder}{\\\\blacksquare}}\" : \"\\\\placeholder{}\"\n    })\n  });\n  const box = coalesce(\n    applyInterBoxSpacing(\n      new Box(root.render(context), { classes: \"ML__base\" }),\n      context\n    )\n  );\n  return makeStruts(box, { classes: \"ML__latex\" }).toMarkup();\n}\nfunction normalizeLayer(layer) {\n  var _a3;\n  if (Array.isArray(layer)) return layer.map((x) => normalizeLayer(x)).flat();\n  const result = typeof layer === \"string\" ? { markup: layer } : layer;\n  if (\"rows\" in result && Array.isArray(result.rows))\n    result.rows = result.rows.map((row) => row.map((x) => normalizeKeycap(x)));\n  (_a3 = result.id) != null ? _a3 : result.id = \"ML__layer_\" + Date.now().toString(36).slice(-2) + Math.floor(Math.random() * 1e5).toString(36);\n  return [result];\n}\nfunction alphabeticLayout() {\n  var _a3, _b3;\n  const keyboard = window.mathVirtualKeyboard;\n  let layoutName = keyboard.alphabeticLayout;\n  if (layoutName === \"auto\") {\n    const activeLayout = getActiveKeyboardLayout();\n    if (activeLayout) layoutName = activeLayout.virtualLayout;\n    if (!layoutName || layoutName === \"auto\") {\n      layoutName = (_a3 = {\n        fr: \"azerty\",\n        be: \"azerty\",\n        al: \"qwertz\",\n        ba: \"qwertz\",\n        cz: \"qwertz\",\n        de: \"qwertz\",\n        hu: \"qwertz\",\n        sk: \"qwertz\",\n        ch: \"qwertz\"\n      }[l10n.locale.slice(0, 2)]) != null ? _a3 : \"qwerty\";\n    }\n  }\n  const ALPHABETIC_TEMPLATE = {\n    qwerty: [\"qwertyuiop\", \" asdfghjkl \", \"^zxcvbnm~\"],\n    azerty: [\"azertyuiop\", \"qsdfghjklm\", \"^ wxcvbn ~\"],\n    qwertz: [\"qwertzuiop\", \" asdfghjkl \", \"^yxcvbnm~\"],\n    dvorak: [\"^  pyfgcrl \", \"aoeuidhtns\", \"qjkxbmwvz~\"],\n    colemak: [\" qwfpgjluy \", \"arstdhneio\", \"^zxcvbkm~\"]\n  };\n  const template = (_b3 = ALPHABETIC_TEMPLATE[layoutName]) != null ? _b3 : ALPHABETIC_TEMPLATE.qwerty;\n  const rows = layoutName === \"azerty\" ? [\n    [\n      { label: \"1\", variants: \"1\" },\n      { label: \"2\", shift: { latex: \"\\xE9\" }, variants: \"2\" },\n      { label: \"3\", shift: { latex: \"\\xF9\" }, variants: \"3\" },\n      { label: \"4\", variants: \"4\" },\n      { label: \"5\", shift: { label: \"(\", latex: \"(\" }, variants: \"5\" },\n      { label: \"6\", shift: { label: \")\", latex: \")\" }, variants: \"6\" },\n      { label: \"7\", shift: { latex: \"\\xE8\" }, variants: \"7\" },\n      { label: \"8\", shift: { latex: \"\\xEA\" }, variants: \"8\" },\n      { label: \"9\", shift: { latex: \"\\xE7\" }, variants: \"9\" },\n      { label: \"0\", shift: { latex: \"\\xE0\" }, variants: \"0\" }\n    ]\n  ] : [\n    [\n      { label: \"1\", variants: \"1\" },\n      { label: \"2\", variants: \"2\" },\n      { label: \"3\", variants: \"3\" },\n      { label: \"4\", variants: \"4\" },\n      { label: \"5\", shift: { latex: \"\\\\frac{#@}{#?}\" }, variants: \"5\" },\n      { label: \"6\", shift: { latex: \"#@^#?\" }, variants: \"6\" },\n      { label: \"7\", variants: \"7\" },\n      { label: \"8\", shift: { latex: \"\\\\times\" }, variants: \"8\" },\n      { label: \"9\", shift: { label: \"(\", latex: \"(\" }, variants: \"9\" },\n      { label: \"0\", shift: { label: \")\", latex: \")\" }, variants: \"0\" }\n    ]\n  ];\n  for (const templateRow of template) {\n    const row = [];\n    for (const k of templateRow) {\n      if (/[a-z]/.test(k)) {\n        row.push({\n          label: k,\n          class: \"hide-shift\",\n          shift: {\n            label: k.toUpperCase(),\n            variants: hasVariants(k.toUpperCase()) ? k.toUpperCase() : void 0\n          },\n          variants: hasVariants(k) ? k : void 0\n        });\n      } else if (k === \"~\") {\n        if (layoutName !== \"dvorak\") row.push(\"[backspace]\");\n        else row.push({ label: \"[backspace]\", width: 1 });\n      } else if (k === \"^\") row.push(\"[shift]\");\n      else if (k === \" \") row.push(\"[separator-5]\");\n    }\n    rows.push(row);\n  }\n  rows.push([\n    // {\n    //   class: 'action',\n    //   label: 'text mode',\n    //   command: ['performWithFeedback', ['switchMode', 'text', '', '']],\n    // },\n    \"[-]\",\n    \"[+]\",\n    \"[=]\",\n    { label: \" \", width: 1.5 },\n    { label: \",\", shift: \";\", variants: \".\", class: \"hide-shift\" },\n    \"[.]\",\n    \"[left]\",\n    \"[right]\",\n    { label: \"[action]\", width: 1.5 }\n  ]);\n  return {\n    label: \"abc\",\n    labelClass: \"MLK__tex-math\",\n    tooltip: \"keyboard.tooltip.alphabetic\",\n    layers: normalizeLayer({ rows })\n  };\n}\nfunction normalizeLayout(layout) {\n  if (layout === \"alphabetic\") return alphabeticLayout();\n  if (typeof layout === \"string\") {\n    console.assert(\n      LAYOUTS[layout] !== void 0,\n      `MathLive 0.101.0: unknown keyboard layout \"${layout}\"`\n    );\n    return normalizeLayout(LAYOUTS[layout]);\n  }\n  let result;\n  if (\"rows\" in layout && Array.isArray(layout.rows)) {\n    console.assert(\n      !(\"layers\" in layout || \"markup\" in layout),\n      `MathLive 0.101.0: when providing a \"rows\" property, \"layers\" and \"markup\" are ignored`\n    );\n    const _a3 = layout, { rows } = _a3, partialLayout = __objRest(_a3, [\"rows\"]);\n    result = __spreadProps(__spreadValues({}, partialLayout), {\n      layers: normalizeLayer({ rows: layout.rows })\n    });\n  } else if (\"markup\" in layout && typeof layout.markup === \"string\") {\n    const _b3 = layout, { markup } = _b3, partialLayout = __objRest(_b3, [\"markup\"]);\n    result = __spreadProps(__spreadValues({}, partialLayout), {\n      layers: normalizeLayer(layout.markup)\n    });\n  } else {\n    result = __spreadValues({}, layout);\n    if (\"layers\" in layout) result.layers = normalizeLayer(layout.layers);\n    else {\n      console.error(\n        `MathLive 0.101.0: provide either a \"rows\", \"markup\" or \"layers\" property`\n      );\n    }\n  }\n  let hasShift = false;\n  let hasEdit = false;\n  for (const layer of result.layers) {\n    if (layer.rows) {\n      for (const keycap of layer.rows.flat()) {\n        if (isShiftKey(keycap)) hasShift = true;\n        const command = keycap.command;\n        if (typeof command === \"string\" && [\"undo\", \"redo\", \"cut\", \"copy\", \"paste\"].includes(command))\n          hasEdit = true;\n      }\n    }\n  }\n  if (!(\"displayShiftedKeycaps\" in layout) || layout.displayShiftedKeycaps === void 0)\n    result.displayShiftedKeycaps = hasShift;\n  if (!(\"displayEditToolbar\" in layout) || layout.displayEditToolbar === void 0)\n    result.displayEditToolbar = !hasEdit;\n  return result;\n}\nfunction makeLayoutsToolbar(keyboard, index) {\n  var _a3, _b3;\n  let markup = `<div class=\"left\">`;\n  if (keyboard.normalizedLayouts.length > 1) {\n    for (const [i, l] of keyboard.normalizedLayouts.entries()) {\n      const layout = l;\n      const classes = [i === index ? \"selected\" : \"layer-switch\"];\n      if (layout.tooltip) classes.push(\"MLK__tooltip\");\n      if (layout.labelClass) classes.push(...layout.labelClass.split(\" \"));\n      markup += `<div class=\"${classes.join(\" \")}\"`;\n      if (layout.tooltip) {\n        markup += \" data-tooltip='\" + ((_a3 = localize(layout.tooltip)) != null ? _a3 : layout.tooltip) + \"' \";\n      }\n      if (i !== index) markup += `data-layer=\"${layout.layers[0].id}\"`;\n      markup += `>${(_b3 = layout.label) != null ? _b3 : \"untitled\"}</div>`;\n    }\n  }\n  markup += \"</div>\";\n  return markup;\n}\nfunction makeEditToolbar(options, mathfield) {\n  let result = \"\";\n  const toolbarOptions = options.editToolbar;\n  if (toolbarOptions === \"none\") return \"\";\n  const availableActions = [];\n  if (mathfield.selectionIsCollapsed)\n    availableActions.push(\"undo\", \"redo\", \"pasteFromClipboard\");\n  else {\n    availableActions.push(\n      \"cutToClipboard\",\n      \"copyToClipboard\",\n      \"pasteFromClipboard\"\n    );\n  }\n  const actionsMarkup = {\n    undo: `<div class='action ${mathfield.canUndo === false ? \"disabled\" : \"\"}'\n          data-command='\"undo\"'\n          data-tooltip='${localize(\"tooltip.undo\")}'>\n          <svg><use xlink:href='#svg-undo' /></svg>\n      </div>`,\n    redo: `<div class='action ${mathfield.canRedo === false ? \"disabled\" : \"\"}'\n          data-command='\"redo\"'\n          data-tooltip='${localize(\"tooltip.redo\")}'>\n          <svg><use xlink:href='#svg-redo' /></svg>\n      </div>`,\n    cutToClipboard: `\n        <div class='action'\n            data-command='\"cutToClipboard\"'\n            data-tooltip='${localize(\"tooltip.cut to clipboard\")}'>\n            <svg><use xlink:href='#svg-cut' /></svg>\n        </div>\n    `,\n    copyToClipboard: `\n        <div class='action'\n            data-command='\"copyToClipboard\"'\n            data-tooltip='${localize(\"tooltip.copy to clipboard\")}'>\n            <svg><use xlink:href='#svg-copy' /></svg>\n        </div>\n    `,\n    pasteFromClipboard: `\n        <div class='action'\n            data-command='\"pasteFromClipboard\"'\n            data-tooltip='${localize(\"tooltip.paste from clipboard\")}'>\n            <svg><use xlink:href='#svg-paste' /></svg>\n        </div>\n    `\n  };\n  result += availableActions.map((action) => actionsMarkup[action]).join(\"\");\n  return result;\n}\nfunction makeSyntheticKeycaps(elementList) {\n  for (const element of elementList)\n    makeSyntheticKeycap(element);\n}\nfunction makeSyntheticKeycap(element) {\n  const keyboard = VirtualKeyboard.singleton;\n  if (!keyboard) return;\n  const keycap = {};\n  if (!element.id) {\n    if (element.hasAttribute(\"data-label\"))\n      keycap.label = element.dataset.label;\n    if (element.hasAttribute(\"data-latex\"))\n      keycap.latex = element.dataset.latex;\n    if (element.hasAttribute(\"data-key\")) keycap.key = element.dataset.key;\n    if (element.hasAttribute(\"data-insert\"))\n      keycap.insert = element.dataset.insert;\n    if (element.hasAttribute(\"data-variants\"))\n      keycap.variants = element.dataset.variants;\n    if (element.hasAttribute(\"data-aside\"))\n      keycap.aside = element.dataset.aside;\n    if (element.className) keycap.class = element.className;\n    if (!keycap.label && !keycap.latex && !keycap.key && !keycap.insert) {\n      keycap.latex = element.innerText;\n      keycap.label = element.innerHTML;\n    }\n    if (element.hasAttribute(\"data-command\")) {\n      try {\n        keycap.command = JSON.parse(element.dataset.command);\n      } catch (e) {\n      }\n    }\n    element.id = keyboard.registerKeycap(keycap);\n  }\n  if (!element.innerHTML) {\n    const [markup, _] = renderKeycap(keycap);\n    element.innerHTML = globalThis.MathfieldElement.createHTML(markup);\n  }\n}\nfunction injectStylesheets() {\n  injectStylesheet(\"virtual-keyboard\");\n  injectStylesheet(\"core\");\n  void loadFonts();\n}\nfunction releaseStylesheets() {\n  releaseStylesheet(\"core\");\n  releaseStylesheet(\"virtual-keyboard\");\n}\nvar SVG_ICONS = `<svg xmlns=\"http://www.w3.org/2000/svg\" style=\"display: none;\">\n\n<symbol id=\"svg-delete-backward\" viewBox=\"0 0 576 512\">\n  <path d=\"M432.1 208.1L385.9 256L432.1 303C442.3 312.4 442.3 327.6 432.1 336.1C423.6 346.3 408.4 346.3 399 336.1L352 289.9L304.1 336.1C295.6 346.3 280.4 346.3 271 336.1C261.7 327.6 261.7 312.4 271 303L318.1 256L271 208.1C261.7 199.6 261.7 184.4 271 175C280.4 165.7 295.6 165.7 304.1 175L352 222.1L399 175C408.4 165.7 423.6 165.7 432.1 175C442.3 184.4 442.3 199.6 432.1 208.1V208.1zM512 64C547.3 64 576 92.65 576 128V384C576 419.3 547.3 448 512 448H205.3C188.3 448 172 441.3 160 429.3L9.372 278.6C3.371 272.6 0 264.5 0 256C0 247.5 3.372 239.4 9.372 233.4L160 82.75C172 70.74 188.3 64 205.3 64L512 64zM528 128C528 119.2 520.8 112 512 112H205.3C201 112 196.9 113.7 193.9 116.7L54.63 256L193.9 395.3C196.9 398.3 201 400 205.3 400H512C520.8 400 528 392.8 528 384V128z\"/>\n</symbol>\n\n<symbol id=\"svg-shift\" viewBox=\"0 0 384 512\">\n  <path d=\"M2.438 252.3C7.391 264.2 19.06 272 32 272h80v160c0 26.51 21.49 48 48 48h64C250.5 480 272 458.5 272 432v-160H352c12.94 0 24.61-7.797 29.56-19.75c4.953-11.97 2.219-25.72-6.938-34.88l-160-176C208.4 35.13 200.2 32 192 32S175.6 35.13 169.4 41.38l-160 176C.2188 226.5-2.516 240.3 2.438 252.3zM192 86.63L313.4 224H224v208H160V224H70.63L192 86.63z\"/>\n</symbol>\n\n<symbol id=\"svg-commit\" viewBox=\"0 0 512 512\">\n  <path d=\"M135 432.1l-128-128C2.344 300.3 0 294.2 0 288s2.344-12.28 7.031-16.97l128-128c9.375-9.375 24.56-9.375 33.94 0s9.375 24.56 0 33.94L81.94 264H464v-208C464 42.75 474.8 32 488 32S512 42.75 512 56V288c0 13.25-10.75 24-24 24H81.94l87.03 87.03c9.375 9.375 9.375 24.56 0 33.94S144.4 442.3 135 432.1z\"/>\n</symbol>\n\n\n<symbol id=\"circle-plus\" viewBox=\"0 0 512 512\"><path d=\"M256 48a208 208 0 1 1 0 416 208 208 0 1 1 0-416zm0 464A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM232 344c0 13.3 10.7 24 24 24s24-10.7 24-24V280h64c13.3 0 24-10.7 24-24s-10.7-24-24-24H280V168c0-13.3-10.7-24-24-24s-24 10.7-24 24v64H168c-13.3 0-24 10.7-24 24s10.7 24 24 24h64v64z\"/></symbol>\n\n<symbol id=\"svg-command\" viewBox=\"0 0 640 512\">\n  <path d=\"M34.495 36.465l211.051 211.05c4.686 4.686 4.686 12.284 0 16.971L34.495 475.535c-4.686 4.686-12.284 4.686-16.97 0l-7.071-7.07c-4.686-4.686-4.686-12.284 0-16.971L205.947 256 10.454 60.506c-4.686-4.686-4.686-12.284 0-16.971l7.071-7.07c4.686-4.687 12.284-4.687 16.97 0zM640 468v-10c0-6.627-5.373-12-12-12H300c-6.627 0-12 5.373-12 12v10c0 6.627 5.373 12 12 12h328c6.627 0 12-5.373 12-12z\"/>\n</symbol>\n\n<symbol id=\"svg-undo\" viewBox=\"0 0 512 512\">\n  <path d=\"M20 8h10c6.627 0 12 5.373 12 12v110.625C85.196 57.047 165.239 7.715 256.793 8.001 393.18 8.428 504.213 120.009 504 256.396 503.786 393.181 392.834 504 256 504c-63.926 0-122.202-24.187-166.178-63.908-5.113-4.618-5.354-12.561-.482-17.433l7.069-7.069c4.503-4.503 11.749-4.714 16.482-.454C150.782 449.238 200.935 470 256 470c117.744 0 214-95.331 214-214 0-117.744-95.331-214-214-214-82.862 0-154.737 47.077-190.289 116H180c6.627 0 12 5.373 12 12v10c0 6.627-5.373 12-12 12H20c-6.627 0-12-5.373-12-12V20c0-6.627 5.373-12 12-12z\"/>\n</symbol>\n<symbol id=\"svg-redo\" viewBox=\"0 0 512 512\">\n  <path d=\"M492 8h-10c-6.627 0-12 5.373-12 12v110.625C426.804 57.047 346.761 7.715 255.207 8.001 118.82 8.428 7.787 120.009 8 256.396 8.214 393.181 119.166 504 256 504c63.926 0 122.202-24.187 166.178-63.908 5.113-4.618 5.354-12.561.482-17.433l-7.069-7.069c-4.503-4.503-11.749-4.714-16.482-.454C361.218 449.238 311.065 470 256 470c-117.744 0-214-95.331-214-214 0-117.744 95.331-214 214-214 82.862 0 154.737 47.077 190.289 116H332c-6.627 0-12 5.373-12 12v10c0 6.627 5.373 12 12 12h160c6.627 0 12-5.373 12-12V20c0-6.627-5.373-12-12-12z\"/>\n</symbol>\n<symbol id=\"svg-arrow-left\" viewBox=\"0 0 320 512\">\n  <path d=\"M206.7 464.6l-183.1-191.1C18.22 267.1 16 261.1 16 256s2.219-11.97 6.688-16.59l183.1-191.1c9.152-9.594 24.34-9.906 33.9-.7187c9.625 9.125 9.938 24.37 .7187 33.91L73.24 256l168 175.4c9.219 9.5 8.906 24.78-.7187 33.91C231 474.5 215.8 474.2 206.7 464.6z\"/>\n</symbol>\n<symbol id=\"svg-arrow-right\" viewBox=\"0 0 320 512\">\n  <path d=\"M113.3 47.41l183.1 191.1c4.469 4.625 6.688 10.62 6.688 16.59s-2.219 11.97-6.688 16.59l-183.1 191.1c-9.152 9.594-24.34 9.906-33.9 .7187c-9.625-9.125-9.938-24.38-.7187-33.91l168-175.4L78.71 80.6c-9.219-9.5-8.906-24.78 .7187-33.91C88.99 37.5 104.2 37.82 113.3 47.41z\"/>\n</symbol>\n<symbol id=\"svg-tab\" viewBox=\"0 0 448 512\">\n  <path d=\"M32 217.1c0-8.8 7.2-16 16-16h144v-93.9c0-7.1 8.6-10.7 13.6-5.7l143.5 143.1c6.3 6.3 6.3 16.4 0 22.7L205.6 410.4c-5 5-13.6 1.5-13.6-5.7v-93.9H48c-8.8 0-16-7.2-16-16v-77.7m-32 0v77.7c0 26.5 21.5 48 48 48h112v61.9c0 35.5 43 53.5 68.2 28.3l143.6-143c18.8-18.8 18.8-49.2 0-68L228.2 78.9c-25.1-25.1-68.2-7.3-68.2 28.3v61.9H48c-26.5 0-48 21.6-48 48zM436 64h-8c-6.6 0-12 5.4-12 12v360c0 6.6 5.4 12 12 12h8c6.6 0 12-5.4 12-12V76c0-6.6-5.4-12-12-12z\"/>\n</symbol>\n<symbol id=\"svg-paste\" viewBox=\"0 0 512 512\"><path d=\"M160 32c11.6 0 21.3 8.2 23.5 19.2C185 58.6 191.6 64 199.2 64H208c8.8 0 16 7.2 16 16V96H96V80c0-8.8 7.2-16 16-16h8.8c7.6 0 14.2-5.4 15.7-12.8C138.7 40.2 148.4 32 160 32zM64 64h2.7C65 69 64 74.4 64 80V96c0 17.7 14.3 32 32 32H224c17.7 0 32-14.3 32-32V80c0-5.6-1-11-2.7-16H256c17.7 0 32 14.3 32 32h32c0-35.3-28.7-64-64-64H210.6c-9-18.9-28.3-32-50.6-32s-41.6 13.1-50.6 32H64C28.7 32 0 60.7 0 96V384c0 35.3 28.7 64 64 64H192V416H64c-17.7 0-32-14.3-32-32V96c0-17.7 14.3-32 32-32zM288 480c-17.7 0-32-14.3-32-32V192c0-17.7 14.3-32 32-32h96v56c0 22.1 17.9 40 40 40h56V448c0 17.7-14.3 32-32 32H288zM416 165.3L474.7 224H424c-4.4 0-8-3.6-8-8V165.3zM448 512c35.3 0 64-28.7 64-64V235.9c0-12.7-5.1-24.9-14.1-33.9l-59.9-59.9c-9-9-21.2-14.1-33.9-14.1H288c-35.3 0-64 28.7-64 64V448c0 35.3 28.7 64 64 64H448z\"/></symbol>\n<symbol id=\"svg-cut\" viewBox=\"0 0 512 512\"><path d=\"M485.6 444.2L333.6 314.9C326.9 309.2 326.1 299.1 331.8 292.4C337.5 285.6 347.6 284.8 354.4 290.5L506.4 419.8C513.1 425.5 513.9 435.6 508.2 442.4C502.5 449.1 492.4 449.9 485.6 444.2zM485.7 67.76C492.5 62.07 502.5 62.94 508.2 69.69C513.9 76.45 513.1 86.55 506.3 92.24L208.5 343.1C218.3 359.7 224 379.2 224 400C224 461.9 173.9 512 112 512C50.14 512 0 461.9 0 400C0 338.1 50.14 288 112 288C141.5 288 168.4 299.4 188.4 318.1L262.2 256L188.4 193.9C168.4 212.6 141.5 224 112 224C50.14 224 0 173.9 0 112C0 50.14 50.14 0 112 0C173.9 0 224 50.14 224 112C224 132.8 218.3 152.3 208.5 168.9L287 235.1L485.7 67.76zM32 112C32 156.2 67.82 192 112 192C156.2 192 192 156.2 192 112C192 67.82 156.2 32 112 32C67.82 32 32 67.82 32 112zM112 480C156.2 480 192 444.2 192 400C192 355.8 156.2 320 112 320C67.82 320 32 355.8 32 400C32 444.2 67.82 480 112 480z\"/></symbol>\n<symbol id=\"svg-copy\" viewBox=\"0 0 512 512\"><path d=\"M272 416C263.2 416 256 423.2 256 432V448c0 17.67-14.33 32-32 32H64c-17.67 0-32-14.33-32-32V192c0-17.67 14.33-32 32-32h112C184.8 160 192 152.8 192 144C192 135.2 184.8 128 176 128H63.99c-35.35 0-64 28.65-64 64l.0098 256C0 483.3 28.65 512 64 512h160c35.35 0 64-28.65 64-64v-16C288 423.2 280.8 416 272 416zM502.6 86.63l-77.25-77.25C419.4 3.371 411.2 0 402.7 0H288C252.7 0 224 28.65 224 64v256c0 35.35 28.65 64 64 64h160c35.35 0 64-28.65 64-64V109.3C512 100.8 508.6 92.63 502.6 86.63zM416 45.25L466.7 96H416V45.25zM480 320c0 17.67-14.33 32-32 32h-160c-17.67 0-32-14.33-32-32V64c0-17.67 14.33-32 32-32h96l.0026 64c0 17.67 14.33 32 32 32H480V320z\"/>\n</symbol>\n<symbol id=\"svg-angle-double-right\" viewBox=\"0 0 512 512\"><path d=\"M470.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-160-160c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L402.7 256 265.4 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l160-160zm-352 160l160-160c12.5-12.5 12.5-32.8 0-45.3l-160-160c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L210.7 256 73.4 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0z\"/>\n</symbol>\n<symbol id=\"svg-angle-double-left\" viewBox=\"0 0 512 512\"><path d=\"M41.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 256 246.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160zm352-160l-160 160c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L301.3 256 438.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0z\"/>\n</symbol>\n<symbol id=\"svg-trash\" viewBox=\"0 0 448 512\">\n  <path d=\"M336 64l-33.6-44.8C293.3 7.1 279.1 0 264 0h-80c-15.1 0-29.3 7.1-38.4 19.2L112 64H24C10.7 64 0 74.7 0 88v2c0 3.3 2.7 6 6 6h26v368c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V96h26c3.3 0 6-2.7 6-6v-2c0-13.3-10.7-24-24-24h-88zM184 32h80c5 0 9.8 2.4 12.8 6.4L296 64H152l19.2-25.6c3-4 7.8-6.4 12.8-6.4zm200 432c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V96h320v368zm-176-44V156c0-6.6 5.4-12 12-12h8c6.6 0 12 5.4 12 12v264c0 6.6-5.4 12-12 12h-8c-6.6 0-12-5.4-12-12zm-80 0V156c0-6.6 5.4-12 12-12h8c6.6 0 12 5.4 12 12v264c0 6.6-5.4 12-12 12h-8c-6.6 0-12-5.4-12-12zm160 0V156c0-6.6 5.4-12 12-12h8c6.6 0 12 5.4 12 12v264c0 6.6-5.4 12-12 12h-8c-6.6 0-12-5.4-12-12z\"/>\n</symbol>\n<symbol id=\"svg-keyboard-down\" viewBox=\"0 0 576 512\"><path d=\"M64 48c-8.8 0-16 7.2-16 16V240c0 8.8 7.2 16 16 16H512c8.8 0 16-7.2 16-16V64c0-8.8-7.2-16-16-16H64zM0 64C0 28.7 28.7 0 64 0H512c35.3 0 64 28.7 64 64V240c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64zM159 359c9.4-9.4 24.6-9.4 33.9 0l95 95 95-95c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9L305 505c-4.5 4.5-10.6 7-17 7s-12.5-2.5-17-7L159 393c-9.4-9.4-9.4-24.6 0-33.9zm1-167c0-8.8 7.2-16 16-16H400c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V192zM120 88h16c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16H120c-8.8 0-16-7.2-16-16V104c0-8.8 7.2-16 16-16zm64 16c0-8.8 7.2-16 16-16h16c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16H200c-8.8 0-16-7.2-16-16V104zm96-16h16c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16H280c-8.8 0-16-7.2-16-16V104c0-8.8 7.2-16 16-16zm64 16c0-8.8 7.2-16 16-16h16c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16H360c-8.8 0-16-7.2-16-16V104zm96-16h16c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16H440c-8.8 0-16-7.2-16-16V104c0-8.8 7.2-16 16-16z\"/></symbol>\n</svg>`;\nfunction makeKeyboardElement(keyboard) {\n  keyboard.resetKeycapRegistry();\n  injectStylesheets();\n  const result = document.createElement(\"div\");\n  result.className = \"ML__keyboard\";\n  const plate = document.createElement(\"div\");\n  plate.className = \"MLK__plate\";\n  plate.innerHTML = globalThis.MathfieldElement.createHTML(\n    SVG_ICONS + keyboard.normalizedLayouts.map((x, i) => makeLayout(keyboard, x, i)).join(\"\")\n  );\n  const backdrop = document.createElement(\"div\");\n  backdrop.className = \"MLK__backdrop\";\n  backdrop.appendChild(plate);\n  result.appendChild(backdrop);\n  result.addEventListener(\"pointerdown\", handlePointerDown, { passive: false });\n  const toolbars = result.querySelectorAll(\".ML__edit-toolbar\");\n  if (toolbars) {\n    for (const toolbar of toolbars) {\n      toolbar.addEventListener(\"click\", (ev) => {\n        var _a3, _b3;\n        let target = ev.target;\n        let command = \"\";\n        while (target && !command) {\n          command = (_a3 = target == null ? void 0 : target.getAttribute(\"data-command\")) != null ? _a3 : \"\";\n          target = (_b3 = target == null ? void 0 : target.parentElement) != null ? _b3 : null;\n        }\n        if (command) keyboard.executeCommand(JSON.parse(command));\n      });\n    }\n  }\n  makeSyntheticKeycaps(\n    result.querySelectorAll(\n      \".MLK__keycap, .action, .fnbutton, .bigfnbutton\"\n    )\n  );\n  const layerElements = result.querySelectorAll(\".MLK__layer\");\n  console.assert(layerElements.length > 0, \"No virtual keyboards available\");\n  for (const x of layerElements)\n    x.addEventListener(\"pointerdown\", (evt) => evt.preventDefault());\n  keyboard.currentLayer = keyboard.latentLayer;\n  return result;\n}\nfunction makeLayout(keyboard, layout, index) {\n  const markup = [];\n  if (!(\"layers\" in layout)) return \"\";\n  for (const layer of layout.layers) {\n    markup.push(`<div tabindex=\"-1\" class=\"MLK__layer\" id=\"${layer.id}\">`);\n    if (keyboard.normalizedLayouts.length > 1 || layout.displayEditToolbar) {\n      markup.push(`<div class='MLK__toolbar' role='toolbar'>`);\n      markup.push(makeLayoutsToolbar(keyboard, index));\n      if (layout.displayEditToolbar)\n        markup.push(`<div class=\"ML__edit-toolbar right\"></div>`);\n      markup.push(`</div>`);\n    }\n    markup.push(makeLayer(keyboard, layer));\n    markup.push(\"</div>\");\n  }\n  return markup.join(\"\");\n}\nfunction makeLayer(keyboard, layer) {\n  if (typeof layer === \"string\") return layer;\n  let layerMarkup = \"\";\n  if (typeof layer.style === \"string\")\n    layerMarkup += `<style>${layer.style}</style>`;\n  else if (typeof layer.style === \"object\")\n    layerMarkup += `<style>${jsonToCss(layer.style)}</style>`;\n  if (layer.backdrop) layerMarkup += `<div class='${layer.backdrop}'>`;\n  if (layer.container) layerMarkup += `<div class='${layer.container}'>`;\n  if (layer.rows) {\n    layerMarkup += `<div class=MLK__rows>`;\n    for (const row of layer.rows) {\n      layerMarkup += `<div dir=\"ltr\" class=MLK__row>`;\n      for (const keycap of row) {\n        if (keycap) {\n          const keycapId = keyboard.registerKeycap(keycap);\n          const [markup, cls] = renderKeycap(keycap);\n          if (/(^|\\s)separator/.test(cls)) layerMarkup += `<div class=\"${cls}\"`;\n          else\n            layerMarkup += `<div tabindex=\"-1\" id=\"${keycapId}\" class=\"${cls}\"`;\n          if (keycap.tooltip)\n            layerMarkup += ` data-tooltip=\"${keycap.tooltip}\"`;\n          layerMarkup += `>${markup}</div>`;\n        }\n      }\n      layerMarkup += `</div>`;\n    }\n    layerMarkup += `</div>`;\n  } else if (layer.markup) layerMarkup += layer.markup;\n  if (layer.container) layerMarkup += \"</div>\";\n  if (layer.backdrop) layerMarkup += \"</div>\";\n  return layerMarkup;\n}\nfunction renderKeycap(keycap, options = { shifted: false }) {\n  var _a3, _b3, _c2, _d2, _e, _f, _g;\n  let markup = \"\";\n  let cls = (_a3 = keycap.class) != null ? _a3 : \"\";\n  if (options.shifted && isShiftKey(keycap)) cls += \" is-active\";\n  if (options.shifted && \"shift\" in keycap) {\n    if (typeof keycap.shift === \"string\") markup = latexToMarkup2(keycap.shift);\n    else if (typeof keycap.shift === \"object\") {\n      markup = keycap.shift.label ? keycap.shift.label : (\n        // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n        (_b3 = latexToMarkup2(keycap.shift.latex || keycap.shift.insert || \"\") || keycap.shift.key) != null ? _b3 : \"\"\n      );\n    }\n    if (typeof keycap.shift === \"object\")\n      cls = (_d2 = (_c2 = keycap.shift.class) != null ? _c2 : keycap.class) != null ? _d2 : \"\";\n  } else {\n    markup = keycap.label ? keycap.label : (\n      // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n      (_e = latexToMarkup2(keycap.latex || keycap.insert || \"\") || keycap.key) != null ? _e : \"\"\n    );\n    if (keycap.shift) {\n      let shiftLabel;\n      if (typeof keycap.shift === \"string\")\n        shiftLabel = latexToMarkup2(keycap.shift);\n      else if (keycap.shift.label) shiftLabel = keycap.shift.label;\n      else {\n        shiftLabel = // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n        (_f = latexToMarkup2(keycap.shift.latex || keycap.shift.insert || \"\") || keycap.shift.key) != null ? _f : \"\";\n      }\n      markup += `<span class=\"MLK__shift\">${shiftLabel}</span>`;\n    }\n    if (keycap.aside) markup += `<aside>${keycap.aside}</aside>`;\n  }\n  if (keycap.layer && !/layer-switch/.test(cls)) cls += \" layer-switch\";\n  if (!/(^|\\s)(separator|action|shift|fnbutton|bigfnbutton)($|\\s)/.test(cls))\n    cls += \" MLK__keycap\";\n  if (!/\\bw[0-9]+\\b/.test(cls) && keycap.width) {\n    cls += (_g = { 0: \" w0\", 0.5: \" w5\", 1.5: \" w15\", 2: \" w20\", 5: \" w50\" }[keycap.width]) != null ? _g : \"\";\n  }\n  return [markup, cls || \"MLK__keycap\"];\n}\nvar KEYCAP_SHORTCUTS = {\n  \"[left]\": {\n    class: \"action hide-shift\",\n    label: \"<svg class=svg-glyph><use xlink:href=#svg-arrow-left /></svg>\",\n    command: \"performWithFeedback(moveToPreviousChar)\",\n    shift: {\n      label: \"<svg class=svg-glyph><use xlink:href=#svg-angle-double-left /></svg>\",\n      command: \"performWithFeedback(extendSelectionBackward)\"\n    }\n  },\n  \"[right]\": {\n    class: \"action hide-shift\",\n    label: \"<svg class=svg-glyph><use xlink:href=#svg-arrow-right /></svg>\",\n    command: \"performWithFeedback(moveToNextChar)\",\n    shift: {\n      label: \"<svg class=svg-glyph><use xlink:href=#svg-angle-double-right /></svg>\",\n      command: \"performWithFeedback(extendSelectionForward)\"\n    }\n  },\n  \"[up]\": {\n    class: \"action hide-shift\",\n    label: \"\\u2191\",\n    command: \"performWithFeedback(moveUp)\",\n    shift: {\n      label: \"\\u219F\",\n      command: \"performWithFeedback(extendSelectionUpward)\"\n    }\n  },\n  \"[down]\": {\n    class: \"action hide-shift\",\n    label: \"\\u2193\",\n    command: \"performWithFeedback(moveDown)\",\n    shift: {\n      label: \"\\u21A1\",\n      command: \"performWithFeedback(extendSelectionDownward)\"\n    }\n  },\n  \"[return]\": {\n    class: \"action hide-shift\",\n    command: \"performWithFeedback(commit)\",\n    shift: { command: \"performWithFeedback(addRowAfter)\" },\n    width: 1.5,\n    label: \"<svg class=svg-glyph><use xlink:href=#svg-commit /></svg>\"\n  },\n  \"[action]\": {\n    class: \"action hide-shift\",\n    command: \"performWithFeedback(commit)\",\n    shift: {\n      label: \"<svg class=svg-glyph><use xlink:href=#circle-plus /></svg>\",\n      command: \"performWithFeedback(addRowAfter)\"\n    },\n    width: 1.5,\n    label: \"<svg class=svg-glyph><use xlink:href=#svg-commit /></svg>\"\n  },\n  \"[hr]\": {\n    class: \"separator horizontal-rule\"\n  },\n  \"[hide-keyboard]\": {\n    class: \"action\",\n    command: [\"hideVirtualKeyboard\"],\n    width: 1.5,\n    label: \"<svg class=svg-glyph-lg><use xlink:href=#svg-keyboard-down /></svg>\"\n  },\n  \"[.]\": {\n    variants: \".\",\n    command: \"performWithFeedback(insertDecimalSeparator)\",\n    shift: \",\",\n    class: \"big-op hide-shift\",\n    label: \".\"\n  },\n  \"[,]\": {\n    variants: \",\",\n    command: \"performWithFeedback(insertDecimalSeparator)\",\n    shift: \".\",\n    class: \"big-op hide-shift\",\n    label: \",\"\n  },\n  \"[+]\": {\n    variants: [{ latex: \"\\\\sum_{#0}^{#0}\", class: \"small\" }, \"\\\\oplus\"],\n    latex: \"+\",\n    label: \"+\",\n    class: \"big-op hide-shift\",\n    shift: {\n      latex: \"\\\\sum\",\n      insert: \"\\\\sum\",\n      class: \"small\"\n    }\n  },\n  \"[-]\": {\n    variants: [\"\\\\pm\", \"\\\\ominus\"],\n    latex: \"-\",\n    label: \"&#x2212;\",\n    shift: \"\\\\pm\",\n    class: \"big-op hide-shift\"\n  },\n  \"[/]\": {\n    class: \"big-op hide-shift\",\n    shift: { class: \"\", latex: \"\\\\frac{1}{#@}\" },\n    variants: [\"/\", \"\\\\div\", \"\\\\%\", \"\\\\oslash\"],\n    latex: \"\\\\frac{#@}{#?}\",\n    label: \"&divide;\"\n  },\n  \"[*]\": {\n    variants: [\n      { latex: \"\\\\prod_{#0}^{#0}\", class: \"small\" },\n      \"\\\\otimes\",\n      \"\\\\cdot\"\n    ],\n    latex: \"\\\\cdot\",\n    label: \"&times;\",\n    shift: { latex: \"\\\\times\" },\n    class: \"big-op hide-shift\"\n  },\n  \"[=]\": {\n    variants: [\n      \"\\\\neq\",\n      \"\\\\equiv\",\n      \"\\\\varpropto\",\n      \"\\\\thickapprox\",\n      \"\\\\lt\",\n      \"\\\\gt\",\n      \"\\\\le\",\n      \"\\\\ge\"\n    ],\n    latex: \"=\",\n    label: \"=\",\n    shift: { label: \"\\u2260\", latex: \"\\\\ne\" },\n    class: \"big-op hide-shift\"\n  },\n  \"[backspace]\": {\n    class: \"action bottom right hide-shift\",\n    width: 1.5,\n    command: \"performWithFeedback(deleteBackward)\",\n    label: \"<svg class=svg-glyph><use xlink:href=#svg-delete-backward /></svg>\",\n    shift: {\n      class: \"action warning\",\n      label: \"<svg class=svg-glyph><use xlink:href=#svg-trash /></svg>\",\n      command: \"deleteAll\"\n    }\n  },\n  \"[undo]\": {\n    class: \"ghost if-can-undo\",\n    command: \"undo\",\n    label: \"<svg class=svg-glyph><use xlink:href=#svg-undo /></svg>\",\n    tooltip: \"tooltip.undo\"\n  },\n  \"[redo]\": {\n    class: \"ghost  if-can-redo\",\n    command: \"redo\",\n    label: \"<svg class=svg-glyph><use xlink:href=#svg-redo /></svg>\",\n    tooltip: \"tooltip.redo\"\n  },\n  \"[(]\": {\n    variants: [\n      // We insert the fences as \"keys\" so they can be handled by smartFence.\n      // They will be sent via `onKeystroke` instead of inserted directly in\n      // the model\n      { latex: \"\\\\lbrack\", key: \"[\" },\n      \"\\\\langle\",\n      \"\\\\lfloor\",\n      \"\\\\lceil\",\n      { latex: \"\\\\lbrace\", key: \"{\" }\n    ],\n    key: \"(\",\n    label: \"(\",\n    shift: { label: \"[\", key: \"[\" },\n    class: \"hide-shift\"\n  },\n  \"[)]\": {\n    variants: [\n      { latex: \"\\\\rbrack\", key: \"]\" },\n      \"\\\\rangle\",\n      \"\\\\rfloor\",\n      \"\\\\rceil\",\n      { latex: \"\\\\rbrace\", key: \"}\" }\n    ],\n    key: \")\",\n    label: \")\",\n    shift: { label: \"]\", latex: \"\\\\rbrack\" },\n    class: \"hide-shift\"\n  },\n  \"[0]\": {\n    variants: \"0\",\n    latex: \"0\",\n    label: \"0\",\n    shift: \"\\\\infty\",\n    class: \"hide-shift\"\n  },\n  \"[1]\": {\n    variants: \"1\",\n    latex: \"1\",\n    label: \"1\",\n    shift: \"#@^{-1}\",\n    class: \"hide-shift\"\n  },\n  \"[2]\": {\n    variants: \"2\",\n    latex: \"2\",\n    label: \"2\",\n    shift: \"#@^2\",\n    class: \"hide-shift\"\n  },\n  \"[3]\": {\n    variants: \"3\",\n    latex: \"3\",\n    label: \"3\",\n    shift: \"#@^3\",\n    class: \"hide-shift\"\n  },\n  \"[4]\": {\n    variants: \"4\",\n    latex: \"4\",\n    label: \"4\",\n    shift: \"#@^4\",\n    class: \"hide-shift\"\n  },\n  \"[5]\": {\n    variants: \"5\",\n    latex: \"5\",\n    label: \"5\",\n    shift: \"#@^5\",\n    class: \"hide-shift\"\n  },\n  \"[6]\": {\n    variants: \"6\",\n    latex: \"6\",\n    label: \"6\",\n    shift: \"#@^6\",\n    class: \"hide-shift\"\n  },\n  \"[7]\": {\n    variants: \"7\",\n    latex: \"7\",\n    label: \"7\",\n    shift: \"#@^7\",\n    class: \"hide-shift\"\n  },\n  \"[8]\": {\n    variants: \"8\",\n    latex: \"8\",\n    label: \"8\",\n    shift: \"#@^8\",\n    class: \"hide-shift\"\n  },\n  \"[9]\": {\n    variants: \"9\",\n    latex: \"9\",\n    label: \"9\",\n    shift: \"#@^9\",\n    class: \"hide-shift\"\n  },\n  \"[separator-5]\": { class: \"separator\", width: 0.5 },\n  \"[separator]\": { class: \"separator\" },\n  \"[separator-10]\": { class: \"separator\" },\n  \"[separator-15]\": { class: \"separator\", width: 1.5 },\n  \"[separator-20]\": { class: \"separator\", width: 2 },\n  \"[separator-50]\": { class: \"separator\", width: 5 },\n  \"[shift]\": {\n    class: \"shift bottom left\",\n    width: 1.5,\n    label: \"<span class=caps-lock-indicator></span><svg class=svg-glyph><use xlink:href=#svg-shift /></svg>\"\n  },\n  \"[foreground-color]\": {\n    variants: \"foreground-color\",\n    command: [\"applyStyle\", { color: \"red\" }],\n    label: \"<span style='border-radius: 50%;width:22px;height:22px; border: 3px solid #cc2428; box-sizing: border-box'>\"\n  },\n  \"[background-color]\": {\n    variants: \"background-color\",\n    command: [\"applyStyle\", { backgroundColor: \"yellow\" }],\n    label: \"<span style='border-radius: 50%;width:22px;height:22px; background:#fff590; box-sizing: border-box'></span>\"\n  }\n};\nfunction normalizeKeycap(keycap) {\n  var _a3;\n  if (typeof keycap === \"string\") {\n    if (keycap === \"[.]\" && globalThis.MathfieldElement.decimalSeparator === \",\")\n      keycap = \"[,]\";\n    if (!KEYCAP_SHORTCUTS[keycap]) return { latex: keycap };\n    keycap = { label: keycap };\n  }\n  let shortcut = void 0;\n  if (\"label\" in keycap && keycap.label && KEYCAP_SHORTCUTS[keycap.label]) {\n    shortcut = __spreadProps(__spreadValues(__spreadValues({}, KEYCAP_SHORTCUTS[keycap.label]), keycap), {\n      label: KEYCAP_SHORTCUTS[keycap.label].label\n    });\n  }\n  if (\"key\" in keycap && keycap.key && KEYCAP_SHORTCUTS[keycap.key]) {\n    shortcut = __spreadProps(__spreadValues(__spreadValues({}, KEYCAP_SHORTCUTS[keycap.key]), keycap), {\n      key: KEYCAP_SHORTCUTS[keycap.key].key\n    });\n  }\n  if (!shortcut) return keycap;\n  if (shortcut.command === \"insertDecimalSeparator\")\n    shortcut.label = (_a3 = globalThis.MathfieldElement.decimalSeparator) != null ? _a3 : \".\";\n  if (shortcut.tooltip === void 0 || shortcut.tooltip === null || shortcut.tooltip === false) {\n    delete shortcut.tooltip;\n  }\n  if (shortcut.tooltip === void 0 || shortcut.tooltip === null || shortcut.tooltip === false) {\n    delete shortcut.tooltip;\n  }\n  if (shortcut.aside === void 0 || shortcut.aside === null || shortcut.aside === false)\n    delete shortcut.aside;\n  if (shortcut.variants === void 0 || shortcut.variants === null || shortcut.variants === false)\n    delete shortcut.variants;\n  if (shortcut.shift === void 0 || shortcut.shift === null || shortcut.shift === false)\n    delete shortcut.shift;\n  return shortcut;\n}\nvar pressAndHoldTimer;\nfunction handlePointerDown(ev) {\n  var _a3;\n  if (ev.button !== 0) return;\n  const keyboard = VirtualKeyboard.singleton;\n  if (!keyboard) return;\n  let layerButton = ev.target;\n  while (layerButton && !layerButton.getAttribute(\"data-layer\"))\n    layerButton = layerButton.parentElement;\n  if (layerButton) {\n    keyboard.currentLayer = (_a3 = layerButton.getAttribute(\"data-layer\")) != null ? _a3 : \"\";\n    ev.preventDefault();\n    return;\n  }\n  const target = parentKeycap(ev.target);\n  if (!(target == null ? void 0 : target.id)) return;\n  const keycap = keyboard.getKeycap(target.id);\n  if (!keycap) return;\n  console.assert(ev.type === \"pointerdown\");\n  const controller = new AbortController();\n  const signal = controller.signal;\n  target.classList.add(\"is-pressed\");\n  target.addEventListener(\n    \"pointerenter\",\n    handleVirtualKeyboardEvent(controller),\n    { capture: true, signal }\n  );\n  target.addEventListener(\n    \"pointerleave\",\n    handleVirtualKeyboardEvent(controller),\n    { capture: true, signal }\n  );\n  target.addEventListener(\n    \"pointercancel\",\n    handleVirtualKeyboardEvent(controller),\n    { signal }\n  );\n  target.addEventListener(\"pointerup\", handleVirtualKeyboardEvent(controller), {\n    signal\n  });\n  if (isShiftKey(keycap)) {\n    target.classList.add(\"is-active\");\n    keyboard.shiftPressCount++;\n  }\n  if (keycap.variants) {\n    if (pressAndHoldTimer) clearTimeout(pressAndHoldTimer);\n    pressAndHoldTimer = setTimeout(() => {\n      if (target.classList.contains(\"is-pressed\")) {\n        target.classList.remove(\"is-pressed\");\n        target.classList.add(\"is-active\");\n        if (ev.target && \"releasePointerCapture\" in ev.target)\n          ev.target.releasePointerCapture(ev.pointerId);\n        showVariantsPanel(target, () => {\n          controller.abort();\n          target == null ? void 0 : target.classList.remove(\"is-active\");\n        });\n      }\n    }, 300);\n  }\n  ev.preventDefault();\n}\nfunction handleVirtualKeyboardEvent(controller) {\n  return (ev) => {\n    const target = parentKeycap(ev.target);\n    if (!(target == null ? void 0 : target.id)) return;\n    const keyboard = VirtualKeyboard.singleton;\n    if (!keyboard) return;\n    const keycap = keyboard.getKeycap(target.id);\n    if (!keycap) return;\n    if (ev.type === \"pointerenter\" && ev.target === target) {\n      const pev = ev;\n      if (pev.isPrimary) target.classList.add(\"is-pressed\");\n    }\n    if (ev.type === \"pointercancel\") {\n      target.classList.remove(\"is-pressed\");\n      if (isShiftKey(keycap)) {\n        keyboard.shiftPressCount--;\n        target.classList.toggle(\"is-active\", keyboard.isShifted);\n      }\n      controller.abort();\n      return;\n    }\n    if (ev.type === \"pointerleave\" && ev.target === target) {\n      target.classList.remove(\"is-pressed\");\n      if (isShiftKey(keycap)) {\n        keyboard.shiftPressCount--;\n        target.classList.toggle(\"is-active\", keyboard.isShifted);\n      }\n      return;\n    }\n    if (ev.type === \"pointerup\") {\n      if (pressAndHoldTimer) clearTimeout(pressAndHoldTimer);\n      if (isShiftKey(keycap)) {\n        target.classList.toggle(\"is-active\", keyboard.isShifted);\n      } else if (target.classList.contains(\"is-pressed\")) {\n        target.classList.remove(\"is-pressed\");\n        if (keyboard.isShifted && keycap.shift) {\n          if (typeof keycap.shift === \"string\") {\n            keyboard.executeCommand([\n              \"insert\",\n              keycap.shift,\n              {\n                focus: true,\n                feedback: true,\n                scrollIntoView: true,\n                mode: \"math\",\n                format: \"latex\"\n              }\n            ]);\n          } else executeKeycapCommand(keycap.shift);\n        } else executeKeycapCommand(keycap);\n        if (keyboard.shiftPressCount === 1 && !ev.shiftKey)\n          keyboard.shiftPressCount = 0;\n      }\n      controller.abort();\n      ev.preventDefault();\n      return;\n    }\n  };\n}\nfunction executeKeycapCommand(keycap) {\n  var _a3;\n  let command = keycap.command;\n  if (!command && keycap.insert) {\n    command = [\n      \"insert\",\n      keycap.insert,\n      {\n        focus: true,\n        feedback: true,\n        scrollIntoView: true,\n        mode: \"math\",\n        format: \"latex\"\n      }\n    ];\n  }\n  if (!command && keycap.key) {\n    command = [\n      \"typedText\",\n      keycap.key,\n      { focus: true, feedback: true, simulateKeystroke: true }\n    ];\n  }\n  if (!command && keycap.latex) {\n    command = [\n      \"insert\",\n      keycap.latex,\n      {\n        focus: true,\n        feedback: true,\n        scrollIntoView: true,\n        mode: \"math\",\n        format: \"latex\"\n      }\n    ];\n  }\n  if (!command) {\n    command = [\n      \"typedText\",\n      keycap.label,\n      { focus: true, feedback: true, simulateKeystroke: true }\n    ];\n  }\n  (_a3 = VirtualKeyboard.singleton) == null ? void 0 : _a3.executeCommand(command);\n}\nfunction isKeycapElement(el) {\n  if (el.nodeType !== 1) return false;\n  const classes = el.classList;\n  return classes.contains(\"MLK__keycap\") || classes.contains(\"shift\") || classes.contains(\"action\") || classes.contains(\"fnbutton\") || classes.contains(\"bigfnbutton\");\n}\nfunction parentKeycap(el) {\n  if (!el) return void 0;\n  let node = el;\n  while (node && !isKeycapElement(node)) node = node.parentElement;\n  return node != null ? node : void 0;\n}\nfunction isShiftKey(k) {\n  return !!k.class && /(^|\\s)shift($|\\s)/.test(k.class);\n}\n\n// src/virtual-keyboard/virtual-keyboard.ts\nvar VirtualKeyboard = class _VirtualKeyboard {\n  constructor() {\n    this.originalContainerBottomPadding = null;\n    this.keycapRegistry = {};\n    /**\n     * `0`: not pressed\n     * `1`: Shift is locked for next char only\n     * `2`: Shift is locked for all characters\n     */\n    this._shiftPressCount = 0;\n    var _a3;\n    this.targetOrigin = window.origin;\n    this.originValidator = \"none\";\n    this._alphabeticLayout = \"auto\";\n    this._layouts = Object.freeze([\"default\"]);\n    this._editToolbar = \"default\";\n    this._container = void 0;\n    this._visible = false;\n    this._rebuilding = false;\n    this.observer = new ResizeObserver((_entries) => {\n      this.adjustBoundingRect();\n      this.dispatchEvent(new Event(\"geometrychange\"));\n      this.sendMessage(\"geometry-changed\", { boundingRect: this.boundingRect });\n    });\n    this.listeners = {};\n    try {\n      (_a3 = window.top) == null ? void 0 : _a3.addEventListener(\"message\", this);\n    } catch (e) {\n      window.addEventListener(\"message\", this);\n    }\n    document.addEventListener(\"focusin\", (event) => {\n      const target = event.target;\n      if (!(target == null ? void 0 : target.isConnected)) return;\n      setTimeout(() => {\n        const mf = focusedMathfield();\n        if (mf && !mf.readOnly && mf.mathVirtualKeyboardPolicy === \"auto\" && isTouchCapable())\n          this.show({ animate: true });\n      }, 300);\n    });\n    document.addEventListener(\"focusout\", (evt) => {\n      if (!(evt.target instanceof MathfieldElement)) return;\n      if (evt.target.mathVirtualKeyboardPolicy !== \"manual\") {\n        setTimeout(() => {\n          if (!focusedMathfield()) this.hide();\n        }, 300);\n      }\n    });\n  }\n  get currentLayer() {\n    var _a3, _b3, _c2;\n    return (_c2 = (_b3 = (_a3 = this._element) == null ? void 0 : _a3.querySelector(\".MLK__layer.is-visible\")) == null ? void 0 : _b3.id) != null ? _c2 : \"\";\n  }\n  set currentLayer(id) {\n    var _a3;\n    if (!this._element) {\n      this.latentLayer = id;\n      return;\n    }\n    let newActive = id ? this._element.querySelector(`#${id}.MLK__layer`) : null;\n    if (!newActive) newActive = this._element.querySelector(\".MLK__layer\");\n    if (newActive) {\n      (_a3 = this._element.querySelector(\".MLK__layer.is-visible\")) == null ? void 0 : _a3.classList.remove(\"is-visible\");\n      newActive.classList.add(\"is-visible\");\n    }\n    this.render();\n  }\n  get shiftPressCount() {\n    return this._shiftPressCount;\n  }\n  set shiftPressCount(count) {\n    var _a3;\n    this._shiftPressCount = count > 2 || count < 0 ? 0 : count;\n    (_a3 = this._element) == null ? void 0 : _a3.classList.toggle(\"is-caps-lock\", this.shiftPressCount === 2);\n    this.render();\n  }\n  get isShifted() {\n    return this._shiftPressCount > 0;\n  }\n  resetKeycapRegistry() {\n    this.keycapRegistry = {};\n  }\n  registerKeycap(keycap) {\n    const id = \"ML__k\" + Date.now().toString(36).slice(-2) + Math.floor(Math.random() * 1e5).toString(36);\n    this.keycapRegistry[id] = keycap;\n    return id;\n  }\n  setKeycap(keycap, value) {\n    KEYCAP_SHORTCUTS[keycap] = normalizeKeycap(value);\n    this.rebuild();\n  }\n  getKeycap(id) {\n    var _a3;\n    return id ? (_a3 = KEYCAP_SHORTCUTS[id]) != null ? _a3 : this.keycapRegistry[id] : void 0;\n  }\n  getLayer(id) {\n    const layouts = this.normalizedLayouts;\n    for (const layout of layouts)\n      for (const layer of layout.layers) if (layer.id === id) return layer;\n    return void 0;\n  }\n  get alphabeticLayout() {\n    return this._alphabeticLayout;\n  }\n  set alphabeticLayout(value) {\n    this._alphabeticLayout = value;\n    this._normalizedLayouts = void 0;\n    this.rebuild();\n  }\n  get layouts() {\n    return this._layouts;\n  }\n  set layouts(value) {\n    this.updateNormalizedLayouts(value);\n    this.rebuild();\n  }\n  updateNormalizedLayouts(value) {\n    const layouts = Array.isArray(value) ? [...value] : [value];\n    const defaultIndex = layouts.findIndex((x) => x === \"default\");\n    if (defaultIndex >= 0) {\n      layouts.splice(\n        defaultIndex,\n        1,\n        \"numeric\",\n        \"symbols\",\n        \"alphabetic\",\n        \"greek\"\n      );\n    }\n    this._layouts = Object.freeze(layouts);\n    this._normalizedLayouts = layouts.map((x) => normalizeLayout(x));\n  }\n  get normalizedLayouts() {\n    if (!this._normalizedLayouts) this.updateNormalizedLayouts(this._layouts);\n    return this._normalizedLayouts;\n  }\n  get editToolbar() {\n    return this._editToolbar;\n  }\n  set editToolbar(value) {\n    this._editToolbar = value;\n    this.rebuild();\n  }\n  get container() {\n    if (this._container === void 0) return window.document.body;\n    return this._container;\n  }\n  set container(value) {\n    this._container = value;\n    this.rebuild();\n  }\n  static get singleton() {\n    if (this._singleton === void 0) {\n      try {\n        this._singleton = new _VirtualKeyboard();\n      } catch (e) {\n        this._singleton = null;\n      }\n    }\n    return this._singleton;\n  }\n  get style() {\n    return this._style;\n  }\n  addEventListener(type, callback, _options) {\n    if (!this.listeners[type]) this.listeners[type] = /* @__PURE__ */ new Set();\n    if (!this.listeners[type].has(callback)) this.listeners[type].add(callback);\n  }\n  dispatchEvent(event) {\n    if (!this.listeners[event.type] || this.listeners[event.type].size === 0)\n      return true;\n    this.listeners[event.type].forEach((x) => {\n      if (typeof x === \"function\") x(event);\n      else x == null ? void 0 : x.handleEvent(event);\n    });\n    return !event.defaultPrevented;\n  }\n  removeEventListener(type, callback, _options) {\n    if (this.listeners[type]) this.listeners[type].delete(callback);\n  }\n  get element() {\n    return this._element;\n  }\n  set element(val) {\n    var _a3;\n    if (this._element === val) return;\n    (_a3 = this._element) == null ? void 0 : _a3.remove();\n    this._element = val;\n  }\n  get visible() {\n    return this._visible;\n  }\n  set visible(val) {\n    if (val) this.show();\n    else this.hide();\n  }\n  get boundingRect() {\n    var _a3;\n    if (!this._visible) return new DOMRect();\n    const plate = (_a3 = this._element) == null ? void 0 : _a3.getElementsByClassName(\"MLK__plate\")[0];\n    if (plate) return plate.getBoundingClientRect();\n    return new DOMRect();\n  }\n  adjustBoundingRect() {\n    var _a3, _b3;\n    const h = this.boundingRect.height;\n    if (this.container === document.body) {\n      (_a3 = this._element) == null ? void 0 : _a3.style.setProperty(\n        \"--_keyboard-height\",\n        `calc(${h}px + var(--_padding-top) + var(--_padding-bottom) + env(safe-area-inset-bottom, 0))`\n      );\n      const keyboardHeight = h - 1;\n      this.container.style.paddingBottom = this.originalContainerBottomPadding ? `calc(${this.originalContainerBottomPadding} + ${keyboardHeight}px)` : `${keyboardHeight}px`;\n    } else (_b3 = this._element) == null ? void 0 : _b3.style.setProperty(\"--_keyboard-height\", `${h}px`);\n  }\n  rebuild() {\n    if (this._rebuilding || !this._element) return;\n    this._rebuilding = true;\n    const currentLayerId = this.currentLayer;\n    requestAnimationFrame(() => {\n      this._rebuilding = false;\n      if (this._element) {\n        this._element.remove();\n        this._element = void 0;\n      }\n      if (this.visible) {\n        this.buildAndAttachElement();\n        this.currentLayer = currentLayerId;\n        this.render();\n        this.adjustBoundingRect();\n        this._element.classList.add(\"is-visible\");\n      }\n    });\n  }\n  /** Update the keycaps to account for the current state */\n  render() {\n    var _a3;\n    if (!this._element) return;\n    const layer = this.getLayer(this.currentLayer);\n    this._element.classList.toggle(\n      \"backdrop-is-transparent\",\n      Boolean(layer && (layer.backdrop || layer.container))\n    );\n    const keycaps = this._element.querySelectorAll(\n      \".MLK__layer.is-visible .MLK__keycap, .MLK__layer.is-visible .action, .fnbutton, .MLK__layer.is-visible .bigfnbutton, .MLK__layer.is-visible .shift\"\n    );\n    if (!keycaps) return;\n    const shifted = this.isShifted;\n    for (const keycapElement of keycaps) {\n      const keycap = this.getKeycap(keycapElement.id);\n      if (keycap) {\n        const [markup, cls] = renderKeycap(keycap, { shifted });\n        keycapElement.innerHTML = globalThis.MathfieldElement.createHTML(markup);\n        keycapElement.className = cls;\n        if (shifted && typeof keycap.shift === \"object\" && ((_a3 = keycap.shift) == null ? void 0 : _a3.tooltip))\n          keycapElement.dataset.tooltip = keycap.shift.tooltip;\n        else if (!shifted && keycap.tooltip)\n          keycapElement.dataset.tooltip = keycap.tooltip;\n      }\n    }\n  }\n  show(options) {\n    var _a3;\n    if (this._visible) return;\n    const container = this.container;\n    if (!container) return;\n    if (!window.mathVirtualKeyboard) return;\n    if (!this.stateWillChange(true)) return;\n    if (!this._element) {\n      this.buildAndAttachElement();\n      this.adjustBoundingRect();\n    }\n    if (!this._visible) {\n      const plate = this._element.getElementsByClassName(\n        \"MLK__plate\"\n      )[0];\n      if (plate) this.observer.observe(plate);\n      if (container === window.document.body) {\n        const padding2 = container.style.paddingBottom;\n        this.originalContainerBottomPadding = padding2;\n        const keyboardHeight = plate.offsetHeight - 1;\n        container.style.paddingBottom = padding2 ? `calc(${padding2} + ${keyboardHeight}px)` : `${keyboardHeight}px`;\n      }\n      window.addEventListener(\"mouseup\", this);\n      window.addEventListener(\"blur\", this);\n      window.addEventListener(\"keydown\", this, { capture: true });\n      window.addEventListener(\"keyup\", this, { capture: true });\n      (_a3 = this._element) == null ? void 0 : _a3.classList.toggle(\n        \"is-caps-lock\",\n        this.shiftPressCount === 2\n      );\n      this.currentLayer = this.latentLayer;\n    }\n    this._visible = true;\n    if (options == null ? void 0 : options.animate) {\n      requestAnimationFrame(() => {\n        if (this._element) {\n          this._element.classList.add(\"animate\");\n          this._element.addEventListener(\n            \"transitionend\",\n            () => {\n              var _a4;\n              return (_a4 = this._element) == null ? void 0 : _a4.classList.remove(\"animate\");\n            },\n            { once: true }\n          );\n          this._element.classList.add(\"is-visible\");\n          this.stateChanged();\n        }\n      });\n    } else {\n      this._element.classList.add(\"is-visible\");\n      this.stateChanged();\n    }\n  }\n  hide(_options) {\n    var _a3;\n    const container = this.container;\n    if (!container) return;\n    if (!this._visible) return;\n    if (!this.stateWillChange(false)) return;\n    this._visible = false;\n    if (this._element) {\n      this.latentLayer = this.currentLayer;\n      const plate = this._element.getElementsByClassName(\"MLK__plate\")[0];\n      if (plate) this.observer.unobserve(plate);\n      window.removeEventListener(\"mouseup\", this);\n      window.removeEventListener(\"blur\", this);\n      window.removeEventListener(\"keydown\", this, { capture: true });\n      window.removeEventListener(\"keyup\", this, { capture: true });\n      window.removeEventListener(\"contextmenu\", this, { capture: true });\n      hideVariantsPanel();\n      releaseStylesheets();\n      (_a3 = this._element) == null ? void 0 : _a3.remove();\n      this._element = void 0;\n      if (this.originalContainerBottomPadding !== null)\n        container.style.paddingBottom = this.originalContainerBottomPadding;\n    }\n    this.stateChanged();\n  }\n  get height() {\n    var _a3, _b3;\n    return (_b3 = (_a3 = this.element) == null ? void 0 : _a3.offsetHeight) != null ? _b3 : 0;\n  }\n  buildAndAttachElement() {\n    var _a3;\n    console.assert(!this.element);\n    this.element = makeKeyboardElement(this);\n    window.addEventListener(\"contextmenu\", this, { capture: true });\n    this.element.addEventListener(\n      \"contextmenu\",\n      (ev) => {\n        if (!ev.shiftKey) {\n          if (ev.ctrlKey || ev.button === 2)\n            showVariantsPanel(ev.target);\n          ev.preventDefault();\n          ev.stopPropagation();\n        }\n      },\n      { capture: true }\n    );\n    (_a3 = this.container) == null ? void 0 : _a3.appendChild(this.element);\n  }\n  handleEvent(evt) {\n    if (isVirtualKeyboardMessage(evt)) {\n      if (!validateOrigin(evt.origin, this.originValidator)) {\n        throw new DOMException(\n          `Message from unknown origin (${evt.origin}) cannot be handled`,\n          \"SecurityError\"\n        );\n      }\n      if (evt.data.action === \"disconnect\")\n        this.connectedMathfieldWindow = void 0;\n      else if (evt.data.action !== \"update-setting\" && evt.data.action !== \"proxy-created\" && evt.data.action !== \"execute-command\") {\n        console.assert(evt.source !== void 0);\n        this.connectedMathfieldWindow = evt.source;\n      }\n      this.handleMessage(evt.data, evt.source);\n    }\n    if (!this._element) return;\n    switch (evt.type) {\n      case \"mouseup\":\n      case \"blur\":\n        document.body.style.userSelect = \"\";\n        this.shiftPressCount = 0;\n        break;\n      case \"contextmenu\":\n        if (evt.button !== 2) evt.preventDefault();\n        break;\n      case \"keydown\": {\n        if (evt.key === \"Shift\" && !evt.repeat) this.shiftPressCount = 1;\n        break;\n      }\n      case \"keyup\": {\n        if (evt.key === \"Shift\" || !evt.getModifierState(\"Shift\") && this.shiftPressCount !== 2)\n          this.shiftPressCount = 0;\n        break;\n      }\n    }\n  }\n  handleMessage(msg, source) {\n    const { action } = msg;\n    if (action === \"execute-command\") {\n      const { command } = msg;\n      const commandTarget = getCommandTarget(command);\n      if (window.top !== void 0 && commandTarget !== \"virtual-keyboard\")\n        return;\n      this.executeCommand(command);\n      return;\n    }\n    if (action === \"connect\" || action === \"show\") {\n      this.sendMessage(\n        \"synchronize-proxy\",\n        {\n          boundingRect: this.boundingRect,\n          alphabeticLayout: this._alphabeticLayout,\n          layouts: this._layouts,\n          editToolbar: this._editToolbar\n        },\n        source\n      );\n    }\n    if (action === \"disconnect\") return;\n    if (window !== window.top) return;\n    if (action === \"show\") {\n      if (typeof msg.animate !== \"undefined\")\n        this.show({ animate: msg.animate });\n      else this.show();\n      return;\n    }\n    if (action === \"hide\") {\n      if (typeof msg.animate !== \"undefined\")\n        this.hide({ animate: msg.animate });\n      else this.hide();\n      return;\n    }\n    if (action === \"update-setting\") {\n      if (msg.alphabeticLayout) this.alphabeticLayout = msg.alphabeticLayout;\n      if (msg.layouts) this.layouts = msg.layouts;\n      if (msg.editToolbar) this.editToolbar = msg.editToolbar;\n      if (msg.setKeycap) {\n        const { keycap, value } = msg.setKeycap;\n        this.setKeycap(keycap, value);\n        this.render();\n      }\n      return;\n    }\n    if (action === \"proxy-created\") {\n      this.sendMessage(\n        \"synchronize-proxy\",\n        {\n          boundingRect: this.boundingRect,\n          alphabeticLayout: this._alphabeticLayout,\n          layouts: this._layouts,\n          editToolbar: this._editToolbar\n        },\n        source\n      );\n      return;\n    }\n  }\n  sendMessage(action, payload, target) {\n    if (payload.command) {\n      this.dispatchEvent(\n        new CustomEvent(\"math-virtual-keyboard-command\", {\n          detail: payload.command\n        })\n      );\n    }\n    if (!target) target = this.connectedMathfieldWindow;\n    if (this.targetOrigin === null || this.targetOrigin === \"null\" || target === window) {\n      window.dispatchEvent(\n        new MessageEvent(\"message\", {\n          source: window,\n          data: __spreadValues({\n            type: VIRTUAL_KEYBOARD_MESSAGE,\n            action\n          }, payload)\n        })\n      );\n      return;\n    }\n    if (target) {\n      target.postMessage(\n        __spreadValues({\n          type: VIRTUAL_KEYBOARD_MESSAGE,\n          action\n        }, payload),\n        { targetOrigin: this.targetOrigin }\n      );\n    } else {\n      if (action === \"execute-command\" && Array.isArray(payload.command) && payload.command[0] === \"insert\") {\n        const s = payload.command[1].split(\"\");\n        for (const c of s) {\n          this.dispatchEvent(\n            new KeyboardEvent(\"keydown\", { key: c, bubbles: true })\n          );\n          this.dispatchEvent(\n            new KeyboardEvent(\"keyup\", { key: c, bubbles: true })\n          );\n        }\n      }\n    }\n  }\n  stateWillChange(visible) {\n    const success = this.dispatchEvent(\n      new CustomEvent(\"before-virtual-keyboard-toggle\", {\n        detail: { visible },\n        bubbles: true,\n        cancelable: true,\n        composed: true\n      })\n    );\n    return success;\n  }\n  stateChanged() {\n    this.dispatchEvent(new Event(\"virtual-keyboard-toggle\"));\n    if (!this._visible) {\n      this.dispatchEvent(new Event(\"geometrychange\"));\n      this.sendMessage(\"geometry-changed\", {\n        boundingRect: this.boundingRect\n      });\n    }\n  }\n  /**\n   * @category Focus\n   */\n  focus() {\n    this.sendMessage(\"focus\", {});\n  }\n  /**\n   * @category Focus\n   */\n  blur() {\n    this.sendMessage(\"blur\", {});\n  }\n  updateToolbar(mf) {\n    const el = this._element;\n    if (!el) return;\n    el.classList.toggle(\"is-math-mode\", mf.mode === \"math\");\n    el.classList.toggle(\"is-text-mode\", mf.mode === \"text\");\n    el.classList.toggle(\"can-undo\", mf.canUndo);\n    el.classList.toggle(\"can-redo\", mf.canRedo);\n    el.classList.toggle(\"can-copy\", !mf.selectionIsCollapsed);\n    el.classList.toggle(\"can-copy\", !mf.selectionIsCollapsed);\n    el.classList.toggle(\"can-paste\", true);\n    const toolbars = el.querySelectorAll(\".ML__edit-toolbar\");\n    if (!toolbars) return;\n    for (const toolbar of toolbars)\n      toolbar.innerHTML = makeEditToolbar(this, mf);\n  }\n  update(mf) {\n    this._style = mf.style;\n    this.updateToolbar(mf);\n  }\n  connect() {\n    this.connectedMathfieldWindow = window;\n  }\n  disconnect() {\n    this.connectedMathfieldWindow = void 0;\n  }\n  executeCommand(command) {\n    command = parseCommand(command);\n    if (!command) return false;\n    let selector;\n    let args = [];\n    let target = getCommandTarget(command);\n    if (isArray(command)) {\n      selector = command[0];\n      if (selector === \"performWithFeedback\") {\n        target = getCommandTarget(\n          command.slice(1)\n        );\n      }\n      args = command.slice(1);\n    } else selector = command;\n    if (target === \"virtual-keyboard\")\n      return COMMANDS[selector].fn(void 0, ...args);\n    this.sendMessage(\"execute-command\", { command });\n    return false;\n  }\n  dispose() {\n    window.removeEventListener(\"mouseup\", this);\n    window.removeEventListener(\"blur\", this);\n    window.removeEventListener(\"message\", this);\n  }\n};\nfunction focusedMathfield() {\n  let target = deepActiveElement();\n  let mf = null;\n  while (target) {\n    if (\"host\" in target && target.host instanceof MathfieldElement) {\n      mf = target.host;\n      break;\n    }\n    target = target.parentNode;\n  }\n  return mf;\n}\n\n// src/virtual-keyboard/global.ts\nif (isBrowser() && !(\"mathVirtualKeyboard\" in window)) {\n  if (window === window[\"top\"]) {\n    const kbd = VirtualKeyboard.singleton;\n    Object.defineProperty(window, \"mathVirtualKeyboard\", {\n      get: () => kbd\n    });\n  } else {\n    Object.defineProperty(window, \"mathVirtualKeyboard\", {\n      get: () => VirtualKeyboardProxy.singleton,\n      configurable: true\n    });\n  }\n}\n\n// src/editor-mathfield/styling.ts\nfunction applyStyle2(mathfield, inStyle) {\n  mathfield.flushInlineShortcutBuffer();\n  mathfield.stopCoalescingUndo();\n  const style = validateStyle(mathfield, inStyle);\n  const { model } = mathfield;\n  if (model.selectionIsCollapsed) {\n    if (mathfield.defaultStyle.fontSeries && style.fontSeries === mathfield.defaultStyle.fontSeries)\n      style.fontSeries = \"auto\";\n    if (style.fontShape && style.fontShape === mathfield.defaultStyle.fontShape)\n      style.fontShape = \"auto\";\n    if (style.color && style.color === mathfield.defaultStyle.color)\n      style.color = \"none\";\n    if (style.backgroundColor && style.backgroundColor === mathfield.defaultStyle.backgroundColor)\n      style.backgroundColor = \"none\";\n    if (style.fontSize && style.fontSize === mathfield.defaultStyle.fontSize)\n      style.fontSize = \"auto\";\n    mathfield.defaultStyle = __spreadValues(__spreadValues({}, mathfield.defaultStyle), style);\n  } else {\n    mathfield.model.deferNotifications(\n      { content: true, type: \"insertText\" },\n      () => {\n        model.selection.ranges.forEach(\n          (range2) => applyStyle(model, range2, style, { operation: \"toggle\" })\n        );\n        mathfield.snapshot(\"style-change\");\n      }\n    );\n  }\n  return true;\n}\nregister2(\n  { applyStyle: applyStyle2 },\n  {\n    target: \"mathfield\",\n    canUndo: true,\n    changeContent: true\n  }\n);\nfunction validateStyle(mathfield, style) {\n  var _a3, _b3, _c2, _d2, _e, _f, _g, _h, _i, _j;\n  const result = {};\n  if (typeof style.color === \"string\") {\n    const newColor = (_b3 = mathfield.colorMap((_a3 = style.color) != null ? _a3 : style.verbatimColor)) != null ? _b3 : \"none\";\n    if (newColor !== style.color)\n      result.verbatimColor = (_c2 = style.verbatimColor) != null ? _c2 : style.color;\n    result.color = newColor;\n  }\n  if (typeof style.backgroundColor === \"string\") {\n    const newColor = (_e = mathfield.backgroundColorMap(\n      (_d2 = style.backgroundColor) != null ? _d2 : style.verbatimBackgroundColor\n    )) != null ? _e : \"none\";\n    if (newColor !== style.backgroundColor) {\n      result.verbatimBackgroundColor = (_f = style.verbatimBackgroundColor) != null ? _f : style.backgroundColor;\n    }\n    result.backgroundColor = newColor;\n  }\n  if (typeof style.fontFamily === \"string\")\n    result.fontFamily = style.fontFamily;\n  if (typeof style.series === \"string\")\n    result.fontSeries = style.series;\n  if (typeof style.fontSeries === \"string\")\n    result.fontSeries = style.fontSeries.toLowerCase();\n  if (result.fontSeries) {\n    result.fontSeries = (_g = {\n      bold: \"b\",\n      medium: \"m\",\n      normal: \"m\"\n    }[result.fontSeries]) != null ? _g : result.fontSeries;\n  }\n  if (typeof style.shape === \"string\")\n    result.fontShape = style.shape;\n  if (typeof style.fontShape === \"string\")\n    result.fontShape = style.fontShape.toLowerCase();\n  if (result.fontShape) {\n    result.fontShape = (_h = {\n      italic: \"it\",\n      up: \"n\",\n      upright: \"n\",\n      normal: \"n\"\n    }[result.fontShape]) != null ? _h : result.fontShape;\n  }\n  if (style.variant) result.variant = style.variant.toLowerCase();\n  if (style.variantStyle)\n    result.variantStyle = style.variantStyle.toLowerCase();\n  const size = (_i = style.size) != null ? _i : style.fontSize;\n  if (typeof size === \"number\")\n    result.fontSize = Math.max(1, Math.min(10, size));\n  else if (typeof size === \"string\") {\n    result.fontSize = (_j = {\n      size1: 1,\n      size2: 2,\n      size3: 3,\n      size4: 4,\n      size5: 5,\n      size6: 6,\n      size7: 7,\n      size8: 8,\n      size9: 9,\n      size10: 10\n    }[size.toLowerCase()]) != null ? _j : {\n      tiny: 1,\n      scriptsize: 2,\n      footnotesize: 3,\n      small: 4,\n      normal: 5,\n      normalsize: 5,\n      large: 6,\n      Large: 7,\n      LARGE: 8,\n      huge: 9,\n      Huge: 10\n    }[size];\n  }\n  return result;\n}\nfunction defaultInsertStyleHook(mathfield, offset, info) {\n  var _a3, _b3;\n  const model = mathfield.model;\n  if (model.mode === \"latex\") return {};\n  const bias = mathfield.styleBias;\n  if (bias === \"none\") return mathfield.defaultStyle;\n  if (model.mode === \"text\")\n    return (_b3 = (_a3 = model.at(bias === \"right\" ? info.after : info.before)) == null ? void 0 : _a3.style) != null ? _b3 : mathfield.defaultStyle;\n  if (model.mode === \"math\") {\n    const atom = model.at(bias === \"right\" ? info.after : info.before);\n    if (!atom) return mathfield.defaultStyle;\n    return __spreadProps(__spreadValues({}, atom.style), { variant: \"normal\" });\n  }\n  return {};\n}\nfunction computeInsertStyle(mathfield) {\n  let hook = mathfield.options.onInsertStyle;\n  if (hook === null) return {};\n  if (hook === void 0) hook = defaultInsertStyleHook;\n  const model = mathfield.model;\n  const bias = mathfield.styleBias;\n  const atom = model.at(model.position);\n  const before = ungroup(model, atom, bias);\n  const after = ungroup(model, atom.rightSibling, bias);\n  return hook(mathfield, model.position, { before, after });\n}\nfunction ungroup(model, atom, bias) {\n  var _a3;\n  if (!atom) return -1;\n  if (atom.type === \"first\" && bias !== \"right\") return -1;\n  if (atom.type !== \"group\") return model.offsetOf(atom);\n  if (!atom.body || atom.body.length < 2) return -1;\n  if (((_a3 = atom.body) == null ? void 0 : _a3.length) === 1) return model.offsetOf(atom.body[0]);\n  if (bias !== \"right\") return model.offsetOf(atom.body[0]);\n  return model.offsetOf(atom.body[atom.body.length - 1]);\n}\n\n// src/editor-mathfield/options.ts\nfunction update(updates) {\n  const result = {};\n  for (const key of Object.keys(updates)) {\n    switch (key) {\n      case \"scriptDepth\":\n        const scriptDepth = updates.scriptDepth;\n        if (isArray(scriptDepth))\n          result.scriptDepth = [scriptDepth[0], scriptDepth[1]];\n        else if (typeof scriptDepth === \"number\")\n          result.scriptDepth = [scriptDepth, scriptDepth];\n        else if (typeof scriptDepth === \"string\") {\n          const [from, to] = scriptDepth.split(\",\").map((x) => parseInt(x.trim()));\n          result.scriptDepth = [from, to];\n        } else throw new TypeError(\"Unexpected value for scriptDepth\");\n        break;\n      case \"mathVirtualKeyboardPolicy\":\n        let keyboardPolicy = updates.mathVirtualKeyboardPolicy.toLowerCase();\n        if (keyboardPolicy === \"sandboxed\") {\n          if (window !== window[\"top\"]) {\n            const kbd = VirtualKeyboard.singleton;\n            Object.defineProperty(window, \"mathVirtualKeyboard\", {\n              get: () => kbd\n            });\n          }\n          keyboardPolicy = \"manual\";\n        }\n        result.mathVirtualKeyboardPolicy = keyboardPolicy;\n        break;\n      case \"letterShapeStyle\":\n        if (updates.letterShapeStyle === \"auto\") {\n          if (l10n.locale.startsWith(\"fr\")) result.letterShapeStyle = \"french\";\n          else result.letterShapeStyle = \"tex\";\n        } else result.letterShapeStyle = updates.letterShapeStyle;\n        break;\n      case \"defaultMode\":\n        if (![\"text\", \"math\", \"inline-math\"].includes(\n          updates.defaultMode\n        )) {\n          console.error(\n            `MathLive 0.101.0:  valid values for defaultMode are \"text\", \"math\" or \"inline-math\"`\n          );\n          result.defaultMode = \"math\";\n        } else result.defaultMode = updates.defaultMode;\n        break;\n      case \"macros\":\n        result.macros = normalizeMacroDictionary(updates.macros);\n        break;\n      default:\n        if (isArray(updates[key])) result[key] = [...updates[key]];\n        else if (typeof updates[key] === \"object\" && !(updates[key] instanceof Element) && key !== \"computeEngine\")\n          result[key] = __spreadValues({}, updates[key]);\n        else result[key] = updates[key];\n    }\n  }\n  return result;\n}\nfunction get(config, keys) {\n  let resolvedKeys;\n  if (typeof keys === \"string\") resolvedKeys = [keys];\n  else if (keys === void 0) resolvedKeys = Object.keys(config);\n  else resolvedKeys = keys;\n  const result = {};\n  for (const x of resolvedKeys) {\n    if (config[x] === null) result[x] = null;\n    else if (isArray(config[x])) result[x] = [...config[x]];\n    else if (typeof config[x] === \"object\" && !(config[x] instanceof Element) && x !== \"computeEngine\") {\n      result[x] = __spreadValues({}, config[x]);\n    } else result[x] = config[x];\n  }\n  if (typeof keys === \"string\") return result[keys];\n  return result;\n}\nfunction getDefault() {\n  return {\n    readOnly: false,\n    defaultMode: \"math\",\n    macros: {},\n    registers: {},\n    colorMap: defaultColorMap,\n    backgroundColorMap: defaultBackgroundColorMap,\n    letterShapeStyle: l10n.locale.startsWith(\"fr\") ? \"french\" : \"tex\",\n    minFontScale: 0,\n    maxMatrixCols: 10,\n    smartMode: false,\n    smartFence: true,\n    smartSuperscript: true,\n    scriptDepth: [Infinity, Infinity],\n    removeExtraneousParentheses: true,\n    isImplicitFunction: (x) => [\n      \"\\\\sin\",\n      \"\\\\cos\",\n      \"\\\\tan\",\n      \"\\\\arcsin\",\n      \"\\\\arccos\",\n      \"\\\\arctan\",\n      \"\\\\arcsec\",\n      \"\\\\arccsc\",\n      \"\\\\arsinh\",\n      \"\\\\arcosh\",\n      \"\\\\artanh\",\n      \"\\\\arcsech\",\n      \"\\\\arccsch\",\n      \"\\\\arg\",\n      \"\\\\ch\",\n      \"\\\\cosec\",\n      \"\\\\cosh\",\n      \"\\\\cot\",\n      \"\\\\cotg\",\n      \"\\\\coth\",\n      \"\\\\csc\",\n      \"\\\\ctg\",\n      \"\\\\cth\",\n      \"\\\\sec\",\n      \"\\\\sinh\",\n      \"\\\\sh\",\n      \"\\\\tanh\",\n      \"\\\\tg\",\n      \"\\\\th\",\n      \"\\\\lg\",\n      \"\\\\lb\",\n      \"\\\\log\",\n      \"\\\\ln\"\n    ].includes(x),\n    mathModeSpace: \"\",\n    placeholderSymbol: \"\\u25A2\",\n    contentPlaceholder: \"\",\n    popoverPolicy: \"auto\",\n    environmentPopoverPolicy: \"off\",\n    keybindings: DEFAULT_KEYBINDINGS,\n    inlineShortcuts: INLINE_SHORTCUTS,\n    inlineShortcutTimeout: 0,\n    mathVirtualKeyboardPolicy: \"auto\",\n    virtualKeyboardTargetOrigin: window == null ? void 0 : window.origin,\n    originValidator: \"none\",\n    onInsertStyle: defaultInsertStyleHook,\n    onInlineShortcut: () => \"\",\n    onScrollIntoView: null,\n    onExport: defaultExportHook,\n    value: \"\"\n  };\n}\nfunction effectiveMode(options) {\n  if (options.defaultMode === \"inline-math\") return \"math\";\n  return options.defaultMode;\n}\n\n// src/editor-model/composition.ts\nfunction updateComposition(model, s) {\n  const cursor = model.at(model.position);\n  if (cursor.type === \"composition\") {\n    cursor.value = s;\n  } else {\n    const { caret } = cursor;\n    cursor.caret = void 0;\n    const atom = new CompositionAtom(s, { mode: cursor.mode });\n    atom.caret = caret;\n    cursor.parent.addChildAfter(atom, cursor);\n    model.position += 1;\n  }\n}\nfunction removeComposition(model) {\n  const cursor = model.at(model.position);\n  if (cursor.type === \"composition\") {\n    cursor.parent.removeChild(cursor);\n    model.position -= 1;\n  }\n}\n\n// src/latex-commands/environments.ts\ndefineEnvironment([\"math\", \"displaymath\"], makeEnvironment);\ndefineEnvironment(\"center\", makeEnvironment);\ndefineFunction(\"displaylines\", \"\", {\n  parse: (parser) => {\n    const lines = [];\n    let line = [];\n    parser.beginContext({ tabular: true });\n    do {\n      if (parser.end()) break;\n      if (parser.match(\"<}>\")) break;\n      if (parser.matchColumnSeparator() || parser.matchRowSeparator()) {\n        lines.push([line]);\n        line = [];\n      } else {\n        line.push(\n          ...parser.scan(\n            (token) => [\"<}>\", \"&\", \"\\\\cr\", \"\\\\\\\\\", \"\\\\tabularnewline\"].includes(token)\n          )\n        );\n      }\n    } while (true);\n    parser.endContext();\n    lines.push([line]);\n    return lines;\n  },\n  createAtom: (options) => new ArrayAtom(\"lines\", options.args, [], {\n    // arraystretch: 1.2,\n    leftDelim: \".\",\n    rightDelim: \".\",\n    columns: [{ align: \"l\" }]\n  })\n});\ndefineTabularEnvironment(\n  \"array\",\n  \"{columns:colspec}\",\n  (name, array, rowGaps, args) => {\n    return new ArrayAtom(name, defaultContent(array), rowGaps, {\n      columns: args[0],\n      mathstyleName: \"textstyle\"\n    });\n  }\n);\ndefineTabularEnvironment(\n  [\"equation\", \"equation*\", \"subequations\"],\n  \"\",\n  (name, array, rowGaps) => {\n    return new ArrayAtom(name, defaultContent(array), rowGaps, {\n      columns: [{ align: \"c\" }]\n    });\n  }\n);\ndefineTabularEnvironment([\"multline\", \"multline*\"], \"\", makeEnvironment);\ndefineTabularEnvironment(\n  [\"align\", \"align*\", \"aligned\", \"eqnarray\"],\n  \"\",\n  makeEnvironment\n);\ndefineTabularEnvironment(\"split\", \"\", makeEnvironment);\ndefineTabularEnvironment(\n  [\"gather\", \"gather*\", \"gathered\"],\n  \"\",\n  makeEnvironment\n);\ndefineTabularEnvironment(\n  [\n    \"matrix\",\n    \"pmatrix\",\n    \"bmatrix\",\n    \"Bmatrix\",\n    \"vmatrix\",\n    \"Vmatrix\",\n    \"matrix*\",\n    \"pmatrix*\",\n    \"bmatrix*\",\n    \"Bmatrix*\",\n    \"vmatrix*\",\n    \"Vmatrix*\"\n  ],\n  \"[columns:colspec]\",\n  makeEnvironment\n);\ndefineTabularEnvironment(\n  [\"smallmatrix\", \"smallmatrix*\"],\n  \"[columns:colspec]\",\n  makeEnvironment\n);\ndefineTabularEnvironment([\"cases\", \"dcases\", \"rcases\"], \"\", makeEnvironment);\nfunction isContentEmpty(array) {\n  for (const row of array)\n    for (const col of row) if (col.length > 0) return false;\n  return true;\n}\nfunction defaultContent(array, count = 1) {\n  if (isContentEmpty(array)) {\n    return Array(count).fill([\n      [new Atom({ type: \"first\" }), new PlaceholderAtom()]\n    ]);\n  }\n  return array.map((row) => {\n    if (row.length === 0) return [[new Atom({ type: \"first\" })]];\n    return row.map((cell) => {\n      if (cell.length === 0) return [new Atom({ type: \"first\" })];\n      if (cell[0].type === \"first\") return cell;\n      return [new Atom({ type: \"first\" }), ...cell];\n    });\n  });\n}\nfunction makeEnvironment(name, content = [[[]]], rowGaps = [], args = [], maxMatrixCols) {\n  content = defaultContent(\n    content,\n    [\"split\", \"align\", \"align*\", \"aligned\", \"eqnarray\"].includes(name) ? 2 : 1\n  );\n  switch (name) {\n    case \"math\":\n      return new ArrayAtom(name, content, rowGaps, {\n        mathstyleName: \"textstyle\"\n      });\n    case \"displaymath\":\n      return new ArrayAtom(name, content, rowGaps, {\n        mathstyleName: \"textstyle\"\n      });\n    case \"center\":\n      return new ArrayAtom(name, content, rowGaps, {\n        columns: [{ align: \"c\" }]\n      });\n    case \"multline\":\n    case \"multline*\":\n      return new ArrayAtom(name, content, rowGaps, {\n        columns: [{ align: \"m\" }],\n        leftDelim: \".\",\n        rightDelim: \".\"\n      });\n    case \"split\":\n      return new ArrayAtom(name, content, rowGaps, {\n        columns: [{ align: \"r\" }, { align: \"l\" }],\n        minColumns: 2\n      });\n    case \"gather\":\n    case \"gathered\":\n      return new ArrayAtom(name, content, rowGaps, {\n        columns: [{ gap: 0.25 }, { align: \"c\" }, { gap: 0 }]\n        // colSeparationType: 'gather',\n      });\n    case \"pmatrix\":\n    case \"pmatrix*\":\n      return new ArrayAtom(name, content, rowGaps, {\n        mathstyleName: \"textstyle\",\n        leftDelim: \"(\",\n        rightDelim: \")\",\n        columns: defaultColumns(args[0], maxMatrixCols)\n      });\n    case \"bmatrix\":\n    case \"bmatrix*\":\n      return new ArrayAtom(name, content, rowGaps, {\n        mathstyleName: \"textstyle\",\n        leftDelim: \"[\",\n        rightDelim: \"]\",\n        columns: defaultColumns(args[0], maxMatrixCols)\n      });\n    case \"Bmatrix\":\n    case \"Bmatrix*\":\n      return new ArrayAtom(name, content, rowGaps, {\n        mathstyleName: \"textstyle\",\n        leftDelim: \"\\\\lbrace\",\n        rightDelim: \"\\\\rbrace\",\n        columns: defaultColumns(args[0], maxMatrixCols)\n      });\n    case \"vmatrix\":\n    case \"vmatrix*\":\n      return new ArrayAtom(name, content, rowGaps, {\n        mathstyleName: \"textstyle\",\n        leftDelim: \"\\\\vert\",\n        rightDelim: \"\\\\vert\",\n        columns: defaultColumns(args[0], maxMatrixCols)\n      });\n    case \"Vmatrix\":\n    case \"Vmatrix*\":\n      return new ArrayAtom(name, content, rowGaps, {\n        mathstyleName: \"textstyle\",\n        leftDelim: \"\\\\Vert\",\n        rightDelim: \"\\\\Vert\",\n        columns: defaultColumns(args[0], maxMatrixCols)\n      });\n    case \"matrix\":\n    case \"matrix*\":\n      return new ArrayAtom(name, content, rowGaps, {\n        mathstyleName: \"textstyle\",\n        leftDelim: \".\",\n        rightDelim: \".\",\n        columns: defaultColumns(args == null ? void 0 : args[0], maxMatrixCols)\n      });\n    case \"smallmatrix\":\n    case \"smallmatrix*\":\n      return new ArrayAtom(name, content, rowGaps, {\n        mathstyleName: \"scriptstyle\",\n        columns: defaultColumns(args == null ? void 0 : args[0], maxMatrixCols),\n        colSeparationType: \"small\",\n        arraystretch: 0.5\n      });\n    case \"cases\":\n    case \"dcases\":\n      return new ArrayAtom(name, content, rowGaps, {\n        mathstyleName: name === \"dcases\" ? \"displaystyle\" : \"textstyle\",\n        arraystretch: 1.2,\n        leftDelim: \"\\\\lbrace\",\n        rightDelim: \".\",\n        columns: [{ align: \"l\" }, { gap: 1 }, { align: \"l\" }]\n      });\n    case \"rcases\":\n      return new ArrayAtom(name, content, rowGaps, {\n        arraystretch: 1.2,\n        leftDelim: \".\",\n        rightDelim: \"\\\\rbrace\",\n        columns: [{ align: \"l\" }, { gap: 1 }, { align: \"l\" }]\n      });\n    case \"lines\":\n      return new ArrayAtom(name, content, rowGaps, {\n        // arraystretch: 1.2,\n        leftDelim: \".\",\n        rightDelim: \".\",\n        columns: [{ align: \"l\" }]\n      });\n    case \"align\":\n    case \"align*\":\n    case \"aligned\":\n    case \"eqnarray\": {\n      let colCount = 0;\n      for (const row of content) colCount = Math.max(colCount, row.length);\n      const columns = [\n        { gap: 0 },\n        { align: \"r\" },\n        { gap: 0.25 },\n        { align: \"l\" }\n      ];\n      let i = 2;\n      while (i < colCount) {\n        columns.push({ gap: 1 }, { align: \"r\" }, { gap: 0.25 }, { align: \"l\" });\n        i += 2;\n      }\n      columns.push({ gap: 0 });\n      return new ArrayAtom(name, content, rowGaps, {\n        arraycolsep: 0,\n        columns,\n        // colSeparationType: 'align',\n        minColumns: 2\n      });\n    }\n  }\n  return new ArrayAtom(name, content, rowGaps, {\n    mathstyleName: \"textstyle\"\n  });\n}\nfunction defaultColumns(args, maxMatrixCols = 10) {\n  return args != null ? args : Array(maxMatrixCols).fill({ align: \"c\" });\n}\n\n// src/editor-model/array.ts\nfunction parentArray(model, where) {\n  let atom = model.at(model.position);\n  while (atom && !(atom.parent instanceof ArrayAtom)) atom = atom.parent;\n  if (atom && atom.type === \"array\") {\n    const array = atom;\n    if (array.environmentName === \"lines\") {\n    }\n  }\n  if (!atom || !(atom.parent instanceof ArrayAtom)) {\n    const cursor = model.at(model.position);\n    atom = cursor;\n    if (!atom.parent.parent) {\n      let secondCell = model.extractAtoms([model.position, model.lastOffset]);\n      let firstCell = model.extractAtoms([0, model.position]);\n      if (firstCell.length === 0) firstCell = placeholderCell();\n      if (secondCell.length === 0) secondCell = placeholderCell();\n      let array;\n      if (where.endsWith(\"column\")) {\n        array = makeEnvironment(\"split\", [[firstCell, secondCell]]);\n        model.root = array;\n        if (isPlaceholderCell(array, 0, 0)) selectCell(model, array, 0, 0);\n        else if (isPlaceholderCell(array, 0, 1)) selectCell(model, array, 0, 1);\n        else model.position = model.offsetOf(cursor);\n      } else {\n        array = makeEnvironment(\"lines\", [[firstCell], [secondCell]]);\n        model.root = array;\n        if (isPlaceholderCell(array, 0, 0)) selectCell(model, array, 0, 0);\n        else if (isPlaceholderCell(array, 1, 0)) selectCell(model, array, 1, 0);\n        else model.position = model.offsetOf(cursor);\n      }\n      return [void 0, [0, 0]];\n    }\n    if (atom.parent instanceof LeftRightAtom) {\n      const parent = atom.parent;\n      let secondCell = model.extractAtoms([\n        model.position,\n        model.offsetOf(parent.lastChild)\n      ]);\n      let firstCell = model.extractAtoms([\n        model.offsetOf(parent.firstChild),\n        model.position\n      ]);\n      if (firstCell.length === 0) firstCell = placeholderCell();\n      if (secondCell.length === 0) secondCell = placeholderCell();\n      let envName = \"pmatrix\";\n      const lDelim = parent.leftDelim;\n      const rDelim = parent.rightDelim;\n      if (lDelim === \"(\" && (rDelim === \")\" || rDelim === \"?\"))\n        envName = \"pmatrix\";\n      else if ((lDelim === \"[\" || lDelim === \"\\\\lbrack\") && (rDelim === \"]\" || rDelim === \"\\\\rbrack\" || rDelim === \"?\"))\n        envName = \"bmatrix\";\n      else if (lDelim === \"\\\\vert\" && rDelim === \"\\\\vert\") envName = \"vmatrix\";\n      else if (lDelim === \"\\\\Vert\" && rDelim === \"\\\\Vert\") envName = \"Vmatrix\";\n      else if ((lDelim === \"{\" || lDelim === \"\\\\lbrace\") && (rDelim === \".\" || rDelim === \"?\"))\n        envName = \"cases\";\n      const array = makeEnvironment(\n        envName,\n        where.endsWith(\"column\") ? [[firstCell, secondCell]] : [[firstCell], [secondCell]]\n      );\n      parent.parent.addChildBefore(array, parent);\n      parent.parent.removeChild(parent);\n      if (isPlaceholderCell(array, 0, 0)) selectCell(model, array, 0, 0);\n      else if (where.endsWith(\"column\")) {\n        if (isPlaceholderCell(array, 0, 1)) selectCell(model, array, 0, 1);\n        else model.position = model.offsetOf(atom);\n      } else {\n        if (isPlaceholderCell(array, 1, 0)) selectCell(model, array, 1, 0);\n        else model.position = model.offsetOf(atom);\n      }\n      return [void 0, [0, 0]];\n    }\n  }\n  return atom && atom.parent instanceof ArrayAtom ? [atom.parent, atom.parentBranch] : [void 0, [0, 0]];\n}\nfunction isPlaceholderCell(array, row, column) {\n  const cell = array.getCell(row, column);\n  if (!cell || cell.length !== 2) return false;\n  return cell[1].type === \"placeholder\";\n}\nfunction cellRange(model, array, row, column) {\n  const cell = array.getCell(row, column);\n  if (!cell) return -1;\n  return [model.offsetOf(cell[0]), model.offsetOf(cell[cell.length - 1])];\n}\nfunction selectCell(model, array, row, column) {\n  const range2 = cellRange(model, array, row, column);\n  if (typeof range2 !== \"number\") model.setSelection(range2);\n}\nfunction setPositionInCell(model, array, row, column, pos) {\n  const cell = array.getCell(row, column);\n  if (!cell) return;\n  model.setPositionHandlingPlaceholder(\n    model.offsetOf(cell[pos === \"start\" ? 0 : cell.length - 1])\n  );\n}\nfunction addCell(model, where) {\n  const [arrayAtom, [row, column]] = parentArray(model, where);\n  if (!arrayAtom) return;\n  switch (where) {\n    case \"after row\":\n      arrayAtom.addRowAfter(row);\n      setPositionInCell(model, arrayAtom, row + 1, 0, \"end\");\n      break;\n    case \"after column\":\n      if (arrayAtom.maxColumns <= arrayAtom.colCount) {\n        model.announce(\"plonk\");\n        return;\n      }\n      arrayAtom.addColumnAfter(column);\n      setPositionInCell(model, arrayAtom, row, column + 1, \"end\");\n      break;\n    case \"before row\":\n      arrayAtom.addRowBefore(row);\n      setPositionInCell(model, arrayAtom, row, 0, \"start\");\n      break;\n    case \"before column\":\n      if (arrayAtom.maxColumns <= arrayAtom.colCount) {\n        model.announce(\"plonk\");\n        return;\n      }\n      arrayAtom.addColumnBefore(column);\n      setPositionInCell(model, arrayAtom, row, column, \"start\");\n      break;\n  }\n}\nfunction addRowAfter(model) {\n  if (!model.contentWillChange({ inputType: \"insertText\" })) return false;\n  addCell(model, \"after row\");\n  model.contentDidChange({ inputType: \"insertText\" });\n  return true;\n}\nfunction addRowBefore(model) {\n  if (!model.contentWillChange({ inputType: \"insertText\" })) return false;\n  addCell(model, \"before row\");\n  model.contentDidChange({ inputType: \"insertText\" });\n  return true;\n}\nfunction addColumnAfter(model) {\n  if (!model.contentWillChange({ inputType: \"insertText\" })) return false;\n  addCell(model, \"after column\");\n  model.contentDidChange({ inputType: \"insertText\" });\n  return true;\n}\nfunction addColumnBefore(model) {\n  if (!model.contentWillChange({ inputType: \"insertText\" })) return false;\n  addCell(model, \"before column\");\n  model.contentDidChange({ inputType: \"insertText\" });\n  return true;\n}\nfunction setEnvironment(model, environment) {\n  if (!model.contentWillChange({})) return false;\n  model.mathfield.snapshot();\n  let leftDelim = \".\";\n  let rightDelim = \".\";\n  switch (environment) {\n    case \"pmatrix\":\n    case \"pmatrix*\":\n      leftDelim = \"(\";\n      rightDelim = \")\";\n      break;\n    case \"bmatrix\":\n    case \"bmatrix*\":\n      leftDelim = \"[\";\n      rightDelim = \"]\";\n      break;\n    case \"Bmatrix\":\n    case \"Bmatrix*\":\n      leftDelim = \"\\\\lbrace\";\n      rightDelim = \"\\\\rbrace\";\n      break;\n    case \"vmatrix\":\n    case \"vmatrix*\":\n      leftDelim = \"\\\\vert\";\n      rightDelim = \"\\\\vert\";\n      break;\n    case \"Vmatrix\":\n    case \"Vmatrix*\":\n      leftDelim = \"\\\\Vert\";\n      rightDelim = \"\\\\Vert\";\n      break;\n    case \"matrix\":\n    case \"matrix*\":\n      leftDelim = \".\";\n      rightDelim = \".\";\n      break;\n    case \"cases\":\n    case \"dcases\":\n      leftDelim = \"\\\\lbrace\";\n      break;\n    case \"rcases\":\n      rightDelim = \"\\\\rbrace\";\n      break;\n  }\n  const atom = model.at(model.position);\n  const arrayAtom = atom.type === \"array\" ? atom : model.parentEnvironment;\n  arrayAtom.environmentName = environment;\n  arrayAtom.leftDelim = leftDelim;\n  arrayAtom.rightDelim = rightDelim;\n  model.contentDidChange({});\n  return true;\n}\nfunction removeCell(model, where) {\n  let atom = model.at(model.position);\n  while (atom && !(Array.isArray(atom.parentBranch) && atom.parent instanceof ArrayAtom))\n    atom = atom.parent;\n  if (Array.isArray(atom == null ? void 0 : atom.parentBranch) && (atom == null ? void 0 : atom.parent) instanceof ArrayAtom) {\n    const arrayAtom = atom.parent;\n    const treeBranch = atom.parentBranch;\n    let pos;\n    switch (where) {\n      case \"row\":\n        if (arrayAtom.rowCount > 1) {\n          arrayAtom.removeRow(treeBranch[0]);\n          const cell = arrayAtom.getCell(\n            Math.max(0, treeBranch[0] - 1),\n            treeBranch[1]\n          );\n          pos = model.offsetOf(cell[cell.length - 1]);\n        }\n        break;\n      case \"column\":\n        if (arrayAtom.colCount > arrayAtom.minColumns) {\n          arrayAtom.removeColumn(treeBranch[1]);\n          const cell = arrayAtom.getCell(\n            treeBranch[0],\n            Math.max(0, treeBranch[1] - 1)\n          );\n          pos = model.offsetOf(cell[cell.length - 1]);\n        }\n        break;\n    }\n    if (pos) model.setPositionHandlingPlaceholder(pos);\n  }\n}\nfunction removeRow(model) {\n  if (!model.contentWillChange({ inputType: \"deleteContent\" })) return false;\n  removeCell(model, \"row\");\n  model.contentDidChange({ inputType: \"deleteContent\" });\n  return true;\n}\nfunction removeColumn(model) {\n  if (!model.contentWillChange({ inputType: \"deleteContent\" })) return false;\n  removeCell(model, \"column\");\n  model.contentDidChange({ inputType: \"deleteContent\" });\n  return true;\n}\nregister2(\n  {\n    addRowAfter,\n    addColumnAfter,\n    addRowBefore,\n    addColumnBefore,\n    removeRow,\n    removeColumn,\n    setEnvironment\n  },\n  {\n    target: \"model\",\n    canUndo: true,\n    changeContent: true,\n    changeSelection: true\n  }\n);\nfunction placeholderCell() {\n  return [new PlaceholderAtom()];\n}\n\n// src/editor/undo.ts\nvar _UndoManager = class _UndoManager {\n  constructor(model) {\n    this.recording = false;\n    this.model = model;\n    this.reset();\n  }\n  reset() {\n    this.stack = [];\n    this.index = -1;\n    this.lastOp = \"\";\n  }\n  startRecording() {\n    this.recording = true;\n  }\n  stopRecording() {\n    this.recording = false;\n  }\n  canUndo() {\n    return this.index - 1 >= 0;\n  }\n  canRedo() {\n    return this.stack.length - 1 > this.index;\n  }\n  /** Call this to stop coalescing future ops, for example when the selection\n   * changes\n   */\n  stopCoalescing(selection) {\n    if (selection && this.index >= 0)\n      this.stack[this.index].selection = selection;\n    this.lastOp = \"\";\n  }\n  undo() {\n    if (!this.canUndo()) return false;\n    this.model.setState(this.stack[this.index - 1], {\n      silenceNotifications: false,\n      type: \"undo\"\n    });\n    this.index -= 1;\n    this.lastOp = \"\";\n    return true;\n  }\n  redo() {\n    if (!this.canRedo()) return false;\n    this.index += 1;\n    this.model.setState(this.stack[this.index], {\n      silenceNotifications: false,\n      type: \"redo\"\n    });\n    this.lastOp = \"\";\n    return true;\n  }\n  pop() {\n    if (!this.canUndo()) return;\n    this.stack.splice(this.index, this.stack.length - this.index);\n    this.index -= 1;\n  }\n  /**\n   * Push a snapshot of the content and selection of the mathfield onto the\n   * undo stack so that it can potentially be reverted to later.\n   *\n   * **Return** `true` if the undo state changed\n   */\n  snapshot(op) {\n    if (!this.recording) return false;\n    if (op && op === this.lastOp) this.pop();\n    this.stack.splice(this.index + 1, this.stack.length - this.index - 1);\n    this.stack.push(this.model.getState());\n    this.index += 1;\n    if (this.stack.length > _UndoManager.maximumDepth) {\n      this.stack.shift();\n      this.index -= 1;\n    }\n    this.lastOp = op != null ? op : \"\";\n    return true;\n  }\n};\n// Maximum number of undo/redo states\n_UndoManager.maximumDepth = 1e3;\nvar UndoManager = _UndoManager;\n\n// src/editor-model/commands.ts\nfunction wordBoundaryOffset(model, offset, direction) {\n  if (model.at(offset).mode !== \"text\") return offset;\n  const dir = direction === \"backward\" ? -1 : 1;\n  let result;\n  if (LETTER_AND_DIGITS.test(model.at(offset).value)) {\n    let i = offset;\n    let match;\n    do {\n      match = model.at(i).mode === \"text\" && LETTER_AND_DIGITS.test(model.at(i).value);\n      i += dir;\n    } while (model.at(i) && match);\n    result = model.at(i) ? i - 2 * dir : i - dir;\n  } else if (/\\s/.test(model.at(offset).value)) {\n    let i = offset;\n    while (model.at(i) && model.at(i).mode === \"text\" && /\\s/.test(model.at(i).value))\n      i += dir;\n    if (!model.at(i)) {\n      result = i - dir;\n    } else {\n      let match = true;\n      do {\n        match = model.at(i).mode === \"text\" && !/\\s/.test(model.at(i).value);\n        i += dir;\n      } while (model.at(i) && match);\n      result = model.at(i) ? i - 2 * dir : i - dir;\n    }\n  } else {\n    let i = offset;\n    while (model.at(i) && model.at(i).mode === \"text\" && !/\\s/.test(model.at(i).value))\n      i += dir;\n    result = model.at(i) ? i : i - dir;\n    let match = true;\n    while (model.at(i) && match) {\n      match = model.at(i).mode === \"text\" && /\\s/.test(model.at(i).value);\n      if (match) result = i;\n      i += dir;\n    }\n    result = model.at(i) ? i - 2 * dir : i - dir;\n  }\n  return result - (dir > 0 ? 0 : 1);\n}\nfunction skip(model, direction, options) {\n  var _a3, _b3, _c2, _d2, _e, _f, _g;\n  const previousPosition = model.position;\n  if (!((_a3 = options == null ? void 0 : options.extend) != null ? _a3 : false)) model.collapseSelection(direction);\n  let atom = model.at(model.position);\n  if (direction === \"forward\") {\n    if (atom.type === \"subsup\") {\n      atom = atom.rightSibling;\n      if (!atom) atom = model.at(model.position + 1);\n    } else atom = model.at(model.position + 1);\n  }\n  if (!atom) {\n    model.announce(\"plonk\");\n    return false;\n  }\n  let offset = model.offsetOf(atom);\n  if (atom instanceof TextAtom) {\n    offset = wordBoundaryOffset(model, offset, direction);\n  } else if (atom instanceof LatexAtom) {\n    if (atom.isSuggestion) {\n      console.assert(direction === \"forward\");\n      while (atom && atom instanceof LatexAtom) {\n        atom.isSuggestion = false;\n        offset = model.offsetOf(atom);\n        atom = atom.rightSibling;\n      }\n    } else if (direction === \"forward\") {\n      atom = atom.rightSibling;\n      if (!atom || !(atom instanceof LatexAtom)) {\n        model.announce(\"plonk\");\n        return false;\n      }\n      while (atom && atom instanceof LatexAtom && /[a-zA-Z\\*]/.test(atom.value)) {\n        offset = model.offsetOf(atom);\n        atom = atom.rightSibling;\n      }\n    } else {\n      atom = atom.leftSibling;\n      if (!atom || !(atom instanceof LatexAtom)) {\n        model.announce(\"plonk\");\n        return false;\n      }\n      while (atom && atom instanceof LatexAtom && /[a-zA-Z\\*]/.test(atom.value)) {\n        offset = model.offsetOf(atom);\n        atom = atom.leftSibling;\n      }\n    }\n  } else if (direction === \"forward\" && atom.type === \"mopen\") {\n    let level = 0;\n    do {\n      if (atom.type === \"mopen\") level += 1;\n      else if (atom.type === \"mclose\") level -= 1;\n      atom = atom.rightSibling;\n    } while (!atom.isLastSibling && level !== 0);\n    offset = model.offsetOf(atom.leftSibling);\n  } else if (direction === \"backward\" && atom.type === \"mclose\") {\n    let level = 0;\n    do {\n      if (atom.type === \"mopen\") level += 1;\n      else if (atom.type === \"mclose\") level -= 1;\n      atom = atom.leftSibling;\n    } while (!atom.isFirstSibling && level !== 0);\n    offset = model.offsetOf(atom);\n  } else if (direction === \"backward\") {\n    if (atom.type === \"first\") {\n      while (offset > 0 && atom.type === \"first\") {\n        offset -= 1;\n        atom = model.at(offset);\n      }\n    } else {\n      const type = atom.type;\n      if (atom.type === \"subsup\") {\n        offset = model.offsetOf(model.at(offset).leftSibling);\n      }\n      offset -= 1;\n      let nextType = (_b3 = model.at(offset)) == null ? void 0 : _b3.type;\n      while (offset >= 0 && nextType === type) {\n        if (((_c2 = model.at(offset)) == null ? void 0 : _c2.type) === \"subsup\")\n          offset = model.offsetOf(model.at(offset).leftSibling);\n        else offset -= 1;\n        nextType = model.at(offset).type;\n      }\n    }\n  } else {\n    const { type } = atom;\n    let nextType = (_d2 = model.at(offset)) == null ? void 0 : _d2.type;\n    const { lastOffset } = model;\n    while (offset <= lastOffset && (nextType === type || nextType === \"subsup\")) {\n      while (((_e = model.at(offset).rightSibling) == null ? void 0 : _e.type) === \"subsup\")\n        offset = model.offsetOf(model.at(offset).rightSibling);\n      offset += 1;\n      nextType = (_f = model.at(offset)) == null ? void 0 : _f.type;\n    }\n    offset -= 1;\n  }\n  if ((_g = options == null ? void 0 : options.extend) != null ? _g : false) {\n    if (!model.setSelection(model.anchor, offset)) {\n      model.announce(\"plonk\");\n      return false;\n    }\n  } else {\n    if (offset === model.position) {\n      model.announce(\"plonk\");\n      return false;\n    }\n    model.position = offset;\n  }\n  model.announce(\"move\", previousPosition);\n  model.mathfield.stopCoalescingUndo();\n  return true;\n}\nfunction move(model, direction, options) {\n  var _a3, _b3;\n  options = options != null ? options : { extend: false };\n  model.mathfield.styleBias = direction === \"backward\" ? \"right\" : \"left\";\n  if (direction !== \"forward\") {\n    const [from, to] = getCommandSuggestionRange(model);\n    if (from !== void 0 && to !== void 0) model.deleteAtoms([from, to]);\n  }\n  if (direction === \"upward\") return moveUpward(model, options);\n  if (direction === \"downward\") return moveDownward(model, options);\n  if (options.extend) {\n    let pos2 = nextValidPosition(model, model.position, direction);\n    if (pos2 < 0) pos2 = 0;\n    if (pos2 > model.lastOffset) pos2 = model.lastOffset;\n    const result = model.setSelection(model.anchor, pos2);\n    model.mathfield.stopCoalescingUndo();\n    return result;\n  }\n  if (model.selectionIsPlaceholder) {\n    model.collapseSelection(direction);\n    const result = move(model, direction);\n    model.mathfield.stopCoalescingUndo();\n    return result;\n  }\n  let pos = model.position;\n  const previousPosition = pos;\n  if (model.collapseSelection(direction)) {\n    pos = model.position;\n    if (!isValidPosition(model, pos))\n      pos = nextValidPosition(model, pos, direction);\n  } else pos = nextValidPosition(model, pos, direction);\n  if (pos < 0 || pos > model.lastOffset) {\n    let success = true;\n    if (!model.silenceNotifications) {\n      success = (_b3 = (_a3 = model.mathfield.host) == null ? void 0 : _a3.dispatchEvent(\n        new CustomEvent(\"move-out\", {\n          detail: { direction },\n          cancelable: true,\n          bubbles: true,\n          composed: true\n        })\n      )) != null ? _b3 : true;\n    }\n    if (success) model.announce(\"plonk\");\n    return success;\n  }\n  model.setPositionHandlingPlaceholder(pos);\n  model.mathfield.stopCoalescingUndo();\n  model.announce(\"move\", previousPosition);\n  return true;\n}\nfunction nextValidPosition(model, pos, direction) {\n  pos = pos + (direction === \"forward\" ? 1 : -1);\n  if (pos < 0 || pos > model.lastOffset) return pos;\n  if (!isValidPosition(model, pos))\n    return nextValidPosition(model, pos, direction);\n  return pos;\n}\nfunction isValidPosition(model, pos) {\n  var _a3;\n  const atom = model.at(pos);\n  let parent = atom.parent;\n  while (parent && !parent.inCaptureSelection) parent = parent.parent;\n  if (parent == null ? void 0 : parent.inCaptureSelection) return false;\n  if ((_a3 = atom.parent) == null ? void 0 : _a3.skipBoundary) {\n    if (!atom.isFirstSibling && atom.isLastSibling) return false;\n    if (atom.type === \"first\") return false;\n  }\n  if (model.mathfield.hasEditablePrompts && !atom.parentPrompt) return false;\n  return true;\n}\nfunction getClosestAtomToXPosition(mathfield, search, x) {\n  let prevX = Infinity;\n  let i = 0;\n  for (; i < search.length; i++) {\n    const atom = search[i];\n    const el = mathfield.getHTMLElement(atom);\n    if (!el) continue;\n    const toX = getLocalDOMRect(el).right;\n    const abs = Math.abs(x - toX);\n    if (abs <= prevX) {\n      prevX = abs;\n    } else {\n      break;\n    }\n  }\n  return search[i - 1];\n}\nfunction moveToClosestAtomVertically(model, fromAtom, toAtoms, extend, direction) {\n  const hasEditablePrompts = model.mathfield.hasEditablePrompts;\n  const editableAtoms = !hasEditablePrompts ? toAtoms : toAtoms.filter((a) => a.type === \"prompt\" && !a.captureSelection);\n  const fromX = getLocalDOMRect(model.mathfield.getHTMLElement(fromAtom)).right;\n  const targetSelection = model.offsetOf(\n    getClosestAtomToXPosition(model.mathfield, editableAtoms, fromX)\n  ) - (hasEditablePrompts ? 1 : 0);\n  if (extend) {\n    const [left, right] = model.selection.ranges[0];\n    let newSelection;\n    const cmp = direction === \"up\" ? left : right;\n    if (targetSelection < cmp) {\n      newSelection = {\n        ranges: [[targetSelection, right]],\n        direction: \"backward\"\n      };\n    } else {\n      newSelection = {\n        ranges: [[left, targetSelection]],\n        direction: \"forward\"\n      };\n    }\n    model.setSelection(newSelection);\n  } else {\n    model.setPositionHandlingPlaceholder(targetSelection);\n  }\n  model.announce(`move ${direction}`);\n}\nfunction moveUpward(model, options) {\n  var _a3, _b3;\n  const extend = (_a3 = options == null ? void 0 : options.extend) != null ? _a3 : false;\n  if (!extend) model.collapseSelection(\"backward\");\n  const handleDeadEnd = () => {\n    var _a4, _b4;\n    let success = true;\n    if (!model.silenceNotifications) {\n      success = (_b4 = (_a4 = model.mathfield.host) == null ? void 0 : _a4.dispatchEvent(\n        new CustomEvent(\"move-out\", {\n          detail: { direction: \"upward\" },\n          cancelable: true,\n          bubbles: true,\n          composed: true\n        })\n      )) != null ? _b4 : true;\n    }\n    model.announce(success ? \"line\" : \"plonk\");\n    return success;\n  };\n  const baseAtom = model.at(model.position);\n  let atom = baseAtom;\n  while (atom && atom.parentBranch !== \"below\" && !(Array.isArray(atom.parentBranch) && atom.parent instanceof ArrayAtom))\n    atom = atom.parent;\n  if (Array.isArray(atom == null ? void 0 : atom.parentBranch) && atom.parent instanceof ArrayAtom) {\n    const arrayAtom = atom.parent;\n    if (atom.parentBranch[0] < 1) return handleDeadEnd();\n    const rowAbove = atom.parentBranch[0] - 1;\n    const aboveCell = arrayAtom.array[rowAbove][atom.parentBranch[1]];\n    const cellHasPrompt = aboveCell.some(\n      (a) => a.type === \"prompt\" && !a.captureSelection\n    );\n    if (!cellHasPrompt && model.mathfield.hasEditablePrompts)\n      return handleDeadEnd();\n    moveToClosestAtomVertically(model, baseAtom, aboveCell, extend, \"up\");\n  } else if (atom) {\n    const branch = (_b3 = atom.parent.branch(\"above\")) != null ? _b3 : atom.parent.createBranch(\"above\");\n    const branchHasPrompt = branch.some(\n      (a) => a.type === \"prompt\" && a.placeholderId\n    );\n    if (!branchHasPrompt && model.mathfield.hasEditablePrompts)\n      return handleDeadEnd();\n    moveToClosestAtomVertically(model, baseAtom, branch, extend, \"up\");\n  } else return handleDeadEnd();\n  model.mathfield.stopCoalescingUndo();\n  return true;\n}\nfunction moveDownward(model, options) {\n  var _a3, _b3;\n  const extend = (_a3 = options == null ? void 0 : options.extend) != null ? _a3 : false;\n  if (!extend) model.collapseSelection(\"forward\");\n  const handleDeadEnd = () => {\n    var _a4, _b4;\n    let success = true;\n    if (!model.silenceNotifications) {\n      success = (_b4 = (_a4 = model.mathfield.host) == null ? void 0 : _a4.dispatchEvent(\n        new CustomEvent(\"move-out\", {\n          detail: { direction: \"downward\" },\n          cancelable: true,\n          bubbles: true,\n          composed: true\n        })\n      )) != null ? _b4 : true;\n    }\n    model.announce(success ? \"line\" : \"plonk\");\n    return success;\n  };\n  const baseAtom = model.at(model.position);\n  let atom = baseAtom;\n  while (atom && atom.parentBranch !== \"above\" && !(Array.isArray(atom.parentBranch) && atom.parent instanceof ArrayAtom))\n    atom = atom.parent;\n  if (Array.isArray(atom == null ? void 0 : atom.parentBranch) && atom.parent instanceof ArrayAtom) {\n    const arrayAtom = atom.parent;\n    if (atom.parentBranch[0] + 1 > arrayAtom.array.length - 1)\n      return handleDeadEnd();\n    const rowBelow = atom.parentBranch[0] + 1;\n    const belowCell = arrayAtom.array[rowBelow][atom.parentBranch[1]];\n    const cellHasPrompt = belowCell.some(\n      (a) => a.type === \"prompt\" && !a.captureSelection\n    );\n    if (!cellHasPrompt && model.mathfield.hasEditablePrompts)\n      return handleDeadEnd();\n    moveToClosestAtomVertically(model, baseAtom, belowCell, extend, \"down\");\n  } else if (atom) {\n    const branch = (_b3 = atom.parent.branch(\"below\")) != null ? _b3 : atom.parent.createBranch(\"below\");\n    const branchHasPrompt = branch.some((a) => a.type === \"prompt\");\n    if (!branchHasPrompt && model.mathfield.hasEditablePrompts)\n      return handleDeadEnd();\n    moveToClosestAtomVertically(model, baseAtom, branch, extend, \"down\");\n  } else return handleDeadEnd();\n  return true;\n}\n\n// src/editor-model/commands-move.ts\nfunction moveAfterParent(model) {\n  const previousPosition = model.position;\n  const parent = model.at(previousPosition).parent;\n  if (!(parent == null ? void 0 : parent.parent)) {\n    model.announce(\"plonk\");\n    return false;\n  }\n  model.position = model.offsetOf(parent);\n  model.mathfield.stopCoalescingUndo();\n  model.announce(\"move\", previousPosition);\n  return true;\n}\nfunction superscriptDepth(model) {\n  let result = 0;\n  let atom = model.at(model.position);\n  let wasSuperscript = false;\n  while (atom) {\n    if (!atom.hasEmptyBranch(\"superscript\") || !atom.hasEmptyBranch(\"subscript\"))\n      result += 1;\n    if (!atom.hasEmptyBranch(\"superscript\")) wasSuperscript = true;\n    else if (!atom.hasEmptyBranch(\"subscript\")) wasSuperscript = false;\n    atom = atom.parent;\n  }\n  return wasSuperscript ? result : 0;\n}\nfunction subscriptDepth(model) {\n  let result = 0;\n  let atom = model.at(model.position);\n  let wasSubscript = false;\n  while (atom) {\n    if (!atom.hasEmptyBranch(\"superscript\") || !atom.hasEmptyBranch(\"subscript\"))\n      result += 1;\n    if (!atom.hasEmptyBranch(\"superscript\")) wasSubscript = false;\n    else if (!atom.hasEmptyBranch(\"subscript\")) wasSubscript = true;\n    atom = atom.parent;\n  }\n  return wasSubscript ? result : 0;\n}\nfunction moveToSuperscript(model) {\n  var _a3;\n  model.collapseSelection();\n  if (superscriptDepth(model) >= model.mathfield.options.scriptDepth[1]) {\n    model.announce(\"plonk\");\n    return false;\n  }\n  let target = model.at(model.position);\n  if (target.subsupPlacement === void 0) {\n    if (((_a3 = target.rightSibling) == null ? void 0 : _a3.type) !== \"subsup\") {\n      target.parent.addChildAfter(\n        new SubsupAtom({ style: target.style }),\n        target\n      );\n    }\n    target = target.rightSibling;\n  }\n  target.createBranch(\"superscript\");\n  model.setSelection(\n    model.getSiblingsRange(model.offsetOf(target.superscript[0]))\n  );\n  return true;\n}\nfunction moveToSubscript(model) {\n  var _a3;\n  model.collapseSelection();\n  if (subscriptDepth(model) >= model.mathfield.options.scriptDepth[0]) {\n    model.announce(\"plonk\");\n    return false;\n  }\n  let target = model.at(model.position);\n  if (target.subsupPlacement === void 0) {\n    if (((_a3 = model.at(model.position + 1)) == null ? void 0 : _a3.type) !== \"subsup\") {\n      target.parent.addChildAfter(\n        new SubsupAtom({ style: model.at(model.position).style }),\n        target\n      );\n    }\n    target = model.at(model.position + 1);\n  }\n  target.createBranch(\"subscript\");\n  model.setSelection(\n    model.getSiblingsRange(model.offsetOf(target.subscript[0]))\n  );\n  return true;\n}\nfunction getTabbableElements() {\n  function tabbable(element) {\n    const regularTabbables = [];\n    const orderedTabbables = [];\n    const candidates = [\n      ...element.querySelectorAll(`input, select, textarea, a[href], button,\n        [tabindex], audio[controls], video[controls],\n        [contenteditable]:not([contenteditable=\"false\"]), details>summary`)\n    ].filter(isNodeMatchingSelectorTabbable);\n    candidates.forEach((candidate, i) => {\n      const candidateTabindex = getTabindex(candidate);\n      if (candidateTabindex === 0) regularTabbables.push(candidate);\n      else {\n        orderedTabbables.push({\n          documentOrder: i,\n          tabIndex: candidateTabindex,\n          node: candidate\n        });\n      }\n    });\n    return orderedTabbables.sort(\n      (a, b) => a.tabIndex === b.tabIndex ? a.documentOrder - b.documentOrder : a.tabIndex - b.tabIndex\n    ).map((a) => a.node).concat(regularTabbables);\n  }\n  function isNodeMatchingSelectorTabbable(element) {\n    if (!isNodeMatchingSelectorFocusable(element) || isNonTabbableRadio(element) || getTabindex(element) < 0)\n      return false;\n    return true;\n  }\n  function isNodeMatchingSelectorFocusable(node) {\n    if (node.disabled || node.type === \"hidden\" && node.tagName.toUpperCase() === \"INPUT\" || isHidden(node))\n      return false;\n    return true;\n  }\n  function getTabindex(node) {\n    var _a3;\n    const tabindexAttr = Number.parseInt(\n      (_a3 = node.getAttribute(\"tabindex\")) != null ? _a3 : \"NaN\",\n      10\n    );\n    if (!Number.isNaN(tabindexAttr)) return tabindexAttr;\n    if (node.contentEditable === \"true\") return 0;\n    if ((node.nodeName === \"AUDIO\" || node.nodeName === \"VIDEO\") && node.getAttribute(\"tabindex\") === null)\n      return 0;\n    return node.tabIndex;\n  }\n  function isNonTabbableRadio(node) {\n    return node.tagName.toUpperCase() === \"INPUT\" && node.type === \"radio\" && !isTabbableRadio(node);\n  }\n  function getCheckedRadio(nodes, form) {\n    for (const node of nodes)\n      if (node.checked && node.form === form) return node;\n    return null;\n  }\n  function isTabbableRadio(node) {\n    var _a3;\n    if (!node.name) return true;\n    const radioScope = (_a3 = node.form) != null ? _a3 : node.ownerDocument;\n    const radioSet = radioScope.querySelectorAll(\n      'input[type=\"radio\"][name=\"' + node.name + '\"]'\n    );\n    const checked = getCheckedRadio(radioSet, node.form);\n    return !checked || checked === node;\n  }\n  function isHidden(element) {\n    if (!isBrowser() || element === document.activeElement || element.contains(document.activeElement))\n      return false;\n    if (getComputedStyle(element).visibility === \"hidden\") return true;\n    const bounds = element.getBoundingClientRect();\n    if (bounds.width === 0 || bounds.height === 0) return true;\n    while (element) {\n      if (getComputedStyle(element).display === \"none\") return true;\n      element = element.parentElement;\n    }\n    return false;\n  }\n  if (!isBrowser()) return [];\n  return tabbable(document.body);\n}\nfunction select(model, target, direction = \"forward\") {\n  const previousPosition = model.position;\n  if (isArray(target)) {\n    const first = model.offsetOf(target[0]);\n    const last = model.offsetOf(target[target.length - 1]);\n    if (direction === \"forward\") model.setSelection(first, last);\n    else model.setSelection(last, first);\n    model.announce(\"move\", previousPosition);\n    model.mathfield.stopCoalescingUndo();\n    return true;\n  }\n  if (direction === \"forward\")\n    return select(model, [target.leftSibling, target]);\n  return select(model, [target, target.leftSibling]);\n}\nfunction leapTo(model, target) {\n  const previousPosition = model.position;\n  if (typeof target === \"number\") target = model.at(target);\n  if (target.type === \"prompt\") {\n    model.setSelection(\n      model.offsetOf(target.firstChild),\n      model.offsetOf(target.lastChild)\n    );\n  } else {\n    const newPosition = model.offsetOf(target);\n    if (target.type === \"placeholder\")\n      model.setSelection(newPosition - 1, newPosition);\n    else model.position = newPosition;\n  }\n  model.announce(\"move\", previousPosition);\n  model.mathfield.stopCoalescingUndo();\n  return true;\n}\nfunction leap(model, dir) {\n  var _a3, _b3;\n  const dist = dir === \"forward\" ? 1 : -1;\n  if (model.at(model.anchor).type === \"placeholder\") move(model, dir);\n  let origin;\n  const parentPrompt = model.at(model.anchor).parentPrompt;\n  if (parentPrompt) {\n    if (dir === \"forward\") origin = model.offsetOf(parentPrompt) + 1;\n    else origin = model.offsetOf(parentPrompt.leftSibling);\n  } else origin = Math.max(model.position + dist, 0);\n  const target = leapTarget(model, origin, dir);\n  if (!target || dir === \"forward\" && model.offsetOf(target) < origin || dir === \"backward\" && model.offsetOf(target) > origin) {\n    const success = (_b3 = (_a3 = model.mathfield.host) == null ? void 0 : _a3.dispatchEvent(\n      new CustomEvent(\"move-out\", {\n        detail: { direction: dir },\n        cancelable: true,\n        bubbles: true,\n        composed: true\n      })\n    )) != null ? _b3 : true;\n    if (!success) {\n      model.announce(\"plonk\");\n      return false;\n    }\n    const tabbable = getTabbableElements();\n    if (!document.activeElement || tabbable.length <= 1) {\n      model.announce(\"plonk\");\n      return false;\n    }\n    let index = tabbable.indexOf(document.activeElement) + dist;\n    if (index < 0) index = tabbable.length - 1;\n    if (index >= tabbable.length) index = 0;\n    tabbable[index].focus();\n    model.mathfield.stopCoalescingUndo();\n    return true;\n  }\n  leapTo(model, target);\n  return true;\n}\nfunction leapTarget(model, origin = 0, dir = \"forward\") {\n  return model.findAtom(\n    (atom) => atom.type === \"placeholder\" || atom.type === \"prompt\" || !model.mathfield.readOnly && atom.treeDepth > 2 && atom.isFirstSibling && atom.isLastSibling,\n    origin,\n    dir\n  );\n}\nregister2(\n  {\n    moveToOpposite: (model) => {\n      const OPPOSITE_RELATIONS = {\n        superscript: \"subscript\",\n        subscript: \"superscript\",\n        above: \"below\",\n        below: \"above\"\n      };\n      const cursor = model.at(model.position);\n      const { parent } = cursor;\n      if (!parent) {\n        model.announce(\"plonk\");\n        return false;\n      }\n      const relation = cursor.parentBranch;\n      let oppositeRelation;\n      if (typeof relation === \"string\")\n        oppositeRelation = OPPOSITE_RELATIONS[relation];\n      if (!oppositeRelation) {\n        const result2 = cursor.subsupPlacement ? moveToSubscript(model) : moveToSuperscript(model);\n        model.mathfield.stopCoalescingUndo();\n        return result2;\n      }\n      if (!parent.branch(oppositeRelation)) {\n        parent.createBranch(oppositeRelation);\n      }\n      const result = model.setSelection(\n        model.getBranchRange(model.offsetOf(parent), oppositeRelation)\n      );\n      model.mathfield.stopCoalescingUndo();\n      return result;\n    },\n    moveBeforeParent: (model) => {\n      const { parent } = model.at(model.position);\n      if (!parent) {\n        model.announce(\"plonk\");\n        return false;\n      }\n      model.position = model.offsetOf(parent);\n      model.mathfield.stopCoalescingUndo();\n      return true;\n    },\n    moveAfterParent: (model) => moveAfterParent(model),\n    moveToNextChar: (model) => move(model, \"forward\"),\n    moveToPreviousChar: (model) => move(model, \"backward\"),\n    moveUp: (model) => move(model, \"upward\"),\n    moveDown: (model) => move(model, \"downward\"),\n    moveToNextWord: (model) => skip(model, \"forward\"),\n    moveToPreviousWord: (model) => skip(model, \"backward\"),\n    moveToGroupStart: (model) => {\n      const pos = model.offsetOf(model.at(model.position).firstSibling);\n      if (pos === model.position) {\n        model.announce(\"plonk\");\n        return false;\n      }\n      model.position = pos;\n      model.mathfield.stopCoalescingUndo();\n      return true;\n    },\n    moveToGroupEnd: (model) => {\n      const pos = model.offsetOf(model.at(model.position).lastSibling);\n      if (pos === model.position) {\n        model.announce(\"plonk\");\n        return false;\n      }\n      model.position = pos;\n      model.mathfield.stopCoalescingUndo();\n      return true;\n    },\n    moveToNextGroup: (model) => {\n      var _a3, _b3, _c2, _d2;\n      if (model.position === model.lastOffset && model.anchor === model.lastOffset)\n        return leap(model, \"forward\");\n      const atom = model.at(model.position);\n      const mode = atom.mode;\n      if (mode === \"text\") {\n        if (model.selectionIsCollapsed) {\n          let first = atom;\n          while (first && first.mode === \"text\") first = first.leftSibling;\n          let last = atom;\n          while (((_a3 = last.rightSibling) == null ? void 0 : _a3.mode) === \"text\") last = last.rightSibling;\n          if (first && last) return select(model, [first, last]);\n        }\n        if (atom.rightSibling.mode === \"text\") {\n          let next = atom;\n          while (next && next.mode === \"text\") next = next.rightSibling;\n          if (next) {\n            leapTo(model, (_b3 = next.leftSibling) != null ? _b3 : next);\n            model.mathfield.switchMode(\"math\");\n            return true;\n          }\n          return leapTo(model, model.lastOffset);\n        }\n      }\n      const parentPrompt = model.at(model.anchor).parentPrompt;\n      const origin = parentPrompt ? model.offsetOf(parentPrompt) + 1 : Math.max(model.position + 1, 0);\n      const target = leapTarget(model, origin, \"forward\");\n      if (target && model.offsetOf(target) < origin)\n        return leap(model, \"forward\");\n      if (target) return leapTo(model, target);\n      const sibling = findSibling(\n        model,\n        atom,\n        (x) => x.type === \"leftright\" || x.type === \"text\",\n        \"forward\"\n      );\n      if (sibling) {\n        if (sibling.mode === \"text\") {\n          let last = sibling;\n          while (last && last.mode === \"text\") last = last.rightSibling;\n          return select(model, [\n            (_c2 = sibling.leftSibling) != null ? _c2 : sibling,\n            (_d2 = last.leftSibling) != null ? _d2 : last\n          ]);\n        }\n        return select(model, sibling);\n      }\n      const parent = atom.parent;\n      if (parent) {\n        if (parent.type === \"leftright\" || parent.type === \"surd\")\n          return select(model, parent);\n        if (atom.parentBranch === \"superscript\" && parent.subscript)\n          return select(model, parent.subscript);\n        if (atom.parentBranch === \"above\" && parent.below)\n          return select(model, parent.below);\n        if (atom.parentBranch === \"superscript\" || atom.parentBranch === \"subscript\")\n          return leapTo(model, parent);\n        if (atom.parentBranch === \"above\" || atom.parentBranch === \"below\")\n          return select(model, parent);\n      }\n      return leapTo(model, model.lastOffset);\n    },\n    moveToPreviousGroup: (model) => {\n      var _a3;\n      if (model.position === 0 && model.anchor === 0)\n        return leap(model, \"backward\");\n      let atom = model.at(model.position);\n      const mode = atom.mode;\n      if (mode === \"text\") {\n        if (model.selectionIsCollapsed) {\n          let first = atom;\n          while (first && first.mode === \"text\") first = first.leftSibling;\n          let last = atom;\n          while (((_a3 = last.rightSibling) == null ? void 0 : _a3.mode) === \"text\") last = last.rightSibling;\n          if (first && last) return select(model, [first, last]);\n        }\n        while (atom && atom.mode === \"text\") atom = atom.leftSibling;\n        if (atom) return leapTo(model, atom);\n        return leapTo(model, 0);\n      }\n      const parentPrompt = model.at(model.anchor).parentPrompt;\n      const origin = parentPrompt ? model.offsetOf(parentPrompt.leftSibling) : Math.max(model.position - 1, 0);\n      const target = leapTarget(model, origin, \"backward\");\n      if (target && model.offsetOf(target) > origin)\n        return leap(model, \"backward\");\n      if (target) return leapTo(model, target);\n      if (mode === \"math\") {\n        const sibling = findSibling(\n          model,\n          atom,\n          (x) => x.type === \"leftright\" || x.type === \"text\",\n          \"backward\"\n        );\n        if (sibling) {\n          if (sibling.mode === \"text\") {\n            let first = sibling;\n            while (first && first.mode === \"text\") first = first.leftSibling;\n            return select(model, [sibling, first]);\n          }\n          return select(model, sibling);\n        }\n        const parent = atom.parent;\n        if (parent) {\n          if (parent.type === \"leftright\" || parent.type === \"surd\")\n            return select(model, parent);\n          if (atom.parentBranch === \"subscript\" && parent.superscript)\n            return select(model, parent.superscript);\n          if (atom.parentBranch === \"below\" && parent.above)\n            return select(model, parent.above);\n          if (atom.parentBranch === \"superscript\" || atom.parentBranch === \"subscript\")\n            return leapTo(model, parent);\n          if (atom.parentBranch === \"above\" || atom.parentBranch === \"below\")\n            return select(model, parent);\n        }\n        return leapTo(model, 0);\n      }\n      return false;\n    },\n    moveToMathfieldStart: (model) => {\n      if (model.selectionIsCollapsed && model.position === 0) {\n        model.announce(\"plonk\");\n        return false;\n      }\n      model.position = 0;\n      model.mathfield.stopCoalescingUndo();\n      return true;\n    },\n    moveToMathfieldEnd: (model) => {\n      if (model.selectionIsCollapsed && model.position === model.lastOffset) {\n        model.announce(\"plonk\");\n        return false;\n      }\n      model.position = model.lastOffset;\n      model.mathfield.stopCoalescingUndo();\n      return true;\n    },\n    moveToSuperscript,\n    moveToSubscript\n  },\n  { target: \"model\", changeSelection: true }\n);\nregister2(\n  {\n    moveToNextPlaceholder: (model) => leap(model, \"forward\"),\n    moveToPreviousPlaceholder: (model) => leap(model, \"backward\")\n  },\n  { target: \"model\", changeSelection: true, audioFeedback: \"return\" }\n);\nfunction findSibling(model, atom, pred, dir) {\n  if (dir === \"forward\") {\n    let result2 = atom.rightSibling;\n    while (result2 && !pred(result2)) result2 = result2.rightSibling;\n    return result2;\n  }\n  let result = atom.leftSibling;\n  while (result && !pred(result)) result = result.leftSibling;\n  return result;\n}\n\n// src/editor-mathfield/smartmode.ts\nfunction convertLastAtomsToText(model, count, until) {\n  if (typeof count === \"function\") {\n    until = count;\n    count = Infinity;\n  }\n  if (count === void 0) count = Infinity;\n  let i = model.position;\n  let done = false;\n  let text = \"\";\n  while (!done) {\n    const atom = model.at(i);\n    done = count === 0 || atom === void 0 || atom.type === \"first\" || atom.mode !== \"math\" || !(atom.type && /mord|mpunct|operator/.test(atom.type) || atom.type === \"mop\" && /[a-zA-Z ]+/.test(atom.value)) || !atom.hasEmptyBranch(\"superscript\") || !atom.hasEmptyBranch(\"subscript\") || typeof until === \"function\" && !until(atom);\n    if (!done) {\n      atom.mode = \"text\";\n      atom.command = atom.value;\n      atom.verbatimLatex = void 0;\n      text += atom.value;\n    }\n    i -= 1;\n    count -= 1;\n  }\n  model.contentDidChange({ data: text, inputType: \"insertText\" });\n}\nfunction convertLastAtomsToMath(model, count, until) {\n  if (typeof count === \"function\") {\n    until = count;\n    count = Infinity;\n  }\n  if (count === void 0) count = Infinity;\n  let i = model.position;\n  let done = false;\n  const data = [];\n  while (!done) {\n    const atom = model.at(i);\n    done = count === 0 || !atom || atom.type === \"first\" || atom.isFirstSibling || atom.mode !== \"text\" || atom.value === \" \" || typeof until === \"function\" && !until(atom);\n    if (!done) {\n      data.push(Atom.serialize([atom], { defaultMode: \"math\" }));\n      atom.mode = \"math\";\n    }\n    i -= 1;\n    count -= 1;\n  }\n  removeIsolatedSpace(model);\n  model.contentDidChange({ data: joinLatex(data), inputType: \"insertText\" });\n}\nfunction removeIsolatedSpace(model) {\n  var _a3;\n  let i = model.position - 1;\n  while (i >= 0 && ((_a3 = model.at(i)) == null ? void 0 : _a3.mode) === \"math\") i -= 1;\n  if (i < 0) return;\n  if (model.at(i).mode === \"text\" && model.at(i).value === \" \" && model.at(i - 1).mode === \"math\") {\n    model.at(i - 1).parent.removeChild(model.at(i - 1));\n    const save = model.silenceNotifications;\n    model.silenceNotifications = true;\n    model.position -= 1;\n    model.silenceNotifications = save;\n    model.contentDidChange({ inputType: \"deleteContent\" });\n  }\n}\nfunction getTextBeforePosition(model) {\n  let result = \"\";\n  let i = model.position;\n  let done = false;\n  while (!done) {\n    const atom = model.at(i);\n    done = !(atom && (atom.mode === \"text\" || atom.mode === \"math\" && atom.type && /mord|mpunct/.test(atom.type)));\n    if (!done) result = atom.value + result;\n    i -= 1;\n  }\n  return result;\n}\nfunction smartMode(mathfield, keystroke, evt) {\n  const { model } = mathfield;\n  if (model.mode === \"latex\") return false;\n  if (!model.at(model.position).isLastSibling) return false;\n  if (!evt || !mightProducePrintableCharacter(evt)) return false;\n  const c = keyboardEventToChar(evt);\n  if (!model.selectionIsCollapsed) {\n    if (mathfield.model.mode === \"text\") {\n      if (/[/_^]/.test(c)) return true;\n    }\n    return false;\n  }\n  const context = getTextBeforePosition(model) + c;\n  if (mathfield.model.mode === \"text\") {\n    if (keystroke === \"Esc\" || /[/\\\\]/.test(c)) {\n      return true;\n    }\n    if (/[\\^_]/.test(c)) {\n      if (/(^|\\s)[a-zA-Z][^_]$/.test(context)) {\n        convertLastAtomsToMath(model, 1);\n      }\n      return true;\n    }\n    const lFence = { \")\": \"(\", \"}\": \"{\", \"]\": \"[\" }[c];\n    const { parent } = model.at(model.position);\n    if (lFence && parent instanceof LeftRightAtom && parent.leftDelim === lFence)\n      return true;\n    if (/(^|[^a-zA-Z])(a|I) $/.test(context)) {\n      return false;\n    }\n    if (/[$€£₤₺¥¤฿¢₡₧₨₹₩₱]/u.test(c)) {\n      return true;\n    }\n    if (/(^|[^a-zA-Z'’])[a-zA-Z] $/.test(context)) {\n      convertLastAtomsToMath(model, 1);\n      return false;\n    }\n    if (/\\D\\.[^\\d\\s]$/.test(context)) {\n      convertLastAtomsToMath(model, 1);\n      const atom = model.at(model.position);\n      atom.value = \"\\u22C5\";\n      atom.style.variant = \"normal\";\n      atom.command = \"\\\\cdot\";\n      atom.verbatimLatex = void 0;\n      model.contentDidChange({ data: \"\\\\cdot\", inputType: \"insertText\" });\n      return true;\n    }\n    if (/(^|\\s)[a-zA-Z][^a-zA-Z]$/.test(context)) {\n      convertLastAtomsToMath(model, 1);\n      return true;\n    }\n    if (/\\.\\d$/.test(context)) {\n      convertLastAtomsToMath(model, 1);\n      return true;\n    }\n    if (/\\([\\d+\\-.]$/.test(context)) {\n      convertLastAtomsToMath(model, 1);\n      return true;\n    }\n    if (/\\([a-z][,;]$/.test(context)) {\n      convertLastAtomsToMath(model, 2);\n      return true;\n    }\n    if (/[\\d+\\-=><*|]$/.test(c)) {\n      removeIsolatedSpace(model);\n      return true;\n    }\n  } else {\n    if (keystroke === \"[Space]\") {\n      convertLastAtomsToText(\n        model,\n        void 0,\n        (a) => /[a-z][:,;.]$/.test(a.value)\n      );\n      return true;\n    }\n    if (/[a-zA-Z]{3,}$/.test(context) && !/(dxd|abc|xyz|uvw)$/.test(context)) {\n      convertLastAtomsToText(model, void 0, (a) => /[a-zA-Z]/.test(a.value));\n      return true;\n    }\n    if (/(^|\\W)(if)$/i.test(context)) {\n      convertLastAtomsToText(model, 1);\n      return true;\n    }\n    if (/(\\u0393|\\u0394|\\u0398|\\u039B|\\u039E|\\u03A0|\\u03A3|\\u03A5|\\u03A6|\\u03A8|\\u03A9|[\\u03B1-\\u03C9]|\\u03D1|\\u03D5|\\u03D6|\\u03F1|\\u03F5){3,}$/u.test(\n      context\n    ) && !/(αβγ)$/.test(context)) {\n      convertLastAtomsToText(\n        model,\n        void 0,\n        (a) => /(:|,|;|.|\\u0393|\\u0394|\\u0398|\\u039B|\\u039E|\\u03A0|\\u03A3|\\u03A5|\\u03A6|\\u03A8|\\u03A9|[\\u03B1-\\u03C9]|\\u03D1|\\u03D5|\\u03D6|\\u03F1|\\u03F5)/u.test(\n          a.value\n        )\n      );\n      return true;\n    }\n    if (c === \"?\") {\n      return true;\n    }\n    if (c === \".\" && !/[\\d-+]\\.$/.test(context)) {\n      return true;\n    }\n  }\n  return false;\n}\n\n// src/editor-mathfield/keystroke-caption.ts\nfunction showKeystroke(mathfield, keystroke) {\n  if (!mathfield.isSelectionEditable || !mathfield.keystrokeCaptionVisible)\n    return;\n  const vb = createKeystrokeCaption();\n  const bounds = mathfield.element.getBoundingClientRect();\n  vb.style.left = `${bounds.left}px`;\n  vb.style.top = `${bounds.top - 64}px`;\n  vb.innerHTML = globalThis.MathfieldElement.createHTML(\n    \"<span>\" + (getKeybindingMarkup(keystroke) || keystroke) + \"</span>\" + vb.innerHTML\n  );\n  vb.style.visibility = \"visible\";\n  setTimeout(() => {\n    if (vb.childNodes.length > 0)\n      vb.childNodes[vb.childNodes.length - 1].remove();\n    if (vb.childNodes.length === 0) vb.style.visibility = \"hidden\";\n  }, 3e3);\n}\nfunction toggleKeystrokeCaption(mathfield) {\n  mathfield.keystrokeCaptionVisible = !mathfield.keystrokeCaptionVisible;\n  if (!mathfield.keystrokeCaptionVisible) {\n    const panel = getSharedElement(\"mathlive-keystroke-caption-panel\");\n    panel.style.visibility = \"hidden\";\n  } else {\n    const panel = createKeystrokeCaption();\n    panel.innerHTML = \"\";\n  }\n  return false;\n}\nfunction createKeystrokeCaption() {\n  const panel = document.getElementById(\"mathlive-keystroke-caption-panel\");\n  if (panel) return panel;\n  injectStylesheet(\"keystroke-caption\");\n  injectStylesheet(\"core\");\n  return getSharedElement(\"mathlive-keystroke-caption-panel\");\n}\nfunction disposeKeystrokeCaption() {\n  if (!document.getElementById(\"mathlive-keystroke-caption-panel\")) return;\n  releaseSharedElement(\"mathlive-keystroke-caption-panel\");\n  releaseStylesheet(\"core\");\n  releaseStylesheet(\"keystroke-caption\");\n}\n\n// src/editor-mathfield/keyboard-input.ts\nfunction onKeystroke(mathfield, evt) {\n  var _a3, _b3, _c2;\n  const { model } = mathfield;\n  const keystroke = keyboardEventToString(evt);\n  if (evt.isTrusted) {\n    validateKeyboardLayout(evt);\n    const activeLayout = getActiveKeyboardLayout();\n    if (mathfield.keyboardLayout !== activeLayout.id) {\n      mathfield.keyboardLayout = activeLayout.id;\n      mathfield._keybindings = void 0;\n    }\n  }\n  clearTimeout(mathfield.inlineShortcutBufferFlushTimer);\n  mathfield.inlineShortcutBufferFlushTimer = 0;\n  showKeystroke(mathfield, keystroke);\n  if (evt.isTrusted && evt.defaultPrevented) {\n    mathfield.flushInlineShortcutBuffer();\n    return false;\n  }\n  let shortcut;\n  let shortcutLength = 0;\n  let selector = \"\";\n  let stateIndex = 0;\n  const buffer = mathfield.inlineShortcutBuffer;\n  if (mathfield.isSelectionEditable) {\n    if (model.mode === \"math\") {\n      if (keystroke === \"[Backspace]\") {\n        if (mathfield.undoManager.lastOp === \"insert-shortcut\")\n          selector = \"undo\";\n        else buffer.pop();\n      } else if (!mightProducePrintableCharacter(evt)) {\n        mathfield.flushInlineShortcutBuffer();\n      } else {\n        const c = keyboardEventToChar(evt);\n        const keystrokes = [\n          ...(_b3 = (_a3 = buffer[buffer.length - 1]) == null ? void 0 : _a3.keystrokes) != null ? _b3 : [],\n          c\n        ];\n        buffer.push({\n          state: model.getState(),\n          keystrokes,\n          leftSiblings: getLeftSiblings(mathfield)\n        });\n        shortcutLength = 0;\n        let candidate = \"\";\n        while (!shortcut && shortcutLength < keystrokes.length) {\n          stateIndex = buffer.length - (keystrokes.length - shortcutLength);\n          candidate = keystrokes.slice(shortcutLength).join(\"\");\n          shortcut = getInlineShortcut(\n            buffer[stateIndex].leftSiblings,\n            candidate,\n            mathfield.options.inlineShortcuts\n          );\n          if (!shortcut && /^[a-zA-Z][a-zA-Z0-9]+?([_\\^][a-zA-Z0-9\\*\\+\\-]+?)?$/.test(candidate))\n            shortcut = mathfield.options.onInlineShortcut(mathfield, candidate);\n          shortcutLength += 1;\n        }\n        mathfield.flushInlineShortcutBuffer({ defer: true });\n      }\n    }\n    if (mathfield.options.smartMode) {\n      if (shortcut) {\n        mathfield.switchMode(\"math\");\n      } else if (smartMode(mathfield, keystroke, evt)) {\n        mathfield.switchMode({ math: \"text\", text: \"math\" }[model.mode]);\n        selector = \"\";\n      }\n    }\n  }\n  if (!shortcut) {\n    if (!selector) {\n      selector = getCommandForKeybinding(\n        mathfield.keybindings,\n        model.mode,\n        evt\n      );\n    }\n    if (!selector && (keystroke === \"[Enter]\" || keystroke === \"[Return]\")) {\n      let success = true;\n      if (model.contentWillChange({ inputType: \"insertLineBreak\" })) {\n        if (mathfield.host) {\n          success = mathfield.host.dispatchEvent(\n            new Event(\"change\", { bubbles: true, composed: true })\n          );\n        }\n        if (!success && evt.preventDefault) {\n          evt.preventDefault();\n          evt.stopPropagation();\n        } else {\n          model.contentDidChange({ inputType: \"insertLineBreak\" });\n        }\n      }\n      return success;\n    }\n    if ((!selector || keystroke === \"[Space]\") && model.mode === \"math\") {\n      if (keystroke === \"[Space]\") {\n        mathfield.styleBias = \"none\";\n        mathfield.flushInlineShortcutBuffer();\n        if (mathfield.options.mathModeSpace) {\n          ModeEditor.insert(model, mathfield.options.mathModeSpace, {\n            format: \"latex\",\n            mode: \"math\"\n          });\n          mathfield.snapshot(\"insert-space\");\n          selector = \"\";\n          mathfield.dirty = true;\n          mathfield.scrollIntoView();\n          if (evt.preventDefault) {\n            evt.preventDefault();\n            evt.stopPropagation();\n          }\n          return false;\n        }\n        const nextSibling = model.at(model.position + 1);\n        const previousSibling = model.at(model.position - 1);\n        if ((nextSibling == null ? void 0 : nextSibling.mode) === \"text\" || (previousSibling == null ? void 0 : previousSibling.mode) === \"text\") {\n          ModeEditor.insert(model, \" \", { mode: \"text\" });\n          mathfield.snapshot(\"insert-space\");\n          mathfield.dirty = true;\n          mathfield.scrollIntoView();\n          return false;\n        }\n      }\n      if (((_c2 = model.at(model.position)) == null ? void 0 : _c2.isDigit()) && globalThis.MathfieldElement.decimalSeparator === \",\" && keyboardEventToChar(evt) === \",\")\n        selector = \"insertDecimalSeparator\";\n    }\n  }\n  if (!shortcut && !selector) {\n    if (!model.mathfield.smartFence) {\n      const { parent: parent2 } = model.at(model.position);\n      if (parent2 instanceof LeftRightAtom && parent2.rightDelim === \"?\" && model.at(model.position).isLastSibling && /^[)}\\]|]$/.test(keystroke)) {\n        mathfield.snapshot();\n        parent2.isDirty = true;\n        parent2.rightDelim = keystroke;\n        model.position += 1;\n        model.selectionDidChange();\n        model.contentDidChange({\n          data: keyboardEventToChar(evt),\n          inputType: \"insertText\"\n        });\n        mathfield.snapshot(\"insert-fence\");\n        mathfield.dirty = true;\n        mathfield.scrollIntoView();\n        if (evt.preventDefault) evt.preventDefault();\n        return false;\n      }\n      if (!model.selectionIsCollapsed) {\n        const fence = keyboardEventToChar(evt);\n        if (fence === \"(\" || fence === \"{\" || fence === \"[\") {\n          const lDelim = { \"(\": \"(\", \"{\": \"\\\\lbrace\", \"[\": \"\\\\lbrack\" }[fence];\n          const rDelim = { \"(\": \")\", \"{\": \"\\\\rbrace\", \"[\": \"\\\\rbrack\" }[fence];\n          const [start, end] = range(model.selection);\n          mathfield.snapshot();\n          model.position = end;\n          ModeEditor.insert(model, rDelim, { format: \"latex\" });\n          model.position = start;\n          ModeEditor.insert(model, lDelim, { format: \"latex\" });\n          model.setSelection(start + 1, end + 1);\n          model.contentDidChange({\n            data: fence,\n            inputType: \"insertText\"\n          });\n          mathfield.snapshot(\"insert-fence\");\n          mathfield.dirty = true;\n          mathfield.scrollIntoView();\n          if (evt.preventDefault) evt.preventDefault();\n          return false;\n        }\n      }\n    } else if (insertSmartFence(\n      model,\n      keyboardEventToChar(evt),\n      computeInsertStyle(mathfield)\n    )) {\n      mathfield.dirty = true;\n      mathfield.scrollIntoView();\n      if (evt.preventDefault) evt.preventDefault();\n      return false;\n    }\n    return true;\n  }\n  const child = model.at(Math.max(model.position, model.anchor));\n  const { parent } = child;\n  if (selector === \"moveAfterParent\" && (parent == null ? void 0 : parent.type) === \"leftright\" && child.isLastSibling && mathfield.options.smartFence && insertSmartFence(model, \".\", mathfield.defaultStyle)) {\n    selector = \"\";\n    requestUpdate(mathfield);\n  }\n  mathfield.keyboardDelegate.cancelComposition();\n  if (selector) mathfield.executeCommand(selector);\n  else if (shortcut) {\n    const style = computeInsertStyle(mathfield);\n    model.setState(buffer[stateIndex].state);\n    let keystrokes = buffer[buffer.length - 1].keystrokes;\n    keystrokes = keystrokes.slice(shortcutLength - 1);\n    for (const c of keystrokes) {\n      ModeEditor.insert(model, c, {\n        silenceNotifications: true,\n        style\n      });\n    }\n    mathfield.snapshot(`insert-shortcut`);\n    model.setState(buffer[stateIndex].state);\n    model.deferNotifications(\n      {\n        content: true,\n        selection: true,\n        data: shortcut,\n        type: \"insertText\"\n      },\n      () => {\n        ModeEditor.insert(model, shortcut, { format: \"latex\", style });\n        removeIsolatedSpace(mathfield.model);\n        if (shortcut.endsWith(\" \")) {\n          mathfield.switchMode(\"text\");\n          ModeEditor.insert(model, \" \", { style, mode: \"text\" });\n        }\n        mathfield.snapshot();\n        if (!model.selectionIsCollapsed) mathfield.flushInlineShortcutBuffer();\n        return true;\n      }\n    );\n    mathfield.dirty = true;\n    model.announce(\"replacement\");\n  }\n  mathfield.scrollIntoView();\n  if (evt.preventDefault) evt.preventDefault();\n  return false;\n}\nfunction onInput(mathfield, text, options) {\n  const { model } = mathfield;\n  if (!mathfield.isSelectionEditable) {\n    model.announce(\"plonk\");\n    return;\n  }\n  options != null ? options : options = {};\n  if (options.focus) mathfield.focus();\n  if (options.feedback) globalThis.MathfieldElement.playSound(\"keypress\");\n  if (typeof options.mode === \"string\") {\n    mathfield.switchMode(options.mode);\n    mathfield.snapshot();\n  }\n  let graphemes = splitGraphemes(text);\n  const keyboard = window.mathVirtualKeyboard;\n  if (keyboard == null ? void 0 : keyboard.isShifted) {\n    graphemes = typeof graphemes === \"string\" ? graphemes.toUpperCase() : graphemes.map((c) => c.toUpperCase());\n  }\n  if (options.simulateKeystroke) {\n    let handled = true;\n    for (const c of graphemes) {\n      if (onKeystroke(mathfield, new KeyboardEvent(\"keypress\", { key: c })))\n        handled = false;\n    }\n    if (handled) return;\n  }\n  if (model.mode === \"latex\") {\n    model.deferNotifications(\n      { content: true, selection: true, data: text, type: \"insertText\" },\n      () => {\n        removeSuggestion(mathfield);\n        for (const c of graphemes)\n          ModeEditor.insert(model, c, { insertionMode: \"replaceSelection\" });\n        mathfield.snapshot(\"insert-latex\");\n        updateAutocomplete(mathfield);\n      }\n    );\n  } else if (model.mode === \"text\") {\n    const style = __spreadValues(__spreadValues({}, getSelectionStyle(model)), mathfield.defaultStyle);\n    for (const c of graphemes)\n      ModeEditor.insert(model, c, { style, insertionMode: \"replaceSelection\" });\n    mathfield.snapshot(\"insert-text\");\n  } else if (model.mode === \"math\")\n    for (const c of graphemes) insertMathModeChar(mathfield, c);\n  mathfield.dirty = true;\n  mathfield.scrollIntoView();\n}\nfunction getLeftSiblings(mf) {\n  const model = mf.model;\n  const result = [];\n  let atom = model.at(Math.min(model.position, model.anchor));\n  while (atom.type !== \"first\") {\n    result.push(atom);\n    atom = atom.leftSibling;\n  }\n  return result;\n}\nfunction insertMathModeChar(mathfield, c) {\n  const model = mathfield.model;\n  const selector = {\n    \"^\": \"moveToSuperscript\",\n    \"_\": \"moveToSubscript\",\n    \" \": mathfield.options.mathModeSpace ? [\"insert\", mathfield.options.mathModeSpace] : \"moveAfterParent\"\n  }[c];\n  if (selector) {\n    mathfield.executeCommand(selector);\n    return;\n  }\n  let style = __spreadValues({}, computeInsertStyle(mathfield));\n  if (!/[a-zA-Z0-9]/.test(c) && mathfield.styleBias !== \"none\") {\n    style.variant = \"normal\";\n    style.variantStyle = void 0;\n  }\n  const atom = model.at(model.position);\n  if (/\\d/.test(c) && mathfield.options.smartSuperscript && atom.parentBranch === \"superscript\" && atom.parent.type !== \"mop\" && atom.parent.type !== \"operator\" && atom.parent.type !== \"extensible-symbol\" && atom.hasNoSiblings) {\n    if (!ModeEditor.insert(model, c, { style, insertionMode: \"replaceSelection\" })) {\n      mathfield.undoManager.pop();\n      return;\n    }\n    mathfield.snapshot(\"insert-mord\");\n    moveAfterParent(model);\n    return;\n  }\n  let input = c;\n  if (input === \"{\") input = \"\\\\lbrace\";\n  else if (input === \"}\") input = \"\\\\rbrace\";\n  else if (input === \"&\") input = \"\\\\&\";\n  else if (input === \"#\") input = \"\\\\#\";\n  else if (input === \"$\") input = \"\\\\$\";\n  else if (input === \"%\") input = \"\\\\%\";\n  else if (input === \"~\") input = \"\\\\~\";\n  else if (input === \"\\\\\") input = \"\\\\backslash\";\n  if (!ModeEditor.insert(model, input, {\n    style,\n    insertionMode: \"replaceSelection\"\n  }))\n    return;\n  mathfield.snapshot(`insert-${model.at(model.position).type}`);\n}\nfunction getSelectionStyle(model) {\n  var _a3, _b3, _c2, _d2;\n  if (model.selectionIsCollapsed) return (_b3 = (_a3 = model.at(model.position)) == null ? void 0 : _a3.style) != null ? _b3 : {};\n  const first = range(model.selection)[0];\n  return (_d2 = (_c2 = model.at(first + 1)) == null ? void 0 : _c2.style) != null ? _d2 : {};\n}\nfunction insertSmartFence(model, key, style) {\n  var _a3;\n  if (!key) return false;\n  if (model.mode !== \"math\") return false;\n  const atom = model.at(model.position);\n  const { parent } = atom;\n  const fence = {\n    \"(\": \"(\",\n    \")\": \")\",\n    \"{\": \"\\\\lbrace\",\n    \"}\": \"\\\\rbrace\",\n    \"[\": \"\\\\lbrack\",\n    \"]\": \"\\\\rbrack\",\n    \"|\": \"|\"\n  }[key];\n  if (!fence) return false;\n  const lDelim = LEFT_DELIM[fence];\n  const rDelim = RIGHT_DELIM[fence];\n  if (!model.selectionIsCollapsed) {\n    model.mathfield.snapshot();\n    const [start, end] = range(model.selection);\n    const body = model.extractAtoms([start, end]);\n    const atom2 = parent.addChildrenAfter(\n      [\n        new LeftRightAtom(\"left...right\", body, {\n          leftDelim: fence,\n          rightDelim: rDelim\n        })\n      ],\n      model.at(start)\n    );\n    model.setSelection(\n      model.offsetOf(atom2.firstChild),\n      model.offsetOf(atom2.lastChild)\n    );\n    model.mathfield.snapshot(\"insert-fence\");\n    model.contentDidChange({ data: fence, inputType: \"insertText\" });\n    return true;\n  }\n  if (fence === \"|\") {\n    const delims = parent instanceof LeftRightAtom ? parent.leftDelim + parent.rightDelim : \"\";\n    if (delims === \"\\\\lbrace\\\\rbrace\" || delims === \"\\\\{\\\\}\" || delims === \"\\\\lbrace?\") {\n      model.mathfield.snapshot();\n      ModeEditor.insert(model, \"\\\\,\\\\middle\\\\vert\\\\,\", {\n        format: \"latex\",\n        style\n      });\n      model.mathfield.snapshot(\"insert-fence\");\n      model.contentDidChange({ data: fence, inputType: \"insertText\" });\n      return true;\n    }\n  }\n  if (rDelim) {\n    if (parent instanceof LeftRightAtom && parent.firstChild === atom && // At first child\n    (parent.leftDelim === \"?\" || parent.leftDelim === \".\")) {\n      parent.leftDelim = fence;\n      parent.isDirty = true;\n      model.mathfield.snapshot();\n      model.contentDidChange({ data: fence, inputType: \"insertText\" });\n      model.mathfield.snapshot(\"insert-fence\");\n      return true;\n    }\n    if (!(parent instanceof LeftRightAtom)) {\n      let sibling = atom;\n      while (sibling) {\n        if (sibling.type === \"mclose\" && sibling.value === rDelim) break;\n        sibling = sibling.rightSibling;\n      }\n      if (sibling) {\n        model.mathfield.snapshot();\n        const body = model.extractAtoms([\n          model.offsetOf(atom),\n          model.offsetOf(sibling)\n        ]);\n        body.pop();\n        parent.addChildrenAfter(\n          [\n            new LeftRightAtom(\"left...right\", body, {\n              leftDelim: fence,\n              rightDelim: rDelim\n            })\n          ],\n          atom\n        );\n        model.position = model.offsetOf(parent.firstChild) + 1;\n        model.contentDidChange({ data: fence, inputType: \"insertText\" });\n        model.mathfield.snapshot(\"insert-fence\");\n        return true;\n      }\n    }\n    const lastSibling = model.offsetOf(atom.lastSibling);\n    let i;\n    for (i = model.position; i <= lastSibling; i++) {\n      const atom2 = model.at(i);\n      if (atom2 instanceof LeftRightAtom && (atom2.leftDelim === \"?\" || atom2.leftDelim === \".\") && isValidOpen(fence, atom2.rightDelim))\n        break;\n    }\n    const match = model.at(i);\n    if (i <= lastSibling && match instanceof LeftRightAtom) {\n      match.leftDelim = fence;\n      model.mathfield.snapshot();\n      let extractedAtoms = model.extractAtoms([model.position, i - 1]);\n      extractedAtoms = extractedAtoms.filter((value) => value.type !== \"first\");\n      match.addChildren(extractedAtoms, match.parentBranch);\n      model.position += 1;\n      model.contentDidChange({ data: fence, inputType: \"insertText\" });\n      model.mathfield.snapshot(\"insert-fence\");\n      return true;\n    }\n    if (parent instanceof LeftRightAtom && (parent.leftDelim === \"?\" || parent.leftDelim === \".\") && isValidOpen(fence, parent.rightDelim)) {\n      parent.isDirty = true;\n      parent.leftDelim = fence;\n      model.mathfield.snapshot();\n      const extractedAtoms = model.extractAtoms([\n        model.offsetOf(atom.firstSibling),\n        model.position\n      ]);\n      for (const extractedAtom of extractedAtoms)\n        parent.parent.addChildBefore(extractedAtom, parent);\n      model.contentDidChange({ data: fence, inputType: \"insertText\" });\n      model.mathfield.snapshot(\"insert-fence\");\n      return true;\n    }\n    if (!(parent instanceof LeftRightAtom && parent.leftDelim === \"|\")) {\n      if (fence === \"(\") {\n        let i2 = model.position - 1;\n        let hasDecimalPoint = false;\n        while (i2 >= 0) {\n          const atom2 = model.at(i2);\n          if (atom2.type === \"first\") break;\n          if (atom2.type === \"mord\" && atom2.value && /^[\\d]$/.test(atom2.value)) {\n            i2 -= 1;\n            continue;\n          }\n          if (atom2.type === \"group\" && ((_a3 = atom2.body) == null ? void 0 : _a3.length) === 2 && atom2.body[0].type === \"first\" && atom2.body[1].value === \",\") {\n            hasDecimalPoint = true;\n            break;\n          }\n          if (atom2.type === \"mord\" && (atom2.value === \",\" || atom2.value === \".\")) {\n            hasDecimalPoint = true;\n            break;\n          }\n          break;\n        }\n        if (hasDecimalPoint) return false;\n      }\n      model.mathfield.snapshot();\n      ModeEditor.insert(model, `\\\\left${fence}\\\\right?`, {\n        format: \"latex\",\n        style\n      });\n      if (atom.lastSibling.type !== \"first\") {\n        const lastSiblingOffset = model.offsetOf(atom.lastSibling);\n        const content = model.extractAtoms([model.position, lastSiblingOffset]);\n        model.at(model.position).body = content;\n        model.position -= 1;\n      }\n      model.mathfield.snapshot(\"insert-fence\");\n      return true;\n    }\n  }\n  if (lDelim) {\n    if (fence === \")\") {\n      let i2 = model.position - 1;\n      let hasDigits = false;\n      while (i2 >= 0) {\n        const atom2 = model.at(i2);\n        if (atom2.type === \"first\") break;\n        if (atom2.type === \"mord\" && atom2.value && /^[\\d]$/.test(atom2.value)) {\n          hasDigits = true;\n          i2 -= 1;\n          continue;\n        }\n        break;\n      }\n      if (hasDigits && model.at(i2).type === \"mopen\" && model.at(i2).value === \"(\")\n        return false;\n    }\n    let sibling = atom;\n    while (sibling) {\n      if (sibling.type === \"mopen\" && sibling.value === lDelim) {\n        model.mathfield.snapshot();\n        const insertAfter = sibling.leftSibling;\n        let body = model.extractAtoms([\n          model.offsetOf(sibling.leftSibling),\n          model.offsetOf(atom)\n        ]);\n        [, ...body] = body;\n        const result = new LeftRightAtom(\"left...right\", body, {\n          leftDelim: lDelim,\n          rightDelim: fence\n        });\n        parent.addChildrenAfter([result], insertAfter);\n        model.position = model.offsetOf(result);\n        model.contentDidChange({ data: fence, inputType: \"insertText\" });\n        model.mathfield.snapshot(\"insert-fence\");\n        return true;\n      }\n      sibling = sibling.leftSibling;\n    }\n    if (parent instanceof LeftRightAtom && atom.isLastSibling && isValidClose(parent.leftDelim, fence)) {\n      model.mathfield.snapshot();\n      parent.isDirty = true;\n      parent.rightDelim = fence;\n      model.position += 1;\n      model.contentDidChange({ data: fence, inputType: \"insertText\" });\n      model.mathfield.snapshot(\"insert-fence\");\n      return true;\n    }\n    const firstSibling = model.offsetOf(atom.firstSibling);\n    let i;\n    for (i = model.position; i >= firstSibling; i--) {\n      const atom2 = model.at(i);\n      if (atom2 instanceof LeftRightAtom && (atom2.rightDelim === \"?\" || atom2.rightDelim === \".\") && isValidClose(atom2.leftDelim, fence))\n        break;\n    }\n    const match = model.at(i);\n    if (i >= firstSibling && match instanceof LeftRightAtom) {\n      model.mathfield.snapshot();\n      match.rightDelim = fence;\n      match.addChildren(\n        model.extractAtoms([i, model.position]),\n        match.parentBranch\n      );\n      model.contentDidChange({ data: fence, inputType: \"insertText\" });\n      model.mathfield.snapshot(\"insert-fence\");\n      return true;\n    }\n    if (parent instanceof LeftRightAtom && (parent.rightDelim === \"?\" || parent.rightDelim === \".\") && isValidClose(parent.leftDelim, fence)) {\n      model.mathfield.snapshot();\n      parent.isDirty = true;\n      parent.rightDelim = fence;\n      parent.parent.addChildren(\n        model.extractAtoms([model.position, model.offsetOf(atom.lastSibling)]),\n        parent.parentBranch\n      );\n      model.position = model.offsetOf(parent);\n      model.contentDidChange({ data: fence, inputType: \"insertText\" });\n      model.mathfield.snapshot(\"insert-fence\");\n      return true;\n    }\n    const grandparent = parent.parent;\n    if (grandparent instanceof LeftRightAtom && (grandparent.rightDelim === \"?\" || grandparent.rightDelim === \".\") && model.at(model.position).isLastSibling) {\n      model.position = model.offsetOf(grandparent);\n      return insertSmartFence(model, fence, style);\n    }\n    return false;\n  }\n  return false;\n}\nfunction isValidClose(open, close) {\n  if (!open) return true;\n  if ([\"(\", \"\\\\lparen\", \"{\", \"\\\\{\", \"\\\\lbrace\", \"[\", \"\\\\lbrack\"].includes(open)) {\n    return [\")\", \"\\\\rparen\", \"}\", \"\\\\}\", \"\\\\rbrace\", \"]\", \"\\\\rbrack\"].includes(\n      close\n    );\n  }\n  return RIGHT_DELIM[open] === close;\n}\nfunction isValidOpen(open, close) {\n  if (!close) return true;\n  if ([\")\", \"\\\\rparen\", \"}\", \"\\\\}\", \"\\\\rbrace\", \"]\", \"\\\\rbrack\"].includes(close)) {\n    return [\"(\", \"\\\\lparen\", \"{\", \"\\\\{\", \"\\\\lbrace\", \"[\", \"\\\\lbrack\"].includes(\n      open\n    );\n  }\n  return LEFT_DELIM[close] === open;\n}\n\n// src/editor-mathfield/commands.ts\nregister2({\n  undo: (mathfield) => {\n    mathfield.undo();\n    return true;\n  },\n  redo: (mathfield) => {\n    mathfield.redo();\n    return true;\n  },\n  scrollIntoView: (mathfield) => {\n    mathfield.scrollIntoView();\n    return true;\n  },\n  scrollToStart: (mathfield) => {\n    mathfield.field.scroll(0, 0);\n    return true;\n  },\n  scrollToEnd: (mathfield) => {\n    const fieldBounds = mathfield.field.getBoundingClientRect();\n    mathfield.field.scroll(fieldBounds.left - window.scrollX, 0);\n    return true;\n  },\n  toggleKeystrokeCaption,\n  toggleContextMenu: (mathfield) => {\n    const result = mathfield.toggleContextMenu();\n    if (!result) mathfield.model.announce(\"plonk\");\n    return result;\n  },\n  plonk: (mathfield) => {\n    mathfield.model.announce(\"plonk\");\n    return true;\n  },\n  switchMode: (mathfield, mode, prefix, suffix) => {\n    mathfield.switchMode(mode, prefix, suffix);\n    return true;\n  },\n  insert: (mathfield, s, options) => mathfield.insert(s, options),\n  typedText: (mathfield, text, options) => {\n    onInput(mathfield, text, options);\n    return true;\n  },\n  insertDecimalSeparator: (mathfield) => {\n    const model = mathfield.model;\n    if (model.mode === \"math\" && globalThis.MathfieldElement.decimalSeparator === \",\") {\n      const child = model.at(Math.max(model.position, model.anchor));\n      if (child.isDigit()) {\n        mathfield.insert(\"{,}\", { format: \"latex\" });\n        mathfield.snapshot(\"insert-mord\");\n        return true;\n      }\n    }\n    mathfield.insert(\".\");\n    return true;\n  },\n  // A 'commit' command is used to simulate pressing the return/enter key,\n  // e.g. when using a virtual keyboard\n  commit: (mathfield) => {\n    var _a3;\n    if (mathfield.model.contentWillChange({ inputType: \"insertLineBreak\" })) {\n      (_a3 = mathfield.host) == null ? void 0 : _a3.dispatchEvent(\n        new Event(\"change\", { bubbles: true, composed: true })\n      );\n      mathfield.model.contentDidChange({ inputType: \"insertLineBreak\" });\n    }\n    return true;\n  },\n  insertPrompt: (mathfield, id, options) => {\n    const promptIds = mathfield.getPrompts();\n    let prospectiveId = \"prompt-\" + Date.now().toString(36).slice(-2) + Math.floor(Math.random() * 1e5).toString(36);\n    let i = 0;\n    while (promptIds.includes(prospectiveId) && i < 100) {\n      if (i === 99) {\n        console.error(\"could not find a unique ID after 100 tries\");\n        return false;\n      }\n      prospectiveId = \"prompt-\" + Date.now().toString(36).slice(-2) + Math.floor(Math.random() * 1e5).toString(36);\n      i++;\n    }\n    mathfield.insert(`\\\\placeholder[${id != null ? id : prospectiveId}]{}`, options);\n    return true;\n  }\n});\nregister2(\n  {\n    copyToClipboard: (mathfield) => {\n      mathfield.focus();\n      if (mathfield.model.selectionIsCollapsed) mathfield.select();\n      if (!(\"queryCommandSupported\" in document && document.queryCommandSupported(\"copy\") && document.execCommand(\"copy\"))) {\n        mathfield.element.querySelector(\".ML__keyboard-sink\").dispatchEvent(\n          new ClipboardEvent(\"copy\", {\n            bubbles: true,\n            composed: true\n          })\n        );\n      }\n      return false;\n    }\n  },\n  { target: \"mathfield\" }\n);\nregister2(\n  {\n    cutToClipboard: (mathfield) => {\n      mathfield.focus();\n      if (!(\"queryCommandSupported\" in document && document.queryCommandSupported(\"cut\") && document.execCommand(\"cut\"))) {\n        mathfield.element.querySelector(\".ML__keyboard-sink\").dispatchEvent(\n          new ClipboardEvent(\"cut\", {\n            bubbles: true,\n            composed: true\n          })\n        );\n      }\n      return true;\n    },\n    pasteFromClipboard: (mathfield) => {\n      mathfield.focus();\n      if (\"queryCommandSupported\" in document && document.queryCommandSupported(\"paste\")) {\n        document.execCommand(\"paste\");\n        return true;\n      }\n      navigator.clipboard.readText().then((text) => {\n        if (text && mathfield.model.contentWillChange({\n          inputType: \"insertFromPaste\",\n          data: text\n        })) {\n          mathfield.stopCoalescingUndo();\n          mathfield.stopRecording();\n          if (mathfield.insert(text, { mode: mathfield.model.mode })) {\n            updateAutocomplete(mathfield);\n            mathfield.startRecording();\n            mathfield.snapshot(\"paste\");\n            mathfield.model.contentDidChange({ inputType: \"insertFromPaste\" });\n            requestUpdate(mathfield);\n          }\n        } else mathfield.model.announce(\"plonk\");\n        mathfield.startRecording();\n      });\n      return true;\n    }\n  },\n  {\n    target: \"mathfield\",\n    canUndo: true,\n    changeContent: true,\n    changeSelection: true\n  }\n);\n\n// src/editor-model/commands-select.ts\nfunction selectGroup(model) {\n  let [start, end] = range(model.selection);\n  start = boundary(model, start, \"backward\");\n  end = boundary(model, end, \"forward\");\n  if (start === end) {\n    const atom = model.at(start);\n    if (atom.type === \"leftright\")\n      return model.setSelection(model.offsetOf(atom.firstChild) - 1, end);\n    if (atom.type === \"first\" && (atom.parent.type === \"leftright\" || atom.parent.type === \"surd\")) {\n      return model.setSelection(\n        start - 1,\n        model.offsetOf(atom.parent.lastChild) + 1\n      );\n    }\n    model.setSelection(start - 1, end);\n  } else model.setSelection(start, end);\n  return true;\n}\nfunction boundary(model, pos, direction) {\n  var _a3, _b3, _c2;\n  let atom = model.at(pos);\n  if (!atom) return pos;\n  const dir = direction === \"forward\" ? 1 : -1;\n  if (atom.mode === \"text\") {\n    while (atom) {\n      if (atom.mode !== \"text\" || !LETTER_AND_DIGITS.test(atom.value)) break;\n      pos += dir;\n      atom = model.at(pos);\n    }\n    return direction === \"backward\" ? pos - 1 : pos;\n  }\n  if (atom.mode === \"latex\") {\n    if (/[a-zA-Z\\*]/.test(atom.value)) {\n      if (direction === \"backward\") {\n        while (atom && atom.mode === \"latex\" && atom.value !== \"\\\\\" && /[a-zA-Z]/.test(atom.value)) {\n          pos += dir;\n          atom = model.at(pos);\n        }\n      } else {\n        while (atom && atom.mode === \"latex\" && /[a-zA-Z\\*]/.test(atom.value)) {\n          pos += dir;\n          atom = model.at(pos);\n        }\n      }\n    } else if (atom.value === \"{\") {\n      if (direction === \"forward\") {\n        while (atom && atom.mode === \"latex\" && atom.value !== \"}\") {\n          pos += dir;\n          atom = model.at(pos);\n        }\n        return pos;\n      }\n      return pos - 1;\n    } else if (atom.value === \"}\") {\n      if (direction === \"backward\") {\n        while (atom && atom.mode === \"latex\" && atom.value !== \"{\") {\n          pos += dir;\n          atom = model.at(pos);\n        }\n        return pos - 1;\n      }\n      return pos;\n    }\n    return pos - 1;\n  }\n  if (atom.mode === \"math\") {\n    if (atom.isDigit()) {\n      while ((_a3 = model.at(pos + dir)) == null ? void 0 : _a3.isDigit()) pos += dir;\n      return direction === \"backward\" ? pos - 1 : pos;\n    }\n    if (atom.style.variant || atom.style.variantStyle) {\n      let x = (_b3 = model.at(pos)) == null ? void 0 : _b3.style;\n      while (x && x.variant === atom.style.variant && x.variantStyle === atom.style.variantStyle) {\n        x = (_c2 = model.at(pos + dir)) == null ? void 0 : _c2.style;\n        pos += dir;\n      }\n      return direction === \"backward\" ? pos - 1 : pos;\n    }\n    return pos;\n  }\n  return pos;\n}\nregister2(\n  {\n    selectGroup: (model) => {\n      const result = selectGroup(model);\n      if (!result) model.announce(\"plonk\");\n      return result;\n    },\n    selectAll: (model) => model.setSelection(0, model.lastOffset),\n    extendSelectionForward: (model) => move(model, \"forward\", { extend: true }),\n    extendSelectionBackward: (model) => move(model, \"backward\", { extend: true }),\n    extendToNextWord: (model) => skip(model, \"forward\", { extend: true }),\n    extendToPreviousWord: (model) => skip(model, \"backward\", { extend: true }),\n    extendSelectionUpward: (model) => move(model, \"upward\", { extend: true }),\n    extendSelectionDownward: (model) => move(model, \"downward\", { extend: true }),\n    /**\n     * Extend the selection until the next boundary is reached. A boundary\n     * is defined by an atom of a different type (mbin, mord, etc...)\n     * than the current focus. For example, in \"1234+x=y\", if the focus is between\n     * \"1\" and \"2\", invoking `extendToNextBoundary_` would extend the selection\n     * to \"234\".\n     */\n    extendToNextBoundary: (model) => skip(model, \"forward\", { extend: true }),\n    /**\n     * Extend the selection until the previous boundary is reached. A boundary\n     * is defined by an atom of a different type (mbin, mord, etc...)\n     * than the current focus. For example, in \"1+23456\", if the focus is between\n     * \"5\" and \"6\", invoking `extendToPreviousBoundary` would extend the selection\n     * to \"2345\".\n     */\n    extendToPreviousBoundary: (model) => skip(model, \"backward\", { extend: true }),\n    extendToGroupStart: (model) => {\n      const result = model.setSelection(\n        model.anchor,\n        model.offsetOf(model.at(model.position).firstSibling)\n      );\n      if (!result) model.announce(\"plonk\");\n      return result;\n    },\n    extendToGroupEnd: (model) => {\n      const result = model.setSelection(\n        model.anchor,\n        model.offsetOf(model.at(model.position).lastSibling)\n      );\n      if (!result) model.announce(\"plonk\");\n      return result;\n    },\n    extendToMathFieldStart: (model) => {\n      const result = model.setSelection(model.anchor, 0);\n      if (!result) model.announce(\"plonk\");\n      return result;\n    },\n    extendToMathFieldEnd: (model) => {\n      const result = model.setSelection(model.anchor, model.lastOffset);\n      if (!result) model.announce(\"plonk\");\n      return result;\n    }\n  },\n  { target: \"model\", changeSelection: true }\n);\n\n// src/editor-mathfield/pointer-input.ts\nvar gLastTap = null;\nvar gTapCount = 0;\nvar PointerTracker = class _PointerTracker {\n  static start(element, evt, onMove, onCancel) {\n    var _a3;\n    _PointerTracker.element = element;\n    (_a3 = _PointerTracker.controller) == null ? void 0 : _a3.abort();\n    _PointerTracker.controller = new AbortController();\n    const options = { signal: _PointerTracker.controller.signal };\n    if (\"PointerEvent\" in window) {\n      element.addEventListener(\"pointermove\", onMove, options);\n      element.addEventListener(\"pointerup\", onCancel, options);\n      element.addEventListener(\"pointercancel\", onCancel, options);\n      if (isPointerEvent(evt)) {\n        _PointerTracker.pointerId = evt.pointerId;\n        element.setPointerCapture(evt.pointerId);\n      }\n    } else {\n      window.addEventListener(\"mousemove\", onMove, options);\n      window.addEventListener(\"blur\", onCancel, options);\n      window.addEventListener(\"mouseup\", onCancel, options);\n    }\n  }\n  static stop() {\n    var _a3;\n    (_a3 = _PointerTracker.controller) == null ? void 0 : _a3.abort();\n    _PointerTracker.controller = void 0;\n    if (typeof _PointerTracker.pointerId === \"number\") {\n      _PointerTracker.element.releasePointerCapture(_PointerTracker.pointerId);\n      _PointerTracker.pointerId = void 0;\n    }\n  }\n};\nfunction isPointerEvent(evt) {\n  return evt !== null && globalThis.PointerEvent !== void 0 && evt instanceof PointerEvent;\n}\nfunction onPointerDown(mathfield, evt) {\n  var _a3;\n  if (evt.buttons > 1) return;\n  mathfield.atomBoundsCache = /* @__PURE__ */ new Map();\n  const that = mathfield;\n  let anchor;\n  let trackingPointer = false;\n  let trackingWords = false;\n  let dirty = \"none\";\n  let scrollLeft = false;\n  let scrollRight = false;\n  const anchorX = evt.clientX;\n  const anchorY = evt.clientY;\n  const anchorTime = Date.now();\n  const field = that.field;\n  const scrollInterval = setInterval(() => {\n    if (scrollLeft) field.scroll({ top: 0, left: field.scrollLeft - 16 });\n    else if (scrollRight) field.scroll({ top: 0, left: field.scrollLeft + 16 });\n  }, 32);\n  function endPointerTracking() {\n    PointerTracker.stop();\n    trackingPointer = false;\n    clearInterval(scrollInterval);\n    mathfield.element.classList.remove(\"tracking\");\n    if (evt) evt.preventDefault();\n  }\n  function onPointerMove(evt2) {\n    if (!that.hasFocus()) {\n      endPointerTracking();\n      return;\n    }\n    const x = evt2.clientX;\n    const y = evt2.clientY;\n    const hysteresis = isPointerEvent(evt2) && evt2.pointerType === \"touch\" ? 20 : 5;\n    if (Date.now() < anchorTime + 500 && Math.abs(anchorX - x) < hysteresis && Math.abs(anchorY - y) < hysteresis) {\n      evt2.preventDefault();\n      evt2.stopPropagation();\n      return;\n    }\n    const fieldBounds = field.getBoundingClientRect();\n    scrollRight = x > fieldBounds.right;\n    scrollLeft = x < fieldBounds.left;\n    let actualAnchor = anchor;\n    if (isPointerEvent(evt2)) {\n      if (!evt2.isPrimary) {\n        actualAnchor = offsetFromPoint(that, evt2.clientX, evt2.clientY, {\n          bias: 0\n        });\n      }\n    }\n    const focus = offsetFromPoint(that, x, y, {\n      bias: x <= anchorX ? x === anchorX ? 0 : -1 : 1\n    });\n    if (actualAnchor >= 0 && focus >= 0) {\n      that.model.extendSelectionTo(actualAnchor, focus);\n      requestUpdate(mathfield);\n    }\n    if (trackingWords) selectGroup(that.model);\n  }\n  if (gLastTap && Math.abs(gLastTap.x - anchorX) < 5 && Math.abs(gLastTap.y - anchorY) < 5 && Date.now() < gLastTap.time + 500) {\n    gTapCount += 1;\n    gLastTap.time = anchorTime;\n  } else {\n    gLastTap = {\n      x: anchorX,\n      y: anchorY,\n      time: anchorTime\n    };\n    gTapCount = 1;\n  }\n  const bounds = field.getBoundingClientRect();\n  if (anchorX >= bounds.left && anchorX <= bounds.right && anchorY >= bounds.top && anchorY <= bounds.bottom) {\n    mathfield.flushInlineShortcutBuffer();\n    anchor = offsetFromPoint(mathfield, anchorX, anchorY, {\n      bias: 0\n    });\n    if (anchor !== mathfield.model.anchor) {\n      mathfield.defaultStyle = {};\n      mathfield.styleBias = \"left\";\n    }\n    if (anchor >= 0) {\n      mathfield.element.classList.add(\"tracking\");\n      if (evt.shiftKey) {\n        const wasCollapsed = mathfield.model.selectionIsCollapsed;\n        mathfield.model.extendSelectionTo(mathfield.model.anchor, anchor);\n        if (acceptCommandSuggestion(mathfield.model) || wasCollapsed)\n          dirty = \"all\";\n        else dirty = \"selection\";\n      } else if (mathfield.model.at(anchor).type === \"placeholder\") {\n        mathfield.model.setSelection(anchor - 1, anchor);\n        dirty = \"selection\";\n      } else if (((_a3 = mathfield.model.at(anchor).rightSibling) == null ? void 0 : _a3.type) === \"placeholder\") {\n        mathfield.model.setSelection(anchor, anchor + 1);\n        dirty = \"selection\";\n      } else {\n        mathfield.model.position = anchor;\n        if (acceptCommandSuggestion(mathfield.model)) dirty = \"all\";\n        else dirty = \"selection\";\n      }\n      if (evt.detail === 3 || gTapCount > 2) {\n        endPointerTracking();\n        if (evt.detail === 3 || gTapCount === 3) {\n          mathfield.model.selection = {\n            ranges: [[0, mathfield.model.lastOffset]]\n          };\n          dirty = \"all\";\n        }\n      } else if (!trackingPointer) {\n        trackingPointer = true;\n        PointerTracker.start(field, evt, onPointerMove, endPointerTracking);\n        if (evt.detail === 2 || gTapCount === 2) {\n          trackingWords = true;\n          selectGroup(mathfield.model);\n          dirty = \"all\";\n        }\n      }\n    }\n    if (!mathfield.hasFocus()) {\n      dirty = \"none\";\n      mathfield.focus({ preventScroll: true });\n    }\n  } else gLastTap = null;\n  mathfield.stopCoalescingUndo();\n  if (dirty !== \"none\") {\n    if (mathfield.model.selectionIsCollapsed) dirty = \"all\";\n    requestUpdate(mathfield);\n  }\n  evt.preventDefault();\n}\nfunction distance(x, y, r) {\n  if (x >= r.left && x <= r.right && y >= r.top && y <= r.bottom) return 0;\n  const dx = x - (r.left + r.right) / 2;\n  const dy = y - (r.top + r.bottom) / 2;\n  return dx * dx + dy * dy;\n}\nfunction nearestAtomFromPointRecursive(mathfield, cache, atom, x, y) {\n  if (!atom.id) return [Infinity, null];\n  if (cache.has(atom.id)) return cache.get(atom.id);\n  const bounds = getAtomBounds(mathfield, atom);\n  if (!bounds) return [Infinity, null];\n  let result = [\n    Infinity,\n    null\n  ];\n  if (atom.hasChildren && !atom.captureSelection && x >= bounds.left && x <= bounds.right) {\n    for (const child of atom.children) {\n      const r = nearestAtomFromPointRecursive(mathfield, cache, child, x, y);\n      if (r[0] <= result[0]) result = r;\n    }\n  }\n  if (!result[1]) result = [distance(x, y, bounds), atom];\n  cache.set(atom.id, result);\n  return result;\n}\nfunction nearestAtomFromPoint(mathfield, x, y) {\n  const [, atom] = nearestAtomFromPointRecursive(\n    mathfield,\n    /* @__PURE__ */ new Map(),\n    mathfield.model.root,\n    x,\n    y\n  );\n  return atom;\n}\nfunction offsetFromPoint(mathfield, x, y, options) {\n  var _a3;\n  const bounds = mathfield.field.querySelector(\".ML__latex\").getBoundingClientRect();\n  if (!bounds) return 0;\n  if (x > bounds.right || y > bounds.bottom + 8)\n    return mathfield.model.lastOffset;\n  if (x < bounds.left || y < bounds.top - 8) return 0;\n  options = options != null ? options : {};\n  options.bias = (_a3 = options.bias) != null ? _a3 : 0;\n  let atom = nearestAtomFromPoint(mathfield, x, y);\n  const parents = [];\n  let parent = atom;\n  while (parent) {\n    parents.unshift(parent);\n    parent = parent.parent;\n  }\n  for (const x2 of parents) {\n    if (x2.captureSelection) {\n      atom = x2;\n      break;\n    }\n  }\n  let result = mathfield.model.offsetOf(atom);\n  if (result < 0) return -1;\n  if (atom.leftSibling) {\n    if (options.bias === 0 && atom.type !== \"placeholder\") {\n      const bounds2 = getAtomBounds(mathfield, atom);\n      if (bounds2 && x < (bounds2.left + bounds2.right) / 2)\n        result = mathfield.model.offsetOf(atom.leftSibling);\n    } else if (options.bias < 0)\n      result = mathfield.model.offsetOf(atom.leftSibling);\n  }\n  return result;\n}\n\n// src/editor-mathfield/mode-editor-math.ts\nvar MathModeEditor = class extends ModeEditor {\n  constructor() {\n    super(\"math\");\n  }\n  onPaste(mathfield, data) {\n    if (!data) return false;\n    if (!mathfield.model.contentWillChange({\n      data: typeof data === \"string\" ? data : null,\n      dataTransfer: typeof data === \"string\" ? null : data,\n      inputType: \"insertFromPaste\"\n    }))\n      return false;\n    let text = \"\";\n    let format = \"auto\";\n    let json = typeof data !== \"string\" ? data.getData(\"application/json+mathlive\") : \"\";\n    if (json) {\n      try {\n        const atomJson = JSON.parse(json);\n        if (atomJson && Array.isArray(atomJson)) {\n          mathfield.snapshot();\n          const atoms = fromJson(atomJson);\n          const { model } = mathfield;\n          if (!model.selectionIsCollapsed)\n            model.deleteAtoms(range(model.selection));\n          const cursor = model.at(model.position);\n          if (cursor.parent instanceof ArrayAtom) {\n            console.assert(cursor.parentBranch !== void 0);\n            const columns = [];\n            let buffer = [];\n            if (atoms[0].type === \"first\") atoms.shift();\n            if (atoms[atoms.length - 1].type === \"first\") atoms.pop();\n            for (const atom of atoms) {\n              if (atom.type === \"first\" && buffer.length > 0) {\n                columns.push(buffer);\n                buffer = [atom];\n              } else buffer.push(atom);\n            }\n            if (buffer.length > 0) columns.push(buffer);\n            let currentRow = Number(cursor.parentBranch[0]);\n            let currentColumn = Number(cursor.parentBranch[1]);\n            const maxColumns = cursor.parent.maxColumns;\n            while (cursor.parent.colCount - currentColumn < columns.length && cursor.parent.colCount < maxColumns)\n              cursor.parent.addColumn();\n            cursor.parent.addChildrenAfter(columns[0], cursor);\n            for (let i = 1; i < columns.length; i++) {\n              currentColumn++;\n              if (currentColumn >= maxColumns) {\n                currentColumn = 0;\n                cursor.parent.addRowAfter(currentRow);\n                currentRow++;\n              }\n              cursor.parent.setCell(currentRow, currentColumn, columns[i]);\n            }\n          } else {\n            cursor.parent.addChildrenAfter(\n              atoms.filter((a) => a.type !== \"first\"),\n              cursor\n            );\n          }\n          model.position = model.offsetOf(atoms[atoms.length - 1]);\n          model.contentDidChange({ inputType: \"insertFromPaste\" });\n          requestUpdate(mathfield);\n          return true;\n        }\n      } catch (e) {\n      }\n    }\n    json = typeof data !== \"string\" ? data.getData(\"application/json\") : \"\";\n    if (json && globalThis.MathfieldElement.computeEngine) {\n      try {\n        const expr = JSON.parse(json);\n        if (typeof expr === \"object\" && \"latex\" in expr && expr.latex)\n          text = expr.latex;\n        if (!text) {\n          const box = globalThis.MathfieldElement.computeEngine.box(expr);\n          if (box && !box.has(\"Error\")) text = box.latex;\n        }\n        if (!text) format = \"latex\";\n      } catch (e) {\n      }\n    }\n    if (!text && typeof data !== \"string\") {\n      text = data.getData(\"application/x-latex\");\n      if (text) format = \"latex\";\n    }\n    if (!text)\n      text = typeof data === \"string\" ? data : data.getData(\"text/plain\");\n    if (text) {\n      let wasLatex;\n      [wasLatex, text] = trimModeShiftCommand(text);\n      if (format === \"auto\" && wasLatex) format = \"latex\";\n      mathfield.stopCoalescingUndo();\n      mathfield.stopRecording();\n      if (this.insert(mathfield.model, text, { format })) {\n        mathfield.startRecording();\n        mathfield.snapshot(\"paste\");\n        requestUpdate(mathfield);\n      }\n      mathfield.startRecording();\n      return true;\n    }\n    return false;\n  }\n  insert(model, input, options) {\n    var _a3, _b3;\n    let data = typeof input === \"string\" ? input : (_b3 = (_a3 = globalThis.MathfieldElement.computeEngine) == null ? void 0 : _a3.box(input).latex) != null ? _b3 : \"\";\n    if (!options.silenceNotifications && !model.contentWillChange({ data, inputType: \"insertText\" }))\n      return false;\n    if (!options.insertionMode) options.insertionMode = \"replaceSelection\";\n    if (!options.selectionMode) options.selectionMode = \"placeholder\";\n    if (!options.format) options.format = \"auto\";\n    const { silenceNotifications } = model;\n    if (options.silenceNotifications) model.silenceNotifications = true;\n    const contentWasChanging = model.silenceNotifications;\n    model.silenceNotifications = true;\n    const args = {\n      \"?\": \"\\\\placeholder{}\",\n      \"@\": \"\\\\placeholder{}\"\n    };\n    args[0] = options.insertionMode === \"replaceAll\" ? \"\" : model.getValue(model.selection, \"latex-unstyled\");\n    if (options.insertionMode === \"replaceSelection\")\n      model.deleteAtoms(range(model.selection));\n    else if (options.insertionMode === \"replaceAll\") model.deleteAtoms();\n    else if (options.insertionMode === \"insertBefore\")\n      model.collapseSelection(\"backward\");\n    else if (options.insertionMode === \"insertAfter\")\n      model.collapseSelection(\"forward\");\n    if (!model.at(model.position).isLastSibling && model.at(model.position + 1).type === \"placeholder\") {\n      model.deleteAtoms([model.position, model.position + 1]);\n    } else if (model.at(model.position).type === \"placeholder\") {\n      model.deleteAtoms([model.position - 1, model.position]);\n    }\n    let implicitArgumentOffset = -1;\n    if (args[0]) {\n      args[\"@\"] = args[0];\n    } else if (typeof input === \"string\" && /(^|[^\\\\])#@/.test(input)) {\n      implicitArgumentOffset = getImplicitArgOffset(model);\n      if (implicitArgumentOffset >= 0) {\n        args[\"@\"] = model.getValue(\n          implicitArgumentOffset,\n          model.position,\n          \"latex\"\n        );\n      }\n    }\n    if (!args[0]) args[0] = args[\"?\"];\n    let usedArg = false;\n    const argFunction = (arg) => {\n      usedArg = true;\n      return args[arg];\n    };\n    let [format, newAtoms] = convertStringToAtoms(\n      model,\n      input,\n      argFunction,\n      options\n    );\n    if (!newAtoms) return false;\n    const insertingFraction = newAtoms.length === 1 && newAtoms[0].type === \"genfrac\";\n    if (insertingFraction && implicitArgumentOffset >= 0 && typeof model.mathfield.options.isImplicitFunction === \"function\" && model.mathfield.options.isImplicitFunction(\n      model.at(model.position).command\n    )) {\n      args[\"@\"] = args[\"?\"];\n      usedArg = false;\n      [format, newAtoms] = convertStringToAtoms(\n        model,\n        input,\n        argFunction,\n        options\n      );\n    } else if (implicitArgumentOffset >= 0) {\n      model.deleteAtoms([implicitArgumentOffset, model.position]);\n    }\n    const { parent } = model.at(model.position);\n    const hadEmptyBody = parent.hasEmptyBranch(\"body\");\n    if (insertingFraction && format !== \"latex\" && model.mathfield.options.removeExtraneousParentheses && parent instanceof LeftRightAtom && parent.leftDelim === \"(\" && hadEmptyBody) {\n      const newParent = parent.parent;\n      const branch = parent.parentBranch;\n      newParent.removeChild(parent);\n      newParent.setChildren(newAtoms, branch);\n    }\n    const cursor = model.at(model.position);\n    cursor.parent.addChildrenAfter(newAtoms, cursor);\n    if (format === \"latex\" && typeof input === \"string\") {\n      if ((parent == null ? void 0 : parent.type) === \"root\" && hadEmptyBody && !usedArg)\n        parent.verbatimLatex = input;\n    }\n    model.silenceNotifications = contentWasChanging;\n    const lastNewAtom = newAtoms[newAtoms.length - 1];\n    if (options.selectionMode === \"placeholder\") {\n      const placeholder = newAtoms.flatMap((x) => [x, ...x.children]).find((x) => x.type === \"placeholder\");\n      if (placeholder) {\n        const placeholderOffset = model.offsetOf(placeholder);\n        model.setSelection(placeholderOffset - 1, placeholderOffset);\n        model.announce(\"move\");\n      } else if (lastNewAtom) {\n        model.position = model.offsetOf(lastNewAtom);\n      }\n    } else if (options.selectionMode === \"before\") {\n    } else if (options.selectionMode === \"after\") {\n      if (lastNewAtom) model.position = model.offsetOf(lastNewAtom);\n    } else if (options.selectionMode === \"item\")\n      model.setSelection(model.anchor, model.offsetOf(lastNewAtom));\n    model.contentDidChange({ data, inputType: \"insertText\" });\n    model.silenceNotifications = silenceNotifications;\n    return true;\n  }\n};\nfunction convertStringToAtoms(model, s, args, options) {\n  var _a3;\n  let format = void 0;\n  let result = [];\n  if (typeof s !== \"string\" || options.format === \"math-json\") {\n    const ce = globalThis.MathfieldElement.computeEngine;\n    if (!ce) return [\"math-json\", []];\n    [format, s] = [\"latex\", ce.box(s).latex];\n    result = parseLatex(s, { context: model.mathfield.context });\n  } else if (typeof s === \"string\" && options.format === \"ascii-math\") {\n    [format, s] = parseMathString(s, {\n      format: \"ascii-math\",\n      inlineShortcuts: model.mathfield.options.inlineShortcuts\n    });\n    result = parseLatex(s, { context: model.mathfield.context });\n    if (format !== \"latex\" && model.mathfield.options.removeExtraneousParentheses)\n      result = result.map((x) => removeExtraneousParenthesis(x));\n  } else if (options.format === \"auto\" || ((_a3 = options.format) == null ? void 0 : _a3.startsWith(\"latex\"))) {\n    if (options.format === \"auto\") {\n      [format, s] = parseMathString(s, {\n        format: \"auto\",\n        inlineShortcuts: model.mathfield.options.inlineShortcuts\n      });\n    }\n    if (options.format === \"latex\") [, s] = trimModeShiftCommand(s);\n    result = parseLatex(s, {\n      context: model.mathfield.context,\n      args\n    });\n    if (options.format !== \"latex\" && model.mathfield.options.removeExtraneousParentheses)\n      result = result.map((x) => removeExtraneousParenthesis(x));\n  }\n  applyStyleToUnstyledAtoms(result, options.style);\n  return [format != null ? format : \"latex\", result];\n}\nfunction removeExtraneousParenthesis(atom) {\n  var _a3;\n  if (atom instanceof LeftRightAtom && atom.leftDelim !== \"(\" && atom.rightDelim === \")\") {\n    const children = (_a3 = atom.body) == null ? void 0 : _a3.filter((x) => x.type !== \"first\");\n    if ((children == null ? void 0 : children.length) === 1 && children[0].type === \"genfrac\")\n      return children[0];\n  }\n  for (const branch of atom.branches) {\n    if (!atom.hasEmptyBranch(branch)) {\n      atom.setChildren(\n        atom.branch(branch).map((x) => removeExtraneousParenthesis(x)),\n        branch\n      );\n    }\n  }\n  if (atom instanceof ArrayAtom) {\n    atom.forEachCell((cell, row, column) => {\n      atom.setCell(\n        row,\n        column,\n        cell.map((x) => removeExtraneousParenthesis(x))\n      );\n    });\n  }\n  return atom;\n}\nfunction getImplicitArgOffset(model) {\n  let atom = model.at(model.position);\n  if (atom.mode === \"text\") {\n    while (!atom.isFirstSibling && atom.mode === \"text\")\n      atom = atom.leftSibling;\n    return model.offsetOf(atom);\n  }\n  const atomAtCursor = atom;\n  let afterDelim = false;\n  if (atom.type === \"mclose\") {\n    const delim = LEFT_DELIM[atom.value];\n    while (!atom.isFirstSibling && !(atom.type === \"mopen\" && atom.value === delim))\n      atom = atom.leftSibling;\n    if (!atom.isFirstSibling) atom = atom.leftSibling;\n    afterDelim = true;\n  } else if (atom.type === \"leftright\") {\n    atom = atom.leftSibling;\n    afterDelim = true;\n  }\n  if (afterDelim) {\n    while (!atom.isFirstSibling && (atom.isFunction || isImplicitArg(atom)))\n      atom = atom.leftSibling;\n  } else {\n    const delimiterStack = [];\n    while (!atom.isFirstSibling && (isImplicitArg(atom) || delimiterStack.length > 0)) {\n      if (atom.type === \"mclose\") delimiterStack.unshift(atom.value);\n      if (atom.type === \"mopen\" && delimiterStack.length > 0 && atom.value === LEFT_DELIM[delimiterStack[0]])\n        delimiterStack.shift();\n      atom = atom.leftSibling;\n    }\n  }\n  if (atomAtCursor === atom) return -1;\n  return model.offsetOf(atom);\n}\nfunction isImplicitArg(atom) {\n  if (atom.isDigit()) return true;\n  if (atom.type && /^(mord|surd|subsup|leftright|mop|mclose)$/.test(atom.type)) {\n    if (atom.type === \"extensible-symbol\") return false;\n    return true;\n  }\n  return false;\n}\nnew MathModeEditor();\n\n// src/editor-mathfield/mode-editor-text.ts\nvar TextModeEditor = class extends ModeEditor {\n  constructor() {\n    super(\"text\");\n  }\n  onPaste(mathfield, data) {\n    if (!data) return false;\n    const text = typeof data === \"string\" ? data : data.getData(\"text/plain\");\n    if (text && mathfield.model.contentWillChange({\n      inputType: \"insertFromPaste\",\n      data: text\n    })) {\n      mathfield.stopCoalescingUndo();\n      mathfield.stopRecording();\n      if (this.insert(mathfield.model, text)) {\n        mathfield.model.contentDidChange({ inputType: \"insertFromPaste\" });\n        mathfield.startRecording();\n        mathfield.snapshot(\"paste\");\n        requestUpdate(mathfield);\n      }\n      mathfield.startRecording();\n      return true;\n    }\n    return false;\n  }\n  insert(model, text, options = {}) {\n    if (!model.contentWillChange({ data: text, inputType: \"insertText\" }))\n      return false;\n    if (!options.insertionMode) options.insertionMode = \"replaceSelection\";\n    if (!options.selectionMode) options.selectionMode = \"placeholder\";\n    if (!options.format) options.format = \"auto\";\n    const { silenceNotifications } = model;\n    if (options.silenceNotifications) model.silenceNotifications = true;\n    const contentWasChanging = model.silenceNotifications;\n    model.silenceNotifications = true;\n    if (options.insertionMode === \"replaceSelection\" && !model.selectionIsCollapsed)\n      model.deleteAtoms(range(model.selection));\n    else if (options.insertionMode === \"replaceAll\") {\n      model.root.setChildren([], \"body\");\n      model.position = 0;\n    } else if (options.insertionMode === \"insertBefore\")\n      model.collapseSelection(\"backward\");\n    else if (options.insertionMode === \"insertAfter\")\n      model.collapseSelection(\"forward\");\n    const newAtoms = convertStringToAtoms2(text, model.mathfield.context);\n    applyStyleToUnstyledAtoms(newAtoms, options.style);\n    if (!newAtoms) return false;\n    const cursor = model.at(model.position);\n    const lastNewAtom = cursor.parent.addChildrenAfter(newAtoms, cursor);\n    model.silenceNotifications = contentWasChanging;\n    if (options.selectionMode === \"before\") {\n    } else if (options.selectionMode === \"item\")\n      model.setSelection(model.anchor, model.offsetOf(lastNewAtom));\n    else if (lastNewAtom) model.position = model.offsetOf(lastNewAtom);\n    model.contentDidChange({ data: text, inputType: \"insertText\" });\n    model.silenceNotifications = silenceNotifications;\n    return true;\n  }\n};\nfunction convertStringToAtoms2(s, context) {\n  s = s.replace(/\\\\/g, \"\\\\textbackslash \");\n  s = s.replace(/#/g, \"\\\\#\");\n  s = s.replace(/\\$/g, \"\\\\$\");\n  s = s.replace(/%/g, \"\\\\%\");\n  s = s.replace(/&/g, \"\\\\&\");\n  s = s.replace(/_/g, \"\\\\_\");\n  s = s.replace(/{/g, \"\\\\textbraceleft \");\n  s = s.replace(/}/g, \"\\\\textbraceright \");\n  s = s.replace(/lbrace/g, \"\\\\textbraceleft \");\n  s = s.replace(/rbrace/g, \"\\\\textbraceright \");\n  s = s.replace(/\\^/g, \"\\\\textasciicircum \");\n  s = s.replace(/~/g, \"\\\\textasciitilde \");\n  s = s.replace(/£/g, \"\\\\textsterling \");\n  return parseLatex(s, { context, parseMode: \"text\" });\n}\nnew TextModeEditor();\n\n// src/virtual-keyboard/mathfield-proxy.ts\nfunction makeProxy(mf) {\n  return {\n    value: mf.model.getValue(),\n    selectionIsCollapsed: mf.model.selectionIsCollapsed,\n    canUndo: mf.canUndo(),\n    canRedo: mf.canRedo(),\n    style: commonStyle(mf.model),\n    mode: mf.model.mode\n  };\n}\nfunction commonStyle(model) {\n  var _a3;\n  if (model.selectionIsCollapsed) return (_a3 = model.at(model.position)) == null ? void 0 : _a3.style;\n  const selectedAtoms = model.getAtoms(model.selection);\n  if (selectedAtoms.length === 0) return {};\n  const style = __spreadValues({}, selectedAtoms[0].style);\n  for (const atom of selectedAtoms) {\n    for (const [key, value] of Object.entries(atom.style))\n      if (style[key] !== value) delete style[key];\n  }\n  return style;\n}\n\n// src/editor/environment-popover.ts\nvar padding = 4;\nvar radius = 20;\nvar paddedWidth = 2 * (radius + padding);\nvar newPlus = (x, y) => `\n  <line x1=\"${x + radius}\" y1=\"${y + radius}\" \n    x2=\"${x > y ? x + radius : 7 * radius + 10 * padding}\" \n    y2=\"${x < y ? y + radius : 7 * radius + 10 * padding}\"/>\n  <svg id=\"plus\" viewBox=\"0 0 40 40\" x=\"${x}\" y=\"${y}\" width=\"40\" height=\"40\">\n    <circle class=\"cls-2\" cx=\"20\" cy=\"20\" r=\"20\"/>\n    <path class=\"font\" d=\"m33.33,20c0,1.84-1.49,3.34-3.33,3.34h-6.67v6.66c0,1.84-1.49,3.34-3.33,3.34s-3.34-1.5-3.34-3.34v-6.66h-6.66c-1.84,0-3.34-1.5-3.34-3.34s1.5-3.33,3.34-3.33h6.66v-6.67c0-1.84,1.5-3.33,3.34-3.33s3.33,1.49,3.33,3.33v6.67h6.67c1.84,0,3.33,1.49,3.33,3.33Z\"/>\n  </svg>`;\nvar newMinus = (x, y) => `\n  <line x1=\"${x + radius}\" y1=\"${y + radius}\" \n    x2=\"${x > y ? x + radius : 7 * radius + 10 * padding}\" \n    y2=\"${x < y ? y + radius : 7 * radius + 10 * padding}\"/>\n  <svg id=\"minus\" viewBox=\"0 0 40 40\" x=\"${x}\" y=\"${y}\" width=\"40\" height=\"40\">\n    <circle class=\"cls-2\" cx=\"20\" cy=\"20\" r=\"20\"/>\n    <path class=\"font\" d=\"m33.33,20c0,1.84-1.49,3.33-3.33,3.33H10c-1.84,0-3.34-1.49-3.34-3.33s1.5-3.34,3.34-3.34h20c1.84,0,3.33,1.5,3.33,3.34Z\"/>\n  </svg>`;\nvar newArrow = (x, y, theta) => `\n  <svg id=\"arrow\" viewBox=\"0 0 40 40\" x=\"${x}\" y=\"${y}\" width=\"40\" height=\"40\">\n    <circle class=\"cls-2\" cx=\"20\" cy=\"20\" r=\"20\"/>\n    <g transform=\"rotate(${theta})\" transform-origin=\"20 20\">\n      <path class=\"font\" d=\"m17.7,7.23h4.6c.52,0,.94.42.94.94v13.82c0,.52.42.94.94.94h3.39c.83,0,1.25,1.01.66,1.6l-7.56,7.56c-.37.37-.96.37-1.32,0l-7.56-7.56c-.59-.59-.17-1.6.66-1.6h3.39c.52,0,.94-.42.94-.94v-13.82c0-.52.42-.94.94-.94Z\"/>\n    </g>  \n  </svg>`;\nvar controllerSvg = `\n<svg class=\"MLEP__array-buttons\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" \nviewBox=\n\"-2 -2 ${8 * radius + 10 * padding + 5} ${8 * radius + 10 * padding + 5}\">\n  <rect \n      class=\"MLEP__array-insert-background rows\"\n      x=\"0\" \n      y=\"${paddedWidth + padding}\" \n      height=\"${3 * paddedWidth}\" \n      width=\"${paddedWidth}\" \n      rx=\"${paddedWidth / 2}\"/>\n      <rect \n      class=\"MLEP__array-insert-background columns\"\n      x=\"${paddedWidth + padding}\" \n      y=\"0\" \n      height=\"${paddedWidth}\" \n      width=\"${3 * paddedWidth}\" \n      rx=\"${paddedWidth / 2}\"/>\n  <g data-command='\"moveDown\"'>\n  ${newArrow(2 * (padding + paddedWidth), 2 * padding + 3 * paddedWidth, 0)}\n  </g>\n  <g data-command='\"moveUp\"'>\n  ${newArrow(2 * (padding + paddedWidth), 2 * padding + paddedWidth, 180)}\n  </g>\n  <g data-command='\"moveToNextWord\"'>\n  ${newArrow(2 * padding + 3 * paddedWidth, 2 * (padding + paddedWidth), -90)}\n  </g>\n  <g data-command='\"moveToPreviousWord\"'>\n  ${newArrow(2 * padding + paddedWidth, 2 * (padding + paddedWidth), 90)}\n  </g>\n  <g>\n\n  <g data-command='\"addColumnBefore\"'>\n  ${newPlus(2 * padding + paddedWidth, padding)}\n  </g>\n  <g data-command='\"removeColumn\"'>\n  ${newMinus(2 * padding + 2 * paddedWidth, padding)}\n  </g>\n  <g data-command='\"addColumnAfter\"'>\n  ${newPlus(2 * padding + 3 * paddedWidth, padding)}\n  </g>\n  <g data-command='\"addRowBefore\"'>\n  ${newPlus(padding, 2 * padding + paddedWidth)}\n  </g>\n  <g data-command='\"removeRow\"'>\n  ${newMinus(padding, 2 * padding + 2 * paddedWidth)}\n  </g>\n  <g data-command='\"addRowAfter\"'>\n    ${newPlus(padding, 2 * padding + 3 * paddedWidth)}\n  </g>\n</svg>`;\nvar matrix = (className) => `\n<svg id=\"matrix\" class=\"${className}\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 28 24\" \n  data-command='[\"setEnvironment\",\"matrix\"]'>\n  <rect class=\"cls-1\" width=\"28\" height=\"24\"/>\n  <circle cx=\"10\" cy=\"8\" r=\"1\"/>\n  <circle cx=\"14\" cy=\"12\" r=\"1\"/>\n  <circle cx=\"18\" cy=\"16\" r=\"1\"/></svg>`;\nvar pmatrix = (className) => `\n<svg id=\"pmatrix\" class=\"${className}\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 28 24\" \ndata-command='[\"setEnvironment\",\"pmatrix\"]'>\n  <rect class=\"cls-1\" width=\"28\" height=\"24\"/>\n  <path class=\"cls-2\" d=\"m6,4c-3.96,4.6-3.96,11.4,0,16\"/>\n  <path class=\"cls-2\" d=\"m22,4c3.96,4.6,3.96,11.4,0,16\"/>\n  <circle cx=\"10\" cy=\"8\" r=\"1\"/>\n  <circle cx=\"14\" cy=\"12\" r=\"1\"/>\n  <circle cx=\"18\" cy=\"16\" r=\"1\"/></svg>`;\nvar Bmatrix = (className) => `\n<svg id=\"Bmatrix\" class=\"${className}\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 28 24\" \n  data-command='[\"setEnvironment\",\"Bmatrix\"]'>\n  <rect class=\"cls-1\" width=\"28\" height=\"24\"/>\n  <path class=\"cls-2\" d=\"m6,4c-1.1,0-2,.9-2,2v3c0,1.66-.9,3-2,3,1.1,0,2,1.34,2,3v3c0,1.1.9,2,2,2\"/>\n  <path class=\"cls-2\" d=\"m22,4c1.1,0,2,.9,2,2v3c0,1.66.9,3,2,3-1.1,0-2,1.34-2,3v3c0,1.1-.9,2-2,2\"/>\n  <circle cx=\"10\" cy=\"8\" r=\"1\"/>\n  <circle cx=\"14\" cy=\"12\" r=\"1\"/>\n  <circle cx=\"18\" cy=\"16\" r=\"1\"/>\n</svg>`;\nvar bmatrix = (className) => `\n<svg id=\"bmatrix\" class=\"${className}\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 28 24\" \n  data-command='[\"setEnvironment\",\"bmatrix\"]'>\n  <rect class=\"cls-1\" width=\"28\" height=\"24\"/>\n  <path class=\"cls-2\" d=\"m6,4h-3v16h3\"/>\n  <path class=\"cls-2\" d=\"m22,4h3v16h-3\"/>\n  <circle cx=\"10\" cy=\"8\" r=\"1\"/>\n  <circle cx=\"14\" cy=\"12\" r=\"1\"/>\n  <circle cx=\"18\" cy=\"16\" r=\"1\"/>\n</svg>`;\nvar vmatrix = (className) => `\n<svg id=\"vmatrix\" class=\"${className}\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 28 24\" \n  data-command='[\"setEnvironment\",\"vmatrix\"]'>\n  <rect class=\"cls-1\" width=\"28\" height=\"24\"/>\n  <circle cx=\"10\" cy=\"8\" r=\"1\"/>\n  <circle cx=\"14\" cy=\"12\" r=\"1\"/>\n  <circle cx=\"18\" cy=\"16\" r=\"1\"/>\n  <line class=\"cls-2\" x1=\"4\" y1=\"4\" x2=\"4\" y2=\"20\"/>\n  <line class=\"cls-2\" x1=\"24\" y1=\"4\" x2=\"24\" y2=\"20\"/>\n</svg>`;\nvar Vmatrix = (className) => `\n<svg id=\"Vmatrix\" class=\"${className}\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"-3.5 -3 35 30\" \n  data-command='[\"setEnvironment\",\"Vmatrix\"]'>\n  <rect class=\"cls-1\" width=\"28\" height=\"24\"/>\n  <circle cx=\"10\" cy=\"8\" r=\"1\"/>\n  <circle cx=\"14\" cy=\"12\" r=\"1\"/>\n  <circle cx=\"18\" cy=\"16\" r=\"1\"/>\n  <line class=\"cls-2\" x1=\"6\" y1=\"4\" x2=\"6\" y2=\"20\"/>\n  <line class=\"cls-2\" x1=\"22\" y1=\"4\" x2=\"22\" y2=\"20\"/>\n  <line class=\"cls-2\" x1=\"2\" y1=\"4\" x2=\"2\" y2=\"20\"/>\n  <line class=\"cls-2\" x1=\"26\" y1=\"4\" x2=\"26\" y2=\"20\"/>\n</svg>`;\nvar cases2 = (className) => `\n<svg id=\"cases\" class=\"${className}\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 28 24\" \n  data-command='[\"setEnvironment\",\"cases\"]'>\n  <rect class=\"cls-1\" width=\"28\" height=\"24\"/>\n  <path class=\"cls-2\" d=\"m10,4c-1.1,0-2,.9-2,2v3c0,1.66-.9,3-2,3,1.1,0,2,1.34,2,3v3c0,1.1.9,2,2,2\"/>\n  <circle cx=\"13\" cy=\"8\" r=\"1\"/>\n  <circle cx=\"13\" cy=\"16\" r=\"1\"/>\n  <circle cx=\"21\" cy=\"8\" r=\"1\"/>\n  <circle cx=\"21\" cy=\"16\" r=\"1\"/>\n</svg>`;\nvar rcases = (className) => `\n<svg id=\"rcases\" class=\"${className}\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 28 24\" \n  data-command='[\"setEnvironment\",\"rcases\"]'>\n  <rect class=\"cls-1\" width=\"28\" height=\"24\"/>\n  <path class=\"cls-2\" d=\"m18,20c1.1,0,2-.9,2-2v-3c0-1.66.9-3,2-3-1.1,0-2-1.34-2-3v-3c0-1.1-.9-2-2-2\"/>\n  <circle cx=\"15\" cy=\"8\" r=\"1\"/>\n  <circle cx=\"15\" cy=\"16\" r=\"1\"/>\n  <circle cx=\"7\" cy=\"8\" r=\"1\"/>\n  <circle cx=\"7\" cy=\"16\" r=\"1\"/>\n</svg>`;\nvar matrixButtons = { matrix, pmatrix, bmatrix, Bmatrix, vmatrix, Vmatrix };\nvar casesButtons = { cases: cases2, rcases, Bmatrix };\nfunction showEnvironmentPopover(mf) {\n  var _a3, _d2;\n  const array = (_a3 = mf.model.parentEnvironment) == null ? void 0 : _a3.array;\n  if (!array) return;\n  let columnCount = 0;\n  array.forEach((column) => {\n    if (!columnCount || column.length > columnCount)\n      columnCount = column.length;\n  });\n  let panel = document.getElementById(\"mathlive-environment-popover\");\n  if (!panel) {\n    panel = getSharedElement(\"mathlive-environment-popover\");\n    injectStylesheet(\"environment-popover\");\n    injectStylesheet(\"core\");\n    panel.setAttribute(\"aria-hidden\", \"true\");\n  }\n  let flexbox;\n  const possiblyExistentFlexbox = panel.querySelector(\n    \".MLEP__environment-controls\"\n  );\n  if (possiblyExistentFlexbox) flexbox = possiblyExistentFlexbox;\n  else {\n    flexbox = document.createElement(\"div\");\n    panel.innerHTML = \"\";\n    panel.appendChild(flexbox);\n  }\n  flexbox.className = \"MLEP__environment-controls\";\n  flexbox.style.display = \"flex\";\n  flexbox.style.width = \"100%\";\n  flexbox.style.height = \"100%\";\n  flexbox.style.boxSizing = \"border-box\";\n  flexbox.innerHTML = controllerSvg;\n  let delimiterOptions = [];\n  let activeDelimeter = \"\";\n  const environment = mf.model.parentEnvironment.environmentName;\n  if (isMatrixEnvironment(environment)) {\n    const normalizedEnvironment = normalizeMatrixName(environment);\n    activeDelimeter = matrixButtons[normalizedEnvironment](\"active\");\n    const _b3 = matrixButtons, { [normalizedEnvironment]: _ } = _b3, filteredDelimeters = __objRest(_b3, [__restKey(normalizedEnvironment)]);\n    delimiterOptions = Object.values(filteredDelimeters).map(\n      (f) => f(\"inactive\")\n    );\n  } else if (isCasesEnvironment(environment)) {\n    const normalizedEnvironment = normalizeCasesName(environment);\n    activeDelimeter = casesButtons[normalizedEnvironment](\"active\");\n    const _c2 = casesButtons, { [normalizedEnvironment]: _ } = _c2, filteredDelimeters = __objRest(_c2, [__restKey(normalizedEnvironment)]);\n    delimiterOptions = Object.values(filteredDelimeters).map(\n      (f) => f(\"inactive\")\n    );\n  } else if (isAlignEnvironment(environment)) {\n    activeDelimeter = matrixButtons[\"matrix\"](\"active\");\n    delimiterOptions = Object.values(casesButtons).map(\n      (f) => f(\"inactive\")\n    );\n  }\n  const delimiterControls = document.createElement(\"div\");\n  delimiterControls.className = \"MLEP__environment-delimiter-controls\";\n  delimiterControls.style.display = \"flex\";\n  delimiterControls.style.flexDirection = \"column\";\n  delimiterControls.innerHTML = `\n  <div class='MLEP__array-delimiter-options'>\n  ${activeDelimeter}\n  ${delimiterOptions.join(\"\")}\n  </div>`;\n  if (activeDelimeter) flexbox.appendChild(delimiterControls);\n  const arrayControls = flexbox.querySelectorAll(\n    \"[data-command]\"\n  );\n  arrayControls.forEach((control) => {\n    const commandString = control.dataset.command;\n    let command = commandString;\n    try {\n      command = JSON.parse(commandString);\n    } catch (e) {\n    }\n    control.addEventListener(\"mousedown\", (ev) => ev.preventDefault());\n    if (command)\n      control.addEventListener(\"click\", () => mf.executeCommand(command));\n  });\n  const position = (_d2 = mf.field) == null ? void 0 : _d2.getBoundingClientRect();\n  if (position) {\n    panel.style.top = `${window.scrollY + (position.top - panel.clientHeight - 15)}px`;\n    panel.style.left = `${position.left + 20}px`;\n    panel.classList.add(\"is-visible\");\n  }\n}\nfunction hideEnvironmentPopover() {\n  const panel = document.getElementById(\"mathlive-environment-popover\");\n  panel == null ? void 0 : panel.classList.remove(\"is-visible\");\n}\nfunction disposeEnvironmentPopover() {\n  if (!document.getElementById(\"mathlive-environment-popover\")) return;\n  releaseSharedElement(\"mathlive-environment-popover\");\n  releaseStylesheet(\"environment-popover\");\n  releaseStylesheet(\"core\");\n}\nfunction updateEnvironmentPopover(mf) {\n  if (!mf.hasFocus()) return;\n  let visible = false;\n  if (mf.model.mode === \"math\") {\n    const env = mf.model.parentEnvironment;\n    if (!!(env == null ? void 0 : env.array) && isTabularEnvironment(env.environmentName)) {\n      const policy = mf.options.environmentPopoverPolicy;\n      visible = policy === \"auto\" || policy === \"on\";\n    }\n  }\n  if (visible) showEnvironmentPopover(mf);\n  else hideEnvironmentPopover();\n}\nfunction normalizeMatrixName(environment) {\n  return environment.replace(\"*\", \"\");\n}\nfunction normalizeCasesName(environment) {\n  if (environment === \"dcases\")\n    return \"cases\";\n  return environment;\n}\n\n// src/ui/i18n/utils.ts\nfunction getComputedDir(element) {\n  const dir = getComputedStyle(element).direction;\n  return dir === \"ltr\" || dir === \"rtl\" ? dir : \"ltr\";\n}\n\n// src/ui/geometry/utils.ts\nfunction getEdge(bounds, position, direction) {\n  if (position === \"left\" || position === \"leading\" && direction === \"ltr\" || position === \"trailing\" && direction === \"rtl\")\n    return bounds.left;\n  return bounds.right;\n}\nfunction getEffectivePos(pos, length, placement, dir) {\n  if (placement === \"middle\") return pos - length / 2;\n  if (placement === \"start\" && dir === \"rtl\" || placement === \"end\" && dir === \"ltr\" || placement === \"top\" || placement === \"right\")\n    return Math.max(0, pos - length);\n  return pos;\n}\nfunction getOppositeEffectivePos(pos, length, placement, dir) {\n  if (placement === \"middle\") return pos - length / 2;\n  if (placement === \"start\" && dir === \"ltr\" || placement === \"end\" && dir === \"rtl\" || placement === \"top\" || placement === \"right\")\n    return pos;\n  return pos - length;\n}\nfunction fitInViewport(element, options) {\n  var _a3, _b3, _c2;\n  const dir = (_a3 = getComputedDir(element)) != null ? _a3 : \"ltr\";\n  element.style.position = \"fixed\";\n  element.style.left = \"\";\n  element.style.top = \"\";\n  element.style.right = \"\";\n  element.style.bottom = \"\";\n  element.style.height = \"\";\n  element.style.width = \"\";\n  const elementBounds = element.getBoundingClientRect();\n  const maxHeight = Number.isFinite(options.maxHeight) ? Math.min(options.maxHeight, window.innerHeight) : window.innerHeight;\n  let height = Math.min(maxHeight, (_b3 = options.height) != null ? _b3 : elementBounds.height);\n  let top = getEffectivePos(\n    options.location.y,\n    height,\n    options.verticalPos,\n    dir\n  );\n  if (top + height > window.innerHeight - 8) {\n    if (options.alternateLocation) {\n      top = getEffectivePos(\n        options.alternateLocation.y,\n        height,\n        options.verticalPos,\n        dir\n      );\n      if (top + height > window.innerHeight - 8) top = void 0;\n    } else top = void 0;\n  }\n  if (!Number.isFinite(top)) {\n    top = Math.max(8, window.innerHeight - 8 - height);\n    if (8 + height > window.innerHeight - 8) {\n      element.style.bottom = \"8px\";\n    }\n  }\n  height = Math.min(top + height, window.innerHeight - 8) - top;\n  const maxWidth = Number.isFinite(options.maxWidth) ? Math.min(options.maxWidth, window.innerWidth) : window.innerWidth;\n  let width = Math.min(maxWidth, (_c2 = options.width) != null ? _c2 : elementBounds.width);\n  let left = getEffectivePos(\n    options.location.x,\n    width,\n    options.horizontalPos,\n    dir\n  );\n  if (left + width > window.innerWidth - 8) {\n    if (options.alternateLocation) {\n      left = getOppositeEffectivePos(\n        options.alternateLocation.x,\n        width,\n        options.verticalPos,\n        dir\n      );\n      if (left + width > window.innerWidth - 8) left = void 0;\n    } else left = void 0;\n  }\n  if (!Number.isFinite(left)) {\n    left = Math.max(8, window.innerWidth - 8 - width);\n    if (8 + width > window.innerWidth - 8) {\n      element.style.right = \"8px\";\n    }\n  }\n  width = Math.min(left + width, window.innerWidth - 8) - left;\n  if (dir === \"rtl\") {\n    element.style.right = `${Math.ceil(\n      window.innerWidth - left - width\n    ).toString()}px`;\n  } else element.style.left = `${Math.ceil(left).toString()}px`;\n  element.style.top = `${Math.ceil(top).toString()}px`;\n  if (height !== elementBounds.height)\n    element.style.height = `${Math.ceil(height).toString()}px`;\n  if (width !== elementBounds.width)\n    element.style.width = `${Math.ceil(width).toString()}px`;\n}\nfunction distance2(p1, p2) {\n  return Math.hypot(p2.x - p1.x, p2.y - p1.y);\n}\n\n// src/public/ui-menu-types.ts\nfunction isSubmenu(item) {\n  return \"submenu\" in item;\n}\nfunction isCommand(item) {\n  return \"type\" in item && item.type === \"command\" || \"onMenuSelect\" in item || \"id\" in item;\n}\nfunction isDivider(item) {\n  return \"type\" in item && item.type === \"divider\";\n}\nfunction isHeading(item) {\n  return \"type\" in item && item.type === \"heading\";\n}\n\n// src/ui/icons/icons.ts\nvar ICON_CATALOG = {};\nfunction icon(name) {\n  let icon2 = ICON_CATALOG[name];\n  if (!icon2) {\n    let markup;\n    switch (name) {\n      case \"checkmark\":\n        markup = `<span aria-hidden=\"true\" class=\"ui-checkmark\"><svg  xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path fill=\"currentColor\" d=\"M435.848 83.466L172.804 346.51l-96.652-96.652c-4.686-4.686-12.284-4.686-16.971 0l-28.284 28.284c-4.686 4.686-4.686 12.284 0 16.971l133.421 133.421c4.686 4.686 12.284 4.686 16.971 0l299.813-299.813c4.686-4.686 4.686-12.284 0-16.971l-28.284-28.284c-4.686-4.686-12.284-4.686-16.97 0z\"></path></svg>\n      </span>`;\n        break;\n      case \"trailing-chevron\":\n        markup = `<span aria-hidden=\"true\" class=\"ui-trailing-chevron\"><svg focusable=\"false\" role=\"img\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 512\"><path fill=\"currentColor\" d=\"M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z\"></path></svg></span>`;\n        break;\n      case \"mixedmark\":\n        markup = '<span aria-hidden=\"true\" class=\"ui-mixedmark\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" viewBox=\"0 0 512 512\"><path fill=\"currentColor\" d=\"M0 256c0-13.3 10.7-24 24-24H488c13.3 0 24 10.7 24 24s-10.7 24-24 24H24c-13.3 0-24-10.7-24-24z\"/></svg></span>';\n    }\n    if (markup) {\n      const template = document.createElement(\"template\");\n      template.innerHTML = markup;\n      ICON_CATALOG[name] = template;\n      icon2 = template;\n    }\n  }\n  if (icon2) {\n    if (\"content\" in icon2)\n      return icon2.content.cloneNode(true);\n    const element = document.createElement(\"svg\");\n    element.innerHTML = icon2.innerHTML;\n    return element;\n  }\n  return void 0;\n}\n\n// src/ui/menu/menu-item.ts\nvar BLINK_SPEED = 80;\nvar _MenuItemState = class {\n  constructor(declaration, parentMenu) {\n    this._className = \"\";\n    /** The DOM element the menu item is rendered as */\n    this._element = null;\n    var _a3;\n    this.parentMenu = parentMenu;\n    this._declaration = declaration;\n    Object.freeze(this._declaration);\n    if (isSubmenu(declaration)) {\n      this.type = \"submenu\";\n      this.submenu = new _MenuListState(declaration.submenu, {\n        parentMenu,\n        submenuClass: declaration.submenuClass,\n        columnCount: declaration.columnCount\n      });\n    } else this.type = (_a3 = declaration.type) != null ? _a3 : \"command\";\n    this.hasCheck = isCommand(declaration) && declaration.checked !== void 0;\n  }\n  get rootMenu() {\n    return this.parentMenu.rootMenu;\n  }\n  get abortController() {\n    if (!this._abortController) this._abortController = new AbortController();\n    return this._abortController;\n  }\n  dispose() {\n    var _a3, _b3;\n    (_a3 = this._abortController) == null ? void 0 : _a3.abort();\n    this._abortController = void 0;\n    (_b3 = this._element) == null ? void 0 : _b3.remove();\n    this._element = null;\n    if (this.submenu) this.submenu.dispose();\n    this.submenu = void 0;\n  }\n  get menuItem() {\n    return this._declaration;\n  }\n  get label() {\n    var _a3;\n    return (_a3 = this._label) != null ? _a3 : \"\";\n  }\n  set label(value) {\n    if (value === void 0) value = \"\";\n    if (value === this._label) return;\n    this._label = value;\n    this.dirty = true;\n  }\n  get visible() {\n    return this._visible;\n  }\n  set visible(value) {\n    if (value === this._visible) return;\n    this._visible = value;\n    this.dirty = true;\n  }\n  get enabled() {\n    return this._enabled;\n  }\n  set enabled(value) {\n    this._enabled = value;\n    if (this.element) {\n      if (value) this.element.removeAttribute(\"aria-disabled\");\n      else this.element.setAttribute(\"aria-disabled\", \"true\");\n    }\n    this.dirty = true;\n  }\n  get checked() {\n    return this._checked;\n  }\n  set checked(value) {\n    this._checked = value;\n    this.dirty = true;\n  }\n  get tooltip() {\n    return this._tooltip;\n  }\n  set tooltip(value) {\n    if (value === this._tooltip) return;\n    this._tooltip = value;\n    this.dirty = true;\n  }\n  get ariaLabel() {\n    return this._ariaLabel;\n  }\n  set ariaLabel(value) {\n    if (value === this._ariaLabel) return;\n    this._ariaLabel = value;\n    this.dirty = true;\n  }\n  get active() {\n    var _a3, _b3;\n    return (_b3 = (_a3 = this.element) == null ? void 0 : _a3.classList.contains(\"active\")) != null ? _b3 : false;\n  }\n  set active(value) {\n    if (!this.element) return;\n    this.element.classList.toggle(\"active\", value);\n  }\n  updateState(modifiers) {\n    var _a3, _b3, _c2;\n    const declaration = this._declaration;\n    if (isDivider(declaration)) {\n      this.enabled = false;\n      this.checked = false;\n      return;\n    }\n    if (isHeading(declaration)) {\n      this.enabled = false;\n      this.checked = false;\n      this.visible = true;\n    }\n    if (isCommand(declaration)) {\n      this.checked = (_a3 = dynamicValue(declaration.checked, modifiers)) != null ? _a3 : false;\n    }\n    if (isCommand(declaration) || isSubmenu(declaration)) {\n      this.enabled = (_b3 = dynamicValue(declaration.enabled, modifiers)) != null ? _b3 : true;\n      this.visible = (_c2 = dynamicValue(declaration.visible, modifiers)) != null ? _c2 : true;\n      if (this.visible && this.enabled && this.submenu) {\n        this.submenu.updateState(modifiers);\n        if (!this.submenu.visible) this.visible = false;\n      }\n    }\n    if (isCommand(declaration) || isHeading(declaration) || isSubmenu(declaration)) {\n      this.label = dynamicValue(declaration.label, modifiers);\n      this._className = dynamicValue(declaration.class, modifiers);\n      this.tooltip = dynamicValue(declaration.tooltip, modifiers);\n      this.ariaLabel = dynamicValue(declaration.ariaLabel, modifiers);\n    }\n    if (this._element) this.updateElement();\n  }\n  set dirty(value) {\n    console.assert(value === true);\n    if (value && this.parentMenu) this.parentMenu.dirty = true;\n  }\n  updateElement() {\n    var _a3;\n    if (!this.visible || !this.element) return;\n    const li = this.element;\n    li.textContent = \"\";\n    li.className = \"\";\n    li.className = (_a3 = this._className) != null ? _a3 : \"\";\n    if (!this.enabled) li.setAttribute(\"aria-disabled\", \"true\");\n    else li.removeAttribute(\"aria-disabled\");\n    if (this.checked === true) {\n      li.setAttribute(\"aria-checked\", \"true\");\n      li.append(icon(\"checkmark\"));\n    } else if (this.checked === \"mixed\") {\n      li.setAttribute(\"aria-checked\", \"mixed\");\n      li.append(icon(\"mixedmark\"));\n    } else li.removeAttribute(\"aria-checked\");\n    if (this.ariaLabel) li.setAttribute(\"aria-label\", this.ariaLabel);\n    const span = document.createElement(\"span\");\n    span.className = this.parentMenu.hasCheck ? \"label indent\" : \"label\";\n    if (this.type === \"heading\") span.classList.add(\"heading\");\n    span.innerHTML = this.label;\n    li.append(span);\n    if (this._tooltip) {\n      li.setAttribute(\"data-tooltip\", this._tooltip);\n    }\n    if (isCommand(this._declaration) && this._declaration.keyboardShortcut) {\n      const kbd = document.createElement(\"kbd\");\n      kbd.innerHTML = getKeybindingMarkup(this._declaration.keyboardShortcut);\n      li.append(kbd);\n    }\n    if (this.type === \"submenu\") li.append(icon(\"trailing-chevron\"));\n  }\n  get element() {\n    if (this._element) return this._element;\n    if (isDivider(this._declaration)) {\n      const li2 = document.createElement(\"li\");\n      li2.setAttribute(\"part\", \"menu-divider\");\n      li2.setAttribute(\"role\", \"divider\");\n      this._element = li2;\n      return li2;\n    }\n    const li = document.createElement(\"li\");\n    this._element = li;\n    if (isCommand(this._declaration) || isHeading(this._declaration) || isSubmenu(this._declaration))\n      li.setAttribute(\"part\", \"menu-item\");\n    li.setAttribute(\"tabindex\", \"-1\");\n    if (this.hasCheck) li.setAttribute(\"role\", \"menuitemcheckbox\");\n    else li.setAttribute(\"role\", \"menuitem\");\n    if (this.type === \"submenu\") {\n      li.setAttribute(\"aria-haspopup\", \"true\");\n      li.setAttribute(\"aria-expanded\", \"false\");\n    }\n    const signal = this.abortController.signal;\n    li.addEventListener(\"pointerenter\", this, { signal });\n    li.addEventListener(\"pointerleave\", this, { signal });\n    li.addEventListener(\"pointerup\", this, { signal });\n    li.addEventListener(\"click\", this, { signal });\n    return this._element;\n  }\n  /** Dispatch a `menu-select` event, and call the\n   * `onMenuSelect()` hook if defined.\n   */\n  dispatchSelect() {\n    var _a3;\n    if (!isCommand(this._declaration)) return;\n    const ev = new CustomEvent(\"menu-select\", {\n      cancelable: true,\n      bubbles: true,\n      detail: {\n        modifiers: this.rootMenu.modifiers,\n        id: this._declaration.id,\n        data: this._declaration.data\n      }\n    });\n    const success = this.parentMenu.dispatchEvent(ev);\n    if (success && typeof this._declaration.onMenuSelect === \"function\") {\n      this._declaration.onMenuSelect({\n        target: (_a3 = this.parentMenu.host) != null ? _a3 : void 0,\n        modifiers: this.rootMenu.modifiers,\n        id: this._declaration.id,\n        data: this._declaration.data\n      });\n    }\n  }\n  handleEvent(event) {\n    var _a3;\n    if (!this.visible || !this.enabled) return;\n    if (event.type === \"click\") {\n      if (this.rootMenu.state === \"modal\") this.select();\n      event.stopPropagation();\n      event.preventDefault();\n      return;\n    }\n    if (event.type === \"pointerenter\") {\n      const ev = event;\n      this.rootMenu.cancelDelayedOperation();\n      if (this.parentMenu.isSubmenuOpen && ((_a3 = this.parentMenu.activeMenuItem) == null ? void 0 : _a3.movingTowardSubmenu(ev))) {\n        this.rootMenu.scheduleOperation(() => {\n          this.parentMenu.activeMenuItem = this;\n          this.openSubmenu();\n        });\n      } else {\n        this.parentMenu.activeMenuItem = this;\n        this.openSubmenu({ withDelay: true });\n      }\n      return;\n    }\n    if (event.type === \"pointerleave\") {\n      if (this.rootMenu.activeSubmenu === this.parentMenu)\n        this.parentMenu.activeMenuItem = null;\n      return;\n    }\n    if (event.type === \"pointerup\") {\n      if (this.rootMenu.state !== \"modal\") this.select();\n      event.stopPropagation();\n      event.preventDefault();\n      return;\n    }\n  }\n  /**\n   * Called when a menu item is selected:\n   * - either dismiss the menu and execute the command\n   * - or display the submenu\n   */\n  select() {\n    this.rootMenu.cancelDelayedOperation();\n    if (this.type === \"submenu\") {\n      this.openSubmenu();\n      return;\n    }\n    this.active = false;\n    setTimeout(() => {\n      this.active = true;\n      setTimeout(() => {\n        this.active = false;\n        this.rootMenu.hide();\n        this.dispatchSelect();\n      }, BLINK_SPEED);\n    }, BLINK_SPEED);\n  }\n  /**\n   * Open the submenu of this menu item, with a delay if options.delay\n   * This delay improves targeting of submenus with the mouse.\n   */\n  openSubmenu(options) {\n    var _a3;\n    if (this.type !== \"submenu\" || !this.element) return;\n    if ((_a3 = options == null ? void 0 : options.withDelay) != null ? _a3 : false) {\n      this.rootMenu.scheduleOperation(() => this.openSubmenu());\n      return;\n    }\n    const bounds = this.element.getBoundingClientRect();\n    const dir = getComputedDir(this.element);\n    this.submenu.show({\n      container: this.rootMenu.element.parentNode,\n      location: { x: getEdge(bounds, \"trailing\", dir), y: bounds.top - 4 },\n      alternateLocation: {\n        x: getEdge(bounds, \"leading\", dir),\n        y: bounds.top - 4\n      }\n    });\n  }\n  movingTowardSubmenu(ev) {\n    if (!this.element) return false;\n    if (this.type !== \"submenu\") return false;\n    const lastEv = this.rootMenu.lastMoveEvent;\n    if (!lastEv) return false;\n    const deltaT = ev.timeStamp - lastEv.timeStamp;\n    if (deltaT > 500) return false;\n    const deltaX = ev.clientX - lastEv.clientX;\n    const s = speed(deltaX, lastEv.clientY - ev.clientY, deltaT);\n    if (s <= 0.2) return false;\n    let position = \"right\";\n    if (this.submenu.element) {\n      const submenuBounds = this.submenu.element.getBoundingClientRect();\n      const bounds = this.element.getBoundingClientRect();\n      if (submenuBounds.left < bounds.left + bounds.width / 2)\n        position = \"left\";\n    }\n    return position === \"right\" ? deltaX > 0 : deltaX < 0;\n  }\n};\nfunction speed(dx, dy, dt) {\n  return Math.hypot(dx, dy) / dt;\n}\nfunction dynamicValue(value, modifiers) {\n  if (value === void 0 || typeof value !== \"function\")\n    return value;\n  modifiers != null ? modifiers : modifiers = { alt: false, control: false, shift: false, meta: false };\n  return value(modifiers);\n}\n\n// src/ui/menu/menu-list.ts\nvar _MenuListState = class __MenuListState {\n  constructor(items, options) {\n    this._element = null;\n    this._activeMenuItem = null;\n    this._dirty = true;\n    var _a3, _b3;\n    this.parentMenu = (_a3 = options == null ? void 0 : options.parentMenu) != null ? _a3 : null;\n    this._submenuClass = options == null ? void 0 : options.submenuClass;\n    this.columnCount = (_b3 = options == null ? void 0 : options.columnCount) != null ? _b3 : 1;\n    this.isSubmenuOpen = false;\n    this.menuItems = items;\n  }\n  get children() {\n    return Object.freeze([...this._menuItems]);\n  }\n  /** Setting the menu items will reset this item and\n   * redefine a set of _MenuItem objects\n   */\n  set menuItems(items) {\n    const parent = this.parentMenu;\n    this.dispose();\n    this.parentMenu = parent;\n    items = [...items];\n    this._menuItems = items.map(\n      (x) => x[\"onCreate\"] ? x[\"onCreate\"](x, this) : new _MenuItemState(x, this)\n    );\n    this.hasCheck = void 0;\n    this.dirty = true;\n  }\n  dispose() {\n    var _a3;\n    this.hide();\n    if (this._element) this._element.remove();\n    if (this._abortController) this._abortController.abort();\n    (_a3 = this._menuItems) == null ? void 0 : _a3.forEach((x) => x.dispose());\n    this._menuItems = [];\n    this._activeMenuItem = null;\n    this.parentMenu = null;\n  }\n  handleEvent(event) {\n    if (event.type === \"wheel\" && this._element) {\n      const ev = event;\n      this._element.scrollBy(0, ev.deltaY);\n      event.stopPropagation();\n    }\n  }\n  dispatchEvent(ev) {\n    return this.rootMenu.dispatchEvent(ev);\n  }\n  get host() {\n    return this.rootMenu.host;\n  }\n  get rootMenu() {\n    return this.parentMenu.rootMenu;\n  }\n  /**\n   * Update the 'model' of this menu (i.e. list of menu items)\n   */\n  updateState(modifiers) {\n    var _a3, _b3, _c2;\n    this._menuItems.forEach((x) => x.updateState(modifiers));\n    const previousHasCheck = this.hasCheck;\n    this.hasCheck = this._menuItems.some((x) => x.visible && x.hasCheck);\n    if (this.hasCheck !== previousHasCheck) {\n      this._menuItems.forEach((x) => x.updateState(modifiers));\n    }\n    let heading = void 0;\n    let itemInHeadingCount = 0;\n    for (const item of this._menuItems) {\n      if (item.type === \"heading\") {\n        if (heading && itemInHeadingCount === 0) heading.visible = false;\n        heading = item;\n        itemInHeadingCount = 0;\n      } else if (item.type === \"divider\" && heading) {\n        heading.visible = itemInHeadingCount > 0;\n        heading = void 0;\n        itemInHeadingCount = 0;\n      } else if (heading && item.visible) itemInHeadingCount += 1;\n    }\n    if (heading) heading.visible = itemInHeadingCount > 0;\n    let wasDivider = true;\n    for (const item of this._menuItems) {\n      if (item.type === \"divider\") {\n        item.visible = !wasDivider;\n        wasDivider = true;\n      } else if (item.visible) wasDivider = false;\n    }\n    if (!((_a3 = this.activeMenuItem) == null ? void 0 : _a3.visible)) this.activeMenuItem = null;\n    if (!((_b3 = this.activeMenuItem) == null ? void 0 : _b3.enabled) && ((_c2 = this.activeMenuItem) == null ? void 0 : _c2.type) === \"submenu\")\n      this._activeMenuItem.submenu.hide();\n    this._dirty = false;\n  }\n  get enabled() {\n    this.updateIfDirty();\n    return this._menuItems.some(\n      (x) => x.type !== \"divider\" && x.visible && x.enabled\n    );\n  }\n  get visible() {\n    this.updateIfDirty();\n    return this._menuItems.some((x) => x.type !== \"divider\" && x.visible);\n  }\n  set dirty(value) {\n    console.assert(value === true);\n    if (this._dirty === value) return;\n    if (value && this.parentMenu) {\n      this._dirty = true;\n      this.parentMenu.dirty = true;\n    }\n  }\n  updateIfDirty() {\n    if (this._dirty) this.updateState(this.rootMenu.modifiers);\n  }\n  /** If the element has been created, update its content to reflect\n   * the current state of the menu items\n   */\n  updateElement() {\n    var _a3;\n    if (!this._element) return;\n    this._element.textContent = \"\";\n    for (const { element, visible } of this._menuItems)\n      if (element && visible) this._element.append(element);\n    (_a3 = this._element.querySelector(\"li:first-of-type\")) == null ? void 0 : _a3.setAttribute(\"tabindex\", \"0\");\n  }\n  /**\n   * Construct (or return a cached version) of an element representing\n   * the items in this menu (model -> view)\n   */\n  get element() {\n    if (this._element) return this._element;\n    const menu = document.createElement(\"menu\");\n    menu.setAttribute(\"role\", \"menu\");\n    menu.setAttribute(\"tabindex\", \"-1\");\n    menu.setAttribute(\"aria-orientation\", \"vertical\");\n    menu.setAttribute(\"part\", \"ui-menu-container\");\n    if (this._submenuClass) menu.classList.add(this._submenuClass);\n    menu.classList.add(\"ui-menu-container\");\n    if (!this._abortController) this._abortController = new AbortController();\n    const signal = this._abortController.signal;\n    menu.addEventListener(\"focus\", this, { signal });\n    menu.addEventListener(\"wheel\", this, { passive: true, signal });\n    this._element = menu;\n    this.updateElement();\n    return menu;\n  }\n  /**\n   * The active menu is displayed on a colored background.\n   */\n  get activeMenuItem() {\n    return this._activeMenuItem;\n  }\n  /**\n   * Set to null to have no active item.\n   * Note that setting the active menu item doesn't automatically\n   * open the submenu (e.g. when keyboard navigating).\n   * Call `item.submenu.openSubmenu()` to open the submenu.\n   */\n  set activeMenuItem(value) {\n    var _a3, _b3, _c2, _d2;\n    this.rootMenu.cancelDelayedOperation();\n    if (value !== this._activeMenuItem) {\n      if (this.activeMenuItem) {\n        const item = this.activeMenuItem;\n        item.active = false;\n        (_a3 = item.submenu) == null ? void 0 : _a3.hide();\n      }\n      if (!((_b3 = value == null ? void 0 : value.visible) != null ? _b3 : true)) {\n        this._activeMenuItem = null;\n        return;\n      }\n      this._activeMenuItem = value;\n      if (value) value.active = true;\n    }\n    if (value) (_c2 = value.element) == null ? void 0 : _c2.focus({ preventScroll: true });\n    else (_d2 = this._element) == null ? void 0 : _d2.focus({ preventScroll: true });\n  }\n  /** First activable menu item */\n  get firstMenuItem() {\n    this.updateIfDirty();\n    let result = 0;\n    let found = false;\n    const menuItems = this._menuItems;\n    while (!found && result <= menuItems.length - 1) {\n      const item = menuItems[result];\n      found = item.type !== \"divider\" && item.visible && item.enabled;\n      result += 1;\n    }\n    return found ? menuItems[result - 1] : null;\n  }\n  /** Last activable menu item */\n  get lastMenuItem() {\n    this.updateIfDirty();\n    const menuItems = this._menuItems;\n    let result = menuItems.length - 1;\n    let found = false;\n    while (!found && result >= 0) {\n      const item = menuItems[result];\n      found = item.type !== \"divider\" && item.visible && item.enabled;\n      result -= 1;\n    }\n    return found ? menuItems[result + 1] : null;\n  }\n  nextMenuItem(stride) {\n    if (stride === 0) return this._activeMenuItem;\n    if (!this._activeMenuItem)\n      return stride > 0 ? this.firstMenuItem : this.lastMenuItem;\n    if (!this.firstMenuItem || !this.lastMenuItem || !this._activeMenuItem)\n      return null;\n    this.updateIfDirty();\n    const first = this._menuItems.indexOf(this.firstMenuItem);\n    const last = this._menuItems.indexOf(this.lastMenuItem);\n    let index = this._menuItems.indexOf(this._activeMenuItem);\n    let count = 1;\n    while (index >= first && index <= last) {\n      index += stride > 0 ? 1 : -1;\n      const item = this._menuItems[index];\n      if (!item) break;\n      if (item.visible && item.enabled) {\n        if (count === Math.abs(stride)) return this._menuItems[index];\n        count += 1;\n      }\n    }\n    return stride > 0 ? this.lastMenuItem : this.firstMenuItem;\n  }\n  getMenuItemColumn(menu) {\n    this.updateIfDirty();\n    const visibleItems = this._menuItems.filter((x) => x.visible && x.enabled);\n    const index = visibleItems.indexOf(menu);\n    if (index < 0) return -1;\n    return index % this.columnCount;\n  }\n  static get collator() {\n    if (__MenuListState._collator) return __MenuListState._collator;\n    __MenuListState._collator = new Intl.Collator(void 0, {\n      usage: \"search\",\n      sensitivity: \"base\"\n    });\n    return __MenuListState._collator;\n  }\n  findMenuItem(text) {\n    var _a3;\n    this.updateIfDirty();\n    const candidates = this._menuItems.filter(\n      (x) => x.type !== \"divider\" && x.visible && x.enabled\n    );\n    if (candidates.length === 0) return null;\n    const last = Math.max(...candidates.map((x) => x.label.length)) - text.length;\n    if (last < 0) return null;\n    let result = null;\n    let i = 0;\n    while (i < last && !result) {\n      result = (_a3 = candidates.find(\n        (x) => __MenuListState.collator.compare(\n          text,\n          x.label.substring(i, text.length)\n        ) === 0\n      )) != null ? _a3 : null;\n      i++;\n    }\n    return result;\n  }\n  /**\n   * @param location: in viewport coordinates\n   * @param alternateLocation: in viewport coordinates\n   * @param container: where the menu should be attached\n   * @return false if no menu to show\n   */\n  show(options) {\n    if (!this.visible || !options.container) return false;\n    this.updateElement();\n    options.container.appendChild(this.element);\n    if (supportPopover()) {\n      this.element.popover = \"manual\";\n      this.element.showPopover();\n    }\n    if (options.location) {\n      fitInViewport(this.element, {\n        location: options.location,\n        alternateLocation: options.alternateLocation,\n        verticalPos: \"bottom\",\n        horizontalPos: \"start\"\n      });\n    }\n    suppressFocusEvents();\n    this.element.focus({ preventScroll: true });\n    enableFocusEvents();\n    if (this.parentMenu) this.parentMenu.openSubmenu = this;\n    return true;\n  }\n  hide() {\n    var _a3, _b3, _c2, _d2, _e;\n    this.openSubmenu = null;\n    this.activeMenuItem = null;\n    if (this.parentMenu) this.parentMenu.openSubmenu = null;\n    if (supportPopover() && ((_a3 = this._element) == null ? void 0 : _a3.popover)) this.element.hidePopover();\n    suppressFocusEvents();\n    (_c2 = (_b3 = this.parentMenu) == null ? void 0 : _b3.element) == null ? void 0 : _c2.focus();\n    (_e = (_d2 = this._element) == null ? void 0 : _d2.parentNode) == null ? void 0 : _e.removeChild(this._element);\n    enableFocusEvents();\n  }\n  /**\n   * This method is called to record that one of our submenus has opened.\n   * To open a submenu call openSubmenu() on the item with the submenu\n   * or show() on the submenu.\n   */\n  set openSubmenu(submenu) {\n    var _a3, _b3, _c2, _d2;\n    const expanded = submenu !== null;\n    if (((_a3 = this.activeMenuItem) == null ? void 0 : _a3.type) === \"submenu\") {\n      (_b3 = this.activeMenuItem.element) == null ? void 0 : _b3.setAttribute(\n        \"aria-expanded\",\n        expanded.toString()\n      );\n    }\n    (_d2 = (_c2 = this.activeMenuItem) == null ? void 0 : _c2.element) == null ? void 0 : _d2.classList.toggle(\"is-submenu-open\", expanded);\n    this.isSubmenuOpen = expanded;\n  }\n};\nfunction suppressFocusEvents() {\n  document.addEventListener(\"focusin\", handleFocusEvent, true);\n  document.addEventListener(\"focusout\", handleFocusEvent, true);\n  document.addEventListener(\"focus\", handleFocusEvent, true);\n  document.addEventListener(\"blur\", handleFocusEvent, true);\n}\nfunction handleFocusEvent(event) {\n  event.stopImmediatePropagation();\n  event.preventDefault();\n}\nfunction enableFocusEvents() {\n  document.removeEventListener(\"focusin\", handleFocusEvent, true);\n  document.removeEventListener(\"focusout\", handleFocusEvent, true);\n  document.removeEventListener(\"focus\", handleFocusEvent, true);\n  document.removeEventListener(\"blur\", handleFocusEvent, true);\n}\n\n// src/ui/menu/menu.ts\nvar _Menu = class _Menu extends _MenuListState {\n  /**\n   * The host is the element that the events will be dispatched from\n   *\n   */\n  constructor(menuItems, options) {\n    var _a3;\n    super(menuItems);\n    /**\n     * - 'closed': the menu is not visible\n     * - 'open': the menu is visible as long as the mouse button is pressed\n     * - 'modal': the menu is visible until dismissed, even with\n     *   the mouse button released\n     */\n    this.state = \"closed\";\n    this.typingBufferResetTimer = 0;\n    this.hysteresisTimer = 0;\n    this._updating = false;\n    this._host = (_a3 = options == null ? void 0 : options.host) != null ? _a3 : null;\n    this.isDynamic = menuItems.some(isDynamic);\n    this._modifiers = {\n      shift: false,\n      control: false,\n      alt: false,\n      meta: false\n    };\n    this.typingBuffer = \"\";\n    this.state = \"closed\";\n  }\n  get modifiers() {\n    return this._modifiers;\n  }\n  set modifiers(value) {\n    if (equalKeyboardModifiers(this._modifiers, value)) return;\n    this._modifiers = value;\n    this.dirty = true;\n  }\n  /**\n   * The currently active menu: could be the root menu or a submenu\n   */\n  get activeSubmenu() {\n    let result = this;\n    while (result.isSubmenuOpen) result = result.activeMenuItem.submenu;\n    return result;\n  }\n  set dirty(value) {\n    if (this._updating) return;\n    console.assert(value === true);\n    if (this._dirty === value) return;\n    this._dirty = true;\n    if (value) {\n      setTimeout(() => {\n        this.updateState(this.modifiers);\n        this.updateElement();\n      });\n    }\n  }\n  updateState(modifiers) {\n    this._updating = true;\n    this.modifiers = modifiers != null ? modifiers : this.modifiers;\n    super.updateState(this.modifiers);\n    this._updating = false;\n  }\n  handleKeyupEvent(ev) {\n    if (this.isDynamic) this.modifiers = keyboardModifiersFromEvent(ev);\n    ev.stopImmediatePropagation();\n  }\n  handleKeydownEvent(ev) {\n    var _a3, _b3, _c2;\n    if (ev.key === \"Tab\" || ev.key === \"Escape\") {\n      this.hide();\n      return;\n    }\n    if (this.isDynamic) this.modifiers = keyboardModifiersFromEvent(ev);\n    let handled = true;\n    const menu = this.activeSubmenu;\n    const menuItem = menu.activeMenuItem;\n    switch (ev.key) {\n      case \" \":\n      case \"Space\":\n      case \"Return\":\n      case \"Enter\":\n        menuItem == null ? void 0 : menuItem.select(keyboardModifiersFromEvent(ev));\n        break;\n      case \"ArrowRight\":\n        if ((menuItem == null ? void 0 : menuItem.type) === \"submenu\") {\n          menuItem.select(keyboardModifiersFromEvent(ev));\n          this.activeSubmenu.activeMenuItem = this.activeSubmenu.firstMenuItem;\n        } else if (!menuItem) menu.activeMenuItem = menu.firstMenuItem;\n        else {\n          const col = (_a3 = menu.getMenuItemColumn(menuItem)) != null ? _a3 : -1;\n          if (col >= 0 && col < ((_b3 = menu.columnCount) != null ? _b3 : 1) - 1) {\n            const next = menu.nextMenuItem(1);\n            if (next) menu.activeMenuItem = next;\n          }\n        }\n        break;\n      case \"ArrowLeft\":\n        if (menu === this.rootMenu) {\n          if (!menuItem) menu.activeMenuItem = menu.firstMenuItem;\n        } else {\n          const col = menuItem ? (_c2 = menu.getMenuItemColumn(menuItem)) != null ? _c2 : -1 : -1;\n          if (col <= 0 || !menuItem) {\n            menu.hide();\n            const activeMenu = menu.parentMenu.activeMenuItem;\n            if (activeMenu) {\n              const { element } = activeMenu;\n              element == null ? void 0 : element.focus();\n              element == null ? void 0 : element.classList.remove(\"is-submenu-open\");\n            }\n          } else {\n            const next = menu.nextMenuItem(-1);\n            if (next) menu.activeMenuItem = next;\n          }\n        }\n        break;\n      case \"ArrowDown\":\n        menu.activeMenuItem = menu.nextMenuItem(menu.columnCount);\n        break;\n      case \"ArrowUp\":\n        menu.activeMenuItem = menu.nextMenuItem(-menu.columnCount);\n        break;\n      case \"Home\":\n      case \"PageUp\":\n        menu.activeMenuItem = menu.firstMenuItem;\n        break;\n      case \"End\":\n      case \"PageDown\":\n        menu.activeMenuItem = menu.lastMenuItem;\n        break;\n      case \"Backspace\":\n        if (this.typingBuffer) {\n          this.typingBuffer = this.typingBuffer.slice(0, -1);\n          if (this.typingBuffer) {\n            clearTimeout(this.typingBufferResetTimer);\n            const newItem = menu.findMenuItem(this.typingBuffer);\n            if (newItem) menu.activeMenuItem = newItem;\n            this.typingBufferResetTimer = setTimeout(() => {\n              this.typingBuffer = \"\";\n            }, 500);\n          }\n        }\n        break;\n      default:\n        if (mightProducePrintableCharacter(ev)) {\n          if (isFinite(this.typingBufferResetTimer))\n            clearTimeout(this.typingBufferResetTimer);\n          this.typingBuffer += ev.key;\n          const newItem = menu.findMenuItem(this.typingBuffer);\n          if (newItem) menu.activeMenuItem = newItem;\n          this.typingBufferResetTimer = setTimeout(() => {\n            this.typingBuffer = \"\";\n          }, 500);\n        } else handled = false;\n    }\n    if (handled) {\n      ev.preventDefault();\n      ev.stopPropagation();\n    }\n  }\n  handleEvent(event) {\n    if (event.type === \"keydown\")\n      this.handleKeydownEvent(event);\n    else if (event.type === \"keyup\")\n      this.handleKeyupEvent(event);\n    else if (event.type === \"pointermove\")\n      this.lastMoveEvent = event;\n    else if (event.type === \"pointerup\" && event.target === this.scrim) {\n      if (Number.isFinite(this.rootMenu._openTimestamp) && Date.now() - this.rootMenu._openTimestamp < 120) {\n        this.state = \"modal\";\n      } else if (this.state === \"modal\") {\n        this.hide();\n      }\n    } else if (event.type === \"contextmenu\") {\n      event.preventDefault();\n      event.stopPropagation();\n      return;\n    }\n    super.handleEvent(event);\n  }\n  /** Return true if the event is **not** canceled */\n  dispatchEvent(ev) {\n    if (!this._host) return true;\n    return this._host.dispatchEvent(ev);\n  }\n  get host() {\n    return this._host;\n  }\n  get scrim() {\n    return Scrim.element;\n  }\n  connectScrim(target) {\n    const scrim = this.scrim;\n    scrim.addEventListener(\"pointerup\", this);\n    scrim.addEventListener(\"contextmenu\", this);\n    scrim.addEventListener(\"keydown\", this);\n    scrim.addEventListener(\"keyup\", this);\n    scrim.addEventListener(\"pointermove\", this);\n    Scrim.open({ root: target, onDismiss: () => this.hide() });\n  }\n  disconnectScrim() {\n    const scrim = this.scrim;\n    scrim.removeEventListener(\"pointerup\", this);\n    scrim.removeEventListener(\"contextmenu\", this);\n    scrim.removeEventListener(\"keydown\", this);\n    scrim.removeEventListener(\"keyup\", this);\n    scrim.removeEventListener(\"pointermove\", this);\n    if (Scrim.state === \"open\") Scrim.scrim.close();\n  }\n  get rootMenu() {\n    return this;\n  }\n  /** Locations are in viewport coordinate. */\n  show(options) {\n    this._onDismiss = options == null ? void 0 : options.onDismiss;\n    if (options == null ? void 0 : options.modifiers) this.modifiers = options.modifiers;\n    this.updateState();\n    this.connectScrim(options == null ? void 0 : options.target);\n    if (!super.show(__spreadProps(__spreadValues({}, options), { container: this.scrim }))) {\n      this.disconnectScrim();\n      return false;\n    }\n    this._openTimestamp = Date.now();\n    this.state = \"open\";\n    return true;\n  }\n  hide() {\n    this.cancelDelayedOperation();\n    if (this.state !== void 0) {\n      if (this.state !== \"closed\") {\n        this.activeMenuItem = null;\n        Scrim.element.parentElement.focus();\n        super.hide();\n        this.state = \"closed\";\n        this.disconnectScrim();\n      }\n      if (this._onDismiss) {\n        this._onDismiss();\n        this._onDismiss = void 0;\n      }\n    }\n  }\n  scheduleOperation(fn) {\n    this.cancelDelayedOperation();\n    const delay = _Menu.SUBMENU_DELAY;\n    if (delay <= 0) {\n      fn();\n      return;\n    }\n    this.hysteresisTimer = setTimeout(() => {\n      this.hysteresisTimer = 0;\n      fn();\n    }, delay);\n  }\n  cancelDelayedOperation() {\n    if (this.hysteresisTimer) {\n      clearTimeout(this.hysteresisTimer);\n      this.hysteresisTimer = 0;\n    }\n  }\n};\n/**\n * Delay (in milliseconds) before displaying a submenu.\n *\n * Prevents distracting flashing of submenus when moving quickly\n * through the options in a menu.\n */\n_Menu.SUBMENU_DELAY = 120;\nvar Menu = _Menu;\nfunction isDynamic(item) {\n  if (isDivider(item)) return false;\n  if (typeof item.label === \"function\" || typeof item.ariaLabel === \"function\" || typeof item.tooltip === \"function\")\n    return true;\n  if ((isCommand(item) || isSubmenu(item)) && (typeof item.enabled === \"function\" || typeof item.visible === \"function\"))\n    return true;\n  if (isCommand(item) && typeof item.checked === \"function\") return true;\n  if (isSubmenu(item)) return item.submenu.some(isDynamic);\n  return false;\n}\n\n// src/ui/events/longpress.ts\nvar LongPress = class {\n  // Maximum distance between the start and end of the gesture, in pixels\n};\nLongPress.DELAY = 300;\n// Amount of time before showing the context menu, in ms\nLongPress.MAX_DISTANCE = 10;\nfunction onLongPress(triggerEvent) {\n  return new Promise((resolve, _reject) => {\n    const startPoint = eventLocation(triggerEvent);\n    if (!startPoint) resolve(false);\n    let lastPoint = startPoint;\n    const timer = setTimeout(() => {\n      controller.abort();\n      resolve(distance2(lastPoint, startPoint) < LongPress.MAX_DISTANCE);\n    }, LongPress.DELAY);\n    const controller = new AbortController();\n    const signal = controller.signal;\n    for (const eventType of [\"pointermove\", \"pointerup\", \"pointercancel\"]) {\n      window.addEventListener(\n        eventType,\n        (evt) => {\n          if (evt.type === \"pointerup\" || evt.type === \"pointercancel\") {\n            clearTimeout(timer);\n            controller.abort();\n            resolve(false);\n          } else if (evt.type === \"pointermove\") {\n            const location = eventLocation(evt);\n            if (location) lastPoint = location;\n          }\n        },\n        { passive: true, signal }\n      );\n    }\n  });\n}\n\n// src/ui/menu/context-menu.ts\nasync function onContextMenu(event, target, menu) {\n  if (event.defaultPrevented) return false;\n  if (event.type === \"contextmenu\") {\n    const evt = event;\n    if (menu.show({\n      target,\n      location: eventLocation(evt),\n      modifiers: keyboardModifiersFromEvent(evt)\n    })) {\n      event.preventDefault();\n      event.stopPropagation();\n      return true;\n    }\n  }\n  if (event.type === \"keydown\") {\n    const evt = event;\n    if (evt.code === \"ContextMenu\" || evt.code === \"F10\" && evt.shiftKey) {\n      const bounds = target == null ? void 0 : target.getBoundingClientRect();\n      if (acceptContextMenu(target) && bounds && menu.show({\n        target,\n        location: {\n          x: Math.ceil(bounds.left + bounds.width / 2),\n          y: Math.ceil(bounds.top + bounds.height / 2)\n        },\n        modifiers: keyboardModifiersFromEvent(evt)\n      })) {\n        event.preventDefault();\n        event.stopPropagation();\n        return true;\n      }\n    }\n  }\n  if (event.type === \"pointerdown\" && event.pointerType !== \"mouse\" && event.button === 0) {\n    let eventTarget = event.target;\n    while (eventTarget && target !== eventTarget)\n      eventTarget = eventTarget.parentNode;\n    if (!eventTarget) return false;\n    if (!menu.visible) return false;\n    const location = eventLocation(event);\n    if (await onLongPress(event)) {\n      if (menu.state !== \"closed\") return false;\n      if (!acceptContextMenu(target)) return false;\n      menu.show({ target, location });\n      return true;\n    }\n  }\n  return false;\n}\nfunction acceptContextMenu(host) {\n  return host.dispatchEvent(new Event(\"contextmenu\", { cancelable: true }));\n}\n\n// src/latex-commands/accents.ts\nvar ACCENTS = {\n  acute: 714,\n  grave: 715,\n  dot: 729,\n  ddot: 168,\n  mathring: 730,\n  tilde: 126,\n  bar: 713,\n  breve: 728,\n  check: 711,\n  hat: 94,\n  vec: 8407\n};\ndefineFunction(Object.keys(ACCENTS), \"{body:auto}\", {\n  createAtom: (options) => new AccentAtom(__spreadProps(__spreadValues({}, options), {\n    body: argAtoms(options.args[0]),\n    accentChar: ACCENTS[options.command.slice(1)]\n  }))\n});\ndefineFunction([\"widehat\", \"widecheck\", \"widetilde\"], \"{body:auto}\", {\n  createAtom: (options) => {\n    const baseString = parseArgAsString(argAtoms(options.args[0]));\n    return new AccentAtom(__spreadProps(__spreadValues({}, options), {\n      body: argAtoms(options.args[0]),\n      svgAccent: options.command.slice(1) + (baseString.length > 5 ? \"4\" : [\"1\", \"1\", \"2\", \"2\", \"3\", \"3\"][baseString.length])\n    }));\n  }\n});\ndefineFunction([\"overarc\", \"overparen\", \"wideparen\"], \"{body:auto}\", {\n  createAtom: (options) => {\n    return new AccentAtom(__spreadProps(__spreadValues({}, options), {\n      body: argAtoms(options.args[0]),\n      svgAccent: \"overarc\"\n    }));\n  }\n});\ndefineFunction([\"underarc\", \"underparen\"], \"{body:auto}\", {\n  createAtom: (options) => {\n    return new OverunderAtom(__spreadProps(__spreadValues({}, options), {\n      body: argAtoms(options.args[0]),\n      svgBelow: \"underarc\"\n    }));\n  }\n});\ndefineFunction(\"utilde\", \"{body:auto}\", {\n  createAtom: (options) => {\n    const body = argAtoms(options.args[0]);\n    const baseString = parseArgAsString(body);\n    const accent = \"widetilde\" + (baseString.length > 5 ? \"4\" : [\"1\", \"1\", \"2\", \"2\", \"3\", \"3\"][baseString.length]);\n    return new OverunderAtom(__spreadProps(__spreadValues({}, options), {\n      body,\n      svgBelow: accent,\n      boxType: atomsBoxType(body)\n    }));\n  }\n});\ndefineFunction(\"^\", \"{:string}\", {\n  createAtom: (options) => {\n    var _a3;\n    return new Atom(__spreadProps(__spreadValues({}, options), {\n      type: \"mord\",\n      isFunction: false,\n      limits: \"adjacent\",\n      value: options.args[0] ? (_a3 = {\n        a: \"\\xE2\",\n        e: \"\\xEA\",\n        i: \"\\xEE\",\n        o: \"\\xF4\",\n        u: \"\\xFB\",\n        A: \"\\xC2\",\n        E: \"\\xCA\",\n        I: \"\\xCE\",\n        O: \"\\xD4\",\n        U: \"\\xDB\"\n      }[options.args[0]]) != null ? _a3 : \"^\" : \"^\"\n    }));\n  }\n});\ndefineFunction(\"`\", \"{:string}\", {\n  createAtom: (options) => {\n    var _a3;\n    return new Atom(__spreadProps(__spreadValues({}, options), {\n      type: \"mord\",\n      isFunction: false,\n      limits: \"adjacent\",\n      value: options.args[0] ? (_a3 = {\n        a: \"\\xE0\",\n        e: \"\\xE8\",\n        i: \"\\xEC\",\n        o: \"\\xF2\",\n        u: \"\\xF9\",\n        A: \"\\xC0\",\n        E: \"\\xC8\",\n        I: \"\\xCC\",\n        O: \"\\xD2\",\n        U: \"\\xD9\"\n      }[options.args[0]]) != null ? _a3 : \"`\" : \"`\"\n    }));\n  }\n});\ndefineFunction(\"'\", \"{:string}\", {\n  createAtom: (options) => {\n    var _a3;\n    return new Atom(__spreadProps(__spreadValues({}, options), {\n      type: \"mord\",\n      isFunction: false,\n      limits: \"adjacent\",\n      value: options.args[0] ? (_a3 = {\n        a: \"\\xE1\",\n        e: \"\\xE9\",\n        i: \"\\xED\",\n        o: \"\\xF3\",\n        u: \"\\xFA\",\n        A: \"\\xC1\",\n        E: \"\\xC9\",\n        I: \"\\xCD\",\n        O: \"\\xD3\",\n        U: \"\\xDA\"\n      }[options.args[0]]) != null ? _a3 : \"'\" : \"'\"\n    }));\n  }\n});\ndefineFunction('\"', \"{:string}\", {\n  createAtom: (options) => {\n    var _a3, _b3;\n    return new Atom(__spreadProps(__spreadValues({}, options), {\n      type: \"mord\",\n      isFunction: false,\n      limits: \"adjacent\",\n      value: ((_a3 = options.args) == null ? void 0 : _a3[0]) ? (_b3 = {\n        a: \"\\xE4\",\n        e: \"\\xEB\",\n        i: \"\\xEF\",\n        o: \"\\xF6\",\n        u: \"\\xFC\",\n        A: \"\\xC4\",\n        E: \"\\xCB\",\n        I: \"\\xCB\",\n        O: \"\\xD6\",\n        U: \"\\xDC\"\n      }[options.args[0]]) != null ? _b3 : '\"' + options.args[0] : '\"'\n    }));\n  }\n});\ndefineFunction(\".\", \"{:string}\", {\n  createAtom: (options) => {\n    var _a3, _b3;\n    return new Atom(__spreadProps(__spreadValues({}, options), {\n      type: \"mord\",\n      isFunction: false,\n      limits: \"adjacent\",\n      value: ((_a3 = options.args) == null ? void 0 : _a3[0]) ? (_b3 = {\n        // a with single dot above\n        a: \"\\u0227\",\n        e: \"\\u0117\",\n        // i with single dot above (combining character)\n        i: \"\\u0307i\",\n        o: \"\\u022F\",\n        // U with single dot above (combining character)\n        u: \"\\u0307u\",\n        A: \"\\u0226\",\n        E: \"\\u0116\",\n        I: \"\\u0130\",\n        O: \"\\u022E\",\n        // U with single dot above (combining character)\n        U: \"\\u0307U\"\n      }[options.args[0]]) != null ? _b3 : \".\" + options.args[0] : \".\"\n    }));\n  }\n});\ndefineFunction(\"=\", \"{:string}\", {\n  createAtom: (options) => {\n    var _a3, _b3;\n    return new Atom(__spreadProps(__spreadValues({}, options), {\n      type: \"mord\",\n      isFunction: false,\n      limits: \"adjacent\",\n      value: ((_a3 = options.args) == null ? void 0 : _a3[0]) ? (_b3 = {\n        // a with macron\n        a: \"\\u0101\",\n        e: \"\\u0113\",\n        i: \"\\u012B\",\n        o: \"\\u014D\",\n        u: \"\\u016B\",\n        A: \"\\u0100\",\n        E: \"\\u0112\",\n        I: \"\\u012A\",\n        O: \"\\u014C\",\n        U: \"\\u016A\"\n      }[options.args[0]]) != null ? _b3 : \"=\" + options.args[0] : \"=\"\n      // fallback\n    }));\n  }\n});\ndefineFunction(\"~\", \"{:string}\", {\n  createAtom: (options) => {\n    var _a3;\n    return new Atom(__spreadProps(__spreadValues({\n      type: \"mord\"\n    }, options), {\n      isFunction: false,\n      limits: \"adjacent\",\n      value: options.args[0] ? (_a3 = { n: \"\\xF1\", N: \"\\xD1\", a: \"\\xE3\", o: \"\\xF5\", A: \"\\xC3\", O: \"\\xD5\" }[options.args[0]]) != null ? _a3 : \"\\xB4\" : \"\\xB4\"\n    }));\n  }\n});\ndefineFunction(\"c\", \"{:string}\", {\n  createAtom: (options) => {\n    var _a3;\n    return new Atom(__spreadProps(__spreadValues({}, options), {\n      type: \"mord\",\n      isFunction: false,\n      limits: \"adjacent\",\n      value: options.args[0] ? (_a3 = { c: \"\\xE7\", C: \"\\xC7\" }[options.args[0]]) != null ? _a3 : \"\" : \"\"\n    }));\n  }\n});\n\n// src/latex-commands/enclose.ts\ndefineFunction(\"enclose\", \"{notation:string}[style:string]{body:auto}\", {\n  createAtom: (atomOptions) => {\n    var _a3, _b3;\n    const args = atomOptions.args;\n    const options = {\n      strokeColor: \"currentColor\",\n      strokeWidth: \"\",\n      strokeStyle: \"solid\",\n      backgroundcolor: \"transparent\",\n      padding: \"auto\",\n      shadow: \"none\",\n      svgStrokeStyle: void 0,\n      borderStyle: void 0,\n      style: (_a3 = atomOptions.style) != null ? _a3 : {}\n    };\n    if (args[1]) {\n      const styles = args[1].split(/,(?![^(]*\\)(?:(?:[^(]*\\)){2})*[^\"]*$)/);\n      for (const s of styles) {\n        const shorthand = s.match(/\\s*(\\S+)\\s+(\\S+)\\s+(.*)/);\n        if (shorthand) {\n          options.strokeWidth = shorthand[1];\n          options.strokeStyle = shorthand[2];\n          options.strokeColor = shorthand[3];\n        } else {\n          const attribute = s.match(/\\s*([a-z]*)\\s*=\\s*\"(.*)\"/);\n          if (attribute) {\n            if (attribute[1] === \"mathbackground\")\n              options.backgroundcolor = attribute[2];\n            else if (attribute[1] === \"mathcolor\")\n              options.strokeColor = attribute[2];\n            else if (attribute[1] === \"padding\") options.padding = attribute[2];\n            else if (attribute[1] === \"shadow\") options.shadow = attribute[2];\n          }\n        }\n      }\n      if (options.strokeStyle === \"dashed\") options.svgStrokeStyle = \"5,5\";\n      else if (options.strokeStyle === \"dotted\") options.svgStrokeStyle = \"1,5\";\n    }\n    options.borderStyle = `${options.strokeWidth} ${options.strokeStyle} ${options.strokeColor}`;\n    const notation = {};\n    ((_b3 = args[0]) != null ? _b3 : \"\").split(/[, ]/).filter((v) => v.length > 0).forEach((x) => {\n      notation[x.toLowerCase()] = true;\n    });\n    return new EncloseAtom(\n      atomOptions.command,\n      argAtoms(args[2]),\n      notation,\n      options\n    );\n  }\n});\ndefineFunction(\"cancel\", \"{body:auto}\", {\n  createAtom: (options) => {\n    var _a3;\n    return new EncloseAtom(\n      options.command,\n      argAtoms(options.args[0]),\n      { updiagonalstrike: true },\n      {\n        strokeColor: \"currentColor\",\n        strokeWidth: \"\",\n        strokeStyle: \"solid\",\n        borderStyle: \"1px solid currentColor\",\n        backgroundcolor: \"transparent\",\n        padding: \"auto\",\n        shadow: \"none\",\n        style: (_a3 = options.style) != null ? _a3 : {}\n      }\n    );\n  }\n});\ndefineFunction(\"bcancel\", \"{body:auto}\", {\n  createAtom: (options) => {\n    var _a3;\n    return new EncloseAtom(\n      options.command,\n      argAtoms(options.args[0]),\n      { downdiagonalstrike: true },\n      {\n        strokeColor: \"currentColor\",\n        strokeWidth: \"\",\n        strokeStyle: \"solid\",\n        borderStyle: \"1px solid currentColor\",\n        backgroundcolor: \"transparent\",\n        padding: \"auto\",\n        shadow: \"none\",\n        style: (_a3 = options.style) != null ? _a3 : {}\n      }\n    );\n  }\n});\ndefineFunction(\"xcancel\", \"{body:auto}\", {\n  createAtom: (options) => {\n    var _a3;\n    return new EncloseAtom(\n      options.command,\n      argAtoms(options.args[0]),\n      { updiagonalstrike: true, downdiagonalstrike: true },\n      {\n        strokeColor: \"currentColor\",\n        strokeWidth: \"\",\n        strokeStyle: \"solid\",\n        borderStyle: \"1px solid currentColor\",\n        backgroundcolor: \"transparent\",\n        padding: \"auto\",\n        shadow: \"none\",\n        style: (_a3 = options.style) != null ? _a3 : {}\n      }\n    );\n  }\n});\n\n// src/latex-commands/extensible-symbols.ts\ndefineFunction(\n  [\n    \"overrightarrow\",\n    \"overleftarrow\",\n    \"Overrightarrow\",\n    \"overleftharpoon\",\n    \"overrightharpoon\",\n    \"overleftrightarrow\",\n    \"overlinesegment\",\n    \"overgroup\"\n  ],\n  \"{:auto}\",\n  {\n    createAtom: (options) => {\n      var _a3;\n      return new OverunderAtom(__spreadProps(__spreadValues({}, options), {\n        body: argAtoms((_a3 = options.args) == null ? void 0 : _a3[0]),\n        skipBoundary: false,\n        supsubPlacement: \"over-under\",\n        paddedBody: true,\n        boxType: \"rel\",\n        // Set the \"svgAbove\" to the name of a SVG object (which is the same\n        // as the command name)\n        svgAbove: options.command.slice(1)\n      }));\n    }\n  }\n);\ndefineFunction(\"overbrace\", \"{:auto}\", {\n  createAtom: (options) => new OverunderAtom(__spreadProps(__spreadValues({}, options), {\n    body: argAtoms(options.args[0]),\n    skipBoundary: false,\n    supsubPlacement: \"over-under\",\n    paddedBody: true,\n    boxType: \"ord\",\n    svgAbove: options.command.slice(1)\n  }))\n});\ndefineFunction(\n  [\n    \"underrightarrow\",\n    \"underleftarrow\",\n    \"underleftrightarrow\",\n    \"underlinesegment\",\n    \"undergroup\"\n  ],\n  \"{:auto}\",\n  {\n    createAtom: (options) => new OverunderAtom(__spreadProps(__spreadValues({}, options), {\n      body: argAtoms(options.args[0]),\n      skipBoundary: false,\n      supsubPlacement: \"over-under\",\n      paddedBody: true,\n      boxType: \"rel\",\n      // Set the \"svgBelow\" to the name of a SVG object (which is the same\n      // as the command name)\n      svgBelow: options.command.slice(1)\n    }))\n  }\n);\ndefineFunction([\"underbrace\"], \"{:auto}\", {\n  createAtom: (options) => new OverunderAtom(__spreadProps(__spreadValues({}, options), {\n    body: argAtoms(options.args[0]),\n    skipBoundary: false,\n    supsubPlacement: \"over-under\",\n    paddedBody: true,\n    boxType: \"ord\",\n    svgBelow: options.command.slice(1)\n  }))\n});\ndefineFunction(\n  [\n    \"xrightarrow\",\n    \"longrightarrow\",\n    // From mhchem.sty package\n    \"xleftarrow\",\n    \"longleftarrow\",\n    // From mhchem.sty package\n    \"xRightarrow\",\n    \"xLeftarrow\",\n    \"xleftharpoonup\",\n    \"xleftharpoondown\",\n    \"xrightharpoonup\",\n    \"xrightharpoondown\",\n    \"xlongequal\",\n    \"xtwoheadleftarrow\",\n    \"xtwoheadrightarrow\",\n    \"xleftrightarrow\",\n    \"longleftrightarrow\",\n    // From mhchem.sty package\n    \"xLeftrightarrow\",\n    \"xrightleftharpoons\",\n    // From mhchem.sty package\n    \"longrightleftharpoons\",\n    \"xleftrightharpoons\",\n    \"xhookleftarrow\",\n    \"xhookrightarrow\",\n    \"xmapsto\",\n    \"xtofrom\",\n    \"xleftrightarrows\",\n    // From mhchem.sty package\n    \"longleftrightarrows\",\n    // From mhchem.sty package\n    \"xRightleftharpoons\",\n    // From mhchem.sty package\n    \"longRightleftharpoons\",\n    // From mhchem.sty package\n    \"xLeftrightharpoons\",\n    // From mhchem.sty package\n    \"longLeftrightharpoons\"\n    // From mhchem.sty package\n  ],\n  \"[:auto]{:auto}\",\n  {\n    createAtom: (options) => {\n      var _a3, _b3, _c2, _d2, _e;\n      return new OverunderAtom(__spreadProps(__spreadValues({}, options), {\n        // Set the \"svgBody\" to the name of a SVG object (which is the same\n        // as the command name)\n        svgBody: options.command.slice(1),\n        // The overscript is optional, i.e. `\\xtofrom` is valid\n        above: ((_b3 = argAtoms((_a3 = options.args) == null ? void 0 : _a3[1])) == null ? void 0 : _b3.length) === 0 ? void 0 : argAtoms((_c2 = options.args) == null ? void 0 : _c2[1]),\n        below: (_e = argAtoms((_d2 = options.args) == null ? void 0 : _d2[0])) != null ? _e : null,\n        skipBoundary: false,\n        supsubPlacement: \"over-under\",\n        paddedBody: true,\n        paddedLabels: true,\n        boxType: \"rel\"\n      }));\n    },\n    serialize: (atom, options) => atom.command + (!atom.hasEmptyBranch(\"below\") ? `[${atom.belowToLatex(options)}]` : \"\") + `{${atom.aboveToLatex(options)}}${atom.supsubToLatex(options)}`\n  }\n);\n\n// src/latex-commands/functions.ts\ndefineFunction(\n  [\n    \"arccos\",\n    \"arcsin\",\n    \"arctan\",\n    \"arctg\",\n    // Not LaTeX standard. Used in France\n    \"arcctg\",\n    // Not LaTeX standard. Used in France\n    \"arg\",\n    \"ch\",\n    // Not LaTeX standard. \\cosh\n    \"cos\",\n    \"cosh\",\n    \"cot\",\n    \"cotg\",\n    // Not LaTeX standard. Used in France\n    \"coth\",\n    \"ctg\",\n    // Not LaTeX standard. Used in France\n    \"cth\",\n    \"csc\",\n    // Not LaTeX standard. \\cth\n    \"cosec\",\n    // Not LaTeX standard.\n    \"deg\",\n    \"dim\",\n    \"exp\",\n    \"gcd\",\n    \"hom\",\n    \"inf\",\n    \"ker\",\n    \"lb\",\n    // Not LaTeX standard. US Dept of Commerce recommendation for log2\n    \"lg\",\n    // Not LaTeX standard. In German and Russian literature,  log10.\n    // Sometimes used as the log2\n    \"ln\",\n    \"log\",\n    \"Pr\",\n    \"sec\",\n    \"sh\",\n    // Not LaTeX standard. \\sinh\n    \"sin\",\n    \"sinh\",\n    \"sup\",\n    \"tan\",\n    \"tanh\",\n    \"tg\",\n    // Not LaTeX standard. Used in France\n    \"th\",\n    // Not LaTeX standard. \\tanh\n    \"arcsec\",\n    \"arccsc\",\n    \"arsinh\",\n    \"arcosh\",\n    \"artanh\",\n    \"arcsech\",\n    \"arccsch\"\n  ],\n  \"\",\n  {\n    isFunction: true,\n    ifMode: \"math\",\n    createAtom: (options) => new OperatorAtom(options.command.slice(1), __spreadProps(__spreadValues({}, options), {\n      limits: \"adjacent\",\n      isFunction: true,\n      variant: \"main\",\n      variantStyle: \"up\"\n    }))\n  }\n);\ndefineFunction([\"liminf\", \"limsup\"], \"\", {\n  ifMode: \"math\",\n  createAtom: (options) => new OperatorAtom(\n    { \"\\\\liminf\": \"lim inf\", \"\\\\limsup\": \"lim sup\" }[options.command],\n    __spreadProps(__spreadValues({}, options), { limits: \"over-under\", variant: \"main\" })\n  )\n});\ndefineFunction([\"lim\", \"mod\"], \"\", {\n  ifMode: \"math\",\n  createAtom: (options) => new OperatorAtom(options.command.slice(1), __spreadProps(__spreadValues({}, options), {\n    limits: \"over-under\",\n    variant: \"main\"\n  }))\n});\ndefineFunction([\"det\", \"max\", \"min\"], \"\", {\n  ifMode: \"math\",\n  isFunction: true,\n  createAtom: (options) => new OperatorAtom(options.command.slice(1), __spreadProps(__spreadValues({}, options), {\n    limits: \"over-under\",\n    isFunction: true,\n    variant: \"main\"\n  }))\n});\ndefineFunction([\"ang\"], \"{:math}\", {\n  ifMode: \"math\",\n  createAtom: (options) => new Atom(__spreadProps(__spreadValues({}, options), { body: argAtoms(options.args[0]) })),\n  serialize: (atom, options) => `\\\\ang{${atom.bodyToLatex(options)}}`,\n  render: (atom, context) => {\n    const box = atom.createBox(context);\n    const caret = box.caret;\n    box.caret = void 0;\n    const deg = new Box(\"\\xB0\", {\n      style: __spreadProps(__spreadValues({}, atom.style), { variant: \"normal\", variantStyle: \"up\" })\n    });\n    return new Box([box, deg], {\n      type: \"inner\",\n      isSelected: atom.isSelected,\n      caret\n    });\n  }\n});\ndefineFunction(\"sqrt\", \"[index:auto]{radicand:expression}\", {\n  ifMode: \"math\",\n  createAtom: (options) => new SurdAtom(__spreadProps(__spreadValues({}, options), {\n    body: argAtoms(options.args[1]),\n    index: options.args[0] ? argAtoms(options.args[0]) : void 0\n  }))\n});\ndefineFunction(\n  [\"frac\", \"dfrac\", \"tfrac\", \"binom\", \"dbinom\", \"tbinom\"],\n  \"{:expression}{:expression}\",\n  {\n    ifMode: \"math\",\n    createAtom: (options) => {\n      const genfracOptions = __spreadValues({}, options);\n      const command = options.command;\n      const args = options.args;\n      switch (command) {\n        case \"\\\\dfrac\":\n        case \"\\\\frac\":\n        case \"\\\\tfrac\":\n          genfracOptions.hasBarLine = true;\n          break;\n        case \"\\\\atopfrac\":\n          genfracOptions.hasBarLine = false;\n          break;\n        case \"\\\\dbinom\":\n        case \"\\\\binom\":\n        case \"\\\\tbinom\":\n          genfracOptions.hasBarLine = false;\n          genfracOptions.leftDelim = \"(\";\n          genfracOptions.rightDelim = \")\";\n          break;\n        case \"\\\\cfrac\":\n          genfracOptions.hasBarLine = true;\n          genfracOptions.continuousFraction = true;\n          break;\n        default:\n      }\n      switch (command) {\n        case \"\\\\dfrac\":\n        case \"\\\\dbinom\":\n          genfracOptions.mathstyleName = \"displaystyle\";\n          break;\n        case \"\\\\tfrac\":\n        case \"\\\\tbinom\":\n          genfracOptions.mathstyleName = \"textstyle\";\n          break;\n        default:\n      }\n      return new GenfracAtom(\n        !args[0] ? [new PlaceholderAtom()] : argAtoms(args[0]),\n        !args[1] ? [new PlaceholderAtom()] : argAtoms(args[1]),\n        genfracOptions\n      );\n    },\n    serialize: (atom, options) => {\n      const numer = atom.aboveToLatex(options);\n      const denom = atom.belowToLatex(options);\n      if (/^[0-9]$/.test(numer) && /^[0-9]$/.test(denom))\n        return `${atom.command}${numer}${denom}`;\n      return latexCommand(atom.command, numer, denom);\n    }\n  }\n);\ndefineFunction([\"cfrac\"], \"[:string]{:expression}{:expression}\", {\n  ifMode: \"math\",\n  createAtom: (options) => {\n    const genfracOptions = __spreadValues({}, options);\n    const args = options.args;\n    genfracOptions.hasBarLine = true;\n    genfracOptions.continuousFraction = true;\n    if (args[0] === \"r\") genfracOptions.align = \"right\";\n    if (args[0] === \"l\") genfracOptions.align = \"left\";\n    return new GenfracAtom(\n      !args[1] ? [new PlaceholderAtom()] : argAtoms(args[1]),\n      !args[2] ? [new PlaceholderAtom()] : argAtoms(args[2]),\n      genfracOptions\n    );\n  },\n  serialize: (atom, options) => {\n    const numer = atom.aboveToLatex(options);\n    const denom = atom.belowToLatex(options);\n    return latexCommand(atom.command, numer, denom);\n  }\n});\ndefineFunction([\"brace\", \"brack\"], \"\", {\n  infix: true,\n  createAtom: (options) => new GenfracAtom(argAtoms(options.args[0]), argAtoms(options.args[1]), __spreadProps(__spreadValues({}, options), {\n    hasBarLine: false,\n    leftDelim: options.command === \"\\\\brace\" ? \"\\\\lbrace\" : \"\\\\lbrack\",\n    rightDelim: options.command === \"\\\\brace\" ? \"\\\\rbrace\" : \"\\\\rbrack\"\n  })),\n  serialize: (atom, options) => joinLatex([\n    atom.aboveToLatex(options),\n    atom.command,\n    atom.belowToLatex(options)\n  ])\n});\ndefineFunction([\"over\", \"atop\", \"choose\"], \"\", {\n  infix: true,\n  createAtom: (options) => {\n    let leftDelim = void 0;\n    let rightDelim = void 0;\n    const args = options.args;\n    if (options.command === \"\\\\choose\") {\n      leftDelim = \"(\";\n      rightDelim = \")\";\n    }\n    return new GenfracAtom(argAtoms(args[0]), argAtoms(args[1]), __spreadProps(__spreadValues({}, options), {\n      hasBarLine: options.command === \"\\\\over\",\n      leftDelim,\n      rightDelim\n    }));\n  },\n  serialize: (atom, options) => joinLatex([\n    atom.aboveToLatex(options),\n    atom.command,\n    atom.belowToLatex(options)\n  ])\n});\ndefineFunction(\n  [\"overwithdelims\", \"atopwithdelims\"],\n  \"{numer:auto}{denom:auto}{left-delim:delim}{right-delim:delim}\",\n  {\n    infix: true,\n    createAtom: (options) => {\n      var _a3, _b3;\n      const args = options.args;\n      return new GenfracAtom(argAtoms(args[0]), argAtoms(args[1]), __spreadProps(__spreadValues({}, options), {\n        leftDelim: (_a3 = args[2]) != null ? _a3 : \".\",\n        rightDelim: (_b3 = args[3]) != null ? _b3 : \".\",\n        hasBarLine: false\n      }));\n    },\n    serialize: (atom, options) => `${atom.aboveToLatex(options)} ${atom.command}${atom.leftDelim}${atom.rightDelim}${atom.belowToLatex(options)}`\n  }\n);\ndefineFunction(\"pdiff\", \"{numerator}{denominator}\", {\n  ifMode: \"math\",\n  createAtom: (options) => new GenfracAtom(argAtoms(options.args[0]), argAtoms(options.args[1]), __spreadProps(__spreadValues({}, options), {\n    hasBarLine: true,\n    numerPrefix: \"\\u2202\",\n    denomPrefix: \"\\u2202\"\n  }))\n});\ndefineFunction(\n  [\n    \"sum\",\n    \"prod\",\n    \"bigcup\",\n    \"bigcap\",\n    \"coprod\",\n    \"bigvee\",\n    \"bigwedge\",\n    \"biguplus\",\n    \"bigotimes\",\n    \"bigoplus\",\n    \"bigodot\",\n    \"bigsqcup\",\n    \"intop\"\n  ],\n  \"\",\n  {\n    ifMode: \"math\",\n    createAtom: (options) => new ExtensibleSymbolAtom(\n      {\n        coprod: \"\\u2210\",\n        bigvee: \"\\u22C1\",\n        bigwedge: \"\\u22C0\",\n        biguplus: \"\\u2A04\",\n        bigcap: \"\\u22C2\",\n        bigcup: \"\\u22C3\",\n        intop: \"\\u222B\",\n        prod: \"\\u220F\",\n        sum: \"\\u2211\",\n        bigotimes: \"\\u2A02\",\n        bigoplus: \"\\u2A01\",\n        bigodot: \"\\u2A00\",\n        bigsqcup: \"\\u2A06\",\n        smallint: \"\\u222B\"\n      }[options.command.slice(1)],\n      __spreadProps(__spreadValues({}, options), {\n        limits: \"auto\",\n        variant: \"main\"\n      })\n    )\n  }\n);\ndefineFunction(\"smallint\", \"\", {\n  ifMode: \"math\",\n  createAtom: (options) => new OperatorAtom(\"\\u222B\", __spreadProps(__spreadValues({}, options), {\n    limits: \"adjacent\",\n    variant: \"main\"\n  }))\n});\nvar EXTENSIBLE_SYMBOLS = {\n  int: \"\\u222B\",\n  iint: \"\\u222C\",\n  iiint: \"\\u222D\",\n  oint: \"\\u222E\",\n  oiint: \"\\u222F\",\n  oiiint: \"\\u2230\",\n  intclockwise: \"\\u2231\",\n  varointclockwise: \"\\u2232\",\n  ointctrclockwise: \"\\u2233\",\n  intctrclockwise: \"\\u2A11\",\n  sqcup: \"\\u2294\",\n  sqcap: \"\\u2293\",\n  uplus: \"\\u228E\",\n  wr: \"\\u2240\",\n  amalg: \"\\u2A3F\",\n  Cap: \"\\u22D2\",\n  Cup: \"\\u22D3\",\n  doublecap: \"\\u22D2\",\n  doublecup: \"\\u22D3\"\n};\ndefineFunction(Object.keys(EXTENSIBLE_SYMBOLS), \"\", {\n  ifMode: \"math\",\n  createAtom: (options) => {\n    const command = options.command;\n    const symbol = EXTENSIBLE_SYMBOLS[command.slice(1)];\n    return new ExtensibleSymbolAtom(symbol, __spreadProps(__spreadValues({}, options), {\n      limits: \"adjacent\",\n      variant: { \"\\u22D2\": \"ams\", \"\\u22D3\": \"ams\" }[symbol]\n    }));\n  }\n});\ndefineFunction([\"Re\", \"Im\"], \"\", {\n  ifMode: \"math\",\n  createAtom: (options) => new OperatorAtom(\n    { \"\\\\Re\": \"\\u211C\", \"\\\\Im\": \"\\u2111\" }[options.command],\n    __spreadProps(__spreadValues({}, options), {\n      limits: \"adjacent\",\n      isFunction: true,\n      variant: \"fraktur\"\n    })\n  )\n});\ndefineFunction(\"middle\", \"{:delim}\", {\n  ifMode: \"math\",\n  createAtom: (options) => {\n    var _a3;\n    return new MiddleDelimAtom(__spreadProps(__spreadValues({}, options), {\n      delim: (_a3 = options.args[0]) != null ? _a3 : \"|\",\n      size: 1\n    }));\n  }\n});\ndefineFunction(\"the\", \"{:value}\", {\n  createAtom: (options) => new Atom(__spreadProps(__spreadValues({}, options), {\n    captureSelection: true,\n    verbatimLatex: null\n    // disable verbatim LaTeX\n  })),\n  render: (atom, parent) => {\n    var _a3;\n    const ctx = new Context({ parent }, atom.style);\n    let classes = \"\";\n    if (atom.isSelected) classes += \" ML__selected\";\n    const arg = ctx.evaluate(atom.args[0]);\n    return new Box(\n      ((_a3 = serializeLatexValue(arg)) != null ? _a3 : \"\").split(\"\").map(\n        (x) => new Box(x, {\n          type: \"ord\",\n          classes,\n          mode: atom.mode,\n          isSelected: atom.isSelected,\n          style: __spreadValues({ variant: \"main\" }, atom.style)\n        })\n      ),\n      {\n        type: \"lift\",\n        style: atom.style,\n        caret: atom.caret,\n        isSelected: atom.isSelected,\n        classes\n      }\n    ).wrap(ctx);\n  },\n  serialize: (atom) => {\n    var _a3;\n    return `\\\\the${(_a3 = serializeLatexValue(atom.args[0])) != null ? _a3 : \"\\\\relax\"}`;\n  }\n});\n\n// src/latex-commands/styling.ts\ndefineFunction(\"mathtip\", \"{:auto}{:math}\", {\n  createAtom: (options) => new TooltipAtom(__spreadProps(__spreadValues({}, options), {\n    body: argAtoms(options.args[0]),\n    tooltip: argAtoms(options.args[1]),\n    content: \"math\"\n  })),\n  serialize: (atom, options) => options.skipStyles ? atom.bodyToLatex(options) : `\\\\texttip{${atom.bodyToLatex(options)}}{${Atom.serialize(\n    [atom.tooltip],\n    __spreadProps(__spreadValues({}, options), {\n      defaultMode: \"math\"\n    })\n  )}}`\n});\ndefineFunction(\"texttip\", \"{:auto}{:text}\", {\n  createAtom: (options) => new TooltipAtom(__spreadProps(__spreadValues({}, options), {\n    body: argAtoms(options.args[0]),\n    tooltip: argAtoms(options.args[1]),\n    content: \"text\"\n  })),\n  serialize: (atom, options) => options.skipStyles ? atom.bodyToLatex(options) : `\\\\texttip{${atom.bodyToLatex(options)}}{${Atom.serialize(\n    [atom.tooltip],\n    __spreadProps(__spreadValues({}, options), {\n      defaultMode: \"text\"\n    })\n  )}}`\n});\ndefineFunction(\"error\", \"{:math}\", {\n  createAtom: (options) => new Atom(__spreadProps(__spreadValues({}, options), { body: argAtoms(options.args[0]) })),\n  serialize: (atom, options) => `\\\\error{${atom.bodyToLatex(options)}}`,\n  render: (atom, context) => atom.createBox(context, { classes: \"ML__error\" })\n});\ndefineFunction(\"ensuremath\", \"{:math}\", {\n  createAtom: (options) => new Atom(__spreadProps(__spreadValues({}, options), { body: argAtoms(options.args[0]) })),\n  serialize: (atom, options) => `${atom.command}{${atom.bodyToLatex(__spreadProps(__spreadValues({}, options), { defaultMode: \"math\" }))}}`\n});\ndefineFunction(\"color\", \"{:value}\", {\n  applyStyle: (style, _name, args, context) => {\n    var _a3, _b3;\n    return __spreadProps(__spreadValues({}, style), {\n      verbatimColor: (_a3 = serializeLatexValue(args[0])) != null ? _a3 : void 0,\n      color: context.toColor((_b3 = args[0]) != null ? _b3 : { string: \"red\" })\n    });\n  }\n});\ndefineFunction(\"textcolor\", \"{:value}{content:auto*}\", {\n  applyStyle: (style, _name, args, context) => {\n    var _a3, _b3;\n    return __spreadProps(__spreadValues({}, style), {\n      verbatimColor: (_a3 = serializeLatexValue(args[0])) != null ? _a3 : void 0,\n      color: context.toColor((_b3 = args[0]) != null ? _b3 : { string: \"red\" })\n    });\n  }\n});\ndefineFunction(\"boxed\", \"{content:math}\", {\n  createAtom: (options) => new BoxAtom(__spreadProps(__spreadValues({}, options), {\n    body: argAtoms(options.args[0]),\n    framecolor: { string: \"black\" }\n  }))\n});\ndefineFunction(\"colorbox\", \"{:value}{:text*}\", {\n  applyStyle: (style, _name, args, context) => {\n    var _a3, _b3;\n    return __spreadProps(__spreadValues({}, style), {\n      verbatimBackgroundColor: (_a3 = serializeLatexValue(args[0])) != null ? _a3 : void 0,\n      backgroundColor: context.toBackgroundColor(\n        (_b3 = args[0]) != null ? _b3 : { string: \"yellow\" }\n      )\n    });\n  }\n});\ndefineFunction(\n  \"fcolorbox\",\n  \"{frame-color:value}{background-color:value}{content:text}\",\n  {\n    applyMode: \"text\",\n    createAtom: (options) => {\n      var _a3, _b3;\n      return new BoxAtom(__spreadProps(__spreadValues({}, options), {\n        body: argAtoms(options.args[2]),\n        framecolor: (_a3 = options.args[0]) != null ? _a3 : { string: \"blue\" },\n        backgroundcolor: (_b3 = options.args[1]) != null ? _b3 : { string: \"yellow\" }\n      }));\n    },\n    serialize: (atom, options) => {\n      var _a3, _b3;\n      return options.skipStyles ? atom.bodyToLatex(__spreadProps(__spreadValues({}, options), { defaultMode: \"text\" })) : latexCommand(\n        atom.command,\n        (_a3 = serializeLatexValue(atom.framecolor)) != null ? _a3 : \"\",\n        (_b3 = serializeLatexValue(atom.backgroundcolor)) != null ? _b3 : \"\",\n        atom.bodyToLatex(__spreadProps(__spreadValues({}, options), { defaultMode: \"text\" }))\n      );\n    }\n  }\n);\ndefineFunction(\"bbox\", \"[:bbox]{body:auto}\", {\n  createAtom: (options) => {\n    var _a3;\n    const arg = options.args[0];\n    const body = argAtoms(options.args[1]);\n    if (!arg) return new BoxAtom(__spreadProps(__spreadValues({}, options), { body }));\n    return new BoxAtom(__spreadProps(__spreadValues({}, options), {\n      body,\n      padding: arg.padding,\n      border: arg.border,\n      backgroundcolor: (_a3 = arg.backgroundcolor) != null ? _a3 : void 0\n    }));\n  },\n  serialize: (atom, options) => {\n    var _a3, _b3;\n    if (options.skipStyles) return atom.bodyToLatex(options);\n    let result = atom.command;\n    if (Number.isFinite(atom.padding) || atom.border !== void 0 || atom.backgroundcolor !== void 0) {\n      const bboxParameters = [];\n      if (atom.padding)\n        bboxParameters.push((_a3 = serializeLatexValue(atom.padding)) != null ? _a3 : \"\");\n      if (atom.border) bboxParameters.push(`border: ${atom.border}`);\n      if (atom.backgroundcolor)\n        bboxParameters.push((_b3 = serializeLatexValue(atom.backgroundcolor)) != null ? _b3 : \"\");\n      result += `[${bboxParameters.join(\",\")}]`;\n    }\n    return latexCommand(result, atom.bodyToLatex(options));\n  }\n});\ndefineFunction(\n  [\"displaystyle\", \"textstyle\", \"scriptstyle\", \"scriptscriptstyle\"],\n  \"{:rest}\",\n  {\n    createAtom: (options) => new Atom(__spreadProps(__spreadValues({}, options), { body: argAtoms(options.args[0]) })),\n    render: (atom, context) => {\n      const ctx = new Context(\n        { parent: context, mathstyle: atom.command.slice(1) },\n        atom.style\n      );\n      const box = Atom.createBox(ctx, atom.body, { type: \"lift\" });\n      if (atom.caret) box.caret = atom.caret;\n      return atom.bind(context, box);\n    },\n    serialize: (atom, options) => options.skipStyles ? atom.bodyToLatex(options) : `{${joinLatex([atom.command, atom.bodyToLatex(options)])}}`\n  }\n);\ndefineFunction(\n  [\n    \"tiny\",\n    \"scriptsize\",\n    \"footnotesize\",\n    \"small\",\n    \"normalsize\",\n    \"large\",\n    \"Large\",\n    \"LARGE\",\n    \"huge\",\n    \"Huge\"\n  ],\n  \"\",\n  {\n    // TeX behaves very inconsistently when sizing commands are applied\n    // to math mode. We allow sizing commands to be applied in both math and\n    // text mode\n    applyStyle: (style, name) => {\n      return __spreadProps(__spreadValues({}, style), {\n        fontSize: {\n          \"\\\\tiny\": 1,\n          \"\\\\scriptsize\": 2,\n          // Not to be confused with \\scriptstyle\n          \"\\\\footnotesize\": 3,\n          \"\\\\small\": 4,\n          \"\\\\normalsize\": 5,\n          \"\\\\large\": 6,\n          \"\\\\Large\": 7,\n          \"\\\\LARGE\": 8,\n          \"\\\\huge\": 9,\n          \"\\\\Huge\": 10\n        }[name]\n      });\n    }\n  }\n);\ndefineFunction(\"fontseries\", \"{:string}\", {\n  ifMode: \"text\",\n  applyStyle: (style, _name, args) => {\n    var _a3;\n    return __spreadProps(__spreadValues({}, style), { fontSeries: (_a3 = args[0]) != null ? _a3 : \"auto\" });\n  }\n});\ndefineFunction(\"fontshape\", \"{:string}\", {\n  ifMode: \"text\",\n  applyStyle: (style, _name, args) => {\n    var _a3;\n    return __spreadProps(__spreadValues({}, style), { fontShape: (_a3 = args[0]) != null ? _a3 : \"auto\" });\n  }\n});\ndefineFunction(\"fontfamily\", \"{:string}\", {\n  ifMode: \"text\",\n  applyStyle: (style, _name, args) => {\n    var _a3;\n    return __spreadProps(__spreadValues({}, style), { fontFamily: (_a3 = args[0]) != null ? _a3 : \"roman\" });\n  }\n});\ndefineFunction(\"selectfont\", \"\", {\n  ifMode: \"text\",\n  applyStyle: (style) => style\n});\ndefineFunction(\"bf\", \"{:rest*}\", {\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), {\n    fontSeries: \"b\",\n    fontShape: \"n\",\n    fontFamily: \"roman\"\n  })\n});\ndefineFunction([\"boldsymbol\", \"bm\", \"bold\"], \"{:math*}\", {\n  applyMode: \"math\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), { variantStyle: \"bold\" })\n});\ndefineFunction(\"bfseries\", \"{:rest*}\", {\n  applyMode: \"text\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), { fontSeries: \"b\" })\n});\ndefineFunction(\"mdseries\", \"{:rest*}\", {\n  applyMode: \"text\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), { fontSeries: \"m\" })\n});\ndefineFunction(\"upshape\", \"{:rest*}\", {\n  applyMode: \"text\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), { fontShape: \"n\" })\n});\ndefineFunction(\"slshape\", \"{:rest*}\", {\n  applyMode: \"text\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), { fontShape: \"sl\" })\n});\ndefineFunction(\"scshape\", \"{:rest*}\", {\n  applyMode: \"text\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), { fontShape: \"sc\" })\n});\ndefineFunction(\"textbf\", \"{:text*}\", {\n  applyMode: \"text\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), { fontSeries: \"b\" })\n});\ndefineFunction(\"textmd\", \"{:text*}\", {\n  applyMode: \"text\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), { fontSeries: \"m\" })\n});\ndefineFunction(\"textup\", \"{:text*}\", {\n  applyMode: \"text\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), { fontShape: \"n\" })\n});\ndefineFunction(\"textnormal\", \"{:text*}\", {\n  applyMode: \"text\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), { fontShape: \"n\", fontSeries: \"m\" })\n});\ndefineFunction(\"textsl\", \"{:text*}\", {\n  applyMode: \"text\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), { fontShape: \"sl\" })\n});\ndefineFunction(\"textit\", \"{:text*}\", {\n  applyMode: \"text\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), { fontShape: \"it\" })\n});\ndefineFunction(\"textsc\", \"{:text*}\", {\n  applyMode: \"text\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), { fontShape: \"sc\" })\n});\ndefineFunction(\"textrm\", \"{:text*}\", {\n  applyMode: \"text\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), { fontFamily: \"roman\" })\n});\ndefineFunction(\"textsf\", \"{:text*}\", {\n  applyMode: \"text\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), { fontFamily: \"sans-serif\" })\n});\ndefineFunction(\"texttt\", \"{:text*}\", {\n  applyMode: \"text\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), { fontFamily: \"monospace\" })\n});\ndefineFunction(\"mathbf\", \"{:math*}\", {\n  applyMode: \"math\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), {\n    variant: \"normal\",\n    variantStyle: \"bold\"\n  })\n});\ndefineFunction(\"mathit\", \"{:math*}\", {\n  applyMode: \"math\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), {\n    variant: \"main\",\n    variantStyle: \"italic\"\n  })\n});\ndefineFunction(\"mathnormal\", \"{:math*}\", {\n  applyMode: \"math\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), {\n    variant: \"normal\",\n    variantStyle: \"italic\"\n  })\n});\ndefineFunction(\"mathbfit\", \"{:math*}\", {\n  applyMode: \"math\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), {\n    variant: \"main\",\n    variantStyle: \"bolditalic\"\n  })\n});\ndefineFunction(\"mathrm\", \"{:math*}\", {\n  applyMode: \"math\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), { variant: \"normal\", variantStyle: \"up\" })\n});\ndefineFunction(\"mathsf\", \"{:math*}\", {\n  applyMode: \"math\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), {\n    variant: \"sans-serif\",\n    variantStyle: \"up\"\n  })\n});\ndefineFunction(\"mathtt\", \"{:math*}\", {\n  applyMode: \"math\",\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), {\n    variant: \"monospace\",\n    variantStyle: \"up\"\n  })\n});\ndefineFunction(\"it\", \"{:rest*}\", {\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), {\n    fontSeries: \"m\",\n    fontShape: \"it\",\n    fontFamily: \"roman\",\n    variantStyle: \"italic\"\n    // For math mode\n  })\n});\ndefineFunction(\"rmfamily\", \"{:rest*}\", {\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), { fontFamily: \"roman\" })\n});\ndefineFunction(\"sffamily\", \"{:rest*}\", {\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), { fontFamily: \"sans-serif\" })\n});\ndefineFunction(\"ttfamily\", \"{:rest*}\", {\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), { fontFamily: \"monospace\" })\n});\ndefineFunction([\"Bbb\", \"mathbb\"], \"{:math*}\", {\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), {\n    variant: \"double-struck\",\n    variantStyle: removeItalic(style.variantStyle)\n  })\n});\ndefineFunction([\"frak\", \"mathfrak\"], \"{:math*}\", {\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), {\n    variant: \"fraktur\",\n    variantStyle: removeItalic(style.variantStyle)\n  })\n});\ndefineFunction(\"mathcal\", \"{:math*}\", {\n  // Note that in LaTeX, \\mathcal forces the 'up' variant. Use \\bm to get bold\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), {\n    variant: \"calligraphic\",\n    variantStyle: removeItalic(style.variantStyle)\n  })\n});\ndefineFunction(\"mathscr\", \"{:math*}\", {\n  applyStyle: (style) => __spreadProps(__spreadValues({}, style), {\n    variant: \"script\",\n    variantStyle: removeItalic(style.variantStyle)\n  })\n});\ndefineFunction(\"mbox\", \"{:text}\", {\n  ifMode: \"math\",\n  createAtom: (options) => new Atom(__spreadProps(__spreadValues({}, options), {\n    type: \"mord\",\n    body: argAtoms(options.args[0]),\n    mode: \"math\"\n  })),\n  serialize: (atom, options) => latexCommand(\n    \"\\\\mbox\",\n    atom.bodyToLatex(__spreadProps(__spreadValues({}, options), { defaultMode: \"text\" }))\n  )\n});\ndefineFunction(\"text\", \"{:text}\", {\n  ifMode: \"math\",\n  applyMode: \"text\"\n});\ndefineFunction([\"class\", \"htmlClass\"], \"{name:string}{content:auto}\", {\n  createAtom: (options) => new Atom(__spreadProps(__spreadValues({}, options), { body: argAtoms(options.args[1]) })),\n  serialize: (atom, options) => {\n    if (!atom.args[0] || options.skipStyles) return atom.bodyToLatex(options);\n    return `${atom.command}{${atom.args[0]}}{${atom.bodyToLatex(\n      options\n    )}}`;\n  },\n  render: (atom, context) => {\n    var _a3;\n    return atom.createBox(context, { classes: (_a3 = atom.args[0]) != null ? _a3 : \"\" });\n  }\n});\ndefineFunction([\"cssId\", \"htmlId\"], \"{id:string}{content:auto}\", {\n  createAtom: (options) => new Atom(__spreadProps(__spreadValues({}, options), { body: argAtoms(options.args[1]) })),\n  serialize: (atom, options) => {\n    var _a3;\n    if (!((_a3 = atom.args) == null ? void 0 : _a3[0]) || options.skipStyles) return atom.bodyToLatex(options);\n    return `${atom.command}{${atom.args[0]}}{${atom.bodyToLatex(\n      options\n    )}}`;\n  },\n  render: (atom, context) => {\n    var _a3;\n    const box = atom.createBox(context);\n    box.cssId = (_a3 = atom.args[0]) != null ? _a3 : \"\";\n    return box;\n  }\n});\ndefineFunction(\"htmlData\", \"{data:string}{content:auto}\", {\n  createAtom: (options) => new Atom(__spreadProps(__spreadValues({}, options), { body: argAtoms(options.args[1]) })),\n  serialize: (atom, options) => {\n    var _a3;\n    if (!((_a3 = atom.args) == null ? void 0 : _a3[0]) || options.skipStyles) return atom.bodyToLatex(options);\n    return `\\\\htmlData{${atom.args[0]}}{${atom.bodyToLatex(\n      options\n    )}}`;\n  },\n  render: (atom, context) => {\n    var _a3;\n    const box = atom.createBox(context);\n    box.htmlData = (_a3 = atom.args[0]) != null ? _a3 : \"\";\n    return box;\n  }\n});\ndefineFunction([\"style\", \"htmlStyle\"], \"{data:string}{content:auto}\", {\n  createAtom: (options) => new Atom(__spreadProps(__spreadValues({}, options), { body: argAtoms(options.args[1]) })),\n  serialize: (atom, options) => {\n    var _a3;\n    if (!((_a3 = atom.args) == null ? void 0 : _a3[0]) || options.skipStyles) return atom.bodyToLatex(options);\n    return `${atom.command}{${atom.args[0]}}{${atom.bodyToLatex(\n      options\n    )}}`;\n  },\n  render: (atom, context) => {\n    var _a3;\n    const box = atom.createBox(context);\n    box.htmlStyle = (_a3 = atom.args[0]) != null ? _a3 : \"\";\n    return box;\n  }\n});\ndefineFunction(\"href\", \"{url:string}{content:auto}\", {\n  createAtom: (options) => new Atom(__spreadProps(__spreadValues({}, options), { body: argAtoms(options.args[1]) })),\n  render: (atom, context) => {\n    var _a3;\n    const box = atom.createBox(context);\n    const href = (_a3 = atom.args[0]) != null ? _a3 : \"\";\n    if (href) box.htmlData = `href=${href}`;\n    return box;\n  }\n});\ndefineFunction(\"em\", \"{:rest}\", {\n  createAtom: (options) => new Atom(__spreadProps(__spreadValues({}, options), { body: argAtoms(options.args[0]) })),\n  serialize: (atom, options) => options.skipStyles ? atom.bodyToLatex(options) : `{\\\\em ${atom.bodyToLatex(options)}}`,\n  render: (atom, context) => atom.createBox(context, { classes: \"ML__emph\", boxType: \"lift\" })\n});\ndefineFunction(\"emph\", \"{:auto}\", {\n  createAtom: (options) => new Atom(__spreadProps(__spreadValues({}, options), { body: argAtoms(options.args[1]) })),\n  serialize: (atom, options) => options.skipStyles ? atom.bodyToLatex(options) : `\\\\emph{${atom.bodyToLatex(options)}}`,\n  render: (atom, context) => atom.createBox(context, { classes: \"ML__emph\", boxType: \"lift\" })\n});\nvar DELIMITER_SIZES = {\n  \"\\\\bigl\": { mclass: \"mopen\", size: 1 },\n  \"\\\\Bigl\": { mclass: \"mopen\", size: 2 },\n  \"\\\\biggl\": { mclass: \"mopen\", size: 3 },\n  \"\\\\Biggl\": { mclass: \"mopen\", size: 4 },\n  \"\\\\bigr\": { mclass: \"mclose\", size: 1 },\n  \"\\\\Bigr\": { mclass: \"mclose\", size: 2 },\n  \"\\\\biggr\": { mclass: \"mclose\", size: 3 },\n  \"\\\\Biggr\": { mclass: \"mclose\", size: 4 },\n  \"\\\\bigm\": { mclass: \"mrel\", size: 1 },\n  \"\\\\Bigm\": { mclass: \"mrel\", size: 2 },\n  \"\\\\biggm\": { mclass: \"mrel\", size: 3 },\n  \"\\\\Biggm\": { mclass: \"mrel\", size: 4 },\n  \"\\\\big\": { mclass: \"mord\", size: 1 },\n  \"\\\\Big\": { mclass: \"mord\", size: 2 },\n  \"\\\\bigg\": { mclass: \"mord\", size: 3 },\n  \"\\\\Bigg\": { mclass: \"mord\", size: 4 }\n};\ndefineFunction(\n  [\n    \"bigl\",\n    \"Bigl\",\n    \"biggl\",\n    \"Biggl\",\n    \"bigr\",\n    \"Bigr\",\n    \"biggr\",\n    \"Biggr\",\n    \"bigm\",\n    \"Bigm\",\n    \"biggm\",\n    \"Biggm\",\n    \"big\",\n    \"Big\",\n    \"bigg\",\n    \"Bigg\"\n  ],\n  \"{:delim}\",\n  {\n    createAtom: (options) => {\n      var _a3;\n      return new SizedDelimAtom(__spreadProps(__spreadValues({}, options), {\n        delim: (_a3 = options.args[0]) != null ? _a3 : \".\",\n        size: DELIMITER_SIZES[options.command].size,\n        delimType: DELIMITER_SIZES[options.command].mclass\n      }));\n    }\n  }\n);\ndefineFunction(\n  [\n    \"hspace\",\n    \"hspace*\"\n    // \\hspace* inserts a non-breakable space, but since we don't line break...\n    // it's the same as \\hspace.\n  ],\n  \"{width:value}\",\n  {\n    createAtom: (options) => {\n      var _a3;\n      return new SpacingAtom(__spreadProps(__spreadValues({}, options), {\n        width: (_a3 = options.args[0]) != null ? _a3 : { dimension: 0 }\n      }));\n    }\n  }\n);\ndefineFunction([\"mkern\", \"kern\", \"mskip\", \"hskip\", \"mspace\"], \"{width:value}\", {\n  createAtom: (options) => {\n    var _a3;\n    return new SpacingAtom(__spreadProps(__spreadValues({}, options), {\n      width: (_a3 = options.args[0]) != null ? _a3 : { dimension: 0 }\n    }));\n  }\n});\ndefineFunction(\"mathchoice\", \"{:math}{:math}{:math}{:math}\", {\n  // display, text, script and scriptscript\n  createAtom: (options) => new Atom(options),\n  render: (atom, context) => {\n    let i = 0;\n    const d = context.mathstyle.id;\n    if (d === T || d === Tc) i = 1;\n    if (d === S || d === Sc) i = 2;\n    if (d === SS || d === SSc) i = 3;\n    const body = argAtoms(atom.args[i]);\n    return Atom.createBox(context, body);\n  },\n  serialize: (atom, options) => `\\\\mathchoice{${Atom.serialize(\n    atom.args[0],\n    options\n  )}}{${Atom.serialize(atom.args[1], options)}}{${Atom.serialize(\n    atom.args[2],\n    options\n  )}}{${Atom.serialize(atom.args[3], options)}}`\n});\ndefineFunction(\"mathop\", \"{:auto}\", {\n  createAtom: (options) => new Atom(__spreadProps(__spreadValues({}, options), {\n    type: \"mop\",\n    body: argAtoms(options.args[0]),\n    limits: \"over-under\",\n    isFunction: true,\n    captureSelection: true\n  })),\n  render: (atom, context) => {\n    var _a3;\n    let base = Atom.createBox(context, atom.body);\n    if (atom.superscript || atom.subscript) {\n      const limits = (_a3 = atom.subsupPlacement) != null ? _a3 : \"auto\";\n      base = limits === \"over-under\" || limits === \"auto\" && context.isDisplayStyle ? atom.attachLimits(context, { base }) : atom.attachSupsub(context, { base });\n    }\n    return new Box(atom.bind(context, base), {\n      type: \"op\",\n      isSelected: atom.isSelected,\n      classes: \"ML__op-group\"\n    });\n  },\n  serialize: (atom, options) => {\n    const result = [latexCommand(atom.command, atom.bodyToLatex(options))];\n    if (atom.explicitSubsupPlacement) {\n      if (atom.subsupPlacement === \"over-under\") result.push(\"\\\\limits\");\n      if (atom.subsupPlacement === \"adjacent\") result.push(\"\\\\nolimits\");\n      if (atom.subsupPlacement === \"auto\") result.push(\"\\\\displaylimits\");\n    }\n    result.push(atom.supsubToLatex(options));\n    return joinLatex(result);\n  }\n});\ndefineFunction(\n  [\n    \"mathbin\",\n    \"mathrel\",\n    \"mathopen\",\n    \"mathclose\",\n    \"mathpunct\",\n    \"mathord\",\n    \"mathinner\"\n  ],\n  \"{:auto}\",\n  {\n    createAtom: (options) => new Atom(__spreadProps(__spreadValues({}, options), {\n      type: {\n        \"\\\\mathbin\": \"mbin\",\n        \"\\\\mathrel\": \"mrel\",\n        \"\\\\mathopen\": \"mopen\",\n        \"\\\\mathclose\": \"mclose\",\n        \"\\\\mathpunct\": \"mpunct\",\n        \"\\\\mathord\": \"mord\",\n        \"\\\\mathinner\": \"minner\"\n      }[options.command],\n      body: argAtoms(options.args[0])\n    }))\n  }\n);\ndefineFunction([\"operatorname\", \"operatorname*\"], \"{operator:math}\", {\n  createAtom: (options) => {\n    const body = argAtoms(options.args[0]).map((x) => {\n      var _a3;\n      if (x.type !== \"first\") {\n        x.type = \"mord\";\n        x.value = (_a3 = { \"\\u2217\": \"*\", \"\\u2212\": \"-\" }[x.value]) != null ? _a3 : x.value;\n        x.isFunction = false;\n        if (!x.style.variant && !x.style.variantStyle) {\n          x.style.variant = \"main\";\n          x.style.variantStyle = \"up\";\n        }\n      }\n      return x;\n    });\n    return new Atom(__spreadProps(__spreadValues({}, options), {\n      type: \"mop\",\n      body,\n      isFunction: true,\n      limits: options.command === \"\\\\operatorname\" ? \"adjacent\" : \"over-under\"\n    }));\n  },\n  render: (atom, context) => {\n    var _a3;\n    let base = Atom.createBox(context, atom.body);\n    if (atom.superscript || atom.subscript) {\n      const limits = (_a3 = atom.subsupPlacement) != null ? _a3 : \"auto\";\n      base = limits === \"over-under\" || limits === \"auto\" && context.isDisplayStyle ? atom.attachLimits(context, { base }) : atom.attachSupsub(context, { base });\n    }\n    if (atom.caret) base.caret = atom.caret;\n    return new Box(atom.bind(context, base), {\n      type: \"op\",\n      isSelected: atom.isSelected,\n      classes: \"ML__op-group\"\n    });\n  },\n  serialize: (atom, options) => {\n    const result = [latexCommand(atom.command, atom.bodyToLatex(options))];\n    if (atom.explicitSubsupPlacement) {\n      if (atom.subsupPlacement === \"over-under\") result.push(\"\\\\limits\");\n      if (atom.subsupPlacement === \"adjacent\") result.push(\"\\\\nolimits\");\n      if (atom.subsupPlacement === \"auto\") result.push(\"\\\\displaylimits\");\n    }\n    result.push(atom.supsubToLatex(options));\n    return joinLatex(result);\n  }\n});\ndefineFunction([\"char\", \"unicode\"], \"{charcode:value}\", {\n  createAtom: (options) => new Atom(__spreadProps(__spreadValues({}, options), { type: options.mode === \"text\" ? \"text\" : \"mord\" })),\n  serialize: (atom) => {\n    var _a3;\n    return `${atom.command}${serializeLatexValue(\n      (_a3 = atom.args[0]) != null ? _a3 : { number: 10067, base: \"hexadecimal\" }\n    )}`;\n  },\n  render: (atom, context) => {\n    let value = context.evaluate(atom.args[0]);\n    if (!value || !(\"number\" in value))\n      value = { number: 10067, base: \"hexadecimal\" };\n    atom.value = String.fromCodePoint(value.number);\n    return atom.createBox(context);\n  }\n});\ndefineFunction(\"rule\", \"[raise:value]{width:value}{thickness:value}\", {\n  createAtom: (options) => new Atom(options),\n  render: (atom, context) => {\n    var _a3, _b3, _c2;\n    const ctx = new Context(\n      { parent: context, mathstyle: \"textstyle\" },\n      atom.style\n    );\n    const shift = ctx.toEm((_a3 = atom.args[0]) != null ? _a3 : { dimension: 0 });\n    const width = ctx.toEm((_b3 = atom.args[1]) != null ? _b3 : { dimension: 10 });\n    const height = ctx.toEm((_c2 = atom.args[2]) != null ? _c2 : { dimension: 10 });\n    const result = new Box(null, {\n      classes: \"ML__rule\",\n      type: \"ord\"\n    });\n    result.width = width;\n    result.height = height + shift;\n    result.depth = -shift;\n    result.setStyle(\"border-right-width\", width, \"em\");\n    result.setStyle(\"border-top-width\", height, \"em\");\n    result.setStyle(\"border-color\", atom.style.color);\n    result.setStyle(\"vertical-align\", shift, \"em\");\n    if (atom.isSelected) result.setStyle(\"opacity\", \"50%\");\n    atom.bind(ctx, result);\n    if (atom.caret) result.caret = atom.caret;\n    return result.wrap(context);\n  },\n  serialize: (atom) => `\\\\rule${atom.args[0] ? `[${serializeLatexValue(atom.args[0])}]` : \"\"}{${serializeLatexValue(atom.args[1])}}{${serializeLatexValue(\n    atom.args[2]\n  )}}`\n});\ndefineFunction([\"overline\", \"underline\"], \"{:auto}\", {\n  createAtom: (options) => new Atom(__spreadProps(__spreadValues({}, options), { body: argAtoms(options.args[0]) })),\n  render: (atom, parentContext) => {\n    const position = atom.command.substring(1);\n    const context = new Context(\n      { parent: parentContext, mathstyle: \"cramp\" },\n      atom.style\n    );\n    const inner = Atom.createBox(context, atom.body);\n    if (!inner) return null;\n    const ruleThickness = context.metrics.defaultRuleThickness / context.scalingFactor;\n    const line = new Box(null, { classes: position + \"-line\" });\n    line.height = ruleThickness;\n    line.maxFontSize = ruleThickness * 1.125 * context.scalingFactor;\n    let stack;\n    if (position === \"overline\") {\n      stack = new VBox({\n        shift: 0,\n        children: [\n          { box: inner },\n          3 * ruleThickness,\n          { box: line },\n          ruleThickness\n        ]\n      });\n    } else {\n      stack = new VBox({\n        top: inner.height,\n        children: [\n          ruleThickness,\n          { box: line },\n          3 * ruleThickness,\n          { box: inner }\n        ]\n      });\n    }\n    if (atom.caret) stack.caret = atom.caret;\n    return new Box(stack, { classes: position, type: \"ignore\" });\n  }\n});\ndefineFunction(\"overset\", \"{:auto}{base:auto}\", {\n  createAtom: (options) => {\n    const body = argAtoms(options.args[1]);\n    return new OverunderAtom(__spreadProps(__spreadValues({}, options), {\n      above: argAtoms(options.args[0]),\n      body,\n      skipBoundary: false,\n      boxType: atomsBoxType(body)\n    }));\n  },\n  serialize: (atom, options) => latexCommand(\n    atom.command,\n    atom.aboveToLatex(options),\n    atom.bodyToLatex(options)\n  )\n});\ndefineFunction(\"underset\", \"{:auto}{base:auto}\", {\n  createAtom: (options) => {\n    const body = argAtoms(options.args[1]);\n    return new OverunderAtom(__spreadProps(__spreadValues({}, options), {\n      below: argAtoms(options.args[0]),\n      body,\n      skipBoundary: false,\n      boxType: atomsBoxType(body)\n    }));\n  },\n  serialize: (atom, options) => latexCommand(\n    atom.command,\n    atom.belowToLatex(options),\n    atom.bodyToLatex(options)\n  )\n});\ndefineFunction(\"overunderset\", \"{above:auto}{below:auto}{base:auto}\", {\n  createAtom: (options) => {\n    const body = argAtoms(options.args[2]);\n    return new OverunderAtom(__spreadProps(__spreadValues({}, options), {\n      above: argAtoms(options.args[0]),\n      below: argAtoms(options.args[1]),\n      body,\n      skipBoundary: false,\n      boxType: atomsBoxType(body)\n    }));\n  },\n  serialize: (atom, options) => latexCommand(\n    atom.command,\n    atom.belowToLatex(options),\n    atom.bodyToLatex(options)\n  )\n});\ndefineFunction(\n  [\"stackrel\", \"stackbin\"],\n  \"[below:auto]{above:auto}{base:auto}\",\n  {\n    createAtom: (options) => new OverunderAtom(__spreadProps(__spreadValues({}, options), {\n      body: argAtoms(options.args[2]),\n      above: argAtoms(options.args[1]),\n      below: argAtoms(options.args[0]),\n      skipBoundary: false,\n      boxType: options.command === \"\\\\stackrel\" ? \"rel\" : \"bin\"\n    })),\n    serialize: (atom, options) => latexCommand(\n      atom.command,\n      atom.aboveToLatex(options),\n      atom.bodyToLatex(options)\n    )\n  }\n);\ndefineFunction(\"smash\", \"[:string]{:auto}\", {\n  createAtom: (options) => {\n    var _a3, _b3, _c2, _d2;\n    return new PhantomAtom(__spreadProps(__spreadValues({}, options), {\n      body: argAtoms(options.args[1]),\n      smashHeight: (_b3 = (_a3 = options.args[0]) == null ? void 0 : _a3.includes(\"t\")) != null ? _b3 : true,\n      smashDepth: (_d2 = (_c2 = options.args[0]) == null ? void 0 : _c2.includes(\"b\")) != null ? _d2 : true\n    }));\n  }\n});\ndefineFunction([\"vphantom\"], \"{:auto}\", {\n  createAtom: (options) => new PhantomAtom(__spreadProps(__spreadValues({}, options), {\n    body: argAtoms(options.args[0]),\n    isInvisible: true,\n    smashWidth: true\n  }))\n});\ndefineFunction([\"hphantom\"], \"{:auto}\", {\n  createAtom: (options) => new PhantomAtom(__spreadProps(__spreadValues({}, options), {\n    body: argAtoms(options.args[0]),\n    isInvisible: true,\n    smashHeight: true,\n    smashDepth: true\n  }))\n});\ndefineFunction([\"phantom\"], \"{:auto}\", {\n  createAtom: (options) => new PhantomAtom(__spreadProps(__spreadValues({}, options), {\n    body: argAtoms(options.args[0]),\n    isInvisible: true\n  }))\n});\ndefineFunction(\"not\", \"{:math}\", {\n  createAtom: (options) => {\n    const body = argAtoms(options.args[0]);\n    if (body.length === 0)\n      return new Atom(__spreadProps(__spreadValues({}, options), { type: \"mrel\", value: \"\\uE020\" }));\n    return new Atom(__spreadProps(__spreadValues({}, options), {\n      body: [\n        new OverlapAtom(__spreadProps(__spreadValues({}, options), { body: \"\\uE020\", align: \"right\" })),\n        ...body\n      ],\n      captureSelection: true\n    }));\n  },\n  serialize: (atom, options) => {\n    const arg = atom.args[0];\n    const isGroup = arg && typeof arg === \"object\" && \"group\" in arg;\n    if (atom.value !== \"\\uE020\") {\n      return isGroup ? `\\\\not{${Atom.serialize(arg.group, options)}}` : `\\\\not${Atom.serialize(arg, options)}`;\n    }\n    return isGroup ? `\\\\not{}` : `\\\\not`;\n  },\n  render: (atom, context) => {\n    if (atom.value) return atom.createBox(context);\n    const isGroup = atom.args[0] && typeof atom.args[0] === \"object\" && \"group\" in atom.args[0];\n    const type = isGroup ? \"ord\" : atomsBoxType(argAtoms(atom.args[0]));\n    const box = Atom.createBox(context, atom.body, { type });\n    if (atom.caret) box.caret = atom.caret;\n    return atom.bind(context, box);\n  }\n});\ndefineFunction([\"ne\", \"neq\"], \"\", {\n  createAtom: (options) => new Atom(__spreadProps(__spreadValues({}, options), {\n    type: \"mrel\",\n    body: [\n      new OverlapAtom(__spreadProps(__spreadValues({}, options), {\n        body: \"\\uE020\",\n        align: \"right\",\n        boxType: \"rel\"\n      })),\n      new Atom(__spreadProps(__spreadValues({}, options), { value: \"=\" }))\n    ],\n    captureSelection: true\n  })),\n  serialize: (atom) => atom.command\n});\ndefineFunction(\"rlap\", \"{:auto}\", {\n  createAtom: (options) => new OverlapAtom(__spreadProps(__spreadValues({}, options), {\n    body: argAtoms(options.args[0]),\n    align: \"right\"\n  }))\n});\ndefineFunction(\"llap\", \"{:auto}\", {\n  createAtom: (options) => new OverlapAtom(__spreadProps(__spreadValues({}, options), {\n    body: argAtoms(options.args[0]),\n    align: \"left\"\n  }))\n});\ndefineFunction(\"mathrlap\", \"{:math}\", {\n  createAtom: (options) => new OverlapAtom(__spreadProps(__spreadValues({}, options), {\n    body: argAtoms(options.args[0]),\n    align: \"right\"\n  }))\n});\ndefineFunction(\"mathllap\", \"{:math}\", {\n  createAtom: (options) => new OverlapAtom(__spreadProps(__spreadValues({}, options), {\n    body: argAtoms(options.args[0]),\n    align: \"left\"\n  }))\n});\ndefineFunction(\"raisebox\", \"{:value}{:text}\", {\n  createAtom: (options) => {\n    var _a3;\n    return new BoxAtom(__spreadProps(__spreadValues({}, options), {\n      body: argAtoms(options.args[1]),\n      padding: { dimension: 0 },\n      offset: (_a3 = options.args[0]) != null ? _a3 : { dimension: 0 }\n    }));\n  },\n  serialize: (atom, options) => {\n    var _a3;\n    return latexCommand(\n      \"\\\\raisebox\",\n      (_a3 = serializeLatexValue(atom.offset)) != null ? _a3 : \"0pt\",\n      atom.bodyToLatex(options)\n    );\n  }\n});\ndefineFunction(\"raise\", \"{:value}{:auto}\", {\n  createAtom: (options) => {\n    var _a3;\n    return new BoxAtom(__spreadProps(__spreadValues({}, options), {\n      body: argAtoms(options.args[1]),\n      padding: { dimension: 0 },\n      offset: (_a3 = options.args[0]) != null ? _a3 : { dimension: 0 }\n    }));\n  },\n  serialize: (atom, options) => {\n    var _a3;\n    return latexCommand(\n      \"\\\\raise\",\n      (_a3 = serializeLatexValue(atom.offset)) != null ? _a3 : \"0pt\",\n      atom.bodyToLatex(options)\n    );\n  }\n});\ndefineFunction(\"lower\", \"{:value}{:auto}\", {\n  createAtom: (options) => {\n    var _a3;\n    return new BoxAtom(__spreadProps(__spreadValues({}, options), {\n      body: argAtoms(options.args[1]),\n      padding: { dimension: 0 },\n      offset: (_a3 = multiplyLatexValue(options.args[0], -1)) != null ? _a3 : { dimension: 0 }\n    }));\n  },\n  serialize: (atom, options) => {\n    var _a3, _b3;\n    return latexCommand(\n      \"\\\\lower\",\n      (_b3 = serializeLatexValue(\n        multiplyLatexValue((_a3 = atom.offset) != null ? _a3 : { dimension: 0 }, -1)\n      )) != null ? _b3 : \"0pt\",\n      atom.bodyToLatex(options)\n    );\n  }\n});\n\n// src/latex-commands/symbols.ts\ndefineSymbols(\"0123456789/@.?!\");\ndefineSymbolRange(65, 90);\ndefineSymbolRange(97, 122);\ndefineSymbols([\n  [\"\\\\forall\", 8704],\n  [\"\\\\exists\", 8707],\n  [\"\\\\nexists\", 8708, \"mord\", \"ams\"],\n  [\"\\\\mid\", 8739, \"mrel\"],\n  [\"\\\\top\", 8868],\n  [\"\\\\bot\", 8869]\n]);\ndefineSymbols([\n  [\"\\\\#\", 35],\n  [\"\\\\&\", 38],\n  [\"\\\\parallelogram\", 9649],\n  [\"\\\\spadesuit\", 9824],\n  [\"\\\\heartsuit\", 9825],\n  [\"\\\\diamondsuit\", 9826],\n  [\"\\\\clubsuit\", 9827],\n  [\"\\\\flat\", 9837],\n  [\"\\\\natural\", 9838],\n  [\"\\\\sharp\", 9839]\n]);\ndefineSymbols([\n  [\"\\\\backslash\", 92],\n  [\"\\\\nabla\", 8711],\n  [\"\\\\partial\", 8706],\n  [\"\\\\ell\", 8467],\n  [\"\\\\hbar\", 8463],\n  [\"\\\\Q\", 81, \"mord\", \"double-struck\"],\n  // NOTE: Check if standard LaTeX\n  [\"\\\\C\", 67, \"mord\", \"double-struck\"],\n  // NOTE: Check if standard LaTeX\n  [\"\\\\P\", 80, \"mord\", \"double-struck\"],\n  // NOTE: Check if standard LaTeX\n  [\"\\\\pounds\", 163],\n  [\"\\\\euro\", 8364]\n  // NOTE: not TeX built-in, but textcomp package\n  // TODO Koppa, Stigma, Sampi\n]);\ndefineSymbols(\n  [\n    [\"\\\\rightarrow\", 8594],\n    [\"\\\\to\", 8594],\n    [\"\\\\leftarrow\", 8592],\n    [\"\\\\gets\", 8592],\n    [\"\\\\Rightarrow\", 8658],\n    [\"\\\\Leftarrow\", 8656],\n    [\"\\\\longrightarrow\", 10230],\n    [\"\\\\longleftarrow\", 10229],\n    [\"\\\\Longrightarrow\", 10233],\n    [\"\\\\implies\", 10233],\n    [\"\\\\Longleftarrow\", 10232],\n    [\"\\\\impliedby\", 10232],\n    [\"\\\\longleftrightarrow\", 10231],\n    [\"\\\\biconditional\", 10231],\n    [\"\\\\Longleftrightarrow\", 10234],\n    [\"\\\\mapsto\", 8614],\n    [\"\\\\longmapsto\", 10236],\n    [\"\\\\uparrow\", 8593],\n    [\"\\\\downarrow\", 8595],\n    [\"\\\\Uparrow\", 8657],\n    [\"\\\\Downarrow\", 8659],\n    [\"\\\\updownarrow\", 8597],\n    [\"\\\\Updownarrow\", 8661],\n    [\"\\\\hookrightarrow\", 8618],\n    [\"\\\\hookleftarrow\", 8617],\n    [\"\\\\rightharpoonup\", 8640],\n    [\"\\\\leftharpoonup\", 8636],\n    [\"\\\\rightharpoondown\", 8641],\n    [\"\\\\leftharpoondown\", 8637],\n    [\"\\\\searrow\", 8600],\n    [\"\\\\nearrow\", 8599],\n    [\"\\\\swarrow\", 8601],\n    [\"\\\\nwarrow\", 8598],\n    [\"\\\\originalof\", 8886],\n    [\"\\\\laplace\", 8886],\n    [\"\\\\imageof\", 8887],\n    [\"\\\\Laplace\", 8887]\n  ],\n  \"mrel\"\n);\ndefineSymbols([\n  [\"\\\\mapsfrom\", 8612, \"mrel\"],\n  [\"\\\\Mapsfrom\", 10502, \"mrel\"],\n  [\"\\\\MapsTo\", 10503, \"mrel\"],\n  [\"\\\\Yup\", 8516, \"mord\"],\n  [\"\\\\lightning\", 8623, \"mrel\"],\n  [\"\\\\leftarrowtriangle\", 8701, \"mrel\"],\n  [\"\\\\rightarrowtriangle\", 8702, \"mrel\"],\n  [\"\\\\leftrightarrowtriangle\", 8703, \"mrel\"],\n  [\"\\\\boxdot\", 8865, \"mbin\"],\n  [\"\\\\bigtriangleup\", 9651, \"mbin\"],\n  [\"\\\\bigtriangledown\", 9661, \"mbin\"],\n  [\"\\\\boxbar\", 9707, \"mbin\"],\n  [\"\\\\Lbag\", 10181, \"mopen\"],\n  [\"\\\\Rbag\", 10182, \"mclose\"],\n  [\"\\\\llbracket\", 10214, \"mopen\"],\n  [\"\\\\rrbracket\", 10215, \"mclose\"],\n  [\"\\\\longmapsfrom\", 10235, \"mrel\"],\n  [\"\\\\Longmapsfrom\", 10237, \"mrel\"],\n  [\"\\\\Longmapsto\", 10238, \"mrel\"],\n  [\"\\\\boxslash\", 10692, \"mbin\"],\n  [\"\\\\boxbslash\", 10693, \"mbin\"],\n  [\"\\\\boxast\", 10694, \"mbin\"],\n  [\"\\\\boxcircle\", 10695, \"mbin\"],\n  [\"\\\\boxbox\", 10696, \"mbin\"],\n  [\"\\\\fatsemi\", 10783, \"mop\"],\n  [\"\\\\leftslice\", 10918, \"mrel\"],\n  [\"\\\\rightslice\", 10919, \"mrel\"],\n  [\"\\\\interleave\", 10996, \"mbin\"],\n  [\"\\\\biginterleave\", 11004, \"mop\"],\n  [\"\\\\sslash\", 11005, \"mbin\"],\n  [\"\\\\talloblong\", 11006, \"mbin\"]\n]);\ndefineSymbols([\n  // 'ams' Delimiters\n  [\"\\\\lbrace\", 123, \"mopen\"],\n  [\"\\\\rbrace\", 125, \"mclose\"],\n  [\"\\\\lparen\", 40, \"mopen\"],\n  // mathtools.sty\n  [\"\\\\rparen\", 41, \"mclose\"],\n  // mathtools.sty\n  [\"\\\\langle\", 10216, \"mopen\"],\n  [\"\\\\rangle\", 10217, \"mclose\"],\n  [\"\\\\lfloor\", 8970, \"mopen\"],\n  [\"\\\\rfloor\", 8971, \"mclose\"],\n  [\"\\\\lceil\", 8968, \"mopen\"],\n  [\"\\\\rceil\", 8969, \"mclose\"],\n  [\"\\\\vert\", 8739],\n  [\"\\\\lvert\", 8739, \"mopen\"],\n  [\"\\\\rvert\", 8739, \"mclose\"],\n  [\"\\\\|\", 8741],\n  [\"\\\\Vert\", 8741],\n  [\"\\\\mVert\", 8741],\n  [\"\\\\lVert\", 8741, \"mopen\"],\n  [\"\\\\rVert\", 8741, \"mclose\"],\n  [\"\\\\lbrack\", 91, \"mopen\"],\n  [\"\\\\rbrack\", 93, \"mclose\"],\n  [\"\\\\{\", 123, \"mopen\"],\n  [\"\\\\}\", 125, \"mclose\"],\n  [\"(\", 40, \"mopen\"],\n  [\")\", 41, \"mclose\"],\n  [\"[\", 91, \"mopen\"],\n  [\"]\", 93, \"mclose\"],\n  [\"\\\\ulcorner\", 9484, \"mopen\", \"ams\"],\n  [\"\\\\urcorner\", 9488, \"mclose\", \"ams\"],\n  [\"\\\\llcorner\", 9492, \"mopen\", \"ams\"],\n  [\"\\\\lrcorner\", 9496, \"mclose\", \"ams\"],\n  // Large Delimiters\n  [\"\\\\lgroup\", 10222, \"mopen\"],\n  [\"\\\\rgroup\", 10223, \"mclose\"],\n  [\"\\\\lmoustache\", 9136, \"mopen\"],\n  [\"\\\\rmoustache\", 9137, \"mclose\"]\n  // defineSymbol('\\\\ne', 0x2260, 'mrel'],\n  // defineSymbol('\\\\neq', 0x2260, 'mrel'],\n  // defineSymbol( '\\\\longequal', 0xF7D9,  'mrel',  MAIN],   // NOTE: Not TeX\n]);\ndefineSymbols(\n  [\n    // 'ams' arrows\n    [\"\\\\dashrightarrow\", 8674],\n    [\"\\\\dashleftarrow\", 8672],\n    [\"\\\\Rrightarrow\", 8667],\n    [\"\\\\Lleftarrow\", 8666],\n    [\"\\\\leftrightarrows\", 8646],\n    [\"\\\\rightleftarrows\", 8644],\n    [\"\\\\curvearrowright\", 8631],\n    [\"\\\\curvearrowleft\", 8630],\n    [\"\\\\rightrightarrows\", 8649],\n    [\"\\\\leftleftarrows\", 8647],\n    [\"\\\\upuparrows\", 8648],\n    [\"\\\\downdownarrows\", 8650],\n    [\"\\\\vartriangle\", 9651],\n    [\"\\\\triangleq\", 8796],\n    [\"\\\\vartriangleleft\", 8882],\n    [\"\\\\trianglelefteq\", 8884],\n    [\"\\\\ntriangleleft\", 8938],\n    [\"\\\\ntrianglelefteq\", 8940],\n    [\"\\\\vartriangleright\", 8883],\n    [\"\\\\trianglerighteq\", 8885],\n    [\"\\\\ntriangleright\", 8939],\n    [\"\\\\ntrianglerighteq\", 8941],\n    [\"\\\\blacktriangleleft\", 9664],\n    [\"\\\\blacktriangleright\", 9654],\n    [\"\\\\leftarrowtail\", 8610],\n    [\"\\\\rightarrowtail\", 8611],\n    [\"\\\\looparrowright\", 8620],\n    [\"\\\\looparrowleft\", 8619],\n    [\"\\\\twoheadleftarrow\", 8606],\n    [\"\\\\twoheadrightarrow\", 8608],\n    [\"\\\\twoheadrightarrowtail\", 10518],\n    [\"\\\\rightleftharpoons\", 8652],\n    [\"\\\\leftrightharpoons\", 8651],\n    [\"\\\\Rsh\", 8625],\n    [\"\\\\Lsh\", 8624],\n    // 'ams' Relations\n    [\"\\\\circlearrowright\", 8635],\n    [\"\\\\circlearrowleft\", 8634],\n    [\"\\\\restriction\", 8638],\n    [\"\\\\upharpoonright\", 8638],\n    [\"\\\\upharpoonleft\", 8639],\n    [\"\\\\downharpoonright\", 8642],\n    [\"\\\\downharpoonleft\", 8643],\n    [\"\\\\rightsquigarrow\", 8669],\n    [\"\\\\leadsto\", 8669],\n    [\"\\\\leftrightsquigarrow\", 8621],\n    [\"\\\\multimap\", 8888],\n    // 'ams' Negated Arrows\n    [\"\\\\nleftarrow\", 8602],\n    [\"\\\\nrightarrow\", 8603],\n    [\"\\\\nRightarrow\", 8655],\n    [\"\\\\nLeftarrow\", 8653],\n    [\"\\\\nleftrightarrow\", 8622],\n    [\"\\\\nLeftrightarrow\", 8654],\n    [\"\\\\nvrightarrow\", 8696],\n    [\"\\\\nvtwoheadrightarrow\", 10496],\n    [\"\\\\nvrightarrowtail\", 10516],\n    [\"\\\\nvtwoheadrightarrowtail\", 10519],\n    // 'ams' Negated Relations\n    [\"\\\\shortparallel\", 8741],\n    [\"\\\\nless\", 8814],\n    [\"\\\\nleqslant\", 57360],\n    [\"\\\\lneq\", 10887],\n    [\"\\\\lneqq\", 8808],\n    [\"\\\\nleqq\", 57361],\n    [\"\\\\lvertneqq\", 57356],\n    [\"\\\\lnsim\", 8934],\n    [\"\\\\lnapprox\", 10889],\n    [\"\\\\nprec\", 8832],\n    [\"\\\\npreceq\", 8928],\n    [\"\\\\precnsim\", 8936],\n    [\"\\\\precnapprox\", 10937],\n    [\"\\\\nsim\", 8769],\n    [\"\\\\nshortmid\", 57350],\n    [\"\\\\nmid\", 8740],\n    [\"\\\\nvdash\", 8876],\n    [\"\\\\nvDash\", 8877],\n    [\"\\\\ngtr\", 8815],\n    [\"\\\\ngeqslant\", 57359],\n    [\"\\\\ngeqq\", 57358],\n    [\"\\\\gneq\", 10888],\n    [\"\\\\gneqq\", 8809],\n    [\"\\\\gvertneqq\", 57357],\n    [\"\\\\gnsim\", 8935],\n    [\"\\\\gnapprox\", 10890],\n    [\"\\\\nsucc\", 8833],\n    [\"\\\\nsucceq\", 8929],\n    [\"\\\\succnsim\", 8937],\n    [\"\\\\succnapprox\", 10938],\n    [\"\\\\ncong\", 8774],\n    [\"\\\\nshortparallel\", 57351],\n    [\"\\\\nparallel\", 8742],\n    [\"\\\\nVDash\", 8879],\n    [\"\\\\nsupseteqq\", 57368],\n    [\"\\\\supsetneq\", 8843],\n    [\"\\\\varsupsetneq\", 57371],\n    [\"\\\\supsetneqq\", 10956],\n    [\"\\\\varsupsetneqq\", 57369],\n    [\"\\\\nVdash\", 8878],\n    [\"\\\\precneqq\", 10933],\n    [\"\\\\succneqq\", 10934],\n    [\"\\\\nsubseteqq\", 57366],\n    [\"\\\\leqslant\", 10877],\n    [\"\\\\geqslant\", 10878],\n    [\"\\\\gtrsim\", 8819],\n    [\"\\\\approxeq\", 8778],\n    [\"\\\\thickapprox\", 8776],\n    [\"\\\\lessapprox\", 10885],\n    [\"\\\\gtrapprox\", 10886],\n    [\"\\\\precapprox\", 10935],\n    [\"\\\\succapprox\", 10936],\n    [\"\\\\thicksim\", 8764],\n    [\"\\\\succsim\", 8831],\n    [\"\\\\precsim\", 8830],\n    [\"\\\\backsim\", 8765],\n    [\"\\\\eqsim\", 8770],\n    [\"\\\\backsimeq\", 8909],\n    [\"\\\\lesssim\", 8818],\n    [\"\\\\nleq\", 8816],\n    [\"\\\\ngeq\", 8817],\n    [\"\\\\smallsmile\", 8995],\n    [\"\\\\smallfrown\", 8994],\n    [\"\\\\leqq\", 8806],\n    [\"\\\\eqslantless\", 10901],\n    [\"\\\\lll\", 8920],\n    [\"\\\\lessgtr\", 8822],\n    [\"\\\\lesseqgtr\", 8922],\n    [\"\\\\lesseqqgtr\", 10891],\n    [\"\\\\risingdotseq\", 8787],\n    [\"\\\\fallingdotseq\", 8786],\n    [\"\\\\subseteqq\", 10949],\n    [\"\\\\Subset\", 8912],\n    [\"\\\\sqsubset\", 8847],\n    [\"\\\\preccurlyeq\", 8828],\n    [\"\\\\curlyeqprec\", 8926],\n    [\"\\\\vDash\", 8872],\n    [\"\\\\Vvdash\", 8874],\n    [\"\\\\bumpeq\", 8783],\n    [\"\\\\Bumpeq\", 8782],\n    [\"\\\\geqq\", 8807],\n    [\"\\\\eqslantgtr\", 10902],\n    [\"\\\\ggg\", 8921],\n    [\"\\\\gtrless\", 8823],\n    [\"\\\\gtreqless\", 8923],\n    [\"\\\\gtreqqless\", 10892],\n    [\"\\\\supseteqq\", 10950],\n    [\"\\\\Supset\", 8913],\n    [\"\\\\sqsupset\", 8848],\n    [\"\\\\succcurlyeq\", 8829],\n    [\"\\\\curlyeqsucc\", 8927],\n    [\"\\\\Vdash\", 8873],\n    [\"\\\\shortmid\", 8739],\n    [\"\\\\between\", 8812],\n    [\"\\\\pitchfork\", 8916],\n    [\"\\\\varpropto\", 8733],\n    [\"\\\\backepsilon\", 8717],\n    [\"\\\\llless\", 8920],\n    [\"\\\\gggtr\", 8921],\n    [\"\\\\doteqdot\", 8785],\n    [\"\\\\Doteq\", 8785],\n    [\"\\\\eqcirc\", 8790],\n    [\"\\\\circeq\", 8791],\n    [\"\\\\therefore\", 8756],\n    [\"\\\\because\", 8757]\n  ],\n  \"mrel\",\n  \"ams\"\n);\ndefineSymbols(\n  [\n    [\"+\", 43],\n    [\"-\", 8722],\n    [\"\\u2212\", 8722],\n    [\"\\\\pm\", 177],\n    [\"\\\\mp\", 8723],\n    [\"*\", 8727],\n    [\"\\\\times\", 215],\n    [\"\\\\div\", 247],\n    [\"\\\\divides\", 8739],\n    [\"\\\\cdot\", 8901],\n    [\"\\\\cap\", 8745],\n    [\"\\\\cup\", 8746],\n    [\"\\\\setminus\", 8726],\n    [\"\\\\land\", 8743],\n    [\"\\\\wedge\", 8743],\n    [\"\\\\lor\", 8744],\n    [\"\\\\vee\", 8744],\n    [\"\\\\circ\", 8728],\n    [\"\\\\bigcirc\", 9711],\n    [\"\\\\bullet\", 8729],\n    [\"\\\\oplus\", 8853],\n    [\"\\\\ominus\", 8854],\n    [\"\\\\otimes\", 8855],\n    [\"\\\\odot\", 8857],\n    [\"\\\\oslash\", 8856],\n    [\"\\\\bigtriangleup\", 9651],\n    [\"\\\\bigtriangledown\", 9661],\n    [\"\\\\triangleleft\", 9667],\n    [\"\\\\triangleright\", 9657],\n    [\"\\\\And\", 38],\n    [\"\\\\dagger\", 8224],\n    [\"\\\\dag\", 8224],\n    [\"\\\\ddag\", 8225],\n    [\"\\\\ddagger\", 8225],\n    [\"\\\\ast\", 8727],\n    [\"\\\\star\", 8902],\n    [\"\\\\bigstar\", 9733],\n    [\"\\\\diamond\", 8900]\n  ],\n  \"mbin\"\n);\ndefineSymbols(\n  [\n    [\"\\\\lhd\", 8882],\n    [\"\\\\rhd\", 8883],\n    [\"\\\\lessdot\", 8918],\n    [\"\\\\gtrdot\", 8919],\n    [\"\\\\ltimes\", 8905],\n    [\"\\\\rtimes\", 8906],\n    [\"\\\\leftthreetimes\", 8907],\n    [\"\\\\rightthreetimes\", 8908],\n    [\"\\\\intercal\", 8890],\n    [\"\\\\dotplus\", 8724],\n    [\"\\\\doublebarwedge\", 10846],\n    [\"\\\\divideontimes\", 8903],\n    [\"\\\\centerdot\", 8901],\n    [\"\\\\smallsetminus\", 8726],\n    [\"\\\\barwedge\", 8892],\n    [\"\\\\veebar\", 8891],\n    [\"\\\\nor\", 8891],\n    // NOTE: Not TeX, Mathematica\n    [\"\\\\curlywedge\", 8911],\n    [\"\\\\curlyvee\", 8910],\n    [\"\\\\boxminus\", 8863],\n    [\"\\\\boxplus\", 8862],\n    [\"\\\\boxtimes\", 8864],\n    [\"\\\\boxdot\", 8865],\n    [\"\\\\circleddash\", 8861],\n    [\"\\\\circledast\", 8859],\n    [\"\\\\circledcirc\", 8858],\n    [\"\\\\unlhd\", 8884],\n    [\"\\\\unrhd\", 8885]\n  ],\n  \"mbin\",\n  \"ams\"\n);\ndefineSymbols([\n  [\"\\\\surd\", 8730],\n  [\"\\\\S\", 167],\n  // Section symbol: §\n  // From MnSymbol package\n  [\"\\\\infty\", 8734],\n  [\"\\\\prime\", 8242],\n  [\"\\\\doubleprime\", 8243],\n  // NOTE: Not in TeX, but Mathematica\n  [\"\\\\angle\", 8736],\n  [\"`\", 8216],\n  [\"\\\\$\", 36],\n  [\"\\\\%\", 37],\n  [\"\\\\_\", 95],\n  // Note: In TeX, greek symbols are only available in Math mode\n  [\"\\\\alpha\", 945],\n  [\"\\\\beta\", 946],\n  [\"\\\\gamma\", 947],\n  [\"\\\\delta\", 948],\n  [\"\\\\epsilon\", 1013],\n  [\"\\\\varepsilon\", 949],\n  [\"\\\\zeta\", 950],\n  [\"\\\\eta\", 951],\n  [\"\\\\theta\", 952],\n  [\"\\\\vartheta\", 977],\n  [\"\\\\iota\", 953],\n  [\"\\\\kappa\", 954],\n  [\"\\\\varkappa\", 1008, \"mord\", \"ams\"],\n  [\"\\\\lambda\", 955],\n  [\"\\\\mu\", 956],\n  [\"\\\\nu\", 957],\n  [\"\\\\xi\", 958],\n  [\"\\\\omicron\", 111],\n  [\"\\\\pi\", 960],\n  [\"\\\\varpi\", 982],\n  [\"\\\\rho\", 961],\n  [\"\\\\varrho\", 1009],\n  [\"\\\\sigma\", 963],\n  [\"\\\\varsigma\", 962],\n  [\"\\\\tau\", 964],\n  [\"\\\\phi\", 981],\n  [\"\\\\varphi\", 966],\n  [\"\\\\upsilon\", 965],\n  [\"\\\\chi\", 967],\n  [\"\\\\psi\", 968],\n  [\"\\\\omega\", 969],\n  [\"\\\\Gamma\", 915],\n  [\"\\\\Delta\", 916],\n  [\"\\\\Theta\", 920],\n  [\"\\\\Lambda\", 923],\n  [\"\\\\Xi\", 926],\n  [\"\\\\Pi\", 928],\n  [\"\\\\Sigma\", 931],\n  [\"\\\\Upsilon\", 933],\n  [\"\\\\Phi\", 934],\n  [\"\\\\Psi\", 936],\n  [\"\\\\Omega\", 937],\n  // 'ams' Greek\n  [\"\\\\digamma\", 989, \"mord\", \"ams\"],\n  [\"\\\\emptyset\", 8709]\n]);\ndefineSymbols(\n  [\n    [\"=\", 61],\n    [\"<\", 60],\n    [\"\\\\lt\", 60],\n    [\">\", 62],\n    [\"\\\\gt\", 62],\n    [\"\\\\le\", 8804],\n    [\"\\\\leq\", 8804],\n    [\"\\\\ge\", 8805],\n    [\"\\\\geq\", 8805],\n    [\"\\\\ll\", 8810],\n    [\"\\\\gg\", 8811],\n    [\"\\\\coloneq\", 8788],\n    // Prefered form as of Summer 2022. See § 3.7.3 https://ctan.math.illinois.edu/macros/latex/contrib/mathtools/mathtools.pdf)\n    [\"\\\\coloneqq\", 8788],\n    // Legacy form\n    [\"\\\\colonequals\", 8788],\n    // From the colonequals package\n    [\"\\\\measeq\", 8797],\n    // MEASSURED BY\n    [\"\\\\eqdef\", 8798],\n    [\"\\\\questeq\", 8799],\n    // QUESTIONED EQUAL TO\n    [\":\", 58],\n    [\"\\\\cong\", 8773],\n    [\"\\\\equiv\", 8801],\n    [\"\\\\prec\", 8826],\n    [\"\\\\preceq\", 10927],\n    [\"\\\\succ\", 8827],\n    [\"\\\\succeq\", 10928],\n    [\"\\\\perp\", 8869],\n    [\"\\\\propto\", 8733],\n    [\"\\\\Colon\", 8759],\n    [\"\\\\smile\", 8995],\n    [\"\\\\frown\", 8994],\n    [\"\\\\sim\", 8764],\n    [\"\\\\doteq\", 8784],\n    [\"\\\\bowtie\", 8904],\n    [\"\\\\Join\", 8904],\n    [\"\\\\asymp\", 8781],\n    [\"\\\\sqsubseteq\", 8849],\n    [\"\\\\sqsupseteq\", 8850],\n    [\"\\\\approx\", 8776],\n    // In TeX, '~' is a spacing command (non-breaking space).\n    // However, '~' is used as an ASCII Math shortctut character, so define a \\\\~\n    // command which maps to the '~' character\n    [\"\\\\~\", 126],\n    [\"\\\\leftrightarrow\", 8596],\n    [\"\\\\Leftrightarrow\", 8660],\n    [\"\\\\models\", 8872],\n    [\"\\\\vdash\", 8866],\n    [\"\\\\dashv\", 8867],\n    [\"\\\\roundimplies\", 10608],\n    [\"\\\\in\", 8712],\n    [\"\\\\notin\", 8713],\n    // defineSymbol('\\\\not', 0x0338],\n    // defineSymbol('\\\\not', 0xe020],\n    [\"\\\\ni\", 8715],\n    [\"\\\\owns\", 8715],\n    [\"\\\\subset\", 8834],\n    [\"\\\\supset\", 8835],\n    [\"\\\\subseteq\", 8838],\n    [\"\\\\supseteq\", 8839],\n    [\"\\\\differencedelta\", 8710],\n    [\"\\\\mvert\", 8739],\n    [\"\\\\parallel\", 8741],\n    [\"\\\\simeq\", 8771]\n  ],\n  \"mrel\"\n);\ndefineSymbols(\n  [\n    [\"\\\\lnot\", 172],\n    [\"\\\\neg\", 172],\n    [\"\\\\triangle\", 9651],\n    [\"\\\\subsetneq\", 8842],\n    [\"\\\\varsubsetneq\", 57370],\n    [\"\\\\subsetneqq\", 10955],\n    [\"\\\\varsubsetneqq\", 57367],\n    [\"\\\\nsubset\", 8836],\n    // NOTE: Not TeX?\n    [\"\\\\nsupset\", 8837],\n    // NOTE: Not TeX?\n    [\"\\\\nsubseteq\", 8840],\n    [\"\\\\nsupseteq\", 8841]\n  ],\n  \"mrel\",\n  \"ams\"\n);\ndefineSymbols([\n  [\"\\\\wp\", 8472],\n  [\"\\\\aleph\", 8501]\n]);\ndefineSymbols(\n  [\n    [\"\\\\blacktriangle\", 9650],\n    [\"\\\\hslash\", 8463],\n    [\"\\\\Finv\", 8498],\n    [\"\\\\Game\", 8513],\n    [\"\\\\eth\", 240],\n    [\"\\\\mho\", 8487],\n    [\"\\\\Bbbk\", 107],\n    [\"\\\\yen\", 165],\n    [\"\\\\square\", 9633],\n    [\"\\\\Box\", 9633],\n    [\"\\\\blacksquare\", 9632],\n    [\"\\\\circledS\", 9416],\n    [\"\\\\circledR\", 174],\n    [\"\\\\triangledown\", 9661],\n    [\"\\\\blacktriangledown\", 9660],\n    [\"\\\\checkmark\", 10003],\n    [\"\\\\diagup\", 9585],\n    [\"\\\\measuredangle\", 8737],\n    [\"\\\\sphericalangle\", 8738],\n    [\"\\\\backprime\", 8245],\n    [\"\\\\backdoubleprime\", 8246],\n    [\"\\\\Diamond\", 9674],\n    [\"\\\\lozenge\", 9674],\n    [\"\\\\blacklozenge\", 10731],\n    [\"\\\\varnothing\", 8709],\n    [\"\\\\complement\", 8705],\n    [\"\\\\maltese\", 10016],\n    // 'ams' Hebrew\n    [\"\\\\beth\", 8502],\n    [\"\\\\daleth\", 8504],\n    [\"\\\\gimel\", 8503]\n  ],\n  \"mord\",\n  \"ams\"\n);\ndefineSymbols(\n  [\n    // See http://tex.stackexchange.com/questions/41476/lengths-and-when-to-use-them\n    [\"\\\\ \", 160],\n    [\"~\", 160]\n  ],\n  \"space\"\n);\ndefineFunction(\n  [\"!\", \",\", \":\", \";\", \">\", \"enskip\", \"enspace\", \"quad\", \"qquad\"],\n  \"\",\n  {\n    createAtom: (options) => new SpacingAtom(options)\n  }\n);\ndefineFunction(\"space\", \"\", {\n  createAtom: (options) => new SpacingAtom(options)\n});\ndefineSymbols(\n  [\n    [\"\\\\colon\", 58],\n    [\"\\\\cdotp\", 8901],\n    [\"\\\\vdots\", 8942, \"mord\"],\n    [\"\\\\ldotp\", 46],\n    [\",\", 44],\n    [\";\", 59]\n  ],\n  \"mpunct\"\n);\ndefineSymbols(\n  [\n    [\"\\\\cdots\", 8943],\n    [\"\\\\ddots\", 8945],\n    [\"\\\\ldots\", 8230],\n    [\"\\\\mathellipsis\", 8230]\n  ],\n  \"minner\"\n);\ndefineSymbols([\n  [\"\\\\/\", 47],\n  [\"|\", 8739, \"mord\"],\n  [\"\\\\imath\", 305],\n  [\"\\\\jmath\", 567],\n  [\"\\\\degree\", 176],\n  [\"'\", 8242],\n  // Prime\n  ['\"', 8221]\n  // Double Prime\n  // defineSymbol( \"\\'', 0x2033,  'mord',  MAIN],       // Double Prime\n]);\n\n// src/formats/atom-to-math-ml.ts\nvar APPLY_FUNCTION = \"<mo>&#x2061;</mo>\";\nvar INVISIBLE_TIMES = \"<mo>&#8290;</mo>\";\nfunction xmlEscape(string) {\n  return string.replace(/\"/g, \"&quot;\").replace(/'/g, \"&#39;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\nfunction makeID(id, options) {\n  if (!id || !options.generateID) return \"\";\n  return ` extid=\"${id}\"`;\n}\nfunction scanIdentifier(stream, final, options) {\n  var _a3, _b3, _c2, _d2, _e, _f, _g, _h;\n  let result = false;\n  final = final != null ? final : stream.atoms.length;\n  let mathML = \"\";\n  let body = \"\";\n  let atom = stream.atoms[stream.index];\n  const variant = (_a3 = atom.style) == null ? void 0 : _a3.variant;\n  const variantStyle = (_b3 = atom.style) == null ? void 0 : _b3.variantStyle;\n  let variantProp = \"\";\n  if (atom.value && (variant || variantStyle)) {\n    const unicodeVariant = (_c2 = mathVariantToUnicode(atom.value, variant, variantStyle)) != null ? _c2 : atom.value;\n    if (unicodeVariant !== atom.value) {\n      stream.index += 1;\n      mathML = `<mi${makeID(atom.id, options)}>${unicodeVariant}</mi>`;\n      if (!parseSubsup(mathML, stream, options)) {\n        stream.mathML += mathML;\n        stream.lastType = \"mi\";\n      }\n      return true;\n    }\n    variantProp = (_d2 = {\n      \"upnormal\": \"normal\",\n      \"boldnormal\": \"bold\",\n      \"italicmain\": \"italic\",\n      \"bolditalicmain\": \"bold-italic\",\n      \"updouble-struck\": \"double-struck\",\n      \"double-struck\": \"double-struck\",\n      \"boldfraktur\": \"bold-fraktur\",\n      \"calligraphic\": \"script\",\n      \"upcalligraphic\": \"script\",\n      \"script\": \"script\",\n      \"boldscript\": \"bold-script\",\n      \"boldcalligraphic\": \"bold-script\",\n      \"fraktur\": \"fraktur\",\n      \"upsans-serif\": \"sans-serif\",\n      \"boldsans-serif\": \"bold-sans-serif\",\n      \"italicsans-serif\": \"sans-serif-italic\",\n      \"bolditalicsans-serif\": \"sans-serif-bold-italic\",\n      \"monospace\": \"monospace\"\n    }[(variantStyle != null ? variantStyle : \"\") + (variant != null ? variant : \"\")]) != null ? _d2 : \"\";\n    if (variantProp) variantProp = ` mathvariant=\"${variantProp}\"`;\n  }\n  const SPECIAL_IDENTIFIERS = {\n    \"\\\\exponentialE\": \"&#x02147;\",\n    \"\\\\imaginaryI\": \"&#x2148;\",\n    \"\\\\differentialD\": \"&#x2146;\",\n    \"\\\\capitalDifferentialD\": \"&#x2145;\",\n    \"\\\\alpha\": \"&#x03b1;\",\n    \"\\\\pi\": \"&#x03c0;\",\n    \"\\\\infty\": \"&#x221e;\",\n    \"\\\\forall\": \"&#x2200;\",\n    \"\\\\nexists\": \"&#x2204;\",\n    \"\\\\exists\": \"&#x2203;\",\n    \"\\\\hbar\": \"\\u210F\",\n    \"\\\\cdotp\": \"\\u22C5\",\n    \"\\\\ldots\": \"\\u2026\",\n    \"\\\\cdots\": \"\\u22EF\",\n    \"\\\\ddots\": \"\\u22F1\",\n    \"\\\\vdots\": \"\\u22EE\",\n    \"\\\\ldotp\": \".\"\n  };\n  if (atom.command === \"!\") {\n    stream.index += 1;\n    mathML = \"<mo>!</mo>\";\n    if (!parseSubsup(mathML, stream, options)) {\n      stream.mathML += mathML;\n      stream.lastType = \"mo\";\n    }\n    return true;\n  }\n  if (SPECIAL_IDENTIFIERS[atom.command]) {\n    stream.index += 1;\n    let mathML2 = `<mi${makeID(atom.id, options)}${variantProp}>${SPECIAL_IDENTIFIERS[atom.command]}</mi>`;\n    if (stream.lastType === \"mi\" || stream.lastType === \"mn\" || stream.lastType === \"mtext\" || stream.lastType === \"fence\")\n      mathML2 = INVISIBLE_TIMES + mathML2;\n    if (!parseSubsup(mathML2, stream, options)) {\n      stream.mathML += mathML2;\n      stream.lastType = \"mi\";\n    }\n    return true;\n  }\n  if (atom.command === \"\\\\operatorname\") {\n    body = toString2(atom.body);\n    stream.index += 1;\n  } else {\n    if (variant || variantStyle) {\n      while (stream.index < final && (atom.type === \"mord\" || atom.type === \"macro\") && !atom.isDigit() && variant === ((_f = (_e = atom.style) == null ? void 0 : _e.variant) != null ? _f : \"\") && variantStyle === ((_h = (_g = atom.style) == null ? void 0 : _g.variantStyle) != null ? _h : \"\")) {\n        body += toString2([atom]);\n        stream.index += 1;\n        atom = stream.atoms[stream.index];\n      }\n    } else if ((atom.type === \"mord\" || atom.type === \"macro\") && !atom.isDigit()) {\n      body += toString2([atom]);\n      stream.index += 1;\n    }\n  }\n  if (body.length > 0) {\n    result = true;\n    mathML = `<mi${variantProp}>${body}</mi>`;\n    const lastType = stream.lastType;\n    if (mathML.endsWith(\">f</mi>\") || mathML.endsWith(\">g</mi>\")) {\n      mathML += APPLY_FUNCTION;\n      stream.lastType = \"applyfunction\";\n    } else stream.lastType = /^<mo>(.*)<\\/mo>$/.test(mathML) ? \"mo\" : \"mi\";\n    if (!parseSubsup(mathML, stream, options)) {\n      if (lastType === \"mi\" || lastType === \"mn\" || lastType === \"mtext\" || lastType === \"fence\")\n        mathML = INVISIBLE_TIMES + mathML;\n      stream.mathML += mathML;\n    }\n  }\n  return result;\n}\nfunction isSuperscriptAtom(stream) {\n  return stream.index < stream.atoms.length && stream.atoms[stream.index].superscript && stream.atoms[stream.index].type === \"subsup\";\n}\nfunction indexOfSuperscriptInNumber(stream) {\n  let result = -1;\n  let i = stream.index;\n  let done = false;\n  let found = false;\n  while (i < stream.atoms.length && !done && !found) {\n    const atom = stream.atoms[i];\n    done = !atom.isDigit();\n    found = !done && atom.superscript !== void 0;\n    i++;\n  }\n  if (found) result = i - 1;\n  return result;\n}\nfunction parseSubsup(base, stream, options) {\n  var _a3;\n  let atom = stream.atoms[stream.index - 1];\n  if (!atom) return false;\n  if (!atom.superscript && !atom.subscript) {\n    if (((_a3 = stream.atoms[stream.index]) == null ? void 0 : _a3.type) === \"subsup\") {\n      atom = stream.atoms[stream.index];\n      stream.index += 1;\n    } else return false;\n  }\n  const lastType = stream.lastType;\n  stream.lastType = \"\";\n  const superscript = toMathML(atom.superscript, options);\n  stream.lastType = \"\";\n  const subscript = toMathML(atom.subscript, options);\n  stream.lastType = lastType;\n  if (!superscript && !subscript) return false;\n  let mathML = \"\";\n  if (superscript && subscript)\n    mathML = `<msubsup>${base}${subscript}${superscript}</msubsup>`;\n  else if (superscript) mathML = `<msup>${base}${superscript}</msup>`;\n  else if (subscript) mathML = `<msub>${base}${subscript}</msub>`;\n  stream.mathML += mathML;\n  stream.lastType = \"\";\n  return true;\n}\nfunction scanText(stream, final, options) {\n  final = final != null ? final : stream.atoms.length;\n  const initial = stream.index;\n  let mathML = \"\";\n  let superscript = indexOfSuperscriptInNumber(stream);\n  if (superscript >= 0 && superscript < final) final = superscript;\n  while (stream.index < final && stream.atoms[stream.index].mode === \"text\") {\n    mathML += stream.atoms[stream.index].value ? stream.atoms[stream.index].value : \" \";\n    stream.index += 1;\n  }\n  if (mathML.length > 0) {\n    mathML = `<mtext ${makeID(\n      stream.atoms[initial].id,\n      options\n    )}>${mathML}</mtext>`;\n    if (superscript < 0 && isSuperscriptAtom(stream)) {\n      superscript = stream.index;\n      stream.index += 1;\n    }\n    if (!parseSubsup(mathML, stream, options)) {\n      stream.mathML += mathML;\n      stream.lastType = \"mtext\";\n    }\n    return true;\n  }\n  return false;\n}\nfunction scanNumber(stream, final, options) {\n  final = final != null ? final : stream.atoms.length;\n  const initial = stream.index;\n  let mathML = \"\";\n  let superscript = indexOfSuperscriptInNumber(stream);\n  if (superscript >= 0 && superscript < final) final = superscript;\n  while (stream.index < final && stream.atoms[stream.index].isDigit()) {\n    mathML += stream.atoms[stream.index].asDigit();\n    stream.index += 1;\n  }\n  if (mathML.length <= 0) return false;\n  mathML = \"<mn\" + makeID(stream.atoms[initial].id, options) + \">\" + mathML + \"</mn>\";\n  if (superscript < 0 && isSuperscriptAtom(stream)) {\n    superscript = stream.index;\n    stream.index += 1;\n  }\n  if (!parseSubsup(mathML, stream, options)) {\n    stream.mathML += mathML;\n    stream.lastType = \"mn\";\n  }\n  return true;\n}\nfunction scanFence(stream, final, options) {\n  let result = false;\n  final = final != null ? final : stream.atoms.length;\n  let mathML = \"\";\n  let lastType = \"\";\n  if (stream.index < final && stream.atoms[stream.index].type === \"mopen\") {\n    let found = false;\n    let depth = 0;\n    const openIndex = stream.index;\n    let closeIndex = -1;\n    let index = openIndex + 1;\n    while (index < final && !found) {\n      if (stream.atoms[index].type === \"mopen\") depth += 1;\n      else if (stream.atoms[index].type === \"mclose\") depth -= 1;\n      if (depth === -1) {\n        found = true;\n        closeIndex = index;\n      }\n      index += 1;\n    }\n    if (found) {\n      mathML = \"<mrow>\";\n      mathML += toMo(stream.atoms[openIndex], options);\n      mathML += toMathML(stream.atoms, options, openIndex + 1, closeIndex);\n      mathML += toMo(stream.atoms[closeIndex], options);\n      mathML += \"</mrow>\";\n      stream.index = closeIndex + 1;\n      if (stream.lastType === \"mi\" || stream.lastType === \"mn\" || stream.lastType === \"mfrac\" || stream.lastType === \"fence\")\n        stream.mathML += INVISIBLE_TIMES;\n      if (parseSubsup(mathML, stream, options)) {\n        result = true;\n        stream.lastType = \"\";\n        mathML = \"\";\n      }\n      lastType = \"fence\";\n    }\n  }\n  if (mathML.length > 0) {\n    result = true;\n    stream.mathML += mathML;\n    stream.lastType = lastType;\n  }\n  return result;\n}\nfunction scanOperator(stream, final, options) {\n  let result = false;\n  final = final != null ? final : stream.atoms.length;\n  let mathML = \"\";\n  let lastType = \"\";\n  const atom = stream.atoms[stream.index];\n  if (!atom) return false;\n  const SPECIAL_OPERATORS = {\n    \"\\\\ne\": \"&ne;\",\n    \"\\\\neq\": \"&ne;\",\n    \"\\\\pm\": \"&#177;\",\n    \"\\\\times\": \"&#215;\",\n    \"\\\\colon\": \":\",\n    \"\\\\vert\": \"|\",\n    \"\\\\Vert\": \"\\u2225\",\n    \"\\\\mid\": \"\\u2223\",\n    \"\\\\{\": \"{\",\n    \"\\\\}\": \"}\",\n    \"\\\\lbrace\": \"{\",\n    \"\\\\rbrace\": \"}\",\n    \"\\\\lbrack\": \"[\",\n    \"\\\\rbrack\": \"]\",\n    \"\\\\lparen\": \"(\",\n    \"\\\\rparen\": \")\",\n    \"\\\\langle\": \"\\u27E8\",\n    \"\\\\rangle\": \"\\u27E9\",\n    \"\\\\lfloor\": \"\\u230A\",\n    \"\\\\rfloor\": \"\\u230B\",\n    \"\\\\lceil\": \"\\u2308\",\n    \"\\\\rceil\": \"\\u2309\"\n  };\n  if (SPECIAL_OPERATORS[atom.command]) {\n    stream.index += 1;\n    const mathML2 = `<mo${makeID(atom.id, options)}>${SPECIAL_OPERATORS[atom.command]}</mo>`;\n    if (!parseSubsup(mathML2, stream, options)) {\n      stream.mathML += mathML2;\n      stream.lastType = \"mo\";\n    }\n    return true;\n  }\n  if (stream.index < final && (atom.type === \"mbin\" || atom.type === \"mrel\")) {\n    mathML += atomToMathML(stream.atoms[stream.index], options);\n    stream.index += 1;\n    lastType = \"mo\";\n  } else if (stream.index < final && (atom.type === \"mop\" || atom.type === \"operator\" || atom.type === \"extensible-symbol\")) {\n    if (atom.subsupPlacement === \"over-under\" && (atom.superscript || atom.subscript)) {\n      const op = toMo(atom, options);\n      if (atom.superscript && atom.subscript) {\n        mathML += \"<munderover>\" + op;\n        mathML += toMathML(atom.subscript, options);\n        mathML += toMathML(atom.superscript, options);\n        mathML += \"</munderover>\";\n      } else if (atom.superscript) {\n        mathML += \"<mover>\" + op;\n        mathML += toMathML(atom.superscript, options);\n        mathML += \"</mover>\";\n      } else if (atom.subscript) {\n        mathML += \"<munder>\" + op;\n        mathML += toMathML(atom.subscript, options);\n        mathML += \"</munder>\";\n      }\n      stream.mathML += mathML;\n      stream.lastType = \"mo\";\n      stream.index += 1;\n      return true;\n    }\n    {\n      const atom2 = stream.atoms[stream.index];\n      const isUnit = atom2.value === \"\\\\operatorname\";\n      const op = isUnit ? '<mi class=\"MathML-Unit\"' + makeID(atom2.id, options) + \">\" + toString2(atom2.value) + \"</mi>\" : toMo(atom2, options);\n      mathML += op;\n      if (!isUnit && !/^<mo>(.*)<\\/mo>$/.test(op)) {\n        mathML += APPLY_FUNCTION;\n        lastType = \"applyfunction\";\n      } else lastType = isUnit ? \"mi\" : \"mo\";\n    }\n    if ((stream.lastType === \"mi\" || stream.lastType === \"mn\") && !/^<mo>(.*)<\\/mo>$/.test(mathML))\n      mathML = INVISIBLE_TIMES + mathML;\n    stream.index += 1;\n  }\n  if (mathML.length > 0) {\n    result = true;\n    if (!parseSubsup(mathML, stream, options)) {\n      stream.mathML += mathML;\n      stream.lastType = lastType;\n    }\n  }\n  return result;\n}\nfunction toMathML(input, options, initial, final) {\n  options != null ? options : options = {};\n  const result = {\n    atoms: [],\n    index: initial != null ? initial : 0,\n    mathML: \"\",\n    lastType: \"\"\n  };\n  if (typeof input === \"number\" || typeof input === \"boolean\")\n    result.mathML = input.toString();\n  else if (typeof input === \"string\") result.mathML = input;\n  else if (input instanceof Atom) result.mathML = atomToMathML(input, options);\n  else if (Array.isArray(input)) {\n    result.atoms = input;\n    let count = 0;\n    final = final ? final : input ? input.length : 0;\n    while (result.index < final) {\n      if (scanText(result, final, options) || scanNumber(result, final, options) || scanIdentifier(result, final, options) || scanOperator(result, final, options) || scanFence(result, final, options))\n        count += 1;\n      else if (result.index < final) {\n        let mathML = atomToMathML(result.atoms[result.index], options);\n        if (result.lastType === \"mn\" && mathML.length > 0 && result.atoms[result.index].type === \"genfrac\") {\n          mathML = \"<mo>&#x2064;</mo>\" + mathML;\n        }\n        if (result.atoms[result.index].type === \"genfrac\")\n          result.lastType = \"mfrac\";\n        else result.lastType = \"\";\n        result.index += 1;\n        if (parseSubsup(mathML, result, options)) count += 1;\n        else {\n          if (mathML.length > 0) {\n            result.mathML += mathML;\n            count += 1;\n          }\n        }\n      }\n    }\n    if (count > 1) result.mathML = \"<mrow>\" + result.mathML + \"</mrow>\";\n  }\n  return result.mathML;\n}\nfunction toMo(atom, options) {\n  let result = \"\";\n  const body = toString2(atom.value);\n  if (body) result = \"<mo\" + makeID(atom.id, options) + \">\" + body + \"</mo>\";\n  return result;\n}\nfunction toString2(atoms) {\n  if (!atoms) return \"\";\n  if (typeof atoms === \"string\") return xmlEscape(atoms);\n  if (!Array.isArray(atoms) && typeof atoms.body === \"string\")\n    return xmlEscape(atoms.body);\n  let result = \"\";\n  for (const atom of atoms)\n    if (typeof atom.value === \"string\") result += atom.value;\n  return xmlEscape(result);\n}\nfunction atomToMathML(atom, options) {\n  var _a3, _b3, _c2, _d2, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v;\n  if (atom.mode === \"text\")\n    return `<mi${makeID(atom.id, options)}>${atom.value}</mi>`;\n  const SVG_CODE_POINTS = {\n    widehat: \"^\",\n    widecheck: \"\\u02C7\",\n    widetilde: \"~\",\n    utilde: \"~\",\n    overleftarrow: \"\\u2190\",\n    underleftarrow: \"\\u2190\",\n    xleftarrow: \"\\u2190\",\n    longleftarrow: \"\\u2190\",\n    overrightarrow: \"\\u2192\",\n    underrightarrow: \"\\u2192\",\n    xrightarrow: \"\\u2192\",\n    longrightarrow: \"\\u2192\",\n    underbrace: \"\\u23DF\",\n    overbrace: \"\\u23DE\",\n    overgroup: \"\\u23E0\",\n    undergroup: \"\\u23E1\",\n    overleftrightarrow: \"\\u2194\",\n    underleftrightarrow: \"\\u2194\",\n    xleftrightarrow: \"\\u2194\",\n    Overrightarrow: \"\\u21D2\",\n    xRightarrow: \"\\u21D2\",\n    overleftharpoon: \"\\u21BC\",\n    xleftharpoonup: \"\\u21BC\",\n    overrightharpoon: \"\\u21C0\",\n    xrightharpoonup: \"\\u21C0\",\n    xLeftarrow: \"\\u21D0\",\n    xLeftrightarrow: \"\\u21D4\",\n    xhookleftarrow: \"\\u21A9\",\n    xhookrightarrow: \"\\u21AA\",\n    xmapsto: \"\\u21A6\",\n    xrightharpoondown: \"\\u21C1\",\n    xleftharpoondown: \"\\u21BD\",\n    xrightleftharpoons: \"\\u21CC\",\n    longrightleftharpoons: \"\\u21CC\",\n    xleftrightharpoons: \"\\u21CB\",\n    xtwoheadleftarrow: \"\\u219E\",\n    xtwoheadrightarrow: \"\\u21A0\",\n    xlongequal: \"=\",\n    xtofrom: \"\\u21C4\",\n    xleftrightarrows: \"\\u21C4\",\n    xRightleftharpoons: \"\\u21CC\",\n    // Not a perfect match.\n    longRightleftharpoons: \"\\u21CC\",\n    // Not a perfect match.\n    xLeftrightharpoons: \"\\u21CB\",\n    // None better available.\n    longLeftrightharpoons: \"\\u21CB\"\n    // None better available.\n  };\n  const SPACING = {\n    \"\\\\!\": -3 / 18,\n    \"\\\\ \": 6 / 18,\n    \"\\\\,\": 3 / 18,\n    \"\\\\:\": 4 / 18,\n    \"\\\\>\": 4 / 18,\n    \"\\\\;\": 5 / 18,\n    \"\\\\enspace\": 0.5,\n    \"\\\\quad\": 1,\n    \"\\\\qquad\": 2,\n    \"\\\\enskip\": 0.5\n  };\n  let result = \"\";\n  let sep = \"\";\n  let col;\n  let row;\n  let i;\n  let underscript;\n  let overscript;\n  let body;\n  const { command } = atom;\n  if (atom.command === \"\\\\error\") {\n    return `<merror${makeID(atom.id, options)}>${toMathML(\n      atom.body,\n      options\n    )}</merror>`;\n  }\n  const SPECIAL_DELIMS = {\n    \"\\\\vert\": \"|\",\n    \"\\\\Vert\": \"\\u2225\",\n    \"\\\\mid\": \"\\u2223\",\n    \"\\\\lbrack\": \"[\",\n    \"\\\\rbrack\": \"]\",\n    \"\\\\{\": \"{\",\n    \"\\\\}\": \"}\",\n    \"\\\\lbrace\": \"{\",\n    \"\\\\rbrace\": \"}\",\n    \"\\\\lparen\": \"(\",\n    \"\\\\rparen\": \")\",\n    \"\\\\langle\": \"\\u27E8\",\n    \"\\\\rangle\": \"\\u27E9\",\n    \"\\\\lfloor\": \"\\u230A\",\n    \"\\\\rfloor\": \"\\u230B\",\n    \"\\\\lceil\": \"\\u2308\",\n    \"\\\\rceil\": \"\\u2309\"\n  };\n  const SPECIAL_ACCENTS = {\n    \"\\\\vec\": \"&#x20d7;\",\n    \"\\\\acute\": \"&#x00b4;\",\n    \"\\\\grave\": \"&#x0060;\",\n    \"\\\\dot\": \"&#x02d9;\",\n    \"\\\\ddot\": \"&#x00a8;\",\n    \"\\\\tilde\": \"&#x007e;\",\n    \"\\\\bar\": \"&#x00af;\",\n    \"\\\\breve\": \"&#x02d8;\",\n    \"\\\\check\": \"&#x02c7;\",\n    \"\\\\hat\": \"&#x005e;\"\n  };\n  switch (atom.type) {\n    case \"first\":\n      break;\n    case \"group\":\n    case \"root\":\n      result = toMathML(atom.body, options);\n      break;\n    case \"array\":\n      if (atom.leftDelim && atom.leftDelim !== \".\" || atom.rightDelim && atom.rightDelim !== \".\") {\n        result += \"<mrow>\";\n        if (atom.leftDelim && atom.leftDelim !== \".\") {\n          result += \"<mo>\" + (SPECIAL_DELIMS[atom.leftDelim] || atom.leftDelim) + \"</mo>\";\n        }\n      }\n      result += \"<mtable\";\n      if (atom.colFormat) {\n        result += ' columnalign=\"';\n        for (i = 0; i < atom.colFormat.length; i++) {\n          if (atom.colFormat[i].align) {\n            result += { l: \"left\", c: \"center\", r: \"right\" }[atom.colFormat[i].align] + \" \";\n          }\n        }\n        result += '\"';\n      }\n      result += \">\";\n      for (row = 0; row < atom.array.length; row++) {\n        result += \"<mtr>\";\n        for (col = 0; col < atom.array[row].length; col++) {\n          result += \"<mtd>\" + toMathML(atom.array[row][col], options) + \"</mtd>\";\n        }\n        result += \"</mtr>\";\n      }\n      result += \"</mtable>\";\n      if (atom.leftDelim && atom.leftDelim !== \".\" || atom.rightDelim && atom.rightDelim !== \".\") {\n        if (atom.rightDelim && atom.rightDelim !== \".\") {\n          result += \"<mo>\" + (SPECIAL_DELIMS[atom.leftDelim] || atom.rightDelim) + \"</mo>\";\n        }\n        result += \"</mrow>\";\n      }\n      break;\n    case \"genfrac\":\n      if (atom.leftDelim || atom.rightDelim) result += \"<mrow>\";\n      if (atom.leftDelim && atom.leftDelim !== \".\") {\n        result += \"<mo\" + makeID(atom.id, options) + \">\" + (SPECIAL_DELIMS[atom.leftDelim] || atom.leftDelim) + \"</mo>\";\n      }\n      if (atom.hasBarLine) {\n        result += \"<mfrac>\";\n        result += toMathML(atom.above, options) || \"<mi>&nbsp;</mi>\";\n        result += toMathML(atom.below, options) || \"<mi>&nbsp;</mi>\";\n        result += \"</mfrac>\";\n      } else {\n        result += \"<mtable\" + makeID(atom.id, options) + \">\";\n        result += \"<mtr>\" + toMathML(atom.above, options) + \"</mtr>\";\n        result += \"<mtr>\" + toMathML(atom.below, options) + \"</mtr>\";\n        result += \"</mtable>\";\n      }\n      if (atom.rightDelim && atom.rightDelim !== \".\") {\n        result += \"<mo\" + makeID(atom.id, options) + \">\" + (SPECIAL_DELIMS[atom.rightDelim] || atom.rightDelim) + \"</mo>\";\n      }\n      if (atom.leftDelim || atom.rightDelim) result += \"</mrow>\";\n      break;\n    case \"surd\":\n      if (!atom.hasEmptyBranch(\"above\")) {\n        result += \"<mroot\" + makeID(atom.id, options) + \">\";\n        result += toMathML(atom.body, options);\n        result += toMathML(atom.above, options);\n        result += \"</mroot>\";\n      } else {\n        result += \"<msqrt\" + makeID(atom.id, options) + \">\";\n        result += toMathML(atom.body, options);\n        result += \"</msqrt>\";\n      }\n      break;\n    case \"leftright\":\n      const leftrightAtom = atom;\n      const lDelim = leftrightAtom.leftDelim;\n      result = \"<mrow>\";\n      if (lDelim && lDelim !== \".\") {\n        result += `<mo${makeID(atom.id, options)}>${(_a3 = SPECIAL_DELIMS[lDelim]) != null ? _a3 : lDelim}</mo>`;\n      }\n      if (atom.body) result += toMathML(atom.body, options);\n      const rDelim = leftrightAtom.matchingRightDelim();\n      if (rDelim && rDelim !== \".\") {\n        result += `<mo${makeID(atom.id, options)}>${(_b3 = SPECIAL_DELIMS[rDelim]) != null ? _b3 : rDelim}</mo>`;\n      }\n      result += \"</mrow>\";\n      break;\n    case \"sizeddelim\":\n    case \"delim\":\n      result += `<mo${makeID(atom.id, options)}>${SPECIAL_DELIMS[atom.value] || atom.value}</mo>`;\n      break;\n    case \"accent\":\n      result += '<mover accent=\"true\"' + makeID(atom.id, options) + \">\";\n      result += toMathML(atom.body, options);\n      result += \"<mo>\" + (SPECIAL_ACCENTS[command] || atom.accent) + \"</mo>\";\n      result += \"</mover>\";\n      break;\n    case \"line\":\n    case \"overlap\":\n      break;\n    case \"overunder\":\n      overscript = atom.above;\n      underscript = atom.below;\n      if ((atom.svgAbove || overscript) && (atom.svgBelow || underscript))\n        body = atom.body;\n      else if (overscript && overscript.length > 0) {\n        body = atom.body;\n        if ((_d2 = (_c2 = atom.body) == null ? void 0 : _c2[0]) == null ? void 0 : _d2.below) {\n          underscript = atom.body[0].below;\n          body = atom.body[0].body;\n        } else if (((_f = (_e = atom.body) == null ? void 0 : _e[0]) == null ? void 0 : _f.type) === \"first\" && ((_h = (_g = atom.body) == null ? void 0 : _g[1]) == null ? void 0 : _h.below)) {\n          underscript = atom.body[1].below;\n          body = atom.body[1].body;\n        }\n      } else if (underscript && underscript.length > 0) {\n        body = atom.body;\n        if ((_j = (_i = atom.body) == null ? void 0 : _i[0]) == null ? void 0 : _j.above) {\n          overscript = atom.body[0].above;\n          body = atom.body[0].body;\n        } else if (((_l = (_k = atom.body) == null ? void 0 : _k[0]) == null ? void 0 : _l.type) === \"first\" && ((_n = (_m = atom.body) == null ? void 0 : _m[1]) == null ? void 0 : _n.above)) {\n          overscript = atom.body[1].overscript;\n          body = atom.body[1].body;\n        }\n      }\n      if ((atom.svgAbove || overscript) && (atom.svgBelow || underscript)) {\n        result += `<munderover ${makeID(atom.id, options)}>`;\n        result += (_o = SVG_CODE_POINTS[atom.svgBody]) != null ? _o : toMathML(body, options);\n        result += (_p = SVG_CODE_POINTS[atom.svgBelow]) != null ? _p : toMathML(underscript, options);\n        result += (_q = SVG_CODE_POINTS[atom.svgAbove]) != null ? _q : toMathML(overscript, options);\n        result += \"</munderover>\";\n      } else if (atom.svgAbove || overscript) {\n        result += `<mover ${makeID(atom.id, options)}>` + ((_r = SVG_CODE_POINTS[atom.svgBody]) != null ? _r : toMathML(body, options));\n        result += (_s = SVG_CODE_POINTS[atom.svgAbove]) != null ? _s : toMathML(overscript, options);\n        result += \"</mover>\";\n      } else if (atom.svgBelow || underscript) {\n        result += `<munder ${makeID(atom.id, options)}>` + ((_t = SVG_CODE_POINTS[atom.svgBody]) != null ? _t : toMathML(body, options));\n        result += (_u = SVG_CODE_POINTS[atom.svgBelow]) != null ? _u : toMathML(underscript, options);\n        result += \"</munder>\";\n      }\n      break;\n    case \"placeholder\":\n      result += \"?\";\n      break;\n    case \"mord\": {\n      result = typeof atom.value === \"string\" ? atom.value : command;\n      if (command === \"\\\\char\") {\n        result = \"&#x\" + (\"000000\" + atom.args[0].number.toString(16)).slice(-4) + \";\";\n      } else if (result.length > 0 && result.startsWith(\"\\\\\")) {\n        if (typeof atom.value === \"string\" && atom.value.charCodeAt(0) > 255) {\n          result = \"&#x\" + (\"000000\" + atom.value.charCodeAt(0).toString(16)).slice(-4) + \";\";\n        } else if (typeof atom.value === \"string\")\n          result = atom.value.charAt(0);\n        else {\n          console.error(\"Did not expect this\");\n          result = \"\";\n        }\n      }\n      const tag = /\\d/.test(result) ? \"mn\" : \"mi\";\n      result = `<${tag}${makeID(atom.id, options)}>${xmlEscape(\n        result\n      )}</${tag}>`;\n      break;\n    }\n    case \"mbin\":\n    case \"mrel\":\n    case \"minner\":\n      result = toMo(atom, options);\n      break;\n    case \"mpunct\":\n      result = '<mo separator=\"true\"' + makeID(atom.id, options) + \">\" + command + \"</mo>\";\n      break;\n    case \"mop\":\n    case \"operator\":\n    case \"extensible-symbol\":\n      if (atom.body !== \"\\u200B\") {\n        result = \"<mo\" + makeID(atom.id, options) + \">\";\n        result += command === \"\\\\operatorname\" ? atom.body : command || atom.body;\n        result += \"</mo>\";\n      }\n      break;\n    case \"box\":\n      result = '<menclose notation=\"box\"';\n      if (atom.backgroundcolor)\n        result += ' mathbackground=\"' + atom.backgroundcolor + '\"';\n      result += makeID(atom.id, options) + \">\" + toMathML(atom.body, options) + \"</menclose>\";\n      break;\n    case \"spacing\":\n      result += '<mspace width=\"' + ((_v = SPACING[command]) != null ? _v : 0) + 'em\"/>';\n      break;\n    case \"enclose\":\n      result = '<menclose notation=\"';\n      for (const notation in atom.notation) {\n        if (Object.prototype.hasOwnProperty.call(atom.notation, notation) && atom.notation[notation]) {\n          result += sep + notation;\n          sep = \" \";\n        }\n      }\n      result += makeID(atom.id, options) + '\">' + toMathML(atom.body, options) + \"</menclose>\";\n      break;\n    case \"prompt\":\n      result = '<menclose notation=\"roundexbox\"\"\">' + toMathML(atom.body, options) + \"</menclose>\";\n      break;\n    case \"space\":\n      result += \"&nbsp;\";\n      break;\n    case \"subsup\":\n      break;\n    case \"phantom\":\n      break;\n    case \"composition\":\n      break;\n    case \"rule\":\n      break;\n    case \"chem\":\n      break;\n    case \"mopen\":\n      result += toMo(atom, options);\n      break;\n    case \"mclose\":\n      result += toMo(atom, options);\n      break;\n    case \"macro\":\n      {\n        const body2 = atom.command + toString2(atom.macroArgs);\n        if (body2) result += `<mo ${makeID(atom.id, options)}>${body2}</mo>`;\n      }\n      break;\n    case \"latexgroup\":\n      result += toMathML(atom.body, options);\n      break;\n    case \"latex\":\n      result += \"<mtext\" + makeID(atom.id, options) + \">\" + atom.value + \"</mtext>\";\n      break;\n    case \"tooltip\":\n      result += toMathML(atom.body, options);\n      break;\n    case \"text\":\n      result += `<mtext ${makeID(atom.id, options)}x>${atom.value}</mtext>`;\n      break;\n    default:\n      if (atom.command === \"\\\\displaystyle\") {\n        return `<mrow ${makeID(\n          atom.id,\n          options\n        )} displaystyle=\"true\">${toMathML(atom.body, options)}</mrow>`;\n      }\n      if (atom.command === \"\\\\textstyle\") {\n        return `<mrow ${makeID(\n          atom.id,\n          options\n        )} displaystyle=\"false\">${toMathML(atom.body, options)}</mrow>`;\n      }\n      console.info(\"Unexpected element in conversion to MathML:\", atom);\n  }\n  return result;\n}\n\n// src/formats/atom-to-speakable-text.ts\nvar PRONUNCIATION = {\n  \"\\\\alpha\": \"alpha \",\n  \"\\\\mu\": \"mew \",\n  \"\\\\sigma\": \"sigma \",\n  \"\\\\pi\": \"pie \",\n  \"\\\\imaginaryI\": \"imaginary eye \",\n  \"\\\\imaginaryJ\": \"imaginary jay \",\n  \"\\\\sum\": \"Summation \",\n  \"\\\\prod\": \"Product \",\n  \"+\": \"plus \",\n  \"-\": \"minus \",\n  \";\": '<break time=\"150ms\"/> semi-colon <break time=\"150ms\"/>',\n  \",\": '<break time=\"150ms\"/> comma  <break time=\"150ms\"/>',\n  \"|\": '<break time=\"150ms\"/>Vertical bar<break time=\"150ms\"/>',\n  \"(\": '<break time=\"150ms\"/>Open paren. <break time=\"150ms\"/>',\n  \")\": '<break time=\"150ms\"/> Close paren. <break time=\"150ms\"/>',\n  \"=\": \"equals \",\n  \"<\": \"is less than \",\n  \"\\\\lt\": \"is less than \",\n  \"<=\": \"is less than or equal to \",\n  \"\\\\le\": \"is less than or equal to \",\n  \"\\\\gt\": \"is greater than \",\n  \">\": \"is greater than \",\n  \"\\\\pm\": \"plus or minus\",\n  \"\\\\mp\": \"minus or plus\",\n  \"\\\\ge\": \"is greater than or equal to \",\n  \"\\\\geq\": \"is greater than or equal to \",\n  \"\\\\leq\": \"is less than or equal to \",\n  \"\\\\ne\": \"is not equal to \",\n  \"\\\\neq\": \"is not equal to \",\n  \"!\": \"factorial \",\n  \"\\\\sin\": \"sine \",\n  \"\\\\cos\": \"cosine \",\n  \"\\u200B\": \"\",\n  \"\\u2212\": \"minus \",\n  \":\": '<break time=\"150ms\"/> such that <break time=\"200ms\"/> ',\n  \"\\\\colon\": '<break time=\"150ms\"/> such that <break time=\"200ms\"/> ',\n  \"\\\\hbar\": \"etch bar \",\n  \"\\\\iff\": '<break time=\"200ms\"/>if, and only if, <break time=\"200ms\"/>',\n  \"\\\\Longleftrightarrow\": '<break time=\"200ms\"/>if, and only if, <break time=\"200ms\"/>',\n  \"\\\\land\": \"and \",\n  \"\\\\lor\": \"or \",\n  \"\\\\neg\": \"not \",\n  \"\\\\div\": \"divided by \",\n  \"\\\\forall\": \"for all \",\n  \"\\\\exists\": \"there exists \",\n  \"\\\\nexists\": \"there does not exists \",\n  \"\\\\in\": \"element of \",\n  \"\\\\N\": 'the set <break time=\"150ms\"/><say-as interpret-as=\"character\">n</say-as>',\n  \"\\\\C\": 'the set <break time=\"150ms\"/><say-as interpret-as=\"character\">c</say-as>',\n  \"\\\\Z\": 'the set <break time=\"150ms\"/><say-as interpret-as=\"character\">z</say-as>',\n  \"\\\\Q\": 'the set <break time=\"150ms\"/><say-as interpret-as=\"character\">q</say-as>',\n  \"\\\\infty\": \"infinity \",\n  \"\\\\nabla\": \"nabla \",\n  \"\\\\partial\": \"partial derivative of \",\n  \"\\\\cdot\": \"times \",\n  \"\\\\cdots\": \"dot dot dot \",\n  \"\\\\Rightarrow\": \"implies \",\n  \"\\\\lparen\": '<break time=\"150ms\"/>open paren<break time=\"150ms\"/>',\n  \"\\\\rparen\": '<break time=\"150ms\"/>close paren<break time=\"150ms\"/>',\n  \"\\\\lbrace\": '<break time=\"150ms\"/>open brace<break time=\"150ms\"/>',\n  \"\\\\{\": '<break time=\"150ms\"/>open brace<break time=\"150ms\"/>',\n  \"\\\\rbrace\": '<break time=\"150ms\"/>close brace<break time=\"150ms\"/>',\n  \"\\\\}\": '<break time=\"150ms\"/>close brace<break time=\"150ms\"/>',\n  \"\\\\langle\": '<break time=\"150ms\"/>left angle bracket<break time=\"150ms\"/>',\n  \"\\\\rangle\": '<break time=\"150ms\"/>right angle bracket<break time=\"150ms\"/>',\n  \"\\\\lfloor\": '<break time=\"150ms\"/>open floor<break time=\"150ms\"/>',\n  \"\\\\rfloor\": '<break time=\"150ms\"/>close floor<break time=\"150ms\"/>',\n  \"\\\\lceil\": '<break time=\"150ms\"/>open ceiling<break time=\"150ms\"/>',\n  \"\\\\rceil\": '<break time=\"150ms\"/>close ceiling<break time=\"150ms\"/>',\n  \"\\\\vert\": '<break time=\"150ms\"/>vertical bar<break time=\"150ms\"/>',\n  \"\\\\mvert\": '<break time=\"150ms\"/>divides<break time=\"150ms\"/>',\n  \"\\\\lvert\": '<break time=\"150ms\"/>left vertical bar<break time=\"150ms\"/>',\n  \"\\\\rvert\": '<break time=\"150ms\"/>right vertical bar<break time=\"150ms\"/>',\n  // '\\\\lbrack':\t\t'left bracket',\n  // '\\\\rbrack':\t\t'right bracket',\n  \"\\\\lbrack\": '<break time=\"150ms\"/> open square bracket <break time=\"150ms\"/>',\n  \"\\\\rbrack\": '<break time=\"150ms\"/> close square bracket <break time=\"150ms\"/>',\n  // Need to add code to detect singluar/plural. Until then spoken as plural since that is vastly more common\n  // note: need to worry about intervening &InvisibleTimes;.\n  // note: need to also do this when in numerator of fraction and number preceeds fraction\n  // note: need to do this for <msup>\n  \"mm\": \"millimeters\",\n  \"cm\": \"centimeters\",\n  \"km\": \"kilometers\",\n  \"kg\": \"kilograms\"\n};\nvar ENVIRONMENTS_NAMES = {\n  \"array\": \"array\",\n  \"matrix\": \"matrix\",\n  \"pmatrix\": \"parenthesis matrix\",\n  \"bmatrix\": \"square brackets matrix\",\n  \"Bmatrix\": \"braces matrix\",\n  \"vmatrix\": \"bars matrix\",\n  \"Vmatrix\": \"double bars matrix\",\n  \"matrix*\": \"matrix\",\n  \"smallmatrix\": \"small matrix\"\n};\nfunction getSpokenName(latex) {\n  let result = \"\";\n  if (latex.startsWith(\"\\\\\")) result = \" \" + latex.replace(\"\\\\\", \"\") + \" \";\n  return result;\n}\nfunction isAtomic(atoms) {\n  let count = 0;\n  if (isArray(atoms)) {\n    for (const atom of atoms) if (atom.type !== \"first\") count += 1;\n  }\n  return count === 1;\n}\nfunction atomicID(atoms) {\n  if (isArray(atoms)) {\n    for (const atom of atoms)\n      if (atom.type !== \"first\" && atom.id) return atom.id.toString();\n  }\n  return \"\";\n}\nfunction atomicValue(atoms) {\n  let result = \"\";\n  if (isArray(atoms)) {\n    for (const atom of atoms) {\n      if (atom.type !== \"first\" && typeof atom.value === \"string\")\n        result += atom.value;\n    }\n  }\n  return result;\n}\nfunction atomsAsText(atoms) {\n  if (!atoms) return \"\";\n  return atoms.map((atom) => atom.value).join(\"\");\n}\nfunction emph(s) {\n  return `<emphasis>${s}</emphasis>`;\n}\nfunction atomsToSpeakableFragment(mode, atom) {\n  var _a3;\n  let result = \"\";\n  let isInDigitRun = false;\n  let isInTextRun = false;\n  for (let i = 0; i < atom.length; i++) {\n    if (atom[i].type === \"first\") continue;\n    if (atom[i].mode !== \"text\") isInTextRun = false;\n    if (i < atom.length - 2 && atom[i].type === \"mopen\" && atom[i + 2].type === \"mclose\" && atom[i + 1].type === \"mord\") {\n      result += \" of \";\n      result += emph(atomToSpeakableFragment(mode, atom[i + 1]));\n      i += 2;\n    } else if (atom[i].mode === \"text\") {\n      if (isInTextRun) result += (_a3 = atom[i].value) != null ? _a3 : \" \";\n      else {\n        isInTextRun = true;\n        result += atomToSpeakableFragment(\"text\", atom[i]);\n      }\n    } else if (atom[i].isDigit()) {\n      if (isInDigitRun) result += atom[i].asDigit();\n      else {\n        isInDigitRun = true;\n        result += atomToSpeakableFragment(mode, atom[i]);\n      }\n    } else {\n      isInDigitRun = false;\n      result += atomToSpeakableFragment(mode, atom[i]);\n    }\n  }\n  return result;\n}\nfunction atomToSpeakableFragment(mode, atom) {\n  var _a3, _b3, _c2, _d2;\n  function letter(c) {\n    if (!globalThis.MathfieldElement.textToSpeechMarkup) {\n      if (/[a-z]/.test(c)) return \" '\" + c.toUpperCase() + \"'\";\n      if (/[A-Z]/.test(c)) return \" 'capital \" + c.toUpperCase() + \"'\";\n      return c;\n    }\n    if (/[a-z]/.test(c))\n      return ` <say-as interpret-as=\"character\">${c}</say-as>`;\n    if (/[A-Z]/.test(c))\n      return `capital <say-as interpret-as=\"character\">${c.toLowerCase()}</say-as>`;\n    return c;\n  }\n  if (!atom) return \"\";\n  if (isArray(atom)) return atomsToSpeakableFragment(mode, atom);\n  let result = \"\";\n  if (atom.id && mode === \"math\")\n    result += '<mark name=\"' + atom.id.toString() + '\"/>';\n  if (atom.mode === \"text\") return result + atom.value;\n  let numer = \"\";\n  let denom = \"\";\n  let body = \"\";\n  let supsubHandled = false;\n  const { command } = atom;\n  switch (command) {\n    case \"\\\\vec\":\n      return \"vector \" + atomToSpeakableFragment(mode, atom.body);\n    case \"\\\\acute\":\n      return atomToSpeakableFragment(mode, atom.body) + \" acute\";\n    case \"\\\\grave\":\n      return atomToSpeakableFragment(mode, atom.body) + \" grave\";\n    case \"\\\\dot\":\n      return \"dot over\" + atomToSpeakableFragment(mode, atom.body);\n    case \"\\\\ddot\":\n      return \"double dot over\" + atomToSpeakableFragment(mode, atom.body);\n    case \"\\\\mathring\":\n      return \"ring over\" + atomToSpeakableFragment(mode, atom.body);\n    case \"\\\\tilde\":\n    case \"\\\\widetilde\":\n      return \"tilde over\" + atomToSpeakableFragment(mode, atom.body);\n    case \"\\\\bar\":\n      return atomToSpeakableFragment(mode, atom.body) + \" bar\";\n    case \"\\\\breve\":\n      return atomToSpeakableFragment(mode, atom.body) + \" breve\";\n    case \"\\\\check\":\n    case \"\\\\widecheck\":\n      return \"check over \" + atomToSpeakableFragment(mode, atom.body);\n    case \"\\\\hat\":\n    case \"\\\\widehat\":\n      return \"hat over\" + atomToSpeakableFragment(mode, atom.body);\n    case \"\\\\overarc\":\n    case \"\\\\overparen\":\n    case \"\\\\wideparen\":\n      return \"arc over \" + atomToSpeakableFragment(mode, atom.body);\n    case \"\\\\underarc\":\n    case \"\\\\underparen\":\n      return \"arc under \" + atomToSpeakableFragment(mode, atom.body);\n  }\n  switch (atom.type) {\n    case \"prompt\":\n      const input = atom.body.length > 1 ? 'start input . <break time=\"500ms\"/> ' + atomToSpeakableFragment(mode, atom.body) + '. <break time=\"500ms\"/> end input' : \"blank\";\n      result += ' <break time=\"300ms\"/> ' + input + '. <break time=\"700ms\"/>' + ((_a3 = atom.correctness) != null ? _a3 : \"\") + ' . <break time=\"700ms\"/> ';\n      break;\n    case \"array\":\n      const array = atom.array;\n      const environment = atom.environmentName;\n      if (Object.keys(ENVIRONMENTS_NAMES).includes(environment)) {\n        result += ` begin ${ENVIRONMENTS_NAMES[environment]} `;\n        for (let i = 0; i < array.length; i++) {\n          if (i > 0) result += \",\";\n          result += ` row ${i + 1} `;\n          for (let j = 0; j < array[i].length; j++) {\n            if (j > 0) result += \",\";\n            result += ` column ${j + 1}: `;\n            result += atomToSpeakableFragment(\"math\", array[i][j]);\n          }\n        }\n        result += ` end ${ENVIRONMENTS_NAMES[environment]} `;\n      }\n      break;\n    case \"group\":\n      if (command === \"\\\\ne\") result += \" not equal \";\n      else if (command === \"\\\\not\") {\n        result += \" not \";\n        result += atomToSpeakableFragment(\"math\", atom.body);\n      } else {\n        result += atomToSpeakableFragment(\"math\", atom.body);\n      }\n      break;\n    case \"root\":\n      result += atomToSpeakableFragment(\"math\", atom.body);\n      break;\n    case \"genfrac\":\n      numer = atomToSpeakableFragment(\"math\", atom.above);\n      denom = atomToSpeakableFragment(\"math\", atom.below);\n      if (isAtomic(atom.above) && isAtomic(atom.below)) {\n        const COMMON_FRACTIONS = {\n          \"1/2\": \" half \",\n          \"1/3\": \" one third \",\n          \"2/3\": \" two third\",\n          \"1/4\": \" one quarter \",\n          \"3/4\": \" three quarter \",\n          \"1/5\": \" one fifth \",\n          \"2/5\": \" two fifths \",\n          \"3/5\": \" three fifths \",\n          \"4/5\": \" four fifths \",\n          \"1/6\": \" one sixth \",\n          \"5/6\": \" five sixths \",\n          \"1/8\": \" one eight \",\n          \"3/8\": \" three eights \",\n          \"5/8\": \" five eights \",\n          \"7/8\": \" seven eights \",\n          \"1/9\": \" one ninth \",\n          \"2/9\": \" two ninths \",\n          \"4/9\": \" four ninths \",\n          \"5/9\": \" five ninths \",\n          \"7/9\": \" seven ninths \",\n          \"8/9\": \" eight ninths \"\n          // '1/10':     ' one tenth ',\n          // '1/12':     ' one twelfth ',\n          // 'x/2':     ' <say-as interpret-as=\"character\">X</say-as> over 2',\n        };\n        const commonFraction = COMMON_FRACTIONS[atomicValue(atom.above) + \"/\" + atomicValue(atom.below)];\n        if (commonFraction) result = commonFraction;\n        else result += numer + \" over \" + denom;\n      } else {\n        result += ' the fraction <break time=\"150ms\"/>' + numer + ' over <break time=\"150ms\"/>' + denom + '.<break time=\"150ms\"/> End fraction.<break time=\"150ms\"/>';\n      }\n      break;\n    case \"surd\":\n      body = atomToSpeakableFragment(\"math\", atom.body);\n      if (atom.hasEmptyBranch(\"above\")) {\n        result += isAtomic(atom.body) ? \" the square root of \" + body + \" , \" : ' the square root of <break time=\"200ms\"/>' + body + '. <break time=\"200ms\"/> End square root';\n      } else {\n        let index = atomToSpeakableFragment(\"math\", atom.above);\n        index = index.trim();\n        const index2 = index.replace(/<mark([^/]*)\\/>/g, \"\");\n        if (index2 === \"3\") {\n          result += ' the cube root of <break time=\"200ms\"/>' + body + '. <break time=\"200ms\"/> End cube root';\n        } else if (index2 === \"n\") {\n          result += ' the nth root of <break time=\"200ms\"/>' + body + '. <break time=\"200ms\"/> End root';\n        } else {\n          result += ' the root with index: <break time=\"200ms\"/>' + index + ', of <break time=\"200ms\"/>' + body + '. <break time=\"200ms\"/> End root';\n        }\n      }\n      break;\n    case \"leftright\":\n      {\n        const delimAtom = atom;\n        result += (_b3 = delimAtom.leftDelim ? PRONUNCIATION[delimAtom.leftDelim] : void 0) != null ? _b3 : delimAtom.leftDelim;\n        result += atomToSpeakableFragment(\"math\", atom.body);\n        result += (_c2 = delimAtom.rightDelim ? PRONUNCIATION[delimAtom.rightDelim] : void 0) != null ? _c2 : delimAtom.rightDelim;\n      }\n      break;\n    case \"rule\":\n      break;\n    case \"overunder\":\n      break;\n    case \"overlap\":\n      break;\n    case \"macro\":\n      const macroName = command.replace(/^\\\\/g, \"\");\n      const macro = getMacros()[macroName];\n      if (macro) {\n        if (macro == null ? void 0 : macro.expand) result += atomToSpeakableFragment(\"math\", atom.body);\n        else result += `${macroName} `;\n      }\n      break;\n    case \"placeholder\":\n      result += \"placeholder \";\n      break;\n    case \"delim\":\n    case \"sizeddelim\":\n    case \"mord\":\n    case \"minner\":\n    case \"mbin\":\n    case \"mrel\":\n    case \"mpunct\":\n    case \"mopen\":\n    case \"mclose\": {\n      if (command === \"\\\\mathbin\" || command === \"\\\\mathrel\" || command === \"\\\\mathopen\" || command === \"\\\\mathclose\" || command === \"\\\\mathpunct\" || command === \"\\\\mathord\" || command === \"\\\\mathinner\") {\n        result = atomToSpeakableFragment(mode, atom.body);\n        break;\n      }\n      let atomValue = atom.isDigit() ? atom.asDigit() : atom.value;\n      let latexValue = atom.command;\n      if (atom.type === \"delim\" || atom.type === \"sizeddelim\") {\n        latexValue = atom.value;\n        atomValue = latexValue;\n      }\n      if (mode === \"text\") result += atomValue;\n      else {\n        if (atom.type === \"mbin\") result += '<break time=\"150ms\"/>';\n        if (atomValue) {\n          const value = PRONUNCIATION[atomValue] || (latexValue ? PRONUNCIATION[latexValue.trim()] : \"\");\n          if (value) result += \" \" + value;\n          else {\n            const spokenName = latexValue ? getSpokenName(latexValue.trim()) : \"\";\n            result += spokenName ? spokenName : letter(atomValue);\n          }\n        } else result += atomToSpeakableFragment(\"math\", atom.body);\n        if (atom.type === \"mbin\") result += '<break time=\"150ms\"/>';\n      }\n      break;\n    }\n    case \"mop\":\n    case \"operator\":\n    case \"extensible-symbol\":\n      if (atom.value !== \"\\u200B\") {\n        const trimLatex = atom.command;\n        if (trimLatex === \"\\\\sum\") {\n          if (!atom.hasEmptyBranch(\"superscript\") && !atom.hasEmptyBranch(\"subscript\")) {\n            let sup = atomToSpeakableFragment(\"math\", atom.superscript);\n            sup = sup.trim();\n            let sub = atomToSpeakableFragment(\"math\", atom.subscript);\n            sub = sub.trim();\n            result += ' the summation from <break time=\"200ms\"/>' + sub + '<break time=\"200ms\"/> to  <break time=\"200ms\"/>' + sup + '<break time=\"200ms\"/> of <break time=\"150ms\"/>';\n            supsubHandled = true;\n          } else if (!atom.hasEmptyBranch(\"subscript\")) {\n            let sub = atomToSpeakableFragment(\"math\", atom.subscript);\n            sub = sub.trim();\n            result += ' the summation from <break time=\"200ms\"/>' + sub + '<break time=\"200ms\"/> of <break time=\"150ms\"/>';\n            supsubHandled = true;\n          } else result += \" the summation of\";\n        } else if (trimLatex === \"\\\\prod\") {\n          if (!atom.hasEmptyBranch(\"superscript\") && !atom.hasEmptyBranch(\"subscript\")) {\n            let sup = atomToSpeakableFragment(\"math\", atom.superscript);\n            sup = sup.trim();\n            let sub = atomToSpeakableFragment(\"math\", atom.subscript);\n            sub = sub.trim();\n            result += ' the product from <break time=\"200ms\"/>' + sub + '<break time=\"200ms\"/> to <break time=\"200ms\"/>' + sup + '<break time=\"200ms\"/> of <break time=\"150ms\"/>';\n            supsubHandled = true;\n          } else if (!atom.hasEmptyBranch(\"subscript\")) {\n            let sub = atomToSpeakableFragment(\"math\", atom.subscript);\n            sub = sub.trim();\n            result += ' the product from <break time=\"200ms\"/>' + sub + '<break time=\"200ms\"/> of <break time=\"150ms\"/>';\n            supsubHandled = true;\n          } else result += \" the product  of \";\n        } else if (trimLatex === \"\\\\int\") {\n          if (!atom.hasEmptyBranch(\"superscript\") && !atom.hasEmptyBranch(\"subscript\")) {\n            let sup = atomToSpeakableFragment(\"math\", atom.superscript);\n            sup = sup.trim();\n            let sub = atomToSpeakableFragment(\"math\", atom.subscript);\n            sub = sub.trim();\n            result += ' the integral from <break time=\"200ms\"/>' + emph(sub) + '<break time=\"200ms\"/> to <break time=\"200ms\"/>' + emph(sup) + ' <break time=\"200ms\"/> of ';\n            supsubHandled = true;\n          } else result += ' the integral of <break time=\"200ms\"/> ';\n        } else if (trimLatex === \"\\\\operatorname\" || trimLatex === \"\\\\operatorname*\")\n          result += atomsAsText(atom.body) + \" \";\n        else if (typeof atom.value === \"string\") {\n          const value = (_d2 = PRONUNCIATION[atom.value]) != null ? _d2 : atom.command ? PRONUNCIATION[atom.command] : void 0;\n          result += value ? value : \" \" + atom.value;\n        } else if (atom.command) {\n          if (atom.command === \"\\\\mathop\")\n            result += atomToSpeakableFragment(\"math\", atom.body);\n          else {\n            result += atom.command.startsWith(\"\\\\\") ? \" \" + atom.command.slice(1) : \" \" + atom.command;\n          }\n        }\n      }\n      break;\n    case \"enclose\":\n      body = atomToSpeakableFragment(\"math\", atom.body);\n      result += \" crossed out \" + body + \". End crossed out.\";\n      break;\n    case \"space\":\n    case \"spacing\":\n      break;\n  }\n  if (!supsubHandled && !atom.hasEmptyBranch(\"superscript\")) {\n    let sup = atomToSpeakableFragment(mode, atom.superscript);\n    sup = sup.trim();\n    const sup2 = sup.replace(/<[^>]*>/g, \"\");\n    if (isAtomic(atom.superscript)) {\n      if (mode === \"math\") {\n        const id = atomicID(atom.superscript);\n        if (id) result += '<mark name=\"' + id + '\"/>';\n      }\n      if (sup2 === \"\\u2032\") result += \" prime \";\n      else if (sup2 === \"2\") result += \" squared \";\n      else if (sup2 === \"3\") result += \" cubed \";\n      else if (Number.isNaN(Number.parseInt(sup2)))\n        result += \" to the \" + sup + \"; \";\n      else {\n        result += ' to the <say-as interpret-as=\"ordinal\">' + sup2 + \"</say-as> power; \";\n      }\n    } else if (Number.isNaN(Number.parseInt(sup2)))\n      result += \" raised to the \" + sup + \"; \";\n    else {\n      result += ' raised to the <say-as interpret-as=\"ordinal\">' + sup2 + \"</say-as> power; \";\n    }\n  }\n  if (!supsubHandled && !atom.hasEmptyBranch(\"subscript\")) {\n    let sub = atomToSpeakableFragment(\"math\", atom.subscript);\n    sub = sub.trim();\n    result += isAtomic(atom.subscript) ? \" sub \" + sub : \" subscript \" + sub + \". End subscript. \";\n  }\n  return result;\n}\nfunction atomToSpeakableText(atoms) {\n  var _a3, _b3;\n  const mfe = globalThis.MathfieldElement;\n  if (mfe.textToSpeechRules === \"sre\" && (\"sre\" in window || \"SRE\" in window)) {\n    const mathML = toMathML(atoms);\n    if (mathML) {\n      if (mfe.textToSpeechMarkup) {\n        mfe.textToSpeechRulesOptions = (_a3 = mfe.textToSpeechRulesOptions) != null ? _a3 : {};\n        mfe.textToSpeechRulesOptions = __spreadProps(__spreadValues({}, mfe.textToSpeechRulesOptions), {\n          markup: mfe.textToSpeechMarkup\n        });\n        if (mfe.textToSpeechRulesOptions.markup === \"ssml\") {\n          mfe.textToSpeechRulesOptions = __spreadProps(__spreadValues({}, mfe.textToSpeechRulesOptions), {\n            markup: \"ssml_step\"\n          });\n        }\n        mfe.textToSpeechRulesOptions = __spreadProps(__spreadValues({}, mfe.textToSpeechRulesOptions), {\n          rate: mfe.speechEngineRate\n        });\n      }\n      const SRE = (_b3 = window[\"SRE\"]) != null ? _b3 : globalThis.sre.System.getInstance();\n      if (mfe.textToSpeechRulesOptions)\n        SRE.setupEngine(mfe.textToSpeechRulesOptions);\n      let result2 = \"\";\n      try {\n        result2 = SRE.toSpeech(mathML);\n      } catch (e) {\n        console.error(\n          `MathLive 0.101.0: \\`SRE.toSpeech()\\` runtime error`,\n          e\n        );\n      }\n      return result2;\n    }\n    return \"\";\n  }\n  let result = atomToSpeakableFragment(\"math\", atoms);\n  if (mfe.textToSpeechMarkup === \"ssml\") {\n    let prosody = \"\";\n    if (mfe.speechEngineRate)\n      prosody = '<prosody rate=\"' + mfe.speechEngineRate + '\">';\n    result = `<?xml version=\"1.0\"?><speak version=\"1.1\" xmlns=\"http://www.w3.org/2001/10/synthesis\" xml:lang=\"en-US\"><amazon:auto-breaths>` + prosody + \"<p><s>\" + result + \"</s></p>\" + (prosody ? \"</prosody>\" : \"\") + \"</amazon:auto-breaths></speak>\";\n  } else if (mfe.textToSpeechMarkup === \"mac\" && osPlatform() === \"macos\") {\n    result = result.replace(/<mark([^/]*)\\/>/g, \"\").replace(/<emphasis>/g, \"[[emph+]]\").replace(/<\\/emphasis>/g, \"\").replace(/<break time=\"(\\d*)ms\"\\/>/g, \"[[slc $1]]\").replace(/<say-as[^>]*>/g, \"\").replace(/<\\/say-as>/g, \"\");\n  } else {\n    result = result.replace(/<[^>]*>/g, \"\").replace(/\\s{2,}/g, \" \");\n  }\n  return result;\n}\n\n// src/formats/atom-to-ascii-math.ts\nvar IDENTIFIERS = {\n  \"\\\\ne\": \"\\u2260\",\n  \"\\\\neq\": \"\\u2260\",\n  \"\\u2212\": \"-\",\n  // MINUS SIGN\n  \"-\": \"-\",\n  \"\\\\alpha\": \"alpha\",\n  \"\\\\beta\": \"beta\",\n  \"\\\\gamma\": \"gamma\",\n  \"\\\\delta\": \"delta\",\n  \"\\\\epsilon\": \"epsilon\",\n  \"\\\\varepsilon\": \"varepsilon\",\n  \"\\\\zeta\": \"zeta\",\n  \"\\\\eta\": \"eta\",\n  \"\\\\theta\": \"theta\",\n  \"\\\\vartheta\": \"vartheta\",\n  \"\\\\iota\": \"iota\",\n  \"\\\\kappa\": \"kappa\",\n  \"\\\\lambda\": \"lambda\",\n  \"\\\\mu\": \"mu\",\n  \"\\\\nu\": \"nu\",\n  \"\\\\xi\": \"xi\",\n  \"\\\\pi\": \"pi\",\n  \"\\\\rho\": \"rho\",\n  \"\\\\sigma\": \"sigma\",\n  \"\\\\tau\": \"tau\",\n  \"\\\\upsilon\": \"upsilon\",\n  \"\\\\phi\": \"phi\",\n  \"\\\\varphi\": \"varphi\",\n  \"\\\\chi\": \"chi\",\n  \"\\\\psi\": \"psi\",\n  \"\\\\omega\": \"omega\",\n  \"\\\\Gamma\": \"Gamma\",\n  \"\\\\Delta\": \"Delta\",\n  \"\\\\Theta\": \"Theta\",\n  \"\\\\Lambda\": \"Lambda\",\n  \"\\\\Xi\": \"Xi\",\n  \"\\\\Pi\": \"Pi\",\n  \"\\\\Sigma\": \"Sigma\",\n  \"\\\\Phi\": \"Phi\",\n  \"\\\\Psi\": \"Psi\",\n  \"\\\\Omega\": \"Omega\",\n  \"\\\\exponentialE\": \"e\",\n  \"\\\\imaginaryI\": \"i\",\n  \"\\\\imaginaryJ\": \"j\",\n  \"\\\\!\": \" \",\n  \"\\\\,\": \" \",\n  \"\\\\:\": \" \",\n  \"\\\\>\": \" \",\n  \"\\\\;\": \" \",\n  \"\\\\enskip\": \" \",\n  \"\\\\enspace\": \" \",\n  \"\\\\qquad\": \" \",\n  \"\\\\quad\": \" \",\n  \"\\\\infty\": \"oo\",\n  \"\\\\R\": \"RR\",\n  \"\\\\N\": \"NN\",\n  \"\\\\Z\": \"ZZ\",\n  \"\\\\Q\": \"QQ\",\n  \"\\\\C\": \"CC\",\n  \"\\\\emptyset\": \"O/\",\n  \"\\\\varnothing\": \"O/\",\n  \"\\\\varDelta\": \"Delta\",\n  \"\\\\varTheta\": \"Theta\",\n  \"\\\\varLambda\": \"Lambda\",\n  \"\\\\varXi\": \"Xi\",\n  \"\\\\varPi\": \"Pi\",\n  \"\\\\varSigma\": \"Sigma\",\n  \"\\\\varUpsilon\": \"Upsilon\",\n  \"\\\\varPhi\": \"Phi\",\n  \"\\\\varPsi\": \"Psi\",\n  \"\\\\varOmega\": \"Omega\"\n};\nvar OPERATORS = {\n  \"\\\\pm\": \"+-\",\n  \"\\\\colon\": \":\",\n  \"\\\\sum\": \" sum \",\n  \"\\\\prod\": \" prod \",\n  \"\\\\bigcap\": \" nnn \",\n  \"\\\\bigcup\": \" uuu \",\n  \"\\\\int\": \" int \",\n  \"\\\\oint\": \" oint \",\n  \"\\\\ge\": \">=\",\n  \"\\\\le\": \"<=\",\n  \"\\\\ne\": \"!=\",\n  \"\\\\neq\": \"!=\",\n  \"\\\\lt\": \"<\",\n  \"\\\\gt\": \">\",\n  \"\\\\gets\": \"<-\",\n  \"\\\\to\": \"->\",\n  \"\\\\land\": \" and \",\n  \"\\\\lor\": \" or \",\n  \"\\\\lnot\": \" not \",\n  \"\\\\forall\": \" AA \",\n  \"\\\\exists\": \" EE \",\n  \"\\\\in\": \" in \",\n  \"\\\\notin\": \" !in \",\n  \"\\\\mapsto\": \"|->\",\n  \"\\\\implies\": \"=>\",\n  \"\\\\iff\": \"<=>\",\n  \"\\\\cdot\": \"*\",\n  \"\\\\ast\": \"**\",\n  \"\\\\star\": \"***\",\n  \"\\\\times\": \"xx\",\n  \"\\\\div\": \"-:\",\n  \"\\\\ltimes\": \"|><\",\n  \"\\\\rtimes\": \"><|\",\n  \"\\\\bowtie\": \"|><|\",\n  \"\\\\circ\": \"@\"\n  // '\\\\lfloor': '\\u230a',\n  // '\\\\rfloor': '\\u230b',\n  // '\\\\lceil': '\\u2308',\n  // '\\\\rceil': '\\u2309',\n  // '\\\\vec': '&#x20d7;',\n  // '\\\\acute': '&#x00b4;',\n  // '\\\\grave': '&#x0060;',\n  // '\\\\dot': '&#x02d9;',\n  // '\\\\ddot': '&#x00a8;',\n  // '\\\\tilde': '&#x007e;',\n  // '\\\\bar': '&#x00af;',\n  // '\\\\breve': '&#x02d8;',\n  // '\\\\check': '&#x02c7;',\n  // '\\\\hat': '&#x005e;'\n};\nvar FENCES2 = {\n  \"\\\\vert\": \"|\",\n  \"\\\\Vert\": \"||\",\n  \"\\\\mid\": \"|\",\n  \"\\\\lbrack\": \"[\",\n  \"\\\\rbrack\": \"]\",\n  \"\\\\lbrace\": \"{\",\n  \"\\\\rbrace\": \"}\",\n  \"\\\\lparen\": \"(\",\n  \"\\\\rparen\": \")\",\n  \"\\\\langle\": \"(:\",\n  \"\\\\rangle\": \":)\"\n};\nfunction joinAsciiMath(xs) {\n  let result = \"\";\n  for (const x of xs) {\n    const last = result[result.length - 1];\n    if (last !== void 0 && /\\d/.test(last) && /^\\d/.test(x)) result += \" \";\n    result += x;\n  }\n  return result;\n}\nfunction atomToAsciiMath(atom, options) {\n  var _a3, _b3, _c2, _d2, _e, _f, _g, _h, _i, _j, _k, _l, _m;\n  if (!atom) return \"\";\n  if (isArray(atom)) {\n    if (atom.length === 0) return \"\";\n    if (atom[0].mode === \"latex\")\n      return atom.map((x) => atomToAsciiMath(x)).join(\"\");\n    if (atom[0].mode === \"text\") {\n      let i2 = 0;\n      let text = \"\";\n      while (((_a3 = atom[i2]) == null ? void 0 : _a3.mode) === \"text\") {\n        text += atom[i2].body ? atomToAsciiMath(atom[i2].body, options) : atom[i2].value;\n        i2++;\n      }\n      if (options == null ? void 0 : options.plain) return text + atomToAsciiMath(atom.slice(i2), options);\n      return `\"${text}\" ${atomToAsciiMath(atom.slice(i2))}`;\n    }\n    let i = 0;\n    const result2 = [];\n    while (atom[i] && atom[i].mode === \"math\") {\n      let digits = \"\";\n      while (atom[i] && atom[i].type === \"mord\" && /\\d/.test(atom[i].value))\n        digits += atom[i++].value;\n      if (digits) result2.push(digits);\n      else result2.push(atomToAsciiMath(atom[i++], options));\n    }\n    result2.push(atomToAsciiMath(atom.slice(i), options));\n    return joinAsciiMath(result2);\n  }\n  if (atom.mode === \"text\")\n    return (options == null ? void 0 : options.plain) ? atom.value : `\"${atom.value}\"`;\n  let result = \"\";\n  const { command } = atom;\n  let m;\n  if (command === \"\\\\placeholder\")\n    return `(${atomToAsciiMath(atom.body, options)})`;\n  switch (atom.type) {\n    case \"accent\":\n      const accent = {\n        \"\\\\vec\": \"vec\",\n        \"\\\\dot\": \"dot\",\n        \"\\\\ddot\": \"ddot\",\n        \"\\\\bar\": \"bar\",\n        \"\\\\hat\": \"hat\",\n        \"\\\\acute\": \"acute;\",\n        // non-standard\n        \"\\\\grave\": \"grave\",\n        // non-standard\n        \"\\\\tilde\": \"tilde\",\n        // non-standard\n        \"\\\\breve\": \"breave\",\n        // non-standard\n        \"\\\\check\": \"check\"\n        // non-standard\n      }[command];\n      result = `${accent != null ? accent : \"\"} ${atomToAsciiMath(atom.body, options)} `;\n      break;\n    case \"first\":\n      return \"\";\n    case \"latexgroup\":\n      return atom.body.map((x) => x.value).join(\"\");\n    case \"group\":\n    case \"root\":\n      result = (_b3 = IDENTIFIERS[command]) != null ? _b3 : atomToAsciiMath(atom.body, options);\n      break;\n    case \"genfrac\":\n      {\n        const genfracAtom = atom;\n        if (genfracAtom.leftDelim || genfracAtom.rightDelim) {\n          result = genfracAtom.leftDelim === \".\" || !genfracAtom.leftDelim ? \"{:\" : genfracAtom.leftDelim;\n        }\n        if (genfracAtom.hasBarLine) {\n          result += \"(\";\n          result += atomToAsciiMath(genfracAtom.above, options);\n          result += \")/(\";\n          result += atomToAsciiMath(genfracAtom.below, options);\n          result += \")\";\n        } else {\n          result += \"(\" + atomToAsciiMath(genfracAtom.above, options) + \"),\";\n          result += \"(\" + atomToAsciiMath(genfracAtom.below, options) + \")\";\n        }\n        if (genfracAtom.leftDelim || genfracAtom.rightDelim) {\n          result += genfracAtom.rightDelim === \".\" || !genfracAtom.rightDelim ? \"{:\" : genfracAtom.rightDelim;\n        }\n      }\n      break;\n    case \"surd\":\n      if (atom.hasEmptyBranch(\"above\"))\n        result += `sqrt(${atomToAsciiMath(atom.body, options)})`;\n      else\n        result += `root(${atomToAsciiMath(atom.above, options)})(${atomToAsciiMath(atom.body, options)})`;\n      break;\n    case \"latex\":\n      result = atom.value;\n      break;\n    case \"leftright\":\n      {\n        const leftrightAtom = atom;\n        let lDelim = leftrightAtom.leftDelim;\n        if (lDelim && FENCES2[lDelim]) lDelim = FENCES2[lDelim];\n        result += lDelim === \".\" || !lDelim ? \"{:\" : lDelim;\n        result += atomToAsciiMath(leftrightAtom.body, options);\n        let rDelim = leftrightAtom.matchingRightDelim();\n        if (rDelim && FENCES2[rDelim]) rDelim = FENCES2[rDelim];\n        result += rDelim === \".\" || !rDelim ? \":}\" : rDelim;\n      }\n      break;\n    case \"sizeddelim\":\n    case \"delim\":\n      result = atom.value;\n      break;\n    case \"overlap\":\n      break;\n    case \"overunder\":\n      break;\n    case \"mord\":\n      result = (_d2 = (_c2 = IDENTIFIERS[command]) != null ? _c2 : command) != null ? _d2 : typeof atom.value === \"string\" ? atom.value : \"\";\n      if (result.startsWith(\"\\\\\")) result += \" \";\n      m = command ? command.match(/{?\\\\char\"([\\dabcdefABCDEF]+)}?/) : null;\n      if (m) {\n        result = String.fromCodePoint(Number.parseInt(\"0x\" + m[1]));\n      } else if (result.length > 0 && result.startsWith(\"\\\\\")) {\n        result = typeof atom.value === \"string\" ? atom.value.charAt(0) : atom.command;\n      }\n      result = asciiStyle(result, atom.style);\n      break;\n    case \"mbin\":\n    case \"mrel\":\n    case \"minner\":\n      result = (_f = (_e = IDENTIFIERS[command]) != null ? _e : OPERATORS[command]) != null ? _f : atom.value;\n      break;\n    case \"mopen\":\n    case \"mclose\":\n      result = atom.value;\n      break;\n    case \"mpunct\":\n      result = (_g = OPERATORS[command]) != null ? _g : command;\n      break;\n    case \"mop\":\n    case \"operator\":\n    case \"extensible-symbol\":\n      if (atom.value !== \"\\u200B\") {\n        if (OPERATORS[command]) result = OPERATORS[command];\n        else {\n          result = command === \"\\\\operatorname\" ? atomToAsciiMath(atom.body, options) : (_h = atom.value) != null ? _h : command;\n        }\n        result += \" \";\n      }\n      break;\n    case \"array\":\n      const array = atom.array;\n      const environment = atom.environmentName;\n      const rowDelim = (_i = {\n        \"bmatrix\": [\"[\", \"]\"],\n        \"bmatrix*\": [\"[\", \"]\"]\n      }[environment]) != null ? _i : [\"(\", \")\"];\n      const rows = [];\n      for (const row of array) {\n        const cells = [];\n        for (const cell of row)\n          cells.push(\n            rowDelim[0] + atomToAsciiMath(cell, options) + rowDelim[1]\n          );\n        rows.push(cells.join(\",\"));\n      }\n      const delim = (_j = {\n        \"bmatrix\": [\"[\", \"]\"],\n        \"bmatrix*\": [\"[\", \"]\"],\n        \"cases\": [\"{\", \":}\"]\n      }[environment]) != null ? _j : [\"(\", \")\"];\n      result = delim[0] + rows.join(\",\") + delim[1];\n      break;\n    case \"box\":\n      break;\n    case \"spacing\":\n      result = (_k = IDENTIFIERS[command]) != null ? _k : \" \";\n      break;\n    case \"enclose\":\n      result = \"(\" + atomToAsciiMath(atom.body, options) + \")\";\n      break;\n    case \"space\":\n      result = \" \";\n      break;\n    case \"subsup\":\n      result = \"\";\n      break;\n    case \"macro\":\n      result = (_m = (_l = IDENTIFIERS[command]) != null ? _l : OPERATORS[command]) != null ? _m : atomToAsciiMath(atom.body, options);\n      break;\n  }\n  if (!atom.hasEmptyBranch(\"subscript\")) {\n    result += \"_\";\n    const arg = atomToAsciiMath(atom.subscript, options);\n    result += arg.length !== 1 ? `(${arg})` : arg;\n  }\n  if (!atom.hasEmptyBranch(\"superscript\")) {\n    result += \"^\";\n    const arg = atomToAsciiMath(atom.superscript, options);\n    result += arg.length !== 1 ? `(${arg})` : arg;\n  }\n  return result;\n}\nfunction asciiStyle(body, style) {\n  if (!style) return body;\n  let result = body;\n  if (style.variant === \"double-struck\") result = `bbb \"${result}\"`;\n  if (style.variant === \"script\") result = `cc \"${result}\"`;\n  if (style.variant === \"fraktur\") result = `fr \"${result}\"`;\n  if (style.variant === \"sans-serif\") result = `sf \"${result}\"`;\n  if (style.variant === \"monospace\") result = `tt \"${result}\"`;\n  if (style.variantStyle === \"bold\") result = `bb \"${result}\"`;\n  if (style.color) return `color({${style.color}})(${result})`;\n  return result;\n}\n\n// src/public/mathlive-ssr.ts\nfunction convertLatexToMarkup(text, options) {\n  var _a3;\n  const from = __spreadProps(__spreadValues({}, getDefaultContext()), {\n    renderPlaceholder: () => new Box(160, { maxFontSize: 1 })\n  });\n  if ((options == null ? void 0 : options.letterShapeStyle) && (options == null ? void 0 : options.letterShapeStyle) !== \"auto\")\n    from.letterShapeStyle = options.letterShapeStyle;\n  if (options == null ? void 0 : options.macros) {\n    const macros = normalizeMacroDictionary(options == null ? void 0 : options.macros);\n    from.getMacro = (token) => getMacroDefinition(token, macros);\n  }\n  if (options == null ? void 0 : options.registers)\n    from.registers = __spreadValues(__spreadValues({}, from.registers), options.registers);\n  const defaultMode = (_a3 = options == null ? void 0 : options.defaultMode) != null ? _a3 : \"math\";\n  let parseMode = \"math\";\n  let mathstyle = \"displaystyle\";\n  if (defaultMode === \"inline-math\") mathstyle = \"textstyle\";\n  else if (defaultMode === \"math\") mathstyle = \"displaystyle\";\n  else if (defaultMode === \"text\") {\n    mathstyle = \"textstyle\";\n    parseMode = \"text\";\n  }\n  const effectiveContext = new Context({ from });\n  const root = new Atom({\n    type: \"root\",\n    mode: parseMode,\n    body: parseLatex(text, { context: effectiveContext, parseMode, mathstyle })\n  });\n  const box = root.render(effectiveContext);\n  if (!box) return \"\";\n  coalesce(applyInterBoxSpacing(box, effectiveContext));\n  const struts = makeStruts(box, { classes: \"ML__latex\" });\n  return struts.toMarkup();\n}\nfunction validateLatex2(s) {\n  return validateLatex(s, { context: getDefaultContext() });\n}\nfunction convertLatexToMathMl(latex, options = {}) {\n  return toMathML(\n    parseLatex(latex, {\n      parseMode: \"math\",\n      args: () => \"\",\n      // Prevent #0 arguments to be replaced with placeholder (default behavior)\n      mathstyle: \"displaystyle\"\n    }),\n    options\n  );\n}\nfunction convertLatexToSpeakableText(latex) {\n  const atoms = parseLatex(latex, {\n    parseMode: \"math\",\n    mathstyle: \"displaystyle\"\n  });\n  return atomToSpeakableText(atoms);\n}\nvar gComputeEngine;\nfunction convertMathJsonToLatex(json) {\n  var _a3, _b3;\n  if (!gComputeEngine) {\n    const ComputeEngineCtor = (_a3 = globalThis[Symbol.for(\"io.cortexjs.compute-engine\")]) == null ? void 0 : _a3.ComputeEngine;\n    if (ComputeEngineCtor) gComputeEngine = new ComputeEngineCtor();\n    else {\n      console.error(\n        `MathLive 0.101.0: The CortexJS Compute Engine library is not available.\n        \n        Load the library, for example with:\n        \n        import \"https://unpkg.com/@cortex-js/compute-engine?module\"`\n      );\n    }\n  }\n  return (_b3 = gComputeEngine == null ? void 0 : gComputeEngine.box(json).latex) != null ? _b3 : \"\";\n}\nfunction convertLatexToAsciiMath(latex, parseMode = \"math\") {\n  return atomToAsciiMath(\n    new Atom({ type: \"root\", body: parseLatex(latex, { parseMode }) })\n  );\n}\nfunction convertAsciiMathToLatex(ascii) {\n  return parseMathString(ascii, { format: \"ascii-math\" })[1];\n}\n\n// src/ui/colors/utils.ts\nfunction asRgb(color) {\n  if (typeof color === \"string\") {\n    const parsed = parseHex2(color);\n    if (!parsed) throw new Error(`Invalid color: ${color}`);\n    return parsed;\n  }\n  if (\"C\" in color) return oklchToRgb(color);\n  if (\"a\" in color) return oklabToRgb(color);\n  return color;\n}\nfunction clampByte2(v) {\n  if (v < 0) return 0;\n  if (v > 255) return 255;\n  return Math.round(v);\n}\nfunction parseHex2(hex) {\n  if (!hex) return void 0;\n  if (hex[0] !== \"#\") return void 0;\n  hex = hex.slice(1);\n  let result;\n  if (hex.length <= 4) {\n    result = {\n      r: parseInt(hex[0] + hex[0], 16),\n      g: parseInt(hex[1] + hex[1], 16),\n      b: parseInt(hex[2] + hex[2], 16)\n    };\n    if (hex.length === 4) result.a = parseInt(hex[3] + hex[3], 16) / 255;\n  } else {\n    result = {\n      r: parseInt(hex[0] + hex[1], 16),\n      g: parseInt(hex[2] + hex[3], 16),\n      b: parseInt(hex[4] + hex[5], 16)\n    };\n    if (hex.length === 8) result.a = parseInt(hex[6] + hex[7], 16) / 255;\n  }\n  if (result && typeof result.a === \"undefined\") result.a = 1;\n  return result;\n}\nfunction oklchToOklab(_) {\n  const [L, C, H] = [_.L, _.C, _.H];\n  const hRadians = H * Math.PI / 180;\n  const result = {\n    L,\n    a: C * Math.cos(hRadians),\n    b: C * Math.sin(hRadians)\n  };\n  if (_.alpha !== void 0) result.alpha = _.alpha;\n  return result;\n}\nfunction oklabToOklch(_) {\n  const [L, a, b] = [_.L, _.a, _.b];\n  const C = Math.sqrt(a * a + b * b);\n  const hRadians = Math.atan2(b, a);\n  const H = hRadians * 180 / Math.PI;\n  const result = { L, C, H };\n  if (_.alpha !== void 0) result.alpha = _.alpha;\n  return result;\n}\nfunction oklabToUnclippedRgb(_) {\n  const [l, a, b] = [_.L, _.a, _.b];\n  const L = Math.pow(\n    0.9999999984505198 * l + 0.39633779217376786 * a + 0.2158037580607588 * b,\n    3\n  );\n  const M = Math.pow(\n    1.00000000888176 * l - 0.10556134232365635 * a - 0.0638541747717059 * b,\n    3\n  );\n  const S2 = Math.pow(\n    l * 1.000000054672411 - 0.0894841820949657 * a - 1.2914855378640917 * b,\n    3\n  );\n  const r = 4.076741661347994 * L - 3.307711590408193 * M + 0.230969928729428 * S2;\n  const g = -1.2684380040921763 * L + 2.6097574006633715 * M - 0.3413193963102197 * S2;\n  const bl = -0.004196086541837188 * L - 0.7034186144594493 * M + 1.7076147009309444 * S2;\n  const conv = (n) => {\n    const abs = Math.abs(n);\n    if (abs <= 31308e-7) return n * 12.92;\n    return (Math.sign(n) || 1) * (1.055 * Math.pow(abs, 1 / 2.4) - 0.055);\n  };\n  return [conv(r), conv(g), conv(bl)];\n}\nfunction inGamut(rgb) {\n  const [r, g, b] = rgb;\n  return r >= 0 && r <= 1 && g >= 0 && g <= 1 && b >= 0 && b <= 1;\n}\nfunction clampRgb(rgb, alpha) {\n  let [r, g, b] = rgb;\n  r = clampByte2(r * 255);\n  g = clampByte2(g * 255);\n  b = clampByte2(b * 255);\n  return alpha !== void 0 ? { r, g, b, alpha } : { r, g, b };\n}\nfunction oklabToRgb(color) {\n  let [r, g, b] = oklabToUnclippedRgb(color);\n  if (inGamut([r, g, b])) return clampRgb([r, g, b], color.alpha);\n  const oklch = oklabToOklch(color);\n  oklch.C = 0;\n  [r, g, b] = oklabToUnclippedRgb(oklchToOklab(oklch));\n  if (!inGamut([r, g, b])) return clampRgb([r, g, b], color.alpha);\n  let low = 0;\n  let high = color.L;\n  let mid = (low + high) / 2;\n  oklch.C = mid;\n  const resolution = 0.36 / Math.pow(2, 12);\n  while (high - low > resolution) {\n    mid = (low + high) / 2;\n    oklch.C = mid;\n    [r, g, b] = oklabToUnclippedRgb(oklchToOklab(oklch));\n    if (inGamut([r, g, b])) low = mid;\n    else high = mid;\n  }\n  return clampRgb([r, g, b], color.alpha);\n}\nfunction oklchToRgb(_) {\n  return oklabToRgb(oklchToOklab(_));\n}\n\n// src/ui/colors/contrast.ts\nfunction apca(bgColor, fgColor) {\n  const bgRgb = asRgb(bgColor);\n  const fgRgb = asRgb(fgColor);\n  const normBG = 0.56;\n  const normTXT = 0.57;\n  const revTXT = 0.62;\n  const revBG = 0.65;\n  const blkThrs = 0.022;\n  const blkClmp = 1.414;\n  const loClip = 0.1;\n  const deltaYmin = 5e-4;\n  const scaleBoW = 1.14;\n  const loBoWoffset = 0.027;\n  const scaleWoB = 1.14;\n  const loWoBoffset = 0.027;\n  function fclamp(Y) {\n    return Y >= blkThrs ? Y : Y + (blkThrs - Y) ** blkClmp;\n  }\n  function linearize(val) {\n    const sign = val < 0 ? -1 : 1;\n    return sign * Math.pow(Math.abs(val), 2.4);\n  }\n  const Yfg = fclamp(\n    linearize(fgRgb.r / 255) * 0.2126729 + linearize(fgRgb.g / 255) * 0.7151522 + linearize(fgRgb.b / 255) * 0.072175\n  );\n  const Ybg = fclamp(\n    linearize(bgRgb.r / 255) * 0.2126729 + linearize(bgRgb.g / 255) * 0.7151522 + linearize(bgRgb.b / 255) * 0.072175\n  );\n  let S2, C, Sapc;\n  if (Math.abs(Ybg - Yfg) < deltaYmin) C = 0;\n  else {\n    if (Ybg > Yfg) {\n      S2 = Ybg ** normBG - Yfg ** normTXT;\n      C = S2 * scaleBoW;\n    } else {\n      S2 = Ybg ** revBG - Yfg ** revTXT;\n      C = S2 * scaleWoB;\n    }\n  }\n  if (Math.abs(C) < loClip) Sapc = 0;\n  else if (C > 0) Sapc = C - loWoBoffset;\n  else Sapc = C + loBoWoffset;\n  return Sapc * 100;\n}\nfunction contrast(bgColor, dark, light) {\n  light != null ? light : light = \"#fff\";\n  dark != null ? dark : dark = \"#000\";\n  const lightContrast = apca(bgColor, light);\n  const darkContrast = apca(bgColor, dark);\n  return Math.abs(lightContrast) > Math.abs(darkContrast) ? light : dark;\n}\n\n// src/ui/colors/css.ts\nfunction asHexColor(_) {\n  const rgb = asRgb(_);\n  let hexString = ((1 << 24) + (clampByte2(rgb.r) << 16) + (clampByte2(rgb.g) << 8) + clampByte2(rgb.b)).toString(16).slice(1);\n  if (rgb.alpha !== void 0 && rgb.alpha < 1)\n    hexString += (\"00\" + Math.round(rgb.alpha * 255).toString(16)).slice(-2);\n  if (hexString[0] === hexString[1] && hexString[2] === hexString[3] && hexString[4] === hexString[5] && hexString[6] === hexString[7]) {\n    hexString = hexString[0] + hexString[2] + hexString[4] + (rgb.alpha !== void 0 && rgb.alpha < 1 ? hexString[6] : \"\");\n  }\n  return \"#\" + hexString;\n}\n\n// src/editor/default-menu.ts\nfunction getSelectionPlainString(mf) {\n  const atoms = getSelectionAtoms(mf);\n  let result = \"\";\n  for (const atom of atoms) {\n    if (typeof atom.value !== \"string\") return \"\";\n    result += atom.value;\n  }\n  return result;\n}\nfunction getSelectionAtoms(mf) {\n  const model = mf.model;\n  const ranges = model.selection.ranges;\n  if (ranges.length !== 1) return [];\n  let atoms = mf.model.getAtoms(ranges[0]);\n  if (atoms.length === 1 && atoms[0].type === \"root\") atoms = atoms[0].children;\n  return atoms.filter((x) => x.type !== \"first\");\n}\nfunction validVariantAtom(mf, variant) {\n  const atoms = getSelectionAtoms(mf);\n  if (atoms.length !== 1) return false;\n  const repertoire = VARIANT_REPERTOIRE[variant];\n  if (!repertoire) return false;\n  if (repertoire.test(atoms[0].value)) return true;\n  return false;\n}\nfunction validVariantStyleSelection(mf) {\n  return getSelectionPlainString(mf).length > 0;\n}\nfunction getVariantSubmenu(mf) {\n  return [\n    variantMenuItem(mf, \"double-struck\", \"mathbb\", \"tooltip.blackboard\"),\n    variantMenuItem(mf, \"fraktur\", \"mathfrak\", \"tooltip.fraktur\"),\n    variantMenuItem(mf, \"calligraphic\", \"mathcal\", \"tooltip.caligraphic\"),\n    variantStyleMenuItem(mf, \"up\", \"mathrm\", \"tooltip.roman-upright\"),\n    variantStyleMenuItem(mf, \"bold\", \"bm\", \"tooltip.bold\"),\n    variantStyleMenuItem(mf, \"italic\", \"mathit\", \"tooltip.italic\")\n  ];\n}\nfunction getAccentSubmenu(mf) {\n  return [\n    {\n      id: \"accent-vec\",\n      class: \"ML__center-menu\",\n      label: () => convertLatexToMarkup(`\\\\vec{${getSelectionPlainString(mf)}}`),\n      visible: () => getSelectionPlainString(mf).length === 1,\n      onMenuSelect: () => mf.insert(\"\\\\vec{#@}\", { selectionMode: \"item\" })\n    },\n    {\n      id: \"accent-overrightarrow\",\n      class: \"ML__center-menu\",\n      label: () => convertLatexToMarkup(\n        `\\\\overrightarrow{${getSelectionPlainString(mf)}}`\n      ),\n      visible: () => getSelectionPlainString(mf).length > 0,\n      onMenuSelect: () => mf.insert(\"\\\\overrightarrow{#@}\", { selectionMode: \"item\" })\n    },\n    {\n      id: \"accent-overleftarrow\",\n      class: \"ML__center-menu\",\n      label: () => convertLatexToMarkup(`\\\\overleftarrow{${getSelectionPlainString(mf)}}`),\n      visible: () => getSelectionPlainString(mf).length > 0,\n      onMenuSelect: () => mf.insert(\"\\\\overleftarrow{#@}\", { selectionMode: \"item\" })\n    },\n    {\n      id: \"accent-dot\",\n      class: \"ML__center-menu\",\n      label: () => convertLatexToMarkup(`\\\\dot{${getSelectionPlainString(mf)}}`),\n      visible: () => getSelectionPlainString(mf).length === 1,\n      onMenuSelect: () => mf.insert(\"\\\\dot{#@}\", { selectionMode: \"item\" })\n    },\n    {\n      id: \"accent-ddot\",\n      class: \"ML__center-menu\",\n      label: () => convertLatexToMarkup(`\\\\ddot{${getSelectionPlainString(mf)}}`),\n      visible: () => getSelectionPlainString(mf).length === 1,\n      onMenuSelect: () => mf.insert(\"\\\\ddot{#@}\", { selectionMode: \"item\" })\n    },\n    {\n      id: \"accent-bar\",\n      class: \"ML__center-menu\",\n      label: () => convertLatexToMarkup(`\\\\bar{${getSelectionPlainString(mf)}}`),\n      visible: () => getSelectionPlainString(mf).length === 1,\n      onMenuSelect: () => mf.insert(\"\\\\bar{#@}\", { selectionMode: \"item\" })\n    },\n    {\n      id: \"accent-overline\",\n      class: \"ML__center-menu\",\n      label: () => convertLatexToMarkup(`\\\\overline{${getSelectionPlainString(mf)}}`),\n      visible: () => getSelectionPlainString(mf).length > 0,\n      onMenuSelect: () => mf.insert(\"\\\\overline{#@}\", { selectionMode: \"item\" })\n    },\n    {\n      id: \"accent-overgroup\",\n      class: \"ML__center-menu\",\n      label: () => convertLatexToMarkup(`\\\\overgroup{${getSelectionPlainString(mf)}}`),\n      visible: () => getSelectionPlainString(mf).length > 0,\n      onMenuSelect: () => mf.insert(\"\\\\overgroup{#@}\", { selectionMode: \"item\" })\n    },\n    {\n      id: \"accent-overbrace\",\n      class: \"ML__center-menu\",\n      label: () => convertLatexToMarkup(`\\\\overbrace{${getSelectionPlainString(mf)}}`),\n      visible: () => getSelectionPlainString(mf).length > 0,\n      onMenuSelect: () => mf.insert(\"\\\\overbrace{#@}\", { selectionMode: \"item\" })\n    },\n    {\n      id: \"accent-underline\",\n      class: \"ML__center-menu\",\n      label: () => convertLatexToMarkup(`\\\\underline{${getSelectionPlainString(mf)}}`),\n      visible: () => getSelectionPlainString(mf).length > 0,\n      onMenuSelect: () => mf.insert(\"\\\\underline{#@}\", { selectionMode: \"item\" })\n    },\n    {\n      id: \"accent-undergroup\",\n      class: \"ML__center-menu\",\n      label: () => convertLatexToMarkup(`\\\\undergroup{${getSelectionPlainString(mf)}}`),\n      visible: () => getSelectionPlainString(mf).length > 0,\n      onMenuSelect: () => mf.insert(\"\\\\undergroup{#@}\", { selectionMode: \"item\" })\n    },\n    {\n      id: \"accent-underbrace\",\n      class: \"ML__center-menu\",\n      label: () => convertLatexToMarkup(`\\\\underbrace{${getSelectionPlainString(mf)}}`),\n      visible: () => getSelectionPlainString(mf).length > 0,\n      onMenuSelect: () => mf.insert(\"\\\\underbrace{#@}\", { selectionMode: \"item\" })\n    }\n  ];\n}\nfunction getDecorationSubmenu(mf) {\n  return [\n    // {\n    //   label: () => convertLatexToMarkup(`\\\\cancel{${getSelection(mf)}}`),\n    //   // visible: () => getSelection(mf).length > 0,\n    //   onMenuSelect: () => mf.insert('\\\\cancel{#@}', { selectionMode: 'item' }),\n    // },\n    {\n      id: \"decoration-boxed\",\n      label: () => convertLatexToMarkup(`\\\\boxed{${mf.getValue(mf.model.selection)}}}`),\n      // visible: () => getSelection(mf).length > 0,\n      onMenuSelect: () => mf.insert(\"\\\\boxed{#@}\", { selectionMode: \"item\" })\n    },\n    {\n      id: \"decoration-red-box\",\n      label: () => convertLatexToMarkup(\n        `\\\\bbox[5px, border: 2px solid red]{${mf.getValue(\n          mf.model.selection\n        )}}`\n      ),\n      // visible: () => getSelection(mf).length > 0,\n      onMenuSelect: () => mf.insert(\"\\\\bbox[5px, border: 2px solid red]{#@}\", {\n        selectionMode: \"item\"\n      })\n    },\n    {\n      id: \"decoration-dashed-black-box\",\n      label: () => convertLatexToMarkup(\n        `\\\\bbox[5px, border: 2px dashed black]{${mf.getValue(\n          mf.model.selection\n        )}}`\n      ),\n      // visible: () => getSelection(mf).length > 0,\n      onMenuSelect: () => mf.insert(\"\\\\bbox[5px, border: 2px dashed black]{#@}\", {\n        selectionMode: \"item\"\n      })\n    }\n  ];\n}\nfunction getBackgroundColorSubmenu(mf) {\n  const result = [];\n  for (const color of Object.keys(BACKGROUND_COLORS)) {\n    result.push({\n      id: `background-color-${color}`,\n      class: (asHexColor(contrast(BACKGROUND_COLORS[color])) === \"#000\" ? \"dark-contrast\" : \"light-contrast\") + \" menu-swatch\",\n      label: `<span style=\"background:${BACKGROUND_COLORS[color]} \"></span>`,\n      ariaLabel: () => {\n        var _a3;\n        return (_a3 = localize(color)) != null ? _a3 : color;\n      },\n      checked: () => {\n        var _a3;\n        return (_a3 = { some: \"mixed\", all: true }[mf.queryStyle({ backgroundColor: color })]) != null ? _a3 : false;\n      },\n      onMenuSelect: () => mf.applyStyle({ backgroundColor: color }, { operation: \"toggle\" })\n    });\n  }\n  return result;\n}\nfunction getColorSubmenu(mf) {\n  const result = [];\n  for (const color of Object.keys(FOREGROUND_COLORS)) {\n    result.push({\n      id: `color-${color}`,\n      class: (contrast(FOREGROUND_COLORS[color]) === \"#000\" ? \"dark-contrast\" : \"light-contrast\") + \" menu-swatch\",\n      label: `<span style=\"background:${FOREGROUND_COLORS[color]} \"></span>`,\n      ariaLabel: () => {\n        var _a3;\n        return (_a3 = localize(color)) != null ? _a3 : color;\n      },\n      checked: () => {\n        var _a3;\n        return (_a3 = { some: \"mixed\", all: true }[mf.queryStyle({ color })]) != null ? _a3 : false;\n      },\n      onMenuSelect: () => mf.applyStyle({ color }, { operation: \"toggle\" })\n    });\n  }\n  return result;\n}\nvar InsertMatrixMenuItem = class extends _MenuItemState {\n  constructor(decl, parent, row, col) {\n    super(decl, parent);\n    this.row = row;\n    this.col = col;\n  }\n  set active(value) {\n    const cells = this.parentMenu.children;\n    if (value) {\n      for (const cell of cells) {\n        cell.element.classList.toggle(\n          \"active\",\n          cell.row <= this.row && cell.col <= this.col\n        );\n      }\n    } else for (const cell of cells) cell.element.classList.remove(\"active\");\n  }\n};\nfunction getInsertMatrixSubmenu(mf) {\n  const result = [];\n  for (let row = 1; row <= 5; row++) {\n    for (let col = 1; col <= 5; col++) {\n      result.push({\n        id: `insert-matrix-${row}x${col}`,\n        onCreate: (decl, parent) => new InsertMatrixMenuItem(decl, parent, row, col),\n        label: `\\u2610`,\n        tooltip: () => localize(\"tooltip.row-by-col\", row, col),\n        data: { row, col },\n        onMenuSelect: () => {\n          mf.insert(\n            `\\\\begin{pmatrix}${Array(row).fill(Array(col).fill(\"#?\").join(\" & \")).join(\"\\\\\\\\\")}\\\\end{pmatrix}`,\n            {\n              selectionMode: \"item\"\n            }\n          );\n        }\n      });\n    }\n  }\n  return result;\n}\nfunction getDefaultMenuItems(mf) {\n  return [\n    // {\n    //   label: 'Show Virtual Keyboard',\n    //   onMenuSelect: () => window.mathVirtualKeyboard.show({ animate: true }),\n    //   visible: () => window.mathVirtualKeyboard.visible === false,\n    // },\n    // {\n    //   label: 'Hide Virtual Keyboard',\n    //   onMenuSelect: () => window.mathVirtualKeyboard.hide({ animate: true }),\n    //   visible: () => window.mathVirtualKeyboard.visible === true,\n    // },\n    {\n      label: () => localize(\"menu.array.add row above\"),\n      id: \"add-row-above\",\n      onMenuSelect: () => mf.executeCommand(\"addRowBefore\"),\n      keyboardShortcut: \"shift+alt+[Return]\",\n      visible: () => inMatrix(mf)\n    },\n    {\n      label: () => localize(\"menu.array.add row below\"),\n      id: \"add-row-below\",\n      onMenuSelect: () => mf.executeCommand(\"addRowAfter\"),\n      keyboardShortcut: \"alt+[Return]\",\n      visible: () => inMatrix(mf)\n    },\n    {\n      label: () => localize(\"menu.array.add column before\"),\n      id: \"add-column-before\",\n      onMenuSelect: () => mf.executeCommand(\"addColumnBefore\"),\n      visible: () => inMatrix(mf),\n      keyboardShortcut: \"shift+alt+[Tab]\",\n      enabled: () => {\n        const array = mf.model.parentEnvironment;\n        if (!array) return false;\n        const [rows, _cols] = shape(mf);\n        return rows < array.maxColumns;\n      }\n    },\n    {\n      label: () => localize(\"menu.array.add column after\"),\n      id: \"add-column-after\",\n      onMenuSelect: () => mf.executeCommand(\"addColumnAfter\"),\n      keyboardShortcut: \"alt+[Tab]\",\n      visible: () => inMatrix(mf)\n    },\n    {\n      type: \"divider\"\n    },\n    {\n      label: () => localize(\"menu.array.delete row\"),\n      id: \"delete-row\",\n      onMenuSelect: () => mf.executeCommand(\"removeRow\"),\n      visible: () => inMatrix(mf)\n    },\n    {\n      label: () => localize(\"menu.array.delete column\"),\n      id: \"delete-column\",\n      onMenuSelect: () => mf.executeCommand(\"removeColumn\"),\n      visible: () => inMatrix(mf)\n    },\n    {\n      type: \"divider\"\n    },\n    {\n      label: () => localize(\"menu.borders\"),\n      visible: () => (isMatrixSelected(mf) || inMatrix(mf)) && mf.isSelectionEditable,\n      submenu: [\n        {\n          label: \" \\u22F1 \",\n          id: \"environment-no-border\",\n          onMenuSelect: () => performSetEnvironment(mf, \"matrix\")\n        },\n        {\n          label: \"(\\u22F1)\",\n          id: \"environment-parentheses\",\n          onMenuSelect: () => performSetEnvironment(mf, \"pmatrix\")\n        },\n        {\n          label: \"[\\u22F1]\",\n          id: \"environment-brackets\",\n          onMenuSelect: () => performSetEnvironment(mf, \"bmatrix\")\n        },\n        {\n          label: \"|\\u22F1|\",\n          id: \"environment-bar\",\n          onMenuSelect: () => performSetEnvironment(mf, \"vmatrix\")\n        },\n        {\n          label: \"{\\u22F1}\",\n          id: \"environment-braces\",\n          onMenuSelect: () => performSetEnvironment(mf, \"Bmatrix\")\n        }\n      ],\n      submenuClass: \"border-submenu\"\n    },\n    {\n      type: \"divider\"\n    },\n    {\n      label: () => localize(\"menu.insert matrix\"),\n      id: \"insert-matrix\",\n      visible: () => mf.isSelectionEditable,\n      submenu: getInsertMatrixSubmenu(mf),\n      submenuClass: \"insert-matrix-submenu\",\n      columnCount: 5\n    },\n    {\n      type: \"divider\"\n    },\n    {\n      label: () => localize(\"menu.insert\"),\n      id: \"insert\",\n      submenu: insertMenu(mf)\n    },\n    {\n      type: \"divider\"\n    },\n    {\n      label: () => localize(\"menu.mode\"),\n      id: \"mode\",\n      visible: () => mf.isSelectionEditable && mf.model.selectionIsCollapsed,\n      submenu: [\n        {\n          label: () => localize(\"menu.mode-math\"),\n          id: \"mode-math\",\n          onMenuSelect: () => {\n            complete(mf, \"accept-all\");\n            mf.executeCommand([\"switchMode\", \"math\"]);\n          },\n          checked: () => mf.model.mode === \"math\"\n        },\n        {\n          label: () => localize(\"menu.mode-text\"),\n          id: \"mode-text\",\n          onMenuSelect: () => {\n            complete(mf, \"accept-all\");\n            mf.executeCommand([\"switchMode\", \"text\"]);\n          },\n          checked: () => mf.model.mode === \"text\"\n        },\n        {\n          label: () => localize(\"menu.mode-latex\"),\n          id: \"mode-latex\",\n          onMenuSelect: () => mf.executeCommand([\"switchMode\", \"latex\"]),\n          checked: () => mf.model.mode === \"latex\"\n        }\n      ]\n    },\n    {\n      type: \"divider\"\n    },\n    {\n      label: () => localize(\"menu.font-style\"),\n      id: \"variant\",\n      visible: () => mf.isSelectionEditable,\n      submenu: getVariantSubmenu(mf),\n      submenuClass: \"variant-submenu\"\n    },\n    {\n      label: () => localize(\"menu.color\"),\n      id: \"color\",\n      visible: () => mf.isSelectionEditable,\n      submenu: getColorSubmenu(mf),\n      columnCount: 4,\n      submenuClass: \"swatches-submenu\"\n    },\n    {\n      label: () => localize(\"menu.background-color\"),\n      id: \"background-color\",\n      visible: () => mf.isSelectionEditable,\n      submenu: getBackgroundColorSubmenu(mf),\n      columnCount: 4,\n      submenuClass: \"swatches-submenu\"\n    },\n    {\n      label: () => localize(\"menu.accent\"),\n      id: \"accent\",\n      visible: () => mf.isSelectionEditable,\n      submenu: getAccentSubmenu(mf),\n      submenuClass: \"variant-submenu\"\n    },\n    {\n      label: () => localize(\"menu.decoration\"),\n      id: \"decoration\",\n      visible: () => mf.isSelectionEditable && getSelectionPlainString(mf).length > 0,\n      submenu: getDecorationSubmenu(mf),\n      submenuClass: \"variant-submenu\"\n    },\n    {\n      type: \"divider\"\n    },\n    {\n      label: () => localize(\"menu.evaluate\"),\n      id: \"ce-evaluate\",\n      visible: () => mf.isSelectionEditable && globalThis.MathfieldElement.computeEngine !== null,\n      onMenuSelect: () => {\n        const latex = evaluate(mf);\n        if (!latex) {\n          mf.model.announce(\"plonk\");\n          return;\n        }\n        if (mf.model.selectionIsCollapsed) {\n          mf.model.position = mf.model.lastOffset;\n          mf.insert(`=${latex}`, {\n            insertionMode: \"insertAfter\",\n            selectionMode: \"item\"\n          });\n        } else {\n          mf.insert(latex, {\n            insertionMode: \"replaceSelection\",\n            selectionMode: \"item\"\n          });\n        }\n      }\n    },\n    {\n      label: () => localize(\"menu.simplify\"),\n      id: \"ce-simplify\",\n      visible: () => mf.isSelectionEditable && globalThis.MathfieldElement.computeEngine !== null,\n      onMenuSelect: () => {\n        var _a3, _b3;\n        if (mf.model.selectionIsCollapsed) {\n          const result = (_a3 = mf.expression) == null ? void 0 : _a3.simplify();\n          mf.model.position = mf.model.lastOffset;\n          if (!result) {\n            mf.model.announce(\"plonk\");\n            return;\n          }\n          mf.insert(`=${result.latex}`, {\n            insertionMode: \"insertAfter\",\n            selectionMode: \"item\"\n          });\n        } else {\n          const result = (_b3 = globalThis.MathfieldElement.computeEngine) == null ? void 0 : _b3.parse(mf.getValue(mf.model.selection)).simplify();\n          if (!result) {\n            mf.model.announce(\"plonk\");\n            return;\n          }\n          mf.insert(result.latex, {\n            insertionMode: \"replaceSelection\",\n            selectionMode: \"item\"\n          });\n        }\n      }\n    },\n    {\n      label: () => {\n        var _a3;\n        const ce = globalThis.MathfieldElement.computeEngine;\n        if (ce === null) return \"\";\n        const unknown = (_a3 = mf.expression) == null ? void 0 : _a3.unknowns[0];\n        if (unknown) {\n          const latex = ce.box(unknown).latex;\n          return localize(\"menu.solve-for\", convertLatexToMarkup(latex));\n        }\n        return localize(\"menu.solve\");\n      },\n      id: \"ce-solve\",\n      visible: () => {\n        var _a3;\n        return mf.isSelectionEditable && globalThis.MathfieldElement.computeEngine !== null && ((_a3 = mf.expression) == null ? void 0 : _a3.unknowns.length) === 1 && mf.expression.unknowns[0] !== \"Nothing\";\n      },\n      onMenuSelect: () => {\n        var _a3;\n        const expr = mf.expression;\n        const unknown = expr == null ? void 0 : expr.unknowns[0];\n        const results = (_a3 = expr.solve(unknown)) == null ? void 0 : _a3.map((x) => {\n          var _a4;\n          return (_a4 = x.simplify().latex) != null ? _a4 : \"\";\n        });\n        if (!results) {\n          mf.model.announce(\"plonk\");\n          return;\n        }\n        mf.insert(\n          `${unknown}=${results.length === 1 ? results[0] : \"\\\\left\\\\lbrace\" + (results == null ? void 0 : results.join(\", \")) + \"\\\\right\\\\rbrace\"}`,\n          {\n            insertionMode: \"replaceAll\",\n            selectionMode: \"item\"\n          }\n        );\n      }\n    },\n    {\n      type: \"divider\"\n    },\n    {\n      label: () => localize(\"menu.cut\"),\n      id: \"cut\",\n      onMenuSelect: () => mf.executeCommand(\"cutToClipboard\"),\n      visible: () => !mf.options.readOnly && mf.isSelectionEditable,\n      keyboardShortcut: \"meta+X\"\n    },\n    // {\n    //   label: 'Copy',\n    //   onMenuSelect: () => mf.executeCommand('copyToClipboard'),\n    // },\n    {\n      label: () => localize(\"menu.copy\"),\n      id: \"copy\",\n      submenu: [\n        {\n          label: () => localize(\"menu.copy-as-latex\"),\n          id: \"copy-latex\",\n          onMenuSelect: () => ModeEditor.copyToClipboard(mf, \"latex\"),\n          keyboardShortcut: \"meta+C\"\n        },\n        {\n          label: () => localize(\"menu.copy-as-ascii-math\"),\n          id: \"copy-ascii-math\",\n          onMenuSelect: () => ModeEditor.copyToClipboard(mf, \"ascii-math\")\n        },\n        {\n          label: () => localize(\"menu.copy-as-mathml\"),\n          id: \"copy-math-ml\",\n          onMenuSelect: () => ModeEditor.copyToClipboard(mf, \"math-ml\")\n        }\n      ]\n    },\n    {\n      label: () => localize(\"menu.paste\"),\n      id: \"paste\",\n      onMenuSelect: () => mf.executeCommand(\"pasteFromClipboard\"),\n      visible: () => mf.hasEditableContent,\n      keyboardShortcut: \"meta+V\"\n    },\n    {\n      label: () => localize(\"menu.select-all\"),\n      id: \"select-all\",\n      keyboardShortcut: \"meta+A\",\n      onMenuSelect: () => mf.executeCommand(\"selectAll\")\n    }\n  ];\n}\nfunction inMatrix(mf) {\n  var _a3;\n  return !!((_a3 = mf.model.parentEnvironment) == null ? void 0 : _a3.array);\n}\nfunction isMatrixSelected(mf) {\n  return mf.model.at(mf.model.position).type === \"array\";\n}\nfunction shape(mf) {\n  var _a3;\n  const array = (_a3 = mf.model.parentEnvironment) == null ? void 0 : _a3.array;\n  if (!array) return [0, 0];\n  return [\n    array.length,\n    array.reduce((acc, col) => Math.max(acc, col.length), 0)\n  ];\n}\nfunction performSetEnvironment(mf, env) {\n  removeSuggestion(mf);\n  mf.flushInlineShortcutBuffer();\n  setEnvironment(mf.model, env);\n  requestUpdate(mf);\n}\nfunction evaluate(mf) {\n  var _a3, _b3;\n  let expr;\n  if (mf.model.selectionIsCollapsed) {\n    expr = (_a3 = globalThis.MathfieldElement.computeEngine) == null ? void 0 : _a3.parse(mf.getValue(), {\n      canonical: false\n    });\n  } else {\n    expr = (_b3 = globalThis.MathfieldElement.computeEngine) == null ? void 0 : _b3.parse(\n      mf.getValue(mf.model.selection),\n      { canonical: false }\n    );\n  }\n  if (!expr) return \"\";\n  let result = expr.evaluate();\n  if (result.isSame(expr)) result = expr.N();\n  return result.latex;\n}\nfunction variantMenuItem(mf, variant, command, tooltip) {\n  return {\n    id: `variant-${variant}`,\n    label: () => {\n      var _a3;\n      const textSelection = getSelectionPlainString(mf);\n      if (textSelection.length < 12)\n        return convertLatexToMarkup(\n          `\\\\${command}{${getSelectionPlainString(mf)}}`\n        );\n      return (_a3 = localize(tooltip)) != null ? _a3 : tooltip;\n    },\n    class: \"ML__xl\",\n    tooltip: () => {\n      var _a3;\n      return (_a3 = localize(tooltip)) != null ? _a3 : tooltip;\n    },\n    visible: () => validVariantAtom(mf, variant),\n    checked: () => {\n      var _a3;\n      return (_a3 = { some: \"mixed\", all: true }[mf.queryStyle({ variant })]) != null ? _a3 : false;\n    },\n    onMenuSelect: () => mf.applyStyle({ variant }, { operation: \"toggle\" })\n  };\n}\nfunction variantStyleMenuItem(mf, variantStyle, command, tooltip) {\n  return {\n    id: `variant-style-${variantStyle}`,\n    label: () => {\n      var _a3;\n      const textSelection = getSelectionPlainString(mf);\n      if (textSelection.length > 0 && textSelection.length < 12)\n        return convertLatexToMarkup(\n          `\\\\${command}{${getSelectionPlainString(mf)}}`\n        );\n      return (_a3 = localize(tooltip)) != null ? _a3 : tooltip;\n    },\n    class: () => {\n      const textSelection = getSelectionPlainString(mf);\n      if (textSelection.length > 0 && textSelection.length < 12)\n        return \"ML__xl\";\n      return \"\";\n    },\n    tooltip: () => {\n      var _a3;\n      return (_a3 = localize(tooltip)) != null ? _a3 : tooltip;\n    },\n    visible: variantStyle === \"bold\" ? true : () => validVariantStyleSelection(mf),\n    checked: () => {\n      var _a3;\n      return (_a3 = { some: \"mixed\", all: true }[mf.queryStyle({ variantStyle })]) != null ? _a3 : false;\n    },\n    onMenuSelect: () => mf.applyStyle({ variantStyle }, { operation: \"toggle\" })\n  };\n}\nfunction insertMenu(mf) {\n  return [\n    {\n      label: () => insertLabel(\"abs\"),\n      id: \"insert-abs\",\n      visible: () => mf.isSelectionEditable,\n      onMenuSelect: () => mf.insert(\"|#?|\")\n    },\n    {\n      label: () => insertLabel(\"nth-root\"),\n      id: \"insert-nth-root\",\n      visible: () => mf.isSelectionEditable,\n      onMenuSelect: () => mf.insert(\"\\\\sqrt[#?]{#?}\")\n    },\n    {\n      label: () => insertLabel(\"log-base\"),\n      id: \"insert-log-base\",\n      visible: () => mf.isSelectionEditable,\n      onMenuSelect: () => mf.insert(\"\\\\log_{#?}{#?}\")\n    },\n    {\n      type: \"heading\",\n      label: () => localize(\"menu.insert.heading-calculus\")\n    },\n    {\n      label: () => insertLabel(\"derivative\"),\n      id: \"insert-derivative\",\n      visible: () => mf.isSelectionEditable,\n      onMenuSelect: () => mf.insert(\"\\\\dfrac{\\\\mathrm{d}}{\\\\mathrm{d}x}#?\\\\bigm|_{x=#?}\")\n    },\n    {\n      label: () => insertLabel(\"nth-derivative\"),\n      id: \"insert-nth-derivative\",\n      visible: () => mf.isSelectionEditable,\n      onMenuSelect: () => mf.insert(\"\\\\dfrac{\\\\mathrm{d}^#?}{\\\\mathrm{d}x^#?}#?\\\\bigm|_{x=#?}\")\n    },\n    {\n      label: () => insertLabel(\"integral\"),\n      id: \"insert-integral\",\n      visible: () => mf.isSelectionEditable,\n      onMenuSelect: () => mf.insert(\"\\\\int_#?^#?#?\\\\,\\\\mathrm{d}#?\")\n    },\n    {\n      label: () => insertLabel(\"sum\"),\n      id: \"insert-sum\",\n      visible: () => mf.isSelectionEditable,\n      onMenuSelect: () => mf.insert(\"\\\\sum_#?^#?#?\")\n    },\n    {\n      label: () => insertLabel(\"product\"),\n      id: \"insert-product\",\n      visible: () => mf.isSelectionEditable,\n      onMenuSelect: () => mf.insert(\"\\\\prod_#?^#?#?\")\n    },\n    {\n      type: \"heading\",\n      label: () => localize(\"menu.insert.heading-complex-numbers\")\n    },\n    {\n      label: () => insertLabel(\"modulus\"),\n      id: \"insert-modulus\",\n      visible: () => mf.isSelectionEditable,\n      onMenuSelect: () => mf.insert(\"\\\\lvert#?\\\\rvert\")\n    },\n    {\n      label: () => insertLabel(\"argument\"),\n      id: \"insert-argument\",\n      visible: () => mf.isSelectionEditable,\n      onMenuSelect: () => mf.insert(\"\\\\arg(#?)\")\n    },\n    {\n      label: () => insertLabel(\"real-part\"),\n      id: \"insert-real-part\",\n      visible: () => mf.isSelectionEditable,\n      onMenuSelect: () => mf.insert(\"\\\\Re(#?)\")\n    },\n    {\n      label: () => insertLabel(\"imaginary-part\"),\n      id: \"insert-imaginary-part\",\n      visible: () => mf.isSelectionEditable,\n      onMenuSelect: () => mf.insert(\"\\\\Im(#?)\")\n    },\n    {\n      label: () => insertLabel(\"conjugate\"),\n      id: \"insert-conjugate\",\n      visible: () => mf.isSelectionEditable,\n      onMenuSelect: () => mf.insert(\"\\\\overline{#?}\")\n    }\n  ];\n}\nfunction insertLabel(id) {\n  return `<span class='ML__insert-template'> ${convertLatexToMarkup(localize(`menu.insert.${id}-template`))}</span><span class=\"ML__insert-label\">${localize(`menu.insert.${id}`)}</span>`;\n}\n\n// src/editor/a11y.ts\nfunction speakableText(arg1, arg2) {\n  if (typeof arg1 === \"string\") return arg1 + atomToSpeakableText(arg2);\n  return atomToSpeakableText(arg1);\n}\nfunction relationName(atom) {\n  var _a3;\n  let result = void 0;\n  if (atom.parent.type === \"prompt\") {\n    if (atom.parentBranch === \"body\") result = \"prompt\";\n  } else if (atom.parentBranch === \"body\") {\n    if (atom.type === \"first\") {\n      if (atom.parent.type === \"root\") result = \"mathfield\";\n      else if (atom.parent.type === \"surd\") result = \"radicand\";\n      else if (atom.parent.type === \"genfrac\") result = \"fraction\";\n      else if (atom.parent.type === \"sizeddelim\") result = \"delimiter\";\n      if (result) return result;\n    }\n    if (atom.type === \"subsup\") {\n      if (atom.superscript && atom.subscript)\n        result = \"superscript and subscript\";\n      else if (atom.superscript) result = \"superscript\";\n      else if (atom.subscript) result = \"subscript\";\n    } else if (atom.type) {\n      result = (_a3 = {\n        \"accent\": \"accented\",\n        \"array\": \"array\",\n        \"box\": \"box\",\n        \"chem\": \"chemical formula\",\n        \"delim\": \"delimiter\",\n        \"enclose\": \"cross out\",\n        \"extensible-symbol\": \"extensible symbol\",\n        \"error\": \"error\",\n        \"first\": \"first\",\n        \"genfrac\": \"fraction\",\n        \"group\": \"group\",\n        \"latex\": \"LaTeX\",\n        \"leftright\": \"delimiter\",\n        \"line\": \"line\",\n        \"subsup\": \"subscript-superscript\",\n        \"operator\": \"operator\",\n        \"overunder\": \"over-under\",\n        \"placeholder\": \"placeholder\",\n        \"rule\": \"rule\",\n        \"sizeddelim\": \"delimiter\",\n        \"space\": \"space\",\n        \"spacing\": \"spacing\",\n        \"surd\": \"square root\",\n        \"text\": \"text\",\n        \"prompt\": \"prompt\",\n        \"root\": \"math field\",\n        \"mop\": \"operator\"\n        // E.g. `\\operatorname`, a `mop` with a body\n      }[atom.type]) != null ? _a3 : \"parent\";\n    }\n  } else if (atom.parent.type === \"genfrac\") {\n    if (atom.parentBranch === \"above\") return \"numerator\";\n    if (atom.parentBranch === \"below\") return \"denominator\";\n  } else if (atom.parent.type === \"surd\") {\n    if (atom.parentBranch === \"above\") result = \"index\";\n  } else if (atom.parentBranch === \"superscript\") result = \"superscript\";\n  else if (atom.parentBranch === \"subscript\") result = \"subscript\";\n  if (!result) console.log(\"unknown relationship\");\n  return result != null ? result : \"parent\";\n}\nfunction defaultAnnounceHook(mathfield, action, previousPosition, atoms) {\n  let liveText = \"\";\n  if (action === \"plonk\") {\n    globalThis.MathfieldElement.playSound(\"plonk\");\n    mathfield.flushInlineShortcutBuffer();\n    return;\n  }\n  if (action === \"delete\") liveText = speakableText(\"deleted: \", atoms);\n  else if (action === \"focus\" || action.includes(\"move\")) {\n    liveText = getRelationshipAsSpokenText(mathfield.model, previousPosition);\n    liveText += getNextAtomAsSpokenText(mathfield.model);\n  } else if (action === \"replacement\") {\n    liveText = speakableText(mathfield.model.at(mathfield.model.position));\n  } else if (action === \"line\") {\n    const label = speakableText(mathfield.model.root);\n    mathfield.keyboardDelegate.setAriaLabel(label);\n  } else liveText = atoms ? speakableText(action + \" \", atoms) : action;\n  if (liveText) {\n    const ariaLiveChangeHack = mathfield.ariaLiveText.textContent.includes(\n      \"\\xA0\"\n    ) ? \" \\u202F \" : \" \\xA0 \";\n    mathfield.ariaLiveText.textContent = liveText + ariaLiveChangeHack;\n  }\n}\nfunction getRelationshipAsSpokenText(model, previousOffset) {\n  if (Number.isNaN(previousOffset)) return \"\";\n  const previous = model.at(previousOffset);\n  if (!previous) return \"\";\n  if (previous.treeDepth <= model.at(model.position).treeDepth) return \"\";\n  let result = \"\";\n  let ancestor = previous.parent;\n  const newParent = model.at(model.position).parent;\n  while (ancestor !== model.root && ancestor !== newParent) {\n    result += `out of ${relationName(ancestor)};`;\n    ancestor = ancestor.parent;\n  }\n  return result;\n}\nfunction getNextAtomAsSpokenText(model) {\n  if (!model.selectionIsCollapsed)\n    return `selected: ${speakableText(model.getAtoms(model.selection))}`;\n  let result = \"\";\n  const cursor = model.at(model.position);\n  if (cursor.isFirstSibling) result = `start of ${relationName(cursor)}: `;\n  if (cursor.isLastSibling) {\n    if (!cursor.isFirstSibling) {\n      if (!cursor.parent.parent)\n        return `${speakableText(cursor)}; end of mathfield`;\n      result = `${speakableText(cursor)}; end of ${relationName(cursor)}`;\n    }\n  } else result += speakableText(cursor);\n  return result;\n}\n\n// src/editor-model/model-private.ts\nvar _Model = class {\n  constructor(target, mode, root) {\n    this.mathfield = target;\n    this.mode = mode;\n    this.silenceNotifications = false;\n    this._selection = { ranges: [[0, 0]], direction: \"none\" };\n    this._anchor = 0;\n    this._position = 0;\n    this.root = root;\n  }\n  dispose() {\n    this.mathfield = void 0;\n  }\n  getState() {\n    const selection = { ranges: [...this._selection.ranges] };\n    if (this.selection.direction && this.selection.direction !== \"none\")\n      selection.direction = this.selection.direction;\n    return {\n      content: this.root.toJson(),\n      selection,\n      mode: this.mode\n    };\n  }\n  setState(state, options) {\n    var _a3;\n    const wasSuppressing = this.silenceNotifications;\n    this.silenceNotifications = (_a3 = options == null ? void 0 : options.silenceNotifications) != null ? _a3 : true;\n    let changeOption = {};\n    if ((options == null ? void 0 : options.type) === \"undo\") changeOption = { inputType: \"historyUndo\" };\n    if ((options == null ? void 0 : options.type) === \"redo\") changeOption = { inputType: \"historyRedo\" };\n    if (this.contentWillChange(changeOption)) {\n      const didSuppress = this.silenceNotifications;\n      this.silenceNotifications = true;\n      this.mode = state.mode;\n      this.root = fromJson(state.content);\n      this.selection = state.selection;\n      this.silenceNotifications = didSuppress;\n      this.contentDidChange(changeOption);\n      this.selectionDidChange();\n    }\n    this.silenceNotifications = wasSuppressing;\n  }\n  get atoms() {\n    return this.root.children;\n  }\n  /**\n   * The selection, accounting for the common ancestors\n   */\n  get selection() {\n    return this._selection;\n  }\n  set selection(value) {\n    this.setSelection(value);\n  }\n  setSelection(arg1, arg2) {\n    if (!this.mathfield.contentEditable && this.mathfield.userSelect === \"none\")\n      return false;\n    return this.deferNotifications({ selection: true, content: true }, () => {\n      var _a3, _b3, _c2;\n      const value = this.normalizeSelection(arg1, arg2);\n      if (value === void 0) throw new TypeError(\"Invalid selection\");\n      if (value.ranges.length === 1 && value.ranges[0][0] === value.ranges[0][1]) {\n        const pos = value.ranges[0][0];\n        if (!this.mathfield.dirty && !((_a3 = this.at(pos)) == null ? void 0 : _a3.parentPrompt) && this.mathfield.hasEditablePrompts) {\n          if ((_b3 = this.at(pos - 1)) == null ? void 0 : _b3.parentPrompt) {\n            this._anchor = this.normalizeOffset(pos - 1);\n            this._position = this._anchor;\n            this._selection = this.normalizeSelection(this._anchor);\n            return;\n          }\n          if ((_c2 = this.at(pos + 1)) == null ? void 0 : _c2.parentPrompt) {\n            this._anchor = this.normalizeOffset(pos + 1);\n            this._position = this._anchor;\n            this._selection = this.normalizeSelection(this._anchor);\n            return;\n          }\n          this._anchor = 0;\n          this._position = 0;\n          this._selection = { ranges: [[0, 0]] };\n          return;\n        }\n        this._anchor = pos;\n        this._position = pos;\n        this._selection = value;\n        return;\n      }\n      const selRange = range(value);\n      if (value.direction === \"backward\")\n        [this._position, this._anchor] = selRange;\n      else [this._anchor, this._position] = selRange;\n      const first = this.at(selRange[0] + 1);\n      const last = this.at(selRange[1]);\n      const commonAncestor = Atom.commonAncestor(first, last);\n      if ((commonAncestor == null ? void 0 : commonAncestor.type) === \"array\" && first.parent === commonAncestor && last.parent === commonAncestor) {\n        this._selection = { ranges: [selRange], direction: value.direction };\n      } else\n        this._selection = { ranges: [selRange], direction: value.direction };\n      console.assert(this._position >= 0 && this._position <= this.lastOffset);\n      return;\n    });\n  }\n  setPositionHandlingPlaceholder(pos) {\n    var _a3;\n    const atom = this.at(pos);\n    if ((atom == null ? void 0 : atom.type) === \"placeholder\") {\n      this.setSelection(pos - 1, pos);\n    } else if (((_a3 = atom == null ? void 0 : atom.rightSibling) == null ? void 0 : _a3.type) === \"placeholder\") {\n      this.setSelection(pos, pos + 1);\n    } else this.position = pos;\n    if (atom instanceof LatexAtom && atom.isSuggestion)\n      atom.isSuggestion = false;\n    this.mathfield.stopCoalescingUndo();\n  }\n  /**\n   * The \"focus\" or \"cursor\" (i.e. not the anchor) a.k.a the insertion point\n   * or caret: where things are going to be inserted next.\n   *\n   */\n  get position() {\n    return this._position;\n  }\n  set position(value) {\n    this.setSelection(value, value);\n  }\n  /**\n   * The offset from which the selection is extended\n   */\n  get anchor() {\n    return this._anchor;\n  }\n  get selectionIsCollapsed() {\n    return this._anchor === this._position;\n  }\n  get selectionIsPlaceholder() {\n    if (Math.abs(this._anchor - this._position) === 1) {\n      return this.at(Math.max(this._anchor, this._position)).type === \"placeholder\";\n    }\n    return false;\n  }\n  collapseSelection(direction = \"forward\") {\n    if (this._anchor === this._position) return false;\n    if (direction === \"backward\")\n      this.position = Math.min(this._anchor, this._position);\n    else this.position = Math.max(this._anchor, this._position);\n    return true;\n  }\n  get lastOffset() {\n    return this.atoms.length - 1;\n  }\n  at(index) {\n    return this.atoms[index];\n  }\n  offsetOf(atom) {\n    return this.atoms.indexOf(atom);\n  }\n  getSiblingsRange(offset) {\n    const atom = this.at(offset);\n    const { parent } = atom;\n    if (!parent) return [0, this.lastOffset];\n    const branch = atom.parent.branch(atom.parentBranch);\n    return [this.offsetOf(branch[0]), this.offsetOf(branch[branch.length - 1])];\n  }\n  getBranchRange(offset, branchName) {\n    const branch = this.at(offset).branch(branchName);\n    return [this.offsetOf(branch[0]), this.offsetOf(branch[branch.length - 1])];\n  }\n  getAtoms(arg1, arg2, arg3) {\n    let options = arg3 != null ? arg3 : {};\n    if (isSelection(arg1)) {\n      options = arg2 != null ? arg2 : {};\n      if (arg1.ranges.length > 1) {\n        return arg1.ranges.reduce(\n          (acc, range2) => [...acc, ...this.getAtoms(range2, options)],\n          []\n        );\n      }\n      arg1 = arg1.ranges[0];\n    }\n    let start;\n    let end;\n    if (isOffset(arg1)) {\n      start = arg1;\n      if (!isOffset(arg2)) return [];\n      end = arg2;\n    } else {\n      [start, end] = arg1;\n      options = arg2 != null ? arg2 : {};\n    }\n    if (!Number.isFinite(start)) return [];\n    if (options.includeChildren === void 0) options.includeChildren = false;\n    if (start < 0) start = this.lastOffset - start + 1;\n    if (end < 0) end = this.lastOffset + end + 1;\n    const first = Math.min(start, end) + 1;\n    const last = Math.max(start, end);\n    if (!options.includeChildren && first === 1 && last === this.lastOffset)\n      return [this.root];\n    let result = [];\n    for (let i = first; i <= last; i++) {\n      const atom = this.atoms[i];\n      if (atomIsInRange(this, atom, first, last)) result.push(atom);\n    }\n    if (!options.includeChildren) {\n      result = result.filter((atom) => {\n        let ancestorIncluded = false;\n        let { parent } = atom;\n        while (parent && !ancestorIncluded) {\n          ancestorIncluded = atomIsInRange(this, parent, first, last);\n          parent = parent.parent;\n        }\n        return !ancestorIncluded;\n      });\n    }\n    return result;\n  }\n  /**\n   * Unlike `getAtoms()`, the argument here is an index\n   * Return all the atoms, in order, starting at startingIndex\n   * then looping back at the beginning\n   */\n  getAllAtoms(startingIndex = 0) {\n    const result = [];\n    const last = this.lastOffset;\n    for (let i = startingIndex; i <= last; i++) result.push(this.atoms[i]);\n    for (let i = 0; i < startingIndex; i++) result.push(this.atoms[i]);\n    return result;\n  }\n  findAtom(filter, startingIndex = 0, direction = \"forward\") {\n    let atom = void 0;\n    const last = this.lastOffset;\n    if (direction === \"forward\") {\n      for (let i = startingIndex; i <= last; i++) {\n        atom = this.atoms[i];\n        if (filter(atom)) return atom;\n      }\n      for (let i = 0; i < startingIndex; i++) {\n        atom = this.atoms[i];\n        if (filter(atom)) return atom;\n      }\n      return void 0;\n    }\n    for (let i = startingIndex; i >= 0; i--) {\n      atom = this.atoms[i];\n      if (filter(atom)) return atom;\n    }\n    for (let i = last; i > startingIndex; i--) {\n      atom = this.atoms[i];\n      if (filter(atom)) return atom;\n    }\n    return void 0;\n  }\n  /** Remove the specified atoms from the tree.\n   * **WARNING** upon return the selection may now be invalid\n   */\n  extractAtoms(range2) {\n    let result = this.getAtoms(range2);\n    if (result.length === 1 && !result[0].parent) {\n      if (result[0].type === \"root\") {\n        result = [...result[0].body];\n        result.shift();\n      } else {\n        result = this.root.cells.flat();\n        this.root = new Atom({ type: \"root\", body: [] });\n        return result;\n      }\n    }\n    for (const child of result) child.parent.removeChild(child);\n    return result;\n  }\n  deleteAtoms(range2) {\n    range2 != null ? range2 : range2 = [0, -1];\n    this.extractAtoms(range2);\n    this.position = range2[0];\n  }\n  atomToString(atom, inFormat) {\n    const format = inFormat != null ? inFormat : \"latex\";\n    if (format.startsWith(\"latex\")) {\n      return Atom.serialize([atom], {\n        expandMacro: format === \"latex-expanded\",\n        skipStyles: format === \"latex-unstyled\",\n        skipPlaceholders: format === \"latex-without-placeholders\",\n        defaultMode: this.mathfield.options.defaultMode\n      });\n    }\n    if (format === \"math-ml\") return toMathML(atom);\n    if (format === \"spoken\") return atomToSpeakableText(atom);\n    if (format === \"spoken-text\") {\n      const saveTextToSpeechMarkup = globalThis.MathfieldElement.textToSpeechMarkup;\n      globalThis.MathfieldElement.textToSpeechMarkup = \"\";\n      const result = atomToSpeakableText(atom);\n      globalThis.MathfieldElement.textToSpeechMarkup = saveTextToSpeechMarkup;\n      return result;\n    }\n    if (format === \"spoken-ssml\" || format === \"spoken-ssml-with-highlighting\") {\n      const saveTextToSpeechMarkup = globalThis.MathfieldElement.textToSpeechMarkup;\n      globalThis.MathfieldElement.textToSpeechMarkup = \"ssml\";\n      const result = atomToSpeakableText(atom);\n      globalThis.MathfieldElement.textToSpeechMarkup = saveTextToSpeechMarkup;\n      return result;\n    }\n    if (format === \"plain-text\") return atomToAsciiMath(atom, { plain: true });\n    if (format === \"ascii-math\") return atomToAsciiMath(atom);\n    console.error(`MathLive 0.101.0: Unexpected format \"${format}`);\n    return \"\";\n  }\n  getValue(arg1, arg2, arg3) {\n    if (arg1 === void 0) return this.atomToString(this.root, \"latex\");\n    if (typeof arg1 === \"string\" && arg1 !== \"math-json\")\n      return this.atomToString(this.root, arg1);\n    let ranges;\n    let format;\n    if (isOffset(arg1) && isOffset(arg2)) {\n      ranges = [this.normalizeRange([arg1, arg2])];\n      format = arg3;\n    } else if (isRange(arg1)) {\n      ranges = [this.normalizeRange(arg1)];\n      format = arg2;\n    } else if (isSelection(arg1)) {\n      ranges = arg1.ranges;\n      format = arg2;\n    } else {\n      ranges = [this.normalizeRange([0, -1])];\n      format = arg1;\n    }\n    format != null ? format : format = \"latex\";\n    if (format === \"math-json\") {\n      if (!globalThis.MathfieldElement.computeEngine) {\n        if (!window[Symbol.for(\"io.cortexjs.compute-engine\")]) {\n          console.error(\n            'The CortexJS Compute Engine library is not available.\\nLoad the library, for example with:\\nimport \"https://unpkg.com/@cortex-js/compute-engine?module\"'\n          );\n        }\n        return '[\"Error\", \"compute-engine-not-available\"]';\n      }\n      const latex = this.getValue({ ranges }, \"latex-unstyled\");\n      try {\n        const expr = globalThis.MathfieldElement.computeEngine.parse(latex);\n        return JSON.stringify(expr.json);\n      } catch (e) {\n        return JSON.stringify([\"Error\", `'${e.toString()}'`]);\n      }\n    }\n    if (format.startsWith(\"latex\")) {\n      const options = {\n        expandMacro: format === \"latex-expanded\",\n        skipStyles: format === \"latex-unstyled\",\n        skipPlaceholders: format === \"latex-without-placeholders\",\n        defaultMode: this.mathfield.options.defaultMode\n      };\n      return joinLatex(\n        ranges.map((range2) => Atom.serialize(this.getAtoms(range2), options))\n      );\n    }\n    return ranges.map(\n      (range2) => this.getAtoms(range2).map((atom) => this.atomToString(atom, format)).join(\"\")\n    ).join(\"\");\n  }\n  /**\n   * Unlike `setSelection`, this method is intended to be used in response\n   * to a user action, and it performs various adjustments to result\n   * in a more intuitive selection.\n   * For example:\n   * - when all the children of an atom are selected, the atom\n   * become selected.\n   * - this method will *not* change the anchor, but may result\n   * in a selection whose boundary is outside the anchor\n   */\n  extendSelectionTo(anchor, position) {\n    if (!this.mathfield.contentEditable && this.mathfield.userSelect === \"none\")\n      return false;\n    return this.deferNotifications({ selection: true }, () => {\n      const range2 = this.normalizeRange([anchor, position]);\n      let [start, end] = range2;\n      let { parent } = this.at(end);\n      if (parent) {\n        if (parent.type === \"genfrac\" || parent.type === \"subsup\") {\n          while (parent !== this.root && childrenInRange(this, parent, [start, end])) {\n            end = this.offsetOf(parent);\n            parent = parent.parent;\n          }\n        }\n      }\n      parent = this.at(start).parent;\n      while (parent !== this.root && childrenInRange(this, parent, [start, end])) {\n        start = this.offsetOf(parent.leftSibling);\n        parent = parent.parent;\n      }\n      parent = this.at(end).parent;\n      if ((parent == null ? void 0 : parent.type) === \"genfrac\") {\n        while (parent !== this.root && childrenInRange(this, parent, [start, end])) {\n          end = this.offsetOf(parent);\n          console.assert(end >= 0);\n          parent = parent.parent;\n        }\n      }\n      this._position = this.normalizeOffset(position);\n      this._selection = {\n        ranges: [[start, end]],\n        direction: \"none\"\n      };\n    });\n  }\n  /**\n   * This method is called to provide feedback when using a screen reader\n   * or other assistive device, for example when changing the selection or\n   * moving the insertion point.\n   *\n   * It can also be used with the 'plonk' command to provide an audible\n   * feedback when a command is not possible.\n   *\n   * This method should not be called from other methods of the model\n   * (such as `setSelection`) as these methods can also be called\n   * programmatically and a feedback in these case would be innapropriate,\n   * however they should be called from functions called as a result of a user\n   * action, such as the functions in `commands.ts`\n   */\n  announce(command, previousPosition, atoms = []) {\n    var _a3, _b3;\n    const success = (_b3 = (_a3 = this.mathfield.host) == null ? void 0 : _a3.dispatchEvent(\n      new CustomEvent(\"announce\", {\n        detail: { command, previousPosition, atoms },\n        cancelable: true,\n        bubbles: true,\n        composed: true\n      })\n    )) != null ? _b3 : true;\n    if (success)\n      defaultAnnounceHook(this.mathfield, command, previousPosition, atoms);\n  }\n  // Suppress notification while scope is executed,\n  // then notify of content change, and selection change (if actual change)\n  deferNotifications(options, f) {\n    const oldSelection = this._selection;\n    const oldAnchor = this._anchor;\n    const oldPosition = this._position;\n    const saved = this.silenceNotifications;\n    this.silenceNotifications = true;\n    const previousCounter = this.root.changeCounter;\n    f();\n    this.silenceNotifications = saved;\n    const selectionChanged = oldAnchor !== this._anchor || oldPosition !== this._position || compareSelection(this._selection, oldSelection) === \"different\";\n    if (options.selection && selectionChanged) this.selectionDidChange();\n    const contentChanged = this.root.changeCounter !== previousCounter;\n    if (options.content && contentChanged)\n      this.contentDidChange({ inputType: options.type });\n    return contentChanged || selectionChanged;\n  }\n  normalizeOffset(value) {\n    if (value > 0) value = Math.min(value, this.lastOffset);\n    else if (value < 0) value = this.lastOffset + value + 1;\n    return value;\n  }\n  /**\n   * Ensure that the range is valid and canonical, i.e.\n   * - start <= end\n   * - collapsed = start === end\n   * - start >= 0, end >=0\n   */\n  normalizeRange(range2) {\n    let [start, end] = range2;\n    start = this.normalizeOffset(start);\n    end = this.normalizeOffset(end);\n    return start < end ? [start, end] : [end, start];\n  }\n  normalizeSelection(value, value2) {\n    var _a3;\n    let result = void 0;\n    if (isOffset(value)) {\n      const offset = this.normalizeOffset(value);\n      if (isOffset(value2)) {\n        const offset2 = this.normalizeOffset(value2);\n        result = offset <= offset2 ? { ranges: [[offset, offset2]], direction: \"none\" } : {\n          ranges: [[offset2, offset]],\n          direction: \"backward\"\n        };\n      } else result = { ranges: [[offset, offset]], direction: \"none\" };\n    } else if (isRange(value)) {\n      const start = this.normalizeOffset(value[0]);\n      const end = this.normalizeOffset(value[1]);\n      result = start <= end ? { ranges: [[start, end]], direction: \"none\" } : { ranges: [[end, start]], direction: \"backward\" };\n    } else if (isSelection(value)) {\n      result = {\n        ranges: value.ranges.map((x) => this.normalizeRange(x)),\n        direction: (_a3 = value.direction) != null ? _a3 : \"none\"\n      };\n    }\n    console.assert(result !== void 0);\n    return result;\n  }\n  /** Returns the first ArrayAtom in ancestry of current position */\n  get parentEnvironment() {\n    let parent = this.at(this.position).parent;\n    if (!parent) return void 0;\n    while (parent.parent && parent.type !== \"array\") parent = parent.parent;\n    if (parent.type !== \"array\") return void 0;\n    return parent;\n  }\n  /** Return the cell (row, col) that the current selection is in */\n  get cell() {\n    var _a3;\n    let atom = this.at(this.position);\n    if (!atom) return void 0;\n    while (atom && ((_a3 = atom.parent) == null ? void 0 : _a3.type) !== \"array\") atom = atom.parent;\n    if (!(atom == null ? void 0 : atom.parent) || atom.parent.type !== \"array\") return void 0;\n    return atom.parentBranch;\n  }\n  contentWillChange(options = {}) {\n    if (this.silenceNotifications || !this.mathfield) return true;\n    const save = this.silenceNotifications;\n    this.silenceNotifications = true;\n    const result = this.mathfield.onContentWillChange(options);\n    this.silenceNotifications = save;\n    return result;\n  }\n  contentDidChange(options) {\n    if (window.mathVirtualKeyboard.visible)\n      window.mathVirtualKeyboard.update(makeProxy(this.mathfield));\n    if (this.silenceNotifications || !this.mathfield.host || !this.mathfield)\n      return;\n    const save = this.silenceNotifications;\n    this.silenceNotifications = true;\n    setTimeout(() => {\n      var _a3;\n      if (!this.mathfield || !isValidMathfield(this.mathfield) || !this.mathfield.host)\n        return;\n      this.mathfield.host.dispatchEvent(\n        new InputEvent(\"input\", __spreadProps(__spreadValues({}, options), {\n          // To work around a bug in WebKit/Safari (the inputType property gets stripped), include the inputType as the 'data' property. (see #1843)\n          data: options.data ? options.data : (_a3 = options.inputType) != null ? _a3 : \"\",\n          bubbles: true,\n          composed: true\n        }))\n      );\n    }, 0);\n    this.silenceNotifications = save;\n  }\n  selectionDidChange() {\n    if (!this.mathfield) return;\n    if (window.mathVirtualKeyboard.visible)\n      window.mathVirtualKeyboard.update(makeProxy(this.mathfield));\n    if (this.silenceNotifications) return;\n    const save = this.silenceNotifications;\n    this.silenceNotifications = true;\n    this.mathfield.onSelectionDidChange();\n    this.silenceNotifications = save;\n  }\n};\nfunction atomIsInRange(model, atom, first, last) {\n  const offset = model.offsetOf(atom);\n  if (offset < first || offset > last) return false;\n  if (!atom.hasChildren) return true;\n  const firstOffset = model.offsetOf(atom.firstChild);\n  if (firstOffset >= first && firstOffset <= last) {\n    const lastOffset = model.offsetOf(atom.lastChild);\n    if (lastOffset >= first && lastOffset <= last) return true;\n  }\n  return false;\n}\nfunction childrenInRange(model, atom, range2) {\n  if (!(atom == null ? void 0 : atom.hasChildren)) return false;\n  const [start, end] = range2;\n  const first = model.offsetOf(atom.firstChild);\n  const last = model.offsetOf(atom.lastChild);\n  if (first >= start && first <= end && last >= first && last <= end)\n    return true;\n  return false;\n}\n\n// src/editor-model/delete.ts\nfunction onDelete(model, direction, atom, branch) {\n  var _a3, _b3, _c2, _d2, _e, _f;\n  const parent = atom.parent;\n  if (parent && atom instanceof LeftRightAtom) {\n    const atStart = !branch && direction === \"forward\" || branch === \"body\" && direction === \"backward\";\n    let pos = atStart ? model.offsetOf(atom.firstChild) : model.offsetOf(atom.lastChild);\n    if (atStart) {\n      if (atom.rightDelim !== \"?\" && atom.rightDelim !== \".\") {\n        atom.leftDelim = \".\";\n        atom.isDirty = true;\n      } else {\n        parent.addChildrenAfter(atom.removeBranch(\"body\"), atom);\n        parent.removeChild(atom);\n        pos--;\n      }\n    } else {\n      if (atom.leftDelim !== \"?\" && atom.leftDelim !== \".\") {\n        atom.rightDelim = \".\";\n        atom.isDirty = true;\n      } else {\n        parent.addChildrenAfter(atom.removeBranch(\"body\"), atom);\n        parent.removeChild(atom);\n        pos--;\n      }\n    }\n    model.position = pos;\n    return true;\n  }\n  if (parent && atom.type === \"surd\") {\n    if (direction === \"forward\" && !branch || direction === \"backward\" && branch === \"body\") {\n      const pos = atom.leftSibling;\n      if (atom.hasChildren)\n        parent.addChildrenAfter(atom.removeBranch(\"body\"), atom);\n      parent.removeChild(atom);\n      model.position = model.offsetOf(pos);\n    } else if (direction === \"forward\" && branch === \"body\") {\n      model.position = model.offsetOf(atom);\n    } else if (!branch && direction === \"backward\") {\n      if (atom.hasChildren) model.position = model.offsetOf(atom.lastChild);\n      else {\n        model.position = Math.max(0, model.offsetOf(atom) - 1);\n        parent.removeChild(atom);\n      }\n    } else if (branch === \"above\") {\n      if (atom.hasEmptyBranch(\"above\")) atom.removeBranch(\"above\");\n      if (direction === \"backward\") {\n        model.position = model.offsetOf(atom.leftSibling);\n      } else {\n        model.position = model.offsetOf(atom.body[0]);\n      }\n    }\n    return true;\n  }\n  if (parent && (atom.type === \"box\" || atom.type === \"enclose\")) {\n    const pos = branch && direction === \"backward\" || !branch && direction === \"forward\" ? atom.leftSibling : atom.lastChild;\n    parent.addChildrenAfter(atom.removeBranch(\"body\"), atom);\n    parent.removeChild(atom);\n    model.position = model.offsetOf(pos);\n    return true;\n  }\n  if (atom.type === \"genfrac\" || atom.type === \"overunder\") {\n    if (!branch) {\n      if (atom.type === \"overunder\" && atom.hasEmptyBranch(\"body\"))\n        return false;\n      if (atom.type === \"genfrac\" && atom.hasEmptyBranch(\"below\") && atom.hasEmptyBranch(\"above\"))\n        return false;\n      model.position = model.offsetOf(\n        direction === \"forward\" ? atom.firstChild : atom.lastChild\n      );\n      return true;\n    }\n    const firstBranch = MathfieldElement.fractionNavigationOrder === \"numerator-denominator\" ? \"above\" : \"below\";\n    const secondBranch = firstBranch === \"above\" ? \"below\" : \"above\";\n    if (parent && (direction === \"forward\" && branch === firstBranch || direction === \"backward\" && branch === secondBranch)) {\n      const first = atom.removeBranch(firstBranch);\n      const second = atom.removeBranch(secondBranch);\n      parent.addChildrenAfter([...first, ...second], atom);\n      parent.removeChild(atom);\n      model.position = model.offsetOf(\n        first.length > 0 ? first[first.length - 1] : second[0]\n      );\n      return true;\n    }\n    if (direction === \"backward\")\n      model.position = model.offsetOf(atom.leftSibling);\n    else model.position = model.offsetOf(atom);\n    return true;\n  }\n  if (atom.type === \"extensible-symbol\" || atom.type === \"subsup\") {\n    if (!branch && direction === \"forward\") return false;\n    if (!branch) {\n      if (atom.subscript || atom.superscript) {\n        const pos = direction === \"forward\" ? (_c2 = (_a3 = atom.superscript) == null ? void 0 : _a3[0]) != null ? _c2 : (_b3 = atom.subscript) == null ? void 0 : _b3[0] : (_f = (_d2 = atom.subscript) == null ? void 0 : _d2[0].lastSibling) != null ? _f : (_e = atom.superscript) == null ? void 0 : _e[0].lastSibling;\n        if (pos) model.position = model.offsetOf(pos);\n        return true;\n      }\n      return false;\n    }\n    if (!atom.hasChildren && atom.type === \"subsup\") {\n      const pos = direction === \"forward\" ? model.offsetOf(atom) : Math.max(0, model.offsetOf(atom) - 1);\n      atom.parent.removeChild(atom);\n      model.position = pos;\n      return true;\n    }\n    if (branch === \"superscript\") {\n      if (direction === \"backward\") {\n        const pos = model.offsetOf(atom.firstChild) - 1;\n        console.assert(pos >= 0);\n        model.position = pos;\n      } else if (atom.subscript)\n        model.position = model.offsetOf(atom.subscript[0]);\n      else model.position = model.offsetOf(atom);\n    } else if (branch === \"subscript\") {\n      if (direction === \"backward\" && atom.superscript) {\n        model.position = model.offsetOf(atom.superscript[0].lastSibling);\n      } else if (direction === \"backward\") {\n        model.position = model.offsetOf(atom.firstChild) - 1;\n      } else {\n        model.position = model.offsetOf(atom);\n      }\n    }\n    if (branch && atom.hasEmptyBranch(branch)) {\n      atom.removeBranch(branch);\n      if (atom.type === \"subsup\" && !atom.subscript && !atom.superscript) {\n        const pos = direction === \"forward\" ? model.offsetOf(atom) : Math.max(0, model.offsetOf(atom) - 1);\n        atom.parent.removeChild(atom);\n        model.position = pos;\n      }\n    }\n    return true;\n  }\n  if ((parent == null ? void 0 : parent.type) === \"genfrac\" && !branch && atom.type !== \"first\") {\n    let pos = model.offsetOf(atom.leftSibling);\n    parent.removeChild(atom);\n    if (parent.hasEmptyBranch(\"above\") && parent.hasEmptyBranch(\"below\")) {\n      pos = model.offsetOf(parent.leftSibling);\n      parent.parent.removeChild(parent);\n      model.announce(\"delete\", void 0, [parent]);\n      model.position = pos;\n      return true;\n    }\n    model.announce(\"delete\", void 0, [atom]);\n    model.position = pos;\n    return true;\n  }\n  if (direction === \"backward\" && ((parent == null ? void 0 : parent.command) === \"\\\\ln\" || (parent == null ? void 0 : parent.command) === \"\\\\log\") && atom.parentBranch !== \"body\") {\n    const pos = model.offsetOf(parent.leftSibling);\n    parent.parent.removeChild(parent);\n    model.announce(\"delete\", void 0, [parent]);\n    model.position = pos;\n    return true;\n  }\n  return false;\n}\nfunction deleteBackward(model) {\n  if (!model.mathfield.isSelectionEditable) return false;\n  if (!model.contentWillChange({ inputType: \"deleteContentBackward\" }))\n    return false;\n  if (!model.selectionIsCollapsed)\n    return deleteRange(model, range(model.selection), \"deleteContentBackward\");\n  return model.deferNotifications(\n    { content: true, selection: true, type: \"deleteContentBackward\" },\n    () => {\n      let target = model.at(model.position);\n      if (target && onDelete(model, \"backward\", target)) return;\n      if (target == null ? void 0 : target.isFirstSibling) {\n        if (onDelete(model, \"backward\", target.parent, target.parentBranch))\n          return;\n        target = null;\n      }\n      if (!target) {\n        model.announce(\"plonk\");\n        return;\n      }\n      model.position = model.offsetOf(target.leftSibling);\n      target.parent.removeChild(target);\n      model.announce(\"delete\", void 0, [target]);\n    }\n  );\n}\nfunction deleteForward(model) {\n  if (!model.mathfield.isSelectionEditable) return false;\n  if (!model.contentWillChange({ inputType: \"deleteContentForward\" }))\n    return false;\n  if (!model.selectionIsCollapsed)\n    return deleteRange(model, range(model.selection), \"deleteContentForward\");\n  return model.deferNotifications(\n    { content: true, selection: true, type: \"deleteContentForward\" },\n    () => {\n      var _a3, _b3;\n      let target = model.at(model.position).rightSibling;\n      if (target && onDelete(model, \"forward\", target)) return;\n      if (!target) {\n        target = model.at(model.position);\n        if (target.isLastSibling && onDelete(model, \"forward\", target.parent, target.parentBranch))\n          return;\n        target = void 0;\n      } else if (model.at(model.position).isLastSibling && onDelete(model, \"forward\", target.parent, target.parentBranch))\n        return;\n      if (model.position === model.lastOffset || !target) {\n        model.announce(\"plonk\");\n        return;\n      }\n      target.parent.removeChild(target);\n      let sibling = (_a3 = model.at(model.position)) == null ? void 0 : _a3.rightSibling;\n      while ((sibling == null ? void 0 : sibling.type) === \"subsup\") {\n        sibling.parent.removeChild(sibling);\n        sibling = (_b3 = model.at(model.position)) == null ? void 0 : _b3.rightSibling;\n      }\n      model.announce(\"delete\", void 0, [target]);\n    }\n  );\n}\nfunction deleteRange(model, range2, type) {\n  const result = model.getAtoms(range2);\n  if (result.length > 0 && result[0].parent) {\n    let firstChild = result[0].parent.firstChild;\n    if (firstChild.type === \"first\") firstChild = firstChild.rightSibling;\n    const lastChild = result[result.length - 1].parent.lastChild;\n    let firstSelected = result[0];\n    if (firstSelected.type === \"first\")\n      firstSelected = firstSelected.rightSibling;\n    const lastSelected = result[result.length - 1];\n    if (firstSelected === firstChild && lastSelected === lastChild) {\n      const parent = result[0].parent;\n      if (parent.parent && parent.type !== \"prompt\")\n        range2 = [model.offsetOf(parent.leftSibling), model.offsetOf(parent)];\n    }\n    if (result.length === 1 && result[0].type === \"placeholder\" && result[0].parent.type === \"genfrac\") {\n      const genfrac = result[0].parent;\n      const branch = result[0].parentBranch === \"below\" ? \"above\" : \"below\";\n      const pos = model.offsetOf(genfrac.leftSibling);\n      return model.deferNotifications(\n        { content: true, selection: true, type },\n        () => {\n          var _a3, _b3;\n          const numer = genfrac.removeBranch(branch);\n          if (!(numer.length === 1 && numer[0].type === \"placeholder\")) {\n            const lastAtom = genfrac.parent.addChildrenAfter(numer, genfrac);\n            (_a3 = genfrac.parent) == null ? void 0 : _a3.removeChild(genfrac);\n            model.position = model.offsetOf(lastAtom);\n          } else {\n            (_b3 = genfrac.parent) == null ? void 0 : _b3.removeChild(genfrac);\n            model.position = Math.max(0, pos);\n          }\n        }\n      );\n    }\n  }\n  return model.deferNotifications(\n    { content: true, selection: true, type },\n    () => model.deleteAtoms(range2)\n  );\n}\n\n// src/editor-model/commands-delete.ts\nregister2(\n  {\n    deleteAll: (model) => model.contentWillChange({ inputType: \"deleteContent\" }) && deleteRange(model, [0, -1], \"deleteContent\"),\n    deleteForward: (model) => deleteForward(model),\n    deleteBackward: (model) => deleteBackward(model),\n    deleteNextWord: (model) => model.contentWillChange({ inputType: \"deleteWordForward\" }) && deleteRange(\n      model,\n      [model.anchor, wordBoundaryOffset(model, model.position, \"forward\")],\n      \"deleteWordForward\"\n    ),\n    deletePreviousWord: (model) => model.contentWillChange({ inputType: \"deleteWordBackward\" }) && deleteRange(\n      model,\n      [model.anchor, wordBoundaryOffset(model, model.position, \"backward\")],\n      \"deleteWordBackward\"\n    ),\n    deleteToGroupStart: (model) => model.contentWillChange({ inputType: \"deleteSoftLineBackward\" }) && deleteRange(\n      model,\n      [model.anchor, model.offsetOf(model.at(model.position).firstSibling)],\n      \"deleteSoftLineBackward\"\n    ),\n    deleteToGroupEnd: (model) => model.contentWillChange({ inputType: \"deleteSoftLineForward\" }) && deleteRange(\n      model,\n      [model.anchor, model.offsetOf(model.at(model.position).lastSibling)],\n      \"deleteSoftLineForward\"\n    ),\n    deleteToMathFieldStart: (model) => model.contentWillChange({ inputType: \"deleteHardLineBackward\" }) && deleteRange(model, [model.anchor, 0], \"deleteHardLineBackward\"),\n    deleteToMathFieldEnd: (model) => model.contentWillChange({ inputType: \"deleteHardLineForward\" }) && deleteRange(model, [model.anchor, -1], \"deleteHardLineForward\")\n  },\n  {\n    target: \"model\",\n    audioFeedback: \"delete\",\n    canUndo: true,\n    changeContent: true,\n    changeSelection: true\n  }\n);\n\n// src/editor-mathfield/mathfield-private.ts\nvar DEFAULT_KEYBOARD_TOGGLE_GLYPH = `<svg xmlns=\"http://www.w3.org/2000/svg\" style=\"width: 21px;\"  viewBox=\"0 0 576 512\" role=\"img\" aria-label=\"${localize(\n  \"tooltip.toggle virtual keyboard\"\n)}\"><path d=\"M528 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm16 336c0 8.823-7.177 16-16 16H48c-8.823 0-16-7.177-16-16V112c0-8.823 7.177-16 16-16h480c8.823 0 16 7.177 16 16v288zM168 268v-24c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zm96 0v-24c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zm96 0v-24c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zm96 0v-24c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zm-336 80v-24c0-6.627-5.373-12-12-12H84c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zm384 0v-24c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zM120 188v-24c0-6.627-5.373-12-12-12H84c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zm96 0v-24c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zm96 0v-24c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zm96 0v-24c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zm96 0v-24c0-6.627-5.373-12-12-12h-24c-6.627 0-12 5.373-12 12v24c0 6.627 5.373 12 12 12h24c6.627 0 12-5.373 12-12zm-96 152v-8c0-6.627-5.373-12-12-12H180c-6.627 0-12 5.373-12 12v8c0 6.627 5.373 12 12 12h216c6.627 0 12-5.373 12-12z\"/></svg>`;\nvar MENU_GLYPH = `<svg xmlns=\"http://www.w3.org/2000/svg\" style=\"height: 18px;\" viewBox=\"0 0 448 512\" role=\"img\" aria-label=\"${localize(\n  \"tooltip.menu\"\n)}\"><path d=\"M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z\"/></svg>`;\nvar _Mathfield = class {\n  /**\n   *\n   * - `options.computeEngine`: An instance of a `ComputeEngine`. It is used to parse and serialize\n   * LaTeX strings, using the information contained in the dictionaries\n   * of the Compute Engine to determine, for example, which symbols are\n   * numbers or which are functions, and therefore correctly interpret\n   * `bf(x)` as `b \\\\times f(x)`.\n   *\n   * If no instance is provided, a new default one is created.\n   *\n   * @param element - The DOM element that this mathfield is attached to.\n   * Note that `element.mathfield` is this object.\n   */\n  constructor(element, options) {\n    this.focusBlurInProgress = false;\n    var _a3, _b3, _c2;\n    this.options = __spreadValues(__spreadProps(__spreadValues({}, getDefault()), {\n      macros: getMacros(),\n      registers: getDefaultRegisters()\n    }), update(options));\n    this.eventController = new AbortController();\n    const signal = this.eventController.signal;\n    if (options.eventSink) this.host = options.eventSink;\n    this.element = element;\n    element.mathfield = this;\n    this.blurred = true;\n    this.keystrokeCaptionVisible = false;\n    this.suggestionIndex = 0;\n    this.inlineShortcutBuffer = [];\n    this.inlineShortcutBufferFlushTimer = 0;\n    this.defaultStyle = {};\n    this.styleBias = \"left\";\n    if (this.options.defaultMode === \"inline-math\")\n      this.element.classList.add(\"ML__is-inline\");\n    else this.element.classList.remove(\"ML__is-inline\");\n    this.dirty = false;\n    let elementText = (_b3 = (_a3 = options.value) != null ? _a3 : this.element.textContent) != null ? _b3 : \"\";\n    elementText = elementText.trim();\n    const mode = effectiveMode(this.options);\n    const root = new Atom({\n      type: \"root\",\n      mode,\n      body: parseLatex(elementText, { context: this.context })\n    });\n    this.model = new _Model(this, mode, root);\n    this.undoManager = new UndoManager(this.model);\n    const markup = [];\n    markup.push(\n      `<span contenteditable=true role=textbox aria-autocomplete=none aria-multiline=false part=keyboard-sink class=ML__keyboard-sink autocapitalize=off autocomplete=off autocorrect=off spellcheck=false inputmode=none tabindex=0></span>`\n    );\n    markup.push(\n      '<span part=container class=ML__container aria-hidden=true  style=\"visibility:hidden\">'\n    );\n    markup.push(\"<span part=content class=ML__content>\");\n    markup.push(contentMarkup(this));\n    markup.push(\"</span>\");\n    if (window.mathVirtualKeyboard) {\n      markup.push(\n        `<div part=virtual-keyboard-toggle class=ML__virtual-keyboard-toggle role=button ${this.hasEditableContent ? \"\" : 'style=\"display:none;\"'} data-l10n-tooltip=\"tooltip.toggle virtual keyboard\">`\n      );\n      markup.push(DEFAULT_KEYBOARD_TOGGLE_GLYPH);\n      markup.push(\"</div>\");\n    }\n    markup.push(\n      `<div part=menu-toggle class=ML__menu-toggle role=button data-l10n-tooltip=\"tooltip.menu\">`\n    );\n    markup.push(MENU_GLYPH);\n    markup.push(\"</div>\");\n    markup.push(\"</span>\");\n    markup.push(\"<span class=ML__sr-only>\");\n    markup.push(\n      \"<span role=status aria-live=assertive aria-atomic=true></span>\"\n    );\n    markup.push(\"</span>\");\n    this.element.innerHTML = globalThis.MathfieldElement.createHTML(\n      markup.join(\"\")\n    );\n    if (!this.element.children) {\n      console.error(\n        `%cMathLive 0.101.0: Something went wrong and the mathfield could not be created.%c\nIf you are using Vue, this may be because you are using the runtime-only build of Vue. Make sure to include \\`runtimeCompiler: true\\` in your Vue configuration. There may a warning from Vue in the log above.`,\n        \"color:red;font-family:system-ui;font-size:1.2rem;font-weight:bold\",\n        \"color:inherit;font-family:system-ui;font-size:inherit;font-weight:inherit\"\n      );\n      return;\n    }\n    this._l10Subscription = l10n.subscribe(() => l10n.update(this.element));\n    l10n.update(this.element);\n    this.field = this.element.querySelector(\"[part=content]\");\n    this.field.addEventListener(\n      \"click\",\n      (evt) => evt.stopImmediatePropagation(),\n      { capture: false, signal }\n    );\n    this.field.addEventListener(\"wheel\", this, { passive: false, signal });\n    if (\"PointerEvent\" in window)\n      this.field.addEventListener(\"pointerdown\", this, { signal });\n    else this.field.addEventListener(\"mousedown\", this, { signal });\n    (_c2 = this.element.querySelector(\"[part=virtual-keyboard-toggle]\")) == null ? void 0 : _c2.addEventListener(\n      \"click\",\n      () => {\n        if (window.mathVirtualKeyboard.visible)\n          window.mathVirtualKeyboard.hide();\n        else {\n          window.mathVirtualKeyboard.show({ animate: true });\n          window.mathVirtualKeyboard.update(makeProxy(this));\n        }\n      },\n      { signal }\n    );\n    this.field.addEventListener(\"contextmenu\", this, { signal });\n    const menuToggle = this.element.querySelector(\"[part=menu-toggle]\");\n    menuToggle == null ? void 0 : menuToggle.addEventListener(\n      \"pointerdown\",\n      (ev) => {\n        if (ev.currentTarget !== menuToggle) return;\n        const menu = this.menu;\n        if (menu.state !== \"closed\") return;\n        this.element.classList.add(\"tracking\");\n        const bounds = menuToggle.getBoundingClientRect();\n        menu.modifiers = keyboardModifiersFromEvent(ev);\n        menu.show({\n          target: menuToggle,\n          location: { x: bounds.left, y: bounds.bottom },\n          onDismiss: () => this.element.classList.remove(\"tracking\")\n        });\n        ev.preventDefault();\n        ev.stopPropagation();\n      },\n      { signal }\n    );\n    if (this.model.atoms.length <= 1 || this.disabled || this.readOnly && !this.hasEditableContent || this.userSelect === \"none\")\n      menuToggle.style.display = \"none\";\n    this.ariaLiveText = this.element.querySelector(\"[role=status]\");\n    this.keyboardDelegate = delegateKeyboardEvents(\n      this.element.querySelector(\".ML__keyboard-sink\"),\n      this.element,\n      this\n    );\n    window.addEventListener(\"resize\", this, { signal });\n    document.addEventListener(\"scroll\", this, { signal });\n    this.resizeObserver = new ResizeObserver((entries) => {\n      if (this.resizeObserverStarted) {\n        this.resizeObserverStarted = false;\n        return;\n      }\n      requestUpdate(this);\n    });\n    this.resizeObserverStarted = true;\n    this.resizeObserver.observe(this.field);\n    window.mathVirtualKeyboard.addEventListener(\n      \"virtual-keyboard-toggle\",\n      this,\n      { signal }\n    );\n    if (gKeyboardLayout && !l10n.locale.startsWith(gKeyboardLayout.locale))\n      setKeyboardLayoutLocale(l10n.locale);\n    if (gFontsState !== \"ready\")\n      document.fonts.ready.then(() => renderSelection(this));\n    element.querySelector(\"[part=container]\").style.removeProperty(\"visibility\");\n    this.undoManager.startRecording();\n    this.undoManager.snapshot(\"set-value\");\n  }\n  connectToVirtualKeyboard() {\n    if (this.connectedToVirtualKeyboard) return;\n    this.connectedToVirtualKeyboard = true;\n    window.addEventListener(\"message\", this, {\n      signal: this.eventController.signal\n    });\n    window.mathVirtualKeyboard.connect();\n    if (window.mathVirtualKeyboard.visible)\n      window.mathVirtualKeyboard.update(makeProxy(this));\n    updateEnvironmentPopover(this);\n  }\n  disconnectFromVirtualKeyboard() {\n    if (!this.connectedToVirtualKeyboard) return;\n    window.removeEventListener(\"message\", this);\n    window.mathVirtualKeyboard.disconnect();\n    this.connectedToVirtualKeyboard = false;\n    hideEnvironmentPopover();\n  }\n  showMenu(_) {\n    var _a3, _b3;\n    const location = (_b3 = (_a3 = _ == null ? void 0 : _.location) != null ? _a3 : getCaretPoint(this.field)) != null ? _b3 : void 0;\n    const modifiers = _ == null ? void 0 : _.modifiers;\n    const target = this.element.querySelector(\"[part=container]\");\n    return this._menu.show({ target, location, modifiers });\n  }\n  get colorMap() {\n    return (name) => {\n      var _a3, _b3, _c2;\n      return (_c2 = (_b3 = (_a3 = this.options).colorMap) == null ? void 0 : _b3.call(_a3, name)) != null ? _c2 : defaultColorMap(name);\n    };\n  }\n  get backgroundColorMap() {\n    return (name) => {\n      var _a3, _b3, _c2, _d2, _e, _f;\n      return (_f = (_e = (_b3 = (_a3 = this.options).backgroundColorMap) == null ? void 0 : _b3.call(_a3, name)) != null ? _e : (_d2 = (_c2 = this.options).colorMap) == null ? void 0 : _d2.call(_c2, name)) != null ? _f : defaultBackgroundColorMap(name);\n    };\n  }\n  get smartFence() {\n    var _a3;\n    return (_a3 = this.options.smartFence) != null ? _a3 : false;\n  }\n  get readOnly() {\n    var _a3;\n    return (_a3 = this.options.readOnly) != null ? _a3 : false;\n  }\n  get disabled() {\n    var _a3, _b3;\n    return (_b3 = (_a3 = this.host) == null ? void 0 : _a3[\"disabled\"]) != null ? _b3 : false;\n  }\n  // This reflects the contenteditable attribute.\n  // Use hasEditableContent instead to take into account readonly and disabled\n  // states.\n  get contentEditable() {\n    if (!this.host) return false;\n    return this.host.getAttribute(\"contenteditable\") !== \"false\";\n  }\n  // This reflect the `user-select` CSS property\n  get userSelect() {\n    if (!this.host) return \"\";\n    const style = getComputedStyle(this.host);\n    return style.getPropertyValue(\"user-select\") || style.getPropertyValue(\"-webkit-user-select\");\n  }\n  // Use to hide/show the virtual keyboard toggle. If false, no point in\n  // showing  the toggle.\n  get hasEditableContent() {\n    if (this.disabled || !this.contentEditable) return false;\n    return !this.readOnly || this.hasEditablePrompts;\n  }\n  get hasEditablePrompts() {\n    return this.readOnly && !this.disabled && this.contentEditable && this.model.findAtom(\n      (a) => a.type === \"prompt\" && !a.locked\n    ) !== void 0;\n  }\n  /** Returns true if the selection is editable:\n   * - mathfield is not disabled, and has contentEditable\n   * - if mathfield is readonly, the current selection is in a prompt which is editable (not locked)\n   */\n  get isSelectionEditable() {\n    if (this.disabled || !this.contentEditable) return false;\n    if (!this.readOnly) return true;\n    const anchor = this.model.at(this.model.anchor);\n    const cursor = this.model.at(this.model.position);\n    const ancestor = Atom.commonAncestor(anchor, cursor);\n    if ((ancestor == null ? void 0 : ancestor.type) === \"prompt\" || (ancestor == null ? void 0 : ancestor.parentPrompt)) return true;\n    return false;\n  }\n  get letterShapeStyle() {\n    var _a3;\n    return (_a3 = this.options.letterShapeStyle) != null ? _a3 : \"tex\";\n  }\n  get minFontScale() {\n    return this.options.minFontScale;\n  }\n  get maxMatrixCols() {\n    return this.options.maxMatrixCols;\n  }\n  /**\n   *\n   * If there is a selection, return if all the atoms in the selection,\n   * some of them or none of them match the `style` argument.\n   *\n   * If there is no selection, return 'all' if the current implicit style\n   * (determined by a combination of the style of the previous atom and\n   * the current style) matches the `style` argument, 'none' if it does not.\n   */\n  queryStyle(inStyle) {\n    const style = validateStyle(this, inStyle);\n    if (\"verbatimColor\" in style) delete style.verbatimColor;\n    if (\"verbatimBackgroundColor\" in style)\n      delete style.verbatimBackgroundColor;\n    const keyCount = Object.keys(style).length;\n    if (keyCount === 0) return \"all\";\n    if (keyCount > 1) {\n      for (const prop2 of Object.keys(style)) {\n        const result = this.queryStyle({ [prop2]: style[prop2] });\n        if (result === \"none\") return \"none\";\n        if (result === \"some\") return \"some\";\n      }\n      return \"all\";\n    }\n    const prop = Object.keys(style)[0];\n    const value = style[prop];\n    if (this.model.selectionIsCollapsed) {\n      const style2 = computeInsertStyle(this);\n      return style2[prop] === value ? \"all\" : \"none\";\n    }\n    const atoms = this.model.getAtoms(this.model.selection, {\n      includeChildren: true\n    });\n    let length = atoms.length;\n    if (length === 0) return \"none\";\n    let count = 0;\n    for (const atom of atoms) {\n      if (atom.type === \"first\") {\n        length -= 1;\n        continue;\n      }\n      if (atom.style[prop] === value) count += 1;\n    }\n    if (count === 0) return \"none\";\n    if (count === length) return \"all\";\n    return \"some\";\n  }\n  get keybindings() {\n    var _a3, _b3;\n    if (this._keybindings) return this._keybindings;\n    const [keybindings, errors] = normalizeKeybindings(\n      this.options.keybindings,\n      (_a3 = getActiveKeyboardLayout()) != null ? _a3 : getDefaultKeyboardLayout()\n    );\n    if (((_b3 = getActiveKeyboardLayout()) == null ? void 0 : _b3.score) > 0) {\n      this._keybindings = keybindings;\n      if (errors.length > 0) {\n        console.error(\n          `MathLive 0.101.0: Invalid keybindings for current keyboard layout`,\n          errors\n        );\n      }\n    }\n    return keybindings;\n  }\n  get menu() {\n    var _a3;\n    (_a3 = this._menu) != null ? _a3 : this._menu = new Menu(getDefaultMenuItems(this), { host: this.host });\n    return this._menu;\n  }\n  set menuItems(menuItems) {\n    if (this._menu) this._menu.menuItems = menuItems;\n    else this._menu = new Menu(menuItems, { host: this.host });\n  }\n  setOptions(config) {\n    var _a3;\n    this.options = __spreadValues(__spreadValues({}, this.options), update(config));\n    this._keybindings = void 0;\n    if (this.options.defaultMode === \"inline-math\")\n      this.element.classList.add(\"ML__is-inline\");\n    else this.element.classList.remove(\"ML__is-inline\");\n    let mode = this.options.defaultMode;\n    if (mode === \"inline-math\") mode = \"math\";\n    if (((_a3 = this.model.root.firstChild) == null ? void 0 : _a3.mode) !== mode)\n      this.model.root.firstChild.mode = mode;\n    if (this.options.readOnly) {\n      if (this.hasFocus() && window.mathVirtualKeyboard.visible)\n        this.executeCommand(\"hideVirtualKeyboard\");\n    }\n    const content = Atom.serialize([this.model.root], {\n      expandMacro: false,\n      defaultMode: this.options.defaultMode\n    });\n    if (\"macros\" in config || this.model.getValue() !== content) reparse(this);\n    if (\"value\" in config || \"registers\" in config || \"colorMap\" in config || \"backgroundColorMap\" in config || \"letterShapeStyle\" in config || \"minFontScale\" in config || \"maxMatrixCols\" in config || \"readOnly\" in config || \"placeholderSymbol\" in config)\n      requestUpdate(this);\n  }\n  getOptions(keys) {\n    return get(this.options, keys);\n  }\n  getOption(key) {\n    return get(this.options, key);\n  }\n  /*\n   * handleEvent is a function invoked when an event is registered with an\n   * object.\n   * The name is defined by `addEventListener()` and cannot be changed.\n   * This pattern is used to be able to release bound event handlers,\n   * (event handlers that need access to `this`) as the `bind()` function\n   * would create a new function that would have to be kept track of\n   * to be able to properly remove the event handler later.\n   */\n  async handleEvent(evt) {\n    var _a3;\n    if (!isValidMathfield(this)) return;\n    if (isVirtualKeyboardMessage(evt)) {\n      if (!validateOrigin(evt.origin, (_a3 = this.options.originValidator) != null ? _a3 : \"none\")) {\n        throw new DOMException(\n          `Message from unknown origin (${evt.origin}) cannot be handled`,\n          \"SecurityError\"\n        );\n      }\n      const { action } = evt.data;\n      if (action === \"execute-command\") {\n        const command = parseCommand(evt.data.command);\n        if (!command) return;\n        if (getCommandTarget(command) === \"virtual-keyboard\") return;\n        this.executeCommand(command);\n      } else if (action === \"update-state\") {\n      } else if (action === \"focus\") this.focus({ preventScroll: true });\n      else if (action === \"blur\") this.blur();\n      return;\n    }\n    switch (evt.type) {\n      case \"focus\":\n        this.onFocus();\n        break;\n      case \"blur\":\n        this.onBlur();\n        break;\n      case \"mousedown\":\n        if (this.userSelect !== \"none\")\n          onPointerDown(this, evt);\n        break;\n      case \"pointerdown\":\n        if (!evt.defaultPrevented && this.userSelect !== \"none\") {\n          onPointerDown(this, evt);\n          if (evt.shiftKey === false) {\n            if (await onContextMenu(\n              evt,\n              this.element.querySelector(\"[part=container]\"),\n              this.menu\n            ))\n              PointerTracker.stop();\n          }\n        }\n        break;\n      case \"contextmenu\":\n        if (this.userSelect !== \"none\" && evt.shiftKey === false) {\n          if (await onContextMenu(\n            evt,\n            this.element.querySelector(\"[part=container]\"),\n            this.menu\n          ))\n            PointerTracker.stop();\n        }\n        break;\n      case \"virtual-keyboard-toggle\":\n        if (this.hasFocus()) updateEnvironmentPopover(this);\n        break;\n      case \"resize\":\n        if (this.geometryChangeTimer)\n          cancelAnimationFrame(this.geometryChangeTimer);\n        this.geometryChangeTimer = requestAnimationFrame(\n          () => isValidMathfield(this) && this.onGeometryChange()\n        );\n        break;\n      case \"scroll\":\n        if (this.geometryChangeTimer)\n          cancelAnimationFrame(this.geometryChangeTimer);\n        this.geometryChangeTimer = requestAnimationFrame(\n          () => isValidMathfield(this) && this.onGeometryChange()\n        );\n        break;\n      case \"wheel\":\n        this.onWheel(evt);\n        break;\n      case \"message\":\n        break;\n      default:\n        console.warn(\"Unexpected event type\", evt.type);\n    }\n  }\n  dispose() {\n    if (!isValidMathfield(this)) return;\n    l10n.unsubscribe(this._l10Subscription);\n    this.keyboardDelegate.dispose();\n    this.keyboardDelegate = void 0;\n    this.eventController.abort();\n    this.eventController = void 0;\n    this.resizeObserver.disconnect();\n    window.mathVirtualKeyboard.removeEventListener(\n      \"virtual-keyboard-toggle\",\n      this\n    );\n    this.disconnectFromVirtualKeyboard();\n    this.model.dispose();\n    const element = this.element;\n    delete element.mathfield;\n    this.element = void 0;\n    this.host = void 0;\n    this.field = void 0;\n    this.ariaLiveText = void 0;\n    disposeKeystrokeCaption();\n    disposeSuggestionPopover();\n    disposeEnvironmentPopover();\n  }\n  flushInlineShortcutBuffer(options) {\n    options != null ? options : options = { defer: false };\n    if (!options.defer) {\n      this.inlineShortcutBuffer = [];\n      clearTimeout(this.inlineShortcutBufferFlushTimer);\n      this.inlineShortcutBufferFlushTimer = 0;\n      return;\n    }\n    if (this.options.inlineShortcutTimeout > 0) {\n      clearTimeout(this.inlineShortcutBufferFlushTimer);\n      this.inlineShortcutBufferFlushTimer = setTimeout(\n        () => this.flushInlineShortcutBuffer(),\n        this.options.inlineShortcutTimeout\n      );\n    }\n  }\n  executeCommand(command) {\n    if (getCommandTarget(command) === \"virtual-keyboard\") {\n      this.focus({ preventScroll: true });\n      window.mathVirtualKeyboard.executeCommand(command);\n      requestAnimationFrame(\n        () => window.mathVirtualKeyboard.update(makeProxy(this))\n      );\n      return false;\n    }\n    return perform(this, command);\n  }\n  get errors() {\n    return validateLatex(this.model.getValue(), { context: this.context });\n  }\n  getValue(arg1, arg2, arg3) {\n    return this.model.getValue(arg1, arg2, arg3);\n  }\n  setValue(value, options) {\n    var _a3;\n    options = options != null ? options : { mode: \"math\" };\n    if (options.insertionMode === void 0)\n      options.insertionMode = \"replaceAll\";\n    if (options.format === void 0 || options.format === \"auto\")\n      options.format = \"latex\";\n    if (options.mode === void 0 || options.mode === \"auto\")\n      options.mode = (_a3 = getMode(this.model, this.model.position)) != null ? _a3 : \"math\";\n    const couldUndo = this.undoManager.canUndo();\n    if (ModeEditor.insert(this.model, value, options)) {\n      requestUpdate(this);\n      if (!couldUndo) this.undoManager.reset();\n      this.undoManager.snapshot(\"set-value\");\n    }\n  }\n  get expression() {\n    const ce = globalThis.MathfieldElement.computeEngine;\n    if (!ce) {\n      console.error(\n        `MathLive 0.101.0:  no compute engine available. Make sure the Compute Engine library is loaded.`\n      );\n      return null;\n    }\n    return ce.box(ce.parse(this.model.getValue(\"latex-unstyled\")));\n  }\n  /** Make sure the caret is visible within the matfield.\n   * If using mathfield element, make sure the mathfield element is visible in\n   * the page\n   */\n  scrollIntoView() {\n    var _a3;\n    if (!this.element) return;\n    if (this.host) {\n      if (this.options.onScrollIntoView) this.options.onScrollIntoView(this);\n      else {\n        this.host.scrollIntoView({ block: \"nearest\", inline: \"nearest\" });\n        if (window.mathVirtualKeyboard.visible && window.mathVirtualKeyboard.container === window.document.body) {\n          const kbdBounds = window.mathVirtualKeyboard.boundingRect;\n          const mathfieldBounds = this.host.getBoundingClientRect();\n          if (mathfieldBounds.bottom > kbdBounds.top) {\n            (_a3 = window.document.scrollingElement) == null ? void 0 : _a3.scrollBy(\n              0,\n              mathfieldBounds.bottom - kbdBounds.top + 8\n            );\n          }\n        }\n      }\n    }\n    if (this.dirty) render(this, { interactive: true });\n    const fieldBounds = this.field.getBoundingClientRect();\n    let caretPoint = null;\n    if (this.model.selectionIsCollapsed)\n      caretPoint = getCaretPoint(this.field);\n    else {\n      const selectionBounds = getSelectionBounds(this);\n      if (selectionBounds.length > 0) {\n        let maxRight = -Infinity;\n        let minTop = -Infinity;\n        for (const r of selectionBounds) {\n          if (r.right > maxRight) maxRight = r.right;\n          if (r.top < minTop) minTop = r.top;\n        }\n        caretPoint = {\n          x: maxRight + fieldBounds.left - this.field.scrollLeft,\n          y: minTop + fieldBounds.top - this.field.scrollTop,\n          height: 0\n        };\n      }\n    }\n    if (this.host && caretPoint) {\n      const hostBounds = this.host.getBoundingClientRect();\n      const y = caretPoint.y;\n      let top = this.host.scrollTop;\n      if (y < hostBounds.top) top = y - hostBounds.top + this.host.scrollTop;\n      else if (y > hostBounds.bottom)\n        top = y - hostBounds.bottom + this.host.scrollTop + caretPoint.height;\n      this.host.scroll({ top, left: 0 });\n    }\n    if (caretPoint) {\n      const x = caretPoint.x - window.scrollX;\n      let left = this.field.scrollLeft;\n      if (x < fieldBounds.left)\n        left = x - fieldBounds.left + this.field.scrollLeft - 20;\n      else if (x > fieldBounds.right)\n        left = x - fieldBounds.right + this.field.scrollLeft + 20;\n      this.field.scroll({\n        top: this.field.scrollTop,\n        // should always be 0\n        left\n      });\n    }\n  }\n  insert(s, options) {\n    if (typeof s !== \"string\") return false;\n    if (s.length === 0 && ((options == null ? void 0 : options.insertionMode) === \"insertBefore\" || (options == null ? void 0 : options.insertionMode) === \"insertAfter\"))\n      return false;\n    if (s.length === 0 && this.model.selectionIsCollapsed) return false;\n    this.flushInlineShortcutBuffer();\n    options = options != null ? options : { mode: \"math\" };\n    if (options.focus) this.focus();\n    if (options.feedback) {\n      if (globalThis.MathfieldElement.keypressVibration && canVibrate())\n        navigator.vibrate(HAPTIC_FEEDBACK_DURATION);\n      globalThis.MathfieldElement.playSound(\"keypress\");\n    }\n    if (s === \"\\\\\\\\\") {\n      addRowAfter(this.model);\n    } else if (s === \"&\") addColumnAfter(this.model);\n    else {\n      if (this.model.selectionIsCollapsed) {\n        ModeEditor.insert(this.model, s, __spreadValues({\n          style: this.model.at(this.model.position).style\n        }, options));\n      } else ModeEditor.insert(this.model, s, options);\n    }\n    this.snapshot(`insert-${this.model.at(this.model.position).type}`);\n    requestUpdate(this);\n    if (options.scrollIntoView) this.scrollIntoView();\n    return true;\n  }\n  /**\n   * Switch from the current mode to the new mode, if different.\n   * Prefix and suffix are optional strings to be inserted before and after\n   * the mode change, so prefix is interpreted with the current mode and\n   * suffix with the new mode.\n   */\n  switchMode(mode, prefix = \"\", suffix = \"\") {\n    if (this.model.mode === mode || !this.hasEditableContent || !this.contentEditable || this.disabled)\n      return;\n    const { model } = this;\n    const previousMode = model.mode;\n    model.mode = mode;\n    if (this.host && !this.host.dispatchEvent(\n      new Event(\"mode-change\", {\n        bubbles: true,\n        composed: true,\n        cancelable: true\n      })\n    )) {\n      model.mode = previousMode;\n      return;\n    }\n    model.mode = previousMode;\n    model.deferNotifications(\n      {\n        content: Boolean(suffix) || Boolean(prefix),\n        selection: true,\n        // Boolean(suffix) || Boolean(prefix),\n        type: \"insertText\"\n      },\n      () => {\n        let cursor = model.at(model.position);\n        const insertString = (s, options) => {\n          if (!s) return;\n          const atoms = model.mode === \"math\" ? parseLatex(parseMathString(s, { format: \"ascii-math\" })[1], {\n            context: this.context\n          }) : [...s].map((c) => new TextAtom(c, c, {}));\n          if (options.select) {\n            const end = cursor.parent.addChildrenAfter(atoms, cursor);\n            model.setSelection(\n              model.offsetOf(atoms[0].leftSibling),\n              model.offsetOf(end)\n            );\n          } else {\n            model.position = model.offsetOf(\n              cursor.parent.addChildrenAfter(atoms, cursor)\n            );\n          }\n          contentChanged = true;\n        };\n        const insertLatexGroup = (latex, options) => {\n          const atom = new LatexGroupAtom(latex);\n          cursor.parent.addChildAfter(atom, cursor);\n          if (options.select) {\n            model.setSelection(\n              model.offsetOf(atom.firstChild),\n              model.offsetOf(atom.lastChild)\n            );\n          } else model.position = model.offsetOf(atom.lastChild);\n          contentChanged = true;\n        };\n        const getContent = () => {\n          const format = mode === \"latex\" ? \"latex\" : mode === \"math\" ? \"plain-text\" : \"ascii-math\";\n          const selRange = range(model.selection);\n          let content = this.model.getValue(selRange, format);\n          const atoms = this.model.extractAtoms(selRange);\n          if (atoms.length === 1 && atoms[0].type === \"placeholder\")\n            content = suffix;\n          cursor = model.at(selRange[0]);\n          return content;\n        };\n        let contentChanged = false;\n        this.flushInlineShortcutBuffer();\n        this.stopCoalescingUndo();\n        complete(this, \"accept\");\n        if (model.selectionIsCollapsed) {\n          insertString(prefix, { select: false });\n          model.mode = mode;\n          if (mode === \"latex\") insertLatexGroup(suffix, { select: false });\n          else insertString(suffix, { select: false });\n        } else {\n          const content = getContent();\n          model.mode = mode;\n          if (mode === \"latex\") insertLatexGroup(content, { select: true });\n          else insertString(content, { select: true });\n        }\n        requestUpdate(this);\n        this.undoManager.snapshot(mode === \"latex\" ? \"insert-latex\" : \"insert\");\n        return contentChanged;\n      }\n    );\n    model.mode = mode;\n    window.mathVirtualKeyboard.update(makeProxy(this));\n  }\n  hasFocus() {\n    return !this.blurred;\n  }\n  focus(options) {\n    var _a3;\n    if (!this.hasFocus()) {\n      this.keyboardDelegate.focus();\n      this.connectToVirtualKeyboard();\n      this.onFocus();\n      this.model.announce(\"line\");\n    }\n    if (!((_a3 = options == null ? void 0 : options.preventScroll) != null ? _a3 : false)) this.scrollIntoView();\n  }\n  blur() {\n    this.disconnectFromVirtualKeyboard();\n    if (!this.hasFocus()) return;\n    this.keyboardDelegate.blur();\n  }\n  select() {\n    this.model.selection = { ranges: [[0, this.model.lastOffset]] };\n    this.focus();\n  }\n  applyStyle(inStyle, inOptions = {}) {\n    var _a3;\n    let range2;\n    let operation = \"set\";\n    let silenceNotifications = false;\n    if (isRange(inOptions)) range2 = inOptions;\n    else {\n      if (inOptions.operation === \"toggle\") operation = \"toggle\";\n      range2 = inOptions.range;\n      silenceNotifications = (_a3 = inOptions.silenceNotifications) != null ? _a3 : false;\n    }\n    if (range2) range2 = this.model.normalizeRange(range2);\n    if (range2 && range2[0] === range2[1]) range2 = void 0;\n    const style = validateStyle(this, inStyle);\n    if (range2 === void 0 && this.model.selectionIsCollapsed) {\n      if (operation === \"set\") {\n        const newStyle2 = __spreadValues({}, this.defaultStyle);\n        if (\"color\" in style) delete newStyle2.verbatimColor;\n        if (\"backgroundColor\" in style) delete newStyle2.verbatimBackgroundColor;\n        this.defaultStyle = __spreadValues(__spreadValues({}, newStyle2), style);\n        this.styleBias = \"none\";\n        return;\n      }\n      const newStyle = __spreadValues({}, this.defaultStyle);\n      for (const prop of Object.keys(style)) {\n        if (newStyle[prop] === style[prop]) {\n          if (prop === \"color\") delete newStyle.verbatimColor;\n          if (prop === \"backgroundColor\")\n            delete newStyle.verbatimBackgroundColor;\n          delete newStyle[prop];\n        } else newStyle[prop] = style[prop];\n      }\n      this.defaultStyle = newStyle;\n      this.styleBias = \"none\";\n      return;\n    }\n    this.model.deferNotifications(\n      { content: !silenceNotifications, type: \"insertText\" },\n      () => {\n        if (range2 === void 0) {\n          for (const range3 of this.model.selection.ranges)\n            applyStyle(this.model, range3, style, { operation });\n        } else applyStyle(this.model, range2, style, { operation });\n      }\n    );\n    requestUpdate(this);\n  }\n  toggleContextMenu() {\n    var _a3;\n    const menu = this.menu;\n    if (!menu.visible) return false;\n    if (menu.state === \"open\") {\n      menu.hide();\n      return true;\n    }\n    const caretBounds = (_a3 = getElementInfo(this, this.model.position)) == null ? void 0 : _a3.bounds;\n    if (!caretBounds) return false;\n    const location = { x: caretBounds.right, y: caretBounds.bottom };\n    menu.show({\n      target: this.element.querySelector(\"[part=container]\"),\n      location,\n      onDismiss: () => {\n        var _a4;\n        return (_a4 = this.element) == null ? void 0 : _a4.focus();\n      }\n    });\n    return true;\n  }\n  getPrompt(id) {\n    const prompt = this.model.findAtom(\n      (a) => a.type === \"prompt\" && a.placeholderId === id\n    );\n    console.assert(\n      prompt !== void 0,\n      `MathLive 0.101.0:  no prompts with matching ID found`\n    );\n    return prompt;\n  }\n  getPromptValue(id, format) {\n    const prompt = this.getPrompt(id);\n    if (!prompt) return \"\";\n    const first = this.model.offsetOf(prompt.firstChild);\n    const last = this.model.offsetOf(prompt.lastChild);\n    return this.model.getValue(first, last, format);\n  }\n  getPrompts(filter) {\n    return this.model.getAllAtoms().filter((a) => {\n      if (a.type !== \"prompt\") return false;\n      if (!filter) return true;\n      if (filter.id && a.placeholderId !== filter.id) return false;\n      if (filter.locked && a.locked !== filter.locked) return false;\n      if (filter.correctness === \"undefined\" && a.correctness) return false;\n      if (filter.correctness && a.correctness !== filter.correctness)\n        return false;\n      return true;\n    }).map((a) => a.placeholderId);\n  }\n  setPromptValue(id, value, insertOptions) {\n    if (value !== void 0) {\n      const prompt = this.getPrompt(id);\n      if (!prompt) {\n        console.error(`MathLive 0.101.0: unknown prompt ${id}`);\n        return;\n      }\n      const branchRange = this.model.getBranchRange(\n        this.model.offsetOf(prompt),\n        \"body\"\n      );\n      this.model.setSelection(branchRange);\n      this.insert(value, __spreadProps(__spreadValues({}, insertOptions), {\n        insertionMode: \"replaceSelection\"\n      }));\n    }\n    if (insertOptions == null ? void 0 : insertOptions.silenceNotifications)\n      this.valueOnFocus = this.getValue();\n    requestUpdate(this);\n  }\n  setPromptState(id, state, locked) {\n    const prompt = this.getPrompt(id);\n    if (!prompt) {\n      console.error(`MathLive 0.101.0: unknown prompt ${id}`);\n      return;\n    }\n    if (state === \"undefined\") prompt.correctness = void 0;\n    else if (typeof state === \"string\") prompt.correctness = state;\n    if (typeof locked === \"boolean\") {\n      prompt.locked = locked;\n      prompt.captureSelection = locked;\n    }\n    requestUpdate(this);\n  }\n  getPromptState(id) {\n    const prompt = this.getPrompt(id);\n    if (!prompt) {\n      console.error(`MathLive 0.101.0: unknown prompt ${id}`);\n      return [void 0, true];\n    }\n    return [prompt.correctness, prompt.locked];\n  }\n  getPromptRange(id) {\n    const prompt = this.getPrompt(id);\n    if (!prompt) {\n      console.error(`MathLive 0.101.0: unknown prompt ${id}`);\n      return [0, 0];\n    }\n    return this.model.getBranchRange(this.model.offsetOf(prompt), \"body\");\n  }\n  canUndo() {\n    return this.undoManager.canUndo();\n  }\n  canRedo() {\n    return this.undoManager.canRedo();\n  }\n  popUndoStack() {\n    this.undoManager.pop();\n  }\n  snapshot(op) {\n    var _a3;\n    if (this.undoManager.snapshot(op)) {\n      if (window.mathVirtualKeyboard.visible)\n        window.mathVirtualKeyboard.update(makeProxy(this));\n      (_a3 = this.host) == null ? void 0 : _a3.dispatchEvent(\n        new CustomEvent(\"undo-state-change\", {\n          bubbles: true,\n          composed: true,\n          detail: { type: \"snapshot\" }\n        })\n      );\n    }\n  }\n  stopCoalescingUndo() {\n    this.undoManager.stopCoalescing(this.model.selection);\n  }\n  stopRecording() {\n    this.undoManager.stopRecording();\n  }\n  startRecording() {\n    this.undoManager.startRecording();\n  }\n  undo() {\n    var _a3;\n    if (!this.undoManager.undo()) return;\n    (_a3 = this.host) == null ? void 0 : _a3.dispatchEvent(\n      new CustomEvent(\"undo-state-change\", {\n        bubbles: true,\n        composed: true,\n        detail: { type: \"undo\" }\n      })\n    );\n  }\n  redo() {\n    var _a3;\n    if (!this.undoManager.redo()) return;\n    (_a3 = this.host) == null ? void 0 : _a3.dispatchEvent(\n      new CustomEvent(\"undo-state-change\", {\n        bubbles: true,\n        composed: true,\n        detail: { type: \"redo\" }\n      })\n    );\n  }\n  resetUndo() {\n    var _a3;\n    (_a3 = this.undoManager) == null ? void 0 : _a3.reset();\n  }\n  onSelectionDidChange() {\n    var _a3, _b3;\n    const model = this.model;\n    this.keyboardDelegate.setValue(\n      model.getValue(model.selection, \"latex-expanded\")\n    );\n    if (model.selectionIsCollapsed) {\n      const latexGroup = getLatexGroup(model);\n      const pos = model.position;\n      const cursor = model.at(pos);\n      const mode = (_a3 = cursor.mode) != null ? _a3 : effectiveMode(this.options);\n      if (latexGroup && (pos < model.offsetOf(latexGroup.firstChild) - 1 || pos > model.offsetOf(latexGroup.lastChild) + 1)) {\n        complete(this, \"accept\", { mode });\n        model.position = model.offsetOf(cursor);\n      } else {\n        const sibling = model.at(pos + 1);\n        if ((sibling == null ? void 0 : sibling.type) === \"first\" && sibling.mode === \"latex\") {\n          model.position = pos + 1;\n        } else if (latexGroup && (sibling == null ? void 0 : sibling.mode) !== \"latex\") {\n          model.position = pos - 1;\n        } else {\n          this.switchMode(mode);\n        }\n      }\n    }\n    (_b3 = this.host) == null ? void 0 : _b3.dispatchEvent(\n      new Event(\"selection-change\", {\n        bubbles: true,\n        composed: true\n      })\n    );\n    if (window.mathVirtualKeyboard.visible)\n      window.mathVirtualKeyboard.update(makeProxy(this));\n    updateEnvironmentPopover(this);\n  }\n  onContentWillChange(options) {\n    var _a3, _b3, _c2;\n    return (_c2 = (_b3 = this.host) == null ? void 0 : _b3.dispatchEvent(\n      new InputEvent(\"beforeinput\", __spreadProps(__spreadValues({}, options), {\n        // To work around a bug in WebKit/Safari (the inputType property gets stripped), include the inputType as the 'data' property. (see #1843)\n        data: options.data ? options.data : (_a3 = options.inputType) != null ? _a3 : \"\",\n        cancelable: true,\n        bubbles: true,\n        composed: true\n      }))\n    )) != null ? _c2 : true;\n  }\n  onFocus() {\n    if (this.focusBlurInProgress || !this.blurred) return;\n    this.focusBlurInProgress = true;\n    this.blurred = false;\n    this.keyboardDelegate.focus();\n    this.stopCoalescingUndo();\n    render(this, { interactive: true });\n    this.valueOnFocus = this.model.getValue();\n    if (this.hasEditablePrompts && !this.model.at(this.model.anchor).parentPrompt)\n      this.executeCommand(\"moveToNextPlaceholder\");\n    this.focusBlurInProgress = false;\n  }\n  onBlur() {\n    var _a3, _b3, _c2;\n    if (this.focusBlurInProgress || this.blurred) return;\n    this.focusBlurInProgress = true;\n    this.stopCoalescingUndo();\n    this.blurred = true;\n    this.ariaLiveText.textContent = \"\";\n    hideSuggestionPopover(this);\n    if (this.model.getValue() !== this.valueOnFocus) {\n      (_a3 = this.host) == null ? void 0 : _a3.dispatchEvent(\n        new Event(\"change\", { bubbles: true, composed: true })\n      );\n    }\n    this.disconnectFromVirtualKeyboard();\n    (_b3 = this.host) == null ? void 0 : _b3.dispatchEvent(\n      new Event(\"blur\", {\n        bubbles: false,\n        // DOM 'focus' and 'blur' don't bubble\n        composed: true\n      })\n    );\n    (_c2 = this.host) == null ? void 0 : _c2.dispatchEvent(\n      new UIEvent(\"focusout\", {\n        bubbles: true,\n        // unlike 'blur', focusout does bubble\n        composed: true\n      })\n    );\n    requestUpdate(this);\n    this.focusBlurInProgress = false;\n    hideEnvironmentPopover();\n    if (mathfield_element_default.restoreFocusWhenDocumentFocused) {\n      const controller = new AbortController();\n      const signal = controller.signal;\n      document.addEventListener(\n        \"visibilitychange\",\n        () => {\n          if (document.visibilityState === \"hidden\") {\n            document.addEventListener(\n              \"visibilitychange\",\n              () => {\n                if (isValidMathfield(this) && document.visibilityState === \"visible\")\n                  this.focus({ preventScroll: true });\n              },\n              { once: true, signal }\n            );\n          }\n        },\n        { once: true, signal }\n      );\n      document.addEventListener(\"focusin\", () => controller.abort(), {\n        once: true\n      });\n    }\n  }\n  onInput(text) {\n    onInput(this, text);\n  }\n  onKeystroke(evt) {\n    return onKeystroke(this, evt);\n  }\n  onCompositionStart(_composition) {\n    this.model.deleteAtoms(range(this.model.selection));\n    const caretPoint = getCaretPoint(this.field);\n    if (!caretPoint) return;\n    requestAnimationFrame(() => {\n      render(this);\n      this.keyboardDelegate.moveTo(\n        caretPoint.x,\n        caretPoint.y - caretPoint.height\n      );\n    });\n  }\n  onCompositionUpdate(composition) {\n    updateComposition(this.model, composition);\n    requestUpdate(this);\n  }\n  onCompositionEnd(composition) {\n    removeComposition(this.model);\n    onInput(this, composition, { simulateKeystroke: true });\n  }\n  onCut(ev) {\n    if (!this.isSelectionEditable) {\n      this.model.announce(\"plonk\");\n      return;\n    }\n    if (this.model.contentWillChange({ inputType: \"deleteByCut\" })) {\n      this.stopCoalescingUndo();\n      if (ev.clipboardData) ModeEditor.onCopy(this, ev);\n      else ModeEditor.copyToClipboard(this, \"latex\");\n      deleteRange(this.model, range(this.model.selection), \"deleteByCut\");\n      this.snapshot(\"cut\");\n      requestUpdate(this);\n    }\n  }\n  onCopy(ev) {\n    if (ev.clipboardData) ModeEditor.onCopy(this, ev);\n    else ModeEditor.copyToClipboard(this, \"latex\");\n  }\n  onPaste(ev) {\n    let result = this.isSelectionEditable;\n    if (result) {\n      result = ModeEditor.onPaste(\n        this.model.at(this.model.position).mode,\n        this,\n        ev.clipboardData\n      );\n    }\n    if (!result) this.model.announce(\"plonk\");\n    ev.preventDefault();\n    ev.stopPropagation();\n    return result;\n  }\n  onGeometryChange() {\n    var _a3;\n    (_a3 = this._menu) == null ? void 0 : _a3.hide();\n    updateSuggestionPopoverPosition(this);\n    updateEnvironmentPopover(this);\n  }\n  onWheel(ev) {\n    const wheelDelta = 5 * ev.deltaX;\n    if (!Number.isFinite(wheelDelta) || wheelDelta === 0) return;\n    const field = this.field;\n    if (wheelDelta < 0 && field.scrollLeft === 0) return;\n    if (wheelDelta > 0 && field.offsetWidth + field.scrollLeft >= field.scrollWidth)\n      return;\n    field.scrollBy({ top: 0, left: wheelDelta });\n    ev.preventDefault();\n    ev.stopPropagation();\n  }\n  getHTMLElement(atom) {\n    let target = atom;\n    while (!target.id && target.hasChildren) target = atom.children[0];\n    return this.field.querySelector(\n      `[data-atom-id=\"${target.id}\"]`\n    );\n  }\n  get context() {\n    var _a3, _b3;\n    return {\n      registers: (_a3 = this.options.registers) != null ? _a3 : {},\n      smartFence: this.smartFence,\n      letterShapeStyle: this.letterShapeStyle,\n      minFontScale: this.minFontScale,\n      maxMatrixCols: this.maxMatrixCols,\n      placeholderSymbol: (_b3 = this.options.placeholderSymbol) != null ? _b3 : \"\\u25A2\",\n      colorMap: (name) => this.colorMap(name),\n      backgroundColorMap: (name) => this.backgroundColorMap(name),\n      getMacro: (token) => getMacroDefinition(\n        token,\n        this.options.macros\n      ),\n      atomIdsSettings: { seed: \"random\", groupNumbers: false }\n    };\n  }\n};\n\n// src/editor/speech.ts\nregister2(\n  {\n    speak: (mathfield, scope, options) => {\n      return speak(mathfield, scope, options);\n    }\n  },\n  { target: \"mathfield\" }\n);\nfunction speak(mathfield, scope, speakOptions) {\n  var _a3;\n  speakOptions = speakOptions != null ? speakOptions : { withHighlighting: false };\n  const { model } = mathfield;\n  function getAtoms(scope2) {\n    let result = null;\n    switch (scope2) {\n      case \"all\":\n        result = model.root;\n        break;\n      case \"selection\":\n        result = model.getAtoms(model.selection);\n        break;\n      case \"left\": {\n        result = model.getAtoms(\n          model.offsetOf(model.at(model.position).leftSibling),\n          model.position\n        );\n        break;\n      }\n      case \"right\": {\n        result = model.getAtoms(\n          model.position,\n          model.offsetOf(model.at(model.position).rightSibling)\n        );\n        break;\n      }\n      case \"group\":\n        result = model.getAtoms(model.getSiblingsRange(model.position));\n        break;\n      case \"parent\": {\n        const { parent } = model.at(model.position);\n        if (parent == null ? void 0 : parent.parent) result = parent;\n        else result = model.root;\n        break;\n      }\n      default:\n        result = model.root;\n    }\n    return result;\n  }\n  function getFailedSpeech(scope2) {\n    let result = \"\";\n    switch (scope2) {\n      case \"all\":\n        console.error(\"Internal failure: speak all failed\");\n        break;\n      case \"selection\":\n        result = \"no selection\";\n        break;\n      case \"left\":\n        result = \"at start\";\n        break;\n      case \"right\":\n        result = \"at end\";\n        break;\n      case \"group\":\n        console.error(\"Internal failure: speak group failed\");\n        break;\n      case \"parent\":\n        result = \"no parent\";\n        break;\n      default:\n        console.error('unknown speak_ param value: \"' + scope2 + '\"');\n        break;\n    }\n    return result;\n  }\n  const mfe = globalThis.MathfieldElement;\n  const atoms = getAtoms(scope);\n  if (atoms === null) {\n    (_a3 = mfe.speakHook) == null ? void 0 : _a3.call(mfe, getFailedSpeech(scope));\n    return false;\n  }\n  if (speakOptions.withHighlighting || mfe.speechEngine === \"amazon\") {\n    mfe.textToSpeechMarkup = globalThis.sre && mfe.textToSpeechRules === \"sre\" ? \"ssml_step\" : \"ssml\";\n  }\n  const text = atomToSpeakableText(atoms);\n  if (isBrowser() && speakOptions.withHighlighting) {\n    globalMathLive().readAloudMathfield = mathfield;\n    render(mathfield, { forHighlighting: true });\n    if (mfe.readAloudHook) mfe.readAloudHook(mathfield.field, text);\n  } else if (mfe.speakHook) mfe.speakHook(text);\n  return false;\n}\nfunction defaultSpeakHook(text) {\n  var _a3, _b3;\n  if (!isBrowser()) {\n    console.log(\"Speak:\", text);\n    return;\n  }\n  const mfe = globalThis.MathfieldElement;\n  if (!mfe.speechEngine || mfe.speechEngine === \"local\") {\n    const utterance = new SpeechSynthesisUtterance(text);\n    globalThis.speechSynthesis.speak(utterance);\n  } else if (mfe.speechEngine === \"amazon\") {\n    if (!(\"AWS\" in window)) {\n      console.error(\n        `MathLive 0.101.0: AWS SDK not loaded. See https://www.npmjs.com/package/aws-sdk`\n      );\n    } else {\n      const polly = new globalThis.AWS.Polly({ apiVersion: \"2016-06-10\" });\n      const parameters = {\n        OutputFormat: \"mp3\",\n        VoiceId: (_a3 = mfe.speechEngineVoice) != null ? _a3 : \"Joanna\",\n        Engine: [\n          \"Amy\",\n          \"Emma\",\n          \"Brian\",\n          \"Ivy\",\n          \"Joanna\",\n          \"Kendra\",\n          \"Kimberly\",\n          \"Salli\",\n          \"Joey\",\n          \"Justin\",\n          \"Matthew\"\n        ].includes((_b3 = mfe.speechEngineVoice) != null ? _b3 : \"Joanna\") ? \"neural\" : \"standard\",\n        // SampleRate: '24000',\n        Text: text,\n        TextType: \"ssml\"\n        // SpeechMarkTypes: ['ssml]'\n      };\n      polly.synthesizeSpeech(parameters, (err, data) => {\n        if (err) {\n          console.trace(\n            `MathLive 0.101.0: \\`polly.synthesizeSpeech()\\` error: ${err}`\n          );\n        } else if (data == null ? void 0 : data.AudioStream) {\n          const uInt8Array = new Uint8Array(data.AudioStream);\n          const blob = new Blob([uInt8Array.buffer], { type: \"audio/mpeg\" });\n          const url = URL.createObjectURL(blob);\n          const audioElement = new Audio(url);\n          audioElement.play().catch((error) => console.error(error));\n        } else console.log(\"polly.synthesizeSpeech():\", data);\n      });\n    }\n  } else if (mfe.speechEngine === \"google\") {\n    console.error(\n      `MathLive 0.101.0: The Google speech engine is not supported yet. Please come again.`\n    );\n  }\n}\n\n// src/editor/speech-read-aloud.ts\nfunction removeHighlight(element) {\n  if (!element) return;\n  element.classList.remove(\"ML__highlight\");\n  if (element.children)\n    for (const child of element.children) removeHighlight(child);\n}\nfunction highlightAtomID(element, atomID) {\n  var _a3;\n  if (!element) return;\n  if (!atomID || ((_a3 = element.dataset) == null ? void 0 : _a3.atomId) === atomID) {\n    element.classList.add(\"ML__highlight\");\n    if (element.children && element.children.length > 0) {\n      [...element.children].forEach((x) => {\n        if (x instanceof HTMLElement) highlightAtomID(x);\n      });\n    }\n  } else {\n    element.classList.remove(\"ML__highlight\");\n    if (element.children && element.children.length > 0) {\n      [...element.children].forEach((x) => {\n        if (x instanceof HTMLElement) highlightAtomID(x, atomID);\n      });\n    }\n  }\n}\nfunction defaultReadAloudHook(element, text) {\n  var _a3;\n  if (!isBrowser()) return;\n  if (globalThis.MathfieldElement.speechEngine !== \"amazon\") {\n    console.error(\n      `MathLive 0.101.0: Use Amazon TTS Engine for synchronized highlighting`\n    );\n    if (typeof globalThis.MathfieldElement.speakHook === \"function\")\n      globalThis.MathfieldElement.speakHook(text);\n    return;\n  }\n  if (!globalThis.AWS) {\n    console.error(\n      `MathLive 0.101.0: AWS SDK not loaded. See https://www.npmjs.com/package/aws-sdk`\n    );\n    return;\n  }\n  const polly = new globalThis.AWS.Polly({ apiVersion: \"2016-06-10\" });\n  const parameters = {\n    OutputFormat: \"json\",\n    VoiceId: (_a3 = globalThis.MathfieldElement.speechEngineVoice) != null ? _a3 : \"Joanna\",\n    Engine: \"standard\",\n    // The neural engine does not appear to support ssml marks\n    Text: text,\n    TextType: \"ssml\",\n    SpeechMarkTypes: [\"ssml\"]\n  };\n  globalMathLive().readAloudElement = element;\n  polly.synthesizeSpeech(parameters, (err, data) => {\n    if (err) {\n      console.trace(\n        `MathLive 0.101.0: \\`polly.synthesizeSpeech()\\` error: ${err}`\n      );\n      return;\n    }\n    if (!(data == null ? void 0 : data.AudioStream)) {\n      console.log(\"polly.synthesizeSpeech():\", data);\n      return;\n    }\n    const response = new TextDecoder(\"utf-8\").decode(\n      new Uint8Array(data.AudioStream)\n    );\n    globalMathLive().readAloudMarks = response.split(\"\\n\").map((x) => x ? JSON.parse(x) : {});\n    globalMathLive().readAloudTokens = [];\n    for (const mark of globalMathLive().readAloudMarks)\n      if (mark.value) globalMathLive().readAloudTokens.push(mark.value);\n    globalMathLive().readAloudCurrentMark = \"\";\n    parameters.OutputFormat = \"mp3\";\n    parameters.SpeechMarkTypes = [];\n    polly.synthesizeSpeech(parameters, (err2, data2) => {\n      if (err2) {\n        console.trace(\n          `MathLive 0.101.0: \\`polly.synthesizeSpeech(\"${text}\") error:${err2}`\n        );\n        return;\n      }\n      if (!(data2 == null ? void 0 : data2.AudioStream)) return;\n      const uInt8Array = new Uint8Array(data2.AudioStream);\n      const blob = new Blob([uInt8Array.buffer], {\n        type: \"audio/mpeg\"\n      });\n      const url = URL.createObjectURL(blob);\n      const global = globalMathLive();\n      if (!global.readAloudAudio) {\n        global.readAloudAudio = new Audio();\n        global.readAloudAudio.addEventListener(\"ended\", () => {\n          const mathfield = global.readAloudMathfield;\n          global.readAloudStatus = \"ended\";\n          document.body.dispatchEvent(\n            new Event(\"read-aloud-status-change\", {\n              bubbles: true,\n              composed: true\n            })\n          );\n          if (mathfield) {\n            render(mathfield);\n            global.readAloudElement = null;\n            global.readAloudMathfield = null;\n            global.readAloudTokens = [];\n            global.readAloudMarks = [];\n            global.readAloudCurrentMark = \"\";\n          } else removeHighlight(global.readAloudElement);\n        });\n        global.readAloudAudio.addEventListener(\"timeupdate\", () => {\n          let value = \"\";\n          const target = global.readAloudAudio.currentTime * 1e3 + 100;\n          for (const mark of global.readAloudMarks)\n            if (mark.time < target) value = mark.value;\n          if (global.readAloudCurrentMark !== value) {\n            global.readAloudCurrentToken = value;\n            if (value && value === global.readAloudFinalToken)\n              global.readAloudAudio.pause();\n            else {\n              global.readAloudCurrentMark = value;\n              highlightAtomID(\n                global.readAloudElement,\n                global.readAloudCurrentMark\n              );\n            }\n          }\n        });\n      } else global.readAloudAudio.pause();\n      global.readAloudAudio.src = url;\n      global.readAloudStatus = \"playing\";\n      document.body.dispatchEvent(\n        new Event(\"read-aloud-status-change\", {\n          bubbles: true,\n          composed: true\n        })\n      );\n      global.readAloudAudio.play();\n    });\n  });\n}\n\n// src/public/mathfield-element.ts\nif (!isBrowser()) {\n  console.error(\n    `MathLive 0.101.0: this version of the MathLive library is for use in the browser. A subset of the API is available on the server side in the \"mathlive-ssr\" library. If using server side rendering (with React for example) you may want to do a dynamic import of the MathLive library inside a \\`useEffect()\\` call.`\n  );\n}\nvar gDeferredState = /* @__PURE__ */ new WeakMap();\nvar AUDIO_FEEDBACK_VOLUME = 0.5;\nvar DEPRECATED_OPTIONS = {\n  letterShapeStyle: \"mf.letterShapeStyle = ...\",\n  horizontalSpacingScale: 'Removed. Use `\"thinmuskip\"`, `\"medmuskip\"`, and `\"thickmuskip\"` registers ',\n  macros: \"mf.macros = ...\",\n  registers: \"mf.registers = ...\",\n  backgroundColorMap: \"mf.backgroundColorMap = ...\",\n  colorMap: \"mf.colorMap = ...\",\n  enablePopover: \"mf.popoverPolicy = ...\",\n  mathModeSpace: \"mf.mathModeSpace = ...\",\n  placeholderSymbol: \"mf.placeholderSymbol = ...\",\n  readOnly: \"mf.readOnly = ...\",\n  removeExtraneousParentheses: \"mf.removeExtraneousParentheses = ...\",\n  scriptDepth: \"mf.scriptDepth = ...\",\n  smartFence: \"mf.smartFence = ...\",\n  smartMode: \"mf.smartMode = ...\",\n  smartSuperscript: \"mf.smartSuperscript = ...\",\n  inlineShortcutTimeout: \"mf.inlineShortcutTimeout = ...\",\n  inlineShortcuts: \"mf.inlineShortcuts = ...\",\n  keybindings: \"mf.keybindings = ...\",\n  virtualKeyboardMode: \"mf.mathVirtualKeyboardPolicy = ...\",\n  customVirtualKeyboardLayers: \"mathVirtualKeyboard.layers = ...\",\n  customVirtualKeyboards: \"mathVirtualKeyboard.layouts = ...\",\n  keypressSound: \"mathVirtualKeyboard.keypressSound = ...\",\n  keypressVibration: \"mathVirtualKeyboard.keypressVibration = ...\",\n  plonkSound: \"mathVirtualKeyboard.plonkSound = ...\",\n  virtualKeyboardContainer: \"mathVirtualKeyboard.container = ...\",\n  virtualKeyboardLayout: \"mathVirtualKeyboard.alphabeticLayout = ...\",\n  virtualKeyboardTheme: \"No longer supported\",\n  virtualKeyboardToggleGlyph: \"No longer supported\",\n  virtualKeyboardToolbar: \"mathVirtualKeyboard.editToolbar = ...\",\n  virtualKeyboards: \"Use `mathVirtualKeyboard.layouts`\",\n  speechEngine: \"`MathfieldElement.speechEngine`\",\n  speechEngineRate: \"`MathfieldElement.speechEngineRate`\",\n  speechEngineVoice: \"`MathfieldElement.speechEngineVoice`\",\n  textToSpeechMarkup: \"`MathfieldElement.textToSpeechMarkup`\",\n  textToSpeechRules: \"`MathfieldElement.textToSpeechRules`\",\n  textToSpeechRulesOptions: \"`MathfieldElement.textToSpeechRulesOptions`\",\n  readAloudHook: \"`MathfieldElement.readAloudHook`\",\n  speakHook: \"`MathfieldElement.speakHook`\",\n  computeEngine: \"`MathfieldElement.computeEngine`\",\n  fontsDirectory: \"`MathfieldElement.fontsDirectory`\",\n  soundsDirectory: \"`MathfieldElement.soundsDirectory`\",\n  createHTML: \"`MathfieldElement.createHTML`\",\n  onExport: \"`mf.onExport`\",\n  onInlineShortcut: \"`mf.onInlineShortcut`\",\n  onScrollIntoView: \"`mf.onScrollIntoView`\",\n  locale: \"MathfieldElement.locale = ...\",\n  strings: \"MathfieldElement.strings = ...\",\n  decimalSeparator: \"MathfieldElement.decimalSeparator = ...\",\n  fractionNavigationOrder: \"MathfieldElement.fractionNavigationOrder = ...\"\n};\nvar _MathfieldElement = class _MathfieldElement extends HTMLElement {\n  /**\n       * To create programmatically a new mathfield use:\n       *\n       ```javascript\n      let mfe = new MathfieldElement();\n  \n      // Set initial value and options\n      mfe.value = \"\\\\frac{\\\\sin(x)}{\\\\cos(x)}\";\n  \n      // Options can be set either as an attribute (for simple options)...\n      mfe.setAttribute(\"letter-shape-style\", \"french\");\n  \n      // ... or using properties\n      mfe.letterShapeStyle = \"french\";\n  \n      // Attach the element to the DOM\n      document.body.appendChild(mfe);\n      ```\n      */\n  constructor(options) {\n    super();\n    /** @internal */\n    this._observer = null;\n    if (options) {\n      const warnings = [];\n      for (const key of Object.keys(options)) {\n        if (DEPRECATED_OPTIONS[key]) {\n          if (DEPRECATED_OPTIONS[key].startsWith(\"mf.\")) {\n            if (!DEPRECATED_OPTIONS[key].startsWith(`mf.${key}`)) {\n              const newName = DEPRECATED_OPTIONS[key].match(/([a-zA-Z]+) =/);\n              warnings.push(\n                `Option \\`${key}\\` has been renamed \\`${newName[1]}\\``\n              );\n            } else {\n              warnings.push(\n                `Option \\`${key}\\` cannot be used as a constructor option. Use ${DEPRECATED_OPTIONS[key]}`\n              );\n            }\n          } else {\n            warnings.push(\n              `Option \\`${key}\\` cannot be used as a constructor option. Use ${DEPRECATED_OPTIONS[key]}`\n            );\n          }\n        }\n      }\n      if (warnings.length > 0) {\n        console.group(\n          `%cMathLive 0.101.0: %cInvalid Options`,\n          \"color:#12b; font-size: 1.1rem\",\n          \"color:#db1111; font-size: 1.1rem\"\n        );\n        console.warn(\n          `Some of the options passed to \\`new MathfieldElement(...)\\` are invalid. \n          See mathfield/changelog/ for details.`\n        );\n        for (const warning of warnings) console.warn(warning);\n        console.groupEnd();\n      }\n    }\n    if (isElementInternalsSupported()) {\n      this._internals = this.attachInternals();\n      this._internals[\"role\"] = \"math\";\n      this._internals.ariaLabel = \"math input field\";\n      this._internals.ariaMultiLine = \"false\";\n    }\n    this.attachShadow({ mode: \"open\", delegatesFocus: true });\n    if (this.shadowRoot && \"adoptedStyleSheets\" in this.shadowRoot) {\n      this.shadowRoot.adoptedStyleSheets = [\n        getStylesheet(\"core\"),\n        getStylesheet(\"mathfield\"),\n        getStylesheet(\"mathfield-element\"),\n        getStylesheet(\"ui\"),\n        getStylesheet(\"menu\")\n      ];\n      this.shadowRoot.appendChild(document.createElement(\"span\"));\n      const slot = document.createElement(\"slot\");\n      slot.style.display = \"none\";\n      this.shadowRoot.appendChild(slot);\n    } else {\n      this.shadowRoot.innerHTML = \"<style>\" + getStylesheetContent(\"core\") + getStylesheetContent(\"mathfield\") + getStylesheetContent(\"mathfield-element\") + getStylesheetContent(\"ui\") + getStylesheetContent(\"menu\") + '</style><span></span><slot style=\"display:none\"></slot>';\n    }\n    if (options) this._setOptions(options);\n  }\n  static get formAssociated() {\n    return isElementInternalsSupported();\n  }\n  /**\n   * Private lifecycle hooks.\n   * If adding a 'boolean' attribute, add its default value to getOptionsFromAttributes\n   * @internal\n   */\n  static get optionsAttributes() {\n    return {\n      \"default-mode\": \"string\",\n      \"letter-shape-style\": \"string\",\n      \"min-font-scale\": \"number\",\n      \"max-matrix-cols\": \"number\",\n      \"popover-policy\": \"string\",\n      \"math-mode-space\": \"string\",\n      \"read-only\": \"boolean\",\n      \"remove-extraneous-parentheses\": \"on/off\",\n      \"smart-fence\": \"on/off\",\n      \"smart-mode\": \"on/off\",\n      \"smart-superscript\": \"on/off\",\n      \"inline-shortcut-timeout\": \"string\",\n      \"script-depth\": \"string\",\n      \"placeholder\": \"string\",\n      \"virtual-keyboard-target-origin\": \"string\",\n      \"math-virtual-keyboard-policy\": \"string\"\n    };\n  }\n  /**\n   * Custom elements lifecycle hooks\n   * @internal\n   */\n  static get observedAttributes() {\n    return [\n      ...Object.keys(this.optionsAttributes),\n      \"contenteditable\",\n      // Global attribute\n      \"disabled\",\n      // Global attribute\n      \"readonly\",\n      // A semi-global attribute (not all standard elements support it, but some do)\n      \"read-only\"\n      // Alternate spelling for `readonly`\n    ];\n  }\n  /**\n   * A URL fragment pointing to the directory containing the fonts\n   * necessary to render a formula.\n   *\n   * These fonts are available in the `/dist/fonts` directory of the SDK.\n   *\n   * Customize this value to reflect where you have copied these fonts,\n   * or to use the CDN version.\n   *\n   * The default value is `\"./fonts\"`. Use `null` to prevent\n   * any fonts from being loaded.\n   *\n   * Changing this setting after the mathfield has been created will have\n   * no effect.\n   *\n   * ```javascript\n   * {\n   *      // Use the CDN version\n   *      fontsDirectory: ''\n   * }\n   * ```\n   *\n   * ```javascript\n   * {\n   *      // Use a directory called \"fonts\", located next to the\n   *      // `mathlive.js` (or `mathlive.mjs`) file.\n   *      fontsDirectory: './fonts'\n   * }\n   * ```\n   *\n   * ```javascript\n   * {\n   *      // Use a directory located at the root of your website\n   *      fontsDirectory: 'https://example.com/fonts'\n   * }\n   * ```\n   *\n   */\n  static get fontsDirectory() {\n    return this._fontsDirectory;\n  }\n  static set fontsDirectory(value) {\n    if (value !== this._fontsDirectory) {\n      this._fontsDirectory = value;\n      reloadFonts();\n    }\n  }\n  /** @internal */\n  get fontsDirectory() {\n    throw new Error(\"Use MathfieldElement.fontsDirectory instead\");\n  }\n  /** @internal */\n  set fontsDirectory(_value) {\n    throw new Error(\"Use MathfieldElement.fontsDirectory instead\");\n  }\n  /**\n   * A URL fragment pointing to the directory containing the optional\n   * sounds used to provide feedback while typing.\n   *\n   * Some default sounds are available in the `/dist/sounds` directory of the SDK.\n   *\n   * Use `null` to prevent any sound from being loaded.\n   * @category Virtual Keyboard\n   */\n  static get soundsDirectory() {\n    return this._soundsDirectory;\n  }\n  static set soundsDirectory(value) {\n    this._soundsDirectory = value;\n    this.audioBuffers = {};\n  }\n  /** @internal */\n  get soundsDirectory() {\n    throw new Error(\"Use MathfieldElement.soundsDirectory instead\");\n  }\n  /** @internal */\n  set soundsDirectory(_value) {\n    throw new Error(\"Use MathfieldElement.soundsDirectory instead\");\n  }\n  /**\n   * When a key on the virtual keyboard is pressed, produce a short audio\n   * feedback.\n   *\n   * If the property is set to a `string`, the same sound is played in all\n   * cases. Otherwise, a distinct sound is played:\n   *\n   * -   `delete` a sound played when the delete key is pressed\n   * -   `return` ... when the return/tab key is pressed\n   * -   `spacebar` ... when the spacebar is pressed\n   * -   `default` ... when any other key is pressed. This property is required,\n   *     the others are optional. If they are missing, this sound is played as\n   *     well.\n   *\n   * The value of the properties should be either a string, the name of an\n   * audio file in the `soundsDirectory` directory or `null` to suppress the sound.\n   * @category Virtual Keyboard\n   */\n  static get keypressSound() {\n    return this._keypressSound;\n  }\n  static set keypressSound(value) {\n    var _a3, _b3, _c2;\n    this.audioBuffers = {};\n    if (value === null) {\n      this._keypressSound = {\n        spacebar: null,\n        return: null,\n        delete: null,\n        default: null\n      };\n    } else if (typeof value === \"string\") {\n      this._keypressSound = {\n        spacebar: value,\n        return: value,\n        delete: value,\n        default: value\n      };\n    } else if (typeof value === \"object\" && \"default\" in value) {\n      this._keypressSound = {\n        spacebar: (_a3 = value.spacebar) != null ? _a3 : value.default,\n        return: (_b3 = value.return) != null ? _b3 : value.default,\n        delete: (_c2 = value.delete) != null ? _c2 : value.default,\n        default: value.default\n      };\n    }\n  }\n  /**\n   * Sound played to provide feedback when a command has no effect, for example\n   * when pressing the spacebar at the root level.\n   *\n   * The property is either:\n   * - a string, the name of an audio file in the `soundsDirectory` directory\n   * - null to turn off the sound\n   */\n  static get plonkSound() {\n    return this._plonkSound;\n  }\n  static set plonkSound(value) {\n    this.audioBuffers = {};\n    this._plonkSound = value;\n  }\n  /** @internal */\n  static get audioContext() {\n    if (!this._audioContext) this._audioContext = new AudioContext();\n    return this._audioContext;\n  }\n  // @todo https://github.com/microsoft/TypeScript/issues/30024\n  /**\n   * Indicates which speech engine to use for speech output.\n   *\n   * Use `local` to use the OS-specific TTS engine.\n   *\n   * Use `amazon` for Amazon Text-to-Speech cloud API. You must include the\n   * AWS API library and configure it with your API key before use.\n   *\n   * **See**\n   * {@link mathfield/guides/speech/ | Guide: Speech}\n   */\n  static get speechEngine() {\n    return this._speechEngine;\n  }\n  static set speechEngine(value) {\n    this._speechEngine = value;\n  }\n  /**\n   * Sets the speed of the selected voice.\n   *\n   * One of `x-slow`, `slow`, `medium`, `fast`, `x-fast` or a value as a\n   * percentage.\n   *\n   * Range is `20%` to `200%` For example `200%` to indicate a speaking rate\n   * twice the default rate.\n   */\n  static get speechEngineRate() {\n    return this._speechEngineRate;\n  }\n  static set speechEngineRate(value) {\n    this._speechEngineRate = value;\n  }\n  /**\n   * Indicates the voice to use with the speech engine.\n   *\n   * This is dependent on the speech engine. For Amazon Polly, see here:\n   * https://docs.aws.amazon.com/polly/latest/dg/voicelist.html\n   *\n   */\n  static get speechEngineVoice() {\n    return this._speechEngineVoice;\n  }\n  static set speechEngineVoice(value) {\n    this._speechEngineVoice = value;\n  }\n  /**\n   * The markup syntax to use for the output of conversion to spoken text.\n   *\n   * Possible values are `ssml` for the SSML markup or `mac` for the macOS\n   * markup, i.e. `&#91;&#91;ltr&#93;&#93;`.\n   *\n   */\n  static get textToSpeechMarkup() {\n    return this._textToSpeechMarkup;\n  }\n  static set textToSpeechMarkup(value) {\n    this._textToSpeechMarkup = value;\n  }\n  /**\n   * Specify which set of text to speech rules to use.\n   *\n   * A value of `mathlive` indicates that the simple rules built into MathLive\n   * should be used.\n   *\n   * A value of `sre` indicates that the Speech Rule Engine from Volker Sorge\n   * should be used.\n   *\n   * **(Caution)** SRE is not included or loaded by MathLive. For this option to\n   * work SRE should be loaded separately.\n   *\n   * **See**\n   * {@link mathfield/guides/speech/ | Guide: Speech}\n   */\n  static get textToSpeechRules() {\n    return this._textToSpeechRules;\n  }\n  static set textToSpeechRules(value) {\n    this._textToSpeechRules = value;\n  }\n  /**\n   * A set of key/value pairs that can be used to configure the speech rule\n   * engine.\n   *\n   * Which options are available depends on the speech rule engine in use.\n   * There are no options available with MathLive's built-in engine. The\n   * options for the SRE engine are documented\n   * {@link https://github.com/zorkow/speech-rule-engine | here}\n   */\n  static get textToSpeechRulesOptions() {\n    return this._textToSpeechRulesOptions;\n  }\n  static set textToSpeechRulesOptions(value) {\n    this._textToSpeechRulesOptions = value;\n  }\n  /**\n   * The locale (language + region) to use for string localization.\n   *\n   * If none is provided, the locale of the browser is used.\n   * @category Localization\n   *\n   */\n  static get locale() {\n    return l10n.locale;\n  }\n  static set locale(value) {\n    if (value === \"auto\") value = navigator.language.slice(0, 5);\n    l10n.locale = value;\n  }\n  /** @internal */\n  get locale() {\n    throw new Error(\"Use MathfieldElement.locale instead\");\n  }\n  /** @internal */\n  set locale(_value) {\n    throw new Error(\"Use MathfieldElement.locale instead\");\n  }\n  /**\n  * An object whose keys are a locale string, and whose values are an object of\n  * string identifier to localized string.\n  *\n  * **Example**\n  *\n  ```js example\n  mf.strings = {\n    \"fr-CA\": {\n        \"tooltip.undo\": \"Annuler\",\n        \"tooltip.redo\": \"Refaire\",\n    }\n  }\n  ```\n  *\n  * If the locale is already supported, this will override the existing\n  * strings. If the locale is not supported, it will be added.\n  *\n  * @category Localization\n  */\n  static get strings() {\n    return l10n.strings;\n  }\n  static set strings(value) {\n    l10n.merge(value);\n  }\n  /** @internal */\n  get strings() {\n    throw new Error(\"Use MathfieldElement.strings instead\");\n  }\n  /** @internal */\n  set strings(_val) {\n    throw new Error(\"Use MathfieldElement.strings instead\");\n  }\n  /**\n   * The symbol used to separate the integer part from the fractional part of a\n   * number.\n   *\n   * When `\",\"` is used, the corresponding LaTeX string is `{,}`, in order\n   * to ensure proper spacing (otherwise an extra gap is displayed after the\n   * comma).\n   *\n   * This affects:\n   * - what happens when the `,` key is pressed (if `decimalSeparator` is\n   * `\",\"`, the `{,}` LaTeX string is inserted when following some digits)\n   * - the label and behavior of the \".\" key in the default virtual keyboard\n   *\n   * **Default**: `\".\"`\n   * @category Localization\n   */\n  static get decimalSeparator() {\n    return this._decimalSeparator;\n  }\n  static set decimalSeparator(value) {\n    this._decimalSeparator = value;\n    if (this._computeEngine) {\n      this._computeEngine.latexOptions.decimalMarker = this.decimalSeparator === \",\" ? \"{,}\" : \".\";\n    }\n  }\n  /** @internal */\n  get decimalSeparator() {\n    throw new Error(\"Use MathfieldElement.decimalSeparator instead\");\n  }\n  /** @internal */\n  set decimalSeparator(_val) {\n    throw new Error(\"Use MathfieldElement.decimalSeparator instead\");\n  }\n  /**\n   * A custom compute engine instance. If none is provided, a default one is\n   * used. If `null` is specified, no compute engine is used.\n   */\n  static get computeEngine() {\n    var _a3, _b3;\n    if (this._computeEngine === void 0) {\n      const ComputeEngineCtor = (_a3 = window[Symbol.for(\"io.cortexjs.compute-engine\")]) == null ? void 0 : _a3.ComputeEngine;\n      if (!ComputeEngineCtor) return null;\n      this._computeEngine = new ComputeEngineCtor();\n      if (this._computeEngine && this.decimalSeparator === \",\")\n        this._computeEngine.latexOptions.decimalMarker = \"{,}\";\n    }\n    return (_b3 = this._computeEngine) != null ? _b3 : null;\n  }\n  static set computeEngine(value) {\n    this._computeEngine = value;\n  }\n  /** @internal */\n  get computeEngine() {\n    throw new Error(\"Use MathfieldElement.computeEngine instead\");\n  }\n  /** @internal */\n  set computeEngine(_val) {\n    throw new Error(\"Use MathfieldElement.computeEngine instead\");\n  }\n  static get isFunction() {\n    if (typeof this._isFunction !== \"function\") return () => false;\n    return this._isFunction;\n  }\n  static set isFunction(value) {\n    this._isFunction = value;\n    document.querySelectorAll(\"math-field\").forEach((el) => {\n      if (el instanceof _MathfieldElement) reparse(el._mathfield);\n    });\n  }\n  static async loadSound(sound) {\n    delete this.audioBuffers[sound];\n    let soundFile = \"\";\n    switch (sound) {\n      case \"keypress\":\n        soundFile = this._keypressSound.default;\n        break;\n      case \"return\":\n        soundFile = this._keypressSound.return;\n        break;\n      case \"spacebar\":\n        soundFile = this._keypressSound.spacebar;\n        break;\n      case \"delete\":\n        soundFile = this._keypressSound.delete;\n        break;\n      case \"plonk\":\n        soundFile = this.plonkSound;\n        break;\n    }\n    if (typeof soundFile !== \"string\") return;\n    soundFile = soundFile.trim();\n    const soundsDirectory = this.soundsDirectory;\n    if (soundsDirectory === void 0 || soundsDirectory === null || soundsDirectory === \"null\" || soundFile === \"none\" || soundFile === \"null\")\n      return;\n    try {\n      const response = await fetch(\n        await resolveUrl(`${soundsDirectory}/${soundFile}`)\n      );\n      const arrayBuffer = await response.arrayBuffer();\n      const audioBuffer = await this.audioContext.decodeAudioData(arrayBuffer);\n      this.audioBuffers[sound] = audioBuffer;\n    } catch (e) {\n    }\n  }\n  static async playSound(name) {\n    if (this.audioContext.state === \"suspended\" || this.audioContext.state === \"interrupted\")\n      await this.audioContext.resume();\n    if (!this.audioBuffers[name]) await this.loadSound(name);\n    if (!this.audioBuffers[name]) return;\n    const soundSource = this.audioContext.createBufferSource();\n    soundSource.buffer = this.audioBuffers[name];\n    const gainNode = this.audioContext.createGain();\n    gainNode.gain.value = AUDIO_FEEDBACK_VOLUME;\n    soundSource.connect(gainNode).connect(this.audioContext.destination);\n    soundSource.start();\n  }\n  showMenu(_) {\n    var _a3, _b3;\n    return (_b3 = (_a3 = this._mathfield) == null ? void 0 : _a3.showMenu(_)) != null ? _b3 : false;\n  }\n  /** @internal */\n  get mathVirtualKeyboard() {\n    throw new Error(\n      \"The `mathVirtualKeyboard` property is not available on the MathfieldElement. Use `window.mathVirtualKeyboard` instead.\"\n    );\n  }\n  /** @internal */\n  onPointerDown() {\n    window.addEventListener(\n      \"pointerup\",\n      (evt) => {\n        const mf = this._mathfield;\n        if (!mf) return;\n        if (evt.target === this && !mf.disabled) {\n          this.dispatchEvent(\n            new MouseEvent(\"click\", {\n              altKey: evt.altKey,\n              button: evt.button,\n              buttons: evt.buttons,\n              clientX: evt.clientX,\n              clientY: evt.clientY,\n              ctrlKey: evt.ctrlKey,\n              metaKey: evt.metaKey,\n              movementX: evt.movementX,\n              movementY: evt.movementY,\n              relatedTarget: evt.relatedTarget,\n              screenX: evt.screenX,\n              screenY: evt.screenY,\n              shiftKey: evt.shiftKey\n            })\n          );\n          const offset = this.getOffsetFromPoint(evt.clientX, evt.clientY);\n          if (offset >= 0) _MathfieldElement.openUrl(getHref(mf, offset));\n          if (evt.pointerType === \"touch\" && this.selectionIsCollapsed)\n            this.position = offset;\n        }\n      },\n      { once: true }\n    );\n  }\n  /**\n   * @inheritDoc _Mathfield#getPromptValue\n   * @category Prompts */\n  getPromptValue(placeholderId, format) {\n    var _a3, _b3;\n    return (_b3 = (_a3 = this._mathfield) == null ? void 0 : _a3.getPromptValue(placeholderId, format)) != null ? _b3 : \"\";\n  }\n  /**  {@inheritDoc _Mathfield.setPromptValue} */\n  /** @category Prompts */\n  setPromptValue(id, content, insertOptions) {\n    var _a3;\n    (_a3 = this._mathfield) == null ? void 0 : _a3.setPromptValue(id, content, insertOptions);\n  }\n  /**\n   * Return the selection range for the specified prompt.\n   *\n   * This can be used for example to select the content of the prompt.\n   *\n   * ```js\n   * mf.selection = mf.getPromptRange('my-prompt-id');\n   * ```\n   *\n   * @category Prompts\n   *\n   */\n  getPromptRange(id) {\n    var _a3, _b3;\n    return (_b3 = (_a3 = this._mathfield) == null ? void 0 : _a3.getPromptRange(id)) != null ? _b3 : null;\n  }\n  /** Return the id of the prompts matching the filter.\n   * @category Prompts\n   */\n  getPrompts(filter) {\n    var _a3, _b3;\n    return (_b3 = (_a3 = this._mathfield) == null ? void 0 : _a3.getPrompts(filter)) != null ? _b3 : [];\n  }\n  get form() {\n    var _a3;\n    return (_a3 = this._internals) == null ? void 0 : _a3[\"form\"];\n  }\n  get name() {\n    var _a3;\n    return (_a3 = this.getAttribute(\"name\")) != null ? _a3 : \"\";\n  }\n  get type() {\n    return this.localName;\n  }\n  get mode() {\n    var _a3, _b3;\n    return (_b3 = (_a3 = this._mathfield) == null ? void 0 : _a3.model.mode) != null ? _b3 : this.defaultMode === \"text\" ? \"text\" : \"math\";\n  }\n  set mode(value) {\n    var _a3;\n    (_a3 = this._mathfield) == null ? void 0 : _a3.switchMode(value);\n  }\n  /**\n     * If the Compute Engine library is available, return a boxed MathJSON expression representing the value of the mathfield.\n     *\n     * To load the Compute Engine library, use:\n     * ```js\n  import 'https://unpkg.com/@cortex-js/compute-engine?module';\n  ```\n     *\n     * @category Accessing and changing the content\n     */\n  get expression() {\n    if (!this._mathfield) return void 0;\n    if (!window[Symbol.for(\"io.cortexjs.compute-engine\")]) {\n      console.error(\n        `MathLive 0.101.0: The CortexJS Compute Engine library is not available.\n        \n        Load the library, for example with:\n        \n        import \"https://unpkg.com/@cortex-js/compute-engine?module\"`\n      );\n      return null;\n    }\n    return this._mathfield.expression;\n  }\n  set expression(mathJson) {\n    var _a3, _b3;\n    if (!this._mathfield) return;\n    const latex = (_b3 = (_a3 = _MathfieldElement.computeEngine) == null ? void 0 : _a3.box(mathJson).latex) != null ? _b3 : null;\n    if (latex !== null) this._mathfield.setValue(latex);\n    if (!window[Symbol.for(\"io.cortexjs.compute-engine\")]) {\n      console.error(\n        `MathLive 0.101.0: The Compute Engine library is not available.\n        \n        Load the library, for example with:\n        \n        import \"https://unpkg.com/@cortex-js/compute-engine?module\"`\n      );\n    }\n  }\n  /**\n   * Return an array of LaTeX syntax errors, if any.\n   * @category Accessing and changing the content\n   */\n  get errors() {\n    var _a3, _b3;\n    return (_b3 = (_a3 = this._mathfield) == null ? void 0 : _a3.errors) != null ? _b3 : [];\n  }\n  _getOptions(keys) {\n    if (this._mathfield) return get(this._mathfield.options, keys);\n    if (!gDeferredState.has(this)) return null;\n    return __spreadValues({}, get(\n      __spreadValues(__spreadValues({}, getDefault()), update(gDeferredState.get(this).options)),\n      keys\n    ));\n  }\n  getOptions(keys) {\n    console.warn(\n      `%cMathLive 0.101.0: %cDeprecated Usage%c\n      \\`mf.getOptions()\\` is deprecated. Read the property directly on the mathfield instead.\n      See mathfield/changelog/ for details.`,\n      \"color:#12b; font-size: 1.1rem\",\n      \"color:#db1111; font-size: 1.1rem\",\n      \"color: inherit, font-size: 1rem\"\n    );\n    if (this._mathfield) return get(this._mathfield.options, keys);\n    if (!gDeferredState.has(this)) return null;\n    return get(\n      __spreadValues(__spreadValues({}, getDefault()), update(gDeferredState.get(this).options)),\n      keys\n    );\n  }\n  /** @internal */\n  reflectAttributes() {\n    const defaultOptions = getDefault();\n    const options = this._getOptions();\n    Object.keys(_MathfieldElement.optionsAttributes).forEach((x) => {\n      const prop = toCamelCase(x);\n      if (_MathfieldElement.optionsAttributes[x] === \"on/off\") {\n        if (defaultOptions[prop] !== options[prop])\n          this.setAttribute(x, options[prop] ? \"on\" : \"off\");\n        else this.removeAttribute(x);\n      } else if (defaultOptions[prop] !== options[prop]) {\n        if (_MathfieldElement.optionsAttributes[x] === \"boolean\") {\n          if (options[prop]) {\n            this.setAttribute(x, \"\");\n          } else {\n            this.removeAttribute(x);\n          }\n        } else {\n          if (typeof options[prop] === \"string\" || typeof options[prop] === \"number\")\n            this.setAttribute(x, options[prop].toString());\n        }\n      }\n    });\n  }\n  /**\n   *  @category Options\n   * @deprecated\n   */\n  getOption(key) {\n    console.warn(\n      `%cMathLive 0.101.0: %cDeprecated Usage%c\n      \\`mf.getOption()\\` is deprecated. Read the property directly on the mathfield instead.\n      See mathfield/changelog/ for details.`,\n      \"color:#12b; font-size: 1.1rem\",\n      \"color:#db1111; font-size: 1.1rem\",\n      \"color: inherit, font-size: 1rem\"\n    );\n    return this._getOptions([key])[key];\n  }\n  /** @internal */\n  _getOption(key) {\n    return this._getOptions([key])[key];\n  }\n  /** @internal */\n  _setOptions(options) {\n    if (this._mathfield) this._mathfield.setOptions(options);\n    else if (gDeferredState.has(this)) {\n      const mergedOptions = __spreadValues(__spreadValues({}, gDeferredState.get(this).options), options);\n      gDeferredState.set(this, __spreadProps(__spreadValues({}, gDeferredState.get(this)), {\n        selection: { ranges: mergedOptions.readOnly ? [[0, 0]] : [[0, -1]] },\n        options: mergedOptions\n      }));\n    } else {\n      gDeferredState.set(this, {\n        value: void 0,\n        selection: { ranges: [[0, 0]] },\n        options,\n        menuItems: void 0\n      });\n    }\n    this.reflectAttributes();\n  }\n  /**\n   *  @category Options\n   * @deprecated\n   */\n  setOptions(options) {\n    console.group(\n      `%cMathLive 0.101.0: %cDeprecated Usage`,\n      \"color:#12b; font-size: 1.1rem\",\n      \"color:#db1111; font-size: 1.1rem\"\n    );\n    console.warn(\n      ` \\`mf.setOptions()\\` is deprecated. Set the property directly on the mathfield instead.\n      See mathfield/changelog/ for details.`\n    );\n    for (const key of Object.keys(options)) {\n      if (DEPRECATED_OPTIONS[key]) {\n        console.warn(\n          `\\`mf.setOptions({${key}:...})\\` -> ${DEPRECATED_OPTIONS[key]}`\n        );\n      }\n    }\n    console.groupEnd();\n    this._setOptions(options);\n  }\n  executeCommand(...args) {\n    var _a3, _b3;\n    let selector;\n    if (args.length === 1)\n      selector = args[0];\n    else selector = [args[0], ...args.slice(1)];\n    if (selector) return (_b3 = (_a3 = this._mathfield) == null ? void 0 : _a3.executeCommand(selector)) != null ? _b3 : false;\n    throw new Error(\"Invalid selector\");\n  }\n  getValue(arg1, arg2, arg3) {\n    var _a3, _b3;\n    if (this._mathfield)\n      return this._mathfield.model.getValue(arg1, arg2, arg3);\n    if (gDeferredState.has(this)) {\n      let start;\n      let end;\n      let format = void 0;\n      if (isSelection(arg1)) {\n        [start, end] = arg1.ranges[0];\n        format = arg2;\n      } else if (isRange(arg1)) {\n        [start, end] = arg1;\n        format = arg2;\n      } else if (isOffset(arg1) && isOffset(arg2)) {\n        start = arg1;\n        end = arg2;\n        format = arg3;\n      } else {\n        start = 0;\n        end = -1;\n        format = arg1;\n      }\n      if ((format === void 0 || format === \"latex\") && start === 0 && end === -1)\n        return (_b3 = (_a3 = gDeferredState.get(this).value) != null ? _a3 : this.textContent) != null ? _b3 : \"\";\n    }\n    return \"\";\n  }\n  /**\n   * @inheritDoc _Mathfield.setValue\n   * @category Accessing and changing the content\n   */\n  setValue(value, options) {\n    if (this._mathfield && value !== void 0) {\n      const currentValue = this._mathfield.model.getValue();\n      if (currentValue === value) return;\n      options != null ? options : options = { silenceNotifications: true, mode: \"math\" };\n      this._mathfield.setValue(value, options);\n      return;\n    }\n    if (gDeferredState.has(this)) {\n      const options2 = gDeferredState.get(this).options;\n      gDeferredState.set(this, {\n        value,\n        selection: { ranges: [[-1, -1]], direction: \"forward\" },\n        options: options2,\n        menuItems: void 0\n      });\n      return;\n    }\n    const attrOptions = getOptionsFromAttributes(this);\n    gDeferredState.set(this, {\n      value,\n      selection: { ranges: [[-1, -1]], direction: \"forward\" },\n      options: attrOptions,\n      menuItems: void 0\n    });\n  }\n  /**\n   * @inheritDoc _Mathfield.hasFocus\n   *\n   * @category Focus\n   *\n   */\n  hasFocus() {\n    var _a3, _b3;\n    return (_b3 = (_a3 = this._mathfield) == null ? void 0 : _a3.hasFocus()) != null ? _b3 : false;\n  }\n  /**\n   * Sets the focus to the mathfield (will respond to keyboard input).\n   *\n   * @category Focus\n   *\n   */\n  focus() {\n    var _a3;\n    (_a3 = this._mathfield) == null ? void 0 : _a3.focus();\n  }\n  /**\n   * Remove the focus from the mathfield (will no longer respond to keyboard\n   * input).\n   *\n   * @category Focus\n   *\n   */\n  blur() {\n    var _a3;\n    (_a3 = this._mathfield) == null ? void 0 : _a3.blur();\n  }\n  /**\n   * Select the content of the mathfield.\n   * @category Selection\n   */\n  select() {\n    var _a3;\n    (_a3 = this._mathfield) == null ? void 0 : _a3.select();\n  }\n  /**\n     * @inheritDoc _Mathfield.insert\n  \n     *  @category Accessing and changing the content\n     */\n  insert(s, options) {\n    var _a3, _b3;\n    return (_b3 = (_a3 = this._mathfield) == null ? void 0 : _a3.insert(s, options)) != null ? _b3 : false;\n  }\n  /**\n   * @inheritDoc _Mathfield.applyStyle\n   *\n   * @category Accessing and changing the content\n   */\n  applyStyle(style, options) {\n    var _a3;\n    return (_a3 = this._mathfield) == null ? void 0 : _a3.applyStyle(style, options);\n  }\n  /**\n   * If there is a selection, return if all the atoms in the selection,\n   * some of them or none of them match the `style` argument.\n   *\n   * If there is no selection, return 'all' if the current implicit style\n   * (determined by a combination of the style of the previous atom and\n   * the current style) matches the `style` argument, 'none' if it does not.\n   *\n   * @category Accessing and changing the content\n   */\n  queryStyle(style) {\n    var _a3, _b3;\n    return (_b3 = (_a3 = this._mathfield) == null ? void 0 : _a3.queryStyle(style)) != null ? _b3 : \"none\";\n  }\n  /** The offset closest to the location `(x, y)` in viewport coordinate.\n   *\n   * **`bias`**:  if `0`, the vertical midline is considered to the left or\n   * right sibling. If `-1`, the left sibling is favored, if `+1`, the right\n   * sibling is favored.\n   *\n   * @category Selection\n   */\n  getOffsetFromPoint(x, y, options) {\n    if (!this._mathfield) return -1;\n    return offsetFromPoint(this._mathfield, x, y, options);\n  }\n  getElementInfo(offset) {\n    return getElementInfo(this._mathfield, offset);\n  }\n  /**\n   * Reset the undo stack\n   *\n   * @category Undo\n   */\n  resetUndo() {\n    var _a3;\n    (_a3 = this._mathfield) == null ? void 0 : _a3.resetUndo();\n  }\n  /**\n   * Return whether there are undoable items\n   * @category Undo\n   */\n  canUndo() {\n    if (!this._mathfield) return false;\n    return this._mathfield.canUndo();\n  }\n  /**\n   * Return whether there are redoable items\n   * @category Undo\n   */\n  canRedo() {\n    if (!this._mathfield) return false;\n    return this._mathfield.canRedo();\n  }\n  /** @internal */\n  handleEvent(evt) {\n    var _a3, _b3, _c2, _d2, _e;\n    if (Scrim.state !== \"closed\") return;\n    if (((_b3 = (_a3 = this._mathfield) == null ? void 0 : _a3.menu) == null ? void 0 : _b3.state) !== \"closed\") return;\n    if (evt.type === \"pointerdown\") this.onPointerDown();\n    if (evt.type === \"focus\") (_c2 = this._mathfield) == null ? void 0 : _c2.focus();\n    if (evt.type === \"blur\" && ((_d2 = Scrim.scrim) == null ? void 0 : _d2.state) === \"closed\" && !(isTouchCapable() && isInIframe()))\n      (_e = this._mathfield) == null ? void 0 : _e.blur();\n  }\n  /**\n   * Custom elements lifecycle hooks\n   * @internal\n   */\n  connectedCallback() {\n    var _a3, _b3, _c2, _d2;\n    const shadowRoot = this.shadowRoot;\n    const host = shadowRoot.host;\n    const computedStyle = window.getComputedStyle(this);\n    const userSelect = computedStyle.userSelect !== \"none\";\n    if (userSelect) host.addEventListener(\"pointerdown\", this, true);\n    else {\n      const span = shadowRoot.querySelector(\"span\");\n      span.style.pointerEvents = \"none\";\n    }\n    host.addEventListener(\"focus\", this, true);\n    host.addEventListener(\"blur\", this, true);\n    this._observer = new MutationObserver(() => {\n      var _a4;\n      this.value = (_a4 = this.textContent) != null ? _a4 : \"\";\n    });\n    this._observer.observe(this, {\n      childList: true,\n      characterData: true,\n      subtree: true\n    });\n    if (!isElementInternalsSupported()) {\n      if (!this.hasAttribute(\"role\")) this.setAttribute(\"role\", \"math\");\n      if (!this.hasAttribute(\"aria-label\"))\n        this.setAttribute(\"aria-label\", \"math input field\");\n      this.setAttribute(\"aria-multiline\", \"false\");\n    }\n    if (userSelect && !this.hasAttribute(\"contenteditable\"))\n      this.setAttribute(\"contenteditable\", \"true\");\n    if (!this.hasAttribute(\"tabindex\")) this.setAttribute(\"tabindex\", \"0\");\n    const slot = shadowRoot.querySelector(\"slot:not([name])\");\n    if (slot) {\n      try {\n        this._style = slot.assignedElements().filter((x) => x.tagName.toLowerCase() === \"style\").map((x) => x.textContent).join(\"\");\n      } catch (error) {\n        console.error(error);\n      }\n    }\n    if (this._style) {\n      const styleElement = document.createElement(\"style\");\n      styleElement.textContent = this._style;\n      shadowRoot.appendChild(styleElement);\n    }\n    let value = \"\";\n    if (this.hasAttribute(\"value\")) value = this.getAttribute(\"value\");\n    else {\n      value = (_a3 = slot == null ? void 0 : slot.assignedNodes().map((x) => x.nodeType === 3 ? x.textContent : \"\").join(\"\").trim()) != null ? _a3 : \"\";\n    }\n    this._mathfield = new _Mathfield(\n      shadowRoot.querySelector(\":host > span\"),\n      __spreadProps(__spreadValues({}, (_c2 = (_b3 = gDeferredState.get(this)) == null ? void 0 : _b3.options) != null ? _c2 : getOptionsFromAttributes(this)), {\n        eventSink: this,\n        value\n      })\n    );\n    if (!gDeferredState.has(this)) {\n      this.upgradeProperty(\"disabled\");\n      this.upgradeProperty(\"readonly\");\n      for (const attr of Object.keys(_MathfieldElement.optionsAttributes))\n        this.upgradeProperty(toCamelCase(attr));\n    }\n    if (!((_d2 = this._mathfield) == null ? void 0 : _d2.model)) {\n      this._mathfield = null;\n      return;\n    }\n    if (gDeferredState.has(this)) {\n      const mf = this._mathfield;\n      const state = gDeferredState.get(this);\n      const menuItems = state.menuItems;\n      mf.model.deferNotifications({ content: false, selection: false }, () => {\n        const value2 = state.value;\n        if (value2 !== void 0) mf.setValue(value2);\n        mf.model.selection = state.selection;\n        gDeferredState.delete(this);\n      });\n      if (menuItems) this.menuItems = menuItems;\n    }\n    window.queueMicrotask(() => {\n      if (!this.isConnected) return;\n      this.dispatchEvent(\n        new Event(\"mount\", {\n          cancelable: false,\n          bubbles: true,\n          composed: true\n        })\n      );\n    });\n    void loadFonts();\n  }\n  /**\n   * Custom elements lifecycle hooks\n   * @internal\n   */\n  disconnectedCallback() {\n    var _a3, _b3, _c2;\n    this.shadowRoot.host.removeEventListener(\"pointerdown\", this, true);\n    if (!this._mathfield) return;\n    (_a3 = this._observer) == null ? void 0 : _a3.disconnect();\n    this._observer = null;\n    window.queueMicrotask(\n      () => (\n        // Notify listeners that we have been unmounted\n        this.dispatchEvent(\n          new Event(\"unmount\", {\n            cancelable: false,\n            bubbles: true,\n            composed: true\n          })\n        )\n      )\n    );\n    const options = get(\n      this._mathfield.options,\n      Object.keys(_MathfieldElement.optionsAttributes).map((x) => toCamelCase(x))\n    );\n    gDeferredState.set(this, {\n      value: this._mathfield.getValue(),\n      selection: this._mathfield.model.selection,\n      menuItems: (_c2 = (_b3 = this._mathfield.menu) == null ? void 0 : _b3.menuItems) != null ? _c2 : void 0,\n      options\n    });\n    this._mathfield.dispose();\n    this._mathfield = null;\n  }\n  /**\n   * Private lifecycle hooks\n   * @internal\n   */\n  upgradeProperty(prop) {\n    if (this.hasOwnProperty(prop)) {\n      const value = this[prop];\n      delete this[prop];\n      if (prop === \"readonly\" || prop === \"read-only\") prop = \"readOnly\";\n      this[prop] = value;\n    }\n  }\n  /**\n   * Custom elements lifecycle hooks\n   * @internal\n   */\n  attributeChangedCallback(name, oldValue, newValue) {\n    if (oldValue === newValue) return;\n    const hasValue = newValue !== null;\n    switch (name) {\n      case \"contenteditable\":\n        requestUpdate(this._mathfield);\n        break;\n      case \"disabled\":\n        this.disabled = hasValue;\n        break;\n      case \"read-only\":\n      case \"readonly\":\n        this.readOnly = hasValue;\n        break;\n      default:\n    }\n  }\n  get readonly() {\n    return this.hasAttribute(\"readonly\") || this.hasAttribute(\"read-only\");\n  }\n  set readonly(value) {\n    const isReadonly = Boolean(value);\n    if (isReadonly) {\n      this.setAttribute(\"readonly\", \"\");\n      if (isElementInternalsSupported()) this._internals.ariaReadOnly = \"true\";\n      else this.setAttribute(\"aria-readonly\", \"true\");\n      this.setAttribute(\"aria-readonly\", \"true\");\n    } else {\n      if (isElementInternalsSupported()) this._internals.ariaReadOnly = \"false\";\n      else this.removeAttribute(\"aria-readonly\");\n      this.removeAttribute(\"readonly\");\n      this.removeAttribute(\"read-only\");\n    }\n    this._setOptions({ readOnly: isReadonly });\n  }\n  get disabled() {\n    return this.hasAttribute(\"disabled\");\n  }\n  set disabled(value) {\n    var _a3;\n    const isDisabled = Boolean(value);\n    if (isDisabled) this.setAttribute(\"disabled\", \"\");\n    else this.removeAttribute(\"disabled\");\n    if (isElementInternalsSupported())\n      this._internals.ariaDisabled = isDisabled ? \"true\" : \"false\";\n    else this.setAttribute(\"aria-disabled\", isDisabled ? \"true\" : \"false\");\n    if (isDisabled && ((_a3 = this._mathfield) == null ? void 0 : _a3.hasFocus) && window.mathVirtualKeyboard.visible)\n      this._mathfield.executeCommand(\"hideVirtualKeyboard\");\n  }\n  /**\n   * The content of the mathfield as a LaTeX expression.\n   * ```js\n   * document.querySelector('mf').value = '\\\\frac{1}{\\\\pi}'\n   * ```\n   *  @category Accessing and changing the content\n   */\n  get value() {\n    return this.getValue();\n  }\n  /**\n   *  @category Accessing and changing the content\n   */\n  set value(value) {\n    this.setValue(value);\n  }\n  /** @category Customization\n   * @inheritDoc LayoutOptions.defaultMode\n   */\n  get defaultMode() {\n    return this._getOption(\"defaultMode\");\n  }\n  set defaultMode(value) {\n    this._setOptions({ defaultMode: value });\n  }\n  /** @category Customization\n   * @inheritDoc LayoutOptions.macros\n   */\n  get macros() {\n    if (!this._mathfield) throw new Error(\"Mathfield not mounted\");\n    return this._getOption(\"macros\");\n  }\n  set macros(value) {\n    this._setOptions({ macros: value });\n  }\n  /** @category Customization\n   * @inheritDoc Registers\n   */\n  get registers() {\n    if (!this._mathfield) throw new Error(\"Mathfield not mounted\");\n    const that = this;\n    return new Proxy(\n      {},\n      {\n        get: (_, prop) => {\n          if (typeof prop !== \"string\") return void 0;\n          return that._getOption(\"registers\")[prop];\n        },\n        set(_, prop, value) {\n          if (typeof prop !== \"string\") return false;\n          that._setOptions({\n            registers: __spreadProps(__spreadValues({}, that._getOption(\"registers\")), { [prop]: value })\n          });\n          return true;\n        }\n      }\n    );\n  }\n  set registers(value) {\n    this._setOptions({ registers: value });\n  }\n  /** @category Customization\n   */\n  /** {@inheritDoc LayoutOptions.colorMap} */\n  get colorMap() {\n    return this._getOption(\"colorMap\");\n  }\n  set colorMap(value) {\n    this._setOptions({ colorMap: value });\n  }\n  /** @category Customization */\n  /** {@inheritDoc LayoutOptions.backgroundColorMap} */\n  get backgroundColorMap() {\n    return this._getOption(\"backgroundColorMap\");\n  }\n  set backgroundColorMap(value) {\n    this._setOptions({ backgroundColorMap: value });\n  }\n  /** @category Customization */\n  /** {@inheritDoc LayoutOptions.letterShapeStyle} */\n  get letterShapeStyle() {\n    return this._getOption(\"letterShapeStyle\");\n  }\n  set letterShapeStyle(value) {\n    this._setOptions({ letterShapeStyle: value });\n  }\n  /** @category Customization */\n  /** {@inheritDoc LayoutOptions.minFontScale} */\n  get minFontScale() {\n    return this._getOption(\"minFontScale\");\n  }\n  set minFontScale(value) {\n    this._setOptions({ minFontScale: value });\n  }\n  /** @category Customization */\n  /**  {@inheritDoc LayoutOptions.maxMatrixCols} */\n  get maxMatrixCols() {\n    return this._getOption(\"maxMatrixCols\");\n  }\n  set maxMatrixCols(value) {\n    this._setOptions({ maxMatrixCols: value });\n  }\n  /** @category Customization */\n  /** {@inheritDoc EditingOptions.smartMode}*/\n  get smartMode() {\n    return this._getOption(\"smartMode\");\n  }\n  set smartMode(value) {\n    this._setOptions({ smartMode: value });\n  }\n  /** @category Customization */\n  /** {@inheritDoc EditingOptions.smartFence}*/\n  get smartFence() {\n    return this._getOption(\"smartFence\");\n  }\n  set smartFence(value) {\n    this._setOptions({ smartFence: value });\n  }\n  /** @category Customization */\n  /** {@inheritDoc EditingOptions.smartSuperscript} */\n  get smartSuperscript() {\n    return this._getOption(\"smartSuperscript\");\n  }\n  set smartSuperscript(value) {\n    this._setOptions({ smartSuperscript: value });\n  }\n  /** @category Customization */\n  /** {@inheritDoc EditingOptions.scriptDepth} */\n  get scriptDepth() {\n    return this._getOption(\"scriptDepth\");\n  }\n  set scriptDepth(value) {\n    this._setOptions({ scriptDepth: value });\n  }\n  /** @category Customization */\n  /** {@inheritDoc EditingOptions.removeExtraneousParentheses} */\n  get removeExtraneousParentheses() {\n    return this._getOption(\"removeExtraneousParentheses\");\n  }\n  set removeExtraneousParentheses(value) {\n    this._setOptions({ removeExtraneousParentheses: value });\n  }\n  /** @category Customization */\n  /** {@inheritDoc EditingOptions.mathModeSpace} */\n  get mathModeSpace() {\n    return this._getOption(\"mathModeSpace\");\n  }\n  set mathModeSpace(value) {\n    this._setOptions({ mathModeSpace: value });\n  }\n  /** @category Customization */\n  /** {@inheritDoc EditingOptions.placeholderSymbol} */\n  get placeholderSymbol() {\n    return this._getOption(\"placeholderSymbol\");\n  }\n  set placeholderSymbol(value) {\n    this._setOptions({ placeholderSymbol: value });\n  }\n  /** @category Customization */\n  /** {@inheritDoc EditingOptions.popoverPolicy} */\n  get popoverPolicy() {\n    return this._getOption(\"popoverPolicy\");\n  }\n  set popoverPolicy(value) {\n    this._setOptions({ popoverPolicy: value });\n  }\n  /**\n   * @category Customization */\n  /** {@inheritDoc EditingOptions.environmentPopoverPolicy}   */\n  get environmentPopoverPolicy() {\n    return this._getOption(\"environmentPopoverPolicy\");\n  }\n  set environmentPopoverPolicy(value) {\n    this._setOptions({ environmentPopoverPolicy: value });\n  }\n  /**\n   * @category Customization\n   */\n  get menuItems() {\n    var _a3;\n    if (!this._mathfield) throw new Error(\"Mathfield not mounted\");\n    return (_a3 = this._mathfield.menu._menuItems.map((x) => x.menuItem)) != null ? _a3 : [];\n  }\n  set menuItems(menuItems) {\n    var _a3;\n    if (!this._mathfield) throw new Error(\"Mathfield not mounted\");\n    if (this._mathfield) {\n      const btn = (_a3 = this._mathfield.element) == null ? void 0 : _a3.querySelector(\n        \"[part=menu-toggle]\"\n      );\n      if (btn) btn.style.display = menuItems.length === 0 ? \"none\" : \"\";\n      this._mathfield.menu.menuItems = menuItems;\n    }\n  }\n  /**\n   * @category Customization\n   * @category Virtual Keyboard\n   */\n  /**    * {@inheritDoc EditingOptions.mathVirtualKeyboardPolicy} */\n  get mathVirtualKeyboardPolicy() {\n    return this._getOption(\"mathVirtualKeyboardPolicy\");\n  }\n  set mathVirtualKeyboardPolicy(value) {\n    this._setOptions({ mathVirtualKeyboardPolicy: value });\n  }\n  /** @category Customization */\n  /**    * {@inheritDoc EditingOptions.inlineShortcuts} */\n  get inlineShortcuts() {\n    if (!this._mathfield) throw new Error(\"Mathfield not mounted\");\n    return this._getOption(\"inlineShortcuts\");\n  }\n  set inlineShortcuts(value) {\n    if (!this._mathfield) throw new Error(\"Mathfield not mounted\");\n    this._setOptions({ inlineShortcuts: value });\n  }\n  /** @category Customization\n   * {@inheritDoc EditingOptions.inlineShortcutTimeout}\n   */\n  get inlineShortcutTimeout() {\n    return this._getOption(\"inlineShortcutTimeout\");\n  }\n  set inlineShortcutTimeout(value) {\n    this._setOptions({ inlineShortcutTimeout: value });\n  }\n  /** @category Customization   */\n  /**    * {@inheritDoc EditingOptions.keybindings} */\n  get keybindings() {\n    if (!this._mathfield) throw new Error(\"Mathfield not mounted\");\n    return this._getOption(\"keybindings\");\n  }\n  set keybindings(value) {\n    if (!this._mathfield) throw new Error(\"Mathfield not mounted\");\n    this._setOptions({ keybindings: value });\n  }\n  /** @category Hooks\n   * @inheritDoc _MathfieldHooks.onInsertStyle\n   */\n  get onInsertStyle() {\n    let hook = this._getOption(\"onInsertStyle\");\n    if (hook === void 0) return defaultInsertStyleHook;\n    return hook;\n  }\n  set onInsertStyle(value) {\n    this._setOptions({ onInsertStyle: value });\n  }\n  /** @category Hooks\n   * @inheritDoc _MathfieldHooks.onInlineShortcut\n   */\n  get onInlineShortcut() {\n    return this._getOption(\"onInlineShortcut\");\n  }\n  set onInlineShortcut(value) {\n    this._setOptions({ onInlineShortcut: value });\n  }\n  /** @category Hooks\n   * @inheritDoc _MathfieldHooks.onScrollIntoView\n   */\n  get onScrollIntoView() {\n    return this._getOption(\"onScrollIntoView\");\n  }\n  set onScrollIntoView(value) {\n    this._setOptions({ onScrollIntoView: value });\n  }\n  /** @category Hooks\n   * @inheritDoc _MathfieldHooks.onExport\n   */\n  get onExport() {\n    return this._getOption(\"onExport\");\n  }\n  set onExport(value) {\n    this._setOptions({ onExport: value });\n  }\n  get readOnly() {\n    return this._getOption(\"readOnly\");\n  }\n  set readOnly(value) {\n    this._setOptions({ readOnly: value });\n  }\n  get isSelectionEditable() {\n    var _a3, _b3;\n    return (_b3 = (_a3 = this._mathfield) == null ? void 0 : _a3.isSelectionEditable) != null ? _b3 : false;\n  }\n  /** @category Prompts */\n  setPromptState(id, state, locked) {\n    var _a3;\n    (_a3 = this._mathfield) == null ? void 0 : _a3.setPromptState(id, state, locked);\n  }\n  getPromptState(id) {\n    var _a3, _b3;\n    return (_b3 = (_a3 = this._mathfield) == null ? void 0 : _a3.getPromptState(id)) != null ? _b3 : [void 0, true];\n  }\n  /** @category Virtual Keyboard */\n  get virtualKeyboardTargetOrigin() {\n    return this._getOption(\"virtualKeyboardTargetOrigin\");\n  }\n  set virtualKeyboardTargetOrigin(value) {\n    this._setOptions({ virtualKeyboardTargetOrigin: value });\n  }\n  /**\n   * An array of ranges representing the selection.\n   *\n   * It is guaranteed there will be at least one element. If a discontinuous\n   * selection is present, the result will include more than one element.\n   *\n   * @category Selection\n   *\n   */\n  get selection() {\n    if (this._mathfield) return this._mathfield.model.selection;\n    if (gDeferredState.has(this)) return gDeferredState.get(this).selection;\n    return { ranges: [[0, 0]], direction: \"forward\" };\n  }\n  /**\n   *\n   * @category Selection\n   */\n  set selection(sel) {\n    if (typeof sel === \"number\") sel = { ranges: [[sel, sel]] };\n    if (this._mathfield) {\n      this._mathfield.model.selection = sel;\n      requestUpdate(this._mathfield);\n      return;\n    }\n    if (gDeferredState.has(this)) {\n      gDeferredState.set(this, __spreadProps(__spreadValues({}, gDeferredState.get(this)), {\n        selection: sel\n      }));\n      return;\n    }\n    gDeferredState.set(this, {\n      value: void 0,\n      selection: sel,\n      options: getOptionsFromAttributes(this),\n      menuItems: void 0\n    });\n  }\n  /**\n   * @category Selection\n   */\n  get selectionIsCollapsed() {\n    const selection = this.selection;\n    return selection.ranges.length === 1 && selection.ranges[0][0] === selection.ranges[0][1];\n  }\n  /**\n   * The position of the caret/insertion point, from 0 to `lastOffset`.\n   *\n   * @category Selection\n   *\n   */\n  get position() {\n    if (this._mathfield) return this._mathfield.model.position;\n    if (gDeferredState.has(this))\n      return gDeferredState.get(this).selection.ranges[0][0];\n    return 0;\n  }\n  /**\n   * @category Selection\n   */\n  set position(offset) {\n    if (this._mathfield) {\n      this._mathfield.model.position = offset;\n      requestUpdate(this._mathfield);\n    }\n    if (gDeferredState.has(this)) {\n      gDeferredState.set(this, __spreadProps(__spreadValues({}, gDeferredState.get(this)), {\n        selection: { ranges: [[offset, offset]] }\n      }));\n      return;\n    }\n    gDeferredState.set(this, {\n      value: void 0,\n      selection: { ranges: [[offset, offset]] },\n      options: getOptionsFromAttributes(this),\n      menuItems: void 0\n    });\n  }\n  /**\n   * The last valid offset.\n   * @category Selection\n   */\n  get lastOffset() {\n    var _a3, _b3;\n    return (_b3 = (_a3 = this._mathfield) == null ? void 0 : _a3.model.lastOffset) != null ? _b3 : -1;\n  }\n};\n_MathfieldElement.version = \"0.101.0\";\n_MathfieldElement.openUrl = (href) => {\n  if (!href) return;\n  const url = new URL(href);\n  if (![\"http:\", \"https:\", \"file:\"].includes(url.protocol.toLowerCase())) {\n    _MathfieldElement.playSound(\"plonk\");\n    return;\n  }\n  window.open(url, \"_blank\");\n};\n/** @internal */\n_MathfieldElement._fontsDirectory = \"./fonts\";\n/** @internal */\n_MathfieldElement._soundsDirectory = \"./sounds\";\n/**\n * When a key on the virtual keyboard is pressed, produce a short haptic\n * feedback, if the device supports it.\n * @category Virtual Keyboard\n */\n_MathfieldElement.keypressVibration = true;\n/** @internal */\n_MathfieldElement._keypressSound = {\n  spacebar: \"keypress-spacebar.wav\",\n  return: \"keypress-return.wav\",\n  delete: \"keypress-delete.wav\",\n  default: \"keypress-standard.wav\"\n};\n/** @ignore */\n_MathfieldElement._plonkSound = \"plonk.wav\";\n/** @internal */\n_MathfieldElement.audioBuffers = {};\n/**\n * Support for [Trusted Type](https://w3c.github.io/webappsec-trusted-types/dist/spec/).\n *\n * This optional function will be called before a string of HTML is\n * injected in the DOM, allowing that string to be sanitized\n * according to a policy defined by the host.\n */\n_MathfieldElement.createHTML = (x) => x;\n/** @internal */\n_MathfieldElement._speechEngineRate = \"100%\";\n/** @internal */\n_MathfieldElement._speechEngineVoice = \"Joanna\";\n/** @internal */\n_MathfieldElement._textToSpeechMarkup = \"\";\n/** @internal */\n_MathfieldElement._textToSpeechRules = \"mathlive\";\n/** @internal */\n_MathfieldElement._textToSpeechRulesOptions = {};\n_MathfieldElement.speakHook = defaultSpeakHook;\n_MathfieldElement.readAloudHook = defaultReadAloudHook;\n/**\n * When switching from a tab to one that contains a mathfield that was\n * previously focused, restore the focus to the mathfield.\n *\n * This is behavior consistent with `<textarea>`, however it can be\n * disabled if it is not desired.\n *\n */\n_MathfieldElement.restoreFocusWhenDocumentFocused = true;\n/** @internal */\n_MathfieldElement._decimalSeparator = \".\";\n/**\n * When using the keyboard to navigate a fraction, the order in which the\n * numerator and navigator are traversed:\n * - \"numerator-denominator\": first the elements in the numerator, then\n *   the elements in the denominator.\n * - \"denominator-numerator\": first the elements in the denominator, then\n *   the elements in the numerator. In some East-Asian cultures, fractions\n *   are read and written denominator first (\"fēnzhī\"). With this option\n *   the keyboard navigation follows this convention.\n *\n * **Default**: `\"numerator-denominator\"`\n * @category Localization\n */\n_MathfieldElement.fractionNavigationOrder = \"numerator-denominator\";\n/** @internal */\n_MathfieldElement._isFunction = (command) => {\n  var _a3, _b3;\n  const ce = globalThis.MathfieldElement.computeEngine;\n  return (_b3 = (_a3 = ce == null ? void 0 : ce.parse(command).domain) == null ? void 0 : _a3.isFunction) != null ? _b3 : false;\n};\nvar MathfieldElement = _MathfieldElement;\nfunction toCamelCase(s) {\n  return s.replace(/[^a-zA-Z\\d]+(.)/g, (_m, c) => c.toUpperCase());\n}\nfunction getOptionsFromAttributes(mfe) {\n  const result = { readOnly: false };\n  const attribs = MathfieldElement.optionsAttributes;\n  Object.keys(attribs).forEach((x) => {\n    var _a3;\n    if (mfe.hasAttribute(x)) {\n      let value = mfe.getAttribute(x);\n      if (x === \"placeholder\") result.contentPlaceholder = value != null ? value : \"\";\n      else if (attribs[x] === \"boolean\") result[toCamelCase(x)] = true;\n      else if (attribs[x] === \"on/off\") {\n        value = (_a3 = value == null ? void 0 : value.toLowerCase()) != null ? _a3 : \"\";\n        if (value === \"on\" || value === \"true\") result[toCamelCase(x)] = true;\n        else if (value === \"off\" || value === \"false\")\n          result[toCamelCase(x)] = false;\n        else result[toCamelCase(x)] = void 0;\n      } else if (attribs[x] === \"number\")\n        result[toCamelCase(x)] = Number.parseFloat(value != null ? value : \"0\");\n      else result[toCamelCase(x)] = value;\n    }\n  });\n  return result;\n}\nfunction isElementInternalsSupported() {\n  if (!(\"ElementInternals\" in window) || !HTMLElement.prototype.attachInternals)\n    return false;\n  if (!(\"role\" in window.ElementInternals.prototype)) return false;\n  return true;\n}\nvar mathfield_element_default = MathfieldElement;\nvar _a2, _b2, _c, _d;\nif (isBrowser() && !((_a2 = window.customElements) == null ? void 0 : _a2.get(\"math-field\"))) {\n  (_c = window[_b2 = Symbol.for(\"io.cortexjs.mathlive\")]) != null ? _c : window[_b2] = {};\n  const global = window[Symbol.for(\"io.cortexjs.mathlive\")];\n  global.version = \"0.101.0\";\n  globalThis.MathfieldElement = MathfieldElement;\n  (_d = window.customElements) == null ? void 0 : _d.define(\"math-field\", MathfieldElement);\n}\n\n// src/addons/static-render.ts\nfunction findEndOfMath(delimiter, text, startIndex) {\n  let index = startIndex;\n  let braceLevel = 0;\n  const delimLength = delimiter.length;\n  while (index < text.length) {\n    const character = text[index];\n    if (braceLevel <= 0 && text.slice(index, index + delimLength) === delimiter)\n      return index;\n    if (character === \"\\\\\") index++;\n    else if (character === \"{\") braceLevel++;\n    else if (character === \"}\") braceLevel--;\n    index++;\n  }\n  return -1;\n}\nfunction splitAtDelimiters(startData, leftDelim, rightDelim, mathstyle, format = \"latex\") {\n  const finalData = [];\n  for (const startDatum of startData) {\n    if (startDatum.type === \"text\") {\n      const text = startDatum.data;\n      let lookingForLeft = true;\n      let currIndex = 0;\n      let nextIndex;\n      nextIndex = text.indexOf(leftDelim);\n      if (nextIndex !== -1) {\n        currIndex = nextIndex;\n        if (currIndex > 0) {\n          finalData.push({\n            type: \"text\",\n            data: text.slice(0, currIndex)\n          });\n        }\n        lookingForLeft = false;\n      }\n      let done = false;\n      while (!done) {\n        if (lookingForLeft) {\n          nextIndex = text.indexOf(leftDelim, currIndex);\n          if (nextIndex === -1) {\n            done = true;\n            break;\n          }\n          if (currIndex !== nextIndex) {\n            finalData.push({\n              type: \"text\",\n              data: text.slice(currIndex, nextIndex)\n            });\n          }\n          currIndex = nextIndex;\n        } else {\n          nextIndex = findEndOfMath(\n            rightDelim,\n            text,\n            currIndex + leftDelim.length\n          );\n          if (nextIndex === -1) {\n            done = true;\n            break;\n          }\n          let formula = text.slice(currIndex + leftDelim.length, nextIndex);\n          if (format === \"ascii-math\")\n            [, formula] = parseMathString(formula, { format: \"ascii-math\" });\n          finalData.push({\n            type: \"math\",\n            data: formula,\n            rawData: text.slice(currIndex, nextIndex + rightDelim.length),\n            mathstyle\n          });\n          currIndex = nextIndex + rightDelim.length;\n        }\n        lookingForLeft = !lookingForLeft;\n      }\n      if (currIndex < text.length) {\n        finalData.push({\n          type: \"text\",\n          data: text.slice(currIndex)\n        });\n      }\n    } else finalData.push(startDatum);\n  }\n  return finalData;\n}\nfunction splitWithDelimiters(text, options) {\n  var _a3, _b3, _c2, _d2, _e, _f, _g, _h;\n  let data = [{ type: \"text\", data: text }];\n  if ((_b3 = (_a3 = options.TeX) == null ? void 0 : _a3.delimiters) == null ? void 0 : _b3.display) {\n    options.TeX.delimiters.display.forEach(([openDelim, closeDelim]) => {\n      data = splitAtDelimiters(data, openDelim, closeDelim, \"displaystyle\");\n    });\n  }\n  if ((_d2 = (_c2 = options.TeX) == null ? void 0 : _c2.delimiters) == null ? void 0 : _d2.inline) {\n    options.TeX.delimiters.inline.forEach(([openDelim, closeDelim]) => {\n      data = splitAtDelimiters(data, openDelim, closeDelim, \"textstyle\");\n    });\n  }\n  if ((_f = (_e = options.asciiMath) == null ? void 0 : _e.delimiters) == null ? void 0 : _f.inline) {\n    options.asciiMath.delimiters.inline.forEach(([openDelim, closeDelim]) => {\n      data = splitAtDelimiters(\n        data,\n        openDelim,\n        closeDelim,\n        \"textstyle\",\n        \"ascii-math\"\n      );\n    });\n  }\n  if ((_h = (_g = options.asciiMath) == null ? void 0 : _g.delimiters) == null ? void 0 : _h.display) {\n    options.asciiMath.delimiters.display.forEach(([openDelim, closeDelim]) => {\n      data = splitAtDelimiters(\n        data,\n        openDelim,\n        closeDelim,\n        \"displaystyle\",\n        \"ascii-math\"\n      );\n    });\n  }\n  return data;\n}\nfunction createMathMLNode(latex, options) {\n  const span = document.createElement(\"span\");\n  span.setAttribute(\"translate\", \"no\");\n  try {\n    const html = \"<math xmlns='http://www.w3.org/1998/Math/MathML'>\" + options.renderToMathML(latex) + \"</math>\";\n    span.innerHTML = globalThis.MathfieldElement.createHTML(html);\n  } catch (error) {\n    console.error(\n      `MathLive 0.101.0:  Could not convert \"${latex}\"' to MathML with ${error}`\n    );\n    span.textContent = latex;\n  }\n  span.className = \"ML__sr-only\";\n  return span;\n}\nfunction createMarkupNode(text, options, mathstyle, createNodeOnFailure) {\n  try {\n    const html = options.renderToMarkup(text, __spreadProps(__spreadValues({}, options), {\n      defaultMode: mathstyle === \"displaystyle\" ? \"math\" : \"inline-math\"\n    }));\n    const element = document.createElement(\"span\");\n    element.dataset.latex = text;\n    element.style.display = mathstyle === \"displaystyle\" ? \"flex\" : \"inline-flex\";\n    element.setAttribute(\"aria-hidden\", \"true\");\n    element.setAttribute(\"translate\", \"no\");\n    element.innerHTML = globalThis.MathfieldElement.createHTML(html);\n    return element;\n  } catch (error) {\n    console.error(\"Could not parse'\" + text + \"' with \", error);\n    if (createNodeOnFailure) return document.createTextNode(text);\n  }\n  return null;\n}\nfunction createAccessibleMarkupPair(latex, mathstyle, options, createNodeOnFailure) {\n  var _a3;\n  const markupNode = createMarkupNode(\n    latex,\n    options,\n    mathstyle ? mathstyle : \"textstyle\",\n    createNodeOnFailure\n  );\n  const accessibleContent = (_a3 = options.renderAccessibleContent) != null ? _a3 : \"\";\n  if (markupNode && /\\b(mathml|speakable-text)\\b/i.test(accessibleContent)) {\n    const fragment = document.createElement(\"span\");\n    if (/\\bmathml\\b/i.test(accessibleContent) && options.renderToMathML)\n      fragment.append(createMathMLNode(latex, options));\n    if (/\\bspeakable-text\\b/i.test(accessibleContent) && options.renderToSpeakableText) {\n      const span = document.createElement(\"span\");\n      span.setAttribute(\"translate\", \"no\");\n      const html = options.renderToSpeakableText(latex);\n      span.innerHTML = globalThis.MathfieldElement.createHTML(html);\n      span.className = \"ML__sr-only\";\n      fragment.append(span);\n    }\n    fragment.append(markupNode);\n    return fragment;\n  }\n  return markupNode;\n}\nfunction scanText2(text, options) {\n  var _a3;\n  let fragment = null;\n  if (((_a3 = options.TeX) == null ? void 0 : _a3.processEnvironments) && /^\\s*\\\\begin/.test(text)) {\n    fragment = document.createDocumentFragment();\n    const node = createAccessibleMarkupPair(text, \"\", options, true);\n    if (node) fragment.appendChild(node);\n  } else {\n    if (!text.trim()) return null;\n    const data = splitWithDelimiters(text, options);\n    if (data.length === 1 && data[0].type === \"text\") {\n      return null;\n    }\n    fragment = document.createDocumentFragment();\n    for (const datum of data) {\n      if (datum.type === \"text\")\n        fragment.appendChild(document.createTextNode(datum.data));\n      else {\n        const node = createAccessibleMarkupPair(\n          datum.data,\n          datum.mathstyle === \"textstyle\" ? \"textstyle\" : \"displaystyle\",\n          options,\n          true\n        );\n        if (node) fragment.appendChild(node);\n      }\n    }\n  }\n  return fragment;\n}\nfunction scanElement(element, options) {\n  var _a3, _b3, _c2, _d2, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;\n  if (element.childNodes.length === 1 && element.childNodes[0].nodeType === 3) {\n    const text = (_a3 = element.childNodes[0].textContent) != null ? _a3 : \"\";\n    if (((_b3 = options.TeX) == null ? void 0 : _b3.processEnvironments) && /^\\s*\\\\begin/.test(text)) {\n      element.textContent = \"\";\n      const node = createAccessibleMarkupPair(text, \"\", options, true);\n      if (node) element.append(node);\n      return;\n    }\n    const data = splitWithDelimiters(text, options);\n    if (data.length === 1 && data[0].type === \"math\") {\n      element.textContent = \"\";\n      const node = createAccessibleMarkupPair(\n        data[0].data,\n        data[0].mathstyle === \"textstyle\" ? \"textstyle\" : \"displaystyle\",\n        options,\n        true\n      );\n      if (node) element.append(node);\n      return;\n    }\n    if (data.length === 1 && data[0].type === \"text\") {\n      return;\n    }\n  }\n  for (let i = element.childNodes.length - 1; i >= 0; i--) {\n    const childNode = element.childNodes[i];\n    if (childNode.nodeType === 3) {\n      let content = (_c2 = childNode.textContent) != null ? _c2 : \"\";\n      while (i > 0 && element.childNodes[i - 1].nodeType === 3) {\n        i--;\n        content = ((_d2 = element.childNodes[i].textContent) != null ? _d2 : \"\") + content;\n      }\n      content = content.trim();\n      if (!content) continue;\n      const frag = scanText2(content, options);\n      if (frag) {\n        i += frag.childNodes.length - 1;\n        childNode.replaceWith(frag);\n      }\n    } else if (childNode.nodeType === 1) {\n      const el = childNode;\n      const tag = childNode.nodeName.toLowerCase();\n      if (tag === \"script\") {\n        const scriptNode = childNode;\n        let textContent = void 0;\n        if ((_e = options.processScriptTypePattern) == null ? void 0 : _e.test(scriptNode.type))\n          textContent = (_f = scriptNode.textContent) != null ? _f : \"\";\n        else if ((_g = options.processMathJSONScriptTypePattern) == null ? void 0 : _g.test(scriptNode.type)) {\n          try {\n            textContent = (_i = options.serializeToLatex) == null ? void 0 : _i.call(\n              options,\n              JSON.parse((_h = scriptNode.textContent) != null ? _h : \"\")\n            );\n          } catch (e) {\n            console.error(e);\n          }\n        }\n        if (textContent) {\n          let style = \"textstyle\";\n          for (const l of scriptNode.type.split(\";\")) {\n            const [key, value] = l.toLowerCase().split(\"=\");\n            if (key.trim() === \"mode\")\n              style = value.trim() === \"display\" ? \"displaystyle\" : \"textstyle\";\n          }\n          const span = createAccessibleMarkupPair(\n            textContent,\n            style,\n            options,\n            true\n          );\n          if (span) scriptNode.parentNode.replaceChild(span, scriptNode);\n        }\n      } else {\n        if ((_j = options.texClassDisplayPattern) == null ? void 0 : _j.test(el.className)) {\n          const formula = el.textContent;\n          el.textContent = \"\";\n          const node = createAccessibleMarkupPair(\n            formula != null ? formula : \"\",\n            \"displaystyle\",\n            options,\n            true\n          );\n          if (node) el.append(node);\n          continue;\n        }\n        if ((_k = options.texClassInlinePattern) == null ? void 0 : _k.test(el.className)) {\n          const formula = el.textContent;\n          el.textContent = \"\";\n          const node = createAccessibleMarkupPair(\n            formula != null ? formula : \"\",\n            \"textstyle\",\n            options,\n            true\n          );\n          if (node) element.append(node);\n          continue;\n        }\n        const shouldProcess = ((_m = (_l = options.processClassPattern) == null ? void 0 : _l.test(el.className)) != null ? _m : false) || !(((_o = (_n = options.skipTags) == null ? void 0 : _n.includes(tag)) != null ? _o : false) || ((_q = (_p = options.ignoreClassPattern) == null ? void 0 : _p.test(el.className)) != null ? _q : false));\n        if (shouldProcess) scanElement(el, options);\n      }\n    }\n  }\n}\nvar DEFAULT_AUTO_RENDER_OPTIONS = {\n  // Name of tags whose content will not be scanned for math delimiters\n  skipTags: [\n    \"math-field\",\n    \"noscript\",\n    \"style\",\n    \"textarea\",\n    \"pre\",\n    \"code\",\n    \"annotation\",\n    \"annotation-xml\"\n  ],\n  // <script> tags of the following types will be processed. Others, ignored.\n  processScriptType: \"math/tex\",\n  // <script> tag with this type will be processed as MathJSON\n  processMathJSONScriptType: \"math/json\",\n  // Regex pattern of the class name of elements whose contents should not\n  // be processed\n  ignoreClass: \"tex2jax_ignore\",\n  // Regex pattern of the class name of elements whose contents should\n  // be processed when they appear inside ones that are ignored.\n  processClass: \"tex2jax_process\",\n  // Indicate the format to use to render accessible content\n  renderAccessibleContent: \"mathml\",\n  asciiMath: {\n    delimiters: {\n      inline: [\n        [\"`\", \"`\"]\n        // ASCII Math delimiters\n      ]\n    }\n  },\n  TeX: {\n    processEnvironments: true,\n    delimiters: {\n      inline: [[\"\\\\(\", \"\\\\)\"]],\n      display: [\n        [\"$$\", \"$$\"],\n        [\"\\\\[\", \"\\\\]\"]\n      ]\n    }\n  }\n};\nfunction _renderMathInElement(element, options) {\n  var _a3, _b3, _c2, _d2, _e, _f, _g, _h;\n  try {\n    const optionsPrivate = __spreadValues(__spreadValues({}, DEFAULT_AUTO_RENDER_OPTIONS), options);\n    optionsPrivate.ignoreClassPattern = new RegExp(\n      (_a3 = optionsPrivate.ignoreClass) != null ? _a3 : \"\"\n    );\n    optionsPrivate.processClassPattern = new RegExp(\n      (_b3 = optionsPrivate.processClass) != null ? _b3 : \"\"\n    );\n    optionsPrivate.processScriptTypePattern = new RegExp(\n      (_c2 = optionsPrivate.processScriptType) != null ? _c2 : \"\"\n    );\n    optionsPrivate.processMathJSONScriptTypePattern = new RegExp(\n      (_d2 = optionsPrivate.processMathJSONScriptType) != null ? _d2 : \"\"\n    );\n    if ((_f = (_e = optionsPrivate.TeX) == null ? void 0 : _e.className) == null ? void 0 : _f.display) {\n      optionsPrivate.texClassDisplayPattern = new RegExp(\n        optionsPrivate.TeX.className.display\n      );\n    }\n    if ((_h = (_g = optionsPrivate.TeX) == null ? void 0 : _g.className) == null ? void 0 : _h.inline) {\n      optionsPrivate.texClassInlinePattern = new RegExp(\n        optionsPrivate.TeX.className.inline\n      );\n    }\n    void loadFonts();\n    injectStylesheet(\"core\");\n    scanElement(element, optionsPrivate);\n  } catch (error) {\n    if (error instanceof Error)\n      console.error(\"renderMathInElement(): \" + error.message);\n    else {\n      console.error(\n        \"renderMathInElement(): Could not render math for element\",\n        element\n      );\n    }\n  }\n}\n\n// src/virtual-keyboard/commands.ts\nfunction switchKeyboardLayer(mathfield, layerName) {\n  const keyboard = VirtualKeyboard.singleton;\n  if (!keyboard) return false;\n  keyboard.show();\n  hideVariantsPanel();\n  keyboard.currentLayer = layerName;\n  keyboard.render();\n  keyboard.focus();\n  return true;\n}\nfunction toggleVirtualKeyboard() {\n  const kbd = window.mathVirtualKeyboard;\n  if (kbd.visible) kbd.hide({ animate: true });\n  else kbd.show({ animate: true });\n  return false;\n}\nregister2(\n  {\n    switchKeyboardLayer,\n    toggleVirtualKeyboard,\n    hideVirtualKeyboard: () => {\n      window.mathVirtualKeyboard.hide({ animate: true });\n      return false;\n    },\n    showVirtualKeyboard: () => {\n      window.mathVirtualKeyboard.show({ animate: true });\n      return false;\n    }\n  },\n  { target: \"virtual-keyboard\" }\n);\n\n// src/mathlive.ts\nfunction globalMathLive() {\n  var _a3, _b3;\n  (_b3 = globalThis[_a3 = Symbol.for(\"io.cortexjs.mathlive\")]) != null ? _b3 : globalThis[_a3] = {};\n  return globalThis[Symbol.for(\"io.cortexjs.mathlive\")];\n}\nfunction renderMathInDocument(options) {\n  if (document.readyState === \"loading\")\n    document.addEventListener(\n      \"DOMContentLoaded\",\n      () => renderMathInElement(document.body, options)\n    );\n  else renderMathInElement(document.body, options);\n}\nfunction getElement(element) {\n  if (typeof element === \"string\") {\n    const result = document.getElementById(element);\n    if (result === null)\n      throw new Error(`The element with ID \"${element}\" could not be found.`);\n    return result;\n  }\n  return element;\n}\nfunction renderMathInElement(element, options) {\n  var _a3, _b3, _c2, _d2;\n  if (document.readyState === \"loading\") {\n    document.addEventListener(\n      \"DOMContentLoaded\",\n      () => renderMathInElement(element, options)\n    );\n    return;\n  }\n  const el = getElement(element);\n  if (!el) return;\n  const optionsPrivate = options != null ? options : {};\n  (_a3 = optionsPrivate.renderToMarkup) != null ? _a3 : optionsPrivate.renderToMarkup = convertLatexToMarkup;\n  (_b3 = optionsPrivate.renderToMathML) != null ? _b3 : optionsPrivate.renderToMathML = convertLatexToMathMl;\n  (_c2 = optionsPrivate.renderToSpeakableText) != null ? _c2 : optionsPrivate.renderToSpeakableText = convertLatexToSpeakableText;\n  (_d2 = optionsPrivate.serializeToLatex) != null ? _d2 : optionsPrivate.serializeToLatex = convertMathJsonToLatex;\n  _renderMathInElement(el, optionsPrivate);\n}\nvar version = {\n  mathlive: \"0.101.0\"\n};\n\n\n\n//# sourceURL=webpack://obsidian-mathlive/./node_modules/mathlive/dist/mathlive.mjs?");

/***/ })

/******/ 	});
/************************************************************************/
/******/ 	// The module cache
/******/ 	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/ 		// Check if module is in cache
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			// no module.id needed
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// Execute the module function
/******/ 		__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/ 	
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/ 	
/************************************************************************/
/******/ 	/* webpack/runtime/compat get default export */
/******/ 	(() => {
/******/ 		// getDefaultExport function for compatibility with non-harmony modules
/******/ 		__webpack_require__.n = (module) => {
/******/ 			var getter = module && module.__esModule ?
/******/ 				() => (module['default']) :
/******/ 				() => (module);
/******/ 			__webpack_require__.d(getter, { a: getter });
/******/ 			return getter;
/******/ 		};
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/define property getters */
/******/ 	(() => {
/******/ 		// define getter functions for harmony exports
/******/ 		__webpack_require__.d = (exports, definition) => {
/******/ 			for(var key in definition) {
/******/ 				if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ 					Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ 				}
/******/ 			}
/******/ 		};
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/hasOwnProperty shorthand */
/******/ 	(() => {
/******/ 		__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/make namespace object */
/******/ 	(() => {
/******/ 		// define __esModule on exports
/******/ 		__webpack_require__.r = (exports) => {
/******/ 			if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 				Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 			}
/******/ 			Object.defineProperty(exports, '__esModule', { value: true });
/******/ 		};
/******/ 	})();
/******/ 	
/************************************************************************/
/******/ 	
/******/ 	// startup
/******/ 	// Load entry module and return exports
/******/ 	// This entry module can't be inlined because the eval devtool is used.
/******/ 	var __webpack_exports__ = __webpack_require__("./main.ts");
/******/ 	var __webpack_export_target__ = exports;
/******/ 	for(var i in __webpack_exports__) __webpack_export_target__[i] = __webpack_exports__[i];
/******/ 	if(__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, "__esModule", { value: true });
/******/ 	
/******/ })()
;
/* nosourcemap */