{"mappings":"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","names":["globalKey","prismGlobal","plainTextGrammar","rest","tokenize","languages","prismGlobal","plainTextGrammar","escapeHtml","string","pattern","replacement","doc","templateEl","createTemplate","html","node","addListener","target","type","listener","options","numLines","str","start","end","count","languageMap","preventDefault","selectionChange","doc","addListener","scrollToEl","editor","el","paddingTop","style","isChrome","getLineStart","text","position","getLineEnd","addListener2","element","type","listener","options","addListener","addTextareaListener","getStyleValue","prop","getPosition","rect1","rect2","updateNode","node","voidlessLangs","prevSelection","regexEscape","str","getLineBefore","text","position","getLineStart","getLines","start","end","getLineEnd","getClosestToken","editor","selector","marginLeft","marginRight","value","line","numLines","walker","doc","node","offset","getLanguage","insertText","newCursorStart","newCursorEnd","textarea","avoidBug","isChrome","removeListener","isWebKit","escapeHtml","setSelection","direction","removeHandler","addListener2","e","target","userAgent","isMac","getModifierCode","addOverlay","overlay","mod","isMac","ignoreTab","setIgnoreTab","newState","whitespaceEnd","str","getIndent","insertSpaces","tabSize","scroll","editor","insertLines","old","newL","start","end","selectionStart","selectionEnd","newLines","last","lastLine","oldLastLine","lastDiff","firstDiff","firstInsersion","lastInsersion","offset","newCursorStart","newCursorEnd","insertText","indentSelectedLines","less","lines","start1","end1","getLines","indentChar","insertTab","pos","getLineStart","insertLineAndIndent","eol","selection","value","getLineEnd","autoIndent","languageMap","getLanguage","indenationCount","getLineBefore","extraIndent","extraLine","newText","moveSelectedLines","up","newStart","newEnd","line","copySelectedLines","scrollByOneLine","getStyleValue","deleteSelectedLines","dir","column","newLineLen","toggleComment","isBlock","position","lang","block","open","close","text","regexEscape","escaped","regex","regex2","allWhiteSpace","first","insertionPoint","hasComment","diff","defaultKeymap","isMac","defaultCommands","selfClosePairs","selfCloseRegex","options","prevCopy","keyCommandMap","inputCommandMap","getSelection","container","clipboard","selfClose","wrapOnly","skipIfEqual","char","setSelection","indent","outdent","_e","isQuote","e","closingTag","preventDefault","getModifierCode","shiftKey","code","mod","isPair","i","addTextareaListener","keyCode","language","type","autoCompleteShortcutLabels","isMac","modifiers","searchShortcutLabels","editHistory","historyLimit","sp","currentEditor","allowMerge","isTyping","prevInputType","prevData","prevTime","isMerge","textarea","getSelection","stack","update","index","setEditorState","self","editor","options","addTextareaListener","e","data","inputType","time","preventDefault","prevSelection","code","getModifierCode","keyCode","isUndo","mod","isRedo","isMac","reset","offset","cursorTemplate","createTemplate","cursorPosition","cEditor","cursorContainer","before","span","cursor","after","update","selection","value","activeLine","position","updateNode","getLineBefore","getLineEnd","scrollIntoView","scrollToEl","self","editor","addTextareaListener","e","getPosition","template","searchTemplate","createTemplate","matchTemplate","testBoundary","str","position","pattern","createSearchAPI","editor","container","nodes","matchPositions","stopSearch","regex","lastNode","caseSensitive","wholeWord","useRegExp","selection","filter","regexEscape","value","searchStr","offset","match","l","index","i","e","prevEnd","start","end","updateNode","addOverlay","highlightSelectionMatches","caseSensitive","minLength","maxLength","self","editor","searchAPI","createSearchAPI","container","start","end","value","l","mStart","mEnd","basic","defaultCommands","indentGuides","matchBrackets","highlightBracketPairs","cursorPosition","highlightSelectionMatches","searchWidget","showInvisibles","matchTags","editHistory","style","search_default","invisibles_default"],"sources":["../esm/npm/@cyfung1031/prism-code-editor@5.2.0-cdn-esm.2/node_modules/@cyfung1031/prism-code-editor/src/prism/core.js","../esm/npm/@cyfung1031/prism-code-editor@5.2.0-cdn-esm.2/node_modules/@cyfung1031/prism-code-editor/src/core.ts","../esm/npm/@cyfung1031/prism-code-editor@5.2.0-cdn-esm.2/node_modules/@cyfung1031/prism-code-editor/src/utils/local.ts","../esm/npm/@cyfung1031/prism-code-editor@5.2.0-cdn-esm.2/node_modules/@cyfung1031/prism-code-editor/src/utils/index.ts","../esm/npm/@cyfung1031/prism-code-editor@5.2.0-cdn-esm.2/node_modules/@cyfung1031/prism-code-editor/src/extensions/commands/utils.ts","../esm/npm/@cyfung1031/prism-code-editor@5.2.0-cdn-esm.2/node_modules/@cyfung1031/prism-code-editor/src/extensions/commands/commands.ts","../esm/npm/@cyfung1031/prism-code-editor@5.2.0-cdn-esm.2/node_modules/@cyfung1031/prism-code-editor/src/extensions/commands/deprecated.ts","../esm/npm/@cyfung1031/prism-code-editor@5.2.0-cdn-esm.2/node_modules/@cyfung1031/prism-code-editor/src/extensions/commands/format.ts","../esm/npm/@cyfung1031/prism-code-editor@5.2.0-cdn-esm.2/node_modules/@cyfung1031/prism-code-editor/src/extensions/commands/index.ts","../esm/npm/@cyfung1031/prism-code-editor@5.2.0-cdn-esm.2/node_modules/@cyfung1031/prism-code-editor/src/extensions/cursor/position.ts","../esm/npm/@cyfung1031/prism-code-editor@5.2.0-cdn-esm.2/node_modules/@cyfung1031/prism-code-editor/src/extensions/cursor/custom.ts","../esm/npm/@cyfung1031/prism-code-editor@5.2.0-cdn-esm.2/node_modules/@cyfung1031/prism-code-editor/src/extensions/search/search.ts","../esm/npm/@cyfung1031/prism-code-editor@5.2.0-cdn-esm.2/node_modules/@cyfung1031/prism-code-editor/src/extensions/search/selection.ts","../esm/npm/@cyfung1031/prism-code-editor@5.2.0-cdn-esm.2/node_modules/@cyfung1031/prism-code-editor/src/extensions/search/search.css","../esm/npm/@cyfung1031/prism-code-editor@5.2.0-cdn-esm.2/node_modules/@cyfung1031/prism-code-editor/src/extensions/search/invisibles.css","../esm/npm/@cyfung1031/prism-code-editor@5.2.0-cdn-esm.2/node_modules/@cyfung1031/prism-code-editor/src/setups/basic.ts"],"sourcesContent":["// Slimmed down Prism core with most high level functions removed\n\nvar globalKey = Symbol.for(\"prism-code-editor.prism\");\nvar prismGlobal = globalThis[globalKey] || (globalThis[globalKey] = {});\n\nvar plainTextGrammar = prismGlobal.plainTextGrammar || (prismGlobal.plainTextGrammar = {});\nvar rest = prismGlobal.rest || (prismGlobal.rest = Symbol.for(\"prism-code-editor.prism.rest\"));\nvar tokenize =\n\tprismGlobal.tokenize || (prismGlobal.tokenize = Symbol.for(\"prism-code-editor.prism.tokenize\"));\n\n/** @param {*} id */\nvar resolve = id =\u003e typeof id == 'string' ? languages[id] : id;\n\n/** @type {Record\u003cstring, any\u003e} */\nvar languages =\n\tprismGlobal.languages ||\n\t(prismGlobal.languages = {\n\t\tplain: plainTextGrammar,\n\t\tplaintext: plainTextGrammar,\n\t\ttext: plainTextGrammar,\n\t\ttxt: plainTextGrammar,\n\t});\n\n/**\n * @param {string} text\n * @param {any} grammar\n */\nvar tokenizeText = (text, grammar) =\u003e (grammar[tokenize] || withoutTokenizer)(text, grammar);\n\n/**\n * @param {string} text\n * @param {any} grammar\n */\nvar withoutTokenizer = (text, grammar) =\u003e {\n\t/** @type {LinkedListNode} */\n\tvar startNode = [text];\n\tvar restGrammar;\n\t/** @type {(string | Token)[]} */\n\tvar array = [], i = 0;\n\twhile (restGrammar = resolve(grammar[rest])) {\n\t\tdelete grammar[rest];\n\t\tObject.assign(grammar, restGrammar);\n\t}\n\n\tmatchGrammar(text, grammar, startNode, 0);\n\n\twhile (array[i++] = startNode[0], startNode = startNode[1]);\n\treturn array;\n};\n\n/**\n * @param {string} string\n * @param {RegExp} pattern\n * @param {string} replacement\n */\nvar escapeHtml = (string, pattern, replacement) =\u003e {\n\treturn string.replace(/\u0026/g, '\u0026amp;').replace(pattern, replacement);\n};\n\nvar closingTag = '\u003c/span\u003e';\nvar openingTags = '';\nvar closingTags = '';\n\n/** @param {(string | Token)[]} tokens */\nvar highlightTokens = tokens =\u003e {\n\tvar str = '', token, i = 0;\n\twhile (token = tokens[i++]) str += stringify(token);\n\treturn str;\n};\n\n/**\n * @param {string | Token | (string | Token)[]} token\n * @returns {string}\n */\nvar stringify = token =\u003e {\n\tif (token instanceof Token) {\n\t\tvar { type, alias, content } = token;\n\t\tvar prevOpening = openingTags;\n\t\tvar prevClosing = closingTags;\n\t\tvar opening = `\u003cspan class=\"token ${\n\t\t\ttype + (alias ? ' ' + alias : '') +\n\t\t\t(type == 'keyword' \u0026\u0026 typeof content == 'string' ? ' keyword-' + content : '')\n\t\t}\"\u003e`;\n\n\t\tclosingTags += closingTag;\n\t\topeningTags += opening;\n\t\tvar contentStr = stringify(content);\n\t\topeningTags = prevOpening;\n\t\tclosingTags = prevClosing;\n\t\treturn opening + contentStr + closingTag;\n\t}\n\n\tif (typeof token != 'string') return highlightTokens(token);\n\n\ttoken = escapeHtml(token, /\u003c/g, '\u0026lt;');\n\tif (closingTags \u0026\u0026 token.includes('\\n')) {\n\t\treturn token.replace(/\\n/g, closingTags + '\\n' + openingTags);\n\t}\n\treturn token;\n};\n\n/**\n * @param {string} text\n * @param {*} ref\n */\nvar highlightText = (text, ref) =\u003e highlightTokens(tokenizeText(text, resolve(ref)));\n\n/**\n * @param {string} text\n * @param {any} grammar\n * @param {LinkedListNode} startNode\n * @param {number} startPos\n * @param {[string, number, number]} [rematch]\n *\n * @typedef {[string | Token, LinkedListNode?]} LinkedListNode\n */\nvar matchGrammar = (text, grammar, startNode, startPos, rematch) =\u003e {\n\tfor (var token in grammar) {\n\t\tif (grammar[token]) for (var j = 0, p = grammar[token], patternObj, patterns = Array.isArray(p) ? p : [p]; patternObj = patterns[j]; j++) {\n\t\t\tif (rematch \u0026\u0026 rematch[0] == token \u0026\u0026 rematch[1] == j) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t/** @type {RegExp} */\n\t\t\tvar pattern = patternObj.pattern || patternObj;\n\t\t\tvar inside = resolve(patternObj.inside);\n\t\t\tvar lookbehind = patternObj.lookbehind;\n\t\t\tvar greedy = pattern.global;\n\t\t\tvar alias = patternObj.alias;\n\n\t\t\tfor ( // iterate the token list and keep track of the current token/string position\n\t\t\t\tvar currentNode = startNode, pos = startPos;\n\t\t\t\tcurrentNode \u0026\u0026 (!rematch || pos \u003c rematch[2]);\n\t\t\t\tpos += currentNode[0].length, currentNode = currentNode[1]\n\t\t\t) {\n\t\t\t\tvar str = currentNode[0];\n\t\t\t\tvar removeCount = 0;\n\t\t\t\tvar match;\n\n\t\t\t\tif (str instanceof Token) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tpattern.lastIndex = greedy ? pos : 0;\n\t\t\t\tmatch = pattern.exec(greedy ? text : str);\n\n\t\t\t\tif (!match \u0026\u0026 greedy) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (!(match \u0026\u0026 match[0])) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// change the match to remove the text matched by the Prism lookbehind group\n\t\t\t\tvar lookbehindLength = lookbehind \u0026\u0026 match[1] ? match[1].length : 0;\n\t\t\t\tvar from = match.index + lookbehindLength;\n\t\t\t\tvar matchStr = match[0].slice(lookbehindLength);\n\t\t\t\tvar to = from + matchStr.length;\n\t\t\t\tvar k, p;\n\n\t\t\t\tif (greedy) {\n\t\t\t\t\t// find the node that contains the match\n\t\t\t\t\tfor (\n\t\t\t\t\t\t;\n\t\t\t\t\t\tp = pos + currentNode[0].length, from \u003e= p;\n\t\t\t\t\t\tcurrentNode = currentNode[1], pos = p\n\t\t\t\t\t);\n\n\t\t\t\t\t// the current node is a Token, then the match starts inside another Token, which is invalid\n\t\t\t\t\tif (currentNode[0] instanceof Token) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\t// find the last node which is affected by this match\n\t\t\t\t\tfor (\n\t\t\t\t\t\tk = currentNode, p = pos;\n\t\t\t\t\t\t(p += k[0].length) \u003c to;\n\t\t\t\t\t\tk = k[1], removeCount++\n\t\t\t\t\t);\n\n\t\t\t\t\t// replace with the new match\n\t\t\t\t\tstr = text.slice(pos, p);\n\t\t\t\t\tfrom -= pos;\n\t\t\t\t\tto -= pos;\n\t\t\t\t}\n\n\t\t\t\tvar after = str.slice(to);\n\t\t\t\tvar reach = pos + str.length;\n\t\t\t\tvar newToken = new Token(token, inside ? tokenizeText(matchStr, inside) : matchStr, matchStr, alias);\n\t\t\t\tvar next = currentNode, i = 0;\n\t\t\t\tvar nestedRematch;\n\n\t\t\t\twhile (next = next[1], i++ \u003c removeCount);\n\n\t\t\t\tif (after) {\n\t\t\t\t\tif (!next || next[0] instanceof Token) next = [after, next];\n\t\t\t\t\telse next[0] = after + next[0];\n\t\t\t\t};\n\n\t\t\t\tpos += from;\n\t\t\t\tcurrentNode[0] = from ? str.slice(0, from) : newToken;\n\n\t\t\t\tif (from) currentNode = currentNode[1] = [newToken, next];\n\t\t\t\telse currentNode[1] = next;\n\n\t\t\t\tif (removeCount) {\n\t\t\t\t\t// at least one Token object was removed, so we have to do some rematching\n\t\t\t\t\t// this can only happen if the current pattern is greedy\n\n\t\t\t\t\tmatchGrammar(text, grammar, currentNode, pos, nestedRematch = [token, j, reach]);\n\t\t\t\t\treach = nestedRematch[2];\n\t\t\t\t}\n\n\t\t\t\tif (rematch \u0026\u0026 reach \u003e rematch[2]) rematch[2] = reach;\n\t\t\t}\n\t\t}\n\t}\n};\n\n/**\n * Creates a new token.\n *\n * @param {string} type\n * @param {string | any[]} content\n * @param {string} matchedStr\n * @param {string} alias\n * @class\n */\nfunction Token(type, content, matchedStr, alias) {\n\tthis.type = type;\n\tthis.content = content;\n\tthis.alias = alias;\n\tthis.length = matchedStr.length;\n}\n\nexport {\n\trest,\n\ttokenize,\n\tToken,\n\tlanguages,\n\ttokenizeText,\n\twithoutTokenizer,\n\tresolve,\n\tescapeHtml,\n\thighlightTokens,\n\thighlightText\n};\n","import type {\r\n\tEditorOptions,\r\n\tPrismEditor,\r\n\tKeyCommandCallback,\r\n\tLanguage,\r\n\tInputCommandCallback,\r\n\tEditorEventMap,\r\n\tInputSelection,\r\n\tEditorExtension,\r\n} from \"./types.js\"\r\nimport { highlightTokens, languages, tokenizeText, TokenStream } from \"./prism/index.js\"\r\n\r\n/**\r\n * Creates a code editor using the specified container and options.\r\n * @param container Element to append the editor to or a selector.\r\n * This can also be a `ShadowRoot` or `DocumentFragment` for example.\r\n * If omitted, you must manually append `editor.container` to the DOM.\r\n * @param options Options the editor is initialized with.\r\n * If omitted, the editor won't function until you call `editor.setOptions`.\r\n * @param extensions Extensions added before the first render. You can still add extensions later.\r\n * @returns Object to interact with the created editor.\r\n */\r\nconst createEditor = \u003cT extends {} = {}\u003e(\r\n\tcontainer?: ParentNode | string | null,\r\n\toptions?: (Partial\u003cEditorOptions\u003cT\u003e\u003e \u0026 Omit\u003cT, keyof EditorOptions\u003e) | null,\r\n\t...extensions: EditorExtension\u003cT\u003e[]\r\n): PrismEditor\u003cT\u003e =\u003e {\r\n\tlet language: string\r\n\tlet prevLines: string[] = []\r\n\tlet activeLine: HTMLDivElement\r\n\tlet value = \"\"\r\n\tlet activeLineNumber: number\r\n\tlet focused = false\r\n\tlet handleSelectionChange = true\r\n\tlet tokens: TokenStream = []\r\n\tlet readOnly: boolean\r\n\tlet lineCount = 0\r\n\r\n\tconst scrollContainer = editorTemplate()\r\n\tconst wrapper = \u003cHTMLDivElement\u003escrollContainer.firstChild\r\n\tconst lines = \u003cHTMLCollectionOf\u003cHTMLDivElement\u003e\u003ewrapper.children\r\n\tconst overlays = lines[0]\r\n\tconst textarea = \u003cHTMLTextAreaElement\u003eoverlays.firstChild\r\n\tconst currentOptions = { language: \"text\", value } as EditorOptions \u0026 T\r\n\tconst currentExtensions = new Set(extensions)\r\n\tconst listeners: {\r\n\t\t[P in keyof EditorEventMap]?: Set\u003cEditorEventMap\u003cT\u003e[P]\u003e\r\n\t} = {}\r\n\r\n\tconst setOptions = (options: Partial\u003cEditorOptions\u003e \u0026 Partial\u003cOmit\u003cT, keyof EditorOptions\u003e\u003e) =\u003e {\r\n\t\tObject.assign(currentOptions, options)\r\n\t\tlet isNewVal = value != (value = options.value ?? value)\r\n\t\tlet isNewLang = language != (language = currentOptions.language)\r\n\r\n\t\treadOnly = !!currentOptions.readOnly\r\n\t\tscrollContainer.style.tabSize = \u003cany\u003ecurrentOptions.tabSize || 2\r\n\t\ttextarea.inputMode = readOnly ? \"none\" : \"\"\r\n\t\ttextarea.setAttribute(\"aria-readonly\", \u003cany\u003ereadOnly)\r\n\t\tupdateClassName()\r\n\t\tupdateExtensions()\r\n\r\n\t\tif (isNewVal) {\r\n\t\t\tif (!focused) textarea.remove()\r\n\t\t\ttextarea.value = value\r\n\t\t\ttextarea.selectionEnd = 0\r\n\t\t\tif (!focused) overlays.prepend(textarea)\r\n\t\t}\r\n\r\n\t\tif (isNewVal || isNewLang) {\r\n\t\t\tupdate()\r\n\t\t}\r\n\t}\r\n\r\n\tconst update = () =\u003e {\r\n\t\ttokens = tokenizeText((value = textarea.value), languages[language] || {})\r\n\t\tdispatchEvent(\"tokenize\", tokens, language, value)\r\n\r\n\t\tlet newLines = highlightTokens(tokens).split(\"\\n\")\r\n\t\tlet start = 0\r\n\t\tlet end2 = lineCount\r\n\t\tlet end1 = (lineCount = newLines.length)\r\n\r\n\t\twhile (newLines[start] == prevLines[start] \u0026\u0026 start \u003c end1) ++start\r\n\t\twhile (end1 \u0026\u0026 newLines[--end1] == prevLines[--end2]);\r\n\r\n\t\tif (start == end1 \u0026\u0026 start == end2) lines[start + 1].innerHTML = newLines[start] + \"\\n\"\r\n\t\telse {\r\n\t\t\tlet insertStart = end2 \u003c start ? end2 : start - 1\r\n\t\t\tlet i = insertStart\r\n\t\t\tlet newHTML = \"\"\r\n\r\n\t\t\twhile (i \u003c end1) newHTML += `\u003cdiv class=pce-line aria-hidden=true\u003e${newLines[++i]}\\n\u003c/div\u003e`\r\n\t\t\tfor (i = end1 \u003c start ? end1 : start - 1; i \u003c end2; i++) lines[start + 1].remove()\r\n\t\t\tif (newHTML) lines[insertStart + 1].insertAdjacentHTML(\"afterend\", newHTML)\r\n\t\t\tscrollContainer.style.setProperty(\r\n\t\t\t\t\"--number-width\",\r\n\t\t\t\t(0 | Math.log10(lineCount)) + 1 + \".001ch\",\r\n\t\t\t)\r\n\t\t}\r\n\r\n\t\tdispatchEvent(\"update\", value)\r\n\t\tdispatchSelection(true)\r\n\t\tif (handleSelectionChange) setTimeout(setTimeout, 0, () =\u003e (handleSelectionChange = true))\r\n\r\n\t\tprevLines = newLines\r\n\t\thandleSelectionChange = false\r\n\t}\r\n\r\n\tconst updateExtensions = (newExtensions?: EditorExtension\u003cT\u003e[]) =\u003e {\r\n\t\t;(newExtensions || currentExtensions).forEach(extension =\u003e {\r\n\t\t\tif (typeof extension == \"object\") {\r\n\t\t\t\textension.update(self, currentOptions)\r\n\t\t\t\tif (newExtensions) currentExtensions.add(extension)\r\n\t\t\t} else {\r\n\t\t\t\textension(self, currentOptions)\r\n\t\t\t\tif (!newExtensions) currentExtensions.delete(extension)\r\n\t\t\t}\r\n\t\t})\r\n\t}\r\n\r\n\tconst updateClassName = ([start, end] = getInputSelection()) =\u003e {\r\n\t\tscrollContainer.className = `prism-code-editor language-${language}${\r\n\t\t\tcurrentOptions.lineNumbers == false ? \"\" : \" show-line-numbers\"\r\n\t\t} pce-${currentOptions.wordWrap ? \"\" : \"no\"}wrap${currentOptions.rtl ? \" pce-rtl\" : \"\"} pce-${\r\n\t\t\tstart \u003c end ? \"has\" : \"no\"\r\n\t\t}-selection${focused ? \" pce-focus\" : \"\"}${readOnly ? \" pce-readonly\" : \"\"}${\r\n\t\t\tcurrentOptions.class ? \" \" + currentOptions.class : \"\"\r\n\t\t}`\r\n\t}\r\n\r\n\tconst getInputSelection = (): InputSelection =\u003e [\r\n\t\ttextarea.selectionStart,\r\n\t\ttextarea.selectionEnd,\r\n\t\ttextarea.selectionDirection,\r\n\t]\r\n\r\n\tconst keyCommandMap: Record\u003cstring, KeyCommandCallback | null\u003e = {\r\n\t\tEscape() {\r\n\t\t\ttextarea.blur()\r\n\t\t},\r\n\t}\r\n\r\n\tconst inputCommandMap: Record\u003cstring, InputCommandCallback | null\u003e = {}\r\n\r\n\tconst dispatchEvent = \u003cT extends keyof EditorEventMap\u003e(\r\n\t\tname: T,\r\n\t\t...args: Parameters\u003cEditorEventMap[T]\u003e\r\n\t) =\u003e {\r\n\t\t// @ts-expect-error\r\n\t\tlisteners[name]?.forEach(handler =\u003e handler.apply(self, args))\r\n\t\t// @ts-expect-error\r\n\t\tcurrentOptions[\"on\" + name[0].toUpperCase() + name.slice(1)]?.(...args, self)\r\n\t}\r\n\r\n\tconst dispatchSelection = (force?: boolean) =\u003e {\r\n\t\tif (force || handleSelectionChange) {\r\n\t\t\tconst selection = getInputSelection()\r\n\t\t\tconst newLine =\r\n\t\t\t\tlines[(activeLineNumber = numLines(value, 0, selection[selection[2] \u003c \"f\" ? 0 : 1]))]\r\n\r\n\t\t\tif (newLine != activeLine) {\r\n\t\t\t\tactiveLine?.classList.remove(\"active-line\")\r\n\t\t\t\tnewLine.classList.add(\"active-line\")\r\n\t\t\t\tactiveLine = newLine\r\n\t\t\t}\r\n\t\t\tupdateClassName(selection)\r\n\t\t\tdispatchEvent(\"selectionChange\", selection, value)\r\n\t\t}\r\n\t}\r\n\r\n\tconst self: PrismEditor\u003cT\u003e = {\r\n\t\tcontainer: scrollContainer,\r\n\t\twrapper,\r\n\t\tlines,\r\n\t\ttextarea,\r\n\t\tget activeLine() {\r\n\t\t\treturn activeLineNumber\r\n\t\t},\r\n\t\tget value() {\r\n\t\t\treturn value\r\n\t\t},\r\n\t\toptions: currentOptions,\r\n\t\tget focused() {\r\n\t\t\treturn focused\r\n\t\t},\r\n\t\tget tokens() {\r\n\t\t\treturn tokens\r\n\t\t},\r\n\t\tinputCommandMap,\r\n\t\tkeyCommandMap,\r\n\t\textensions: {},\r\n\t\tsetOptions,\r\n\t\tupdate,\r\n\t\tgetSelection: getInputSelection,\r\n\t\taddExtensions(...extensions) {\r\n\t\t\tupdateExtensions(extensions)\r\n\t\t},\r\n\t\ton: (name, handler) =\u003e {\r\n\t\t\t;(listeners[name] ||= new Set\u003cany\u003e()).add(handler)\r\n\t\t\treturn () =\u003e listeners[name]!.delete(handler)\r\n\t\t},\r\n\t\tremove() {\r\n\t\t\tscrollContainer.remove()\r\n\t\t},\r\n\t}\r\n\r\n\taddListener(textarea, \"keydown\", e =\u003e {\r\n\t\tkeyCommandMap[e.key]?.(e, getInputSelection(), value) \u0026\u0026 preventDefault(e)\r\n\t})\r\n\r\n\taddListener(textarea, \"beforeinput\", e =\u003e {\r\n\t\tif (\r\n\t\t\treadOnly ||\r\n\t\t\t(e.inputType == \"insertText\" \u0026\u0026 inputCommandMap[e.data!]?.(e, getInputSelection(), value))\r\n\t\t)\r\n\t\t\tpreventDefault(e)\r\n\t})\r\n\taddListener(textarea, \"input\", update)\r\n\taddListener(textarea, \"blur\", () =\u003e {\r\n\t\tselectionChange = null\r\n\t\tfocused = false\r\n\t\tupdateClassName()\r\n\t})\r\n\taddListener(textarea, \"focus\", () =\u003e {\r\n\t\tselectionChange = dispatchSelection\r\n\t\tfocused = true\r\n\t\tupdateClassName()\r\n\t})\r\n\t// For browsers that support selectionchange on textareas\r\n\taddListener(textarea, \"selectionchange\", e =\u003e {\r\n\t\tdispatchSelection(!e.isTrusted)\r\n\t\tpreventDefault(e)\r\n\t})\r\n\r\n\tgetElement(container)?.append(scrollContainer)\r\n\toptions \u0026\u0026 setOptions(options)\r\n\treturn self\r\n}\r\n\r\n/**\r\n * Almost identical to {@link createEditor}, but instead of appending the editor to your\r\n * element, the editor replaces it.\r\n *\r\n * The `textContent` of the placeholder will be the code in the editor unless `options.value` is defined.\r\n * @param placeholder Node or selector which will be replaced by the editor.\r\n * @param options Options the editor is initialized with.\r\n * @param extensions Extensions added before the first render. You can still add extensions later.\r\n * @returns Object to interact with the created editor.\r\n */\r\nconst editorFromPlaceholder = \u003cT extends {} = {}\u003e(\r\n\tplaceholder: string | ChildNode,\r\n\toptions: Partial\u003cEditorOptions\u003cT\u003e\u003e \u0026 Omit\u003cT, keyof EditorOptions\u003e,\r\n\t...extensions: EditorExtension\u003cT\u003e[]\r\n) =\u003e {\r\n\tconst el = getElement(placeholder)!\r\n\tconst editor = createEditor\u003cT\u003e(\r\n\t\tnull,\r\n\t\tObject.assign({ value: el.textContent }, options),\r\n\t\t...extensions,\r\n\t)\r\n\tel.replaceWith(editor.container)\r\n\treturn editor\r\n}\r\n\r\n/** Equivalent to `document` in a browser setting, `null` otherwise. */\r\nconst doc = \"u\" \u003e typeof window ? document : null\r\n\r\nconst templateEl = /* @__PURE__ */ doc?.createElement(\"div\")\r\n\r\nconst createTemplate = \u003cT extends Element = HTMLDivElement\u003e(html: string, node?: Node) =\u003e {\r\n\tif (templateEl) {\r\n\t\ttemplateEl.innerHTML = html\r\n\t\tnode = templateEl.firstChild!\r\n\t}\r\n\treturn () =\u003e \u003cT\u003enode!.cloneNode(true)\r\n}\r\n\r\nconst addListener = \u003cT extends keyof HTMLElementEventMap\u003e(\r\n\ttarget: HTMLElement,\r\n\ttype: T,\r\n\tlistener: (this: HTMLElement, ev: HTMLElementEventMap[T]) =\u003e any,\r\n\toptions?: boolean | AddEventListenerOptions,\r\n) =\u003e target.addEventListener(type, listener, options)\r\n\r\nconst getElement = \u003cT extends Node\u003e(el?: T | string | null) =\u003e\r\n\ttypeof el == \"string\" ? doc!.querySelector\u003cHTMLElement\u003e(el) : el\r\n\r\n/**\r\n * Counts number of lines in the string between `start` and `end`.\r\n * If start and end are omitted, the whole string is searched.\r\n */\r\nconst numLines = (str: string, start = 0, end = Infinity) =\u003e {\r\n\tlet count = 1\r\n\tfor (; (start = str.indexOf(\"\\n\", start) + 1) \u0026\u0026 start \u003c= end; count++);\r\n\treturn count\r\n}\r\n\r\n/** Object storing all language specific behavior. */\r\nconst languageMap: Record\u003cstring, Language\u003e =\r\n\t((globalThis as any)[Symbol.for(\"prism-code-editor.languageMap\")] ||= {})\r\n\r\nconst editorTemplate = /* @__PURE__ */ createTemplate(\r\n\t\"\u003cdiv\u003e\u003cdiv class=pce-wrapper\u003e\u003cdiv class=pce-overlays\u003e\u003ctextarea class=pce-textarea spellcheck=false autocapitalize=off autocomplete=off\u003e\",\r\n)\r\n\r\nconst preventDefault = (e: Event) =\u003e {\r\n\te.preventDefault()\r\n\te.stopImmediatePropagation()\r\n}\r\n\r\nconst setSelectionChange = (f?: (force?: boolean) =\u003e void) =\u003e (selectionChange = f)\r\n\r\nlet selectionChange: null | undefined | ((force?: boolean) =\u003e void)\r\n\r\n// @ts-expect-error Allow adding listener to document\r\nif (doc) addListener(doc, \"selectionchange\", () =\u003e selectionChange?.())\r\n\r\nexport {\r\n\tcreateEditor,\r\n\tlanguageMap,\r\n\tnumLines,\r\n\tcreateTemplate,\r\n\tgetElement,\r\n\tpreventDefault,\r\n\teditorFromPlaceholder,\r\n\taddListener,\r\n\tsetSelectionChange,\r\n\tdoc,\r\n}\r\n","import { PrismEditor } from \"../index.js\"\nimport { addListener } from \"../core.js\"\nimport { isChrome } from \"./index.js\"\nimport { PrismCodeBlock } from \"../client/code-block.js\"\n\nconst scrollToEl = (editor: PrismEditor, el: HTMLElement, paddingTop = 0) =\u003e {\n\tconst style = editor.container.style\n\n\tstyle.setProperty(\"--_sp\", \"var(--pce-scroll-padding, 2ch)\")\n\tstyle.scrollPaddingBlock = `calc(var(--_sp) + ${paddingTop}px) calc(var(--_sp) + ${\n\t\tisChrome \u0026\u0026 !el.offsetWidth ? el.offsetHeight : 0\n\t}px)`\n\n\tel.scrollIntoView({ block: \"nearest\" })\n\tstyle.scrollPaddingBlock = \"\"\n\tstyle.removeProperty(\"--_sp\")\n}\n\nconst getLineStart = (text: string, position: number) =\u003e\n\tposition ? text.lastIndexOf(\"\\n\", position - 1) + 1 : 0\n\nconst getLineEnd = (text: string, position: number) =\u003e\n\t(position = text.indexOf(\"\\n\", position)) + 1 ? position : text.length\n\nconst addListener2 = \u003cT extends keyof HTMLElementEventMap\u003e(\n\telement: HTMLElement,\n\ttype: T,\n\tlistener: (this: HTMLElement, ev: HTMLElementEventMap[T]) =\u003e any,\n\toptions?: boolean | AddEventListenerOptions,\n) =\u003e {\n\taddListener(element, type, listener, options)\n\treturn () =\u003e element.removeEventListener(type, listener, options)\n}\n\nconst addTextareaListener = \u003cT extends keyof HTMLElementEventMap\u003e(\n\teditor: PrismEditor,\n\ttype: T,\n\tlistener: (this: HTMLElement, ev: HTMLElementEventMap[T]) =\u003e any,\n\toptions?: boolean | AddEventListenerOptions,\n) =\u003e addListener2(editor.textarea, type, listener, options)\n\nconst getStyleValue = (el: HTMLElement, prop: keyof CSSStyleDeclaration) =\u003e\n\tparseFloat(\u003cstring\u003egetComputedStyle(el)[prop])\n\nconst getPosition = (editor: PrismEditor | PrismCodeBlock, el: HTMLElement) =\u003e {\n\tconst rect1 = el.getBoundingClientRect()\n\tconst rect2 = editor.lines[0].getBoundingClientRect()\n\n\treturn {\n\t\ttop: rect1.y - rect2.y,\n\t\tbottom: rect2.bottom - rect1.bottom,\n\t\tleft: rect1.x - rect2.x,\n\t\tright: rect2.right - rect1.right,\n\t\theight: rect1.height,\n\t}\n}\n\nconst updateNode = (node: Text, text: string) =\u003e {\n\tif (node.data != text) node.data = text\n}\n\nconst voidlessLangs = new Set(\"xml,rss,atom,jsx,tsx,xquery,xeora,xeoracube,actionscript\".split(\",\"))\nconst voidTags = /^(?:area|base|w?br|col|embed|hr|img|input|link|meta|source|track)$/\n\nexport {\n\tscrollToEl,\n\tgetLineStart,\n\tgetLineEnd,\n\tgetStyleValue,\n\taddListener2,\n\taddTextareaListener,\n\tgetPosition,\n\tupdateNode,\n\tvoidTags,\n\tvoidlessLangs,\n}\n","import { InputSelection, PrismEditor } from \"../index.js\"\nimport { numLines, doc } from \"../core.js\"\nimport { addListener2, getLineEnd, getLineStart } from \"./local.js\"\nimport { PrismCodeBlock } from \"../client/code-block.js\"\nimport { escapeHtml } from \"../prism/core.js\"\n\n/**\n * If {@link insertText} has been called, this variable stores the editor's selection\n * before the call. This variable is set to 0 right before {@link insertText} returns.\n * This can therefore be used inside a `beforeinput` handler to determine if\n * {@link insertText} fired the event, and if true, get the selection before the call.\n *\n * Intended for internal use only.\n */\nlet prevSelection: InputSelection | 0\n\n/**\n * Escapes all regex syntax characters with a backslash and returns the escaped string.\n *\n * The returned string is not safe inside a character class.\n */\nconst regexEscape = (str: string) =\u003e str.replace(/[$+?|.^*()[\\]{}\\\\]/g, \"\\\\$\u0026\")\n\n/** Returns the string between the position and the previous \\n. */\nconst getLineBefore = (text: string, position: number) =\u003e\n\ttext.slice(getLineStart(text, position), position)\n\n/**\n * Gets all lines that are at least partially between `start` and `end`.\n * @param text Text to search in.\n * @param start Start of the selection.\n * @param end End of the selection. Defaults to `start`.\n * @returns A tuple containing an array of lines, the starting position of the first line,\n * and the ending position of the last line.\n */\nconst getLines = (text: string, start: number, end = start) =\u003e\n\t[\n\t\ttext.slice((start = getLineStart(text, start)), (end = getLineEnd(text, end))).split(\"\\n\"),\n\t\tstart,\n\t\tend,\n\t] as const\n\n/**\n * Searches a full line for a token that matches a selector and contains `position`\n * within the specified margins. Tokens are searched in reverse document order which means\n * children are searched before their parents.\n * @param editor Editor you want to search in.\n * @param selector CSS selector for the tokens you want to search for.\n * @param marginLeft How far to the left of the token the position can be. Defaults to 0.\n * @param marginRight How far to the right of the token the position can be. Defaults to `marginLeft`.\n * @param position Position to search in. Defaults to `selectionStart`.\n * @returns A span element if one's found or undefined if not.\n * @example\n * This will return a string token if the cursor\n * is at least 1 character inside a string token\n * ```javascript\n * getClosestToken(editor, '.string', -1)\n * ```\n */\nconst getClosestToken = (\n\teditor: PrismEditor,\n\tselector: string,\n\tmarginLeft = 0,\n\tmarginRight = marginLeft,\n\tposition = editor.getSelection()[0],\n) =\u003e {\n\tconst value = editor.value\n\tconst line = editor.lines[numLines(value, 0, position)]\n\t// We unfortunitely have to include elements, else we can't get empty tokens\n\tconst walker = doc!.createTreeWalker(line, 5)\n\n\tlet node = walker.lastChild()\n\tlet offset = getLineEnd(value, position) + 1 - position - (\u003cText\u003enode).length\n\n\twhile (-offset \u003c= marginRight \u0026\u0026 (node = walker.previousNode())) {\n\t\tif (node.lastChild) continue\n\t\toffset -= (\u003cText\u003enode).length || 0\n\n\t\tif (offset \u003c= marginLeft) {\n\t\t\tfor (; node != line; node = node.parentNode!) {\n\t\t\t\tif ((\u003cElement\u003enode).matches?.(selector)) return \u003cHTMLSpanElement\u003enode\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Gets the current language at a position.\n * Useful if you want to run different logic based on the language.\n * @param editor Editor to search in.\n * @param position Position to search in. Defaults to `selectionStart`.\n */\nconst getLanguage = (editor: PrismEditor, position?: number) =\u003e\n\tgetClosestToken(editor, \"[class*=language-]\", 0, 0, position)?.className.match(\n\t\t/language-(\\S*)/,\n\t)![1] || editor.options.language\n\n/**\n * Inserts text into the editor (unless it's read-only) while keeping undo/redo history.\n * Focuses the `textarea` if it isn't already.\n * @param editor Target editor.\n * @param text Text to insert.\n * @param start Position to start the insertion. Defaults to `selectionStart`.\n * @param end Position to end the insertion. Defaults to `start` if specified, else `selectionEnd`.\n * @param newCursorStart New starting position for the cursor. Defaults to the end of the inserted text.\n * @param newCursorEnd New ending position for the cursor. Defaults to `newCursorStart`.\n */\nconst insertText = (\n\teditor: PrismEditor,\n\ttext: string,\n\tstart?: number | null,\n\tend?: number | null,\n\tnewCursorStart?: number | null,\n\tnewCursorEnd?: number | null,\n) =\u003e {\n\tif (editor.options.readOnly) return\n\tprevSelection = editor.getSelection()\n\tend ??= start\n\n\tlet textarea = editor.textarea\n\tlet value = editor.value\n\t// Bug inserting new lines at the end if the editor ends with an empty line\n\tlet avoidBug =\n\t\tisChrome \u0026\u0026 !value[end ?? prevSelection[1]] \u0026\u0026 /\\n$/.test(text) \u0026\u0026 /^$|\\n$/.test(value)\n\tlet removeListener: () =\u003e any\n\n\teditor.focused || textarea.focus()\n\tif (start != null) textarea.setSelectionRange(start, end!)\n\n\tif (newCursorStart != null) {\n\t\tremoveListener = editor.on(\"update\", () =\u003e {\n\t\t\ttextarea.setSelectionRange(\n\t\t\t\tnewCursorStart,\n\t\t\t\tnewCursorEnd ?? newCursorStart,\n\t\t\t\t(\u003cInputSelection\u003eprevSelection)[2],\n\t\t\t)\n\t\t\tremoveListener()\n\t\t})\n\t}\n\n\t// Only Safari dispatches a beforeinput event\n\tisWebKit || textarea.dispatchEvent(new InputEvent(\"beforeinput\", { data: text }))\n\n\t// Inserting escaped HTML in Chrome and Safari instead for much better performance\n\tif (isChrome || isWebKit) {\n\t\tif (avoidBug) {\n\t\t\t// This means the last new line won't be inserted if there's\n\t\t\t// no selection, but that's less annoying than the bug.\n\t\t\ttextarea.selectionEnd--\n\t\t\ttext = text.slice(0, -1)\n\t\t}\n\t\t// New line at the end is always ignored in Safari\n\t\tif (isWebKit) text += \"\\n\"\n\t\tdoc!.execCommand(text ? \"insertHTML\" : \"delete\", false, escapeHtml(text, /\u003c/g, \"\u0026lt;\"))\n\t\tif (avoidBug) textarea.selectionStart++\n\t} else doc!.execCommand(text ? \"insertText\" : \"delete\", false, text)\n\n\tprevSelection = 0\n}\n\n/**\n * Sets the selection for the `textarea` and synchronously runs the selectionChange listeners.\n * If you don't want to synchronously run the listeners, use `textarea.setSelectionRange` instead.\n * @param editor Editor you want to change the selection of.\n * @param start New selectionStart.\n * @param end New selectionEnd. Defaults to `start`.\n * @param direction New direction.\n */\nconst setSelection = (\n\teditor: PrismEditor,\n\tstart: number,\n\tend = start,\n\tdirection?: \"backward\" | \"forward\" | \"none\",\n) =\u003e {\n\tlet textarea = editor.textarea\n\t// Webkit 18.3 and earlier focuses the textarea when changing the selection\n\tlet removeHandler = addListener2(textarea, \"focus\", e =\u003e {\n\t\tlet target = e.relatedTarget as HTMLElement\n\t\ttarget ? target.focus() : textarea.blur()\n\t})\n\n\ttextarea.setSelectionRange(start, end, direction)\n\tremoveHandler()\n\ttextarea.dispatchEvent(new Event(\"selectionchange\"))\n}\n\nconst userAgent = doc ? navigator.userAgent : \"\"\n/** Whether the user is on an Apple-based system. */\nconst isMac = doc ? /Mac|iPhone|iP[ao]d/.test(navigator.platform) : false\n/** Whether the browser is Chromium based. */\nconst isChrome = /Chrome\\//.test(userAgent)\n/** Whether the browser uses the WebKit browser engine. */\nconst isWebKit = !isChrome \u0026\u0026 /AppleWebKit\\//.test(userAgent)\n\n/**\n * Returns a 4 bit integer where each bit represents whether\n * each modifier is pressed in the order Shift, Meta, Ctrl, Alt.\n *\n * ```javascript\n * e.shiftKey \u0026\u0026 !e.metaKey \u0026\u0026 e.ctrlKey \u0026\u0026 e.altKey\n * // is equivalent to\n * getModifierCode(e) == 0b1011\n * ```\n */\nconst getModifierCode = (\n\te: KeyboardEvent, // @ts-expect-error\n): number =\u003e e.altKey + e.ctrlKey * 2 + e.metaKey * 4 + e.shiftKey * 8\n\n/**\n * Adds an overlay by appending the element to the editor's overlays.\n * Equivalent to calling `editor.lines[0].append(overlay)`.\n * @param editor Editor or code block you want to add an overlay to.\n * @param overlay The overlay you want to add.\n */\nconst addOverlay = (editor: PrismEditor | PrismCodeBlock, overlay: HTMLElement) =\u003e\n\teditor.lines[0].append(overlay)\n\n/**\n * Gets the position of the cursor in the document. It returns a tuple with three numbers:\n *\n * 1. The line number of the cursor\n * 2. The 1-based column of the cursor\n * 3. Number of characters selected\n *\n * @example\n * const [line, col, selected] = getDocumentPosition(editor)\n */\nconst getDocumentPosition = (editor: PrismEditor): [number, number, number] =\u003e {\n\tlet [start, end, dir] = editor.getSelection()\n\tlet pos = dir \u003c \"f\" ? start : end\n\tlet value = editor.value\n\tlet col = 0\n\tlet chars = 0\n\tlet tabSize = editor.options.tabSize || 2\n\n\tfor (const char of getLineBefore(value, pos)) {\n\t\tcol += char == \"\\t\" ? tabSize - (col % tabSize) : 1\n\t}\n\n\tfor (const _ of value.slice(start, end)) chars++\n\n\treturn [editor.activeLine, col + 1, chars]\n}\n\nexport {\n\tregexEscape,\n\tgetLineBefore,\n\tgetLines,\n\tgetClosestToken,\n\tgetLanguage,\n\tinsertText,\n\tgetModifierCode,\n\tsetSelection,\n\taddOverlay,\n\tgetDocumentPosition,\n\tisMac,\n\tisChrome,\n\tisWebKit,\n\tprevSelection,\n}\n","import { PrismEditor } from \"../../index.js\"\nimport { preventDefault } from \"../../core.js\"\nimport { getModifierCode, isMac } from \"../../utils/index.js\"\nimport { addTextareaListener } from \"../../utils/local.js\"\nimport { HotkeyMap, EditorHotkey, HotkeySequenceOptions, Hotkey } from \"./types.js\"\n\n/**\n * Normalizes modifier keys to a bitmask that's used by {@link getKeysFromEvent}.\n * All keys are case insensitive.\n *\n * Rules:\n * - `alt` → `1`\n * - `ctrl` or `control` → `2`\n * - `meta` or `cmd` → `4`\n * - `shift` → `8`\n * - `mod` → `4` on Mac, `2` otherwise\n *\n * @param key Key to normalize.\n * @returns Normalized and lowercase key.\n * @example\n * normalizeKey(\"a\") // \"0+a\"\n * normalizeKey(\"+\") // \"0++\"\n * normalizeKey(\"ctrl+alt+a\") // \"3+a\"\n * normalizeKey(\"10+ALT+a\") // \"11+a\"\n * normalizeKey(\"shift+alt+12+a\") // \"13+a\"\n */\nconst normalizeKey = (key: string) =\u003e {\n\tlet code = 0\n\tlet parts = key.toLowerCase().split(\"+\")\n\tlet last = parts.pop() || \"+\"\n\tfor (const part of parts) {\n\t\tcode |= +part || modifierMap[part] || 0\n\t}\n\treturn code + \"+\" + last\n}\n\n/**\n * Gets a `Set` of keys that match a keyboard event.\n * @param e Keyboard event to get keys for.\n */\nconst getKeysFromEvent = (e: KeyboardEvent) =\u003e {\n\tif (!keyCodeMap[48]) {\n\t\t// Alphanumeric\n\t\tfor (let i = 48; i \u003c 91; i++) {\n\t\t\tkeyCodeMap[i] = String.fromCharCode(i \u003e 64 ? i + 32 : i)\n\t\t}\n\n\t\t// Numpad\n\t\tfor (let i = 96; i \u003c 112; i++) {\n\t\t\tkeyCodeMap[i] = String.fromCharCode(i \u003c 106 ? i - 48 : i - 64)\n\t\t}\n\t}\n\n\tconst key = e.key || \"\"\n\tconst code = getModifierCode(e)\n\tconst keyBase = keyCodeMap[e.keyCode]\n\tconst keyShift = keyCodeMapShift[e.keyCode]\n\tconst hasShift = code \u003e 7\n\n\tconst useKeyCode = (isMac \u0026\u0026 code == 12) || key == \"Dead\" || key == \"Unidentified\"\n\tconst keyName = (useKeyCode \u0026\u0026 ((hasShift \u0026\u0026 keyShift) || keyBase)) || key.toLowerCase()\n\n\tconst isNotChar = /\\w\\w| /.test(keyName.slice(0, 2))\n\tconst noShift = code \u0026 7\n\tconst commands = new Set([`${isNotChar || /\\p{L}/u.test(keyName) ? code : noShift}+${keyName}`])\n\n\tif (!isNotChar) {\n\t\tif (noShift \u0026\u0026 !(isMac \u0026\u0026 noShift == 1) \u0026\u0026 keyBase) {\n\t\t\tcommands.add(code + \"+\" + keyBase)\n\t\t\tif (hasShift \u0026\u0026 keyShift) {\n\t\t\t\tcommands.add(noShift + \"+\" + keyShift)\n\t\t\t}\n\t\t} else if (hasShift) commands.add(code + \"+\" + keyName)\n\t}\n\n\treturn commands\n}\n\nconst editorMap = new WeakMap\u003cPrismEditor, HotkeyMap\u003cPrismEditor\u003e\u003e()\n\n/**\n * Utility that runs all commands whose key matches the keyboard event until a command\n * returns a truthy value. In that case `preventDefault` and `stopImmediatePropagation`\n * are called.\n *\n * @param e Keyboard event to run commands for.\n * @param map Record mapping keys to a list of commands for that key.\n * @param data Argument to pass to the commands.\n * @returns `true` if a command returned a truthy value.\n *\n * @example\n * addEventListener(\"keydown\", e =\u003e {\n *   const handled = !!runHotkeys(e, map, data)\n * })\n */\nconst runHotkeys = \u003cT\u003e(e: KeyboardEvent, map: HotkeyMap\u003cT\u003e, data: T) =\u003e {\n\tlet seen = new Set\u003cHotkey\u003cT\u003e\u003e()\n\tlet firstKey: string\n\n\ttry {\n\t\tfor (const key of getKeysFromEvent(e)) {\n\t\t\tfirstKey ||= key\n\t\t\tfor (const set of map[key] || []) {\n\t\t\t\tfor (const cmd of set || []) {\n\t\t\t\t\tif (!seen.has(cmd)) {\n\t\t\t\t\t\tif (cmd(data, e, key)) {\n\t\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t\t\treturn true\n\t\t\t\t\t\t}\n\t\t\t\t\t\tseen.add(cmd)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} finally {\n\t\tmap.any?.forEach(set =\u003e set?.forEach(cmd =\u003e cmd(data, e, firstKey)))\n\t}\n}\n\nconst getMap = \u003cT extends {}\u003e(editor: PrismEditor\u003cT\u003e) =\u003e {\n\tlet map = editorMap.get(editor) as HotkeyMap\u003cPrismEditor\u003cT\u003e\u003e\n\n\tif (!map) {\n\t\teditorMap.set(editor, (map = {}))\n\t\taddTextareaListener(editor, \"keydown\", e =\u003e {\n\t\t\trunHotkeys(e, map, editor)\n\t\t})\n\t}\n\n\treturn map\n}\n\n/**\n * Registers a command for the specified key.\n *\n * @param editor Editor to add the command to.\n * @param key Key the command will run for.\n * @param command Command for the specified key.\n * @param precedence Positive integer denoting the precedence of the command where `0`\n * is the highest precedence. Defaults to `2`.\n * @returns Function to remove the hotkey.\n */\nconst addEditorHotkey = \u003cT extends {}\u003e(\n\teditor: PrismEditor\u003cT\u003e,\n\tkey: string,\n\tcommand: EditorHotkey\u003cT\u003e,\n\tprecedence?: number,\n) =\u003e {\n\treturn addHotkey(getMap(editor), key, command, precedence)\n}\n\n/**\n * Registers a command for the specified key to the hotkey map.\n *\n * @param map Map to add the command to.\n * @param key Key the command will run for.\n * @param command Command for the specified key.\n * @param precedence Positive integer denoting the precedence of the command where `0`\n * is the highest precedence. Defaults to `2`.\n * @returns Function to remove the hotkey.\n */\nconst addHotkey = \u003cT\u003e(map: HotkeyMap\u003cT\u003e, key: string, command: Hotkey\u003cT\u003e, precedence = 2) =\u003e {\n\tlet set = ((map[key == \"any\" ? key : normalizeKey(key)] ||= [])[precedence] ||= new Set())\n\n\tset.add(command)\n\n\treturn () =\u003e {\n\t\tset.delete(command)\n\t}\n}\n\n/**\n * Registers a sequential hotkey to the specifed editor.\n *\n * @param editor Editor to add the sequence to.\n * @param sequence Sequence of keys to press for the command to be executed.\n * @param command Command to execute when the sequence is pressed.\n * @returns Function to remove the hotkey.\n */\nconst addEditorHotkeySequence = \u003cT extends {}\u003e(\n\teditor: PrismEditor\u003cT\u003e,\n\tsequence: string[],\n\tcommand: EditorHotkey\u003cT\u003e,\n\toptions?: HotkeySequenceOptions,\n) =\u003e {\n\treturn addHotkeySequence(getMap(editor), sequence, command, options)\n}\n\n/**\n * Registers a sequential hotkey to the specifed hotkey map.\n *\n * @param map Map to add the sequence to.\n * @param sequence Sequence of keys to press for the command to be executed.\n * @param command Command to execute when the sequence is pressed.\n * @returns Function to remove the hotkey.\n */\nconst addHotkeySequence = \u003cT\u003e(\n\tmap: HotkeyMap\u003cT\u003e,\n\tsequence: string[],\n\tcommand: Hotkey\u003cT\u003e,\n\toptions: HotkeySequenceOptions = {},\n) =\u003e {\n\tlet lastTimestamp: number\n\tlet handledEvent: KeyboardEvent\n\tlet current = 0\n\tlet last = sequence.length - 1\n\tlet removeHandler: () =\u003e void\n\n\tif (last \u003c 0) throw Error(\"Sequence must have a least one key\")\n\n\tconst { timeout = 2000, precedence, preventDefault = true } = options\n\n\tconst handleStep: Hotkey\u003cT\u003e = (data, e, key) =\u003e {\n\t\tif (current) removeHandler()\n\t\tif (lastTimestamp + timeout \u003c (lastTimestamp = Date.now())) {\n\t\t\treturn\n\t\t}\n\n\t\thandledEvent = e\n\n\t\tif (current == last) {\n\t\t\tcurrent = 0\n\t\t\treturn command(data, e, key)\n\t\t}\n\n\t\tif (preventDefault) e.preventDefault()\n\t\tremoveHandler = addHotkey(map, sequence[++current], handleStep, 0)\n\t}\n\n\tconst removeStart = addHotkey(\n\t\tmap,\n\t\tsequence[0],\n\t\t(data, e, key) =\u003e {\n\t\t\tif (handledEvent != e) {\n\t\t\t\tlastTimestamp = Date.now()\n\t\t\t\tcurrent = 0\n\t\t\t\thandleStep(data, e, key)\n\t\t\t}\n\t\t},\n\t\tprecedence,\n\t)\n\n\tconst removeAny = addHotkey(map, \"any\", (_, e) =\u003e {\n\t\tif (current \u0026\u0026 handledEvent != e \u0026\u0026 !isModifierKey(e)) {\n\t\t\tcurrent = 0\n\t\t\tremoveHandler()\n\t\t}\n\t})\n\n\treturn () =\u003e {\n\t\tremoveStart()\n\t\tremoveAny()\n\t\tremoveHandler?.()\n\t}\n}\n\n/**\n * Returns whether the key pressed is Alt, Shift, Control, or Meta.\n * @param e Keyboard event to check.\n */\nconst isModifierKey = (e: KeyboardEvent) =\u003e {\n\treturn modifierCodes.has(e.keyCode)\n}\n\nconst modifierCodes = new Set([16, 17, 18, 91, 92, 224, 225])\n\nconst mod = isMac ? 4 : 2\n\nconst keyCodeMap: Record\u003cnumber, string | undefined\u003e = {\n\t32: \" \",\n\t173: \"-\",\n\t186: \";\",\n\t187: \"=\",\n\t188: \",\",\n\t189: \"-\",\n\t190: \".\",\n\t191: \"/\",\n\t192: \"`\",\n\t219: \"[\",\n\t220: \"\\\\\",\n\t221: \"]\",\n\t222: \"'\",\n}\n\nconst keyCodeMapShift: Record\u003cnumber, string | undefined\u003e = {\n\t48: \")\",\n\t49: \"!\",\n\t50: \"@\",\n\t51: \"#\",\n\t52: \"$\",\n\t53: \"%\",\n\t54: \"^\",\n\t55: \"\u0026\",\n\t56: \"*\",\n\t57: \"(\",\n\t59: \":\",\n\t61: \"+\",\n\t173: \"_\",\n\t186: \":\",\n\t187: \"+\",\n\t188: \"\u003c\",\n\t189: \"_\",\n\t190: \"\u003e\",\n\t191: \"?\",\n\t192: \"~\",\n\t219: \"{\",\n\t220: \"|\",\n\t221: \"}\",\n\t222: '\"',\n}\n\nconst modifierMap: Record\u003cstring, number | undefined\u003e = {\n\talt: 1,\n\tcontrol: 2,\n\tctrl: 2,\n\tmeta: 4,\n\tcmd: 4,\n\tshift: 8,\n\tmod: isMac ? 4 : 2,\n}\n\nexport {\n\tnormalizeKey,\n\tgetKeysFromEvent,\n\taddEditorHotkey,\n\taddHotkey,\n\taddEditorHotkeySequence,\n\taddHotkeySequence,\n\trunHotkeys,\n\tisModifierKey,\n\tmod,\n}\n","import { Language, languageMap } from \"../..\"\nimport { PrismEditor } from \"../../types.js\"\nimport {\n\tgetLanguage,\n\tgetLineBefore,\n\tgetLines,\n\tinsertText,\n\tisMac,\n\tregexEscape,\n} from \"../../utils/index.js\"\nimport { getLineEnd, getLineStart, getStyleValue } from \"../../utils/local\"\nimport { defaultCommands } from \"./deprecated.js\"\nimport { EditorHotkey } from \"./types.js\"\n\nlet ignoreTab = false\n\n/**\n * Sets whether editors should ignore tab or use it for indentation. Users can toggle\n * this using `Ctrl` + `M` / `Ctrl` + `Shift` + `M` (Mac) when the {@link defaultKeymap}\n * or {@link defaultCommands} extension is used.\n */\nconst setIgnoreTab = (newState: boolean) =\u003e (ignoreTab = newState)\nconst whitespaceEnd = (str: string) =\u003e str.search(/\\S|$/)\n\nconst getIndent = ({ options: { insertSpaces = true, tabSize } }: PrismEditor) =\u003e\n\t[insertSpaces ? \" \" : \"\\t\", insertSpaces ? tabSize || 2 : 1] as const\n\nconst scroll = (editor: PrismEditor) =\u003e\n\t!editor.options.readOnly \u0026\u0026 !editor.extensions.cursor?.scrollIntoView()\n\n/**\n * Inserts slightly altered lines while keeping the same selection.\n * Used when toggling comments and indenting.\n */\nconst insertLines = (\n\teditor: PrismEditor,\n\told: string[],\n\tnewL: string[],\n\tstart: number,\n\tend: number,\n\tselectionStart: number,\n\tselectionEnd: number,\n) =\u003e {\n\tlet newLines = newL.join(\"\\n\")\n\n\tif (newLines == old.join(\"\\n\")) return\n\n\tconst last = old.length - 1\n\tconst lastLine = newL[last]\n\tconst oldLastLine = old[last]\n\tconst lastDiff = oldLastLine.length - lastLine.length\n\tconst firstDiff = newL[0].length - old[0].length\n\tconst firstInsersion = start + whitespaceEnd((firstDiff \u003c 0 ? newL : old)[0])\n\tconst lastInsersion =\n\t\tend - oldLastLine.length + whitespaceEnd(lastDiff \u003e 0 ? lastLine : oldLastLine)\n\tconst offset = start - end + newLines.length + lastDiff\n\tconst newCursorStart =\n\t\tfirstInsersion \u003e selectionStart\n\t\t\t? selectionStart\n\t\t\t: Math.max(firstInsersion, selectionStart + firstDiff)\n\tconst newCursorEnd = selectionEnd + start - end + newLines.length\n\n\tinsertText(\n\t\teditor,\n\t\tnewLines,\n\t\tstart,\n\t\tend,\n\t\tnewCursorStart,\n\t\tselectionEnd \u003c lastInsersion\n\t\t\t? newCursorEnd + lastDiff\n\t\t\t: Math.max(lastInsersion + offset, newCursorEnd),\n\t)\n}\n\n/**\n * Command that indents or outdents all user-selected lines in the editor unless the\n * editor is `readOnly`.\n * @param editor Editor to execute the command on.\n * @param less By default lines are indented. By passing `true`, lines are outdented\n * instead.\n */\nconst indentSelectedLines = (editor: PrismEditor, less?: boolean) =\u003e {\n\tconst [start, end] = editor.getSelection()\n\tconst [lines, start1, end1] = getLines(editor.value, start, end)\n\tconst [indentChar, tabSize] = getIndent(editor)\n\n\tinsertLines(\n\t\teditor,\n\t\tlines,\n\t\tlines.map(\n\t\t\tless\n\t\t\t\t? str =\u003e str.slice(whitespaceEnd(str) ? tabSize - (whitespaceEnd(str) % tabSize) : 0)\n\t\t\t\t: str =\u003e str \u0026\u0026 indentChar.repeat(tabSize - (whitespaceEnd(str) % tabSize)) + str,\n\t\t),\n\t\tstart1,\n\t\tend1,\n\t\tstart,\n\t\tend,\n\t)\n\n\treturn scroll(editor)\n}\n\n/**\n * Command that inserts spaces if `insertSpaces` isn't `false` or a tab character\n * otherwise at the specified position unless the editor is `readOnly`.\n * @param editor Editor to execute the command on.\n * @param pos Position to insert the tab.\n */\nconst insertTab = (editor: PrismEditor, pos: number) =\u003e {\n\tconst [indentChar, tabSize] = getIndent(editor)\n\n\tinsertText(\n\t\teditor,\n\t\tindentChar.repeat(tabSize - ((pos - getLineStart(editor.value, pos)) % tabSize)),\n\t)\n\n\treturn scroll(editor)\n}\n\n/**\n * Command that inserts a new line replacing the current selection unless the editor is\n * `readOnly`. It uses the `autoIndent` behavior of the current language to determine\n * whether to preserve the indentation or increase it.\n * @param editor Editor to execute the command on.\n * @param eol If `true`, the new line is inserted at the end of the line instead of at\n * the cursor's position.\n */\nconst insertLineAndIndent = (editor: PrismEditor, eol?: boolean) =\u003e {\n\tlet selection = editor.getSelection()\n\tlet value = editor.value\n\n\tif (eol) selection[0] = selection[1] = getLineEnd(value, selection[1])\n\n\tconst [indentChar, tabSize] = getIndent(editor)\n\tconst [start, end] = selection\n\tconst autoIndent = languageMap[getLanguage(editor, start)]?.autoIndent\n\tconst indenationCount = Math.floor(whitespaceEnd(getLineBefore(value, start)) / tabSize) * tabSize\n\tconst extraIndent = autoIndent?.[0]?.(selection, value, editor) ? tabSize : 0\n\tconst extraLine = autoIndent?.[1]?.(selection, value, editor)\n\tconst newText =\n\t\t\"\\n\" +\n\t\tindentChar.repeat(indenationCount + extraIndent) +\n\t\t(extraLine ? \"\\n\" + indentChar.repeat(indenationCount) : \"\")\n\n\tif (newText[1] || value[end]) {\n\t\tinsertText(editor, newText, start, end, start + indenationCount + extraIndent + 1)\n\t\treturn scroll(editor)\n\t}\n}\n\n/**\n * Command that moves all selected lines unless the editor is `readOnly`.\n * @param editor Editor to execute the command on.\n * @param up Whether to move the lines up. Defaults to `false`.\n */\nconst moveSelectedLines = (editor: PrismEditor, up?: boolean) =\u003e {\n\tconst [start, end] = editor.getSelection()\n\tconst value = editor.value\n\tconst newStart = up ? getLineStart(value, start) - 1 : start\n\tconst newEnd = up ? end : value.indexOf(\"\\n\", end) + 1\n\n\tif (newStart \u003e -1 \u0026\u0026 newEnd \u003e 0) {\n\t\tconst [lines, start1, end1] = getLines(value, newStart, newEnd)\n\t\tconst line = lines[up ? \"shift\" : \"pop\"]()!\n\t\tconst offset = (line.length + 1) * (up ? -1 : 1)\n\n\t\tlines[up ? \"push\" : \"unshift\"](line)\n\t\tinsertText(editor, lines.join(\"\\n\"), start1, end1, start + offset, end + offset)\n\t}\n\n\treturn scroll(editor)\n}\n\n/**\n * Command that copies all selected lines unless the editor is `readOnly`.\n * @param editor Editor to execute the command on.\n * @param up Whether or not the selection should remain on the top copy. Defaults to\n * `false`.\n */\nconst copySelectedLines = (editor: PrismEditor, up?: boolean) =\u003e {\n\tconst [start, end] = editor.getSelection()\n\tconst value = editor.value\n\tconst [lines, start1, end1] = getLines(value, start, end)\n\tconst str = lines.join(\"\\n\")\n\tconst offset = up ? 0 : str.length + 1\n\n\tinsertText(editor, str + \"\\n\" + str, start1, end1, start + offset, end + offset)\n\treturn scroll(editor)\n}\n\n/**\n * Command that scrolls the editor by one line.\n * @param editor Editor to execute the command on.\n * @param up Whether to scroll up. Defaults to `false`.\n */\nconst scrollByOneLine = (editor: PrismEditor, up?: boolean) =\u003e {\n\teditor.container.scrollBy(0, getStyleValue(editor.container, \"lineHeight\") * (up ? -1 : 1))\n\treturn true\n}\n\n/**\n * Command that deletes all selected lines unless the editor is `readOnly`.\n * @param editor Editor to execute the command on.\n */\nconst deleteSelectedLines = (editor: PrismEditor) =\u003e {\n\tconst [start, end, dir] = editor.getSelection()\n\tconst value = editor.value\n\tconst [lines, start1, end1] = getLines(value, start, end)\n\tconst column = dir \u003e \"f\" ? end - end1 + lines.pop()!.length : start - start1\n\tconst newLineLen = getLineEnd(value, end1 + 1) - end1 - 1\n\n\tinsertText(\n\t\teditor,\n\t\t\"\",\n\t\tstart1 - \u003cany\u003e!!start1,\n\t\tend1 + \u003cany\u003e!start1,\n\t\tstart1 + Math.min(column, newLineLen),\n\t)\n\treturn scroll(editor)\n}\n\n/**\n * Command that toggles the comment around the current selection unless the editor is\n * `readOnly`. Comment syntax is determined using the current {@link Language}. It will\n * use the `getComments()` method if present and the `comments` property otherwise.\n * @param editor Editor to execute the command on.\n * @param isBlock Whether or not to toggle the comment using block syntax.\n */\nconst toggleComment = (editor: PrismEditor, isBlock?: boolean) =\u003e {\n\tconst [start, end] = editor.getSelection()\n\tconst value = editor.value\n\tconst position = isBlock ? start : getLineStart(value, start)\n\tconst lang = languageMap[getLanguage(editor, position)] || {}\n\tconst { line, block } = lang.getComments?.(editor, position, value) || lang.comments || {}\n\tconst [lines, start1, end1] = getLines(value, start, end)\n\tconst last = lines.length - 1\n\n\tif (isBlock) {\n\t\tif (block) {\n\t\t\tconst [open, close] = block\n\t\t\tconst text = value.slice(start, end)\n\t\t\tconst pos = value.slice(0, start).search(regexEscape(open) + \" ?$\")\n\n\t\t\tif (pos + 1 \u0026\u0026 RegExp(\"^ ?\" + regexEscape(close)).test(value.slice(end))) {\n\t\t\t\tinsertText(\n\t\t\t\t\teditor,\n\t\t\t\t\ttext,\n\t\t\t\t\tpos,\n\t\t\t\t\tend + \u003cany\u003e(value[end] == \" \") + close.length,\n\t\t\t\t\tpos,\n\t\t\t\t\tpos + end - start,\n\t\t\t\t)\n\t\t\t} else {\n\t\t\t\tinsertText(\n\t\t\t\t\teditor,\n\t\t\t\t\t`${open} ${text} ${close}`,\n\t\t\t\t\tstart,\n\t\t\t\t\tend,\n\t\t\t\t\tstart + open.length + 1,\n\t\t\t\t\tend + open.length + 1,\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif (line) {\n\t\t\tconst escaped = regexEscape(line)\n\t\t\tconst regex = RegExp(`^\\\\s*(${escaped} ?|$)`)\n\t\t\tconst regex2 = RegExp(escaped + \" ?\")\n\t\t\tconst allWhiteSpace = !/\\S/.test(value.slice(start1, end1))\n\t\t\tconst newLines = lines.map(\n\t\t\t\t!allWhiteSpace \u0026\u0026 lines.every(line =\u003e regex.test(line))\n\t\t\t\t\t? str =\u003e str.replace(regex2, \"\")\n\t\t\t\t\t: str =\u003e (allWhiteSpace || /\\S/.test(str) ? str.replace(/(?!\\s)/, line + \" \") : str),\n\t\t\t)\n\t\t\tinsertLines(editor, lines, newLines, start1, end1, start, end)\n\t\t} else if (block) {\n\t\t\tconst [open, close] = block\n\t\t\tconst first = lines[0]\n\t\t\tconst insertionPoint = whitespaceEnd(first)\n\t\t\tconst hasComment = first.startsWith(open, insertionPoint) \u0026\u0026 lines[last].endsWith(close)\n\n\t\t\tlines[0] = first.replace(\n\t\t\t\thasComment ? RegExp(regexEscape(open) + \" ?\") : /(?!\\s)/,\n\t\t\t\thasComment ? \"\" : open + \" \",\n\t\t\t)\n\t\t\tlet diff = lines[0].length - first.length\n\t\t\tlines[last] = hasComment\n\t\t\t\t? lines[last].replace(RegExp(` ?${regexEscape(close)}$`), \"\")\n\t\t\t\t: lines[last] + \" \" + close\n\n\t\t\tlet newText = lines.join(\"\\n\")\n\t\t\tlet firstInsersion = insertionPoint + start1\n\t\t\tlet newStart = firstInsersion \u003e start ? start : Math.max(start + diff, firstInsersion)\n\t\t\tlet newEnd =\n\t\t\t\tfirstInsersion \u003e end - \u003cany\u003e(start != end)\n\t\t\t\t\t? end\n\t\t\t\t\t: Math.min(Math.max(firstInsersion, end + diff), start1 + newText.length)\n\t\t\tinsertText(editor, newText, start1, end1, newStart, Math.max(newStart, newEnd))\n\t\t}\n\t}\n\n\treturn block || (line \u0026\u0026 !isBlock) ? scroll(editor) : false\n}\n\n/**\n * Default keymapping that includes the following commands:\n *\n * - `Alt` + `ArrowUp`: Move line up\n * - `Alt` + `ArrowDown`: Move line down\n * - `Ctrl` + `ArrowUp`: Scroll one line up (Windows/Linux)\n * - `Ctrl` + `ArrowDown`: Scroll one line down (Windows/Linux)\n * - `Ctrl` + `PageUp`: Scroll one line up (Mac)\n * - `Ctrl` + `PageDown`: Scroll one line down (Mac)\n * - `Shift` + `Alt` + `ArrowUp`: Copy line up\n * - `Shift` + `Alt` + `ArrowDown`: Copy line down\n * - `Enter`: Insert line and indent\n * - `Shift` + `Enter`: Insert line and indent\n * - `Mod` + `Enter`: Insert blank line\n * - `Mod` + `]`: Indent line\n * - `Mod` + `[`: Outdent line\n * - `Tab`: Indent line (Tab capture enabled)\n * - `Shift` + `Tab`: Outdent line (Tab capture enabled)\n * - `Shift` + `Mod` + `K`: Delete line\n * - `Mod` + `/`: Toggle comment\n * - `Shift` + `Alt` + `A`: Toggle block comment\n * - `Ctrl` + `M`: Toggle tab capturing (Windows/Linux)\n * - `Ctrl` + `Shift` + `M`: Toggle tab capturing (Mac)\n *\n * Here, `Mod` refers to `Cmd` on Mac and `Ctrl` otherwise.\n */\nconst defaultKeymap: Record\u003cstring, EditorHotkey\u003e = {\n\tTab(editor) {\n\t\tif (!ignoreTab) {\n\t\t\tconst [start, end] = editor.getSelection()\n\t\t\treturn start == end ? insertTab(editor, start) : indentSelectedLines(editor)\n\t\t}\n\t},\n\t\"8+Tab\": editor =\u003e !ignoreTab \u0026\u0026 indentSelectedLines(editor, true),\n\t\"1+ArrowDown\": editor =\u003e moveSelectedLines(editor),\n\t\"1+ArrowUp\": editor =\u003e moveSelectedLines(editor, true),\n\t\"9+ArrowDown\": editor =\u003e copySelectedLines(editor),\n\t\"9+ArrowUp\": editor =\u003e copySelectedLines(editor, true),\n\tEnter: editor =\u003e insertLineAndIndent(editor),\n\t\"8+Enter\": editor =\u003e insertLineAndIndent(editor),\n\t\"Mod+Enter\": editor =\u003e insertLineAndIndent(editor, true),\n\t\"Mod+]\": editor =\u003e indentSelectedLines(editor),\n\t\"Mod+[\": editor =\u003e indentSelectedLines(editor, true),\n\t\"8+Mod+k\": deleteSelectedLines,\n\t\"Mod+/\": editor =\u003e toggleComment(editor),\n\t\"9+a\": editor =\u003e toggleComment(editor, true),\n\t[isMac ? \"10+m\" : \"2+m\"]: () =\u003e ((ignoreTab = !ignoreTab), true),\n\t[`2+${isMac ? \"Page\" : \"Arrow\"}Down`]: editor =\u003e scrollByOneLine(editor),\n\t[`2+${isMac ? \"Page\" : \"Arrow\"}Up`]: editor =\u003e scrollByOneLine(editor, true),\n}\n\nexport {\n\twhitespaceEnd,\n\tscroll,\n\tindentSelectedLines,\n\tinsertTab,\n\tinsertLineAndIndent,\n\tmoveSelectedLines,\n\tcopySelectedLines,\n\tscrollByOneLine,\n\tdeleteSelectedLines,\n\ttoggleComment,\n\tsetIgnoreTab,\n\tdefaultKeymap,\n\tignoreTab,\n}\n","import { InputSelection, BasicExtension } from \"../../index.js\"\nimport { preventDefault, languageMap } from \"../../core.js\"\nimport {\n\tgetLanguage,\n\tinsertText,\n\tgetLineBefore,\n\tgetLines,\n\tregexEscape,\n\tgetModifierCode,\n\tsetSelection,\n\tisMac,\n} from \"../../utils/index.js\"\nimport { addTextareaListener, getLineEnd, getLineStart, getStyleValue } from \"../../utils/local.js\"\nimport { mod } from \"./utils.js\"\nimport { ignoreTab, setIgnoreTab, whitespaceEnd } from \"./commands.js\"\nimport { editorCommands } from \"./index.js\"\n\n/**\n * Extension that will add automatic indentation and closing of brackets, quotes, and\n * tags along with the commands presented later.\n *\n * ## Commands\n *\n * Here, `Mod` refers to `Cmd` on Mac and `Ctrl` otherwise.\n *\n * - `Alt` + `ArrowUp`: Move line up\n * - `Alt` + `ArrowDown`: Move line down\n * - `Ctrl` + `ArrowUp`: Scroll one line up (Windows/Linux only)\n * - `Ctrl` + `ArrowDown`: Scroll one line down (Windows/Linux only)\n * - `Shift` + `Alt` + `ArrowUp`: Copy line up\n * - `Shift` + `Alt` + `ArrowDown`: Copy line down\n * - `Mod` + `Enter`: Insert blank line\n * - `Mod` + `]`: Indent line\n * - `Mod` + `[`: Outdent line\n * - `Tab`: Indent line (Tab capture enabled)\n * - `Shift` + `Tab`: Outdent line (Tab capture enabled)\n * - `Shift` + `Mod` + `K`: Delete line\n * - `Mod` + `/`: Toggle comment\n * - `Shift` + `Alt` + `A`: Toggle block comment\n * - `Ctrl` + `M`: Toggle tab capturing (Windows/Linux)\n * - `Ctrl` + `Shift` + `M`: Toggle tab capturing (Mac)\n *\n * @param selfClosePairs Pairs of self-closing brackets and quotes.\n * Must be an array of strings with 2 characters each.\n * Defaults to `['\"\"', \"''\", '``', '()', '[]', '{}']`.\n * @param selfCloseRegex Regex controlling whether or not a bracket/quote should\n * automatically close based on the character before and after the cursor.\n * Defaults to ``/([^$\\w'\"`][\"'`]|.[[({])[.,:;\\])}\u003e\\s]|.[[({]`/s``.\n *\n * @deprecated Consider using {@link editorCommands} instead. This will be removed in next\n * major release.\n */\nconst defaultCommands = (\n\tselfClosePairs = ['\"\"', \"''\", \"``\", \"()\", \"[]\", \"{}\"],\n\tselfCloseRegex = /([^$\\w'\"`][\"'`]|.[[({])[.,:;\\])}\u003e\\s]|.[[({]`/s,\n): BasicExtension =\u003e {\n\treturn (editor, options) =\u003e {\n\t\tlet prevCopy: string\n\t\tconst { keyCommandMap, inputCommandMap, getSelection, container } = editor\n\n\t\tconst clipboard = navigator.clipboard\n\n\t\tconst getIndent = ({ insertSpaces = true, tabSize } = options) =\u003e\n\t\t\t[insertSpaces ? \" \" : \"\\t\", insertSpaces ? tabSize || 2 : 1] as const\n\n\t\tconst scroll = () =\u003e !options.readOnly \u0026\u0026 !editor.extensions.cursor?.scrollIntoView()\n\n\t\t/**\n\t\t * Automatically closes quotes and brackets if text is selected,\n\t\t * or if the character before and after the cursor matches a regex\n\t\t * @param wrapOnly If true, the character will only be closed if text is selected.\n\t\t */\n\t\tconst selfClose = (\n\t\t\t[start, end]: InputSelection,\n\t\t\t[open, close]: string,\n\t\t\tvalue: string,\n\t\t\twrapOnly?: boolean,\n\t\t) =\u003e\n\t\t\t(start \u003c end ||\n\t\t\t\t(!wrapOnly \u0026\u0026 selfCloseRegex.test((value[end - 1] || \" \") + open + (value[end] || \" \")))) \u0026\u0026\n\t\t\t!insertText(editor, open + value.slice(start, end) + close, null, null, start + 1, end + 1)!\n\n\t\tconst skipIfEqual = ([start, end]: InputSelection, char: string, value: string) =\u003e\n\t\t\tstart == end \u0026\u0026 value[end] == char \u0026\u0026 !setSelection(editor, start + 1)!\n\n\t\t/**\n\t\t * Inserts slightly altered lines while keeping the same selection.\n\t\t * Used when toggling comments and indenting.\n\t\t */\n\t\tconst insertLines = (\n\t\t\told: string[],\n\t\t\tnewL: string[],\n\t\t\tstart: number,\n\t\t\tend: number,\n\t\t\tselectionStart: number,\n\t\t\tselectionEnd: number,\n\t\t) =\u003e {\n\t\t\tlet newLines = newL.join(\"\\n\")\n\t\t\tif (newLines != old.join(\"\\n\")) {\n\t\t\t\tconst last = old.length - 1\n\t\t\t\tconst lastLine = newL[last]\n\t\t\t\tconst oldLastLine = old[last]\n\t\t\t\tconst lastDiff = oldLastLine.length - lastLine.length\n\t\t\t\tconst firstDiff = newL[0].length - old[0].length\n\t\t\t\tconst firstInsersion = start + whitespaceEnd((firstDiff \u003c 0 ? newL : old)[0])\n\t\t\t\tconst lastInsersion =\n\t\t\t\t\tend - oldLastLine.length + whitespaceEnd(lastDiff \u003e 0 ? lastLine : oldLastLine)\n\t\t\t\tconst offset = start - end + newLines.length + lastDiff\n\t\t\t\tconst newCursorStart =\n\t\t\t\t\tfirstInsersion \u003e selectionStart\n\t\t\t\t\t\t? selectionStart\n\t\t\t\t\t\t: Math.max(firstInsersion, selectionStart + firstDiff)\n\t\t\t\tconst newCursorEnd = selectionEnd + start - end + newLines.length\n\t\t\t\tinsertText(\n\t\t\t\t\teditor,\n\t\t\t\t\tnewLines,\n\t\t\t\t\tstart,\n\t\t\t\t\tend,\n\t\t\t\t\tnewCursorStart,\n\t\t\t\t\tselectionEnd \u003c lastInsersion\n\t\t\t\t\t\t? newCursorEnd + lastDiff\n\t\t\t\t\t\t: Math.max(lastInsersion + offset, newCursorEnd),\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\tconst indent = (\n\t\t\toutdent: boolean,\n\t\t\tlines: string[],\n\t\t\tstart1: number,\n\t\t\tend1: number,\n\t\t\tstart: number,\n\t\t\tend: number,\n\t\t\tindentChar: string,\n\t\t\ttabSize: number,\n\t\t) =\u003e {\n\t\t\tinsertLines(\n\t\t\t\tlines,\n\t\t\t\tlines.map(\n\t\t\t\t\toutdent\n\t\t\t\t\t\t? str =\u003e str.slice(whitespaceEnd(str) ? tabSize - (whitespaceEnd(str) % tabSize) : 0)\n\t\t\t\t\t\t: str =\u003e str \u0026\u0026 indentChar.repeat(tabSize - (whitespaceEnd(str) % tabSize)) + str,\n\t\t\t\t),\n\t\t\t\tstart1,\n\t\t\t\tend1,\n\t\t\t\tstart,\n\t\t\t\tend,\n\t\t\t)\n\t\t}\n\n\t\tinputCommandMap[\"\u003c\"] = (_e, selection, value) =\u003e selfClose(selection, \"\u003c\u003e\", value, true)\n\n\t\tselfClosePairs.forEach(([open, close]) =\u003e {\n\t\t\tconst isQuote = open == close\n\t\t\tinputCommandMap[open] = (_e, selection, value) =\u003e\n\t\t\t\t((isQuote \u0026\u0026 skipIfEqual(selection, close, value)) ||\n\t\t\t\t\tselfClose(selection, open + close, value)) \u0026\u0026\n\t\t\t\tscroll()\n\t\t\tif (!isQuote)\n\t\t\t\tinputCommandMap[close] = (_e, selection, value) =\u003e\n\t\t\t\t\tskipIfEqual(selection, close, value) \u0026\u0026 scroll()\n\t\t})\n\n\t\tinputCommandMap[\"\u003e\"] = (e, selection, value) =\u003e {\n\t\t\tconst closingTag = languageMap[getLanguage(editor)]?.autoCloseTags?.(selection, value, editor)\n\t\t\tif (closingTag) {\n\t\t\t\tinsertText(editor, \"\u003e\" + closingTag, null, null, selection[0] + 1)\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\t\t}\n\n\t\tkeyCommandMap.Tab = (e, [start, end], value) =\u003e {\n\t\t\tif (ignoreTab || options.readOnly || getModifierCode(e) \u0026 7) return\n\t\t\tconst [indentChar, tabSize] = getIndent()\n\t\t\tconst shiftKey = e.shiftKey\n\t\t\tconst [lines, start1, end1] = getLines(value, start, end)\n\t\t\tif (start \u003c end || shiftKey) {\n\t\t\t\tindent(shiftKey, lines, start1, end1, start, end, indentChar, tabSize)\n\t\t\t} else insertText(editor, indentChar.repeat(tabSize - ((start - start1) % tabSize)))\n\t\t\treturn scroll()\n\t\t}\n\n\t\tkeyCommandMap.Enter = (e, selection, value) =\u003e {\n\t\t\tconst code = getModifierCode(e) \u0026 7\n\t\t\tif (!code || code == mod) {\n\t\t\t\tif (code) selection[0] = selection[1] = getLines(value, selection[1])[2]\n\t\t\t\tconst [indentChar, tabSize] = getIndent()\n\t\t\t\tconst [start, end] = selection\n\t\t\t\tconst autoIndent = languageMap[getLanguage(editor, start)]?.autoIndent\n\t\t\t\tconst indenationCount =\n\t\t\t\t\tMath.floor(whitespaceEnd(getLineBefore(value, start)) / tabSize) * tabSize\n\t\t\t\tconst extraIndent = autoIndent?.[0]?.(selection, value, editor) ? tabSize : 0\n\t\t\t\tconst extraLine = autoIndent?.[1]?.(selection, value, editor)\n\t\t\t\tconst newText =\n\t\t\t\t\t\"\\n\" +\n\t\t\t\t\tindentChar.repeat(indenationCount + extraIndent) +\n\t\t\t\t\t(extraLine ? \"\\n\" + indentChar.repeat(indenationCount) : \"\")\n\n\t\t\t\tif (newText[1] || value[end]) {\n\t\t\t\t\tinsertText(editor, newText, start, end, start + indenationCount + extraIndent + 1)\n\t\t\t\t\treturn scroll()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tkeyCommandMap.Backspace = (_e, [start, end], value) =\u003e {\n\t\t\tif (start == end) {\n\t\t\t\tconst line = getLineBefore(value, start)\n\t\t\t\tconst tabSize = options.tabSize || 2\n\t\t\t\tconst isPair = selfClosePairs.includes(value.slice(start - 1, start + 1))\n\t\t\t\tconst indenationCount = /[^ ]/.test(line) ? 0 : ((line.length - 1) % tabSize) + 1\n\n\t\t\t\tif (isPair || indenationCount \u003e 1) {\n\t\t\t\t\tinsertText(editor, \"\", start - (isPair ? 1 : indenationCount), start + \u003cany\u003eisPair)\n\t\t\t\t\treturn scroll()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (let i = 0; i \u003c 2; i++) {\n\t\t\tkeyCommandMap[i ? \"ArrowDown\" : \"ArrowUp\"] = (e, [start, end], value) =\u003e {\n\t\t\t\tconst code = getModifierCode(e)\n\n\t\t\t\tif (code == 1) {\n\t\t\t\t\t// Moving lines\n\t\t\t\t\tconst newStart = i ? start : getLineStart(value, start) - 1\n\t\t\t\t\tconst newEnd = i ? value.indexOf(\"\\n\", end) + 1 : end\n\t\t\t\t\tif (newStart \u003e -1 \u0026\u0026 newEnd \u003e 0) {\n\t\t\t\t\t\tconst [lines, start1, end1] = getLines(value, newStart, newEnd)\n\t\t\t\t\t\tconst line = lines[i ? \"pop\" : \"shift\"]()!\n\t\t\t\t\t\tconst offset = (line.length + 1) * (i ? 1 : -1)\n\n\t\t\t\t\t\tlines[i ? \"unshift\" : \"push\"](line)\n\t\t\t\t\t\tinsertText(editor, lines.join(\"\\n\"), start1, end1, start + offset, end + offset)\n\t\t\t\t\t}\n\t\t\t\t\treturn scroll()\n\t\t\t\t} else if (code == 9) {\n\t\t\t\t\t// Copying lines\n\t\t\t\t\tconst [lines, start1, end1] = getLines(value, start, end)\n\t\t\t\t\tconst str = lines.join(\"\\n\")\n\t\t\t\t\tconst offset = i ? str.length + 1 : 0\n\t\t\t\t\tinsertText(editor, str + \"\\n\" + str, start1, end1, start + offset, end + offset)\n\t\t\t\t\treturn scroll()\n\t\t\t\t} else if (code == 2 \u0026\u0026 !isMac) {\n\t\t\t\t\tcontainer.scrollBy(0, getStyleValue(container, \"lineHeight\") * (i ? 1 : -1))\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\taddTextareaListener(editor, \"keydown\", e =\u003e {\n\t\t\tconst code = getModifierCode(e)\n\t\t\tconst keyCode = e.keyCode\n\t\t\tconst [start, end, dir] = getSelection()\n\n\t\t\tif (code == mod \u0026\u0026 (keyCode == 221 || keyCode == 219)) {\n\t\t\t\tindent(keyCode == 219, ...getLines(editor.value, start, end), start, end, ...getIndent())\n\t\t\t\tscroll()\n\t\t\t\tpreventDefault(e)\n\t\t\t} else if (code == (isMac ? 0b1010 : 0b0010) \u0026\u0026 keyCode == 77) {\n\t\t\t\tsetIgnoreTab(!ignoreTab)\n\t\t\t\tpreventDefault(e)\n\t\t\t} else if ((keyCode == 191 \u0026\u0026 code == mod) || (keyCode == 65 \u0026\u0026 code == 9)) {\n\t\t\t\tconst value = editor.value\n\t\t\t\tconst isBlock = code == 9\n\t\t\t\tconst position = isBlock ? start : getLineStart(value, start)\n\t\t\t\tconst language = languageMap[getLanguage(editor, position)] || {}\n\t\t\t\tconst { line, block } =\n\t\t\t\t\tlanguage.getComments?.(editor, position, value) || language.comments || {}\n\t\t\t\tconst [lines, start1, end1] = getLines(value, start, end)\n\t\t\t\tconst last = lines.length - 1\n\n\t\t\t\tif (isBlock) {\n\t\t\t\t\tif (block) {\n\t\t\t\t\t\tconst [open, close] = block\n\t\t\t\t\t\tconst text = value.slice(start, end)\n\t\t\t\t\t\tconst pos = value.slice(0, start).search(regexEscape(open) + \" ?$\")\n\n\t\t\t\t\t\tif (pos + 1 \u0026\u0026 RegExp(\"^ ?\" + regexEscape(close)).test(value.slice(end)))\n\t\t\t\t\t\t\tinsertText(\n\t\t\t\t\t\t\t\teditor,\n\t\t\t\t\t\t\t\ttext,\n\t\t\t\t\t\t\t\tpos,\n\t\t\t\t\t\t\t\tend + \u003cany\u003e(value[end] == \" \") + close.length,\n\t\t\t\t\t\t\t\tpos,\n\t\t\t\t\t\t\t\tpos + end - start,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tinsertText(\n\t\t\t\t\t\t\t\teditor,\n\t\t\t\t\t\t\t\t`${open} ${text} ${close}`,\n\t\t\t\t\t\t\t\tstart,\n\t\t\t\t\t\t\t\tend,\n\t\t\t\t\t\t\t\tstart + open.length + 1,\n\t\t\t\t\t\t\t\tend + open.length + 1,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\tscroll()\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (line) {\n\t\t\t\t\t\tconst escaped = regexEscape(line)\n\t\t\t\t\t\tconst regex = RegExp(`^\\\\s*(${escaped} ?|$)`)\n\t\t\t\t\t\tconst regex2 = RegExp(escaped + \" ?\")\n\t\t\t\t\t\tconst allWhiteSpace = !/\\S/.test(value.slice(start1, end1))\n\t\t\t\t\t\tconst newLines = lines.map(\n\t\t\t\t\t\t\t!allWhiteSpace \u0026\u0026 lines.every(line =\u003e regex.test(line))\n\t\t\t\t\t\t\t\t? str =\u003e str.replace(regex2, \"\")\n\t\t\t\t\t\t\t\t: str =\u003e\n\t\t\t\t\t\t\t\t\t\tallWhiteSpace || /\\S/.test(str) ? str.replace(/(?!\\s)/, line + \" \") : str,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tinsertLines(lines, newLines, start1, end1, start, end)\n\t\t\t\t\t\tscroll()\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t} else if (block) {\n\t\t\t\t\t\tconst [open, close] = block\n\t\t\t\t\t\tconst first = lines[0]\n\t\t\t\t\t\tconst insertionPoint = whitespaceEnd(first)\n\t\t\t\t\t\tconst hasComment = first.startsWith(open, insertionPoint) \u0026\u0026 lines[last].endsWith(close)\n\n\t\t\t\t\t\tlines[0] = first.replace(\n\t\t\t\t\t\t\thasComment ? RegExp(regexEscape(open) + \" ?\") : /(?!\\s)/,\n\t\t\t\t\t\t\thasComment ? \"\" : open + \" \",\n\t\t\t\t\t\t)\n\t\t\t\t\t\tlet diff = lines[0].length - first.length\n\t\t\t\t\t\tlines[last] = hasComment\n\t\t\t\t\t\t\t? lines[last].replace(RegExp(` ?${regexEscape(close)}$`), \"\")\n\t\t\t\t\t\t\t: lines[last] + \" \" + close\n\n\t\t\t\t\t\tlet newText = lines.join(\"\\n\")\n\t\t\t\t\t\tlet firstInsersion = insertionPoint + start1\n\t\t\t\t\t\tlet newStart = firstInsersion \u003e start ? start : Math.max(start + diff, firstInsersion)\n\t\t\t\t\t\tlet newEnd =\n\t\t\t\t\t\t\tfirstInsersion \u003e end - \u003cany\u003e(start != end)\n\t\t\t\t\t\t\t\t? end\n\t\t\t\t\t\t\t\t: Math.min(Math.max(firstInsersion, end + diff), start1 + newText.length)\n\t\t\t\t\t\tinsertText(editor, newText, start1, end1, newStart, Math.max(newStart, newEnd))\n\t\t\t\t\t\tscroll()\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (code == 8 + mod \u0026\u0026 keyCode == 75) {\n\t\t\t\tconst value = editor.value\n\t\t\t\tconst [lines, start1, end1] = getLines(value, start, end)\n\t\t\t\tconst column = dir \u003e \"f\" ? end - end1 + lines.pop()!.length : start - start1\n\t\t\t\tconst newLineLen = getLineEnd(value, end1 + 1) - end1 - 1\n\t\t\t\tinsertText(\n\t\t\t\t\teditor,\n\t\t\t\t\t\"\",\n\t\t\t\t\tstart1 - \u003cany\u003e!!start1,\n\t\t\t\t\tend1 + \u003cany\u003e!start1,\n\t\t\t\t\tstart1 + Math.min(column, newLineLen),\n\t\t\t\t)\n\t\t\t\tscroll()\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\t\t})\n\t\t;([\"copy\", \"cut\", \"paste\"] as const).forEach(type =\u003e\n\t\t\taddTextareaListener(editor, type, e =\u003e {\n\t\t\t\tconst [start, end] = getSelection()\n\t\t\t\tif (start == end \u0026\u0026 clipboard) {\n\t\t\t\t\tconst [[line], start1, end1] = getLines(editor.value, start, end)\n\t\t\t\t\tif (type == \"paste\") {\n\t\t\t\t\t\tif (e.clipboardData!.getData(\"text/plain\") == prevCopy) {\n\t\t\t\t\t\t\tinsertText(editor, prevCopy + \"\\n\", start1, start1, start + prevCopy.length + 1)\n\t\t\t\t\t\t\tscroll()\n\t\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclipboard.writeText((prevCopy = line))\n\t\t\t\t\t\tif (type == \"cut\") insertText(editor, \"\", start1, end1 + 1), scroll()\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}),\n\t\t)\n\t}\n}\n\nexport { defaultCommands }\n","import { isMac } from \"../../utils/index.js\"\nimport { autoComplete } from \"../autocomplete/tooltip.js\"\nimport { searchWidget } from \"../search/widget.js\"\nimport { defaultKeymap } from \"./commands.js\"\nimport { normalizeKey } from \"./utils.js\"\n\nconst macModifiers: Record\u003cnumber, string\u003e = {\n\t2: \"⌃\",\n\t1: \"⌥\",\n\t8: \"⇧\",\n\t4: \"⌘\",\n}\n\nconst winModifiers: Record\u003cnumber, string\u003e = {\n\t2: \"Ctrl\",\n\t1: \"Alt\",\n\t8: \"Shift\",\n\t4: \"Win\",\n}\n\nconst keyDisplay: Record\u003cstring, string | undefined\u003e = {\n\tarrowdown: \"↓\",\n\tarrowleft: \"←\",\n\tarrowright: \"→\",\n\tarrowup: \"↑\",\n\tdelete: \"Del\",\n\tescape: \"Esc\",\n\tpagedown: \"PageDown\",\n\tpageup: \"PageUp\",\n\t\" \": \"Space\",\n}\n\n/**\n * Utility that formats a hotkey to display in a user interface. Modifier keys use symbols\n * on Mac and labels otherwise.\n *\n * @param hotkey Hotkey to format for display.\n * @param separator String to join the segments together with. Defaults to `\" \"` on Mac\n * and `\"+\"` otherwise.\n * @returns Formatted key for display.\n *\n * @example\n * // On Mac\n * formatHotkey(\"mod+s\") // \"⌘ S\"\n * formatHotkey(\"12+escape\") // \"⇧ ⌘ Esc\"\n * formatHotkey(\"arrowup\") // \"↑\"\n *\n * // On Windows/Linux\n * formatHotkey(\"mod+s\") // \"Ctrl+S\"\n * formatHotkey(\"12+escape\") // \"Shift+Win+Esc\"\n * formatHotkey(\"arrowup\") // \"↑\"\n */\nconst formatHotkey = (hotkey: string, separator = isMac ? \" \" : \"+\") =\u003e {\n\tconst [code, key] = normalizeKey(hotkey).split(\"+\")\n\tconst result: string[] = []\n\tconst modifiers = isMac ? macModifiers : winModifiers\n\n\tfor (let c in modifiers) {\n\t\tif (+code \u0026 +c) result.push(modifiers[c])\n\t}\n\n\tresult.push(key ? keyDisplay[key] || key[0].toUpperCase() + key.slice(1) : \"+\")\n\n\treturn result.join(separator)\n}\n\n/**\n * Array of keyboard shortcuts and descriptions for {@link defaultKeymap}. Useful for\n * documenting key bindings to users. It consists of tuples containing two string each\n * where the first string is the key binding and the second is the description.\n *\n * @example\n * for (const [key, description] of defaultKeymapLabels) {\n *   console.log(formatHotkey(key), description)\n * }\n */\nconst defaultKeymapLabels: [string, string][] = [\n\t[\"1+ArrowDown\", \"Move lines down\"],\n\t[\"1+ArrowUp\", \"Move lines up\"],\n\t[\"9+ArrowDown\", \"Copy lines down\"],\n\t[\"9+ArrowUp\", \"Copy lines up\"],\n\t[`2+${isMac ? \"Page\" : \"Arrow\"}Down`, \"Scroll one line down\"],\n\t[`2+${isMac ? \"Page\" : \"Arrow\"}Up`, \"Scroll one line up\"],\n\t[\"Enter\", \"Insert line and indent\"],\n\t[\"Mod+Enter\", \"Insert blank line\"],\n\t[\"Mod+]\", \"Indent lines\"],\n\t[\"Mod+[\", \"Outdent lines\"],\n\t[\"8+Mod+k\", \"Delete lines\"],\n\t[\"Mod+/\", \"Toggle line comment\"],\n\t[\"9+a\", \"Toggle block comment\"],\n\t[isMac ? \"10+m\" : \"2+m\", \"Toggle tab capturing\"],\n\t[\"Tab\", \"Indent lines\"],\n\t[\"8+Tab\", \"Outdent lines\"],\n]\n\n/**\n * Array of keyboard shortcuts and descriptions for the {@link autoComplete} extension.\n * Useful for documenting key bindings to users. It consists of tuples containing two\n * string each where the first string is the key binding and the second is the description.\n *\n * @example\n * for (const [key, description] of autoCompleteShortcutLabels) {\n *   console.log(formatHotkey(key), description)\n * }\n */\nconst autoCompleteShortcutLabels: [string, string][] = [\n\t[\"2+ \", \"Trigger suggestion\"],\n\t[\"mod+i\", \"Trigger suggestion\"],\n\t...(isMac ? ([[\"1+Escape\", \"Trigger suggestion\"]] satisfies [string, string][]) : []),\n\t[\"2+ \", \"Toggle suggestion documentation\"],\n\t[\"mod+i\", \"Toggle suggestion documentation\"],\n\t[\"Tab\", \"Insert suggestion\"],\n\t[\"Enter\", \"Insert suggestion\"],\n\t[\"Escape\", \"Close completion widget\"],\n\t[\"Escape\", \"Clear tab stops\"],\n\t[\"Tab\", \"Select next tab stop\"],\n\t[\"8+Tab\", \"Select previous tab stop\"],\n\t[\"ArrowUp\", \"Select previous suggestion\"],\n\t[\"ArrowDown\", \"Select next suggestion\"],\n\t[\"PageUp\", \"Select first visible suggestion\"],\n\t[\"PageDown\", \"Select last visible suggestion\"],\n]\n\nconst modifiers = isMac ? 5 : 1\n\n/**\n * Array of keyboard shortcuts and descriptions for the {@link searchWidget} extension.\n * Useful for documenting key bindings to users. It consists of tuples containing two\n * string each where the first string is the key binding and the second is the description.\n *\n * @example\n * for (const [key, description] of searchShortcutLabels) {\n *   console.log(formatHotkey(key), description)\n * }\n */\nconst searchShortcutLabels: [string, string][] = [\n\t[\"mod+f\", \"Start search\"],\n\t[\"mod+g\", \"Find next match\"],\n\t[\"mod+8+g\", \"Find previous match\"],\n\t[\"f3\", \"Find next match\"],\n\t[\"8+f3\", \"Find previous match\"],\n\t[\"Enter\", \"Select next match\"],\n\t[\"8+Enter\", \"Select previous match\"],\n\t[\"Escape\", \"Close search widget\"],\n\t[\"Enter\", \"Replace match\"],\n\t[`${isMac ? 4 : 3}+Enter`, \"Replace all matches\"],\n\t[modifiers + \"+r\", \"Toggle regex search\"],\n\t[modifiers + \"+p\", \"Toggle case preservation\"],\n\t[modifiers + \"+w\", \"Toggle whole word search\"],\n\t[modifiers + \"+l\", \"Toggle find in selection\"],\n]\n\nexport { formatHotkey, defaultKeymapLabels, autoCompleteShortcutLabels, searchShortcutLabels }\n","/** @module commands */\n\nimport { InputSelection, BasicExtension, PrismEditor } from \"../../index.js\"\nimport { preventDefault, languageMap } from \"../../core.js\"\nimport {\n\tgetLanguage,\n\tinsertText,\n\tgetLines,\n\tgetModifierCode,\n\tprevSelection,\n\tsetSelection,\n\tisMac,\n\tgetLineBefore,\n} from \"../../utils/index.js\"\nimport { addTextareaListener } from \"../../utils/local.js\"\nimport { EditHistory, EditorHotkey } from \"./types.js\"\nimport { mod, addEditorHotkey } from \"./utils.js\"\nimport { scroll } from \"./commands.js\"\n\n/**\n * Extension that will add automatic closing of brackets, quotes, and tags along\n * with the specified commands.\n *\n * @param hotkeyMap Commands that will be added to the editor.\n * @param selfClosePairs Pairs of self-closing brackets and quotes.\n * Must be an array of strings with 2 characters each.\n * Defaults to `['\"\"', \"''\", '``', '()', '[]', '{}']`.\n * @param selfCloseRegex Regex controlling whether or not a bracket/quote should\n * automatically close based on the character before and after the cursor.\n * Defaults to ``/([^$\\w'\"`][\"'`]|.[[({])[.,:;\\])}\u003e\\s]|.[[({]`/s``.\n */\nconst editorCommands = (\n\thotkeyMap: Record\u003cstring, EditorHotkey\u003e,\n\tselfClosePairs = ['\"\"', \"''\", \"``\", \"()\", \"[]\", \"{}\"],\n\tselfCloseRegex = /([^$\\w'\"`][\"'`]|.[[({])[.,:;\\])}\u003e\\s]|.[[({]`/s,\n): BasicExtension =\u003e {\n\treturn (editor, options) =\u003e {\n\t\tlet prevCopy: string\n\t\tconst inputCommandMap = editor.inputCommandMap\n\t\tconst clipboard = navigator.clipboard\n\n\t\t/**\n\t\t * Automatically closes quotes and brackets if text is selected,\n\t\t * or if the character before and after the cursor matches a regex\n\t\t * @param wrapOnly If true, the character will only be closed if text is selected.\n\t\t */\n\t\tconst selfClose = (\n\t\t\t[start, end]: InputSelection,\n\t\t\t[open, close]: string,\n\t\t\tvalue: string,\n\t\t\twrapOnly?: boolean,\n\t\t) =\u003e\n\t\t\t(start \u003c end ||\n\t\t\t\t(!wrapOnly \u0026\u0026 selfCloseRegex.test((value[end - 1] || \" \") + open + (value[end] || \" \")))) \u0026\u0026\n\t\t\t!insertText(editor, open + value.slice(start, end) + close, null, null, start + 1, end + 1)!\n\n\t\tconst skipIfEqual = ([start, end]: InputSelection, char: string, value: string) =\u003e\n\t\t\tstart == end \u0026\u0026 value[end] == char \u0026\u0026 !setSelection(editor, start + 1)!\n\n\t\tconst backspaceCommand = () =\u003e {\n\t\t\tconst [start, end] = editor.getSelection()\n\n\t\t\tif (start == end) {\n\t\t\t\tconst value = editor.value\n\t\t\t\tconst line = getLineBefore(value, start)\n\t\t\t\tconst tabSize = options.tabSize || 2\n\t\t\t\tconst isPair = selfClosePairs.includes(value.slice(start - 1, start + 1))\n\t\t\t\tconst indenationCount = /[^ ]/.test(line) ? 0 : ((line.length - 1) % tabSize) + 1\n\n\t\t\t\tif ((isPair || indenationCount \u003e 1) \u0026\u0026 start == end) {\n\t\t\t\t\tinsertText(editor, \"\", start - (isPair ? 1 : indenationCount), start + \u003cany\u003eisPair)\n\t\t\t\t\treturn scroll(editor)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tinputCommandMap[\"\u003c\"] = (_e, selection, value) =\u003e selfClose(selection, \"\u003c\u003e\", value, true)\n\n\t\tselfClosePairs.forEach(([open, close]) =\u003e {\n\t\t\tconst isQuote = open == close\n\t\t\tinputCommandMap[open] = (_e, selection, value) =\u003e\n\t\t\t\t((isQuote \u0026\u0026 skipIfEqual(selection, close, value)) ||\n\t\t\t\t\tselfClose(selection, open + close, value)) \u0026\u0026\n\t\t\t\tscroll(editor)\n\t\t\tif (!isQuote)\n\t\t\t\tinputCommandMap[close] = (_e, selection, value) =\u003e\n\t\t\t\t\tskipIfEqual(selection, close, value) \u0026\u0026 scroll(editor)\n\t\t})\n\n\t\tinputCommandMap[\"\u003e\"] = (e, selection, value) =\u003e {\n\t\t\tconst closingTag = languageMap[getLanguage(editor)]?.autoCloseTags?.(selection, value, editor)\n\t\t\tif (closingTag) {\n\t\t\t\tinsertText(editor, \"\u003e\" + closingTag, null, null, selection[0] + 1)\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\t\t}\n\n\t\taddEditorHotkey(editor, \"Backspace\", backspaceCommand)\n\t\taddEditorHotkey(editor, \"8+Backspace\", backspaceCommand)\n\n\t\tfor (const key in hotkeyMap) {\n\t\t\taddEditorHotkey(editor, key, hotkeyMap[key])\n\t\t}\n\n\t\t;([\"copy\", \"cut\", \"paste\"] as const).forEach(type =\u003e\n\t\t\taddTextareaListener(editor, type, e =\u003e {\n\t\t\t\tconst [start, end] = editor.getSelection()\n\t\t\t\tif (start == end \u0026\u0026 clipboard) {\n\t\t\t\t\tconst [[line], start1, end1] = getLines(editor.value, start, end)\n\t\t\t\t\tif (type == \"paste\") {\n\t\t\t\t\t\tif (e.clipboardData!.getData(\"text/plain\") == prevCopy) {\n\t\t\t\t\t\t\tinsertText(editor, prevCopy + \"\\n\", start1, start1, start + prevCopy.length + 1)\n\t\t\t\t\t\t\tscroll(editor)\n\t\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclipboard.writeText((prevCopy = line))\n\t\t\t\t\t\tif (type == \"cut\") insertText(editor, \"\", start1, end1 + 1), scroll(editor)\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}),\n\t\t)\n\t}\n}\n\n/**\n * History extension that overrides the undo/redo behavior of the browser.\n *\n * Without this extension, the browser's native undo/redo is used, which can be sufficient\n * in some cases.\n *\n * Once added to an editor, this extension can be accessed from `editor.extensions.history`.\n *\n * If you want to create a new editor with different extensions while keeping the undo/redo\n * history of an old editor, you can! Just add the old editor's history extension instance\n * to the new editor. Keep in mind that this will fully break the undo/redo behavior of the\n * old editor.\n *\n * @param historyLimit The maximum size of the history stack. Defaults to 999.\n */\nconst editHistory = (historyLimit = 999) =\u003e {\n\tlet sp = 0\n\tlet currentEditor: PrismEditor\n\tlet allowMerge: boolean\n\tlet isTyping = false\n\tlet prevInputType: string\n\tlet prevData: string | null\n\tlet prevTime: number\n\tlet isMerge: boolean\n\tlet textarea: HTMLTextAreaElement\n\tlet getSelection: PrismEditor[\"getSelection\"]\n\n\tconst stack: [string, InputSelection, InputSelection][] = []\n\tconst update = (index: number) =\u003e {\n\t\tif (index \u003e= historyLimit) {\n\t\t\tindex--\n\t\t\tstack.shift()\n\t\t}\n\t\tstack.splice((sp = index), historyLimit, [currentEditor.value, getSelection(), getSelection()])\n\t}\n\tconst setEditorState = (index: number) =\u003e {\n\t\tif (stack[index]) {\n\t\t\ttextarea.value = stack[index][0]\n\t\t\ttextarea.setSelectionRange(...stack[index][index \u003c sp ? 2 : 1])\n\t\t\tcurrentEditor.update()\n\t\t\tcurrentEditor.extensions.cursor?.scrollIntoView()\n\t\t\tsp = index\n\t\t\tallowMerge = false\n\t\t}\n\t}\n\n\tconst self: EditHistory = (editor, options) =\u003e {\n\t\teditor.extensions.history = self\n\t\tcurrentEditor = editor\n\t\tgetSelection = editor.getSelection\n\t\ttextarea || update(0)\n\t\ttextarea = editor.textarea\n\n\t\teditor.on(\"selectionChange\", () =\u003e {\n\t\t\tallowMerge = isTyping\n\t\t\tisTyping = false\n\t\t})\n\n\t\taddTextareaListener(editor, \"beforeinput\", e =\u003e {\n\t\t\tlet data = e.data\n\t\t\tlet inputType = e.inputType\n\t\t\tlet time = e.timeStamp\n\n\t\t\tif (/history/.test(inputType)) {\n\t\t\t\tsetEditorState(sp + (inputType[7] == \"U\" ? -1 : 1))\n\t\t\t\tpreventDefault(e)\n\t\t\t} else if (\n\t\t\t\t!(isMerge =\n\t\t\t\t\tallowMerge \u0026\u0026\n\t\t\t\t\t(prevInputType == inputType || (time - prevTime \u003c 99 \u0026\u0026 inputType.slice(-4) == \"Drop\")) \u0026\u0026\n\t\t\t\t\t!prevSelection \u0026\u0026\n\t\t\t\t\t(data != \" \" || prevData == data))\n\t\t\t) {\n\t\t\t\tstack[sp][2] = prevSelection || getSelection()\n\t\t\t}\n\t\t\tisTyping = true\n\t\t\tprevData = data\n\t\t\tprevTime = time\n\t\t\tprevInputType = inputType\n\t\t})\n\t\taddTextareaListener(editor, \"input\", () =\u003e update(sp + \u003cany\u003e!isMerge))\n\t\taddTextareaListener(editor, \"keydown\", e =\u003e {\n\t\t\tif (!options.readOnly) {\n\t\t\t\tconst code = getModifierCode(e)\n\t\t\t\tconst keyCode = e.keyCode\n\t\t\t\tconst isUndo = code == mod \u0026\u0026 keyCode == 90\n\t\t\t\tconst isRedo =\n\t\t\t\t\t(code == mod + 8 \u0026\u0026 keyCode == 90) || (!isMac \u0026\u0026 code == mod \u0026\u0026 keyCode == 89)\n\t\t\t\tif (isUndo) {\n\t\t\t\t\tsetEditorState(sp - 1)\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t} else if (isRedo) {\n\t\t\t\t\tsetEditorState(sp + 1)\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\teditor.addExtensions({\n\t\t\tupdate() {\n\t\t\t\tif (editor.value != textarea.value) reset()\n\t\t\t},\n\t\t})\n\t}\n\n\tconst reset = (self.clear = () =\u003e {\n\t\tupdate(0)\n\t\tallowMerge = false\n\t})\n\n\tself.has = offset =\u003e sp + offset in stack\n\tself.go = offset =\u003e setEditorState(sp + offset)\n\n\treturn self\n}\n\nexport { editorCommands, editHistory }\nexport {\n\tnormalizeKey,\n\tgetKeysFromEvent,\n\taddEditorHotkey,\n\taddHotkey,\n\taddEditorHotkeySequence,\n\taddHotkeySequence,\n\trunHotkeys,\n\tisModifierKey,\n} from \"./utils.js\"\nexport {\n\tindentSelectedLines,\n\tinsertTab,\n\tinsertLineAndIndent,\n\tmoveSelectedLines,\n\tcopySelectedLines,\n\tscrollByOneLine,\n\tdeleteSelectedLines,\n\ttoggleComment,\n\tsetIgnoreTab,\n\tdefaultKeymap,\n\tignoreTab,\n} from \"./commands.js\"\nexport * from \"./deprecated.js\"\nexport * from \"./types.js\"\nexport * from \"./format.js\"\n","import { BasicExtension, PrismEditor } from \"../../index.js\"\nimport { createTemplate } from \"../../core.js\"\nimport { getLineBefore } from \"../../utils/index.js\"\nimport {\n\tgetLineEnd,\n\tscrollToEl,\n\taddTextareaListener,\n\tgetPosition,\n\tupdateNode,\n} from \"../../utils/local.js\"\nimport { defaultCommands } from \"../commands/index.js\"\n\n/** Postion of the cursor relative to the editor's overlays. */\nexport type CursorPosition = {\n\ttop: number\n\tbottom: number\n\tleft: number\n\tright: number\n\theight: number\n}\n\nexport interface Cursor extends BasicExtension {\n\t/** Gets the cursor position relative to the editor overlays. */\n\tgetPosition(): CursorPosition\n\t/** Scrolls the cursor into view. */\n\tscrollIntoView(): void\n\t/** The empty span element representing the cursor. */\n\telement: HTMLSpanElement\n}\n\nconst cursorTemplate = /* @__PURE__ */ createTemplate(\n\t\"\u003cdiv style=position:absolute;top:0;opacity:0;padding-inline-end:inherit\u003e \u003cspan\u003e\u003cspan\u003e\u003c/span\u003e \",\n)\n\n/**\n * Extension which can be used to calculate the position of the cursor and scroll it into view.\n * This is used by the {@link defaultCommands} extension to keep the cursor in view while typing.\n *\n * The extension can also be accessed from `editor.extensions.cursor` when added.\n */\nexport const cursorPosition = () =\u003e {\n\tlet cEditor: PrismEditor\n\n\tconst cursorContainer = cursorTemplate()\n\tconst [before, span] = \u003c[Text, HTMLSpanElement]\u003e(\u003cunknown\u003ecursorContainer.childNodes)\n\tconst [cursor, after] = \u003c[HTMLSpanElement, Text]\u003e(\u003cunknown\u003espan.childNodes)\n\tconst update = () =\u003e {\n\t\tconst selection = cEditor.getSelection()\n\t\tconst value = cEditor.value\n\t\tconst activeLine = cEditor.lines[cEditor.activeLine]\n\t\tconst position = selection[selection[2] \u003c \"f\" ? 0 : 1]\n\n\t\tupdateNode(before, getLineBefore(value, position))\n\t\tupdateNode(after, value.slice(position, getLineEnd(value, position)) + \"\\n\")\n\t\tif (cursorContainer.parentNode != activeLine) activeLine.prepend(cursorContainer)\n\t}\n\tconst scrollIntoView = () =\u003e {\n\t\tupdate()\n\t\tscrollToEl(cEditor, cursor)\n\t}\n\n\tconst self: Cursor = editor =\u003e {\n\t\tcEditor = editor\n\n\t\teditor.extensions.cursor = self\n\t\taddTextareaListener(editor, \"input\", e =\u003e {\n\t\t\tif (/history/.test((\u003cInputEvent\u003ee).inputType)) scrollIntoView()\n\t\t})\n\t}\n\n\tself.getPosition = () =\u003e {\n\t\tupdate()\n\t\treturn getPosition(cEditor, cursor)\n\t}\n\n\tself.scrollIntoView = scrollIntoView\n\tself.element = cursor\n\n\treturn self\n}\n","import { createTemplate } from \"../../core.js\"\nimport { BasicExtension } from \"../../types.js\"\nimport { addOverlay } from \"../../utils/index.js\"\nimport { addTextareaListener } from \"../../utils/local.js\"\nimport { cursorPosition } from \"./position.js\"\n\nconst template = createTemplate(\"\u003cdiv class=pce-cursor\u003e\")\n\n/**\n * Extension that overrides the browser's default cursor.\n *\n * Due to a known issue, it's **not recommended** to use this extension with `wordWrap`\n * enabled.\n *\n * Use the `--pce-cursor` CSS variable to change the cursor's color and the `.pce-cursor`\n * selector for other styling.\n *\n * Requires the {@link cursorPosition} extension and styling from\n * `prism-code-editor/cursor.css` to work.\n */\nconst customCursor = (): BasicExtension =\u003e {\n\treturn editor =\u003e {\n\t\tlet cursor = template()\n\t\tlet textareaStyle = editor.textarea.style\n\t\tlet toggle: number\n\n\t\teditor.on(\"selectionChange\", () =\u003e {\n\t\t\tconst pos = editor.extensions.cursor?.getPosition()\n\n\t\t\tif (pos) {\n\t\t\t\ttextareaStyle.zIndex = textareaStyle.caretColor = \"auto\"\n\t\t\t\tcursor.style = `left:${pos.left}px;top:${pos.top}px;height:${\n\t\t\t\t\tpos.height\n\t\t\t\t}px;animation-name:pce-blink${(toggle = +!toggle)}`\n\t\t\t}\n\t\t})\n\n\t\taddTextareaListener(editor, \"dragover\", () =\u003e {\n\t\t\ttextareaStyle.caretColor = \"\"\n\t\t})\n\n\t\taddOverlay(editor, cursor)\n\t}\n}\n\nexport { customCursor }\n","import { addOverlay, regexEscape } from \"../../utils/index.js\"\r\nimport { createTemplate } from \"../../core.js\"\r\nimport { PrismEditor } from \"../../types.js\"\r\nimport { updateNode } from \"../../utils/local.js\"\r\n\r\nconst searchTemplate = /* @__PURE__ */ createTemplate(\r\n\t'\u003cdiv style=\"color:#0000;contain:strict;padding:0 var(--_pse) 0 var(--padding-left)\" aria-hidden=true\u003e ',\r\n)\r\n\r\nconst matchTemplate = /* @__PURE__ */ createTemplate(\"\u003cspan\u003e \")\r\n\r\nconst testBoundary = (str: string, position: number, pattern = /[_\\p{N}\\p{L}]{2}/u) =\u003e {\r\n\tif (!position) return false\r\n\treturn pattern.test(\r\n\t\tstr.slice(\r\n\t\t\tposition - (str.codePointAt(position - 2)! \u003e 0xffff ? 2 : 1),\r\n\t\t\tposition + (str.codePointAt(position)! \u003e 0xffff ? 2 : 1),\r\n\t\t),\r\n\t)\r\n}\r\n\r\nexport type SearchFilter = (start: number, end: number) =\u003e boolean\r\n\r\n/** Object with methods useful for performing a search and highlighting the matches. */\r\nexport interface SearchAPI {\r\n\t/**\r\n\t * Unhides the search container and highlights all matches of the specified string in the editor.\r\n\t * @param str String to search for.\r\n\t * @param caseSensitive Whether or not the search is case sensetive.\r\n\t * @param wholeWord Whether or not matches must be surrounded by word boundaries.\r\n\t * @param useRegExp If true, special characters won't be escaped when creating the RegExp.\r\n\t * @param selection Boundaries to search between. If excluded, all the code is searched.\r\n\t * @param filter A function called for each match with the start and end positions of the match.\r\n\t * If it returns false, the match won't be included.\r\n\t * @param wholeWordBoundry Pattern controlling the behavior of whole word search. Best left\r\n\t * undefined unless you know what you're doing. Does nothing if `wholeWord` isn't set to `true`.\r\n\t * Defaults to `/[_\\p{N}\\p{L}]{2}/u`.\r\n\t * @returns An error message if the RegExp was invalid.\r\n\t */\r\n\tsearch(\r\n\t\tstr: string,\r\n\t\tcaseSensitive?: boolean,\r\n\t\twholeWord?: boolean,\r\n\t\tuseRegExp?: boolean,\r\n\t\tselection?: [number, number],\r\n\t\tfilter?: SearchFilter,\r\n\t\twholeWordBoundry?: RegExp,\r\n\t): string | void\r\n\t/** Container that all the search results are appended to. */\r\n\treadonly container: HTMLDivElement\r\n\t/** Current regex used for searching. */\r\n\treadonly regex: RegExp\r\n\t/** Array of positions of all the matches. */\r\n\treadonly matches: [number, number][]\r\n\t/** Removes the search container and all matches. */\r\n\tstopSearch(): void\r\n}\r\n\r\n/** Function adding search functionality to an editor. */\r\nconst createSearchAPI = (editor: PrismEditor): SearchAPI =\u003e {\r\n\tconst container = searchTemplate()\r\n\tconst nodes: ChildNode[] = [container.firstChild!]\r\n\tconst matchPositions: [number, number][] = []\r\n\tconst stopSearch = () =\u003e {\r\n\t\tif (matchPositions[0]) {\r\n\t\t\tmatchPositions.length = 0\r\n\t\t\tcontainer.remove()\r\n\t\t}\r\n\t}\r\n\r\n\tlet regex: RegExp\r\n\tlet lastNode = 0\r\n\r\n\treturn {\r\n\t\tsearch(str, caseSensitive, wholeWord, useRegExp, selection, filter, pattern) {\r\n\t\t\tif (!str) return stopSearch()\r\n\t\t\tif (!useRegExp) str = regexEscape(str)\r\n\t\t\tconst value = editor.value\r\n\t\t\tconst searchStr = selection ? value.slice(...selection) : value\r\n\t\t\tconst offset = selection ? selection[0] : 0\r\n\r\n\t\t\tlet match: RegExpExecArray | null\r\n\t\t\tlet l: number\r\n\t\t\tlet index: number\r\n\t\t\tlet i = 0\r\n\r\n\t\t\ttry {\r\n\t\t\t\tregex = RegExp(str, caseSensitive ? \"gum\" : \"gumi\")\r\n\t\t\t\twhile ((match = regex.exec(searchStr))) {\r\n\t\t\t\t\tl = match[0].length\r\n\t\t\t\t\tindex = match.index + offset\r\n\t\t\t\t\tif (!l) regex.lastIndex += value.codePointAt(index)! \u003e 0xffff ? 2 : 1\r\n\t\t\t\t\tif (\r\n\t\t\t\t\t\twholeWord \u0026\u0026\r\n\t\t\t\t\t\t(testBoundary(value, index, pattern) || testBoundary(value, index + l, pattern))\r\n\t\t\t\t\t)\r\n\t\t\t\t\t\tcontinue\r\n\t\t\t\t\tif (!filter || filter(index, index + l)) matchPositions[i++] = [index, index + l]\r\n\t\t\t\t}\r\n\t\t\t} catch (e) {\r\n\t\t\t\tstopSearch()\r\n\t\t\t\treturn (\u003cError\u003ee).message\r\n\t\t\t}\r\n\r\n\t\t\tif (i) {\r\n\t\t\t\tmatchPositions.length = i\r\n\t\t\t\tl = Math.min(i * 2, 20000)\r\n\r\n\t\t\t\tfor (i = nodes.length; i \u003c= l; ) {\r\n\t\t\t\t\tnodes[i++] = matchTemplate()\r\n\t\t\t\t\tnodes[i++] = new Text()\r\n\t\t\t\t}\r\n\r\n\t\t\t\tfor (i = l; i \u003c lastNode; ) nodes[++i].remove()\r\n\t\t\t\tif (lastNode \u003c l) container.append(...nodes.slice(lastNode + 1, l + 1))\r\n\r\n\t\t\t\tlet prevEnd = 0\r\n\t\t\t\tfor (i = 0; i \u003c l; ) {\r\n\t\t\t\t\tconst [start, end] = matchPositions[i / 2]\r\n\t\t\t\t\tupdateNode(nodes[i++] as Text, value.slice(prevEnd, start))\r\n\t\t\t\t\tupdateNode(nodes[i++].firstChild as Text, value.slice(start, (prevEnd = end)))\r\n\t\t\t\t}\r\n\r\n\t\t\t\tupdateNode(nodes[l] as Text, value.slice(prevEnd))\r\n\t\t\t\tif (!container.parentNode) addOverlay(editor, container)\r\n\t\t\t\tlastNode = l\r\n\t\t\t} else stopSearch()\r\n\t\t},\r\n\t\tcontainer,\r\n\t\tget regex() {\r\n\t\t\treturn regex\r\n\t\t},\r\n\t\tmatches: matchPositions,\r\n\t\tstopSearch,\r\n\t}\r\n}\r\n\r\nexport { createSearchAPI, searchTemplate, matchTemplate }\r\n","import { BasicExtension } from \"../../index.js\"\r\nimport { SearchAPI, SearchFilter, createSearchAPI } from \"./search.js\"\r\n\r\nexport interface SelectionMatchHighlighter extends BasicExtension {\r\n\t/**\r\n\t * Search API used by the extension.\r\n\t * Can be used get the position of the matches for example.\r\n\t * This property is only present after the extension is added to an editor.\r\n\t */\r\n\tapi?: SearchAPI\r\n}\r\n\r\nexport interface WordHighlighter extends SelectionMatchHighlighter {\r\n\t/** Sets the search filter used. Useful for updating the filter after changing an editor's language. */\r\n\tsetFilter(newFilter: SearchFilter): void\r\n}\r\n\r\n/**\r\n * Extension that highlights selection matches in an editor.\r\n * @param caseSensitive Whether or not matches must have the same case. Defaults to false.\r\n * @param minLength Minimum length needed to perform a search. Defaults to 1.\r\n * @param maxLength Maximum length at which to perform a search. Defaults to 200.\r\n\r\n * Lower values of `minLength` and higher values of `maxLength` can impact performance.\r\n * \r\n * The CSS-selector `.selection-matches span` can be used to style the matches.\r\n */\r\nconst highlightSelectionMatches = (caseSensitive?: boolean, minLength = 1, maxLength = 200) =\u003e {\r\n\tconst self: SelectionMatchHighlighter = editor =\u003e {\r\n\t\tconst searchAPI = (self.api = createSearchAPI(editor))\r\n\t\tconst container = searchAPI.container\r\n\r\n\t\tcontainer.style.zIndex = \u003cany\u003e-1\r\n\t\tcontainer.className = \"selection-matches\"\r\n\r\n\t\teditor.on(\"selectionChange\", ([start, end], value) =\u003e {\r\n\t\t\tvalue = editor.focused ? value.slice(start, end) : \"\"\r\n\t\t\tstart += value.search(/\\S/)\r\n\t\t\tvalue = value.trim()\r\n\t\t\tlet l = value.length\r\n\r\n\t\t\tsearchAPI.search(\r\n\t\t\t\tminLength \u003e l || l \u003e maxLength ? \"\" : value,\r\n\t\t\t\tcaseSensitive,\r\n\t\t\t\tfalse,\r\n\t\t\t\tfalse,\r\n\t\t\t\tundefined,\r\n\t\t\t\t(mStart, mEnd) =\u003e mStart \u003e start || mEnd \u003c= start\r\n\t\t\t)\r\n\t\t})\r\n\t}\r\n\treturn self\r\n}\r\n\r\n/**\r\n * Extension that highlights all instances of the word the cursor is on if there's no selection.\r\n * @param filter Function that can filter away matches based on their position.\r\n * The filter can be changed later using the `setFilter` method.\r\n * @param includeHyphens A function returning whether or not hyphens should be included in the search.\r\n * For languages that don't commonly use hyphens as an operator (such as CSS), it makes sense to\r\n * return true. If this parameter is omitted, hyphens are not included.\r\n *\r\n * The CSS-selector `.word-matches span` can be used to style the matches.\r\n *\r\n * @example\r\n * This filters away all words that start inside a string, comment or keyword or regex token.\r\n * Different filter functions should be chosen based on the language.\r\n * ```\r\n * const selector = \".string, .comment, .keyword, .regex\"\r\n * const filter = start =\u003e !getClosestToken(editor, selector, 0, 0, start)\r\n * const includeHyphens = position =\u003e getLanguage(editor, position) == \"css\"\r\n *\r\n * editor.addExtensions(\r\n * \thighlightCurrentWord(filter, includeHyphens)\r\n * )\r\n * ```\r\n */\r\nconst highlightCurrentWord = (\r\n\tfilter?: SearchFilter,\r\n\tincludeHyphens?: (cursorPosition: number) =\u003e boolean,\r\n) =\u003e {\r\n\tconst self: WordHighlighter = editor =\u003e {\r\n\t\tlet noHighlight = false\r\n\t\tlet searchAPI = (self.api = createSearchAPI(editor))\r\n\t\tlet container = searchAPI.container\r\n\r\n\t\tcontainer.style.zIndex = \u003cany\u003e-1\r\n\t\tcontainer.className = \"word-matches\"\r\n\r\n\t\teditor.on(\"update\", () =\u003e (noHighlight = true))\r\n\t\teditor.on(\"selectionChange\", ([start, end], value) =\u003e {\r\n\t\t\tif (start \u003c end || !editor.focused || noHighlight) searchAPI.search(\"\")\r\n\t\t\telse {\r\n\t\t\t\tlet group = `[_$\\\\p{L}\\\\d${includeHyphens \u0026\u0026 includeHyphens(start) ? \"-\" : \"\"}]`\r\n\t\t\t\tlet before = value.slice(0, start).match(RegExp(group + \"*$\", \"u\"))!\r\n\t\t\t\tlet index = before.index!\r\n\t\t\t\tlet word = before[0] + value.slice(start).match(RegExp(\"^\" + group + \"*\", \"u\"))![0]\r\n\t\t\t\tsearchAPI.search(\r\n\t\t\t\t\t/^-*(\\d|$)/.test(word) || (filter \u0026\u0026 !filter(index, index + word.length)) ? \"\" : word,\r\n\t\t\t\t\ttrue,\r\n\t\t\t\t\ttrue,\r\n\t\t\t\t\tfalse,\r\n\t\t\t\t\tundefined,\r\n\t\t\t\t\tfilter,\r\n\t\t\t\t\tRegExp(group + \"{2}\", \"u\"),\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t\tnoHighlight = false\r\n\t\t})\r\n\t}\r\n\tself.setFilter = newFilter =\u003e (filter = newFilter)\r\n\treturn self\r\n}\r\n\r\nexport { highlightSelectionMatches, highlightCurrentWord }\r\n",".prism-search {\r\n\tdisplay: grid;\r\n\tborder: 1px solid var(--pce-widget-border);\r\n\tgrid: auto / 1em auto;\r\n\tgap: 0.3em;\r\n\tpadding: 0.3em;\r\n\tborder-radius: 0.3em;\r\n\tmargin: -99in 0 0 0;\r\n\tline-height: 1.5;\r\n\tcolor: var(--pce-widget-color);\r\n\tbackground: var(--pce-widget-bg);\r\n\tposition: sticky;\r\n\ttop: 0.5em;\r\n\tright: 0.5em;\r\n\tleft: 0.5em;\r\n\tz-index: 4;\r\n\tpointer-events: auto;\r\n}\r\n\r\n.prism-search-container * {\r\n\tbox-sizing: border-box;\r\n}\r\n\r\n.prism-search button {\r\n\tall: unset;\r\n\tcursor: pointer;\r\n}\r\n\r\n.pce-readonly .prism-search {\r\n\tgrid: auto / auto;\r\n}\r\n\r\n.prism-search \u003e div \u003e div {\r\n\tdisplay: flex;\r\n}\r\n\r\n.pce-input input {\r\n\tpadding: 0 0 0 0.3em;\r\n\twidth: calc(var(--search-width, 20em) - 10ch - 4px);\r\n\tfont: inherit;\r\n\tborder: none;\r\n\tbackground: #0000;\r\n\tcolor: var(--pce-widget-color);\r\n\toutline: 0;\r\n}\r\n\r\n.pce-input ::placeholder {\r\n\tcolor: inherit;\r\n\topacity: 0.6;\r\n}\r\n\r\n.pce-match-count {\r\n\tmargin: 1px auto 1px 0;\r\n}\r\n\r\n.pce-match-count,\r\n.pce-input {\r\n\tfont-family: Arial, Helvetica, sans-serif;\r\n}\r\n\r\n.pce-options {\r\n\tcolor: var(--pce-widget-color-options);\r\n\tfont-size: 80%;\r\n\tgap: 0.25em;\r\n}\r\n\r\n.pce-options button {\r\n\tpadding: 0 0.2em;\r\n\tborder-radius: 0.2em;\r\n\twidth: 1.2em;\r\n\ttext-align: center;\r\n}\r\n\r\n.pce-options button span {\r\n\tpointer-events: none;\r\n}\r\n\r\n.prism-search button:focus-visible {\r\n\toutline: 1px solid var(--pce-widget-focus);\r\n\tz-index: 1;\r\n}\r\n\r\n.pce-input,\r\n.pce-options button {\r\n\tbox-shadow: 0 0 0 1px var(--_border, var(--pce-widget-border));\r\n\tmargin: 1px;\r\n}\r\n\r\n.pce-input {\r\n\tdisplay: flex;\r\n\tposition: relative;\r\n\tbackground: var(--pce-widget-bg-input);\r\n\tborder-radius: 0.15em;\r\n\theight: 1.5em;\r\n}\r\n\r\n.pce-input:focus-within {\r\n\t--_border: var(--pce-widget-focus);\r\n}\r\n\r\n.pce-find button {\r\n\tdisplay: grid;\r\n\talign-items: center;\r\n\tpadding: 0 0.4em;\r\n}\r\n\r\n.pce-replace button {\r\n\twidth: 7.3ch;\r\n\ttext-align: center;\r\n}\r\n\r\n.pce-replace :last-child {\r\n\twidth: 2.7ch;\r\n}\r\n\r\n.pce-input button {\r\n\tbox-shadow: -1px 0 0 0 var(--pce-widget-border);\r\n\tmargin-left: 1px;\r\n}\r\n\r\n.pce-prev::before {\r\n\ttransform: rotate(-90deg);\r\n}\r\n\r\n.pce-next::before,\r\n.pce-expand::before {\r\n\ttransform: rotate(90deg);\r\n}\r\n\r\n@media (hover: hover) {\r\n\t.prism-search button:hover {\r\n\t\tbackground: var(--pce-widget-bg-hover);\r\n\t}\r\n}\r\n\r\n.pce-options button[aria-pressed=\"true\"] {\r\n\tbackground: var(--pce-widget-bg-active);\r\n\tcolor: var(--pce-widget-color-active);\r\n\t--_border: var(--pce-widget-focus);\r\n}\r\n\r\n.pce-input \u003e :nth-child(3) {\r\n\tborder-radius: 0 0.15em 0.15em 0;\r\n}\r\n\r\n.pce-input.pce-error {\r\n\t--_border: var(--pce-widget-error);\r\n\t--pce-widget-focus: var(--_border);\r\n}\r\n\r\n.search-error {\r\n\tdisplay: none;\r\n\tposition: absolute;\r\n\ttop: 100%;\r\n\tbox-shadow: inherit;\r\n\twidth: 100%;\r\n\twhite-space: normal;\r\n\tword-break: break-word;\r\n\tleft: 0;\r\n\tbackground: var(--pce-widget-bg-error);\r\n\tpadding: 0.5em;\r\n\tz-index: 1;\r\n}\r\n\r\n.pce-error:focus-within .search-error {\r\n\tdisplay: block;\r\n}\r\n\r\nbutton.pce-close {\r\n\tdisplay: grid;\r\n\twidth: 1.3em;\r\n\theight: 1.3em;\r\n\tplace-items: center;\r\n\tmargin-left: auto;\r\n\tborder-radius: 0.3em;\r\n}\r\n\r\n.pce-find button::before,\r\n.pce-expand::before,\r\n.pce-close::before {\r\n\tcontent: \"\";\r\n\tbackground: currentColor;\r\n\theight: 1.2em;\r\n\topacity: 0.75;\r\n}\r\n\r\n.pce-close::before {\r\n\tclip-path: polygon(\r\n\t\t50% 44.34%,\r\n\t\t0% 74.34%,\r\n\t\t9.43% 80%,\r\n\t\t9.43% 20%,\r\n\t\t0% 25.66%,\r\n\t\t50% 55.66%,\r\n\t\t100% 25.66%,\r\n\t\t90.57% 20%,\r\n\t\t50% 44.34%,\r\n\t\t9.43% 20%,\r\n\t\t9.43% 80%,\r\n\t\t50% 55.66%,\r\n\t\t90.57% 80%,\r\n\t\t100% 74.34%\r\n\t);\r\n\twidth: 0.72em;\r\n}\r\n\r\n.prism-search \u003e div {\r\n\tdisplay: grid;\r\n\tgap: 0.25em;\r\n\twidth: var(--search-width, 20em);\r\n}\r\n\r\nbutton.pce-expand {\r\n\tdisplay: grid;\r\n\tplace-items: center;\r\n\tborder-radius: 0.25em;\r\n\tmargin: -0.15em;\r\n}\r\n\r\n.pce-readonly .pce-expand,\r\n[aria-expanded=\"false\"] + div .pce-replace,\r\n.pce-readonly .pce-replace {\r\n\tdisplay: none;\r\n}\r\n\r\n.pce-expand[aria-expanded=\"true\"]::before {\r\n\ttransform: rotate(180deg);\r\n}\r\n\r\n.pce-find button::before,\r\n.pce-expand::before {\r\n\twidth: 0.84em;\r\n\tclip-path: polygon(50% 28.96%, 0% 63.96%, 10.1% 71.04%, 50% 43.11%, 89.9% 71.04%, 100% 63.96%);\r\n}\r\n\r\nbutton.pce-regex {\r\n\tdisplay: flex;\r\n}\r\n\r\n.pce-regex span {\r\n\tdisplay: flex;\r\n\talign-items: flex-end;\r\n}\r\n\r\n.pce-regex span::before {\r\n\tcontent: \"\";\r\n\twidth: 0.3em;\r\n\theight: 0.3em;\r\n\tbackground: currentColor;\r\n\tmargin: 0 0 0.2em 0.1em;\r\n}\r\n\r\n.pce-regex span::after {\r\n\tcontent: \"*\";\r\n\tline-height: 0;\r\n\tfont-size: 140%;\r\n\tmargin-bottom: 0.5em;\r\n}\r\n\r\nbutton.pce-in-selection {\r\n\tdisplay: grid;\r\n\tplace-items: center;\r\n}\r\n\r\nbutton.pce-whole {\r\n\tposition: relative;\r\n}\r\n\r\n.pce-whole::after {\r\n\tcontent: \"\";\r\n\tposition: absolute;\r\n\tbottom: 0.31em;\r\n\tright: 0.27em;\r\n\tleft: 0.27em;\r\n\theight: 0.25em;\r\n\tclip-path: inset(1px -1px -1px);\r\n\tbox-shadow: 0 0 0 1px;\r\n}\r\n\r\n.pce-in-selection::before {\r\n\tcontent: \"\";\r\n\theight: 80%;\r\n\twidth: 90%;\r\n\tbackground: currentColor;\r\n\tclip-path: polygon(\r\n\t\t0 16%,\r\n\t\t80% 16%,\r\n\t\t80% 24%,\r\n\t\t0 24%,\r\n\t\t0 46%,\r\n\t\t100% 46%,\r\n\t\t100% 54%,\r\n\t\t0 54%,\r\n\t\t0 76%,\r\n\t\t60% 76%,\r\n\t\t60% 84%,\r\n\t\t0 84%\r\n\t);\r\n}\r\n\r\n.pce-matches span {\r\n\tbackground: var(--pce-search-match);\r\n}\r\n\r\n.pce-matches :empty {\r\n\tpadding: 0 2px;\r\n\tmargin: 0 -2px;\r\n}\r\n",".pce-invisibles ::before,\n.token.tab::before,\n.token.space::before {\n\tcontent: \"·\";\n\tposition: absolute;\n\tcolor: var(--pce-invisibles, #e3e4e229);\n}\n\n.pce-tab::before,\n.token.tab::before {\n\tcontent: \"→\";\n}\n\n/*\n * Clip paths and mask images didn't work properly on inline elements in Safari or Chrome\n * so I scrapped it for pseudo-elements with unicode characters instead.\n */\n\n/* .pce-invisibles span {\n\t--mask: 50% no-repeat\n\turl('data:image/svg+xml,\u003csvg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\u003ccircle cx=\"8\" cy=\"8\" r=\"2.4\"/\u003e\u003c/svg\u003e');\n\t-webkit-mask: var(--mask);\n\tmask: var(--mask);\n\tclip-path: circle(0.15ch);\n\tbackground: var(--pce-invisibles, #e3e4e229);\n\tdisplay: inline-block;\n}\n\nspan.pce-tab {\n\t--mask: 0 50% / 1em 1em no-repeat\n\t\turl('data:image/svg+xml,\u003csvg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\u003cpath d=\"m0 7.4h7.1l-1.45-1.45.7-.7 2.45 2.45 0 .6-2.45 2.45-.7-.7 1.45-1.45h-7.4z\"/\u003e\u003c/svg\u003e');\n\tclip-path: polygon(\n\t\t0 calc(50% - 0.038em),\n\t\t0.444em calc(50% - 0.038em),\n\t\t0.353em calc(50% - 0.128em),\n\t\t0.397em calc(50% - 0.172em),\n\t\t0.55em calc(50% - 0.019em),\n\t\t0.55em calc(50% + 0.019em),\n\t\t0.397em calc(50% + 0.172em),\n\t\t0.353em calc(50% + 0.128em),\n\t\t0.444em calc(50% + 0.038em),\n\t\t0 calc(50% + 0.038em)\n\t);\n} */\n","import \"../languages/index.js\"\nimport { matchBrackets } from \"../extensions/matchBrackets/index.js\"\nimport { highlightBracketPairs } from \"../extensions/matchBrackets/highlight.js\"\nimport { indentGuides } from \"../extensions/guides.js\"\nimport { cursorPosition } from \"../extensions/cursor/index.js\"\nimport { defaultCommands, editHistory } from \"../extensions/commands/index.js\"\nimport { EditorExtension } from \"../index.js\"\nimport {\n\tsearchWidget,\n\tshowInvisibles,\n\thighlightSelectionMatches,\n} from \"../extensions/search/index.js\"\nimport { matchTags } from \"../extensions/matchTags.js\"\nimport searchStyle from \"../extensions/search/search.css?inline\"\nimport invisibles from \"../extensions/search/invisibles.css?inline\"\n\nexport const basic = (): EditorExtension[] =\u003e [\n\tdefaultCommands(),\n\tindentGuides(),\n\tmatchBrackets(),\n\thighlightBracketPairs(),\n\tcursorPosition(),\n\thighlightSelectionMatches(),\n\tsearchWidget(),\n\tshowInvisibles(),\n\tmatchTags(),\n\teditHistory(),\n]\n\nexport const style = searchStyle + invisibles\n"],"version":3}
