feat(syntax_highlight): add syntax highlighting api endpoint with html/json output!@@ -1,10 +1,10 @@
{
- "_generatedAtUnix": 1664493709726,
+ "_generatedAtUnix": 1664503855283,
"_hashAlgorithm": "sha1",
"_version": 2,
"islands": {
"Code": {
- "hash": "6b04788e5f7abcf319aaa7ed122b91c6fa6ac952",
+ "hash": "1fb3b1015338a81ad565d1abb9b689372e7959e7",
"pathSource": "./app/islands/Code.tsx",
"pathBundle": "./public/.islands/Code.bundle.js",
"pathSourceMap": "./public/.islands/Code.bundle.js.map"
@@ -34,7 +34,7 @@
"pathSourceMap": "./public/.islands/RepositoryCreateForm.bundle.js.map"
},
"RepositoryFilesDiffsList": {
- "hash": "117895a214a1d54625205f5b8a2e98a82b5ac7c6",
+ "hash": "ab4c2ce9ebcbc4e17885f9920da5d36ffb19a232",
"pathSource": "./app/islands/RepositoryFilesDiffsList.tsx",
"pathBundle": "./public/.islands/RepositoryFilesDiffsList.bundle.js",
"pathSourceMap": "./public/.islands/RepositoryFilesDiffsList.bundle.js.map"
@@ -0,0 +1,125 @@
+// 1st-party
+import { ReqHandler } from "@ethicdevs/react-monolith";
+// 3rd-party
+import Prism from "prismjs";
+import { parse as parseHtmlToJson } from "himalaya";
+// app
+import type { AppThemeScheme } from "../../types";
+import { AppRoute, AppRoutesParams } from "../../routes";
+import { escapeHtmlCode } from "../../utils/shared/escapeHtmlCode";
+
+const syntaxHighlightThemes: Record<AppThemeScheme, string> = {
+ light: `code[class*="language-"],pre[class*="language-"]{color:#000;background:0 0;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;padding-left:3.5em;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*="language-"]::-moz-selection,code[class*="language-"]::-moz-selection,pre[class*="language-"] ::-moz-selection,pre[class*="language-"]::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*="language-"]::selection,code[class*="language-"]::selection,pre[class*="language-"] ::selection,pre[class*="language-"]::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*="language-"],pre[class*="language-"]{text-shadow:none}}pre[class*="language-"]{padding:1em;margin:0.5em 0;overflow-y:hidden;overflow-x:auto}:not(pre) > code[class*="language-"],pre[class*="language-"]{background:#f5f2f0}:not(pre) > code[class*="language-"]{padding:0.1em;border-radius:0.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.token.namespace{opacity:0.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:hsla(0, 0%, 100%, 0.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}`,
+ dark: `code[class*="language-"],pre[class*="language-"]{color:#fff;background:0 0;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;padding-left:3.5em;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}@media print{code[class*="language-"],pre[class*="language-"]{text-shadow:none}}:not(pre) > code[class*="language-"],pre[class*="language-"]{background:#4c3f33}pre[class*="language-"]{padding:1em;margin:0.5em 0;overflow-y:hidden;overflow-x:auto;border:0.3em solid #7a6651;border-radius:0.5em;box-shadow:1px 1px 0.5em #000 inset}:not(pre) > code[class*="language-"]{padding:0.15em 0.2em 0.05em;border-radius:0.3em;border:0.13em solid #7a6651;box-shadow:1px 1px 0.3em -0.1em #000 inset;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#997f66}.token.punctuation{opacity:0.7}.token.namespace{opacity:0.7}.token.boolean,.token.constant,.token.number,.token.property,.token.symbol,.token.tag{color:#d1939e}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#bce051}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f4b73d}.token.atrule,.token.attr-value,.token.keyword{color:#d1939e}.token.important,.token.regex{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.deleted{color:red}`,
+};
+
+function getHighlightedCode(
+ code: string,
+ language: string,
+ themeScheme: AppThemeScheme
+): { html: string; cssRules: string; durationMs: number } {
+ const _startTimeMs = Date.now();
+ const isLanguageSupportedByPrism = !!(
+ Prism.languages != null &&
+ typeof Prism.languages === "object" &&
+ language in Prism.languages &&
+ Prism.languages[language] != null
+ );
+
+ const html = isLanguageSupportedByPrism
+ ? Prism.highlight(code, Prism.languages[language], language)
+ : escapeHtmlCode(code);
+
+ return {
+ html,
+ cssRules: syntaxHighlightThemes[themeScheme],
+ durationMs: Date.now() - _startTimeMs,
+ };
+}
+
+const highlightCodeAction: ReqHandler = async (request, reply) => {
+ const { outputFormat = "html" } =
+ request.params as AppRoutesParams[AppRoute.SYNTAX_HIGHLIGHT_HIGHLIGHT_CODE_ACTION]["params"];
+
+ const {
+ code,
+ language,
+ theme_scheme: themeScheme,
+ } = request.body as AppRoutesParams[AppRoute.SYNTAX_HIGHLIGHT_HIGHLIGHT_CODE_ACTION]["body"];
+
+ if (request.validationError != null) {
+ if (outputFormat === "html") {
+ return reply.status(500).send(`<div class="error">
+ <h1>Woops, Internal Server Error...</h1>
+ <p>${request.validationError.message}</p>
+</div>`);
+ }
+
+ // json
+ return reply.status(500).send({
+ success: false,
+ error: request.validationError,
+ });
+ }
+
+ const result = getHighlightedCode(code, language, themeScheme);
+
+ if (outputFormat === "html") {
+ return reply.status(200).send(result);
+ } else if (outputFormat === "json") {
+ const parsedJson = parseHtmlToJson(result.html);
+
+ console.log("parsedJson:", parsedJson);
+
+ const tokens = parsedJson.reduce((acc, node) => {
+ const getNodeTextRecursive = (n: typeof node, depth = 0): string => {
+ if (depth > 1000) throw new Error("Too much recursion.");
+ return n.type === "text"
+ ? n.content.replace(/\r\n/i, "\n")
+ : getNodeTextRecursive(n.children[0], depth + 1);
+ };
+ const getNodesRecursive = (
+ n: typeof node,
+ depth = 0
+ ): { text: string; type: string }[] => {
+ if (depth > 1000) throw new Error("Too much recursion.");
+ return n.type === "text"
+ ? [
+ {
+ text: n.content.replace(/\r\n/i, "\n"),
+ type: "text",
+ },
+ ]
+ : n.children.map((childNode) => ({
+ text: getNodeTextRecursive(childNode),
+ type:
+ childNode.type === "text"
+ ? "text"
+ : childNode.attributes[0].key === "class"
+ ? childNode.attributes[0].value.replace(/^token /i, "")
+ : "attr",
+ }));
+ };
+ if (node.type === "text") {
+ acc = [
+ ...acc,
+ { text: node.content.replace(/\r\n/i, "\n"), type: "text" },
+ ];
+ } else {
+ acc = [...acc, ...getNodesRecursive(node)];
+ }
+ return acc;
+ }, [] as { text: string; type: string }[]);
+ return reply.status(200).send(tokens);
+ }
+
+ // unknown format
+ return reply.status(200).send({
+ success: false,
+ error: {
+ message: "Unknown output format. Must be one of: `html` | `json`.",
+ },
+ });
+};
+
+export default highlightCodeAction;
@@ -0,0 +1,6 @@
+// request handlers
+import { default as highlightCodeAction } from "./highlightCodeAction";
+
+export const SyntaxHighlightController = {
+ highlightCodeAction,
+};
@@ -0,0 +1,103 @@
+code[class*="language-"],
+pre[class*="language-"] {
+ color: #fff;
+ background: 0 0;
+ text-align: left;
+ white-space: pre;
+ word-spacing: normal;
+ word-break: normal;
+ word-wrap: normal;
+ padding-left: 3.5em;
+ line-height: 1.5;
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+ -webkit-hyphens: none;
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ hyphens: none;
+}
+@media print {
+ code[class*="language-"],
+ pre[class*="language-"] {
+ text-shadow: none;
+ }
+}
+:not(pre) > code[class*="language-"],
+pre[class*="language-"] {
+ background: #4c3f33;
+}
+pre[class*="language-"] {
+ padding: 1em;
+ margin: 0.5em 0;
+ overflow-y: hidden;
+ overflow-x: auto;
+ border: 0.3em solid #7a6651;
+ border-radius: 0.5em;
+ box-shadow: 1px 1px 0.5em #000 inset;
+}
+:not(pre) > code[class*="language-"] {
+ padding: 0.15em 0.2em 0.05em;
+ border-radius: 0.3em;
+ border: 0.13em solid #7a6651;
+ box-shadow: 1px 1px 0.3em -0.1em #000 inset;
+ white-space: normal;
+}
+.token.cdata,
+.token.comment,
+.token.doctype,
+.token.prolog {
+ color: #997f66;
+}
+.token.punctuation {
+ opacity: 0.7;
+}
+.token.namespace {
+ opacity: 0.7;
+}
+.token.boolean,
+.token.constant,
+.token.number,
+.token.property,
+.token.symbol,
+.token.tag {
+ color: #d1939e;
+}
+.token.attr-name,
+.token.builtin,
+.token.char,
+.token.inserted,
+.token.selector,
+.token.string {
+ color: #bce051;
+}
+.language-css .token.string,
+.style .token.string,
+.token.entity,
+.token.operator,
+.token.url,
+.token.variable {
+ color: #f4b73d;
+}
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+ color: #d1939e;
+}
+.token.important,
+.token.regex {
+ color: #e90;
+}
+.token.bold,
+.token.important {
+ font-weight: 700;
+}
+.token.italic {
+ font-style: italic;
+}
+.token.entity {
+ cursor: help;
+}
+.token.deleted {
+ color: red;
+}
@@ -0,0 +1,115 @@
+code[class*="language-"],
+pre[class*="language-"] {
+ color: #000;
+ background: 0 0;
+ text-align: left;
+ white-space: pre;
+ word-spacing: normal;
+ word-break: normal;
+ word-wrap: normal;
+ padding-left: 3.5em;
+ line-height: 1.5;
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+ -webkit-hyphens: none;
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ hyphens: none;
+}
+code[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection,
+pre[class*="language-"] ::-moz-selection,
+pre[class*="language-"]::-moz-selection {
+ text-shadow: none;
+ background: #b3d4fc;
+}
+code[class*="language-"] ::selection,
+code[class*="language-"]::selection,
+pre[class*="language-"] ::selection,
+pre[class*="language-"]::selection {
+ text-shadow: none;
+ background: #b3d4fc;
+}
+@media print {
+ code[class*="language-"],
+ pre[class*="language-"] {
+ text-shadow: none;
+ }
+}
+pre[class*="language-"] {
+ padding: 1em;
+ margin: 0.5em 0;
+ overflow-y: hidden;
+ overflow-x: auto;
+}
+:not(pre) > code[class*="language-"],
+pre[class*="language-"] {
+ background: #f5f2f0;
+}
+:not(pre) > code[class*="language-"] {
+ padding: 0.1em;
+ border-radius: 0.3em;
+ white-space: normal;
+}
+.token.cdata,
+.token.comment,
+.token.doctype,
+.token.prolog {
+ color: #708090;
+}
+.token.punctuation {
+ color: #999;
+}
+.token.namespace {
+ opacity: 0.7;
+}
+.token.boolean,
+.token.constant,
+.token.deleted,
+.token.number,
+.token.property,
+.token.symbol,
+.token.tag {
+ color: #905;
+}
+.token.attr-name,
+.token.builtin,
+.token.char,
+.token.inserted,
+.token.selector,
+.token.string {
+ color: #690;
+}
+.language-css .token.string,
+.style .token.string,
+.token.entity,
+.token.operator,
+.token.url {
+ color: #9a6e3a;
+ background: hsla(0, 0%, 100%, 0.5);
+}
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+ color: #07a;
+}
+.token.class-name,
+.token.function {
+ color: #dd4a68;
+}
+.token.important,
+.token.regex,
+.token.variable {
+ color: #e90;
+}
+.token.bold,
+.token.important {
+ font-weight: 700;
+}
+.token.italic {
+ font-style: italic;
+}
+.token.entity {
+ cursor: help;
+}
@@ -1,13 +1,14 @@
// 1st-party
import { ReactIsland } from "@ethicdevs/react-monolith";
// 3rd-party
-import React, { useCallback, useEffect, useState } from "react";
+import React, { useCallback, useEffect, useMemo, useState } from "react";
import Prism from "prismjs";
import styled, { css } from "styled-components";
// app
import type { AppThemeScheme, WithThemeSchemeProp } from "../types";
import { NamedColors } from "../utils/style";
import { ClientSideRouterEvents } from "./InstantRouterIndicator";
+import { escapeHtmlCode } from "../utils/shared/escapeHtmlCode";
interface CodeProps {
code: string;
@@ -15,14 +16,29 @@ interface CodeProps {
[x: string]: unknown;
}
-function escapeHtml(text: string): string {
- return (text || "")
- .split(/&/gm)
- .join("&")
- .split(/</gm)
- .join("<")
- .split(/>/gm)
- .join(">");
+function getLineStartsAt(maybeGitdiff: string): {
+ before: number;
+ after: number;
+} {
+ if (maybeGitdiff == null) {
+ return {
+ before: 0,
+ after: 0,
+ };
+ }
+ const gitdiffLinesRegExp = /@@ -([\d]+),[\d]+ \+[\d]+,([\d]+) @@/i;
+ const matches = gitdiffLinesRegExp.exec(maybeGitdiff);
+ if (matches == null || Array.isArray(matches) === false) {
+ return {
+ before: 0,
+ after: 0,
+ };
+ }
+ const [_, beforeLineNumber, afterLineNumber] = matches;
+ return {
+ before: parseInt(beforeLineNumber, 10) - 1,
+ after: parseInt(afterLineNumber, 10) - 1,
+ };
}
const Code: ReactIsland<CodeProps & WithThemeSchemeProp> = ({
@@ -31,6 +47,9 @@ const Code: ReactIsland<CodeProps & WithThemeSchemeProp> = ({
themeScheme,
...props
}) => {
+ const codeBlockLineStartsAt = useMemo(() => getLineStartsAt(code), [code]);
+ const lineStartAt = codeBlockLineStartsAt.before;
+
const computeSyntaxHighlighting = useCallback(() => {
const innerHtml = {
__html:
@@ -43,16 +62,20 @@ const Code: ReactIsland<CodeProps & WithThemeSchemeProp> = ({
language in Prism.languages &&
Prism.languages[language] != null
? Prism.highlight(code, Prism.languages[language], language)
- : escapeHtml(code),
+ : escapeHtmlCode(code),
};
+
const linesCount = innerHtml.__html.split("\n").length;
+
innerHtml.__html += `\n<span aria-hidden="true" class="line-numbers-rows">`;
for (let i = linesCount; i > 0; i--) {
- innerHtml.__html += `<span></span>`;
+ const lineNumber = lineStartAt + (linesCount - i + 1);
+ innerHtml.__html += `<a id="l-${lineNumber}" href="#l-${lineNumber}" data-line-number="${lineNumber}"></a>`;
}
innerHtml.__html += `</span>`;
+
return innerHtml;
- }, [code, language]);
+ }, [code, language, lineStartAt]);
const [innerHtml, setInnerHtml] = useState<{ __html: string }>(
computeSyntaxHighlighting()
@@ -81,7 +104,7 @@ const Code: ReactIsland<CodeProps & WithThemeSchemeProp> = ({
<div className="line-numbers" style={{ width: "100%" }}>
<StylePreTag
data-language={language}
- data-start={1}
+ data-start={lineStartAt}
className={` language-${language} line-numbers`}
themeScheme={themeScheme}
style={{ counterReset: "linenumber 0" }}
@@ -97,13 +120,13 @@ export const getThemedCodeCss = (themeScheme: AppThemeScheme): JSX.Element => (
{themeScheme === "light" ? (
<style
dangerouslySetInnerHTML={{
- __html: `code[class*=language-],pre[class*=language-]{color:#000;background:0 0;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;padding-left:3.5em;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}`,
+ __html: `code[class*=language-],pre[class*=language-]{color:#000;background:0 0;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;padding-left:3.5em;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow-y:hidden;overflow-x:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}`,
}}
/>
) : (
<style
dangerouslySetInnerHTML={{
- __html: `code[class*=language-],pre[class*=language-]{color:#fff;background:0 0;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;padding-left:3.5em;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}:not(pre)>code[class*=language-],pre[class*=language-]{background:#4c3f33}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border:.3em solid #7a6651;border-radius:.5em;box-shadow:1px 1px .5em #000 inset}:not(pre)>code[class*=language-]{padding:.15em .2em .05em;border-radius:.3em;border:.13em solid #7a6651;box-shadow:1px 1px .3em -.1em #000 inset;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#997f66}.token.punctuation{opacity:.7}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.number,.token.property,.token.symbol,.token.tag{color:#d1939e}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#bce051}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f4b73d}.token.atrule,.token.attr-value,.token.keyword{color:#d1939e}.token.important,.token.regex{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.deleted{color:red}`,
+ __html: `code[class*=language-],pre[class*=language-]{color:#fff;background:0 0;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;padding-left:3.5em;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}:not(pre)>code[class*=language-],pre[class*=language-]{background:#4c3f33}pre[class*=language-]{padding:1em;margin:.5em 0;overflow-y:hidden;overflow-x:auto;border:.3em solid #7a6651;border-radius:.5em;box-shadow:1px 1px .5em #000 inset}:not(pre)>code[class*=language-]{padding:.15em .2em .05em;border-radius:.3em;border:.13em solid #7a6651;box-shadow:1px 1px .3em -.1em #000 inset;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#997f66}.token.punctuation{opacity:.7}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.number,.token.property,.token.symbol,.token.tag{color:#d1939e}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#bce051}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f4b73d}.token.atrule,.token.attr-value,.token.keyword{color:#d1939e}.token.important,.token.regex{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.deleted{color:red}`,
}}
/>
)}
@@ -121,36 +144,37 @@ pre.line-numbers > code {
position: relative;
display: block;
padding-left: 3.5em;
+ padding-bottom: 0;
white-space: inherit;
}
.line-numbers .line-numbers-rows {
position: absolute;
- pointer-events: none;
top: 0;
- font-size: 100%;
+ bottom: 0;
left: 0;
+ font-size: 100%;
width: 3em; /* works for line-numbers below 1000 lines */
letter-spacing: -1px;
- border-right: 1px solid #999;
+ border-right: 1px solid ${NamedColors.BORDER_DEFAULT[themeScheme]};
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-
}
-.line-numbers-rows > span {
+.line-numbers-rows > a {
display: block;
counter-increment: linenumber;
+ font-weight: normal;
}
-.line-numbers-rows > span:before {
- content: counter(linenumber);
- color: #999;
+.line-numbers-rows > a:before {
+ content: attr(data-line-number);
+ color: ${NamedColors.TEXT_MUTED[themeScheme]};
display: block;
- padding-right: 0.8em;
+ padding-right: 0.4em;
text-align: right;
}
`,
@@ -167,6 +191,8 @@ const StylePreTag = styled.pre<WithThemeSchemeProp>`
box-shadow: none !important;
text-shadow: none !important;
+ border-radius: 8px;
+
${({ themeScheme }) => css`
background-color: ${NamedColors.CARD[themeScheme]} !important;
border: 1px solid ${NamedColors.BORDER_DEFAULT[themeScheme]} !important;
@@ -74,9 +74,9 @@ const RepositoryFilesDiffsList: ReactIsland<
</Grid.Row>
</Grid.Col>
<Grid.Col fluid style={{ marginTop: 8 }}>
- {chunks.map((chunk, idx) => (
+ {chunks.map((chunk, subIdx) => (
<div
- data-islandid={`${Code.name}$$${idx + 1}`}
+ data-islandid={`${Code.name}$$${idx + 1}${subIdx + 1}`}
key={[idx, chunk.content].join(":")}
style={{ width: "100%" }}
>
@@ -15,6 +15,8 @@ import { RepositoryController } from "./controllers/repository";
import { UserController } from "./controllers/user";
import * as HomeController from "./controllers/HomeController";
import * as ThemeController from "./controllers/ThemeController";
+import { AppThemeScheme } from "./types";
+import { SyntaxHighlightController } from "./controllers/syntax_highlight";
export enum AppRoute {
HOME = "home",
@@ -38,6 +40,7 @@ export enum AppRoute {
REPOSITORY_FORK_ACTION = "repository.fork.action",
REPOSITORY_PULL_REQUESTS = "repository.pull_requests",
REPOSITORY_SHOW_OBJECT = "repository.show_object",
+ SYNTAX_HIGHLIGHT_HIGHLIGHT_CODE_ACTION = "syntax_highlight.highlight_code.action",
}
export interface AppRoutesParams extends IRouteParams {
@@ -151,6 +154,16 @@ export interface AppRoutesParams extends IRouteParams {
objectId: string;
};
};
+ [AppRoute.SYNTAX_HIGHLIGHT_HIGHLIGHT_CODE_ACTION]: {
+ params: {
+ outputFormat?: "html" | "json";
+ };
+ body: {
+ code: string;
+ language: string;
+ theme_scheme: AppThemeScheme;
+ };
+ };
}
export const AppRoutesSchemas: Record<AppRoute, undefined | FastifySchema> = {
@@ -448,6 +461,36 @@ export const AppRoutesSchemas: Record<AppRoute, undefined | FastifySchema> = {
},
},
},
+ [AppRoute.SYNTAX_HIGHLIGHT_HIGHLIGHT_CODE_ACTION]: {
+ params: {
+ type: "object",
+ required: [],
+ additionalProperties: false,
+ properties: {
+ outputFormat: {
+ type: "string",
+ enum: ["html", "json"],
+ },
+ },
+ },
+ body: {
+ type: "object",
+ required: ["code", "language", "theme_scheme"],
+ additionalProperties: false,
+ properties: {
+ code: {
+ type: "string",
+ },
+ language: {
+ type: "string",
+ },
+ theme_scheme: {
+ type: "string",
+ enum: ["light", "dark"],
+ },
+ },
+ },
+ },
};
const RootAppRouter: AppRouter = () => {
@@ -624,6 +667,16 @@ const RootAppRouter: AppRouter = () => {
schema={AppRoutesSchemas[AppRoute.REPOSITORY_SHOW_OBJECT]}
handler={RepositoryController.getRepositoryShowObjectView}
/>
+ {/* --- */}
+ <Router.Route
+ name={AppRoute.SYNTAX_HIGHLIGHT_HIGHLIGHT_CODE_ACTION}
+ method={"POST"}
+ path={"/api/syntax/highlight/:outputFormat"}
+ schema={
+ AppRoutesSchemas[AppRoute.SYNTAX_HIGHLIGHT_HIGHLIGHT_CODE_ACTION]
+ }
+ handler={SyntaxHighlightController.highlightCodeAction}
+ />
</Router.Group>
</Router.Root>
);
@@ -182,7 +182,7 @@ async function main(): Promise<AppServer> {
type: "application/javascript",
textContent: `if (typeof window !== "undefined") {
window.Prism = window.Prism || { plugins: {} };
- window.Prism.manual = false;
+ window.Prism.manual = true;
window.Prism.plugins.autoloader = {
use_minifed: ${env === "production" ? "true" : "false"},
languages_path: "/public/assets/prism/components/",
@@ -0,0 +1,9 @@
+export function escapeHtmlCode(text: string): string {
+ return (text || "")
+ .split(/&/gm)
+ .join("&")
+ .split(/</gm)
+ .join("<")
+ .split(/>/gm)
+ .join(">");
+}
@@ -18,7 +18,7 @@ const NamedColors = {
dark: Colors.PRIMARY_01,
},
CARD: {
- dark: Colors.GRAY_DARK_02,
+ dark: Colors.GRAY_DARK_01,
light: Colors.WHITE_01,
},
CARD_OVERLAY: {
@@ -41,6 +41,7 @@
"fastify-static": "^4.6.1",
"file-extension": "^4.0.5",
"gray-matter": "^4.0.3",
+ "himalaya": "^1.1.0",
"image-extensions": "^1.1.0",
"is-image": "^3.1.0",
"language-detect": "^1.1.0",
@@ -0,0 +1,3373 @@
+/* PrismJS 1.29.0
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+diff&plugins=line-highlight+line-numbers+autoloader+normalize-whitespace+diff-highlight */
+/// <reference lib="WebWorker"/>
+s;
+var _self =
+ typeof window !== "undefined"
+ ? window // if in browser
+ : typeof WorkerGlobalScope !== "undefined" &&
+ self instanceof WorkerGlobalScope
+ ? self // if in worker
+ : {}; // if in node js
+
+/**
+ * Prism: Lightweight, robust, elegant syntax highlighting
+ *
+ * @license MIT <https://opensource.org/licenses/MIT>
+ * @author Lea Verou <https://lea.verou.me>
+ * @namespace
+ * @public
+ */
+var Prism = (function (_self) {
+ // Private helper vars
+ var lang = /(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i;
+ var uniqueId = 0;
+
+ // The grammar object for plaintext
+ var plainTextGrammar = {};
+
+ var _ = {
+ /**
+ * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the
+ * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load
+ * additional languages or plugins yourself.
+ *
+ * By setting this value to `true`, Prism will not automatically highlight all code elements on the page.
+ *
+ * You obviously have to change this value before the automatic highlighting started. To do this, you can add an
+ * empty Prism object into the global scope before loading the Prism script like this:
+ *
+ * ```js
+ * window.Prism = window.Prism || {};
+ * Prism.manual = true;
+ * // add a new <script> to load Prism's script
+ * ```
+ *
+ * @default false
+ * @type {boolean}
+ * @memberof Prism
+ * @public
+ */
+ manual: _self.Prism && _self.Prism.manual,
+ /**
+ * By default, if Prism is in a web worker, it assumes that it is in a worker it created itself, so it uses
+ * `addEventListener` to communicate with its parent instance. However, if you're using Prism manually in your
+ * own worker, you don't want it to do this.
+ *
+ * By setting this value to `true`, Prism will not add its own listeners to the worker.
+ *
+ * You obviously have to change this value before Prism executes. To do this, you can add an
+ * empty Prism object into the global scope before loading the Prism script like this:
+ *
+ * ```js
+ * window.Prism = window.Prism || {};
+ * Prism.disableWorkerMessageHandler = true;
+ * // Load Prism's script
+ * ```
+ *
+ * @default false
+ * @type {boolean}
+ * @memberof Prism
+ * @public
+ */
+ disableWorkerMessageHandler:
+ _self.Prism && _self.Prism.disableWorkerMessageHandler,
+
+ /**
+ * A namespace for utility methods.
+ *
+ * All function in this namespace that are not explicitly marked as _public_ are for __internal use only__ and may
+ * change or disappear at any time.
+ *
+ * @namespace
+ * @memberof Prism
+ */
+ util: {
+ encode: function encode(tokens) {
+ if (tokens instanceof Token) {
+ return new Token(tokens.type, encode(tokens.content), tokens.alias);
+ } else if (Array.isArray(tokens)) {
+ return tokens.map(encode);
+ } else {
+ return tokens
+ .replace(/&/g, "&")
+ .replace(/</g, "<")
+ .replace(/\u00a0/g, " ");
+ }
+ },
+
+ /**
+ * Returns the name of the type of the given value.
+ *
+ * @param {any} o
+ * @returns {string}
+ * @example
+ * type(null) === 'Null'
+ * type(undefined) === 'Undefined'
+ * type(123) === 'Number'
+ * type('foo') === 'String'
+ * type(true) === 'Boolean'
+ * type([1, 2]) === 'Array'
+ * type({}) === 'Object'
+ * type(String) === 'Function'
+ * type(/abc+/) === 'RegExp'
+ */
+ type: function (o) {
+ return Object.prototype.toString.call(o).slice(8, -1);
+ },
+
+ /**
+ * Returns a unique number for the given object. Later calls will still return the same number.
+ *
+ * @param {Object} obj
+ * @returns {number}
+ */
+ objId: function (obj) {
+ if (!obj["__id"]) {
+ Object.defineProperty(obj, "__id", { value: ++uniqueId });
+ }
+ return obj["__id"];
+ },
+
+ /**
+ * Creates a deep clone of the given object.
+ *
+ * The main intended use of this function is to clone language definitions.
+ *
+ * @param {T} o
+ * @param {Record<number, any>} [visited]
+ * @returns {T}
+ * @template T
+ */
+ clone: function deepClone(o, visited) {
+ visited = visited || {};
+
+ var clone;
+ var id;
+ switch (_.util.type(o)) {
+ case "Object":
+ id = _.util.objId(o);
+ if (visited[id]) {
+ return visited[id];
+ }
+ clone = /** @type {Record<string, any>} */ ({});
+ visited[id] = clone;
+
+ for (var key in o) {
+ if (o.hasOwnProperty(key)) {
+ clone[key] = deepClone(o[key], visited);
+ }
+ }
+
+ return /** @type {any} */ (clone);
+
+ case "Array":
+ id = _.util.objId(o);
+ if (visited[id]) {
+ return visited[id];
+ }
+ clone = [];
+ visited[id] = clone;
+
+ /** @type {Array} */ (/** @type {any} */ (o)).forEach(function (
+ v,
+ i
+ ) {
+ clone[i] = deepClone(v, visited);
+ });
+
+ return /** @type {any} */ (clone);
+
+ default:
+ return o;
+ }
+ },
+
+ /**
+ * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class.
+ *
+ * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned.
+ *
+ * @param {Element} element
+ * @returns {string}
+ */
+ getLanguage: function (element) {
+ while (element) {
+ var m = lang.exec(element.className);
+ if (m) {
+ return m[1].toLowerCase();
+ }
+ element = element.parentElement;
+ }
+ return "none";
+ },
+
+ /**
+ * Sets the Prism `language-xxxx` class of the given element.
+ *
+ * @param {Element} element
+ * @param {string} language
+ * @returns {void}
+ */
+ setLanguage: function (element, language) {
+ // remove all `language-xxxx` classes
+ // (this might leave behind a leading space)
+ element.className = element.className.replace(RegExp(lang, "gi"), "");
+
+ // add the new `language-xxxx` class
+ // (using `classList` will automatically clean up spaces for us)
+ element.classList.add("language-" + language);
+ },
+
+ /**
+ * Returns the script element that is currently executing.
+ *
+ * This does __not__ work for line script element.
+ *
+ * @returns {HTMLScriptElement | null}
+ */
+ currentScript: function () {
+ if (typeof document === "undefined") {
+ return null;
+ }
+ if (
+ "currentScript" in document &&
+ 1 < 2 /* hack to trip TS' flow analysis */
+ ) {
+ return /** @type {any} */ (document.currentScript);
+ }
+
+ // IE11 workaround
+ // we'll get the src of the current script by parsing IE11's error stack trace
+ // this will not work for inline scripts
+
+ try {
+ throw new Error();
+ } catch (err) {
+ // Get file src url from stack. Specifically works with the format of stack traces in IE.
+ // A stack will look like this:
+ //
+ // Error
+ // at _.util.currentScript (http://localhost/components/prism-core.js:119:5)
+ // at Global code (http://localhost/components/prism-core.js:606:1)
+
+ var src = (/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(err.stack) ||
+ [])[1];
+ if (src) {
+ var scripts = document.getElementsByTagName("script");
+ for (var i in scripts) {
+ if (scripts[i].src == src) {
+ return scripts[i];
+ }
+ }
+ }
+ return null;
+ }
+ },
+
+ /**
+ * Returns whether a given class is active for `element`.
+ *
+ * The class can be activated if `element` or one of its ancestors has the given class and it can be deactivated
+ * if `element` or one of its ancestors has the negated version of the given class. The _negated version_ of the
+ * given class is just the given class with a `no-` prefix.
+ *
+ * Whether the class is active is determined by the closest ancestor of `element` (where `element` itself is
+ * closest ancestor) that has the given class or the negated version of it. If neither `element` nor any of its
+ * ancestors have the given class or the negated version of it, then the default activation will be returned.
+ *
+ * In the paradoxical situation where the closest ancestor contains __both__ the given class and the negated
+ * version of it, the class is considered active.
+ *
+ * @param {Element} element
+ * @param {string} className
+ * @param {boolean} [defaultActivation=false]
+ * @returns {boolean}
+ */
+ isActive: function (element, className, defaultActivation) {
+ var no = "no-" + className;
+
+ while (element) {
+ var classList = element.classList;
+ if (classList.contains(className)) {
+ return true;
+ }
+ if (classList.contains(no)) {
+ return false;
+ }
+ element = element.parentElement;
+ }
+ return !!defaultActivation;
+ },
+ },
+
+ /**
+ * This namespace contains all currently loaded languages and the some helper functions to create and modify languages.
+ *
+ * @namespace
+ * @memberof Prism
+ * @public
+ */
+ languages: {
+ /**
+ * The grammar for plain, unformatted text.
+ */
+ plain: plainTextGrammar,
+ plaintext: plainTextGrammar,
+ text: plainTextGrammar,
+ txt: plainTextGrammar,
+
+ /**
+ * Creates a deep copy of the language with the given id and appends the given tokens.
+ *
+ * If a token in `redef` also appears in the copied language, then the existing token in the copied language
+ * will be overwritten at its original position.
+ *
+ * ## Best practices
+ *
+ * Since the position of overwriting tokens (token in `redef` that overwrite tokens in the copied language)
+ * doesn't matter, they can technically be in any order. However, this can be confusing to others that trying to
+ * understand the language definition because, normally, the order of tokens matters in Prism grammars.
+ *
+ * Therefore, it is encouraged to order overwriting tokens according to the positions of the overwritten tokens.
+ * Furthermore, all non-overwriting tokens should be placed after the overwriting ones.
+ *
+ * @param {string} id The id of the language to extend. This has to be a key in `Prism.languages`.
+ * @param {Grammar} redef The new tokens to append.
+ * @returns {Grammar} The new language created.
+ * @public
+ * @example
+ * Prism.languages['css-with-colors'] = Prism.languages.extend('css', {
+ * // Prism.languages.css already has a 'comment' token, so this token will overwrite CSS' 'comment' token
+ * // at its original position
+ * 'comment': { ... },
+ * // CSS doesn't have a 'color' token, so this token will be appended
+ * 'color': /\b(?:red|green|blue)\b/
+ * });
+ */
+ extend: function (id, redef) {
+ var lang = _.util.clone(_.languages[id]);
+
+ for (var key in redef) {
+ lang[key] = redef[key];
+ }
+
+ return lang;
+ },
+
+ /**
+ * Inserts tokens _before_ another token in a language definition or any other grammar.
+ *
+ * ## Usage
+ *
+ * This helper method makes it easy to modify existing languages. For example, the CSS language definition
+ * not only defines CSS highlighting for CSS documents, but also needs to define highlighting for CSS embedded
+ * in HTML through `<style>` elements. To do this, it needs to modify `Prism.languages.markup` and add the
+ * appropriate tokens. However, `Prism.languages.markup` is a regular JavaScript object literal, so if you do
+ * this:
+ *
+ * ```js
+ * Prism.languages.markup.style = {
+ * // token
+ * };
+ * ```
+ *
+ * then the `style` token will be added (and processed) at the end. `insertBefore` allows you to insert tokens
+ * before existing tokens. For the CSS example above, you would use it like this:
+ *
+ * ```js
+ * Prism.languages.insertBefore('markup', 'cdata', {
+ * 'style': {
+ * // token
+ * }
+ * });
+ * ```
+ *
+ * ## Special cases
+ *
+ * If the grammars of `inside` and `insert` have tokens with the same name, the tokens in `inside`'s grammar
+ * will be ignored.
+ *
+ * This behavior can be used to insert tokens after `before`:
+ *
+ * ```js
+ * Prism.languages.insertBefore('markup', 'comment', {
+ * 'comment': Prism.languages.markup.comment,
+ * // tokens after 'comment'
+ * });
+ * ```
+ *
+ * ## Limitations
+ *
+ * The main problem `insertBefore` has to solve is iteration order. Since ES2015, the iteration order for object
+ * properties is guaranteed to be the insertion order (except for integer keys) but some browsers behave
+ * differently when keys are deleted and re-inserted. So `insertBefore` can't be implemented by temporarily
+ * deleting properties which is necessary to insert at arbitrary positions.
+ *
+ * To solve this problem, `insertBefore` doesn't actually insert the given tokens into the target object.
+ * Instead, it will create a new object and replace all references to the target object with the new one. This
+ * can be done without temporarily deleting properties, so the iteration order is well-defined.
+ *
+ * However, only references that can be reached from `Prism.languages` or `insert` will be replaced. I.e. if
+ * you hold the target object in a variable, then the value of the variable will not change.
+ *
+ * ```js
+ * var oldMarkup = Prism.languages.markup;
+ * var newMarkup = Prism.languages.insertBefore('markup', 'comment', { ... });
+ *
+ * assert(oldMarkup !== Prism.languages.markup);
+ * assert(newMarkup === Prism.languages.markup);
+ * ```
+ *
+ * @param {string} inside The property of `root` (e.g. a language id in `Prism.languages`) that contains the
+ * object to be modified.
+ * @param {string} before The key to insert before.
+ * @param {Grammar} insert An object containing the key-value pairs to be inserted.
+ * @param {Object<string, any>} [root] The object containing `inside`, i.e. the object that contains the
+ * object to be modified.
+ *
+ * Defaults to `Prism.languages`.
+ * @returns {Grammar} The new grammar object.
+ * @public
+ */
+ insertBefore: function (inside, before, insert, root) {
+ root = root || /** @type {any} */ (_.languages);
+ var grammar = root[inside];
+ /** @type {Grammar} */
+ var ret = {};
+
+ for (var token in grammar) {
+ if (grammar.hasOwnProperty(token)) {
+ if (token == before) {
+ for (var newToken in insert) {
+ if (insert.hasOwnProperty(newToken)) {
+ ret[newToken] = insert[newToken];
+ }
+ }
+ }
+
+ // Do not insert token which also occur in insert. See #1525
+ if (!insert.hasOwnProperty(token)) {
+ ret[token] = grammar[token];
+ }
+ }
+ }
+
+ var old = root[inside];
+ root[inside] = ret;
+
+ // Update references in other language definitions
+ _.languages.DFS(_.languages, function (key, value) {
+ if (value === old && key != inside) {
+ this[key] = ret;
+ }
+ });
+
+ return ret;
+ },
+
+ // Traverse a language definition with Depth First Search
+ DFS: function DFS(o, callback, type, visited) {
+ visited = visited || {};
+
+ var objId = _.util.objId;
+
+ for (var i in o) {
+ if (o.hasOwnProperty(i)) {
+ callback.call(o, i, o[i], type || i);
+
+ var property = o[i];
+ var propertyType = _.util.type(property);
+
+ if (propertyType === "Object" && !visited[objId(property)]) {
+ visited[objId(property)] = true;
+ DFS(property, callback, null, visited);
+ } else if (propertyType === "Array" && !visited[objId(property)]) {
+ visited[objId(property)] = true;
+ DFS(property, callback, i, visited);
+ }
+ }
+ }
+ },
+ },
+
+ plugins: {},
+
+ /**
+ * This is the most high-level function in Prism’s API.
+ * It fetches all the elements that have a `.language-xxxx` class and then calls {@link Prism.highlightElement} on
+ * each one of them.
+ *
+ * This is equivalent to `Prism.highlightAllUnder(document, async, callback)`.
+ *
+ * @param {boolean} [async=false] Same as in {@link Prism.highlightAllUnder}.
+ * @param {HighlightCallback} [callback] Same as in {@link Prism.highlightAllUnder}.
+ * @memberof Prism
+ * @public
+ */
+ highlightAll: function (async, callback) {
+ _.highlightAllUnder(document, async, callback);
+ },
+
+ /**
+ * Fetches all the descendants of `container` that have a `.language-xxxx` class and then calls
+ * {@link Prism.highlightElement} on each one of them.
+ *
+ * The following hooks will be run:
+ * 1. `before-highlightall`
+ * 2. `before-all-elements-highlight`
+ * 3. All hooks of {@link Prism.highlightElement} for each element.
+ *
+ * @param {ParentNode} container The root element, whose descendants that have a `.language-xxxx` class will be highlighted.
+ * @param {boolean} [async=false] Whether each element is to be highlighted asynchronously using Web Workers.
+ * @param {HighlightCallback} [callback] An optional callback to be invoked on each element after its highlighting is done.
+ * @memberof Prism
+ * @public
+ */
+ highlightAllUnder: function (container, async, callback) {
+ var env = {
+ callback: callback,
+ container: container,
+ selector:
+ 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code',
+ };
+
+ _.hooks.run("before-highlightall", env);
+
+ env.elements = Array.prototype.slice.apply(
+ env.container.querySelectorAll(env.selector)
+ );
+
+ _.hooks.run("before-all-elements-highlight", env);
+
+ for (var i = 0, element; (element = env.elements[i++]); ) {
+ _.highlightElement(element, async === true, env.callback);
+ }
+ },
+
+ /**
+ * Highlights the code inside a single element.
+ *
+ * The following hooks will be run:
+ * 1. `before-sanity-check`
+ * 2. `before-highlight`
+ * 3. All hooks of {@link Prism.highlight}. These hooks will be run by an asynchronous worker if `async` is `true`.
+ * 4. `before-insert`
+ * 5. `after-highlight`
+ * 6. `complete`
+ *
+ * Some the above hooks will be skipped if the element doesn't contain any text or there is no grammar loaded for
+ * the element's language.
+ *
+ * @param {Element} element The element containing the code.
+ * It must have a class of `language-xxxx` to be processed, where `xxxx` is a valid language identifier.
+ * @param {boolean} [async=false] Whether the element is to be highlighted asynchronously using Web Workers
+ * to improve performance and avoid blocking the UI when highlighting very large chunks of code. This option is
+ * [disabled by default](https://prismjs.com/faq.html#why-is-asynchronous-highlighting-disabled-by-default).
+ *
+ * Note: All language definitions required to highlight the code must be included in the main `prism.js` file for
+ * asynchronous highlighting to work. You can build your own bundle on the
+ * [Download page](https://prismjs.com/download.html).
+ * @param {HighlightCallback} [callback] An optional callback to be invoked after the highlighting is done.
+ * Mostly useful when `async` is `true`, since in that case, the highlighting is done asynchronously.
+ * @memberof Prism
+ * @public
+ */
+ highlightElement: function (element, async, callback) {
+ // Find language
+ var language = _.util.getLanguage(element);
+ var grammar = _.languages[language];
+
+ // Set language on the element, if not present
+ _.util.setLanguage(element, language);
+
+ // Set language on the parent, for styling
+ var parent = element.parentElement;
+ if (parent && parent.nodeName.toLowerCase() === "pre") {
+ _.util.setLanguage(parent, language);
+ }
+
+ var code = element.textContent;
+
+ var env = {
+ element: element,
+ language: language,
+ grammar: grammar,
+ code: code,
+ };
+
+ function insertHighlightedCode(highlightedCode) {
+ env.highlightedCode = highlightedCode;
+
+ _.hooks.run("before-insert", env);
+
+ env.element.innerHTML = env.highlightedCode;
+
+ _.hooks.run("after-highlight", env);
+ _.hooks.run("complete", env);
+ callback && callback.call(env.element);
+ }
+
+ _.hooks.run("before-sanity-check", env);
+
+ // plugins may change/add the parent/element
+ parent = env.element.parentElement;
+ if (
+ parent &&
+ parent.nodeName.toLowerCase() === "pre" &&
+ !parent.hasAttribute("tabindex")
+ ) {
+ parent.setAttribute("tabindex", "0");
+ }
+
+ if (!env.code) {
+ _.hooks.run("complete", env);
+ callback && callback.call(env.element);
+ return;
+ }
+
+ _.hooks.run("before-highlight", env);
+
+ if (!env.grammar) {
+ insertHighlightedCode(_.util.encode(env.code));
+ return;
+ }
+
+ if (async && _self.Worker) {
+ var worker = new Worker(_.filename);
+
+ worker.onmessage = function (evt) {
+ insertHighlightedCode(evt.data);
+ };
+
+ worker.postMessage(
+ JSON.stringify({
+ language: env.language,
+ code: env.code,
+ immediateClose: true,
+ })
+ );
+ } else {
+ insertHighlightedCode(_.highlight(env.code, env.grammar, env.language));
+ }
+ },
+
+ /**
+ * Low-level function, only use if you know what you’re doing. It accepts a string of text as input
+ * and the language definitions to use, and returns a string with the HTML produced.
+ *
+ * The following hooks will be run:
+ * 1. `before-tokenize`
+ * 2. `after-tokenize`
+ * 3. `wrap`: On each {@link Token}.
+ *
+ * @param {string} text A string with the code to be highlighted.
+ * @param {Grammar} grammar An object containing the tokens to use.
+ *
+ * Usually a language definition like `Prism.languages.markup`.
+ * @param {string} language The name of the language definition passed to `grammar`.
+ * @returns {string} The highlighted HTML.
+ * @memberof Prism
+ * @public
+ * @example
+ * Prism.highlight('var foo = true;', Prism.languages.javascript, 'javascript');
+ */
+ highlight: function (text, grammar, language) {
+ var env = {
+ code: text,
+ grammar: grammar,
+ language: language,
+ };
+ _.hooks.run("before-tokenize", env);
+ if (!env.grammar) {
+ throw new Error('The language "' + env.language + '" has no grammar.');
+ }
+ env.tokens = _.tokenize(env.code, env.grammar);
+ _.hooks.run("after-tokenize", env);
+ return Token.stringify(_.util.encode(env.tokens), env.language);
+ },
+
+ /**
+ * This is the heart of Prism, and the most low-level function you can use. It accepts a string of text as input
+ * and the language definitions to use, and returns an array with the tokenized code.
+ *
+ * When the language definition includes nested tokens, the function is called recursively on each of these tokens.
+ *
+ * This method could be useful in other contexts as well, as a very crude parser.
+ *
+ * @param {string} text A string with the code to be highlighted.
+ * @param {Grammar} grammar An object containing the tokens to use.
+ *
+ * Usually a language definition like `Prism.languages.markup`.
+ * @returns {TokenStream} An array of strings and tokens, a token stream.
+ * @memberof Prism
+ * @public
+ * @example
+ * let code = `var foo = 0;`;
+ * let tokens = Prism.tokenize(code, Prism.languages.javascript);
+ * tokens.forEach(token => {
+ * if (token instanceof Prism.Token && token.type === 'number') {
+ * console.log(`Found numeric literal: ${token.content}`);
+ * }
+ * });
+ */
+ tokenize: function (text, grammar) {
+ var rest = grammar.rest;
+ if (rest) {
+ for (var token in rest) {
+ grammar[token] = rest[token];
+ }
+
+ delete grammar.rest;
+ }
+
+ var tokenList = new LinkedList();
+ addAfter(tokenList, tokenList.head, text);
+
+ matchGrammar(text, tokenList, grammar, tokenList.head, 0);
+
+ return toArray(tokenList);
+ },
+
+ /**
+ * @namespace
+ * @memberof Prism
+ * @public
+ */
+ hooks: {
+ all: {},
+
+ /**
+ * Adds the given callback to the list of callbacks for the given hook.
+ *
+ * The callback will be invoked when the hook it is registered for is run.
+ * Hooks are usually directly run by a highlight function but you can also run hooks yourself.
+ *
+ * One callback function can be registered to multiple hooks and the same hook multiple times.
+ *
+ * @param {string} name The name of the hook.
+ * @param {HookCallback} callback The callback function which is given environment variables.
+ * @public
+ */
+ add: function (name, callback) {
+ var hooks = _.hooks.all;
+
+ hooks[name] = hooks[name] || [];
+
+ hooks[name].push(callback);
+ },
+
+ /**
+ * Runs a hook invoking all registered callbacks with the given environment variables.
+ *
+ * Callbacks will be invoked synchronously and in the order in which they were registered.
+ *
+ * @param {string} name The name of the hook.
+ * @param {Object<string, any>} env The environment variables of the hook passed to all callbacks registered.
+ * @public
+ */
+ run: function (name, env) {
+ var callbacks = _.hooks.all[name];
+
+ if (!callbacks || !callbacks.length) {
+ return;
+ }
+
+ for (var i = 0, callback; (callback = callbacks[i++]); ) {
+ callback(env);
+ }
+ },
+ },
+
+ Token: Token,
+ };
+ _self.Prism = _;
+
+ // Typescript note:
+ // The following can be used to import the Token type in JSDoc:
+ //
+ // @typedef {InstanceType<import("./prism-core")["Token"]>} Token
+
+ /**
+ * Creates a new token.
+ *
+ * @param {string} type See {@link Token#type type}
+ * @param {string | TokenStream} content See {@link Token#content content}
+ * @param {string|string[]} [alias] The alias(es) of the token.
+ * @param {string} [matchedStr=""] A copy of the full string this token was created from.
+ * @class
+ * @global
+ * @public
+ */
+ function Token(type, content, alias, matchedStr) {
+ /**
+ * The type of the token.
+ *
+ * This is usually the key of a pattern in a {@link Grammar}.
+ *
+ * @type {string}
+ * @see GrammarToken
+ * @public
+ */
+ this.type = type;
+ /**
+ * The strings or tokens contained by this token.
+ *
+ * This will be a token stream if the pattern matched also defined an `inside` grammar.
+ *
+ * @type {string | TokenStream}
+ * @public
+ */
+ this.content = content;
+ /**
+ * The alias(es) of the token.
+ *
+ * @type {string|string[]}
+ * @see GrammarToken
+ * @public
+ */
+ this.alias = alias;
+ // Copy of the full string this token was created from
+ this.length = (matchedStr || "").length | 0;
+ }
+
+ /**
+ * A token stream is an array of strings and {@link Token Token} objects.
+ *
+ * Token streams have to fulfill a few properties that are assumed by most functions (mostly internal ones) that process
+ * them.
+ *
+ * 1. No adjacent strings.
+ * 2. No empty strings.
+ *
+ * The only exception here is the token stream that only contains the empty string and nothing else.
+ *
+ * @typedef {Array<string | Token>} TokenStream
+ * @global
+ * @public
+ */
+
+ /**
+ * Converts the given token or token stream to an HTML representation.
+ *
+ * The following hooks will be run:
+ * 1. `wrap`: On each {@link Token}.
+ *
+ * @param {string | Token | TokenStream} o The token or token stream to be converted.
+ * @param {string} language The name of current language.
+ * @returns {string} The HTML representation of the token or token stream.
+ * @memberof Token
+ * @static
+ */
+ Token.stringify = function stringify(o, language) {
+ if (typeof o == "string") {
+ return o;
+ }
+ if (Array.isArray(o)) {
+ var s = "";
+ o.forEach(function (e) {
+ s += stringify(e, language);
+ });
+ return s;
+ }
+
+ var env = {
+ type: o.type,
+ content: stringify(o.content, language),
+ tag: "span",
+ classes: ["token", o.type],
+ attributes: {},
+ language: language,
+ };
+
+ var aliases = o.alias;
+ if (aliases) {
+ if (Array.isArray(aliases)) {
+ Array.prototype.push.apply(env.classes, aliases);
+ } else {
+ env.classes.push(aliases);
+ }
+ }
+
+ _.hooks.run("wrap", env);
+
+ var attributes = "";
+ for (var name in env.attributes) {
+ attributes +=
+ " " +
+ name +
+ '="' +
+ (env.attributes[name] || "").replace(/"/g, """) +
+ '"';
+ }
+
+ return (
+ "<" +
+ env.tag +
+ ' class="' +
+ env.classes.join(" ") +
+ '"' +
+ attributes +
+ ">" +
+ env.content +
+ "</" +
+ env.tag +
+ ">"
+ );
+ };
+
+ /**
+ * @param {RegExp} pattern
+ * @param {number} pos
+ * @param {string} text
+ * @param {boolean} lookbehind
+ * @returns {RegExpExecArray | null}
+ */
+ function matchPattern(pattern, pos, text, lookbehind) {
+ pattern.lastIndex = pos;
+ var match = pattern.exec(text);
+ if (match && lookbehind && match[1]) {
+ // change the match to remove the text matched by the Prism lookbehind group
+ var lookbehindLength = match[1].length;
+ match.index += lookbehindLength;
+ match[0] = match[0].slice(lookbehindLength);
+ }
+ return match;
+ }
+
+ /**
+ * @param {string} text
+ * @param {LinkedList<string | Token>} tokenList
+ * @param {any} grammar
+ * @param {LinkedListNode<string | Token>} startNode
+ * @param {number} startPos
+ * @param {RematchOptions} [rematch]
+ * @returns {void}
+ * @private
+ *
+ * @typedef RematchOptions
+ * @property {string} cause
+ * @property {number} reach
+ */
+ function matchGrammar(
+ text,
+ tokenList,
+ grammar,
+ startNode,
+ startPos,
+ rematch
+ ) {
+ for (var token in grammar) {
+ if (!grammar.hasOwnProperty(token) || !grammar[token]) {
+ continue;
+ }
+
+ var patterns = grammar[token];
+ patterns = Array.isArray(patterns) ? patterns : [patterns];
+
+ for (var j = 0; j < patterns.length; ++j) {
+ if (rematch && rematch.cause == token + "," + j) {
+ return;
+ }
+
+ var patternObj = patterns[j];
+ var inside = patternObj.inside;
+ var lookbehind = !!patternObj.lookbehind;
+ var greedy = !!patternObj.greedy;
+ var alias = patternObj.alias;
+
+ if (greedy && !patternObj.pattern.global) {
+ // Without the global flag, lastIndex won't work
+ var flags = patternObj.pattern.toString().match(/[imsuy]*$/)[0];
+ patternObj.pattern = RegExp(patternObj.pattern.source, flags + "g");
+ }
+
+ /** @type {RegExp} */
+ var pattern = patternObj.pattern || patternObj;
+
+ for (
+ // iterate the token list and keep track of the current token/string position
+ var currentNode = startNode.next, pos = startPos;
+ currentNode !== tokenList.tail;
+ pos += currentNode.value.length, currentNode = currentNode.next
+ ) {
+ if (rematch && pos >= rematch.reach) {
+ break;
+ }
+
+ var str = currentNode.value;
+
+ if (tokenList.length > text.length) {
+ // Something went terribly wrong, ABORT, ABORT!
+ return;
+ }
+
+ if (str instanceof Token) {
+ continue;
+ }
+
+ var removeCount = 1; // this is the to parameter of removeBetween
+ var match;
+
+ if (greedy) {
+ match = matchPattern(pattern, pos, text, lookbehind);
+ if (!match || match.index >= text.length) {
+ break;
+ }
+
+ var from = match.index;
+ var to = match.index + match[0].length;
+ var p = pos;
+
+ // find the node that contains the match
+ p += currentNode.value.length;
+ while (from >= p) {
+ currentNode = currentNode.next;
+ p += currentNode.value.length;
+ }
+ // adjust pos (and p)
+ p -= currentNode.value.length;
+ pos = p;
+
+ // the current node is a Token, then the match starts inside another Token, which is invalid
+ if (currentNode.value instanceof Token) {
+ continue;
+ }
+
+ // find the last node which is affected by this match
+ for (
+ var k = currentNode;
+ k !== tokenList.tail && (p < to || typeof k.value === "string");
+ k = k.next
+ ) {
+ removeCount++;
+ p += k.value.length;
+ }
+ removeCount--;
+
+ // replace with the new match
+ str = text.slice(pos, p);
+ match.index -= pos;
+ } else {
+ match = matchPattern(pattern, 0, str, lookbehind);
+ if (!match) {
+ continue;
+ }
+ }
+
+ // eslint-disable-next-line no-redeclare
+ var from = match.index;
+ var matchStr = match[0];
+ var before = str.slice(0, from);
+ var after = str.slice(from + matchStr.length);
+
+ var reach = pos + str.length;
+ if (rematch && reach > rematch.reach) {
+ rematch.reach = reach;
+ }
+
+ var removeFrom = currentNode.prev;
+
+ if (before) {
+ removeFrom = addAfter(tokenList, removeFrom, before);
+ pos += before.length;
+ }
+
+ removeRange(tokenList, removeFrom, removeCount);
+
+ var wrapped = new Token(
+ token,
+ inside ? _.tokenize(matchStr, inside) : matchStr,
+ alias,
+ matchStr
+ );
+ currentNode = addAfter(tokenList, removeFrom, wrapped);
+
+ if (after) {
+ addAfter(tokenList, currentNode, after);
+ }
+
+ if (removeCount > 1) {
+ // at least one Token object was removed, so we have to do some rematching
+ // this can only happen if the current pattern is greedy
+
+ /** @type {RematchOptions} */
+ var nestedRematch = {
+ cause: token + "," + j,
+ reach: reach,
+ };
+ matchGrammar(
+ text,
+ tokenList,
+ grammar,
+ currentNode.prev,
+ pos,
+ nestedRematch
+ );
+
+ // the reach might have been extended because of the rematching
+ if (rematch && nestedRematch.reach > rematch.reach) {
+ rematch.reach = nestedRematch.reach;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @typedef LinkedListNode
+ * @property {T} value
+ * @property {LinkedListNode<T> | null} prev The previous node.
+ * @property {LinkedListNode<T> | null} next The next node.
+ * @template T
+ * @private
+ */
+
+ /**
+ * @template T
+ * @private
+ */
+ function LinkedList() {
+ /** @type {LinkedListNode<T>} */
+ var head = { value: null, prev: null, next: null };
+ /** @type {LinkedListNode<T>} */
+ var tail = { value: null, prev: head, next: null };
+ head.next = tail;
+
+ /** @type {LinkedListNode<T>} */
+ this.head = head;
+ /** @type {LinkedListNode<T>} */
+ this.tail = tail;
+ this.length = 0;
+ }
+
+ /**
+ * Adds a new node with the given value to the list.
+ *
+ * @param {LinkedList<T>} list
+ * @param {LinkedListNode<T>} node
+ * @param {T} value
+ * @returns {LinkedListNode<T>} The added node.
+ * @template T
+ */
+ function addAfter(list, node, value) {
+ // assumes that node != list.tail && values.length >= 0
+ var next = node.next;
+
+ var newNode = { value: value, prev: node, next: next };
+ node.next = newNode;
+ next.prev = newNode;
+ list.length++;
+
+ return newNode;
+ }
+ /**
+ * Removes `count` nodes after the given node. The given node will not be removed.
+ *
+ * @param {LinkedList<T>} list
+ * @param {LinkedListNode<T>} node
+ * @param {number} count
+ * @template T
+ */
+ function removeRange(list, node, count) {
+ var next = node.next;
+ for (var i = 0; i < count && next !== list.tail; i++) {
+ next = next.next;
+ }
+ node.next = next;
+ next.prev = node;
+ list.length -= i;
+ }
+ /**
+ * @param {LinkedList<T>} list
+ * @returns {T[]}
+ * @template T
+ */
+ function toArray(list) {
+ var array = [];
+ var node = list.head.next;
+ while (node !== list.tail) {
+ array.push(node.value);
+ node = node.next;
+ }
+ return array;
+ }
+
+ if (!_self.document) {
+ if (!_self.addEventListener) {
+ // in Node.js
+ return _;
+ }
+
+ if (!_.disableWorkerMessageHandler) {
+ // In worker
+ _self.addEventListener(
+ "message",
+ function (evt) {
+ var message = JSON.parse(evt.data);
+ var lang = message.language;
+ var code = message.code;
+ var immediateClose = message.immediateClose;
+
+ _self.postMessage(_.highlight(code, _.languages[lang], lang));
+ if (immediateClose) {
+ _self.close();
+ }
+ },
+ false
+ );
+ }
+
+ return _;
+ }
+
+ // Get current script and highlight
+ var script = _.util.currentScript();
+
+ if (script) {
+ _.filename = script.src;
+
+ if (script.hasAttribute("data-manual")) {
+ _.manual = true;
+ }
+ }
+
+ function highlightAutomaticallyCallback() {
+ if (!_.manual) {
+ _.highlightAll();
+ }
+ }
+
+ if (!_.manual) {
+ // If the document state is "loading", then we'll use DOMContentLoaded.
+ // If the document state is "interactive" and the prism.js script is deferred, then we'll also use the
+ // DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they
+ // might take longer one animation frame to execute which can create a race condition where only some plugins have
+ // been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded.
+ // See https://github.com/PrismJS/prism/issues/2102
+ var readyState = document.readyState;
+ if (
+ readyState === "loading" ||
+ (readyState === "interactive" && script && script.defer)
+ ) {
+ document.addEventListener(
+ "DOMContentLoaded",
+ highlightAutomaticallyCallback
+ );
+ } else {
+ if (window.requestAnimationFrame) {
+ window.requestAnimationFrame(highlightAutomaticallyCallback);
+ } else {
+ window.setTimeout(highlightAutomaticallyCallback, 16);
+ }
+ }
+ }
+
+ return _;
+})(_self);
+
+if (typeof module !== "undefined" && module.exports) {
+ module.exports = Prism;
+}
+
+// hack for components to work correctly in node.js
+if (typeof global !== "undefined") {
+ global.Prism = Prism;
+}
+
+// some additional documentation/types
+
+/**
+ * The expansion of a simple `RegExp` literal to support additional properties.
+ *
+ * @typedef GrammarToken
+ * @property {RegExp} pattern The regular expression of the token.
+ * @property {boolean} [lookbehind=false] If `true`, then the first capturing group of `pattern` will (effectively)
+ * behave as a lookbehind group meaning that the captured text will not be part of the matched text of the new token.
+ * @property {boolean} [greedy=false] Whether the token is greedy.
+ * @property {string|string[]} [alias] An optional alias or list of aliases.
+ * @property {Grammar} [inside] The nested grammar of this token.
+ *
+ * The `inside` grammar will be used to tokenize the text value of each token of this kind.
+ *
+ * This can be used to make nested and even recursive language definitions.
+ *
+ * Note: This can cause infinite recursion. Be careful when you embed different languages or even the same language into
+ * each another.
+ * @global
+ * @public
+ */
+
+/**
+ * @typedef Grammar
+ * @type {Object<string, RegExp | GrammarToken | Array<RegExp | GrammarToken>>}
+ * @property {Grammar} [rest] An optional grammar object that will be appended to this grammar.
+ * @global
+ * @public
+ */
+
+/**
+ * A function which will invoked after an element was successfully highlighted.
+ *
+ * @callback HighlightCallback
+ * @param {Element} element The element successfully highlighted.
+ * @returns {void}
+ * @global
+ * @public
+ */
+
+/**
+ * @callback HookCallback
+ * @param {Object<string, any>} env The environment variables of the hook.
+ * @returns {void}
+ * @global
+ * @public
+ */
+Prism.languages.markup = {
+ comment: {
+ pattern: /<!--(?:(?!<!--)[\s\S])*?-->/,
+ greedy: true,
+ },
+ prolog: {
+ pattern: /<\?[\s\S]+?\?>/,
+ greedy: true,
+ },
+ doctype: {
+ // https://www.w3.org/TR/xml/#NT-doctypedecl
+ pattern:
+ /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,
+ greedy: true,
+ inside: {
+ "internal-subset": {
+ pattern: /(^[^\[]*\[)[\s\S]+(?=\]>$)/,
+ lookbehind: true,
+ greedy: true,
+ inside: null, // see below
+ },
+ string: {
+ pattern: /"[^"]*"|'[^']*'/,
+ greedy: true,
+ },
+ punctuation: /^<!|>$|[[\]]/,
+ "doctype-tag": /^DOCTYPE/i,
+ name: /[^\s<>'"]+/,
+ },
+ },
+ cdata: {
+ pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
+ greedy: true,
+ },
+ tag: {
+ pattern:
+ /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,
+ greedy: true,
+ inside: {
+ tag: {
+ pattern: /^<\/?[^\s>\/]+/,
+ inside: {
+ punctuation: /^<\/?/,
+ namespace: /^[^\s>\/:]+:/,
+ },
+ },
+ "special-attr": [],
+ "attr-value": {
+ pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,
+ inside: {
+ punctuation: [
+ {
+ pattern: /^=/,
+ alias: "attr-equals",
+ },
+ {
+ pattern: /^(\s*)["']|["']$/,
+ lookbehind: true,
+ },
+ ],
+ },
+ },
+ punctuation: /\/?>/,
+ "attr-name": {
+ pattern: /[^\s>\/]+/,
+ inside: {
+ namespace: /^[^\s>\/:]+:/,
+ },
+ },
+ },
+ },
+ entity: [
+ {
+ pattern: /&[\da-z]{1,8};/i,
+ alias: "named-entity",
+ },
+ /&#x?[\da-f]{1,8};/i,
+ ],
+};
+
+Prism.languages.markup["tag"].inside["attr-value"].inside["entity"] =
+ Prism.languages.markup["entity"];
+Prism.languages.markup["doctype"].inside["internal-subset"].inside =
+ Prism.languages.markup;
+
+// Plugin to make entity title show the real entity, idea by Roman Komarov
+Prism.hooks.add("wrap", function (env) {
+ if (env.type === "entity") {
+ env.attributes["title"] = env.content.replace(/&/, "&");
+ }
+});
+
+Object.defineProperty(Prism.languages.markup.tag, "addInlined", {
+ /**
+ * Adds an inlined language to markup.
+ *
+ * An example of an inlined language is CSS with `<style>` tags.
+ *
+ * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as
+ * case insensitive.
+ * @param {string} lang The language key.
+ * @example
+ * addInlined('style', 'css');
+ */
+ value: function addInlined(tagName, lang) {
+ var includedCdataInside = {};
+ includedCdataInside["language-" + lang] = {
+ pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,
+ lookbehind: true,
+ inside: Prism.languages[lang],
+ };
+ includedCdataInside["cdata"] = /^<!\[CDATA\[|\]\]>$/i;
+
+ var inside = {
+ "included-cdata": {
+ pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
+ inside: includedCdataInside,
+ },
+ };
+ inside["language-" + lang] = {
+ pattern: /[\s\S]+/,
+ inside: Prism.languages[lang],
+ };
+
+ var def = {};
+ def[tagName] = {
+ pattern: RegExp(
+ /(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(
+ /__/g,
+ function () {
+ return tagName;
+ }
+ ),
+ "i"
+ ),
+ lookbehind: true,
+ greedy: true,
+ inside: inside,
+ };
+
+ Prism.languages.insertBefore("markup", "cdata", def);
+ },
+});
+Object.defineProperty(Prism.languages.markup.tag, "addAttribute", {
+ /**
+ * Adds an pattern to highlight languages embedded in HTML attributes.
+ *
+ * An example of an inlined language is CSS with `style` attributes.
+ *
+ * @param {string} attrName The name of the tag that contains the inlined language. This name will be treated as
+ * case insensitive.
+ * @param {string} lang The language key.
+ * @example
+ * addAttribute('style', 'css');
+ */
+ value: function (attrName, lang) {
+ Prism.languages.markup.tag.inside["special-attr"].push({
+ pattern: RegExp(
+ /(^|["'\s])/.source +
+ "(?:" +
+ attrName +
+ ")" +
+ /\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,
+ "i"
+ ),
+ lookbehind: true,
+ inside: {
+ "attr-name": /^[^\s=]+/,
+ "attr-value": {
+ pattern: /=[\s\S]+/,
+ inside: {
+ value: {
+ pattern: /(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,
+ lookbehind: true,
+ alias: [lang, "language-" + lang],
+ inside: Prism.languages[lang],
+ },
+ punctuation: [
+ {
+ pattern: /^=/,
+ alias: "attr-equals",
+ },
+ /"|'/,
+ ],
+ },
+ },
+ },
+ });
+ },
+});
+
+Prism.languages.html = Prism.languages.markup;
+Prism.languages.mathml = Prism.languages.markup;
+Prism.languages.svg = Prism.languages.markup;
+
+Prism.languages.xml = Prism.languages.extend("markup", {});
+Prism.languages.ssml = Prism.languages.xml;
+Prism.languages.atom = Prism.languages.xml;
+Prism.languages.rss = Prism.languages.xml;
+
+(function (Prism) {
+ var string =
+ /(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;
+
+ Prism.languages.css = {
+ comment: /\/\*[\s\S]*?\*\//,
+ atrule: {
+ pattern: RegExp(
+ "@[\\w-](?:" +
+ /[^;{\s"']|\s+(?!\s)/.source +
+ "|" +
+ string.source +
+ ")*?" +
+ /(?:;|(?=\s*\{))/.source
+ ),
+ inside: {
+ rule: /^@[\w-]+/,
+ "selector-function-argument": {
+ pattern:
+ /(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,
+ lookbehind: true,
+ alias: "selector",
+ },
+ keyword: {
+ pattern: /(^|[^\w-])(?:and|not|only|or)(?![\w-])/,
+ lookbehind: true,
+ },
+ // See rest below
+ },
+ },
+ url: {
+ // https://drafts.csswg.org/css-values-3/#urls
+ pattern: RegExp(
+ "\\burl\\((?:" +
+ string.source +
+ "|" +
+ /(?:[^\\\r\n()"']|\\[\s\S])*/.source +
+ ")\\)",
+ "i"
+ ),
+ greedy: true,
+ inside: {
+ function: /^url/i,
+ punctuation: /^\(|\)$/,
+ string: {
+ pattern: RegExp("^" + string.source + "$"),
+ alias: "url",
+ },
+ },
+ },
+ selector: {
+ pattern: RegExp(
+ "(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|" +
+ string.source +
+ ")*(?=\\s*\\{)"
+ ),
+ lookbehind: true,
+ },
+ string: {
+ pattern: string,
+ greedy: true,
+ },
+ property: {
+ pattern:
+ /(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,
+ lookbehind: true,
+ },
+ important: /!important\b/i,
+ function: {
+ pattern: /(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,
+ lookbehind: true,
+ },
+ punctuation: /[(){};:,]/,
+ };
+
+ Prism.languages.css["atrule"].inside.rest = Prism.languages.css;
+
+ var markup = Prism.languages.markup;
+ if (markup) {
+ markup.tag.addInlined("style", "css");
+ markup.tag.addAttribute("style", "css");
+ }
+})(Prism);
+
+Prism.languages.clike = {
+ comment: [
+ {
+ pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
+ lookbehind: true,
+ greedy: true,
+ },
+ {
+ pattern: /(^|[^\\:])\/\/.*/,
+ lookbehind: true,
+ greedy: true,
+ },
+ ],
+ string: {
+ pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
+ greedy: true,
+ },
+ "class-name": {
+ pattern:
+ /(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,
+ lookbehind: true,
+ inside: {
+ punctuation: /[.\\]/,
+ },
+ },
+ keyword:
+ /\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,
+ boolean: /\b(?:false|true)\b/,
+ function: /\b\w+(?=\()/,
+ number: /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,
+ operator: /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,
+ punctuation: /[{}[\];(),.:]/,
+};
+
+Prism.languages.javascript = Prism.languages.extend("clike", {
+ "class-name": [
+ Prism.languages.clike["class-name"],
+ {
+ pattern:
+ /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,
+ lookbehind: true,
+ },
+ ],
+ keyword: [
+ {
+ pattern: /((?:^|\})\s*)catch\b/,
+ lookbehind: true,
+ },
+ {
+ pattern:
+ /(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,
+ lookbehind: true,
+ },
+ ],
+ // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
+ function:
+ /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
+ number: {
+ pattern: RegExp(
+ /(^|[^\w$])/.source +
+ "(?:" +
+ // constant
+ (/NaN|Infinity/.source +
+ "|" +
+ // binary integer
+ /0[bB][01]+(?:_[01]+)*n?/.source +
+ "|" +
+ // octal integer
+ /0[oO][0-7]+(?:_[0-7]+)*n?/.source +
+ "|" +
+ // hexadecimal integer
+ /0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source +
+ "|" +
+ // decimal bigint
+ /\d+(?:_\d+)*n/.source +
+ "|" +
+ // decimal number (integer or float) but no bigint
+ /(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/
+ .source) +
+ ")" +
+ /(?![\w$])/.source
+ ),
+ lookbehind: true,
+ },
+ operator:
+ /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/,
+});
+
+Prism.languages.javascript["class-name"][0].pattern =
+ /(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/;
+
+Prism.languages.insertBefore("javascript", "keyword", {
+ regex: {
+ pattern: RegExp(
+ // lookbehind
+ // eslint-disable-next-line regexp/no-dupe-characters-character-class
+ /((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source +
+ // Regex pattern:
+ // There are 2 regex patterns here. The RegExp set notation proposal added support for nested character
+ // classes if the `v` flag is present. Unfortunately, nested CCs are both context-free and incompatible
+ // with the only syntax, so we have to define 2 different regex patterns.
+ /\//.source +
+ "(?:" +
+ /(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/
+ .source +
+ "|" +
+ // `v` flag syntax. This supports 3 levels of nested character classes.
+ /(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/
+ .source +
+ ")" +
+ // lookahead
+ /(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source
+ ),
+ lookbehind: true,
+ greedy: true,
+ inside: {
+ "regex-source": {
+ pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/,
+ lookbehind: true,
+ alias: "language-regex",
+ inside: Prism.languages.regex,
+ },
+ "regex-delimiter": /^\/|\/$/,
+ "regex-flags": /^[a-z]+$/,
+ },
+ },
+ // This must be declared before keyword because we use "function" inside the look-forward
+ "function-variable": {
+ pattern:
+ /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,
+ alias: "function",
+ },
+ parameter: [
+ {
+ pattern:
+ /(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,
+ lookbehind: true,
+ inside: Prism.languages.javascript,
+ },
+ {
+ pattern:
+ /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,
+ lookbehind: true,
+ inside: Prism.languages.javascript,
+ },
+ {
+ pattern:
+ /(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,
+ lookbehind: true,
+ inside: Prism.languages.javascript,
+ },
+ {
+ pattern:
+ /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,
+ lookbehind: true,
+ inside: Prism.languages.javascript,
+ },
+ ],
+ constant: /\b[A-Z](?:[A-Z_]|\dx?)*\b/,
+});
+
+Prism.languages.insertBefore("javascript", "string", {
+ hashbang: {
+ pattern: /^#!.*/,
+ greedy: true,
+ alias: "comment",
+ },
+ "template-string": {
+ pattern:
+ /`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,
+ greedy: true,
+ inside: {
+ "template-punctuation": {
+ pattern: /^`|`$/,
+ alias: "string",
+ },
+ interpolation: {
+ pattern:
+ /((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,
+ lookbehind: true,
+ inside: {
+ "interpolation-punctuation": {
+ pattern: /^\$\{|\}$/,
+ alias: "punctuation",
+ },
+ rest: Prism.languages.javascript,
+ },
+ },
+ string: /[\s\S]+/,
+ },
+ },
+ "string-property": {
+ pattern:
+ /((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,
+ lookbehind: true,
+ greedy: true,
+ alias: "property",
+ },
+});
+
+Prism.languages.insertBefore("javascript", "operator", {
+ "literal-property": {
+ pattern:
+ /((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,
+ lookbehind: true,
+ alias: "property",
+ },
+});
+
+if (Prism.languages.markup) {
+ Prism.languages.markup.tag.addInlined("script", "javascript");
+
+ // add attribute support for all DOM events.
+ // https://developer.mozilla.org/en-US/docs/Web/Events#Standard_events
+ Prism.languages.markup.tag.addAttribute(
+ /on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/
+ .source,
+ "javascript"
+ );
+}
+
+Prism.languages.js = Prism.languages.javascript;
+
+(function (Prism) {
+ Prism.languages.diff = {
+ coord: [
+ // Match all kinds of coord lines (prefixed by "+++", "---" or "***").
+ /^(?:\*{3}|-{3}|\+{3}).*$/m,
+ // Match "@@ ... @@" coord lines in unified diff.
+ /^@@.*@@$/m,
+ // Match coord lines in normal diff (starts with a number).
+ /^\d.*$/m,
+ ],
+
+ // deleted, inserted, unchanged, diff
+ };
+
+ /**
+ * A map from the name of a block to its line prefix.
+ *
+ * @type {Object<string, string>}
+ */
+ var PREFIXES = {
+ "deleted-sign": "-",
+ "deleted-arrow": "<",
+ "inserted-sign": "+",
+ "inserted-arrow": ">",
+ unchanged: " ",
+ diff: "!",
+ };
+
+ // add a token for each prefix
+ Object.keys(PREFIXES).forEach(function (name) {
+ var prefix = PREFIXES[name];
+
+ var alias = [];
+ if (!/^\w+$/.test(name)) {
+ // "deleted-sign" -> "deleted"
+ alias.push(/\w+/.exec(name)[0]);
+ }
+ if (name === "diff") {
+ alias.push("bold");
+ }
+
+ Prism.languages.diff[name] = {
+ pattern: RegExp("^(?:[" + prefix + "].*(?:\r\n?|\n|(?![\\s\\S])))+", "m"),
+ alias: alias,
+ inside: {
+ line: {
+ pattern: /(.)(?=[\s\S]).*(?:\r\n?|\n)?/,
+ lookbehind: true,
+ },
+ prefix: {
+ pattern: /[\s\S]/,
+ alias: /\w+/.exec(name)[0],
+ },
+ },
+ };
+ });
+
+ // make prefixes available to Diff plugin
+ Object.defineProperty(Prism.languages.diff, "PREFIXES", {
+ value: PREFIXES,
+ });
+})(Prism);
+
+(function () {
+ if (
+ typeof Prism === "undefined" ||
+ typeof document === "undefined" ||
+ !document.querySelector
+ ) {
+ return;
+ }
+
+ var LINE_NUMBERS_CLASS = "line-numbers";
+ var LINKABLE_LINE_NUMBERS_CLASS = "linkable-line-numbers";
+ var NEW_LINE_EXP = /\n(?!$)/g;
+
+ /**
+ * @param {string} selector
+ * @param {ParentNode} [container]
+ * @returns {HTMLElement[]}
+ */
+ function $$(selector, container) {
+ return Array.prototype.slice.call(
+ (container || document).querySelectorAll(selector)
+ );
+ }
+
+ /**
+ * Returns whether the given element has the given class.
+ *
+ * @param {Element} element
+ * @param {string} className
+ * @returns {boolean}
+ */
+ function hasClass(element, className) {
+ return element.classList.contains(className);
+ }
+
+ /**
+ * Calls the given function.
+ *
+ * @param {() => any} func
+ * @returns {void}
+ */
+ function callFunction(func) {
+ func();
+ }
+
+ // Some browsers round the line-height, others don't.
+ // We need to test for it to position the elements properly.
+ var isLineHeightRounded = (function () {
+ var res;
+ return function () {
+ if (typeof res === "undefined") {
+ var d = document.createElement("div");
+ d.style.fontSize = "13px";
+ d.style.lineHeight = "1.5";
+ d.style.padding = "0";
+ d.style.border = "0";
+ d.innerHTML = " <br /> ";
+ document.body.appendChild(d);
+ // Browsers that round the line-height should have offsetHeight === 38
+ // The others should have 39.
+ res = d.offsetHeight === 38;
+ document.body.removeChild(d);
+ }
+ return res;
+ };
+ })();
+
+ /**
+ * Returns the top offset of the content box of the given parent and the content box of one of its children.
+ *
+ * @param {HTMLElement} parent
+ * @param {HTMLElement} child
+ */
+ function getContentBoxTopOffset(parent, child) {
+ var parentStyle = getComputedStyle(parent);
+ var childStyle = getComputedStyle(child);
+
+ /**
+ * Returns the numeric value of the given pixel value.
+ *
+ * @param {string} px
+ */
+ function pxToNumber(px) {
+ return +px.substr(0, px.length - 2);
+ }
+
+ return (
+ child.offsetTop +
+ pxToNumber(childStyle.borderTopWidth) +
+ pxToNumber(childStyle.paddingTop) -
+ pxToNumber(parentStyle.paddingTop)
+ );
+ }
+
+ /**
+ * Returns whether the Line Highlight plugin is active for the given element.
+ *
+ * If this function returns `false`, do not call `highlightLines` for the given element.
+ *
+ * @param {HTMLElement | null | undefined} pre
+ * @returns {boolean}
+ */
+ function isActiveFor(pre) {
+ if (!pre || !/pre/i.test(pre.nodeName)) {
+ return false;
+ }
+
+ if (pre.hasAttribute("data-line")) {
+ return true;
+ }
+
+ if (pre.id && Prism.util.isActive(pre, LINKABLE_LINE_NUMBERS_CLASS)) {
+ // Technically, the line numbers plugin is also necessary but this plugin doesn't control the classes of
+ // the line numbers plugin, so we can't assume that they are present.
+ return true;
+ }
+
+ return false;
+ }
+
+ var scrollIntoView = true;
+
+ Prism.plugins.lineHighlight = {
+ /**
+ * Highlights the lines of the given pre.
+ *
+ * This function is split into a DOM measuring and mutate phase to improve performance.
+ * The returned function mutates the DOM when called.
+ *
+ * @param {HTMLElement} pre
+ * @param {string | null} [lines]
+ * @param {string} [classes='']
+ * @returns {() => void}
+ */
+ highlightLines: function highlightLines(pre, lines, classes) {
+ lines =
+ typeof lines === "string" ? lines : pre.getAttribute("data-line") || "";
+
+ var ranges = lines.replace(/\s+/g, "").split(",").filter(Boolean);
+ var offset = +pre.getAttribute("data-line-offset") || 0;
+
+ var parseMethod = isLineHeightRounded() ? parseInt : parseFloat;
+ var lineHeight = parseMethod(getComputedStyle(pre).lineHeight);
+ var hasLineNumbers = Prism.util.isActive(pre, LINE_NUMBERS_CLASS);
+ var codeElement = pre.querySelector("code");
+ var parentElement = hasLineNumbers ? pre : codeElement || pre;
+ var mutateActions = /** @type {(() => void)[]} */ ([]);
+ var lineBreakMatch = codeElement.textContent.match(NEW_LINE_EXP);
+ var numberOfLines = lineBreakMatch ? lineBreakMatch.length + 1 : 1;
+ /**
+ * The top offset between the content box of the <code> element and the content box of the parent element of
+ * the line highlight element (either `<pre>` or `<code>`).
+ *
+ * This offset might not be zero for some themes where the <code> element has a top margin. Some plugins
+ * (or users) might also add element above the <code> element. Because the line highlight is aligned relative
+ * to the <pre> element, we have to take this into account.
+ *
+ * This offset will be 0 if the parent element of the line highlight element is the `<code>` element.
+ */
+ var codePreOffset =
+ !codeElement || parentElement == codeElement
+ ? 0
+ : getContentBoxTopOffset(pre, codeElement);
+
+ ranges.forEach(function (currentRange) {
+ var range = currentRange.split("-");
+
+ var start = +range[0];
+ var end = +range[1] || start;
+ end = Math.min(numberOfLines + offset, end);
+
+ if (end < start) {
+ return;
+ }
+
+ /** @type {HTMLElement} */
+ var line =
+ pre.querySelector(
+ '.line-highlight[data-range="' + currentRange + '"]'
+ ) || document.createElement("div");
+
+ mutateActions.push(function () {
+ line.setAttribute("aria-hidden", "true");
+ line.setAttribute("data-range", currentRange);
+ line.className = (classes || "") + " line-highlight";
+ });
+
+ // if the line-numbers plugin is enabled, then there is no reason for this plugin to display the line numbers
+ if (hasLineNumbers && Prism.plugins.lineNumbers) {
+ var startNode = Prism.plugins.lineNumbers.getLine(pre, start);
+ var endNode = Prism.plugins.lineNumbers.getLine(pre, end);
+
+ if (startNode) {
+ var top = startNode.offsetTop + codePreOffset + "px";
+ mutateActions.push(function () {
+ line.style.top = top;
+ });
+ }
+
+ if (endNode) {
+ var height =
+ endNode.offsetTop -
+ startNode.offsetTop +
+ endNode.offsetHeight +
+ "px";
+ mutateActions.push(function () {
+ line.style.height = height;
+ });
+ }
+ } else {
+ mutateActions.push(function () {
+ line.setAttribute("data-start", String(start));
+
+ if (end > start) {
+ line.setAttribute("data-end", String(end));
+ }
+
+ line.style.top =
+ (start - offset - 1) * lineHeight + codePreOffset + "px";
+
+ line.textContent = new Array(end - start + 2).join(" \n");
+ });
+ }
+
+ mutateActions.push(function () {
+ line.style.width = pre.scrollWidth + "px";
+ });
+
+ mutateActions.push(function () {
+ // allow this to play nicely with the line-numbers plugin
+ // need to attack to pre as when line-numbers is enabled, the code tag is relatively which screws up the positioning
+ parentElement.appendChild(line);
+ });
+ });
+
+ var id = pre.id;
+ if (
+ hasLineNumbers &&
+ Prism.util.isActive(pre, LINKABLE_LINE_NUMBERS_CLASS) &&
+ id
+ ) {
+ // This implements linkable line numbers. Linkable line numbers use Line Highlight to create a link to a
+ // specific line. For this to work, the pre element has to:
+ // 1) have line numbers,
+ // 2) have the `linkable-line-numbers` class or an ascendant that has that class, and
+ // 3) have an id.
+
+ if (!hasClass(pre, LINKABLE_LINE_NUMBERS_CLASS)) {
+ // add class to pre
+ mutateActions.push(function () {
+ pre.classList.add(LINKABLE_LINE_NUMBERS_CLASS);
+ });
+ }
+
+ var start = parseInt(pre.getAttribute("data-start") || "1");
+
+ // iterate all line number spans
+ $$(".line-numbers-rows > span", pre).forEach(function (lineSpan, i) {
+ var lineNumber = i + start;
+ lineSpan.onclick = function () {
+ var hash = id + "." + lineNumber;
+
+ // this will prevent scrolling since the span is obviously in view
+ scrollIntoView = false;
+ location.hash = hash;
+ setTimeout(function () {
+ scrollIntoView = true;
+ }, 1);
+ };
+ });
+ }
+
+ return function () {
+ mutateActions.forEach(callFunction);
+ };
+ },
+ };
+
+ function applyHash() {
+ var hash = location.hash.slice(1);
+
+ // Remove pre-existing temporary lines
+ $$(".temporary.line-highlight").forEach(function (line) {
+ line.parentNode.removeChild(line);
+ });
+
+ var range = (hash.match(/\.([\d,-]+)$/) || [, ""])[1];
+
+ if (!range || document.getElementById(hash)) {
+ return;
+ }
+
+ var id = hash.slice(0, hash.lastIndexOf("."));
+ var pre = document.getElementById(id);
+
+ if (!pre) {
+ return;
+ }
+
+ if (!pre.hasAttribute("data-line")) {
+ pre.setAttribute("data-line", "");
+ }
+
+ var mutateDom = Prism.plugins.lineHighlight.highlightLines(
+ pre,
+ range,
+ "temporary "
+ );
+ mutateDom();
+
+ if (scrollIntoView) {
+ document.querySelector(".temporary.line-highlight").scrollIntoView();
+ }
+ }
+
+ var fakeTimer = 0; // Hack to limit the number of times applyHash() runs
+
+ Prism.hooks.add("before-sanity-check", function (env) {
+ var pre = env.element.parentElement;
+ if (!isActiveFor(pre)) {
+ return;
+ }
+
+ /*
+ * Cleanup for other plugins (e.g. autoloader).
+ *
+ * Sometimes <code> blocks are highlighted multiple times. It is necessary
+ * to cleanup any left-over tags, because the whitespace inside of the <div>
+ * tags change the content of the <code> tag.
+ */
+ var num = 0;
+ $$(".line-highlight", pre).forEach(function (line) {
+ num += line.textContent.length;
+ line.parentNode.removeChild(line);
+ });
+ // Remove extra whitespace
+ if (num && /^(?: \n)+$/.test(env.code.slice(-num))) {
+ env.code = env.code.slice(0, -num);
+ }
+ });
+
+ Prism.hooks.add("complete", function completeHook(env) {
+ var pre = env.element.parentElement;
+ if (!isActiveFor(pre)) {
+ return;
+ }
+
+ clearTimeout(fakeTimer);
+
+ var hasLineNumbers = Prism.plugins.lineNumbers;
+ var isLineNumbersLoaded = env.plugins && env.plugins.lineNumbers;
+
+ if (
+ hasClass(pre, LINE_NUMBERS_CLASS) &&
+ hasLineNumbers &&
+ !isLineNumbersLoaded
+ ) {
+ Prism.hooks.add("line-numbers", completeHook);
+ } else {
+ var mutateDom = Prism.plugins.lineHighlight.highlightLines(pre);
+ mutateDom();
+ fakeTimer = setTimeout(applyHash, 1);
+ }
+ });
+
+ window.addEventListener("hashchange", applyHash);
+ window.addEventListener("resize", function () {
+ var actions = $$("pre")
+ .filter(isActiveFor)
+ .map(function (pre) {
+ return Prism.plugins.lineHighlight.highlightLines(pre);
+ });
+ actions.forEach(callFunction);
+ });
+})();
+
+(function () {
+ if (typeof Prism === "undefined" || typeof document === "undefined") {
+ return;
+ }
+
+ /**
+ * Plugin name which is used as a class name for <pre> which is activating the plugin
+ *
+ * @type {string}
+ */
+ var PLUGIN_NAME = "line-numbers";
+
+ /**
+ * Regular expression used for determining line breaks
+ *
+ * @type {RegExp}
+ */
+ var NEW_LINE_EXP = /\n(?!$)/g;
+
+ /**
+ * Global exports
+ */
+ var config = (Prism.plugins.lineNumbers = {
+ /**
+ * Get node for provided line number
+ *
+ * @param {Element} element pre element
+ * @param {number} number line number
+ * @returns {Element|undefined}
+ */
+ getLine: function (element, number) {
+ if (
+ element.tagName !== "PRE" ||
+ !element.classList.contains(PLUGIN_NAME)
+ ) {
+ return;
+ }
+
+ var lineNumberRows = element.querySelector(".line-numbers-rows");
+ if (!lineNumberRows) {
+ return;
+ }
+ var lineNumberStart =
+ parseInt(element.getAttribute("data-start"), 10) || 1;
+ var lineNumberEnd =
+ lineNumberStart + (lineNumberRows.children.length - 1);
+
+ if (number < lineNumberStart) {
+ number = lineNumberStart;
+ }
+ if (number > lineNumberEnd) {
+ number = lineNumberEnd;
+ }
+
+ var lineIndex = number - lineNumberStart;
+
+ return lineNumberRows.children[lineIndex];
+ },
+
+ /**
+ * Resizes the line numbers of the given element.
+ *
+ * This function will not add line numbers. It will only resize existing ones.
+ *
+ * @param {HTMLElement} element A `<pre>` element with line numbers.
+ * @returns {void}
+ */
+ resize: function (element) {
+ resizeElements([element]);
+ },
+
+ /**
+ * Whether the plugin can assume that the units font sizes and margins are not depended on the size of
+ * the current viewport.
+ *
+ * Setting this to `true` will allow the plugin to do certain optimizations for better performance.
+ *
+ * Set this to `false` if you use any of the following CSS units: `vh`, `vw`, `vmin`, `vmax`.
+ *
+ * @type {boolean}
+ */
+ assumeViewportIndependence: true,
+ });
+
+ /**
+ * Resizes the given elements.
+ *
+ * @param {HTMLElement[]} elements
+ */
+ function resizeElements(elements) {
+ elements = elements.filter(function (e) {
+ var codeStyles = getStyles(e);
+ var whiteSpace = codeStyles["white-space"];
+ return whiteSpace === "pre-wrap" || whiteSpace === "pre-line";
+ });
+
+ if (elements.length == 0) {
+ return;
+ }
+
+ var infos = elements
+ .map(function (element) {
+ var codeElement = element.querySelector("code");
+ var lineNumbersWrapper = element.querySelector(".line-numbers-rows");
+ if (!codeElement || !lineNumbersWrapper) {
+ return undefined;
+ }
+
+ /** @type {HTMLElement} */
+ var lineNumberSizer = element.querySelector(".line-numbers-sizer");
+ var codeLines = codeElement.textContent.split(NEW_LINE_EXP);
+
+ if (!lineNumberSizer) {
+ lineNumberSizer = document.createElement("span");
+ lineNumberSizer.className = "line-numbers-sizer";
+
+ codeElement.appendChild(lineNumberSizer);
+ }
+
+ lineNumberSizer.innerHTML = "0";
+ lineNumberSizer.style.display = "block";
+
+ var oneLinerHeight = lineNumberSizer.getBoundingClientRect().height;
+ lineNumberSizer.innerHTML = "";
+
+ return {
+ element: element,
+ lines: codeLines,
+ lineHeights: [],
+ oneLinerHeight: oneLinerHeight,
+ sizer: lineNumberSizer,
+ };
+ })
+ .filter(Boolean);
+
+ infos.forEach(function (info) {
+ var lineNumberSizer = info.sizer;
+ var lines = info.lines;
+ var lineHeights = info.lineHeights;
+ var oneLinerHeight = info.oneLinerHeight;
+
+ lineHeights[lines.length - 1] = undefined;
+ lines.forEach(function (line, index) {
+ if (line && line.length > 1) {
+ var e = lineNumberSizer.appendChild(document.createElement("span"));
+ e.style.display = "block";
+ e.textContent = line;
+ } else {
+ lineHeights[index] = oneLinerHeight;
+ }
+ });
+ });
+
+ infos.forEach(function (info) {
+ var lineNumberSizer = info.sizer;
+ var lineHeights = info.lineHeights;
+
+ var childIndex = 0;
+ for (var i = 0; i < lineHeights.length; i++) {
+ if (lineHeights[i] === undefined) {
+ lineHeights[i] =
+ lineNumberSizer.children[
+ childIndex++
+ ].getBoundingClientRect().height;
+ }
+ }
+ });
+
+ infos.forEach(function (info) {
+ var lineNumberSizer = info.sizer;
+ var wrapper = info.element.querySelector(".line-numbers-rows");
+
+ lineNumberSizer.style.display = "none";
+ lineNumberSizer.innerHTML = "";
+
+ info.lineHeights.forEach(function (height, lineNumber) {
+ wrapper.children[lineNumber].style.height = height + "px";
+ });
+ });
+ }
+
+ /**
+ * Returns style declarations for the element
+ *
+ * @param {Element} element
+ */
+ function getStyles(element) {
+ if (!element) {
+ return null;
+ }
+
+ return window.getComputedStyle
+ ? getComputedStyle(element)
+ : element.currentStyle || null;
+ }
+
+ var lastWidth = undefined;
+ window.addEventListener("resize", function () {
+ if (config.assumeViewportIndependence && lastWidth === window.innerWidth) {
+ return;
+ }
+ lastWidth = window.innerWidth;
+
+ resizeElements(
+ Array.prototype.slice.call(
+ document.querySelectorAll("pre." + PLUGIN_NAME)
+ )
+ );
+ });
+
+ Prism.hooks.add("complete", function (env) {
+ if (!env.code) {
+ return;
+ }
+
+ var code = /** @type {Element} */ (env.element);
+ var pre = /** @type {HTMLElement} */ (code.parentNode);
+
+ // works only for <code> wrapped inside <pre> (not inline)
+ if (!pre || !/pre/i.test(pre.nodeName)) {
+ return;
+ }
+
+ // Abort if line numbers already exists
+ if (code.querySelector(".line-numbers-rows")) {
+ return;
+ }
+
+ // only add line numbers if <code> or one of its ancestors has the `line-numbers` class
+ if (!Prism.util.isActive(code, PLUGIN_NAME)) {
+ return;
+ }
+
+ // Remove the class 'line-numbers' from the <code>
+ code.classList.remove(PLUGIN_NAME);
+ // Add the class 'line-numbers' to the <pre>
+ pre.classList.add(PLUGIN_NAME);
+
+ var match = env.code.match(NEW_LINE_EXP);
+ var linesNum = match ? match.length + 1 : 1;
+ var lineNumbersWrapper;
+
+ var lines = new Array(linesNum + 1).join("<span></span>");
+
+ lineNumbersWrapper = document.createElement("span");
+ lineNumbersWrapper.setAttribute("aria-hidden", "true");
+ lineNumbersWrapper.className = "line-numbers-rows";
+ lineNumbersWrapper.innerHTML = lines;
+
+ if (pre.hasAttribute("data-start")) {
+ pre.style.counterReset =
+ "linenumber " + (parseInt(pre.getAttribute("data-start"), 10) - 1);
+ }
+
+ env.element.appendChild(lineNumbersWrapper);
+
+ resizeElements([pre]);
+
+ Prism.hooks.run("line-numbers", env);
+ });
+
+ Prism.hooks.add("line-numbers", function (env) {
+ env.plugins = env.plugins || {};
+ env.plugins.lineNumbers = true;
+ });
+})();
+
+(function () {
+ if (typeof Prism === "undefined" || typeof document === "undefined") {
+ return;
+ }
+
+ /* eslint-disable */
+
+ /**
+ * The dependencies map is built automatically with gulp.
+ *
+ * @type {Object<string, string | string[]>}
+ */
+ var lang_dependencies = /*dependencies_placeholder[*/ {
+ javascript: "clike",
+ actionscript: "javascript",
+ apex: ["clike", "sql"],
+ arduino: "cpp",
+ aspnet: ["markup", "csharp"],
+ birb: "clike",
+ bison: "c",
+ c: "clike",
+ csharp: "clike",
+ cpp: "c",
+ cfscript: "clike",
+ chaiscript: ["clike", "cpp"],
+ cilkc: "c",
+ cilkcpp: "cpp",
+ coffeescript: "javascript",
+ crystal: "ruby",
+ "css-extras": "css",
+ d: "clike",
+ dart: "clike",
+ django: "markup-templating",
+ ejs: ["javascript", "markup-templating"],
+ etlua: ["lua", "markup-templating"],
+ erb: ["ruby", "markup-templating"],
+ fsharp: "clike",
+ "firestore-security-rules": "clike",
+ flow: "javascript",
+ ftl: "markup-templating",
+ gml: "clike",
+ glsl: "c",
+ go: "clike",
+ gradle: "clike",
+ groovy: "clike",
+ haml: "ruby",
+ handlebars: "markup-templating",
+ haxe: "clike",
+ hlsl: "c",
+ idris: "haskell",
+ java: "clike",
+ javadoc: ["markup", "java", "javadoclike"],
+ jolie: "clike",
+ jsdoc: ["javascript", "javadoclike", "typescript"],
+ "js-extras": "javascript",
+ json5: "json",
+ jsonp: "json",
+ "js-templates": "javascript",
+ kotlin: "clike",
+ latte: ["clike", "markup-templating", "php"],
+ less: "css",
+ lilypond: "scheme",
+ liquid: "markup-templating",
+ markdown: "markup",
+ "markup-templating": "markup",
+ mongodb: "javascript",
+ n4js: "javascript",
+ objectivec: "c",
+ opencl: "c",
+ parser: "markup",
+ php: "markup-templating",
+ phpdoc: ["php", "javadoclike"],
+ "php-extras": "php",
+ plsql: "sql",
+ processing: "clike",
+ protobuf: "clike",
+ pug: ["markup", "javascript"],
+ purebasic: "clike",
+ purescript: "haskell",
+ qsharp: "clike",
+ qml: "javascript",
+ qore: "clike",
+ racket: "scheme",
+ cshtml: ["markup", "csharp"],
+ jsx: ["markup", "javascript"],
+ tsx: ["jsx", "typescript"],
+ reason: "clike",
+ ruby: "clike",
+ sass: "css",
+ scss: "css",
+ scala: "java",
+ "shell-session": "bash",
+ smarty: "markup-templating",
+ solidity: "clike",
+ soy: "markup-templating",
+ sparql: "turtle",
+ sqf: "clike",
+ squirrel: "clike",
+ stata: ["mata", "java", "python"],
+ "t4-cs": ["t4-templating", "csharp"],
+ "t4-vb": ["t4-templating", "vbnet"],
+ tap: "yaml",
+ tt2: ["clike", "markup-templating"],
+ textile: "markup",
+ twig: "markup-templating",
+ typescript: "javascript",
+ v: "clike",
+ vala: "clike",
+ vbnet: "basic",
+ velocity: "markup",
+ wiki: "markup",
+ xeora: "markup",
+ "xml-doc": "markup",
+ xquery: "markup",
+ }; /*]*/
+
+ var lang_aliases = /*aliases_placeholder[*/ {
+ html: "markup",
+ xml: "markup",
+ svg: "markup",
+ mathml: "markup",
+ ssml: "markup",
+ atom: "markup",
+ rss: "markup",
+ js: "javascript",
+ g4: "antlr4",
+ ino: "arduino",
+ "arm-asm": "armasm",
+ art: "arturo",
+ adoc: "asciidoc",
+ avs: "avisynth",
+ avdl: "avro-idl",
+ gawk: "awk",
+ sh: "bash",
+ shell: "bash",
+ shortcode: "bbcode",
+ rbnf: "bnf",
+ oscript: "bsl",
+ cs: "csharp",
+ dotnet: "csharp",
+ cfc: "cfscript",
+ "cilk-c": "cilkc",
+ "cilk-cpp": "cilkcpp",
+ cilk: "cilkcpp",
+ coffee: "coffeescript",
+ conc: "concurnas",
+ jinja2: "django",
+ "dns-zone": "dns-zone-file",
+ dockerfile: "docker",
+ gv: "dot",
+ eta: "ejs",
+ xlsx: "excel-formula",
+ xls: "excel-formula",
+ gamemakerlanguage: "gml",
+ po: "gettext",
+ gni: "gn",
+ ld: "linker-script",
+ "go-mod": "go-module",
+ hbs: "handlebars",
+ mustache: "handlebars",
+ hs: "haskell",
+ idr: "idris",
+ gitignore: "ignore",
+ hgignore: "ignore",
+ npmignore: "ignore",
+ webmanifest: "json",
+ kt: "kotlin",
+ kts: "kotlin",
+ kum: "kumir",
+ tex: "latex",
+ context: "latex",
+ ly: "lilypond",
+ emacs: "lisp",
+ elisp: "lisp",
+ "emacs-lisp": "lisp",
+ md: "markdown",
+ moon: "moonscript",
+ n4jsd: "n4js",
+ nani: "naniscript",
+ objc: "objectivec",
+ qasm: "openqasm",
+ objectpascal: "pascal",
+ px: "pcaxis",
+ pcode: "peoplecode",
+ plantuml: "plant-uml",
+ pq: "powerquery",
+ mscript: "powerquery",
+ pbfasm: "purebasic",
+ purs: "purescript",
+ py: "python",
+ qs: "qsharp",
+ rkt: "racket",
+ razor: "cshtml",
+ rpy: "renpy",
+ res: "rescript",
+ robot: "robotframework",
+ rb: "ruby",
+ "sh-session": "shell-session",
+ shellsession: "shell-session",
+ smlnj: "sml",
+ sol: "solidity",
+ sln: "solution-file",
+ rq: "sparql",
+ sclang: "supercollider",
+ t4: "t4-cs",
+ trickle: "tremor",
+ troy: "tremor",
+ trig: "turtle",
+ ts: "typescript",
+ tsconfig: "typoscript",
+ uscript: "unrealscript",
+ uc: "unrealscript",
+ url: "uri",
+ vb: "visual-basic",
+ vba: "visual-basic",
+ webidl: "web-idl",
+ mathematica: "wolfram",
+ nb: "wolfram",
+ wl: "wolfram",
+ xeoracube: "xeora",
+ yml: "yaml",
+ }; /*]*/
+
+ /* eslint-enable */
+
+ /**
+ * @typedef LangDataItem
+ * @property {{ success?: () => void, error?: () => void }[]} callbacks
+ * @property {boolean} [error]
+ * @property {boolean} [loading]
+ */
+ /** @type {Object<string, LangDataItem>} */
+ var lang_data = {};
+
+ var ignored_language = "none";
+ var languages_path = "/public/assets/prism/components/";
+
+ var script = Prism.util.currentScript();
+ /*if (script) {
+ var autoloaderFile =
+ /\bplugins\/autoloader\/prism-autoloader\.(?:min\.)?js(?:\?[^\r\n/]*)?$/i;
+ var prismFile = /(^|\/)[\w-]+\.(?:min\.)?js(?:\?[^\r\n/]*)?$/i;
+
+ var autoloaderPath = script.getAttribute("data-autoloader-path");
+ if (autoloaderPath != null) {
+ // data-autoloader-path is set, so just use it
+ languages_path = autoloaderPath.trim().replace(/\/?$/, "/");
+ } else {
+ var src = script.src;
+ if (autoloaderFile.test(src)) {
+ // the script is the original autoloader script in the usual Prism project structure
+ languages_path = src.replace(autoloaderFile, "components/");
+ } else if (prismFile.test(src)) {
+ // the script is part of a bundle like a custom prism.js from the download page
+ languages_path = src.replace(prismFile, "$1components/");
+ }
+ }
+ }*/
+
+ var config = (Prism.plugins.autoloader = {
+ languages_path: languages_path,
+ use_minified: true,
+ loadLanguages: loadLanguages,
+ });
+
+ /**
+ * Lazily loads an external script.
+ *
+ * @param {string} src
+ * @param {() => void} [success]
+ * @param {() => void} [error]
+ */
+ function addScript(src, success, error) {
+ var s = document.createElement("script");
+ s.src = src;
+ s.async = true;
+ s.onload = function () {
+ document.body.removeChild(s);
+ success && success();
+ };
+ s.onerror = function () {
+ document.body.removeChild(s);
+ error && error();
+ };
+ document.body.appendChild(s);
+ }
+
+ /**
+ * Returns all additional dependencies of the given element defined by the `data-dependencies` attribute.
+ *
+ * @param {Element} element
+ * @returns {string[]}
+ */
+ function getDependencies(element) {
+ var deps = (element.getAttribute("data-dependencies") || "").trim();
+ if (!deps) {
+ var parent = element.parentElement;
+ if (parent && parent.tagName.toLowerCase() === "pre") {
+ deps = (parent.getAttribute("data-dependencies") || "").trim();
+ }
+ }
+ return deps ? deps.split(/\s*,\s*/g) : [];
+ }
+
+ /**
+ * Returns whether the given language is currently loaded.
+ *
+ * @param {string} lang
+ * @returns {boolean}
+ */
+ function isLoaded(lang) {
+ if (lang.indexOf("!") >= 0) {
+ // forced reload
+ return false;
+ }
+
+ lang = lang_aliases[lang] || lang; // resolve alias
+
+ if (lang in Prism.languages) {
+ // the given language is already loaded
+ return true;
+ }
+
+ // this will catch extensions like CSS extras that don't add a grammar to Prism.languages
+ var data = lang_data[lang];
+ return data && !data.error && data.loading === false;
+ }
+
+ /**
+ * Returns the path to a grammar, using the language_path and use_minified config keys.
+ *
+ * @param {string} lang
+ * @returns {string}
+ */
+ function getLanguagePath(lang) {
+ return (
+ config.languages_path +
+ "prism-" +
+ lang +
+ (config.use_minified ? ".min" : "") +
+ ".js"
+ );
+ }
+
+ /**
+ * Loads all given grammars concurrently.
+ *
+ * @param {string[]|string} languages
+ * @param {(languages: string[]) => void} [success]
+ * @param {(language: string) => void} [error] This callback will be invoked on the first language to fail.
+ */
+ function loadLanguages(languages, success, error) {
+ if (typeof languages === "string") {
+ languages = [languages];
+ }
+
+ var total = languages.length;
+ var completed = 0;
+ var failed = false;
+
+ if (total === 0) {
+ if (success) {
+ setTimeout(success, 0);
+ }
+ return;
+ }
+
+ function successCallback() {
+ if (failed) {
+ return;
+ }
+ completed++;
+ if (completed === total) {
+ success && success(languages);
+ }
+ }
+
+ languages.forEach(function (lang) {
+ loadLanguage(lang, successCallback, function () {
+ if (failed) {
+ return;
+ }
+ failed = true;
+ error && error(lang);
+ });
+ });
+ }
+
+ /**
+ * Loads a grammar with its dependencies.
+ *
+ * @param {string} lang
+ * @param {() => void} [success]
+ * @param {() => void} [error]
+ */
+ function loadLanguage(lang, success, error) {
+ var force = lang.indexOf("!") >= 0;
+
+ lang = lang.replace("!", "");
+ lang = lang_aliases[lang] || lang;
+
+ function load() {
+ var data = lang_data[lang];
+ if (!data) {
+ data = lang_data[lang] = {
+ callbacks: [],
+ };
+ }
+ data.callbacks.push({
+ success: success,
+ error: error,
+ });
+
+ if (!force && isLoaded(lang)) {
+ // the language is already loaded and we aren't forced to reload
+ languageCallback(lang, "success");
+ } else if (!force && data.error) {
+ // the language failed to load before and we don't reload
+ languageCallback(lang, "error");
+ } else if (force || !data.loading) {
+ // the language isn't currently loading and/or we are forced to reload
+ data.loading = true;
+ data.error = false;
+
+ addScript(
+ getLanguagePath(lang),
+ function () {
+ data.loading = false;
+ languageCallback(lang, "success");
+ },
+ function () {
+ data.loading = false;
+ data.error = true;
+ languageCallback(lang, "error");
+ }
+ );
+ }
+ }
+
+ var dependencies = lang_dependencies[lang];
+ if (dependencies && dependencies.length) {
+ loadLanguages(dependencies, load, error);
+ } else {
+ load();
+ }
+ }
+
+ /**
+ * Runs all callbacks of the given type for the given language.
+ *
+ * @param {string} lang
+ * @param {"success" | "error"} type
+ */
+ function languageCallback(lang, type) {
+ if (lang_data[lang]) {
+ var callbacks = lang_data[lang].callbacks;
+ for (var i = 0, l = callbacks.length; i < l; i++) {
+ var callback = callbacks[i][type];
+ if (callback) {
+ setTimeout(callback, 0);
+ }
+ }
+ callbacks.length = 0;
+ }
+ }
+
+ Prism.hooks.add("complete", function (env) {
+ var element = env.element;
+ var language = env.language;
+ if (!element || !language || language === ignored_language) {
+ return;
+ }
+
+ var deps = getDependencies(element);
+ if (/^diff-./i.test(language)) {
+ // the "diff-xxxx" format is used by the Diff Highlight plugin
+ deps.push("diff");
+ deps.push(language.substr("diff-".length));
+ } else {
+ deps.push(language);
+ }
+
+ if (!deps.every(isLoaded)) {
+ // the language or some dependencies aren't loaded
+ loadLanguages(deps, function () {
+ Prism.highlightElement(element);
+ });
+ }
+ });
+})();
+
+(function () {
+ if (typeof Prism === "undefined") {
+ return;
+ }
+
+ var assign =
+ Object.assign ||
+ function (obj1, obj2) {
+ for (var name in obj2) {
+ if (obj2.hasOwnProperty(name)) {
+ obj1[name] = obj2[name];
+ }
+ }
+ return obj1;
+ };
+
+ function NormalizeWhitespace(defaults) {
+ this.defaults = assign({}, defaults);
+ }
+
+ function toCamelCase(value) {
+ return value.replace(/-(\w)/g, function (match, firstChar) {
+ return firstChar.toUpperCase();
+ });
+ }
+
+ function tabLen(str) {
+ var res = 0;
+ for (var i = 0; i < str.length; ++i) {
+ if (str.charCodeAt(i) == "\t".charCodeAt(0)) {
+ res += 3;
+ }
+ }
+ return str.length + res;
+ }
+
+ var settingsConfig = {
+ "remove-trailing": "boolean",
+ "remove-indent": "boolean",
+ "left-trim": "boolean",
+ "right-trim": "boolean",
+ "break-lines": "number",
+ indent: "number",
+ "remove-initial-line-feed": "boolean",
+ "tabs-to-spaces": "number",
+ "spaces-to-tabs": "number",
+ };
+
+ NormalizeWhitespace.prototype = {
+ setDefaults: function (defaults) {
+ this.defaults = assign(this.defaults, defaults);
+ },
+ normalize: function (input, settings) {
+ settings = assign(this.defaults, settings);
+
+ for (var name in settings) {
+ var methodName = toCamelCase(name);
+ if (
+ name !== "normalize" &&
+ methodName !== "setDefaults" &&
+ settings[name] &&
+ this[methodName]
+ ) {
+ input = this[methodName].call(this, input, settings[name]);
+ }
+ }
+
+ return input;
+ },
+
+ /*
+ * Normalization methods
+ */
+ leftTrim: function (input) {
+ return input.replace(/^\s+/, "");
+ },
+ rightTrim: function (input) {
+ return input.replace(/\s+$/, "");
+ },
+ tabsToSpaces: function (input, spaces) {
+ spaces = spaces | 0 || 4;
+ return input.replace(/\t/g, new Array(++spaces).join(" "));
+ },
+ spacesToTabs: function (input, spaces) {
+ spaces = spaces | 0 || 4;
+ return input.replace(RegExp(" {" + spaces + "}", "g"), "\t");
+ },
+ removeTrailing: function (input) {
+ return input.replace(/\s*?$/gm, "");
+ },
+ // Support for deprecated plugin remove-initial-line-feed
+ removeInitialLineFeed: function (input) {
+ return input.replace(/^(?:\r?\n|\r)/, "");
+ },
+ removeIndent: function (input) {
+ var indents = input.match(/^[^\S\n\r]*(?=\S)/gm);
+
+ if (!indents || !indents[0].length) {
+ return input;
+ }
+
+ indents.sort(function (a, b) {
+ return a.length - b.length;
+ });
+
+ if (!indents[0].length) {
+ return input;
+ }
+
+ return input.replace(RegExp("^" + indents[0], "gm"), "");
+ },
+ indent: function (input, tabs) {
+ return input.replace(
+ /^[^\S\n\r]*(?=\S)/gm,
+ new Array(++tabs).join("\t") + "$&"
+ );
+ },
+ breakLines: function (input, characters) {
+ characters = characters === true ? 80 : characters | 0 || 80;
+
+ var lines = input.split("\n");
+ for (var i = 0; i < lines.length; ++i) {
+ if (tabLen(lines[i]) <= characters) {
+ continue;
+ }
+
+ var line = lines[i].split(/(\s+)/g);
+ var len = 0;
+
+ for (var j = 0; j < line.length; ++j) {
+ var tl = tabLen(line[j]);
+ len += tl;
+ if (len > characters) {
+ line[j] = "\n" + line[j];
+ len = tl;
+ }
+ }
+ lines[i] = line.join("");
+ }
+ return lines.join("\n");
+ },
+ };
+
+ // Support node modules
+ if (typeof module !== "undefined" && module.exports) {
+ module.exports = NormalizeWhitespace;
+ }
+
+ Prism.plugins.NormalizeWhitespace = new NormalizeWhitespace({
+ "remove-trailing": true,
+ "remove-indent": true,
+ "left-trim": true,
+ "right-trim": true,
+ /*'break-lines': 80,
+ 'indent': 2,
+ 'remove-initial-line-feed': false,
+ 'tabs-to-spaces': 4,
+ 'spaces-to-tabs': 4*/
+ });
+
+ Prism.hooks.add("before-sanity-check", function (env) {
+ var Normalizer = Prism.plugins.NormalizeWhitespace;
+
+ // Check settings
+ if (env.settings && env.settings["whitespace-normalization"] === false) {
+ return;
+ }
+
+ // Check classes
+ if (!Prism.util.isActive(env.element, "whitespace-normalization", true)) {
+ return;
+ }
+
+ // Simple mode if there is no env.element
+ if ((!env.element || !env.element.parentNode) && env.code) {
+ env.code = Normalizer.normalize(env.code, env.settings);
+ return;
+ }
+
+ // Normal mode
+ var pre = env.element.parentNode;
+ if (!env.code || !pre || pre.nodeName.toLowerCase() !== "pre") {
+ return;
+ }
+
+ if (env.settings == null) {
+ env.settings = {};
+ }
+
+ // Read settings from 'data-' attributes
+ for (var key in settingsConfig) {
+ if (Object.hasOwnProperty.call(settingsConfig, key)) {
+ var settingType = settingsConfig[key];
+ if (pre.hasAttribute("data-" + key)) {
+ try {
+ var value = JSON.parse(pre.getAttribute("data-" + key) || "true");
+ if (typeof value === settingType) {
+ env.settings[key] = value;
+ }
+ } catch (_error) {
+ // ignore error
+ }
+ }
+ }
+ }
+
+ var children = pre.childNodes;
+ var before = "";
+ var after = "";
+ var codeFound = false;
+
+ // Move surrounding whitespace from the <pre> tag into the <code> tag
+ for (var i = 0; i < children.length; ++i) {
+ var node = children[i];
+
+ if (node == env.element) {
+ codeFound = true;
+ } else if (node.nodeName === "#text") {
+ if (codeFound) {
+ after += node.nodeValue;
+ } else {
+ before += node.nodeValue;
+ }
+
+ pre.removeChild(node);
+ --i;
+ }
+ }
+
+ if (!env.element.children.length || !Prism.plugins.KeepMarkup) {
+ env.code = before + env.code + after;
+ env.code = Normalizer.normalize(env.code, env.settings);
+ } else {
+ // Preserve markup for keep-markup plugin
+ var html = before + env.element.innerHTML + after;
+ env.element.innerHTML = Normalizer.normalize(html, env.settings);
+ env.code = env.element.textContent;
+ }
+ });
+})();
+
+(function () {
+ if (typeof Prism === "undefined") {
+ return;
+ }
+
+ var LANGUAGE_REGEX = /^diff-([\w-]+)/i;
+ var HTML_TAG =
+ /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/g;
+ //this will match a line plus the line break while ignoring the line breaks HTML tags may contain.
+ var HTML_LINE = RegExp(
+ /(?:__|[^\r\n<])*(?:\r\n?|\n|(?:__|[^\r\n<])(?![^\r\n]))/.source.replace(
+ /__/g,
+ function () {
+ return HTML_TAG.source;
+ }
+ ),
+ "gi"
+ );
+
+ var warningLogged = false;
+
+ Prism.hooks.add("before-sanity-check", function (env) {
+ var lang = env.language;
+ if (LANGUAGE_REGEX.test(lang) && !env.grammar) {
+ env.grammar = Prism.languages[lang] = Prism.languages.diff;
+ }
+ });
+ Prism.hooks.add("before-tokenize", function (env) {
+ if (!warningLogged && !Prism.languages.diff && !Prism.plugins.autoloader) {
+ warningLogged = true;
+ console.warn(
+ "Prism's Diff Highlight plugin requires the Diff language definition (prism-diff.js)." +
+ "Make sure the language definition is loaded or use Prism's Autoloader plugin."
+ );
+ }
+
+ var lang = env.language;
+ if (LANGUAGE_REGEX.test(lang) && !Prism.languages[lang]) {
+ Prism.languages[lang] = Prism.languages.diff;
+ }
+ });
+
+ Prism.hooks.add("wrap", function (env) {
+ var diffLanguage;
+ var diffGrammar;
+
+ if (env.language !== "diff") {
+ var langMatch = LANGUAGE_REGEX.exec(env.language);
+ if (!langMatch) {
+ return; // not a language specific diff
+ }
+
+ diffLanguage = langMatch[1];
+ diffGrammar = Prism.languages[diffLanguage];
+ }
+
+ var PREFIXES = Prism.languages.diff && Prism.languages.diff.PREFIXES;
+
+ // one of the diff tokens without any nested tokens
+ if (PREFIXES && env.type in PREFIXES) {
+ /** @type {string} */
+ var content = env.content.replace(HTML_TAG, ""); // remove all HTML tags
+
+ /** @type {string} */
+ var decoded = content.replace(/</g, "<").replace(/&/g, "&");
+
+ // remove any one-character prefix
+ var code = decoded.replace(/(^|[\r\n])./g, "$1");
+
+ // highlight, if possible
+ var highlighted;
+ if (diffGrammar) {
+ highlighted = Prism.highlight(code, diffGrammar, diffLanguage);
+ } else {
+ highlighted = Prism.util.encode(code);
+ }
+
+ // get the HTML source of the prefix token
+ var prefixToken = new Prism.Token("prefix", PREFIXES[env.type], [
+ /\w+/.exec(env.type)[0],
+ ]);
+ var prefix = Prism.Token.stringify(prefixToken, env.language);
+
+ // add prefix
+ var lines = [];
+ var m;
+ HTML_LINE.lastIndex = 0;
+ while ((m = HTML_LINE.exec(highlighted))) {
+ lines.push(prefix + m[0]);
+ }
+ if (/(?:^|[\r\n]).$/.test(decoded)) {
+ // because both "+a\n+" and "+a\n" will map to "a\n" after the line prefixes are removed
+ lines.push(prefix);
+ }
+ env.content = lines.join("");
+
+ if (diffGrammar) {
+ env.classes.push("language-" + diffLanguage);
+ }
+ }
+ });
+})();
@@ -1,3373 +0,0 @@
-/* PrismJS 1.29.0
-https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+diff&plugins=line-highlight+line-numbers+autoloader+normalize-whitespace+diff-highlight */
-/// <reference lib="WebWorker"/>
-
-var _self =
- typeof window !== "undefined"
- ? window // if in browser
- : typeof WorkerGlobalScope !== "undefined" &&
- self instanceof WorkerGlobalScope
- ? self // if in worker
- : {}; // if in node js
-
-/**
- * Prism: Lightweight, robust, elegant syntax highlighting
- *
- * @license MIT <https://opensource.org/licenses/MIT>
- * @author Lea Verou <https://lea.verou.me>
- * @namespace
- * @public
- */
-var Prism = (function (_self) {
- // Private helper vars
- var lang = /(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i;
- var uniqueId = 0;
-
- // The grammar object for plaintext
- var plainTextGrammar = {};
-
- var _ = {
- /**
- * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the
- * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load
- * additional languages or plugins yourself.
- *
- * By setting this value to `true`, Prism will not automatically highlight all code elements on the page.
- *
- * You obviously have to change this value before the automatic highlighting started. To do this, you can add an
- * empty Prism object into the global scope before loading the Prism script like this:
- *
- * ```js
- * window.Prism = window.Prism || {};
- * Prism.manual = true;
- * // add a new <script> to load Prism's script
- * ```
- *
- * @default false
- * @type {boolean}
- * @memberof Prism
- * @public
- */
- manual: _self.Prism && _self.Prism.manual,
- /**
- * By default, if Prism is in a web worker, it assumes that it is in a worker it created itself, so it uses
- * `addEventListener` to communicate with its parent instance. However, if you're using Prism manually in your
- * own worker, you don't want it to do this.
- *
- * By setting this value to `true`, Prism will not add its own listeners to the worker.
- *
- * You obviously have to change this value before Prism executes. To do this, you can add an
- * empty Prism object into the global scope before loading the Prism script like this:
- *
- * ```js
- * window.Prism = window.Prism || {};
- * Prism.disableWorkerMessageHandler = true;
- * // Load Prism's script
- * ```
- *
- * @default false
- * @type {boolean}
- * @memberof Prism
- * @public
- */
- disableWorkerMessageHandler:
- _self.Prism && _self.Prism.disableWorkerMessageHandler,
-
- /**
- * A namespace for utility methods.
- *
- * All function in this namespace that are not explicitly marked as _public_ are for __internal use only__ and may
- * change or disappear at any time.
- *
- * @namespace
- * @memberof Prism
- */
- util: {
- encode: function encode(tokens) {
- if (tokens instanceof Token) {
- return new Token(tokens.type, encode(tokens.content), tokens.alias);
- } else if (Array.isArray(tokens)) {
- return tokens.map(encode);
- } else {
- return tokens
- .replace(/&/g, "&")
- .replace(/</g, "<")
- .replace(/\u00a0/g, " ");
- }
- },
-
- /**
- * Returns the name of the type of the given value.
- *
- * @param {any} o
- * @returns {string}
- * @example
- * type(null) === 'Null'
- * type(undefined) === 'Undefined'
- * type(123) === 'Number'
- * type('foo') === 'String'
- * type(true) === 'Boolean'
- * type([1, 2]) === 'Array'
- * type({}) === 'Object'
- * type(String) === 'Function'
- * type(/abc+/) === 'RegExp'
- */
- type: function (o) {
- return Object.prototype.toString.call(o).slice(8, -1);
- },
-
- /**
- * Returns a unique number for the given object. Later calls will still return the same number.
- *
- * @param {Object} obj
- * @returns {number}
- */
- objId: function (obj) {
- if (!obj["__id"]) {
- Object.defineProperty(obj, "__id", { value: ++uniqueId });
- }
- return obj["__id"];
- },
-
- /**
- * Creates a deep clone of the given object.
- *
- * The main intended use of this function is to clone language definitions.
- *
- * @param {T} o
- * @param {Record<number, any>} [visited]
- * @returns {T}
- * @template T
- */
- clone: function deepClone(o, visited) {
- visited = visited || {};
-
- var clone;
- var id;
- switch (_.util.type(o)) {
- case "Object":
- id = _.util.objId(o);
- if (visited[id]) {
- return visited[id];
- }
- clone = /** @type {Record<string, any>} */ ({});
- visited[id] = clone;
-
- for (var key in o) {
- if (o.hasOwnProperty(key)) {
- clone[key] = deepClone(o[key], visited);
- }
- }
-
- return /** @type {any} */ (clone);
-
- case "Array":
- id = _.util.objId(o);
- if (visited[id]) {
- return visited[id];
- }
- clone = [];
- visited[id] = clone;
-
- /** @type {Array} */ (/** @type {any} */ (o)).forEach(function (
- v,
- i
- ) {
- clone[i] = deepClone(v, visited);
- });
-
- return /** @type {any} */ (clone);
-
- default:
- return o;
- }
- },
-
- /**
- * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class.
- *
- * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned.
- *
- * @param {Element} element
- * @returns {string}
- */
- getLanguage: function (element) {
- while (element) {
- var m = lang.exec(element.className);
- if (m) {
- return m[1].toLowerCase();
- }
- element = element.parentElement;
- }
- return "none";
- },
-
- /**
- * Sets the Prism `language-xxxx` class of the given element.
- *
- * @param {Element} element
- * @param {string} language
- * @returns {void}
- */
- setLanguage: function (element, language) {
- // remove all `language-xxxx` classes
- // (this might leave behind a leading space)
- element.className = element.className.replace(RegExp(lang, "gi"), "");
-
- // add the new `language-xxxx` class
- // (using `classList` will automatically clean up spaces for us)
- element.classList.add("language-" + language);
- },
-
- /**
- * Returns the script element that is currently executing.
- *
- * This does __not__ work for line script element.
- *
- * @returns {HTMLScriptElement | null}
- */
- currentScript: function () {
- if (typeof document === "undefined") {
- return null;
- }
- if (
- "currentScript" in document &&
- 1 < 2 /* hack to trip TS' flow analysis */
- ) {
- return /** @type {any} */ (document.currentScript);
- }
-
- // IE11 workaround
- // we'll get the src of the current script by parsing IE11's error stack trace
- // this will not work for inline scripts
-
- try {
- throw new Error();
- } catch (err) {
- // Get file src url from stack. Specifically works with the format of stack traces in IE.
- // A stack will look like this:
- //
- // Error
- // at _.util.currentScript (http://localhost/components/prism-core.js:119:5)
- // at Global code (http://localhost/components/prism-core.js:606:1)
-
- var src = (/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(err.stack) ||
- [])[1];
- if (src) {
- var scripts = document.getElementsByTagName("script");
- for (var i in scripts) {
- if (scripts[i].src == src) {
- return scripts[i];
- }
- }
- }
- return null;
- }
- },
-
- /**
- * Returns whether a given class is active for `element`.
- *
- * The class can be activated if `element` or one of its ancestors has the given class and it can be deactivated
- * if `element` or one of its ancestors has the negated version of the given class. The _negated version_ of the
- * given class is just the given class with a `no-` prefix.
- *
- * Whether the class is active is determined by the closest ancestor of `element` (where `element` itself is
- * closest ancestor) that has the given class or the negated version of it. If neither `element` nor any of its
- * ancestors have the given class or the negated version of it, then the default activation will be returned.
- *
- * In the paradoxical situation where the closest ancestor contains __both__ the given class and the negated
- * version of it, the class is considered active.
- *
- * @param {Element} element
- * @param {string} className
- * @param {boolean} [defaultActivation=false]
- * @returns {boolean}
- */
- isActive: function (element, className, defaultActivation) {
- var no = "no-" + className;
-
- while (element) {
- var classList = element.classList;
- if (classList.contains(className)) {
- return true;
- }
- if (classList.contains(no)) {
- return false;
- }
- element = element.parentElement;
- }
- return !!defaultActivation;
- },
- },
-
- /**
- * This namespace contains all currently loaded languages and the some helper functions to create and modify languages.
- *
- * @namespace
- * @memberof Prism
- * @public
- */
- languages: {
- /**
- * The grammar for plain, unformatted text.
- */
- plain: plainTextGrammar,
- plaintext: plainTextGrammar,
- text: plainTextGrammar,
- txt: plainTextGrammar,
-
- /**
- * Creates a deep copy of the language with the given id and appends the given tokens.
- *
- * If a token in `redef` also appears in the copied language, then the existing token in the copied language
- * will be overwritten at its original position.
- *
- * ## Best practices
- *
- * Since the position of overwriting tokens (token in `redef` that overwrite tokens in the copied language)
- * doesn't matter, they can technically be in any order. However, this can be confusing to others that trying to
- * understand the language definition because, normally, the order of tokens matters in Prism grammars.
- *
- * Therefore, it is encouraged to order overwriting tokens according to the positions of the overwritten tokens.
- * Furthermore, all non-overwriting tokens should be placed after the overwriting ones.
- *
- * @param {string} id The id of the language to extend. This has to be a key in `Prism.languages`.
- * @param {Grammar} redef The new tokens to append.
- * @returns {Grammar} The new language created.
- * @public
- * @example
- * Prism.languages['css-with-colors'] = Prism.languages.extend('css', {
- * // Prism.languages.css already has a 'comment' token, so this token will overwrite CSS' 'comment' token
- * // at its original position
- * 'comment': { ... },
- * // CSS doesn't have a 'color' token, so this token will be appended
- * 'color': /\b(?:red|green|blue)\b/
- * });
- */
- extend: function (id, redef) {
- var lang = _.util.clone(_.languages[id]);
-
- for (var key in redef) {
- lang[key] = redef[key];
- }
-
- return lang;
- },
-
- /**
- * Inserts tokens _before_ another token in a language definition or any other grammar.
- *
- * ## Usage
- *
- * This helper method makes it easy to modify existing languages. For example, the CSS language definition
- * not only defines CSS highlighting for CSS documents, but also needs to define highlighting for CSS embedded
- * in HTML through `<style>` elements. To do this, it needs to modify `Prism.languages.markup` and add the
- * appropriate tokens. However, `Prism.languages.markup` is a regular JavaScript object literal, so if you do
- * this:
- *
- * ```js
- * Prism.languages.markup.style = {
- * // token
- * };
- * ```
- *
- * then the `style` token will be added (and processed) at the end. `insertBefore` allows you to insert tokens
- * before existing tokens. For the CSS example above, you would use it like this:
- *
- * ```js
- * Prism.languages.insertBefore('markup', 'cdata', {
- * 'style': {
- * // token
- * }
- * });
- * ```
- *
- * ## Special cases
- *
- * If the grammars of `inside` and `insert` have tokens with the same name, the tokens in `inside`'s grammar
- * will be ignored.
- *
- * This behavior can be used to insert tokens after `before`:
- *
- * ```js
- * Prism.languages.insertBefore('markup', 'comment', {
- * 'comment': Prism.languages.markup.comment,
- * // tokens after 'comment'
- * });
- * ```
- *
- * ## Limitations
- *
- * The main problem `insertBefore` has to solve is iteration order. Since ES2015, the iteration order for object
- * properties is guaranteed to be the insertion order (except for integer keys) but some browsers behave
- * differently when keys are deleted and re-inserted. So `insertBefore` can't be implemented by temporarily
- * deleting properties which is necessary to insert at arbitrary positions.
- *
- * To solve this problem, `insertBefore` doesn't actually insert the given tokens into the target object.
- * Instead, it will create a new object and replace all references to the target object with the new one. This
- * can be done without temporarily deleting properties, so the iteration order is well-defined.
- *
- * However, only references that can be reached from `Prism.languages` or `insert` will be replaced. I.e. if
- * you hold the target object in a variable, then the value of the variable will not change.
- *
- * ```js
- * var oldMarkup = Prism.languages.markup;
- * var newMarkup = Prism.languages.insertBefore('markup', 'comment', { ... });
- *
- * assert(oldMarkup !== Prism.languages.markup);
- * assert(newMarkup === Prism.languages.markup);
- * ```
- *
- * @param {string} inside The property of `root` (e.g. a language id in `Prism.languages`) that contains the
- * object to be modified.
- * @param {string} before The key to insert before.
- * @param {Grammar} insert An object containing the key-value pairs to be inserted.
- * @param {Object<string, any>} [root] The object containing `inside`, i.e. the object that contains the
- * object to be modified.
- *
- * Defaults to `Prism.languages`.
- * @returns {Grammar} The new grammar object.
- * @public
- */
- insertBefore: function (inside, before, insert, root) {
- root = root || /** @type {any} */ (_.languages);
- var grammar = root[inside];
- /** @type {Grammar} */
- var ret = {};
-
- for (var token in grammar) {
- if (grammar.hasOwnProperty(token)) {
- if (token == before) {
- for (var newToken in insert) {
- if (insert.hasOwnProperty(newToken)) {
- ret[newToken] = insert[newToken];
- }
- }
- }
-
- // Do not insert token which also occur in insert. See #1525
- if (!insert.hasOwnProperty(token)) {
- ret[token] = grammar[token];
- }
- }
- }
-
- var old = root[inside];
- root[inside] = ret;
-
- // Update references in other language definitions
- _.languages.DFS(_.languages, function (key, value) {
- if (value === old && key != inside) {
- this[key] = ret;
- }
- });
-
- return ret;
- },
-
- // Traverse a language definition with Depth First Search
- DFS: function DFS(o, callback, type, visited) {
- visited = visited || {};
-
- var objId = _.util.objId;
-
- for (var i in o) {
- if (o.hasOwnProperty(i)) {
- callback.call(o, i, o[i], type || i);
-
- var property = o[i];
- var propertyType = _.util.type(property);
-
- if (propertyType === "Object" && !visited[objId(property)]) {
- visited[objId(property)] = true;
- DFS(property, callback, null, visited);
- } else if (propertyType === "Array" && !visited[objId(property)]) {
- visited[objId(property)] = true;
- DFS(property, callback, i, visited);
- }
- }
- }
- },
- },
-
- plugins: {},
-
- /**
- * This is the most high-level function in Prism’s API.
- * It fetches all the elements that have a `.language-xxxx` class and then calls {@link Prism.highlightElement} on
- * each one of them.
- *
- * This is equivalent to `Prism.highlightAllUnder(document, async, callback)`.
- *
- * @param {boolean} [async=false] Same as in {@link Prism.highlightAllUnder}.
- * @param {HighlightCallback} [callback] Same as in {@link Prism.highlightAllUnder}.
- * @memberof Prism
- * @public
- */
- highlightAll: function (async, callback) {
- _.highlightAllUnder(document, async, callback);
- },
-
- /**
- * Fetches all the descendants of `container` that have a `.language-xxxx` class and then calls
- * {@link Prism.highlightElement} on each one of them.
- *
- * The following hooks will be run:
- * 1. `before-highlightall`
- * 2. `before-all-elements-highlight`
- * 3. All hooks of {@link Prism.highlightElement} for each element.
- *
- * @param {ParentNode} container The root element, whose descendants that have a `.language-xxxx` class will be highlighted.
- * @param {boolean} [async=false] Whether each element is to be highlighted asynchronously using Web Workers.
- * @param {HighlightCallback} [callback] An optional callback to be invoked on each element after its highlighting is done.
- * @memberof Prism
- * @public
- */
- highlightAllUnder: function (container, async, callback) {
- var env = {
- callback: callback,
- container: container,
- selector:
- 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code',
- };
-
- _.hooks.run("before-highlightall", env);
-
- env.elements = Array.prototype.slice.apply(
- env.container.querySelectorAll(env.selector)
- );
-
- _.hooks.run("before-all-elements-highlight", env);
-
- for (var i = 0, element; (element = env.elements[i++]); ) {
- _.highlightElement(element, async === true, env.callback);
- }
- },
-
- /**
- * Highlights the code inside a single element.
- *
- * The following hooks will be run:
- * 1. `before-sanity-check`
- * 2. `before-highlight`
- * 3. All hooks of {@link Prism.highlight}. These hooks will be run by an asynchronous worker if `async` is `true`.
- * 4. `before-insert`
- * 5. `after-highlight`
- * 6. `complete`
- *
- * Some the above hooks will be skipped if the element doesn't contain any text or there is no grammar loaded for
- * the element's language.
- *
- * @param {Element} element The element containing the code.
- * It must have a class of `language-xxxx` to be processed, where `xxxx` is a valid language identifier.
- * @param {boolean} [async=false] Whether the element is to be highlighted asynchronously using Web Workers
- * to improve performance and avoid blocking the UI when highlighting very large chunks of code. This option is
- * [disabled by default](https://prismjs.com/faq.html#why-is-asynchronous-highlighting-disabled-by-default).
- *
- * Note: All language definitions required to highlight the code must be included in the main `prism.js` file for
- * asynchronous highlighting to work. You can build your own bundle on the
- * [Download page](https://prismjs.com/download.html).
- * @param {HighlightCallback} [callback] An optional callback to be invoked after the highlighting is done.
- * Mostly useful when `async` is `true`, since in that case, the highlighting is done asynchronously.
- * @memberof Prism
- * @public
- */
- highlightElement: function (element, async, callback) {
- // Find language
- var language = _.util.getLanguage(element);
- var grammar = _.languages[language];
-
- // Set language on the element, if not present
- _.util.setLanguage(element, language);
-
- // Set language on the parent, for styling
- var parent = element.parentElement;
- if (parent && parent.nodeName.toLowerCase() === "pre") {
- _.util.setLanguage(parent, language);
- }
-
- var code = element.textContent;
-
- var env = {
- element: element,
- language: language,
- grammar: grammar,
- code: code,
- };
-
- function insertHighlightedCode(highlightedCode) {
- env.highlightedCode = highlightedCode;
-
- _.hooks.run("before-insert", env);
-
- env.element.innerHTML = env.highlightedCode;
-
- _.hooks.run("after-highlight", env);
- _.hooks.run("complete", env);
- callback && callback.call(env.element);
- }
-
- _.hooks.run("before-sanity-check", env);
-
- // plugins may change/add the parent/element
- parent = env.element.parentElement;
- if (
- parent &&
- parent.nodeName.toLowerCase() === "pre" &&
- !parent.hasAttribute("tabindex")
- ) {
- parent.setAttribute("tabindex", "0");
- }
-
- if (!env.code) {
- _.hooks.run("complete", env);
- callback && callback.call(env.element);
- return;
- }
-
- _.hooks.run("before-highlight", env);
-
- if (!env.grammar) {
- insertHighlightedCode(_.util.encode(env.code));
- return;
- }
-
- if (async && _self.Worker) {
- var worker = new Worker(_.filename);
-
- worker.onmessage = function (evt) {
- insertHighlightedCode(evt.data);
- };
-
- worker.postMessage(
- JSON.stringify({
- language: env.language,
- code: env.code,
- immediateClose: true,
- })
- );
- } else {
- insertHighlightedCode(_.highlight(env.code, env.grammar, env.language));
- }
- },
-
- /**
- * Low-level function, only use if you know what you’re doing. It accepts a string of text as input
- * and the language definitions to use, and returns a string with the HTML produced.
- *
- * The following hooks will be run:
- * 1. `before-tokenize`
- * 2. `after-tokenize`
- * 3. `wrap`: On each {@link Token}.
- *
- * @param {string} text A string with the code to be highlighted.
- * @param {Grammar} grammar An object containing the tokens to use.
- *
- * Usually a language definition like `Prism.languages.markup`.
- * @param {string} language The name of the language definition passed to `grammar`.
- * @returns {string} The highlighted HTML.
- * @memberof Prism
- * @public
- * @example
- * Prism.highlight('var foo = true;', Prism.languages.javascript, 'javascript');
- */
- highlight: function (text, grammar, language) {
- var env = {
- code: text,
- grammar: grammar,
- language: language,
- };
- _.hooks.run("before-tokenize", env);
- if (!env.grammar) {
- throw new Error('The language "' + env.language + '" has no grammar.');
- }
- env.tokens = _.tokenize(env.code, env.grammar);
- _.hooks.run("after-tokenize", env);
- return Token.stringify(_.util.encode(env.tokens), env.language);
- },
-
- /**
- * This is the heart of Prism, and the most low-level function you can use. It accepts a string of text as input
- * and the language definitions to use, and returns an array with the tokenized code.
- *
- * When the language definition includes nested tokens, the function is called recursively on each of these tokens.
- *
- * This method could be useful in other contexts as well, as a very crude parser.
- *
- * @param {string} text A string with the code to be highlighted.
- * @param {Grammar} grammar An object containing the tokens to use.
- *
- * Usually a language definition like `Prism.languages.markup`.
- * @returns {TokenStream} An array of strings and tokens, a token stream.
- * @memberof Prism
- * @public
- * @example
- * let code = `var foo = 0;`;
- * let tokens = Prism.tokenize(code, Prism.languages.javascript);
- * tokens.forEach(token => {
- * if (token instanceof Prism.Token && token.type === 'number') {
- * console.log(`Found numeric literal: ${token.content}`);
- * }
- * });
- */
- tokenize: function (text, grammar) {
- var rest = grammar.rest;
- if (rest) {
- for (var token in rest) {
- grammar[token] = rest[token];
- }
-
- delete grammar.rest;
- }
-
- var tokenList = new LinkedList();
- addAfter(tokenList, tokenList.head, text);
-
- matchGrammar(text, tokenList, grammar, tokenList.head, 0);
-
- return toArray(tokenList);
- },
-
- /**
- * @namespace
- * @memberof Prism
- * @public
- */
- hooks: {
- all: {},
-
- /**
- * Adds the given callback to the list of callbacks for the given hook.
- *
- * The callback will be invoked when the hook it is registered for is run.
- * Hooks are usually directly run by a highlight function but you can also run hooks yourself.
- *
- * One callback function can be registered to multiple hooks and the same hook multiple times.
- *
- * @param {string} name The name of the hook.
- * @param {HookCallback} callback The callback function which is given environment variables.
- * @public
- */
- add: function (name, callback) {
- var hooks = _.hooks.all;
-
- hooks[name] = hooks[name] || [];
-
- hooks[name].push(callback);
- },
-
- /**
- * Runs a hook invoking all registered callbacks with the given environment variables.
- *
- * Callbacks will be invoked synchronously and in the order in which they were registered.
- *
- * @param {string} name The name of the hook.
- * @param {Object<string, any>} env The environment variables of the hook passed to all callbacks registered.
- * @public
- */
- run: function (name, env) {
- var callbacks = _.hooks.all[name];
-
- if (!callbacks || !callbacks.length) {
- return;
- }
-
- for (var i = 0, callback; (callback = callbacks[i++]); ) {
- callback(env);
- }
- },
- },
-
- Token: Token,
- };
- _self.Prism = _;
-
- // Typescript note:
- // The following can be used to import the Token type in JSDoc:
- //
- // @typedef {InstanceType<import("./prism-core")["Token"]>} Token
-
- /**
- * Creates a new token.
- *
- * @param {string} type See {@link Token#type type}
- * @param {string | TokenStream} content See {@link Token#content content}
- * @param {string|string[]} [alias] The alias(es) of the token.
- * @param {string} [matchedStr=""] A copy of the full string this token was created from.
- * @class
- * @global
- * @public
- */
- function Token(type, content, alias, matchedStr) {
- /**
- * The type of the token.
- *
- * This is usually the key of a pattern in a {@link Grammar}.
- *
- * @type {string}
- * @see GrammarToken
- * @public
- */
- this.type = type;
- /**
- * The strings or tokens contained by this token.
- *
- * This will be a token stream if the pattern matched also defined an `inside` grammar.
- *
- * @type {string | TokenStream}
- * @public
- */
- this.content = content;
- /**
- * The alias(es) of the token.
- *
- * @type {string|string[]}
- * @see GrammarToken
- * @public
- */
- this.alias = alias;
- // Copy of the full string this token was created from
- this.length = (matchedStr || "").length | 0;
- }
-
- /**
- * A token stream is an array of strings and {@link Token Token} objects.
- *
- * Token streams have to fulfill a few properties that are assumed by most functions (mostly internal ones) that process
- * them.
- *
- * 1. No adjacent strings.
- * 2. No empty strings.
- *
- * The only exception here is the token stream that only contains the empty string and nothing else.
- *
- * @typedef {Array<string | Token>} TokenStream
- * @global
- * @public
- */
-
- /**
- * Converts the given token or token stream to an HTML representation.
- *
- * The following hooks will be run:
- * 1. `wrap`: On each {@link Token}.
- *
- * @param {string | Token | TokenStream} o The token or token stream to be converted.
- * @param {string} language The name of current language.
- * @returns {string} The HTML representation of the token or token stream.
- * @memberof Token
- * @static
- */
- Token.stringify = function stringify(o, language) {
- if (typeof o == "string") {
- return o;
- }
- if (Array.isArray(o)) {
- var s = "";
- o.forEach(function (e) {
- s += stringify(e, language);
- });
- return s;
- }
-
- var env = {
- type: o.type,
- content: stringify(o.content, language),
- tag: "span",
- classes: ["token", o.type],
- attributes: {},
- language: language,
- };
-
- var aliases = o.alias;
- if (aliases) {
- if (Array.isArray(aliases)) {
- Array.prototype.push.apply(env.classes, aliases);
- } else {
- env.classes.push(aliases);
- }
- }
-
- _.hooks.run("wrap", env);
-
- var attributes = "";
- for (var name in env.attributes) {
- attributes +=
- " " +
- name +
- '="' +
- (env.attributes[name] || "").replace(/"/g, """) +
- '"';
- }
-
- return (
- "<" +
- env.tag +
- ' class="' +
- env.classes.join(" ") +
- '"' +
- attributes +
- ">" +
- env.content +
- "</" +
- env.tag +
- ">"
- );
- };
-
- /**
- * @param {RegExp} pattern
- * @param {number} pos
- * @param {string} text
- * @param {boolean} lookbehind
- * @returns {RegExpExecArray | null}
- */
- function matchPattern(pattern, pos, text, lookbehind) {
- pattern.lastIndex = pos;
- var match = pattern.exec(text);
- if (match && lookbehind && match[1]) {
- // change the match to remove the text matched by the Prism lookbehind group
- var lookbehindLength = match[1].length;
- match.index += lookbehindLength;
- match[0] = match[0].slice(lookbehindLength);
- }
- return match;
- }
-
- /**
- * @param {string} text
- * @param {LinkedList<string | Token>} tokenList
- * @param {any} grammar
- * @param {LinkedListNode<string | Token>} startNode
- * @param {number} startPos
- * @param {RematchOptions} [rematch]
- * @returns {void}
- * @private
- *
- * @typedef RematchOptions
- * @property {string} cause
- * @property {number} reach
- */
- function matchGrammar(
- text,
- tokenList,
- grammar,
- startNode,
- startPos,
- rematch
- ) {
- for (var token in grammar) {
- if (!grammar.hasOwnProperty(token) || !grammar[token]) {
- continue;
- }
-
- var patterns = grammar[token];
- patterns = Array.isArray(patterns) ? patterns : [patterns];
-
- for (var j = 0; j < patterns.length; ++j) {
- if (rematch && rematch.cause == token + "," + j) {
- return;
- }
-
- var patternObj = patterns[j];
- var inside = patternObj.inside;
- var lookbehind = !!patternObj.lookbehind;
- var greedy = !!patternObj.greedy;
- var alias = patternObj.alias;
-
- if (greedy && !patternObj.pattern.global) {
- // Without the global flag, lastIndex won't work
- var flags = patternObj.pattern.toString().match(/[imsuy]*$/)[0];
- patternObj.pattern = RegExp(patternObj.pattern.source, flags + "g");
- }
-
- /** @type {RegExp} */
- var pattern = patternObj.pattern || patternObj;
-
- for (
- // iterate the token list and keep track of the current token/string position
- var currentNode = startNode.next, pos = startPos;
- currentNode !== tokenList.tail;
- pos += currentNode.value.length, currentNode = currentNode.next
- ) {
- if (rematch && pos >= rematch.reach) {
- break;
- }
-
- var str = currentNode.value;
-
- if (tokenList.length > text.length) {
- // Something went terribly wrong, ABORT, ABORT!
- return;
- }
-
- if (str instanceof Token) {
- continue;
- }
-
- var removeCount = 1; // this is the to parameter of removeBetween
- var match;
-
- if (greedy) {
- match = matchPattern(pattern, pos, text, lookbehind);
- if (!match || match.index >= text.length) {
- break;
- }
-
- var from = match.index;
- var to = match.index + match[0].length;
- var p = pos;
-
- // find the node that contains the match
- p += currentNode.value.length;
- while (from >= p) {
- currentNode = currentNode.next;
- p += currentNode.value.length;
- }
- // adjust pos (and p)
- p -= currentNode.value.length;
- pos = p;
-
- // the current node is a Token, then the match starts inside another Token, which is invalid
- if (currentNode.value instanceof Token) {
- continue;
- }
-
- // find the last node which is affected by this match
- for (
- var k = currentNode;
- k !== tokenList.tail && (p < to || typeof k.value === "string");
- k = k.next
- ) {
- removeCount++;
- p += k.value.length;
- }
- removeCount--;
-
- // replace with the new match
- str = text.slice(pos, p);
- match.index -= pos;
- } else {
- match = matchPattern(pattern, 0, str, lookbehind);
- if (!match) {
- continue;
- }
- }
-
- // eslint-disable-next-line no-redeclare
- var from = match.index;
- var matchStr = match[0];
- var before = str.slice(0, from);
- var after = str.slice(from + matchStr.length);
-
- var reach = pos + str.length;
- if (rematch && reach > rematch.reach) {
- rematch.reach = reach;
- }
-
- var removeFrom = currentNode.prev;
-
- if (before) {
- removeFrom = addAfter(tokenList, removeFrom, before);
- pos += before.length;
- }
-
- removeRange(tokenList, removeFrom, removeCount);
-
- var wrapped = new Token(
- token,
- inside ? _.tokenize(matchStr, inside) : matchStr,
- alias,
- matchStr
- );
- currentNode = addAfter(tokenList, removeFrom, wrapped);
-
- if (after) {
- addAfter(tokenList, currentNode, after);
- }
-
- if (removeCount > 1) {
- // at least one Token object was removed, so we have to do some rematching
- // this can only happen if the current pattern is greedy
-
- /** @type {RematchOptions} */
- var nestedRematch = {
- cause: token + "," + j,
- reach: reach,
- };
- matchGrammar(
- text,
- tokenList,
- grammar,
- currentNode.prev,
- pos,
- nestedRematch
- );
-
- // the reach might have been extended because of the rematching
- if (rematch && nestedRematch.reach > rematch.reach) {
- rematch.reach = nestedRematch.reach;
- }
- }
- }
- }
- }
- }
-
- /**
- * @typedef LinkedListNode
- * @property {T} value
- * @property {LinkedListNode<T> | null} prev The previous node.
- * @property {LinkedListNode<T> | null} next The next node.
- * @template T
- * @private
- */
-
- /**
- * @template T
- * @private
- */
- function LinkedList() {
- /** @type {LinkedListNode<T>} */
- var head = { value: null, prev: null, next: null };
- /** @type {LinkedListNode<T>} */
- var tail = { value: null, prev: head, next: null };
- head.next = tail;
-
- /** @type {LinkedListNode<T>} */
- this.head = head;
- /** @type {LinkedListNode<T>} */
- this.tail = tail;
- this.length = 0;
- }
-
- /**
- * Adds a new node with the given value to the list.
- *
- * @param {LinkedList<T>} list
- * @param {LinkedListNode<T>} node
- * @param {T} value
- * @returns {LinkedListNode<T>} The added node.
- * @template T
- */
- function addAfter(list, node, value) {
- // assumes that node != list.tail && values.length >= 0
- var next = node.next;
-
- var newNode = { value: value, prev: node, next: next };
- node.next = newNode;
- next.prev = newNode;
- list.length++;
-
- return newNode;
- }
- /**
- * Removes `count` nodes after the given node. The given node will not be removed.
- *
- * @param {LinkedList<T>} list
- * @param {LinkedListNode<T>} node
- * @param {number} count
- * @template T
- */
- function removeRange(list, node, count) {
- var next = node.next;
- for (var i = 0; i < count && next !== list.tail; i++) {
- next = next.next;
- }
- node.next = next;
- next.prev = node;
- list.length -= i;
- }
- /**
- * @param {LinkedList<T>} list
- * @returns {T[]}
- * @template T
- */
- function toArray(list) {
- var array = [];
- var node = list.head.next;
- while (node !== list.tail) {
- array.push(node.value);
- node = node.next;
- }
- return array;
- }
-
- if (!_self.document) {
- if (!_self.addEventListener) {
- // in Node.js
- return _;
- }
-
- if (!_.disableWorkerMessageHandler) {
- // In worker
- _self.addEventListener(
- "message",
- function (evt) {
- var message = JSON.parse(evt.data);
- var lang = message.language;
- var code = message.code;
- var immediateClose = message.immediateClose;
-
- _self.postMessage(_.highlight(code, _.languages[lang], lang));
- if (immediateClose) {
- _self.close();
- }
- },
- false
- );
- }
-
- return _;
- }
-
- // Get current script and highlight
- var script = _.util.currentScript();
-
- if (script) {
- _.filename = script.src;
-
- if (script.hasAttribute("data-manual")) {
- _.manual = true;
- }
- }
-
- function highlightAutomaticallyCallback() {
- if (!_.manual) {
- _.highlightAll();
- }
- }
-
- if (!_.manual) {
- // If the document state is "loading", then we'll use DOMContentLoaded.
- // If the document state is "interactive" and the prism.js script is deferred, then we'll also use the
- // DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they
- // might take longer one animation frame to execute which can create a race condition where only some plugins have
- // been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded.
- // See https://github.com/PrismJS/prism/issues/2102
- var readyState = document.readyState;
- if (
- readyState === "loading" ||
- (readyState === "interactive" && script && script.defer)
- ) {
- document.addEventListener(
- "DOMContentLoaded",
- highlightAutomaticallyCallback
- );
- } else {
- if (window.requestAnimationFrame) {
- window.requestAnimationFrame(highlightAutomaticallyCallback);
- } else {
- window.setTimeout(highlightAutomaticallyCallback, 16);
- }
- }
- }
-
- return _;
-})(_self);
-
-if (typeof module !== "undefined" && module.exports) {
- module.exports = Prism;
-}
-
-// hack for components to work correctly in node.js
-if (typeof global !== "undefined") {
- global.Prism = Prism;
-}
-
-// some additional documentation/types
-
-/**
- * The expansion of a simple `RegExp` literal to support additional properties.
- *
- * @typedef GrammarToken
- * @property {RegExp} pattern The regular expression of the token.
- * @property {boolean} [lookbehind=false] If `true`, then the first capturing group of `pattern` will (effectively)
- * behave as a lookbehind group meaning that the captured text will not be part of the matched text of the new token.
- * @property {boolean} [greedy=false] Whether the token is greedy.
- * @property {string|string[]} [alias] An optional alias or list of aliases.
- * @property {Grammar} [inside] The nested grammar of this token.
- *
- * The `inside` grammar will be used to tokenize the text value of each token of this kind.
- *
- * This can be used to make nested and even recursive language definitions.
- *
- * Note: This can cause infinite recursion. Be careful when you embed different languages or even the same language into
- * each another.
- * @global
- * @public
- */
-
-/**
- * @typedef Grammar
- * @type {Object<string, RegExp | GrammarToken | Array<RegExp | GrammarToken>>}
- * @property {Grammar} [rest] An optional grammar object that will be appended to this grammar.
- * @global
- * @public
- */
-
-/**
- * A function which will invoked after an element was successfully highlighted.
- *
- * @callback HighlightCallback
- * @param {Element} element The element successfully highlighted.
- * @returns {void}
- * @global
- * @public
- */
-
-/**
- * @callback HookCallback
- * @param {Object<string, any>} env The environment variables of the hook.
- * @returns {void}
- * @global
- * @public
- */
-Prism.languages.markup = {
- comment: {
- pattern: /<!--(?:(?!<!--)[\s\S])*?-->/,
- greedy: true,
- },
- prolog: {
- pattern: /<\?[\s\S]+?\?>/,
- greedy: true,
- },
- doctype: {
- // https://www.w3.org/TR/xml/#NT-doctypedecl
- pattern:
- /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,
- greedy: true,
- inside: {
- "internal-subset": {
- pattern: /(^[^\[]*\[)[\s\S]+(?=\]>$)/,
- lookbehind: true,
- greedy: true,
- inside: null, // see below
- },
- string: {
- pattern: /"[^"]*"|'[^']*'/,
- greedy: true,
- },
- punctuation: /^<!|>$|[[\]]/,
- "doctype-tag": /^DOCTYPE/i,
- name: /[^\s<>'"]+/,
- },
- },
- cdata: {
- pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
- greedy: true,
- },
- tag: {
- pattern:
- /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,
- greedy: true,
- inside: {
- tag: {
- pattern: /^<\/?[^\s>\/]+/,
- inside: {
- punctuation: /^<\/?/,
- namespace: /^[^\s>\/:]+:/,
- },
- },
- "special-attr": [],
- "attr-value": {
- pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,
- inside: {
- punctuation: [
- {
- pattern: /^=/,
- alias: "attr-equals",
- },
- {
- pattern: /^(\s*)["']|["']$/,
- lookbehind: true,
- },
- ],
- },
- },
- punctuation: /\/?>/,
- "attr-name": {
- pattern: /[^\s>\/]+/,
- inside: {
- namespace: /^[^\s>\/:]+:/,
- },
- },
- },
- },
- entity: [
- {
- pattern: /&[\da-z]{1,8};/i,
- alias: "named-entity",
- },
- /&#x?[\da-f]{1,8};/i,
- ],
-};
-
-Prism.languages.markup["tag"].inside["attr-value"].inside["entity"] =
- Prism.languages.markup["entity"];
-Prism.languages.markup["doctype"].inside["internal-subset"].inside =
- Prism.languages.markup;
-
-// Plugin to make entity title show the real entity, idea by Roman Komarov
-Prism.hooks.add("wrap", function (env) {
- if (env.type === "entity") {
- env.attributes["title"] = env.content.replace(/&/, "&");
- }
-});
-
-Object.defineProperty(Prism.languages.markup.tag, "addInlined", {
- /**
- * Adds an inlined language to markup.
- *
- * An example of an inlined language is CSS with `<style>` tags.
- *
- * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as
- * case insensitive.
- * @param {string} lang The language key.
- * @example
- * addInlined('style', 'css');
- */
- value: function addInlined(tagName, lang) {
- var includedCdataInside = {};
- includedCdataInside["language-" + lang] = {
- pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,
- lookbehind: true,
- inside: Prism.languages[lang],
- };
- includedCdataInside["cdata"] = /^<!\[CDATA\[|\]\]>$/i;
-
- var inside = {
- "included-cdata": {
- pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
- inside: includedCdataInside,
- },
- };
- inside["language-" + lang] = {
- pattern: /[\s\S]+/,
- inside: Prism.languages[lang],
- };
-
- var def = {};
- def[tagName] = {
- pattern: RegExp(
- /(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(
- /__/g,
- function () {
- return tagName;
- }
- ),
- "i"
- ),
- lookbehind: true,
- greedy: true,
- inside: inside,
- };
-
- Prism.languages.insertBefore("markup", "cdata", def);
- },
-});
-Object.defineProperty(Prism.languages.markup.tag, "addAttribute", {
- /**
- * Adds an pattern to highlight languages embedded in HTML attributes.
- *
- * An example of an inlined language is CSS with `style` attributes.
- *
- * @param {string} attrName The name of the tag that contains the inlined language. This name will be treated as
- * case insensitive.
- * @param {string} lang The language key.
- * @example
- * addAttribute('style', 'css');
- */
- value: function (attrName, lang) {
- Prism.languages.markup.tag.inside["special-attr"].push({
- pattern: RegExp(
- /(^|["'\s])/.source +
- "(?:" +
- attrName +
- ")" +
- /\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,
- "i"
- ),
- lookbehind: true,
- inside: {
- "attr-name": /^[^\s=]+/,
- "attr-value": {
- pattern: /=[\s\S]+/,
- inside: {
- value: {
- pattern: /(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,
- lookbehind: true,
- alias: [lang, "language-" + lang],
- inside: Prism.languages[lang],
- },
- punctuation: [
- {
- pattern: /^=/,
- alias: "attr-equals",
- },
- /"|'/,
- ],
- },
- },
- },
- });
- },
-});
-
-Prism.languages.html = Prism.languages.markup;
-Prism.languages.mathml = Prism.languages.markup;
-Prism.languages.svg = Prism.languages.markup;
-
-Prism.languages.xml = Prism.languages.extend("markup", {});
-Prism.languages.ssml = Prism.languages.xml;
-Prism.languages.atom = Prism.languages.xml;
-Prism.languages.rss = Prism.languages.xml;
-
-(function (Prism) {
- var string =
- /(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;
-
- Prism.languages.css = {
- comment: /\/\*[\s\S]*?\*\//,
- atrule: {
- pattern: RegExp(
- "@[\\w-](?:" +
- /[^;{\s"']|\s+(?!\s)/.source +
- "|" +
- string.source +
- ")*?" +
- /(?:;|(?=\s*\{))/.source
- ),
- inside: {
- rule: /^@[\w-]+/,
- "selector-function-argument": {
- pattern:
- /(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,
- lookbehind: true,
- alias: "selector",
- },
- keyword: {
- pattern: /(^|[^\w-])(?:and|not|only|or)(?![\w-])/,
- lookbehind: true,
- },
- // See rest below
- },
- },
- url: {
- // https://drafts.csswg.org/css-values-3/#urls
- pattern: RegExp(
- "\\burl\\((?:" +
- string.source +
- "|" +
- /(?:[^\\\r\n()"']|\\[\s\S])*/.source +
- ")\\)",
- "i"
- ),
- greedy: true,
- inside: {
- function: /^url/i,
- punctuation: /^\(|\)$/,
- string: {
- pattern: RegExp("^" + string.source + "$"),
- alias: "url",
- },
- },
- },
- selector: {
- pattern: RegExp(
- "(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|" +
- string.source +
- ")*(?=\\s*\\{)"
- ),
- lookbehind: true,
- },
- string: {
- pattern: string,
- greedy: true,
- },
- property: {
- pattern:
- /(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,
- lookbehind: true,
- },
- important: /!important\b/i,
- function: {
- pattern: /(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,
- lookbehind: true,
- },
- punctuation: /[(){};:,]/,
- };
-
- Prism.languages.css["atrule"].inside.rest = Prism.languages.css;
-
- var markup = Prism.languages.markup;
- if (markup) {
- markup.tag.addInlined("style", "css");
- markup.tag.addAttribute("style", "css");
- }
-})(Prism);
-
-Prism.languages.clike = {
- comment: [
- {
- pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
- lookbehind: true,
- greedy: true,
- },
- {
- pattern: /(^|[^\\:])\/\/.*/,
- lookbehind: true,
- greedy: true,
- },
- ],
- string: {
- pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
- greedy: true,
- },
- "class-name": {
- pattern:
- /(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,
- lookbehind: true,
- inside: {
- punctuation: /[.\\]/,
- },
- },
- keyword:
- /\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,
- boolean: /\b(?:false|true)\b/,
- function: /\b\w+(?=\()/,
- number: /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,
- operator: /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,
- punctuation: /[{}[\];(),.:]/,
-};
-
-Prism.languages.javascript = Prism.languages.extend("clike", {
- "class-name": [
- Prism.languages.clike["class-name"],
- {
- pattern:
- /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,
- lookbehind: true,
- },
- ],
- keyword: [
- {
- pattern: /((?:^|\})\s*)catch\b/,
- lookbehind: true,
- },
- {
- pattern:
- /(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,
- lookbehind: true,
- },
- ],
- // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
- function:
- /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
- number: {
- pattern: RegExp(
- /(^|[^\w$])/.source +
- "(?:" +
- // constant
- (/NaN|Infinity/.source +
- "|" +
- // binary integer
- /0[bB][01]+(?:_[01]+)*n?/.source +
- "|" +
- // octal integer
- /0[oO][0-7]+(?:_[0-7]+)*n?/.source +
- "|" +
- // hexadecimal integer
- /0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source +
- "|" +
- // decimal bigint
- /\d+(?:_\d+)*n/.source +
- "|" +
- // decimal number (integer or float) but no bigint
- /(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/
- .source) +
- ")" +
- /(?![\w$])/.source
- ),
- lookbehind: true,
- },
- operator:
- /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/,
-});
-
-Prism.languages.javascript["class-name"][0].pattern =
- /(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/;
-
-Prism.languages.insertBefore("javascript", "keyword", {
- regex: {
- pattern: RegExp(
- // lookbehind
- // eslint-disable-next-line regexp/no-dupe-characters-character-class
- /((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source +
- // Regex pattern:
- // There are 2 regex patterns here. The RegExp set notation proposal added support for nested character
- // classes if the `v` flag is present. Unfortunately, nested CCs are both context-free and incompatible
- // with the only syntax, so we have to define 2 different regex patterns.
- /\//.source +
- "(?:" +
- /(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/
- .source +
- "|" +
- // `v` flag syntax. This supports 3 levels of nested character classes.
- /(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/
- .source +
- ")" +
- // lookahead
- /(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source
- ),
- lookbehind: true,
- greedy: true,
- inside: {
- "regex-source": {
- pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/,
- lookbehind: true,
- alias: "language-regex",
- inside: Prism.languages.regex,
- },
- "regex-delimiter": /^\/|\/$/,
- "regex-flags": /^[a-z]+$/,
- },
- },
- // This must be declared before keyword because we use "function" inside the look-forward
- "function-variable": {
- pattern:
- /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,
- alias: "function",
- },
- parameter: [
- {
- pattern:
- /(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,
- lookbehind: true,
- inside: Prism.languages.javascript,
- },
- {
- pattern:
- /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,
- lookbehind: true,
- inside: Prism.languages.javascript,
- },
- {
- pattern:
- /(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,
- lookbehind: true,
- inside: Prism.languages.javascript,
- },
- {
- pattern:
- /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,
- lookbehind: true,
- inside: Prism.languages.javascript,
- },
- ],
- constant: /\b[A-Z](?:[A-Z_]|\dx?)*\b/,
-});
-
-Prism.languages.insertBefore("javascript", "string", {
- hashbang: {
- pattern: /^#!.*/,
- greedy: true,
- alias: "comment",
- },
- "template-string": {
- pattern:
- /`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,
- greedy: true,
- inside: {
- "template-punctuation": {
- pattern: /^`|`$/,
- alias: "string",
- },
- interpolation: {
- pattern:
- /((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,
- lookbehind: true,
- inside: {
- "interpolation-punctuation": {
- pattern: /^\$\{|\}$/,
- alias: "punctuation",
- },
- rest: Prism.languages.javascript,
- },
- },
- string: /[\s\S]+/,
- },
- },
- "string-property": {
- pattern:
- /((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,
- lookbehind: true,
- greedy: true,
- alias: "property",
- },
-});
-
-Prism.languages.insertBefore("javascript", "operator", {
- "literal-property": {
- pattern:
- /((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,
- lookbehind: true,
- alias: "property",
- },
-});
-
-if (Prism.languages.markup) {
- Prism.languages.markup.tag.addInlined("script", "javascript");
-
- // add attribute support for all DOM events.
- // https://developer.mozilla.org/en-US/docs/Web/Events#Standard_events
- Prism.languages.markup.tag.addAttribute(
- /on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/
- .source,
- "javascript"
- );
-}
-
-Prism.languages.js = Prism.languages.javascript;
-
-(function (Prism) {
- Prism.languages.diff = {
- coord: [
- // Match all kinds of coord lines (prefixed by "+++", "---" or "***").
- /^(?:\*{3}|-{3}|\+{3}).*$/m,
- // Match "@@ ... @@" coord lines in unified diff.
- /^@@.*@@$/m,
- // Match coord lines in normal diff (starts with a number).
- /^\d.*$/m,
- ],
-
- // deleted, inserted, unchanged, diff
- };
-
- /**
- * A map from the name of a block to its line prefix.
- *
- * @type {Object<string, string>}
- */
- var PREFIXES = {
- "deleted-sign": "-",
- "deleted-arrow": "<",
- "inserted-sign": "+",
- "inserted-arrow": ">",
- unchanged: " ",
- diff: "!",
- };
-
- // add a token for each prefix
- Object.keys(PREFIXES).forEach(function (name) {
- var prefix = PREFIXES[name];
-
- var alias = [];
- if (!/^\w+$/.test(name)) {
- // "deleted-sign" -> "deleted"
- alias.push(/\w+/.exec(name)[0]);
- }
- if (name === "diff") {
- alias.push("bold");
- }
-
- Prism.languages.diff[name] = {
- pattern: RegExp("^(?:[" + prefix + "].*(?:\r\n?|\n|(?![\\s\\S])))+", "m"),
- alias: alias,
- inside: {
- line: {
- pattern: /(.)(?=[\s\S]).*(?:\r\n?|\n)?/,
- lookbehind: true,
- },
- prefix: {
- pattern: /[\s\S]/,
- alias: /\w+/.exec(name)[0],
- },
- },
- };
- });
-
- // make prefixes available to Diff plugin
- Object.defineProperty(Prism.languages.diff, "PREFIXES", {
- value: PREFIXES,
- });
-})(Prism);
-
-(function () {
- if (
- typeof Prism === "undefined" ||
- typeof document === "undefined" ||
- !document.querySelector
- ) {
- return;
- }
-
- var LINE_NUMBERS_CLASS = "line-numbers";
- var LINKABLE_LINE_NUMBERS_CLASS = "linkable-line-numbers";
- var NEW_LINE_EXP = /\n(?!$)/g;
-
- /**
- * @param {string} selector
- * @param {ParentNode} [container]
- * @returns {HTMLElement[]}
- */
- function $$(selector, container) {
- return Array.prototype.slice.call(
- (container || document).querySelectorAll(selector)
- );
- }
-
- /**
- * Returns whether the given element has the given class.
- *
- * @param {Element} element
- * @param {string} className
- * @returns {boolean}
- */
- function hasClass(element, className) {
- return element.classList.contains(className);
- }
-
- /**
- * Calls the given function.
- *
- * @param {() => any} func
- * @returns {void}
- */
- function callFunction(func) {
- func();
- }
-
- // Some browsers round the line-height, others don't.
- // We need to test for it to position the elements properly.
- var isLineHeightRounded = (function () {
- var res;
- return function () {
- if (typeof res === "undefined") {
- var d = document.createElement("div");
- d.style.fontSize = "13px";
- d.style.lineHeight = "1.5";
- d.style.padding = "0";
- d.style.border = "0";
- d.innerHTML = " <br /> ";
- document.body.appendChild(d);
- // Browsers that round the line-height should have offsetHeight === 38
- // The others should have 39.
- res = d.offsetHeight === 38;
- document.body.removeChild(d);
- }
- return res;
- };
- })();
-
- /**
- * Returns the top offset of the content box of the given parent and the content box of one of its children.
- *
- * @param {HTMLElement} parent
- * @param {HTMLElement} child
- */
- function getContentBoxTopOffset(parent, child) {
- var parentStyle = getComputedStyle(parent);
- var childStyle = getComputedStyle(child);
-
- /**
- * Returns the numeric value of the given pixel value.
- *
- * @param {string} px
- */
- function pxToNumber(px) {
- return +px.substr(0, px.length - 2);
- }
-
- return (
- child.offsetTop +
- pxToNumber(childStyle.borderTopWidth) +
- pxToNumber(childStyle.paddingTop) -
- pxToNumber(parentStyle.paddingTop)
- );
- }
-
- /**
- * Returns whether the Line Highlight plugin is active for the given element.
- *
- * If this function returns `false`, do not call `highlightLines` for the given element.
- *
- * @param {HTMLElement | null | undefined} pre
- * @returns {boolean}
- */
- function isActiveFor(pre) {
- if (!pre || !/pre/i.test(pre.nodeName)) {
- return false;
- }
-
- if (pre.hasAttribute("data-line")) {
- return true;
- }
-
- if (pre.id && Prism.util.isActive(pre, LINKABLE_LINE_NUMBERS_CLASS)) {
- // Technically, the line numbers plugin is also necessary but this plugin doesn't control the classes of
- // the line numbers plugin, so we can't assume that they are present.
- return true;
- }
-
- return false;
- }
-
- var scrollIntoView = true;
-
- Prism.plugins.lineHighlight = {
- /**
- * Highlights the lines of the given pre.
- *
- * This function is split into a DOM measuring and mutate phase to improve performance.
- * The returned function mutates the DOM when called.
- *
- * @param {HTMLElement} pre
- * @param {string | null} [lines]
- * @param {string} [classes='']
- * @returns {() => void}
- */
- highlightLines: function highlightLines(pre, lines, classes) {
- lines =
- typeof lines === "string" ? lines : pre.getAttribute("data-line") || "";
-
- var ranges = lines.replace(/\s+/g, "").split(",").filter(Boolean);
- var offset = +pre.getAttribute("data-line-offset") || 0;
-
- var parseMethod = isLineHeightRounded() ? parseInt : parseFloat;
- var lineHeight = parseMethod(getComputedStyle(pre).lineHeight);
- var hasLineNumbers = Prism.util.isActive(pre, LINE_NUMBERS_CLASS);
- var codeElement = pre.querySelector("code");
- var parentElement = hasLineNumbers ? pre : codeElement || pre;
- var mutateActions = /** @type {(() => void)[]} */ ([]);
- var lineBreakMatch = codeElement.textContent.match(NEW_LINE_EXP);
- var numberOfLines = lineBreakMatch ? lineBreakMatch.length + 1 : 1;
- /**
- * The top offset between the content box of the <code> element and the content box of the parent element of
- * the line highlight element (either `<pre>` or `<code>`).
- *
- * This offset might not be zero for some themes where the <code> element has a top margin. Some plugins
- * (or users) might also add element above the <code> element. Because the line highlight is aligned relative
- * to the <pre> element, we have to take this into account.
- *
- * This offset will be 0 if the parent element of the line highlight element is the `<code>` element.
- */
- var codePreOffset =
- !codeElement || parentElement == codeElement
- ? 0
- : getContentBoxTopOffset(pre, codeElement);
-
- ranges.forEach(function (currentRange) {
- var range = currentRange.split("-");
-
- var start = +range[0];
- var end = +range[1] || start;
- end = Math.min(numberOfLines + offset, end);
-
- if (end < start) {
- return;
- }
-
- /** @type {HTMLElement} */
- var line =
- pre.querySelector(
- '.line-highlight[data-range="' + currentRange + '"]'
- ) || document.createElement("div");
-
- mutateActions.push(function () {
- line.setAttribute("aria-hidden", "true");
- line.setAttribute("data-range", currentRange);
- line.className = (classes || "") + " line-highlight";
- });
-
- // if the line-numbers plugin is enabled, then there is no reason for this plugin to display the line numbers
- if (hasLineNumbers && Prism.plugins.lineNumbers) {
- var startNode = Prism.plugins.lineNumbers.getLine(pre, start);
- var endNode = Prism.plugins.lineNumbers.getLine(pre, end);
-
- if (startNode) {
- var top = startNode.offsetTop + codePreOffset + "px";
- mutateActions.push(function () {
- line.style.top = top;
- });
- }
-
- if (endNode) {
- var height =
- endNode.offsetTop -
- startNode.offsetTop +
- endNode.offsetHeight +
- "px";
- mutateActions.push(function () {
- line.style.height = height;
- });
- }
- } else {
- mutateActions.push(function () {
- line.setAttribute("data-start", String(start));
-
- if (end > start) {
- line.setAttribute("data-end", String(end));
- }
-
- line.style.top =
- (start - offset - 1) * lineHeight + codePreOffset + "px";
-
- line.textContent = new Array(end - start + 2).join(" \n");
- });
- }
-
- mutateActions.push(function () {
- line.style.width = pre.scrollWidth + "px";
- });
-
- mutateActions.push(function () {
- // allow this to play nicely with the line-numbers plugin
- // need to attack to pre as when line-numbers is enabled, the code tag is relatively which screws up the positioning
- parentElement.appendChild(line);
- });
- });
-
- var id = pre.id;
- if (
- hasLineNumbers &&
- Prism.util.isActive(pre, LINKABLE_LINE_NUMBERS_CLASS) &&
- id
- ) {
- // This implements linkable line numbers. Linkable line numbers use Line Highlight to create a link to a
- // specific line. For this to work, the pre element has to:
- // 1) have line numbers,
- // 2) have the `linkable-line-numbers` class or an ascendant that has that class, and
- // 3) have an id.
-
- if (!hasClass(pre, LINKABLE_LINE_NUMBERS_CLASS)) {
- // add class to pre
- mutateActions.push(function () {
- pre.classList.add(LINKABLE_LINE_NUMBERS_CLASS);
- });
- }
-
- var start = parseInt(pre.getAttribute("data-start") || "1");
-
- // iterate all line number spans
- $$(".line-numbers-rows > span", pre).forEach(function (lineSpan, i) {
- var lineNumber = i + start;
- lineSpan.onclick = function () {
- var hash = id + "." + lineNumber;
-
- // this will prevent scrolling since the span is obviously in view
- scrollIntoView = false;
- location.hash = hash;
- setTimeout(function () {
- scrollIntoView = true;
- }, 1);
- };
- });
- }
-
- return function () {
- mutateActions.forEach(callFunction);
- };
- },
- };
-
- function applyHash() {
- var hash = location.hash.slice(1);
-
- // Remove pre-existing temporary lines
- $$(".temporary.line-highlight").forEach(function (line) {
- line.parentNode.removeChild(line);
- });
-
- var range = (hash.match(/\.([\d,-]+)$/) || [, ""])[1];
-
- if (!range || document.getElementById(hash)) {
- return;
- }
-
- var id = hash.slice(0, hash.lastIndexOf("."));
- var pre = document.getElementById(id);
-
- if (!pre) {
- return;
- }
-
- if (!pre.hasAttribute("data-line")) {
- pre.setAttribute("data-line", "");
- }
-
- var mutateDom = Prism.plugins.lineHighlight.highlightLines(
- pre,
- range,
- "temporary "
- );
- mutateDom();
-
- if (scrollIntoView) {
- document.querySelector(".temporary.line-highlight").scrollIntoView();
- }
- }
-
- var fakeTimer = 0; // Hack to limit the number of times applyHash() runs
-
- Prism.hooks.add("before-sanity-check", function (env) {
- var pre = env.element.parentElement;
- if (!isActiveFor(pre)) {
- return;
- }
-
- /*
- * Cleanup for other plugins (e.g. autoloader).
- *
- * Sometimes <code> blocks are highlighted multiple times. It is necessary
- * to cleanup any left-over tags, because the whitespace inside of the <div>
- * tags change the content of the <code> tag.
- */
- var num = 0;
- $$(".line-highlight", pre).forEach(function (line) {
- num += line.textContent.length;
- line.parentNode.removeChild(line);
- });
- // Remove extra whitespace
- if (num && /^(?: \n)+$/.test(env.code.slice(-num))) {
- env.code = env.code.slice(0, -num);
- }
- });
-
- Prism.hooks.add("complete", function completeHook(env) {
- var pre = env.element.parentElement;
- if (!isActiveFor(pre)) {
- return;
- }
-
- clearTimeout(fakeTimer);
-
- var hasLineNumbers = Prism.plugins.lineNumbers;
- var isLineNumbersLoaded = env.plugins && env.plugins.lineNumbers;
-
- if (
- hasClass(pre, LINE_NUMBERS_CLASS) &&
- hasLineNumbers &&
- !isLineNumbersLoaded
- ) {
- Prism.hooks.add("line-numbers", completeHook);
- } else {
- var mutateDom = Prism.plugins.lineHighlight.highlightLines(pre);
- mutateDom();
- fakeTimer = setTimeout(applyHash, 1);
- }
- });
-
- window.addEventListener("hashchange", applyHash);
- window.addEventListener("resize", function () {
- var actions = $$("pre")
- .filter(isActiveFor)
- .map(function (pre) {
- return Prism.plugins.lineHighlight.highlightLines(pre);
- });
- actions.forEach(callFunction);
- });
-})();
-
-(function () {
- if (typeof Prism === "undefined" || typeof document === "undefined") {
- return;
- }
-
- /**
- * Plugin name which is used as a class name for <pre> which is activating the plugin
- *
- * @type {string}
- */
- var PLUGIN_NAME = "line-numbers";
-
- /**
- * Regular expression used for determining line breaks
- *
- * @type {RegExp}
- */
- var NEW_LINE_EXP = /\n(?!$)/g;
-
- /**
- * Global exports
- */
- var config = (Prism.plugins.lineNumbers = {
- /**
- * Get node for provided line number
- *
- * @param {Element} element pre element
- * @param {number} number line number
- * @returns {Element|undefined}
- */
- getLine: function (element, number) {
- if (
- element.tagName !== "PRE" ||
- !element.classList.contains(PLUGIN_NAME)
- ) {
- return;
- }
-
- var lineNumberRows = element.querySelector(".line-numbers-rows");
- if (!lineNumberRows) {
- return;
- }
- var lineNumberStart =
- parseInt(element.getAttribute("data-start"), 10) || 1;
- var lineNumberEnd =
- lineNumberStart + (lineNumberRows.children.length - 1);
-
- if (number < lineNumberStart) {
- number = lineNumberStart;
- }
- if (number > lineNumberEnd) {
- number = lineNumberEnd;
- }
-
- var lineIndex = number - lineNumberStart;
-
- return lineNumberRows.children[lineIndex];
- },
-
- /**
- * Resizes the line numbers of the given element.
- *
- * This function will not add line numbers. It will only resize existing ones.
- *
- * @param {HTMLElement} element A `<pre>` element with line numbers.
- * @returns {void}
- */
- resize: function (element) {
- resizeElements([element]);
- },
-
- /**
- * Whether the plugin can assume that the units font sizes and margins are not depended on the size of
- * the current viewport.
- *
- * Setting this to `true` will allow the plugin to do certain optimizations for better performance.
- *
- * Set this to `false` if you use any of the following CSS units: `vh`, `vw`, `vmin`, `vmax`.
- *
- * @type {boolean}
- */
- assumeViewportIndependence: true,
- });
-
- /**
- * Resizes the given elements.
- *
- * @param {HTMLElement[]} elements
- */
- function resizeElements(elements) {
- elements = elements.filter(function (e) {
- var codeStyles = getStyles(e);
- var whiteSpace = codeStyles["white-space"];
- return whiteSpace === "pre-wrap" || whiteSpace === "pre-line";
- });
-
- if (elements.length == 0) {
- return;
- }
-
- var infos = elements
- .map(function (element) {
- var codeElement = element.querySelector("code");
- var lineNumbersWrapper = element.querySelector(".line-numbers-rows");
- if (!codeElement || !lineNumbersWrapper) {
- return undefined;
- }
-
- /** @type {HTMLElement} */
- var lineNumberSizer = element.querySelector(".line-numbers-sizer");
- var codeLines = codeElement.textContent.split(NEW_LINE_EXP);
-
- if (!lineNumberSizer) {
- lineNumberSizer = document.createElement("span");
- lineNumberSizer.className = "line-numbers-sizer";
-
- codeElement.appendChild(lineNumberSizer);
- }
-
- lineNumberSizer.innerHTML = "0";
- lineNumberSizer.style.display = "block";
-
- var oneLinerHeight = lineNumberSizer.getBoundingClientRect().height;
- lineNumberSizer.innerHTML = "";
-
- return {
- element: element,
- lines: codeLines,
- lineHeights: [],
- oneLinerHeight: oneLinerHeight,
- sizer: lineNumberSizer,
- };
- })
- .filter(Boolean);
-
- infos.forEach(function (info) {
- var lineNumberSizer = info.sizer;
- var lines = info.lines;
- var lineHeights = info.lineHeights;
- var oneLinerHeight = info.oneLinerHeight;
-
- lineHeights[lines.length - 1] = undefined;
- lines.forEach(function (line, index) {
- if (line && line.length > 1) {
- var e = lineNumberSizer.appendChild(document.createElement("span"));
- e.style.display = "block";
- e.textContent = line;
- } else {
- lineHeights[index] = oneLinerHeight;
- }
- });
- });
-
- infos.forEach(function (info) {
- var lineNumberSizer = info.sizer;
- var lineHeights = info.lineHeights;
-
- var childIndex = 0;
- for (var i = 0; i < lineHeights.length; i++) {
- if (lineHeights[i] === undefined) {
- lineHeights[i] =
- lineNumberSizer.children[
- childIndex++
- ].getBoundingClientRect().height;
- }
- }
- });
-
- infos.forEach(function (info) {
- var lineNumberSizer = info.sizer;
- var wrapper = info.element.querySelector(".line-numbers-rows");
-
- lineNumberSizer.style.display = "none";
- lineNumberSizer.innerHTML = "";
-
- info.lineHeights.forEach(function (height, lineNumber) {
- wrapper.children[lineNumber].style.height = height + "px";
- });
- });
- }
-
- /**
- * Returns style declarations for the element
- *
- * @param {Element} element
- */
- function getStyles(element) {
- if (!element) {
- return null;
- }
-
- return window.getComputedStyle
- ? getComputedStyle(element)
- : element.currentStyle || null;
- }
-
- var lastWidth = undefined;
- window.addEventListener("resize", function () {
- if (config.assumeViewportIndependence && lastWidth === window.innerWidth) {
- return;
- }
- lastWidth = window.innerWidth;
-
- resizeElements(
- Array.prototype.slice.call(
- document.querySelectorAll("pre." + PLUGIN_NAME)
- )
- );
- });
-
- Prism.hooks.add("complete", function (env) {
- if (!env.code) {
- return;
- }
-
- var code = /** @type {Element} */ (env.element);
- var pre = /** @type {HTMLElement} */ (code.parentNode);
-
- // works only for <code> wrapped inside <pre> (not inline)
- if (!pre || !/pre/i.test(pre.nodeName)) {
- return;
- }
-
- // Abort if line numbers already exists
- if (code.querySelector(".line-numbers-rows")) {
- return;
- }
-
- // only add line numbers if <code> or one of its ancestors has the `line-numbers` class
- if (!Prism.util.isActive(code, PLUGIN_NAME)) {
- return;
- }
-
- // Remove the class 'line-numbers' from the <code>
- code.classList.remove(PLUGIN_NAME);
- // Add the class 'line-numbers' to the <pre>
- pre.classList.add(PLUGIN_NAME);
-
- var match = env.code.match(NEW_LINE_EXP);
- var linesNum = match ? match.length + 1 : 1;
- var lineNumbersWrapper;
-
- var lines = new Array(linesNum + 1).join("<span></span>");
-
- lineNumbersWrapper = document.createElement("span");
- lineNumbersWrapper.setAttribute("aria-hidden", "true");
- lineNumbersWrapper.className = "line-numbers-rows";
- lineNumbersWrapper.innerHTML = lines;
-
- if (pre.hasAttribute("data-start")) {
- pre.style.counterReset =
- "linenumber " + (parseInt(pre.getAttribute("data-start"), 10) - 1);
- }
-
- env.element.appendChild(lineNumbersWrapper);
-
- resizeElements([pre]);
-
- Prism.hooks.run("line-numbers", env);
- });
-
- Prism.hooks.add("line-numbers", function (env) {
- env.plugins = env.plugins || {};
- env.plugins.lineNumbers = true;
- });
-})();
-
-(function () {
- if (typeof Prism === "undefined" || typeof document === "undefined") {
- return;
- }
-
- /* eslint-disable */
-
- /**
- * The dependencies map is built automatically with gulp.
- *
- * @type {Object<string, string | string[]>}
- */
- var lang_dependencies = /*dependencies_placeholder[*/ {
- javascript: "clike",
- actionscript: "javascript",
- apex: ["clike", "sql"],
- arduino: "cpp",
- aspnet: ["markup", "csharp"],
- birb: "clike",
- bison: "c",
- c: "clike",
- csharp: "clike",
- cpp: "c",
- cfscript: "clike",
- chaiscript: ["clike", "cpp"],
- cilkc: "c",
- cilkcpp: "cpp",
- coffeescript: "javascript",
- crystal: "ruby",
- "css-extras": "css",
- d: "clike",
- dart: "clike",
- django: "markup-templating",
- ejs: ["javascript", "markup-templating"],
- etlua: ["lua", "markup-templating"],
- erb: ["ruby", "markup-templating"],
- fsharp: "clike",
- "firestore-security-rules": "clike",
- flow: "javascript",
- ftl: "markup-templating",
- gml: "clike",
- glsl: "c",
- go: "clike",
- gradle: "clike",
- groovy: "clike",
- haml: "ruby",
- handlebars: "markup-templating",
- haxe: "clike",
- hlsl: "c",
- idris: "haskell",
- java: "clike",
- javadoc: ["markup", "java", "javadoclike"],
- jolie: "clike",
- jsdoc: ["javascript", "javadoclike", "typescript"],
- "js-extras": "javascript",
- json5: "json",
- jsonp: "json",
- "js-templates": "javascript",
- kotlin: "clike",
- latte: ["clike", "markup-templating", "php"],
- less: "css",
- lilypond: "scheme",
- liquid: "markup-templating",
- markdown: "markup",
- "markup-templating": "markup",
- mongodb: "javascript",
- n4js: "javascript",
- objectivec: "c",
- opencl: "c",
- parser: "markup",
- php: "markup-templating",
- phpdoc: ["php", "javadoclike"],
- "php-extras": "php",
- plsql: "sql",
- processing: "clike",
- protobuf: "clike",
- pug: ["markup", "javascript"],
- purebasic: "clike",
- purescript: "haskell",
- qsharp: "clike",
- qml: "javascript",
- qore: "clike",
- racket: "scheme",
- cshtml: ["markup", "csharp"],
- jsx: ["markup", "javascript"],
- tsx: ["jsx", "typescript"],
- reason: "clike",
- ruby: "clike",
- sass: "css",
- scss: "css",
- scala: "java",
- "shell-session": "bash",
- smarty: "markup-templating",
- solidity: "clike",
- soy: "markup-templating",
- sparql: "turtle",
- sqf: "clike",
- squirrel: "clike",
- stata: ["mata", "java", "python"],
- "t4-cs": ["t4-templating", "csharp"],
- "t4-vb": ["t4-templating", "vbnet"],
- tap: "yaml",
- tt2: ["clike", "markup-templating"],
- textile: "markup",
- twig: "markup-templating",
- typescript: "javascript",
- v: "clike",
- vala: "clike",
- vbnet: "basic",
- velocity: "markup",
- wiki: "markup",
- xeora: "markup",
- "xml-doc": "markup",
- xquery: "markup",
- }; /*]*/
-
- var lang_aliases = /*aliases_placeholder[*/ {
- html: "markup",
- xml: "markup",
- svg: "markup",
- mathml: "markup",
- ssml: "markup",
- atom: "markup",
- rss: "markup",
- js: "javascript",
- g4: "antlr4",
- ino: "arduino",
- "arm-asm": "armasm",
- art: "arturo",
- adoc: "asciidoc",
- avs: "avisynth",
- avdl: "avro-idl",
- gawk: "awk",
- sh: "bash",
- shell: "bash",
- shortcode: "bbcode",
- rbnf: "bnf",
- oscript: "bsl",
- cs: "csharp",
- dotnet: "csharp",
- cfc: "cfscript",
- "cilk-c": "cilkc",
- "cilk-cpp": "cilkcpp",
- cilk: "cilkcpp",
- coffee: "coffeescript",
- conc: "concurnas",
- jinja2: "django",
- "dns-zone": "dns-zone-file",
- dockerfile: "docker",
- gv: "dot",
- eta: "ejs",
- xlsx: "excel-formula",
- xls: "excel-formula",
- gamemakerlanguage: "gml",
- po: "gettext",
- gni: "gn",
- ld: "linker-script",
- "go-mod": "go-module",
- hbs: "handlebars",
- mustache: "handlebars",
- hs: "haskell",
- idr: "idris",
- gitignore: "ignore",
- hgignore: "ignore",
- npmignore: "ignore",
- webmanifest: "json",
- kt: "kotlin",
- kts: "kotlin",
- kum: "kumir",
- tex: "latex",
- context: "latex",
- ly: "lilypond",
- emacs: "lisp",
- elisp: "lisp",
- "emacs-lisp": "lisp",
- md: "markdown",
- moon: "moonscript",
- n4jsd: "n4js",
- nani: "naniscript",
- objc: "objectivec",
- qasm: "openqasm",
- objectpascal: "pascal",
- px: "pcaxis",
- pcode: "peoplecode",
- plantuml: "plant-uml",
- pq: "powerquery",
- mscript: "powerquery",
- pbfasm: "purebasic",
- purs: "purescript",
- py: "python",
- qs: "qsharp",
- rkt: "racket",
- razor: "cshtml",
- rpy: "renpy",
- res: "rescript",
- robot: "robotframework",
- rb: "ruby",
- "sh-session": "shell-session",
- shellsession: "shell-session",
- smlnj: "sml",
- sol: "solidity",
- sln: "solution-file",
- rq: "sparql",
- sclang: "supercollider",
- t4: "t4-cs",
- trickle: "tremor",
- troy: "tremor",
- trig: "turtle",
- ts: "typescript",
- tsconfig: "typoscript",
- uscript: "unrealscript",
- uc: "unrealscript",
- url: "uri",
- vb: "visual-basic",
- vba: "visual-basic",
- webidl: "web-idl",
- mathematica: "wolfram",
- nb: "wolfram",
- wl: "wolfram",
- xeoracube: "xeora",
- yml: "yaml",
- }; /*]*/
-
- /* eslint-enable */
-
- /**
- * @typedef LangDataItem
- * @property {{ success?: () => void, error?: () => void }[]} callbacks
- * @property {boolean} [error]
- * @property {boolean} [loading]
- */
- /** @type {Object<string, LangDataItem>} */
- var lang_data = {};
-
- var ignored_language = "none";
- var languages_path = "/public/assets/prism/components/";
-
- var script = Prism.util.currentScript();
- /*if (script) {
- var autoloaderFile =
- /\bplugins\/autoloader\/prism-autoloader\.(?:min\.)?js(?:\?[^\r\n/]*)?$/i;
- var prismFile = /(^|\/)[\w-]+\.(?:min\.)?js(?:\?[^\r\n/]*)?$/i;
-
- var autoloaderPath = script.getAttribute("data-autoloader-path");
- if (autoloaderPath != null) {
- // data-autoloader-path is set, so just use it
- languages_path = autoloaderPath.trim().replace(/\/?$/, "/");
- } else {
- var src = script.src;
- if (autoloaderFile.test(src)) {
- // the script is the original autoloader script in the usual Prism project structure
- languages_path = src.replace(autoloaderFile, "components/");
- } else if (prismFile.test(src)) {
- // the script is part of a bundle like a custom prism.js from the download page
- languages_path = src.replace(prismFile, "$1components/");
- }
- }
- }*/
-
- var config = (Prism.plugins.autoloader = {
- languages_path: languages_path,
- use_minified: true,
- loadLanguages: loadLanguages,
- });
-
- /**
- * Lazily loads an external script.
- *
- * @param {string} src
- * @param {() => void} [success]
- * @param {() => void} [error]
- */
- function addScript(src, success, error) {
- var s = document.createElement("script");
- s.src = src;
- s.async = true;
- s.onload = function () {
- document.body.removeChild(s);
- success && success();
- };
- s.onerror = function () {
- document.body.removeChild(s);
- error && error();
- };
- document.body.appendChild(s);
- }
-
- /**
- * Returns all additional dependencies of the given element defined by the `data-dependencies` attribute.
- *
- * @param {Element} element
- * @returns {string[]}
- */
- function getDependencies(element) {
- var deps = (element.getAttribute("data-dependencies") || "").trim();
- if (!deps) {
- var parent = element.parentElement;
- if (parent && parent.tagName.toLowerCase() === "pre") {
- deps = (parent.getAttribute("data-dependencies") || "").trim();
- }
- }
- return deps ? deps.split(/\s*,\s*/g) : [];
- }
-
- /**
- * Returns whether the given language is currently loaded.
- *
- * @param {string} lang
- * @returns {boolean}
- */
- function isLoaded(lang) {
- if (lang.indexOf("!") >= 0) {
- // forced reload
- return false;
- }
-
- lang = lang_aliases[lang] || lang; // resolve alias
-
- if (lang in Prism.languages) {
- // the given language is already loaded
- return true;
- }
-
- // this will catch extensions like CSS extras that don't add a grammar to Prism.languages
- var data = lang_data[lang];
- return data && !data.error && data.loading === false;
- }
-
- /**
- * Returns the path to a grammar, using the language_path and use_minified config keys.
- *
- * @param {string} lang
- * @returns {string}
- */
- function getLanguagePath(lang) {
- return (
- config.languages_path +
- "prism-" +
- lang +
- (config.use_minified ? ".min" : "") +
- ".js"
- );
- }
-
- /**
- * Loads all given grammars concurrently.
- *
- * @param {string[]|string} languages
- * @param {(languages: string[]) => void} [success]
- * @param {(language: string) => void} [error] This callback will be invoked on the first language to fail.
- */
- function loadLanguages(languages, success, error) {
- if (typeof languages === "string") {
- languages = [languages];
- }
-
- var total = languages.length;
- var completed = 0;
- var failed = false;
-
- if (total === 0) {
- if (success) {
- setTimeout(success, 0);
- }
- return;
- }
-
- function successCallback() {
- if (failed) {
- return;
- }
- completed++;
- if (completed === total) {
- success && success(languages);
- }
- }
-
- languages.forEach(function (lang) {
- loadLanguage(lang, successCallback, function () {
- if (failed) {
- return;
- }
- failed = true;
- error && error(lang);
- });
- });
- }
-
- /**
- * Loads a grammar with its dependencies.
- *
- * @param {string} lang
- * @param {() => void} [success]
- * @param {() => void} [error]
- */
- function loadLanguage(lang, success, error) {
- var force = lang.indexOf("!") >= 0;
-
- lang = lang.replace("!", "");
- lang = lang_aliases[lang] || lang;
-
- function load() {
- var data = lang_data[lang];
- if (!data) {
- data = lang_data[lang] = {
- callbacks: [],
- };
- }
- data.callbacks.push({
- success: success,
- error: error,
- });
-
- if (!force && isLoaded(lang)) {
- // the language is already loaded and we aren't forced to reload
- languageCallback(lang, "success");
- } else if (!force && data.error) {
- // the language failed to load before and we don't reload
- languageCallback(lang, "error");
- } else if (force || !data.loading) {
- // the language isn't currently loading and/or we are forced to reload
- data.loading = true;
- data.error = false;
-
- addScript(
- getLanguagePath(lang),
- function () {
- data.loading = false;
- languageCallback(lang, "success");
- },
- function () {
- data.loading = false;
- data.error = true;
- languageCallback(lang, "error");
- }
- );
- }
- }
-
- var dependencies = lang_dependencies[lang];
- if (dependencies && dependencies.length) {
- loadLanguages(dependencies, load, error);
- } else {
- load();
- }
- }
-
- /**
- * Runs all callbacks of the given type for the given language.
- *
- * @param {string} lang
- * @param {"success" | "error"} type
- */
- function languageCallback(lang, type) {
- if (lang_data[lang]) {
- var callbacks = lang_data[lang].callbacks;
- for (var i = 0, l = callbacks.length; i < l; i++) {
- var callback = callbacks[i][type];
- if (callback) {
- setTimeout(callback, 0);
- }
- }
- callbacks.length = 0;
- }
- }
-
- Prism.hooks.add("complete", function (env) {
- var element = env.element;
- var language = env.language;
- if (!element || !language || language === ignored_language) {
- return;
- }
-
- var deps = getDependencies(element);
- if (/^diff-./i.test(language)) {
- // the "diff-xxxx" format is used by the Diff Highlight plugin
- deps.push("diff");
- deps.push(language.substr("diff-".length));
- } else {
- deps.push(language);
- }
-
- if (!deps.every(isLoaded)) {
- // the language or some dependencies aren't loaded
- loadLanguages(deps, function () {
- Prism.highlightElement(element);
- });
- }
- });
-})();
-
-(function () {
- if (typeof Prism === "undefined") {
- return;
- }
-
- var assign =
- Object.assign ||
- function (obj1, obj2) {
- for (var name in obj2) {
- if (obj2.hasOwnProperty(name)) {
- obj1[name] = obj2[name];
- }
- }
- return obj1;
- };
-
- function NormalizeWhitespace(defaults) {
- this.defaults = assign({}, defaults);
- }
-
- function toCamelCase(value) {
- return value.replace(/-(\w)/g, function (match, firstChar) {
- return firstChar.toUpperCase();
- });
- }
-
- function tabLen(str) {
- var res = 0;
- for (var i = 0; i < str.length; ++i) {
- if (str.charCodeAt(i) == "\t".charCodeAt(0)) {
- res += 3;
- }
- }
- return str.length + res;
- }
-
- var settingsConfig = {
- "remove-trailing": "boolean",
- "remove-indent": "boolean",
- "left-trim": "boolean",
- "right-trim": "boolean",
- "break-lines": "number",
- indent: "number",
- "remove-initial-line-feed": "boolean",
- "tabs-to-spaces": "number",
- "spaces-to-tabs": "number",
- };
-
- NormalizeWhitespace.prototype = {
- setDefaults: function (defaults) {
- this.defaults = assign(this.defaults, defaults);
- },
- normalize: function (input, settings) {
- settings = assign(this.defaults, settings);
-
- for (var name in settings) {
- var methodName = toCamelCase(name);
- if (
- name !== "normalize" &&
- methodName !== "setDefaults" &&
- settings[name] &&
- this[methodName]
- ) {
- input = this[methodName].call(this, input, settings[name]);
- }
- }
-
- return input;
- },
-
- /*
- * Normalization methods
- */
- leftTrim: function (input) {
- return input.replace(/^\s+/, "");
- },
- rightTrim: function (input) {
- return input.replace(/\s+$/, "");
- },
- tabsToSpaces: function (input, spaces) {
- spaces = spaces | 0 || 4;
- return input.replace(/\t/g, new Array(++spaces).join(" "));
- },
- spacesToTabs: function (input, spaces) {
- spaces = spaces | 0 || 4;
- return input.replace(RegExp(" {" + spaces + "}", "g"), "\t");
- },
- removeTrailing: function (input) {
- return input.replace(/\s*?$/gm, "");
- },
- // Support for deprecated plugin remove-initial-line-feed
- removeInitialLineFeed: function (input) {
- return input.replace(/^(?:\r?\n|\r)/, "");
- },
- removeIndent: function (input) {
- var indents = input.match(/^[^\S\n\r]*(?=\S)/gm);
-
- if (!indents || !indents[0].length) {
- return input;
- }
-
- indents.sort(function (a, b) {
- return a.length - b.length;
- });
-
- if (!indents[0].length) {
- return input;
- }
-
- return input.replace(RegExp("^" + indents[0], "gm"), "");
- },
- indent: function (input, tabs) {
- return input.replace(
- /^[^\S\n\r]*(?=\S)/gm,
- new Array(++tabs).join("\t") + "$&"
- );
- },
- breakLines: function (input, characters) {
- characters = characters === true ? 80 : characters | 0 || 80;
-
- var lines = input.split("\n");
- for (var i = 0; i < lines.length; ++i) {
- if (tabLen(lines[i]) <= characters) {
- continue;
- }
-
- var line = lines[i].split(/(\s+)/g);
- var len = 0;
-
- for (var j = 0; j < line.length; ++j) {
- var tl = tabLen(line[j]);
- len += tl;
- if (len > characters) {
- line[j] = "\n" + line[j];
- len = tl;
- }
- }
- lines[i] = line.join("");
- }
- return lines.join("\n");
- },
- };
-
- // Support node modules
- if (typeof module !== "undefined" && module.exports) {
- module.exports = NormalizeWhitespace;
- }
-
- Prism.plugins.NormalizeWhitespace = new NormalizeWhitespace({
- "remove-trailing": true,
- "remove-indent": true,
- "left-trim": true,
- "right-trim": true,
- /*'break-lines': 80,
- 'indent': 2,
- 'remove-initial-line-feed': false,
- 'tabs-to-spaces': 4,
- 'spaces-to-tabs': 4*/
- });
-
- Prism.hooks.add("before-sanity-check", function (env) {
- var Normalizer = Prism.plugins.NormalizeWhitespace;
-
- // Check settings
- if (env.settings && env.settings["whitespace-normalization"] === false) {
- return;
- }
-
- // Check classes
- if (!Prism.util.isActive(env.element, "whitespace-normalization", true)) {
- return;
- }
-
- // Simple mode if there is no env.element
- if ((!env.element || !env.element.parentNode) && env.code) {
- env.code = Normalizer.normalize(env.code, env.settings);
- return;
- }
-
- // Normal mode
- var pre = env.element.parentNode;
- if (!env.code || !pre || pre.nodeName.toLowerCase() !== "pre") {
- return;
- }
-
- if (env.settings == null) {
- env.settings = {};
- }
-
- // Read settings from 'data-' attributes
- for (var key in settingsConfig) {
- if (Object.hasOwnProperty.call(settingsConfig, key)) {
- var settingType = settingsConfig[key];
- if (pre.hasAttribute("data-" + key)) {
- try {
- var value = JSON.parse(pre.getAttribute("data-" + key) || "true");
- if (typeof value === settingType) {
- env.settings[key] = value;
- }
- } catch (_error) {
- // ignore error
- }
- }
- }
- }
-
- var children = pre.childNodes;
- var before = "";
- var after = "";
- var codeFound = false;
-
- // Move surrounding whitespace from the <pre> tag into the <code> tag
- for (var i = 0; i < children.length; ++i) {
- var node = children[i];
-
- if (node == env.element) {
- codeFound = true;
- } else if (node.nodeName === "#text") {
- if (codeFound) {
- after += node.nodeValue;
- } else {
- before += node.nodeValue;
- }
-
- pre.removeChild(node);
- --i;
- }
- }
-
- if (!env.element.children.length || !Prism.plugins.KeepMarkup) {
- env.code = before + env.code + after;
- env.code = Normalizer.normalize(env.code, env.settings);
- } else {
- // Preserve markup for keep-markup plugin
- var html = before + env.element.innerHTML + after;
- env.element.innerHTML = Normalizer.normalize(html, env.settings);
- env.code = env.element.textContent;
- }
- });
-})();
-
-(function () {
- if (typeof Prism === "undefined") {
- return;
- }
-
- var LANGUAGE_REGEX = /^diff-([\w-]+)/i;
- var HTML_TAG =
- /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/g;
- //this will match a line plus the line break while ignoring the line breaks HTML tags may contain.
- var HTML_LINE = RegExp(
- /(?:__|[^\r\n<])*(?:\r\n?|\n|(?:__|[^\r\n<])(?![^\r\n]))/.source.replace(
- /__/g,
- function () {
- return HTML_TAG.source;
- }
- ),
- "gi"
- );
-
- var warningLogged = false;
-
- Prism.hooks.add("before-sanity-check", function (env) {
- var lang = env.language;
- if (LANGUAGE_REGEX.test(lang) && !env.grammar) {
- env.grammar = Prism.languages[lang] = Prism.languages.diff;
- }
- });
- Prism.hooks.add("before-tokenize", function (env) {
- if (!warningLogged && !Prism.languages.diff && !Prism.plugins.autoloader) {
- warningLogged = true;
- console.warn(
- "Prism's Diff Highlight plugin requires the Diff language definition (prism-diff.js)." +
- "Make sure the language definition is loaded or use Prism's Autoloader plugin."
- );
- }
-
- var lang = env.language;
- if (LANGUAGE_REGEX.test(lang) && !Prism.languages[lang]) {
- Prism.languages[lang] = Prism.languages.diff;
- }
- });
-
- Prism.hooks.add("wrap", function (env) {
- var diffLanguage;
- var diffGrammar;
-
- if (env.language !== "diff") {
- var langMatch = LANGUAGE_REGEX.exec(env.language);
- if (!langMatch) {
- return; // not a language specific diff
- }
-
- diffLanguage = langMatch[1];
- diffGrammar = Prism.languages[diffLanguage];
- }
-
- var PREFIXES = Prism.languages.diff && Prism.languages.diff.PREFIXES;
-
- // one of the diff tokens without any nested tokens
- if (PREFIXES && env.type in PREFIXES) {
- /** @type {string} */
- var content = env.content.replace(HTML_TAG, ""); // remove all HTML tags
-
- /** @type {string} */
- var decoded = content.replace(/</g, "<").replace(/&/g, "&");
-
- // remove any one-character prefix
- var code = decoded.replace(/(^|[\r\n])./g, "$1");
-
- // highlight, if possible
- var highlighted;
- if (diffGrammar) {
- highlighted = Prism.highlight(code, diffGrammar, diffLanguage);
- } else {
- highlighted = Prism.util.encode(code);
- }
-
- // get the HTML source of the prefix token
- var prefixToken = new Prism.Token("prefix", PREFIXES[env.type], [
- /\w+/.exec(env.type)[0],
- ]);
- var prefix = Prism.Token.stringify(prefixToken, env.language);
-
- // add prefix
- var lines = [];
- var m;
- HTML_LINE.lastIndex = 0;
- while ((m = HTML_LINE.exec(highlighted))) {
- lines.push(prefix + m[0]);
- }
- if (/(?:^|[\r\n]).$/.test(decoded)) {
- // because both "+a\n+" and "+a\n" will map to "a\n" after the line prefixes are removed
- lines.push(prefix);
- }
- env.content = lines.join("");
-
- if (diffGrammar) {
- env.classes.push("language-" + diffLanguage);
- }
- }
- });
-})();
@@ -0,0 +1,2 @@
+var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(e){var t=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,n=0,r={},a={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(t){return t instanceof i?new i(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++n}),e.__id},clone:function e(t,n){var r,i;switch(n=n||{},a.util.type(t)){case"Object":if(i=a.util.objId(t),n[i])return n[i];for(var s in r={},n[i]=r,t)t.hasOwnProperty(s)&&(r[s]=e(t[s],n));return r;case"Array":return i=a.util.objId(t),n[i]?n[i]:(r=[],n[i]=r,t.forEach(function(t,a){r[a]=e(t,n)}),r);default:return t}},getLanguage:function(e){for(;e;){var n=t.exec(e.className);if(n)return n[1].toLowerCase();e=e.parentElement}return"none"},setLanguage:function(e,n){e.className=e.className.replace(RegExp(t,"gi"),""),e.classList.add("language-"+n)},currentScript:function(){if("undefined"==typeof document)return null;if("currentScript"in document)return document.currentScript;try{throw new Error}catch(r){var e=(/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(r.stack)||[])[1];if(e){var t=document.getElementsByTagName("script");for(var n in t)if(t[n].src==e)return t[n]}return null}},isActive:function(e,t,n){for(var r="no-"+t;e;){var a=e.classList;if(a.contains(t))return!0;if(a.contains(r))return!1;e=e.parentElement}return!!n}},languages:{plain:r,plaintext:r,text:r,txt:r,extend:function(e,t){var n=a.util.clone(a.languages[e]);for(var r in t)n[r]=t[r];return n},insertBefore:function(e,t,n,r){var i=(r=r||a.languages)[e],s={};for(var l in i)if(i.hasOwnProperty(l)){if(l==t)for(var o in n)n.hasOwnProperty(o)&&(s[o]=n[o]);n.hasOwnProperty(l)||(s[l]=i[l])}var u=r[e];return r[e]=s,a.languages.DFS(a.languages,function(t,n){n===u&&t!=e&&(this[t]=s)}),s},DFS:function e(t,n,r,i){i=i||{};var s=a.util.objId;for(var l in t)if(t.hasOwnProperty(l)){n.call(t,l,t[l],r||l);var o=t[l],u=a.util.type(o);"Object"!==u||i[s(o)]?"Array"!==u||i[s(o)]||(i[s(o)]=!0,e(o,n,l,i)):(i[s(o)]=!0,e(o,n,null,i))}}},plugins:{},highlightAll:function(e,t){a.highlightAllUnder(document,e,t)},highlightAllUnder:function(e,t,n){var r={callback:n,container:e,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};a.hooks.run("before-highlightall",r),r.elements=Array.prototype.slice.apply(r.container.querySelectorAll(r.selector)),a.hooks.run("before-all-elements-highlight",r);for(var i,s=0;i=r.elements[s++];)a.highlightElement(i,!0===t,r.callback)},highlightElement:function(t,n,r){var i=a.util.getLanguage(t),s=a.languages[i];a.util.setLanguage(t,i);var l=t.parentElement;l&&"pre"===l.nodeName.toLowerCase()&&a.util.setLanguage(l,i);var o={element:t,language:i,grammar:s,code:t.textContent};function u(e){o.highlightedCode=e,a.hooks.run("before-insert",o),o.element.innerHTML=o.highlightedCode,a.hooks.run("after-highlight",o),a.hooks.run("complete",o),r&&r.call(o.element)}if(a.hooks.run("before-sanity-check",o),(l=o.element.parentElement)&&"pre"===l.nodeName.toLowerCase()&&!l.hasAttribute("tabindex")&&l.setAttribute("tabindex","0"),!o.code)return a.hooks.run("complete",o),void(r&&r.call(o.element));if(a.hooks.run("before-highlight",o),o.grammar)if(n&&e.Worker){var c=new Worker(a.filename);c.onmessage=function(e){u(e.data)},c.postMessage(JSON.stringify({language:o.language,code:o.code,immediateClose:!0}))}else u(a.highlight(o.code,o.grammar,o.language));else u(a.util.encode(o.code))},highlight:function(e,t,n){var r={code:e,grammar:t,language:n};if(a.hooks.run("before-tokenize",r),!r.grammar)throw new Error('The language "'+r.language+'" has no grammar.');return r.tokens=a.tokenize(r.code,r.grammar),a.hooks.run("after-tokenize",r),i.stringify(a.util.encode(r.tokens),r.language)},tokenize:function(e,t){var n=t.rest;if(n){for(var r in n)t[r]=n[r];delete t.rest}var u=new function(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0};return l(u,u.head,e),function e(t,n,r,u,c,p){for(var g in r)if(r.hasOwnProperty(g)&&r[g]){var d=r[g];d=Array.isArray(d)?d:[d];for(var m=0;m<d.length;++m){if(p&&p.cause==g+","+m)return;var f=d[m],h=f.inside,v=!!f.lookbehind,b=!!f.greedy,k=f.alias;if(b&&!f.pattern.global){var y=f.pattern.toString().match(/[imsuy]*$/)[0];f.pattern=RegExp(f.pattern.source,y+"g")}for(var x=f.pattern||f,w=u.next,P=c;w!==n.tail&&!(p&&P>=p.reach);P+=w.value.length,w=w.next){var F=w.value;if(n.length>t.length)return;if(!(F instanceof i)){var A,j=1;if(b){if(!(A=s(x,P,t,v))||A.index>=t.length)break;var S=A.index,$=A.index+A[0].length,E=P;for(E+=w.value.length;S>=E;)w=w.next,E+=w.value.length;if(E-=w.value.length,P=E,w.value instanceof i)continue;for(var C=w;C!==n.tail&&(E<$||"string"==typeof C.value);C=C.next)j++,E+=C.value.length;j--,F=t.slice(P,E),A.index-=P}else if(!(A=s(x,0,F,v)))continue;var S=A.index,L=A[0],z=F.slice(0,S),_=F.slice(S+L.length),T=P+F.length;p&&T>p.reach&&(p.reach=T);var q=w.prev;z&&(q=l(n,q,z),P+=z.length),o(n,q,j);var N=new i(g,h?a.tokenize(L,h):L,k,L);if(w=l(n,q,N),_&&l(n,w,_),j>1){var O={cause:g+","+m,reach:T};e(t,n,r,w.prev,P,O),p&&O.reach>p.reach&&(p.reach=O.reach)}}}}}}(e,u,t,u.head,0),function(e){var t=[],n=e.head.next;for(;n!==e.tail;)t.push(n.value),n=n.next;return t}(u)},hooks:{all:{},add:function(e,t){var n=a.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=a.hooks.all[e];if(n&&n.length)for(var r,i=0;r=n[i++];)r(t)}},Token:i};function i(e,t,n,r){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length}function s(e,t,n,r){e.lastIndex=t;var a=e.exec(n);if(a&&r&&a[1]){var i=a[1].length;a.index+=i,a[0]=a[0].slice(i)}return a}function l(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function o(e,t,n){for(var r=t.next,a=0;a<n&&r!==e.tail;a++)r=r.next;t.next=r,r.prev=t,e.length-=a}if(e.Prism=a,i.stringify=function e(t,n){if("string"==typeof t)return t;if(Array.isArray(t)){var r="";return t.forEach(function(t){r+=e(t,n)}),r}var i={type:t.type,content:e(t.content,n),tag:"span",classes:["token",t.type],attributes:{},language:n},s=t.alias;s&&(Array.isArray(s)?Array.prototype.push.apply(i.classes,s):i.classes.push(s)),a.hooks.run("wrap",i);var l="";for(var o in i.attributes)l+=" "+o+'="'+(i.attributes[o]||"").replace(/"/g,""")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'"'+l+">"+i.content+"</"+i.tag+">"},!e.document)return e.addEventListener?(a.disableWorkerMessageHandler||e.addEventListener("message",function(t){var n=JSON.parse(t.data),r=n.language,i=n.code,s=n.immediateClose;e.postMessage(a.highlight(i,a.languages[r],r)),s&&e.close()},!1),a):a;var u=a.util.currentScript();function c(){a.manual||a.highlightAll()}if(u&&(a.filename=u.src,u.hasAttribute("data-manual")&&(a.manual=!0)),!a.manual){var p=document.readyState;"loading"===p||"interactive"===p&&u&&u.defer?document.addEventListener("DOMContentLoaded",c):window.requestAnimationFrame?window.requestAnimationFrame(c):window.setTimeout(c,16)}return a}(_self);
+"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism),Prism.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))}),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:Prism.languages[t]},n.cdata=/^<!\[CDATA\[|\]\]>$/i;var r={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:Prism.languages[t]};var a={};a[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,function(){return e}),"i"),lookbehind:!0,greedy:!0,inside:r},Prism.languages.insertBefore("markup","cdata",a)}}),Object.defineProperty(Prism.languages.markup.tag,"addAttribute",{value:function(e,t){Prism.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:Prism.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml,function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:"+/[^;{\s"']|\s+(?!\s)/.source+"|"+t.source+")*?"+/(?:;|(?=\s*\{))/.source),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(Prism),Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:Prism.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),Prism.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),Prism.languages.markup&&(Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),Prism.languages.js=Prism.languages.javascript,function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach(function(n){var r=t[n],a=[];/^\w+$/.test(n)||a.push(/\w+/.exec(n)[0]),"diff"===n&&a.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:a,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}}),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(Prism),function(){if(void 0!==Prism&&"undefined"!=typeof document&&document.querySelector){var e,t="linkable-line-numbers",n=/\n(?!$)/g,r=function(){if(void 0===e){var t=document.createElement("div");t.style.fontSize="13px",t.style.lineHeight="1.5",t.style.padding="0",t.style.border="0",t.innerHTML=" <br /> ",document.body.appendChild(t),e=38===t.offsetHeight,document.body.removeChild(t)}return e},a=!0;Prism.plugins.lineHighlight={highlightLines:function(e,i,u){var c=(i="string"==typeof i?i:e.getAttribute("data-line")||"").replace(/\s+/g,"").split(",").filter(Boolean),p=+e.getAttribute("data-line-offset")||0,g=(r()?parseInt:parseFloat)(getComputedStyle(e).lineHeight),d=Prism.util.isActive(e,"line-numbers"),m=e.querySelector("code"),f=d?e:m||e,h=[],v=m.textContent.match(n),b=v?v.length+1:1,k=m&&f!=m?function(e,t){var n=getComputedStyle(e),r=getComputedStyle(t);function a(e){return+e.substr(0,e.length-2)}return t.offsetTop+a(r.borderTopWidth)+a(r.paddingTop)-a(n.paddingTop)}(e,m):0;c.forEach(function(t){var n=t.split("-"),r=+n[0],a=+n[1]||r;if(!((a=Math.min(b+p,a))<r)){var i=e.querySelector('.line-highlight[data-range="'+t+'"]')||document.createElement("div");if(h.push(function(){i.setAttribute("aria-hidden","true"),i.setAttribute("data-range",t),i.className=(u||"")+" line-highlight"}),d&&Prism.plugins.lineNumbers){var s=Prism.plugins.lineNumbers.getLine(e,r),l=Prism.plugins.lineNumbers.getLine(e,a);if(s){var o=s.offsetTop+k+"px";h.push(function(){i.style.top=o})}if(l){var c=l.offsetTop-s.offsetTop+l.offsetHeight+"px";h.push(function(){i.style.height=c})}}else h.push(function(){i.setAttribute("data-start",String(r)),a>r&&i.setAttribute("data-end",String(a)),i.style.top=(r-p-1)*g+k+"px",i.textContent=new Array(a-r+2).join(" \n")});h.push(function(){i.style.width=e.scrollWidth+"px"}),h.push(function(){f.appendChild(i)})}});var y=e.id;if(d&&Prism.util.isActive(e,t)&&y){l(e,t)||h.push(function(){e.classList.add(t)});var x=parseInt(e.getAttribute("data-start")||"1");s(".line-numbers-rows > span",e).forEach(function(e,t){var n=t+x;e.onclick=function(){var e=y+"."+n;a=!1,location.hash=e,setTimeout(function(){a=!0},1)}})}return function(){h.forEach(o)}}};var i=0;Prism.hooks.add("before-sanity-check",function(e){var t=e.element.parentElement;if(u(t)){var n=0;s(".line-highlight",t).forEach(function(e){n+=e.textContent.length,e.parentNode.removeChild(e)}),n&&/^(?: \n)+$/.test(e.code.slice(-n))&&(e.code=e.code.slice(0,-n))}}),Prism.hooks.add("complete",function e(t){var n=t.element.parentElement;if(u(n)){clearTimeout(i);var r=Prism.plugins.lineNumbers,a=t.plugins&&t.plugins.lineNumbers;if(l(n,"line-numbers")&&r&&!a)Prism.hooks.add("line-numbers",e);else Prism.plugins.lineHighlight.highlightLines(n)(),i=setTimeout(c,1)}}),window.addEventListener("hashchange",c),window.addEventListener("resize",function(){s("pre").filter(u).map(function(e){return Prism.plugins.lineHighlight.highlightLines(e)}).forEach(o)})}function s(e,t){return Array.prototype.slice.call((t||document).querySelectorAll(e))}function l(e,t){return e.classList.contains(t)}function o(e){e()}function u(e){return!(!e||!/pre/i.test(e.nodeName))&&(!!e.hasAttribute("data-line")||!(!e.id||!Prism.util.isActive(e,t)))}function c(){var e=location.hash.slice(1);s(".temporary.line-highlight").forEach(function(e){e.parentNode.removeChild(e)});var t=(e.match(/\.([\d,-]+)$/)||[,""])[1];if(t&&!document.getElementById(e)){var n=e.slice(0,e.lastIndexOf(".")),r=document.getElementById(n);if(r)r.hasAttribute("data-line")||r.setAttribute("data-line",""),Prism.plugins.lineHighlight.highlightLines(r,t,"temporary ")(),a&&document.querySelector(".temporary.line-highlight").scrollIntoView()}}}(),function(){if(void 0!==Prism&&"undefined"!=typeof document){var e=/\n(?!$)/g,t=Prism.plugins.lineNumbers={getLine:function(e,t){if("PRE"===e.tagName&&e.classList.contains("line-numbers")){var n=e.querySelector(".line-numbers-rows");if(n){var r=parseInt(e.getAttribute("data-start"),10)||1,a=r+(n.children.length-1);t<r&&(t=r),t>a&&(t=a);var i=t-r;return n.children[i]}}},resize:function(e){r([e])},assumeViewportIndependence:!0},n=void 0;window.addEventListener("resize",function(){t.assumeViewportIndependence&&n===window.innerWidth||(n=window.innerWidth,r(Array.prototype.slice.call(document.querySelectorAll("pre.line-numbers"))))}),Prism.hooks.add("complete",function(t){if(t.code){var n=t.element,a=n.parentNode;if(a&&/pre/i.test(a.nodeName)&&!n.querySelector(".line-numbers-rows")&&Prism.util.isActive(n,"line-numbers")){n.classList.remove("line-numbers"),a.classList.add("line-numbers");var i,s=t.code.match(e),l=s?s.length+1:1,o=new Array(l+1).join("<span></span>");(i=document.createElement("span")).setAttribute("aria-hidden","true"),i.className="line-numbers-rows",i.innerHTML=o,a.hasAttribute("data-start")&&(a.style.counterReset="linenumber "+(parseInt(a.getAttribute("data-start"),10)-1)),t.element.appendChild(i),r([a]),Prism.hooks.run("line-numbers",t)}}}),Prism.hooks.add("line-numbers",function(e){e.plugins=e.plugins||{},e.plugins.lineNumbers=!0})}function r(t){if(0!=(t=t.filter(function(e){var t=function(e){if(!e)return null;return window.getComputedStyle?getComputedStyle(e):e.currentStyle||null}(e)["white-space"];return"pre-wrap"===t||"pre-line"===t})).length){var n=t.map(function(t){var n=t.querySelector("code"),r=t.querySelector(".line-numbers-rows");if(n&&r){var a=t.querySelector(".line-numbers-sizer"),i=n.textContent.split(e);a||((a=document.createElement("span")).className="line-numbers-sizer",n.appendChild(a)),a.innerHTML="0",a.style.display="block";var s=a.getBoundingClientRect().height;return a.innerHTML="",{element:t,lines:i,lineHeights:[],oneLinerHeight:s,sizer:a}}}).filter(Boolean);n.forEach(function(e){var t=e.sizer,n=e.lines,r=e.lineHeights,a=e.oneLinerHeight;r[n.length-1]=void 0,n.forEach(function(e,n){if(e&&e.length>1){var i=t.appendChild(document.createElement("span"));i.style.display="block",i.textContent=e}else r[n]=a})}),n.forEach(function(e){for(var t=e.sizer,n=e.lineHeights,r=0,a=0;a<n.length;a++)void 0===n[a]&&(n[a]=t.children[r++].getBoundingClientRect().height)}),n.forEach(function(e){var t=e.sizer,n=e.element.querySelector(".line-numbers-rows");t.style.display="none",t.innerHTML="",e.lineHeights.forEach(function(e,t){n.children[t].style.height=e+"px"})})}}}(),function(){if(void 0!==Prism&&"undefined"!=typeof document){var e={javascript:"clike",actionscript:"javascript",apex:["clike","sql"],arduino:"cpp",aspnet:["markup","csharp"],birb:"clike",bison:"c",c:"clike",csharp:"clike",cpp:"c",cfscript:"clike",chaiscript:["clike","cpp"],cilkc:"c",cilkcpp:"cpp",coffeescript:"javascript",crystal:"ruby","css-extras":"css",d:"clike",dart:"clike",django:"markup-templating",ejs:["javascript","markup-templating"],etlua:["lua","markup-templating"],erb:["ruby","markup-templating"],fsharp:"clike","firestore-security-rules":"clike",flow:"javascript",ftl:"markup-templating",gml:"clike",glsl:"c",go:"clike",gradle:"clike",groovy:"clike",haml:"ruby",handlebars:"markup-templating",haxe:"clike",hlsl:"c",idris:"haskell",java:"clike",javadoc:["markup","java","javadoclike"],jolie:"clike",jsdoc:["javascript","javadoclike","typescript"],"js-extras":"javascript",json5:"json",jsonp:"json","js-templates":"javascript",kotlin:"clike",latte:["clike","markup-templating","php"],less:"css",lilypond:"scheme",liquid:"markup-templating",markdown:"markup","markup-templating":"markup",mongodb:"javascript",n4js:"javascript",objectivec:"c",opencl:"c",parser:"markup",php:"markup-templating",phpdoc:["php","javadoclike"],"php-extras":"php",plsql:"sql",processing:"clike",protobuf:"clike",pug:["markup","javascript"],purebasic:"clike",purescript:"haskell",qsharp:"clike",qml:"javascript",qore:"clike",racket:"scheme",cshtml:["markup","csharp"],jsx:["markup","javascript"],tsx:["jsx","typescript"],reason:"clike",ruby:"clike",sass:"css",scss:"css",scala:"java","shell-session":"bash",smarty:"markup-templating",solidity:"clike",soy:"markup-templating",sparql:"turtle",sqf:"clike",squirrel:"clike",stata:["mata","java","python"],"t4-cs":["t4-templating","csharp"],"t4-vb":["t4-templating","vbnet"],tap:"yaml",tt2:["clike","markup-templating"],textile:"markup",twig:"markup-templating",typescript:"javascript",v:"clike",vala:"clike",vbnet:"basic",velocity:"markup",wiki:"markup",xeora:"markup","xml-doc":"markup",xquery:"markup"},t={html:"markup",xml:"markup",svg:"markup",mathml:"markup",ssml:"markup",atom:"markup",rss:"markup",js:"javascript",g4:"antlr4",ino:"arduino","arm-asm":"armasm",art:"arturo",adoc:"asciidoc",avs:"avisynth",avdl:"avro-idl",gawk:"awk",sh:"bash",shell:"bash",shortcode:"bbcode",rbnf:"bnf",oscript:"bsl",cs:"csharp",dotnet:"csharp",cfc:"cfscript","cilk-c":"cilkc","cilk-cpp":"cilkcpp",cilk:"cilkcpp",coffee:"coffeescript",conc:"concurnas",jinja2:"django","dns-zone":"dns-zone-file",dockerfile:"docker",gv:"dot",eta:"ejs",xlsx:"excel-formula",xls:"excel-formula",gamemakerlanguage:"gml",po:"gettext",gni:"gn",ld:"linker-script","go-mod":"go-module",hbs:"handlebars",mustache:"handlebars",hs:"haskell",idr:"idris",gitignore:"ignore",hgignore:"ignore",npmignore:"ignore",webmanifest:"json",kt:"kotlin",kts:"kotlin",kum:"kumir",tex:"latex",context:"latex",ly:"lilypond",emacs:"lisp",elisp:"lisp","emacs-lisp":"lisp",md:"markdown",moon:"moonscript",n4jsd:"n4js",nani:"naniscript",objc:"objectivec",qasm:"openqasm",objectpascal:"pascal",px:"pcaxis",pcode:"peoplecode",plantuml:"plant-uml",pq:"powerquery",mscript:"powerquery",pbfasm:"purebasic",purs:"purescript",py:"python",qs:"qsharp",rkt:"racket",razor:"cshtml",rpy:"renpy",res:"rescript",robot:"robotframework",rb:"ruby","sh-session":"shell-session",shellsession:"shell-session",smlnj:"sml",sol:"solidity",sln:"solution-file",rq:"sparql",sclang:"supercollider",t4:"t4-cs",trickle:"tremor",troy:"tremor",trig:"turtle",ts:"typescript",tsconfig:"typoscript",uscript:"unrealscript",uc:"unrealscript",url:"uri",vb:"visual-basic",vba:"visual-basic",webidl:"web-idl",mathematica:"wolfram",nb:"wolfram",wl:"wolfram",xeoracube:"xeora",yml:"yaml"},n={},r=(Prism.util.currentScript(),Prism.plugins.autoloader={languages_path:"/public/assets/prism/components/",use_minified:!0,loadLanguages:i});Prism.hooks.add("complete",function(e){var t=e.element,n=e.language;if(t&&n&&"none"!==n){var r=function(e){var t=(e.getAttribute("data-dependencies")||"").trim();if(!t){var n=e.parentElement;n&&"pre"===n.tagName.toLowerCase()&&(t=(n.getAttribute("data-dependencies")||"").trim())}return t?t.split(/\s*,\s*/g):[]}(t);/^diff-./i.test(n)?(r.push("diff"),r.push(n.substr("diff-".length))):r.push(n),r.every(a)||i(r,function(){Prism.highlightElement(t)})}})}function a(e){if(e.indexOf("!")>=0)return!1;if((e=t[e]||e)in Prism.languages)return!0;var r=n[e];return r&&!r.error&&!1===r.loading}function i(l,o,u){"string"==typeof l&&(l=[l]);var c=l.length,p=0,g=!1;function d(){g||++p===c&&o&&o(l)}0!==c?l.forEach(function(l){!function(l,o,u){var c=l.indexOf("!")>=0;function p(){var e=n[l];e||(e=n[l]={callbacks:[]}),e.callbacks.push({success:o,error:u}),!c&&a(l)?s(l,"success"):!c&&e.error?s(l,"error"):!c&&e.loading||(e.loading=!0,e.error=!1,function(e,t,n){var r=document.createElement("script");r.src=e,r.async=!0,r.onload=function(){document.body.removeChild(r),t&&t()},r.onerror=function(){document.body.removeChild(r),n&&n()},document.body.appendChild(r)}(function(e){return r.languages_path+"prism-"+e+(r.use_minified?".min":"")+".js"}(l),function(){e.loading=!1,s(l,"success")},function(){e.loading=!1,e.error=!0,s(l,"error")}))}l=l.replace("!",""),l=t[l]||l;var g=e[l];g&&g.length?i(g,p,u):p()}(l,d,function(){g||(g=!0,u&&u(l))})}):o&&setTimeout(o,0)}function s(e,t){if(n[e]){for(var r=n[e].callbacks,a=0,i=r.length;a<i;a++){var s=r[a][t];s&&setTimeout(s,0)}r.length=0}}}(),function(){if(void 0!==Prism){var e=Object.assign||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e},t={"remove-trailing":"boolean","remove-indent":"boolean","left-trim":"boolean","right-trim":"boolean","break-lines":"number",indent:"number","remove-initial-line-feed":"boolean","tabs-to-spaces":"number","spaces-to-tabs":"number"};n.prototype={setDefaults:function(t){this.defaults=e(this.defaults,t)},normalize:function(t,n){for(var r in n=e(this.defaults,n)){var a=r.replace(/-(\w)/g,function(e,t){return t.toUpperCase()});"normalize"!==r&&"setDefaults"!==a&&n[r]&&this[a]&&(t=this[a].call(this,t,n[r]))}return t},leftTrim:function(e){return e.replace(/^\s+/,"")},rightTrim:function(e){return e.replace(/\s+$/,"")},tabsToSpaces:function(e,t){return t=0|t||4,e.replace(/\t/g,new Array(++t).join(" "))},spacesToTabs:function(e,t){return t=0|t||4,e.replace(RegExp(" {"+t+"}","g"),"\t")},removeTrailing:function(e){return e.replace(/\s*?$/gm,"")},removeInitialLineFeed:function(e){return e.replace(/^(?:\r?\n|\r)/,"")},removeIndent:function(e){var t=e.match(/^[^\S\n\r]*(?=\S)/gm);return t&&t[0].length?(t.sort(function(e,t){return e.length-t.length}),t[0].length?e.replace(RegExp("^"+t[0],"gm"),""):e):e},indent:function(e,t){return e.replace(/^[^\S\n\r]*(?=\S)/gm,new Array(++t).join("\t")+"$&")},breakLines:function(e,t){t=!0===t?80:0|t||80;for(var n=e.split("\n"),a=0;a<n.length;++a)if(!(r(n[a])<=t)){for(var i=n[a].split(/(\s+)/g),s=0,l=0;l<i.length;++l){var o=r(i[l]);(s+=o)>t&&(i[l]="\n"+i[l],s=o)}n[a]=i.join("")}return n.join("\n")}},"undefined"!=typeof module&&module.exports&&(module.exports=n),Prism.plugins.NormalizeWhitespace=new n({"remove-trailing":!0,"remove-indent":!0,"left-trim":!0,"right-trim":!0}),Prism.hooks.add("before-sanity-check",function(e){var n=Prism.plugins.NormalizeWhitespace;if((!e.settings||!1!==e.settings["whitespace-normalization"])&&Prism.util.isActive(e.element,"whitespace-normalization",!0))if(e.element&&e.element.parentNode||!e.code){var r=e.element.parentNode;if(e.code&&r&&"pre"===r.nodeName.toLowerCase()){for(var a in null==e.settings&&(e.settings={}),t)if(Object.hasOwnProperty.call(t,a)){var i=t[a];if(r.hasAttribute("data-"+a))try{var s=JSON.parse(r.getAttribute("data-"+a)||"true");typeof s===i&&(e.settings[a]=s)}catch(e){}}for(var l=r.childNodes,o="",u="",c=!1,p=0;p<l.length;++p){var g=l[p];g==e.element?c=!0:"#text"===g.nodeName&&(c?u+=g.nodeValue:o+=g.nodeValue,r.removeChild(g),--p)}if(e.element.children.length&&Prism.plugins.KeepMarkup){var d=o+e.element.innerHTML+u;e.element.innerHTML=n.normalize(d,e.settings),e.code=e.element.textContent}else e.code=o+e.code+u,e.code=n.normalize(e.code,e.settings)}}else e.code=n.normalize(e.code,e.settings)})}function n(t){this.defaults=e({},t)}function r(e){for(var t=0,n=0;n<e.length;++n)e.charCodeAt(n)=="\t".charCodeAt(0)&&(t+=3);return e.length+t}}(),function(){if(void 0!==Prism){var e=/^diff-([\w-]+)/i,t=/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/g,n=RegExp(/(?:__|[^\r\n<])*(?:\r\n?|\n|(?:__|[^\r\n<])(?![^\r\n]))/.source.replace(/__/g,function(){return t.source}),"gi"),r=!1;Prism.hooks.add("before-sanity-check",function(t){var n=t.language;e.test(n)&&!t.grammar&&(t.grammar=Prism.languages[n]=Prism.languages.diff)}),Prism.hooks.add("before-tokenize",function(t){r||Prism.languages.diff||Prism.plugins.autoloader||(r=!0,console.warn("Prism's Diff Highlight plugin requires the Diff language definition (prism-diff.js).Make sure the language definition is loaded or use Prism's Autoloader plugin."));var n=t.language;e.test(n)&&!Prism.languages[n]&&(Prism.languages[n]=Prism.languages.diff)}),Prism.hooks.add("wrap",function(r){var a,i;if("diff"!==r.language){var s=e.exec(r.language);if(!s)return;a=s[1],i=Prism.languages[a]}var l=Prism.languages.diff&&Prism.languages.diff.PREFIXES;if(l&&r.type in l){var o,u=r.content.replace(t,"").replace(/</g,"<").replace(/&/g,"&"),c=u.replace(/(^|[\r\n])./g,"$1");o=i?Prism.highlight(c,i,a):Prism.util.encode(c);var p,g=new Prism.Token("prefix",l[r.type],[/\w+/.exec(r.type)[0]]),d=Prism.Token.stringify(g,r.language),m=[];for(n.lastIndex=0;p=n.exec(o);)m.push(d+p[0]);/(?:^|[\r\n]).$/.test(u)&&m.push(d),r.content=m.join(""),i&&r.classes.push("language-"+a)}})}}();
@@ -1,2 +0,0 @@
-var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(e){var t=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,n=0,r={},a={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(t){return t instanceof i?new i(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++n}),e.__id},clone:function e(t,n){var r,i;switch(n=n||{},a.util.type(t)){case"Object":if(i=a.util.objId(t),n[i])return n[i];for(var s in r={},n[i]=r,t)t.hasOwnProperty(s)&&(r[s]=e(t[s],n));return r;case"Array":return i=a.util.objId(t),n[i]?n[i]:(r=[],n[i]=r,t.forEach(function(t,a){r[a]=e(t,n)}),r);default:return t}},getLanguage:function(e){for(;e;){var n=t.exec(e.className);if(n)return n[1].toLowerCase();e=e.parentElement}return"none"},setLanguage:function(e,n){e.className=e.className.replace(RegExp(t,"gi"),""),e.classList.add("language-"+n)},currentScript:function(){if("undefined"==typeof document)return null;if("currentScript"in document)return document.currentScript;try{throw new Error}catch(r){var e=(/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(r.stack)||[])[1];if(e){var t=document.getElementsByTagName("script");for(var n in t)if(t[n].src==e)return t[n]}return null}},isActive:function(e,t,n){for(var r="no-"+t;e;){var a=e.classList;if(a.contains(t))return!0;if(a.contains(r))return!1;e=e.parentElement}return!!n}},languages:{plain:r,plaintext:r,text:r,txt:r,extend:function(e,t){var n=a.util.clone(a.languages[e]);for(var r in t)n[r]=t[r];return n},insertBefore:function(e,t,n,r){var i=(r=r||a.languages)[e],s={};for(var l in i)if(i.hasOwnProperty(l)){if(l==t)for(var o in n)n.hasOwnProperty(o)&&(s[o]=n[o]);n.hasOwnProperty(l)||(s[l]=i[l])}var u=r[e];return r[e]=s,a.languages.DFS(a.languages,function(t,n){n===u&&t!=e&&(this[t]=s)}),s},DFS:function e(t,n,r,i){i=i||{};var s=a.util.objId;for(var l in t)if(t.hasOwnProperty(l)){n.call(t,l,t[l],r||l);var o=t[l],u=a.util.type(o);"Object"!==u||i[s(o)]?"Array"!==u||i[s(o)]||(i[s(o)]=!0,e(o,n,l,i)):(i[s(o)]=!0,e(o,n,null,i))}}},plugins:{},highlightAll:function(e,t){a.highlightAllUnder(document,e,t)},highlightAllUnder:function(e,t,n){var r={callback:n,container:e,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};a.hooks.run("before-highlightall",r),r.elements=Array.prototype.slice.apply(r.container.querySelectorAll(r.selector)),a.hooks.run("before-all-elements-highlight",r);for(var i,s=0;i=r.elements[s++];)a.highlightElement(i,!0===t,r.callback)},highlightElement:function(t,n,r){var i=a.util.getLanguage(t),s=a.languages[i];a.util.setLanguage(t,i);var l=t.parentElement;l&&"pre"===l.nodeName.toLowerCase()&&a.util.setLanguage(l,i);var o={element:t,language:i,grammar:s,code:t.textContent};function u(e){o.highlightedCode=e,a.hooks.run("before-insert",o),o.element.innerHTML=o.highlightedCode,a.hooks.run("after-highlight",o),a.hooks.run("complete",o),r&&r.call(o.element)}if(a.hooks.run("before-sanity-check",o),(l=o.element.parentElement)&&"pre"===l.nodeName.toLowerCase()&&!l.hasAttribute("tabindex")&&l.setAttribute("tabindex","0"),!o.code)return a.hooks.run("complete",o),void(r&&r.call(o.element));if(a.hooks.run("before-highlight",o),o.grammar)if(n&&e.Worker){var c=new Worker(a.filename);c.onmessage=function(e){u(e.data)},c.postMessage(JSON.stringify({language:o.language,code:o.code,immediateClose:!0}))}else u(a.highlight(o.code,o.grammar,o.language));else u(a.util.encode(o.code))},highlight:function(e,t,n){var r={code:e,grammar:t,language:n};if(a.hooks.run("before-tokenize",r),!r.grammar)throw new Error('The language "'+r.language+'" has no grammar.');return r.tokens=a.tokenize(r.code,r.grammar),a.hooks.run("after-tokenize",r),i.stringify(a.util.encode(r.tokens),r.language)},tokenize:function(e,t){var n=t.rest;if(n){for(var r in n)t[r]=n[r];delete t.rest}var u=new function(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0};return l(u,u.head,e),function e(t,n,r,u,c,p){for(var g in r)if(r.hasOwnProperty(g)&&r[g]){var d=r[g];d=Array.isArray(d)?d:[d];for(var m=0;m<d.length;++m){if(p&&p.cause==g+","+m)return;var f=d[m],h=f.inside,v=!!f.lookbehind,b=!!f.greedy,k=f.alias;if(b&&!f.pattern.global){var y=f.pattern.toString().match(/[imsuy]*$/)[0];f.pattern=RegExp(f.pattern.source,y+"g")}for(var x=f.pattern||f,w=u.next,P=c;w!==n.tail&&!(p&&P>=p.reach);P+=w.value.length,w=w.next){var F=w.value;if(n.length>t.length)return;if(!(F instanceof i)){var A,j=1;if(b){if(!(A=s(x,P,t,v))||A.index>=t.length)break;var S=A.index,$=A.index+A[0].length,E=P;for(E+=w.value.length;S>=E;)w=w.next,E+=w.value.length;if(E-=w.value.length,P=E,w.value instanceof i)continue;for(var C=w;C!==n.tail&&(E<$||"string"==typeof C.value);C=C.next)j++,E+=C.value.length;j--,F=t.slice(P,E),A.index-=P}else if(!(A=s(x,0,F,v)))continue;var S=A.index,L=A[0],z=F.slice(0,S),_=F.slice(S+L.length),T=P+F.length;p&&T>p.reach&&(p.reach=T);var q=w.prev;z&&(q=l(n,q,z),P+=z.length),o(n,q,j);var N=new i(g,h?a.tokenize(L,h):L,k,L);if(w=l(n,q,N),_&&l(n,w,_),j>1){var O={cause:g+","+m,reach:T};e(t,n,r,w.prev,P,O),p&&O.reach>p.reach&&(p.reach=O.reach)}}}}}}(e,u,t,u.head,0),function(e){var t=[],n=e.head.next;for(;n!==e.tail;)t.push(n.value),n=n.next;return t}(u)},hooks:{all:{},add:function(e,t){var n=a.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=a.hooks.all[e];if(n&&n.length)for(var r,i=0;r=n[i++];)r(t)}},Token:i};function i(e,t,n,r){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length}function s(e,t,n,r){e.lastIndex=t;var a=e.exec(n);if(a&&r&&a[1]){var i=a[1].length;a.index+=i,a[0]=a[0].slice(i)}return a}function l(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function o(e,t,n){for(var r=t.next,a=0;a<n&&r!==e.tail;a++)r=r.next;t.next=r,r.prev=t,e.length-=a}if(e.Prism=a,i.stringify=function e(t,n){if("string"==typeof t)return t;if(Array.isArray(t)){var r="";return t.forEach(function(t){r+=e(t,n)}),r}var i={type:t.type,content:e(t.content,n),tag:"span",classes:["token",t.type],attributes:{},language:n},s=t.alias;s&&(Array.isArray(s)?Array.prototype.push.apply(i.classes,s):i.classes.push(s)),a.hooks.run("wrap",i);var l="";for(var o in i.attributes)l+=" "+o+'="'+(i.attributes[o]||"").replace(/"/g,""")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'"'+l+">"+i.content+"</"+i.tag+">"},!e.document)return e.addEventListener?(a.disableWorkerMessageHandler||e.addEventListener("message",function(t){var n=JSON.parse(t.data),r=n.language,i=n.code,s=n.immediateClose;e.postMessage(a.highlight(i,a.languages[r],r)),s&&e.close()},!1),a):a;var u=a.util.currentScript();function c(){a.manual||a.highlightAll()}if(u&&(a.filename=u.src,u.hasAttribute("data-manual")&&(a.manual=!0)),!a.manual){var p=document.readyState;"loading"===p||"interactive"===p&&u&&u.defer?document.addEventListener("DOMContentLoaded",c):window.requestAnimationFrame?window.requestAnimationFrame(c):window.setTimeout(c,16)}return a}(_self);
-"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism),Prism.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))}),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:Prism.languages[t]},n.cdata=/^<!\[CDATA\[|\]\]>$/i;var r={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:Prism.languages[t]};var a={};a[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,function(){return e}),"i"),lookbehind:!0,greedy:!0,inside:r},Prism.languages.insertBefore("markup","cdata",a)}}),Object.defineProperty(Prism.languages.markup.tag,"addAttribute",{value:function(e,t){Prism.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:Prism.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml,function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:"+/[^;{\s"']|\s+(?!\s)/.source+"|"+t.source+")*?"+/(?:;|(?=\s*\{))/.source),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(Prism),Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:Prism.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),Prism.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),Prism.languages.markup&&(Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),Prism.languages.js=Prism.languages.javascript,function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach(function(n){var r=t[n],a=[];/^\w+$/.test(n)||a.push(/\w+/.exec(n)[0]),"diff"===n&&a.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:a,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}}),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(Prism),function(){if(void 0!==Prism&&"undefined"!=typeof document&&document.querySelector){var e,t="linkable-line-numbers",n=/\n(?!$)/g,r=function(){if(void 0===e){var t=document.createElement("div");t.style.fontSize="13px",t.style.lineHeight="1.5",t.style.padding="0",t.style.border="0",t.innerHTML=" <br /> ",document.body.appendChild(t),e=38===t.offsetHeight,document.body.removeChild(t)}return e},a=!0;Prism.plugins.lineHighlight={highlightLines:function(e,i,u){var c=(i="string"==typeof i?i:e.getAttribute("data-line")||"").replace(/\s+/g,"").split(",").filter(Boolean),p=+e.getAttribute("data-line-offset")||0,g=(r()?parseInt:parseFloat)(getComputedStyle(e).lineHeight),d=Prism.util.isActive(e,"line-numbers"),m=e.querySelector("code"),f=d?e:m||e,h=[],v=m.textContent.match(n),b=v?v.length+1:1,k=m&&f!=m?function(e,t){var n=getComputedStyle(e),r=getComputedStyle(t);function a(e){return+e.substr(0,e.length-2)}return t.offsetTop+a(r.borderTopWidth)+a(r.paddingTop)-a(n.paddingTop)}(e,m):0;c.forEach(function(t){var n=t.split("-"),r=+n[0],a=+n[1]||r;if(!((a=Math.min(b+p,a))<r)){var i=e.querySelector('.line-highlight[data-range="'+t+'"]')||document.createElement("div");if(h.push(function(){i.setAttribute("aria-hidden","true"),i.setAttribute("data-range",t),i.className=(u||"")+" line-highlight"}),d&&Prism.plugins.lineNumbers){var s=Prism.plugins.lineNumbers.getLine(e,r),l=Prism.plugins.lineNumbers.getLine(e,a);if(s){var o=s.offsetTop+k+"px";h.push(function(){i.style.top=o})}if(l){var c=l.offsetTop-s.offsetTop+l.offsetHeight+"px";h.push(function(){i.style.height=c})}}else h.push(function(){i.setAttribute("data-start",String(r)),a>r&&i.setAttribute("data-end",String(a)),i.style.top=(r-p-1)*g+k+"px",i.textContent=new Array(a-r+2).join(" \n")});h.push(function(){i.style.width=e.scrollWidth+"px"}),h.push(function(){f.appendChild(i)})}});var y=e.id;if(d&&Prism.util.isActive(e,t)&&y){l(e,t)||h.push(function(){e.classList.add(t)});var x=parseInt(e.getAttribute("data-start")||"1");s(".line-numbers-rows > span",e).forEach(function(e,t){var n=t+x;e.onclick=function(){var e=y+"."+n;a=!1,location.hash=e,setTimeout(function(){a=!0},1)}})}return function(){h.forEach(o)}}};var i=0;Prism.hooks.add("before-sanity-check",function(e){var t=e.element.parentElement;if(u(t)){var n=0;s(".line-highlight",t).forEach(function(e){n+=e.textContent.length,e.parentNode.removeChild(e)}),n&&/^(?: \n)+$/.test(e.code.slice(-n))&&(e.code=e.code.slice(0,-n))}}),Prism.hooks.add("complete",function e(t){var n=t.element.parentElement;if(u(n)){clearTimeout(i);var r=Prism.plugins.lineNumbers,a=t.plugins&&t.plugins.lineNumbers;if(l(n,"line-numbers")&&r&&!a)Prism.hooks.add("line-numbers",e);else Prism.plugins.lineHighlight.highlightLines(n)(),i=setTimeout(c,1)}}),window.addEventListener("hashchange",c),window.addEventListener("resize",function(){s("pre").filter(u).map(function(e){return Prism.plugins.lineHighlight.highlightLines(e)}).forEach(o)})}function s(e,t){return Array.prototype.slice.call((t||document).querySelectorAll(e))}function l(e,t){return e.classList.contains(t)}function o(e){e()}function u(e){return!(!e||!/pre/i.test(e.nodeName))&&(!!e.hasAttribute("data-line")||!(!e.id||!Prism.util.isActive(e,t)))}function c(){var e=location.hash.slice(1);s(".temporary.line-highlight").forEach(function(e){e.parentNode.removeChild(e)});var t=(e.match(/\.([\d,-]+)$/)||[,""])[1];if(t&&!document.getElementById(e)){var n=e.slice(0,e.lastIndexOf(".")),r=document.getElementById(n);if(r)r.hasAttribute("data-line")||r.setAttribute("data-line",""),Prism.plugins.lineHighlight.highlightLines(r,t,"temporary ")(),a&&document.querySelector(".temporary.line-highlight").scrollIntoView()}}}(),function(){if(void 0!==Prism&&"undefined"!=typeof document){var e=/\n(?!$)/g,t=Prism.plugins.lineNumbers={getLine:function(e,t){if("PRE"===e.tagName&&e.classList.contains("line-numbers")){var n=e.querySelector(".line-numbers-rows");if(n){var r=parseInt(e.getAttribute("data-start"),10)||1,a=r+(n.children.length-1);t<r&&(t=r),t>a&&(t=a);var i=t-r;return n.children[i]}}},resize:function(e){r([e])},assumeViewportIndependence:!0},n=void 0;window.addEventListener("resize",function(){t.assumeViewportIndependence&&n===window.innerWidth||(n=window.innerWidth,r(Array.prototype.slice.call(document.querySelectorAll("pre.line-numbers"))))}),Prism.hooks.add("complete",function(t){if(t.code){var n=t.element,a=n.parentNode;if(a&&/pre/i.test(a.nodeName)&&!n.querySelector(".line-numbers-rows")&&Prism.util.isActive(n,"line-numbers")){n.classList.remove("line-numbers"),a.classList.add("line-numbers");var i,s=t.code.match(e),l=s?s.length+1:1,o=new Array(l+1).join("<span></span>");(i=document.createElement("span")).setAttribute("aria-hidden","true"),i.className="line-numbers-rows",i.innerHTML=o,a.hasAttribute("data-start")&&(a.style.counterReset="linenumber "+(parseInt(a.getAttribute("data-start"),10)-1)),t.element.appendChild(i),r([a]),Prism.hooks.run("line-numbers",t)}}}),Prism.hooks.add("line-numbers",function(e){e.plugins=e.plugins||{},e.plugins.lineNumbers=!0})}function r(t){if(0!=(t=t.filter(function(e){var t=function(e){if(!e)return null;return window.getComputedStyle?getComputedStyle(e):e.currentStyle||null}(e)["white-space"];return"pre-wrap"===t||"pre-line"===t})).length){var n=t.map(function(t){var n=t.querySelector("code"),r=t.querySelector(".line-numbers-rows");if(n&&r){var a=t.querySelector(".line-numbers-sizer"),i=n.textContent.split(e);a||((a=document.createElement("span")).className="line-numbers-sizer",n.appendChild(a)),a.innerHTML="0",a.style.display="block";var s=a.getBoundingClientRect().height;return a.innerHTML="",{element:t,lines:i,lineHeights:[],oneLinerHeight:s,sizer:a}}}).filter(Boolean);n.forEach(function(e){var t=e.sizer,n=e.lines,r=e.lineHeights,a=e.oneLinerHeight;r[n.length-1]=void 0,n.forEach(function(e,n){if(e&&e.length>1){var i=t.appendChild(document.createElement("span"));i.style.display="block",i.textContent=e}else r[n]=a})}),n.forEach(function(e){for(var t=e.sizer,n=e.lineHeights,r=0,a=0;a<n.length;a++)void 0===n[a]&&(n[a]=t.children[r++].getBoundingClientRect().height)}),n.forEach(function(e){var t=e.sizer,n=e.element.querySelector(".line-numbers-rows");t.style.display="none",t.innerHTML="",e.lineHeights.forEach(function(e,t){n.children[t].style.height=e+"px"})})}}}(),function(){if(void 0!==Prism&&"undefined"!=typeof document){var e={javascript:"clike",actionscript:"javascript",apex:["clike","sql"],arduino:"cpp",aspnet:["markup","csharp"],birb:"clike",bison:"c",c:"clike",csharp:"clike",cpp:"c",cfscript:"clike",chaiscript:["clike","cpp"],cilkc:"c",cilkcpp:"cpp",coffeescript:"javascript",crystal:"ruby","css-extras":"css",d:"clike",dart:"clike",django:"markup-templating",ejs:["javascript","markup-templating"],etlua:["lua","markup-templating"],erb:["ruby","markup-templating"],fsharp:"clike","firestore-security-rules":"clike",flow:"javascript",ftl:"markup-templating",gml:"clike",glsl:"c",go:"clike",gradle:"clike",groovy:"clike",haml:"ruby",handlebars:"markup-templating",haxe:"clike",hlsl:"c",idris:"haskell",java:"clike",javadoc:["markup","java","javadoclike"],jolie:"clike",jsdoc:["javascript","javadoclike","typescript"],"js-extras":"javascript",json5:"json",jsonp:"json","js-templates":"javascript",kotlin:"clike",latte:["clike","markup-templating","php"],less:"css",lilypond:"scheme",liquid:"markup-templating",markdown:"markup","markup-templating":"markup",mongodb:"javascript",n4js:"javascript",objectivec:"c",opencl:"c",parser:"markup",php:"markup-templating",phpdoc:["php","javadoclike"],"php-extras":"php",plsql:"sql",processing:"clike",protobuf:"clike",pug:["markup","javascript"],purebasic:"clike",purescript:"haskell",qsharp:"clike",qml:"javascript",qore:"clike",racket:"scheme",cshtml:["markup","csharp"],jsx:["markup","javascript"],tsx:["jsx","typescript"],reason:"clike",ruby:"clike",sass:"css",scss:"css",scala:"java","shell-session":"bash",smarty:"markup-templating",solidity:"clike",soy:"markup-templating",sparql:"turtle",sqf:"clike",squirrel:"clike",stata:["mata","java","python"],"t4-cs":["t4-templating","csharp"],"t4-vb":["t4-templating","vbnet"],tap:"yaml",tt2:["clike","markup-templating"],textile:"markup",twig:"markup-templating",typescript:"javascript",v:"clike",vala:"clike",vbnet:"basic",velocity:"markup",wiki:"markup",xeora:"markup","xml-doc":"markup",xquery:"markup"},t={html:"markup",xml:"markup",svg:"markup",mathml:"markup",ssml:"markup",atom:"markup",rss:"markup",js:"javascript",g4:"antlr4",ino:"arduino","arm-asm":"armasm",art:"arturo",adoc:"asciidoc",avs:"avisynth",avdl:"avro-idl",gawk:"awk",sh:"bash",shell:"bash",shortcode:"bbcode",rbnf:"bnf",oscript:"bsl",cs:"csharp",dotnet:"csharp",cfc:"cfscript","cilk-c":"cilkc","cilk-cpp":"cilkcpp",cilk:"cilkcpp",coffee:"coffeescript",conc:"concurnas",jinja2:"django","dns-zone":"dns-zone-file",dockerfile:"docker",gv:"dot",eta:"ejs",xlsx:"excel-formula",xls:"excel-formula",gamemakerlanguage:"gml",po:"gettext",gni:"gn",ld:"linker-script","go-mod":"go-module",hbs:"handlebars",mustache:"handlebars",hs:"haskell",idr:"idris",gitignore:"ignore",hgignore:"ignore",npmignore:"ignore",webmanifest:"json",kt:"kotlin",kts:"kotlin",kum:"kumir",tex:"latex",context:"latex",ly:"lilypond",emacs:"lisp",elisp:"lisp","emacs-lisp":"lisp",md:"markdown",moon:"moonscript",n4jsd:"n4js",nani:"naniscript",objc:"objectivec",qasm:"openqasm",objectpascal:"pascal",px:"pcaxis",pcode:"peoplecode",plantuml:"plant-uml",pq:"powerquery",mscript:"powerquery",pbfasm:"purebasic",purs:"purescript",py:"python",qs:"qsharp",rkt:"racket",razor:"cshtml",rpy:"renpy",res:"rescript",robot:"robotframework",rb:"ruby","sh-session":"shell-session",shellsession:"shell-session",smlnj:"sml",sol:"solidity",sln:"solution-file",rq:"sparql",sclang:"supercollider",t4:"t4-cs",trickle:"tremor",troy:"tremor",trig:"turtle",ts:"typescript",tsconfig:"typoscript",uscript:"unrealscript",uc:"unrealscript",url:"uri",vb:"visual-basic",vba:"visual-basic",webidl:"web-idl",mathematica:"wolfram",nb:"wolfram",wl:"wolfram",xeoracube:"xeora",yml:"yaml"},n={},r=(Prism.util.currentScript(),Prism.plugins.autoloader={languages_path:"/public/assets/prism/components/",use_minified:!0,loadLanguages:i});Prism.hooks.add("complete",function(e){var t=e.element,n=e.language;if(t&&n&&"none"!==n){var r=function(e){var t=(e.getAttribute("data-dependencies")||"").trim();if(!t){var n=e.parentElement;n&&"pre"===n.tagName.toLowerCase()&&(t=(n.getAttribute("data-dependencies")||"").trim())}return t?t.split(/\s*,\s*/g):[]}(t);/^diff-./i.test(n)?(r.push("diff"),r.push(n.substr("diff-".length))):r.push(n),r.every(a)||i(r,function(){Prism.highlightElement(t)})}})}function a(e){if(e.indexOf("!")>=0)return!1;if((e=t[e]||e)in Prism.languages)return!0;var r=n[e];return r&&!r.error&&!1===r.loading}function i(l,o,u){"string"==typeof l&&(l=[l]);var c=l.length,p=0,g=!1;function d(){g||++p===c&&o&&o(l)}0!==c?l.forEach(function(l){!function(l,o,u){var c=l.indexOf("!")>=0;function p(){var e=n[l];e||(e=n[l]={callbacks:[]}),e.callbacks.push({success:o,error:u}),!c&&a(l)?s(l,"success"):!c&&e.error?s(l,"error"):!c&&e.loading||(e.loading=!0,e.error=!1,function(e,t,n){var r=document.createElement("script");r.src=e,r.async=!0,r.onload=function(){document.body.removeChild(r),t&&t()},r.onerror=function(){document.body.removeChild(r),n&&n()},document.body.appendChild(r)}(function(e){return r.languages_path+"prism-"+e+(r.use_minified?".min":"")+".js"}(l),function(){e.loading=!1,s(l,"success")},function(){e.loading=!1,e.error=!0,s(l,"error")}))}l=l.replace("!",""),l=t[l]||l;var g=e[l];g&&g.length?i(g,p,u):p()}(l,d,function(){g||(g=!0,u&&u(l))})}):o&&setTimeout(o,0)}function s(e,t){if(n[e]){for(var r=n[e].callbacks,a=0,i=r.length;a<i;a++){var s=r[a][t];s&&setTimeout(s,0)}r.length=0}}}(),function(){if(void 0!==Prism){var e=Object.assign||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e},t={"remove-trailing":"boolean","remove-indent":"boolean","left-trim":"boolean","right-trim":"boolean","break-lines":"number",indent:"number","remove-initial-line-feed":"boolean","tabs-to-spaces":"number","spaces-to-tabs":"number"};n.prototype={setDefaults:function(t){this.defaults=e(this.defaults,t)},normalize:function(t,n){for(var r in n=e(this.defaults,n)){var a=r.replace(/-(\w)/g,function(e,t){return t.toUpperCase()});"normalize"!==r&&"setDefaults"!==a&&n[r]&&this[a]&&(t=this[a].call(this,t,n[r]))}return t},leftTrim:function(e){return e.replace(/^\s+/,"")},rightTrim:function(e){return e.replace(/\s+$/,"")},tabsToSpaces:function(e,t){return t=0|t||4,e.replace(/\t/g,new Array(++t).join(" "))},spacesToTabs:function(e,t){return t=0|t||4,e.replace(RegExp(" {"+t+"}","g"),"\t")},removeTrailing:function(e){return e.replace(/\s*?$/gm,"")},removeInitialLineFeed:function(e){return e.replace(/^(?:\r?\n|\r)/,"")},removeIndent:function(e){var t=e.match(/^[^\S\n\r]*(?=\S)/gm);return t&&t[0].length?(t.sort(function(e,t){return e.length-t.length}),t[0].length?e.replace(RegExp("^"+t[0],"gm"),""):e):e},indent:function(e,t){return e.replace(/^[^\S\n\r]*(?=\S)/gm,new Array(++t).join("\t")+"$&")},breakLines:function(e,t){t=!0===t?80:0|t||80;for(var n=e.split("\n"),a=0;a<n.length;++a)if(!(r(n[a])<=t)){for(var i=n[a].split(/(\s+)/g),s=0,l=0;l<i.length;++l){var o=r(i[l]);(s+=o)>t&&(i[l]="\n"+i[l],s=o)}n[a]=i.join("")}return n.join("\n")}},"undefined"!=typeof module&&module.exports&&(module.exports=n),Prism.plugins.NormalizeWhitespace=new n({"remove-trailing":!0,"remove-indent":!0,"left-trim":!0,"right-trim":!0}),Prism.hooks.add("before-sanity-check",function(e){var n=Prism.plugins.NormalizeWhitespace;if((!e.settings||!1!==e.settings["whitespace-normalization"])&&Prism.util.isActive(e.element,"whitespace-normalization",!0))if(e.element&&e.element.parentNode||!e.code){var r=e.element.parentNode;if(e.code&&r&&"pre"===r.nodeName.toLowerCase()){for(var a in null==e.settings&&(e.settings={}),t)if(Object.hasOwnProperty.call(t,a)){var i=t[a];if(r.hasAttribute("data-"+a))try{var s=JSON.parse(r.getAttribute("data-"+a)||"true");typeof s===i&&(e.settings[a]=s)}catch(e){}}for(var l=r.childNodes,o="",u="",c=!1,p=0;p<l.length;++p){var g=l[p];g==e.element?c=!0:"#text"===g.nodeName&&(c?u+=g.nodeValue:o+=g.nodeValue,r.removeChild(g),--p)}if(e.element.children.length&&Prism.plugins.KeepMarkup){var d=o+e.element.innerHTML+u;e.element.innerHTML=n.normalize(d,e.settings),e.code=e.element.textContent}else e.code=o+e.code+u,e.code=n.normalize(e.code,e.settings)}}else e.code=n.normalize(e.code,e.settings)})}function n(t){this.defaults=e({},t)}function r(e){for(var t=0,n=0;n<e.length;++n)e.charCodeAt(n)=="\t".charCodeAt(0)&&(t+=3);return e.length+t}}(),function(){if(void 0!==Prism){var e=/^diff-([\w-]+)/i,t=/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/g,n=RegExp(/(?:__|[^\r\n<])*(?:\r\n?|\n|(?:__|[^\r\n<])(?![^\r\n]))/.source.replace(/__/g,function(){return t.source}),"gi"),r=!1;Prism.hooks.add("before-sanity-check",function(t){var n=t.language;e.test(n)&&!t.grammar&&(t.grammar=Prism.languages[n]=Prism.languages.diff)}),Prism.hooks.add("before-tokenize",function(t){r||Prism.languages.diff||Prism.plugins.autoloader||(r=!0,console.warn("Prism's Diff Highlight plugin requires the Diff language definition (prism-diff.js).Make sure the language definition is loaded or use Prism's Autoloader plugin."));var n=t.language;e.test(n)&&!Prism.languages[n]&&(Prism.languages[n]=Prism.languages.diff)}),Prism.hooks.add("wrap",function(r){var a,i;if("diff"!==r.language){var s=e.exec(r.language);if(!s)return;a=s[1],i=Prism.languages[a]}var l=Prism.languages.diff&&Prism.languages.diff.PREFIXES;if(l&&r.type in l){var o,u=r.content.replace(t,"").replace(/</g,"<").replace(/&/g,"&"),c=u.replace(/(^|[\r\n])./g,"$1");o=i?Prism.highlight(c,i,a):Prism.util.encode(c);var p,g=new Prism.Token("prefix",l[r.type],[/\w+/.exec(r.type)[0]]),d=Prism.Token.stringify(g,r.language),m=[];for(n.lastIndex=0;p=n.exec(o);)m.push(d+p[0]);/(?:^|[\r\n]).$/.test(u)&&m.push(d),r.content=m.join(""),i&&r.classes.push("language-"+a)}})}}();
@@ -0,0 +1,22 @@
+declare module "himalaya";
+
+interface TextNode {
+ type: "text";
+ content: string;
+}
+
+interface RealNode {
+ type: "element";
+ tagName: keyof HTMLElementTagNameMap;
+ attributes: Array<{
+ key: string;
+ value: string;
+ }>;
+ children: Array<RealNode | TextNode>;
+}
+
+export declare type ParseResult = (TextNode | RealNode)[];
+
+export declare function parse<T = ParseResult>(html: string): T;
+
+export default parse;
@@ -2539,6 +2539,10 @@ has@^1.0.3:
dependencies:
function-bind "^1.1.1"
+himalaya@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/himalaya/-/himalaya-1.1.0.tgz#31724ae9d35714cd7c6f4be94888953f3604606a"
+
hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.3.0:
version "3.3.2"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"