@vectojs/markdown 0.13.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -17
- package/dist/Markdown.d.ts +119 -153
- package/dist/blockAffordances.d.ts +179 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1233 -566
- package/dist/index.mjs +1205 -547
- package/dist/markdown-code.d.ts +102 -0
- package/dist/markdown-entities.d.ts +33 -0
- package/dist/markdown-image.d.ts +126 -0
- package/dist/markdown-inline.d.ts +58 -0
- package/dist/markdown-math.d.ts +169 -0
- package/dist/theme.d.ts +153 -0
- package/package.json +8 -7
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
// src/Markdown.ts
|
|
2
2
|
import {
|
|
3
|
-
contentLineInHint,
|
|
4
3
|
BidiResolver,
|
|
5
|
-
|
|
6
|
-
GlyphRasterAtlas,
|
|
7
|
-
OBJECT_REPLACEMENT,
|
|
8
|
-
prepareContentGrid,
|
|
4
|
+
OBJECT_REPLACEMENT as OBJECT_REPLACEMENT2,
|
|
9
5
|
SVGEntity,
|
|
10
6
|
beginVectoUserTiming,
|
|
11
7
|
endVectoUserTiming,
|
|
@@ -422,450 +418,113 @@ function createStreamController(host, options = {}) {
|
|
|
422
418
|
return new StreamControllerImpl(host, options);
|
|
423
419
|
}
|
|
424
420
|
|
|
425
|
-
// src/
|
|
426
|
-
import {
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
var NONE = { kind: "none" };
|
|
435
|
-
var PENDING = { kind: "pending" };
|
|
436
|
-
function scanFrontMatter(text, complete) {
|
|
437
|
-
if (text.length === 0) return PENDING;
|
|
438
|
-
const open = OPEN_RE.exec(text);
|
|
439
|
-
if (!open) {
|
|
440
|
-
return !complete && OPENER_PREFIX_RE.test(text) ? PENDING : NONE;
|
|
441
|
-
}
|
|
442
|
-
const decide = complete || text.length > MAX_PENDING_CHARS;
|
|
443
|
-
const contentStart = open[0].length;
|
|
444
|
-
let cursor = contentStart;
|
|
445
|
-
let keyChecked = false;
|
|
446
|
-
while (cursor < text.length) {
|
|
447
|
-
const nl = text.indexOf("\n", cursor);
|
|
448
|
-
if (nl === -1 && !decide) return PENDING;
|
|
449
|
-
const line = text.slice(cursor, nl === -1 ? text.length : nl).replace(/\r$/, "");
|
|
450
|
-
if (!keyChecked) {
|
|
451
|
-
if (!KEY_RE.test(line)) return NONE;
|
|
452
|
-
keyChecked = true;
|
|
453
|
-
} else if (CLOSE_RE.test(line)) {
|
|
454
|
-
return {
|
|
455
|
-
kind: "found",
|
|
456
|
-
raw: text.slice(contentStart, cursor),
|
|
457
|
-
// A closer with no trailing newline ends the document, so the body is
|
|
458
|
-
// empty rather than starting one character past the end.
|
|
459
|
-
bodyStart: nl === -1 ? text.length : nl + 1
|
|
460
|
-
};
|
|
461
|
-
}
|
|
462
|
-
if (nl === -1) break;
|
|
463
|
-
cursor = nl + 1;
|
|
464
|
-
}
|
|
465
|
-
return decide ? NONE : PENDING;
|
|
466
|
-
}
|
|
467
|
-
function parseFrontMatterFields(raw) {
|
|
468
|
-
const out = {};
|
|
469
|
-
for (const rawLine of raw.split("\n")) {
|
|
470
|
-
const line = rawLine.replace(/\r$/, "");
|
|
471
|
-
if (line.length === 0 || /^[\s#]/.test(line)) continue;
|
|
472
|
-
const sep = line.indexOf(":");
|
|
473
|
-
if (sep <= 0) continue;
|
|
474
|
-
const value = line.slice(sep + 1);
|
|
475
|
-
if (value.length > 0 && value[0] !== " " && value[0] !== " ") continue;
|
|
476
|
-
out[line.slice(0, sep).trim()] = unquote(value.trim());
|
|
421
|
+
// src/markdown-entities.ts
|
|
422
|
+
import { Entity } from "@vectojs/core";
|
|
423
|
+
var HorizontalRule = class extends Entity {
|
|
424
|
+
color;
|
|
425
|
+
constructor(w, color) {
|
|
426
|
+
super();
|
|
427
|
+
this.width = w;
|
|
428
|
+
this.height = 1;
|
|
429
|
+
this.color = color;
|
|
477
430
|
}
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
function unquote(value) {
|
|
481
|
-
if (value.length < 2) return value;
|
|
482
|
-
const first = value[0];
|
|
483
|
-
if ((first === '"' || first === "'") && value.endsWith(first)) {
|
|
484
|
-
return value.slice(1, -1);
|
|
431
|
+
isPointInside() {
|
|
432
|
+
return false;
|
|
485
433
|
}
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
var WORKER_SOURCE_STRING = '"use strict";(()=>{function V(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var _=V();function ke(t){_=t}var C={exec:()=>null};function P(t){let e=[];return n=>{let s=Math.max(0,Math.min(3,n-1)),r=e[s];return r||(r=t(s),e[s]=r),r}}function k(t,e=""){let n=typeof t=="string"?t:t.source,s={replace:(r,l)=>{let a=typeof l=="string"?l:l.source;return a=a.replace(x.caret,"$1"),n=n.replace(r,a),s},getRegex:()=>new RegExp(n,e)};return s}var _e=((t="")=>{try{return!!new RegExp("(?<=1)(?<!1)"+t)}catch{return!1}})(),x={codeRemoveIndent:/^(?: {1,4}| {0,3}\\t)/gm,outputLinkReplace:/\\\\([\\[\\]])/g,indentCodeCompensation:/^(\\s+)(?:```)/,beginningSpace:/^\\s+/,endingHash:/#$/,startingSpaceChar:/^ /,endingSpaceChar:/ $/,nonSpaceChar:/[^ ]/,newLineCharGlobal:/\\n/g,tabCharGlobal:/\\t/g,multipleSpaceGlobal:/\\s+/g,blankLine:/^[ \\t]*$/,doubleBlankLine:/\\n[ \\t]*\\n[ \\t]*$/,blockquoteStart:/^ {0,3}>/,blockquoteSetextReplace:/\\n {0,3}((?:=+|-+) *)(?=\\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \\t]?/gm,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\\[[ xX]\\] +\\S/,listReplaceTask:/^\\[[ xX]\\] +/,listTaskCheckbox:/\\[[ xX]\\]/,anyLine:/\\n.*\\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\\||\\| *$/g,tableRowBlankLine:/\\n[ \\t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^<a /i,endATag:/^<\\/a>/i,startPreScriptTag:/^<(pre|code|kbd|script)(\\s|>)/i,endPreScriptTag:/^<\\/(pre|code|kbd|script)(\\s|>)/i,startAngleBracket:/^</,endAngleBracket:/>$/,pedanticHrefTitle:/^([^\'"]*[^\\s])\\s+([\'"])(.*)\\2/,unicodeAlphaNumeric:/[\\p{L}\\p{N}]/u,escapeTest:/[&<>"\']/,escapeReplace:/[&<>"\']/g,escapeTestNoEncode:/[<>"\']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/,escapeReplaceNoEncode:/[<>"\']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/g,caret:/(^|[^\\[])\\^/g,percentDecode:/%25/g,findPipe:/\\|/g,splitPipe:/ \\|/,slashPipe:/\\\\\\|/g,carriageReturn:/\\r\\n|\\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\\S*/,endingNewline:/\\n$/,listItemRegex:t=>new RegExp(`^( {0,3}${t})((?:[ ][^\\\\n]*)?(?:\\\\n|$))`),nextBulletRegex:P(t=>new RegExp(`^ {0,${t}}(?:[*+-]|\\\\d{1,9}[.)])((?:[ ][^\\\\n]*)?(?:\\\\n|$))`)),hrRegex:P(t=>new RegExp(`^ {0,${t}}((?:- *){3,}|(?:_ *){3,}|(?:\\\\* *){3,})(?:\\\\n+|$)`)),fencesBeginRegex:P(t=>new RegExp(`^ {0,${t}}(?:\\`\\`\\`|~~~)`)),headingBeginRegex:P(t=>new RegExp(`^ {0,${t}}#`)),htmlBeginRegex:P(t=>new RegExp(`^ {0,${t}}<(?:[a-z].*>|!--)`,"i")),blockquoteBeginRegex:P(t=>new RegExp(`^ {0,${t}}>`))},Pe=/^(?:[ \\t]*(?:\\n|$))+/,Me=/^((?: {4}| {0,3}\\t)[^\\n]+(?:\\n(?:[ \\t]*(?:\\n|$))*)?)+/,Ee=/^ {0,3}(`{3,}(?=[^`\\n]*(?:\\n|$))|~{3,})([^\\n]*)(?:\\n|$)(?:|([\\s\\S]*?)(?:\\n|$))(?: {0,3}\\1[~`]* *(?=\\n|$)|$)/,v=/^ {0,3}((?:-[\\t ]*){3,}|(?:_[ \\t]*){3,}|(?:\\*[ \\t]*){3,})(?:\\n+|$)/,Be=/^ {0,3}(#{1,6})(?=\\s|$)(.*)(?:\\n+|$)/,K=/ {0,3}(?:[*+-]|\\d{1,9}[.)])/,fe=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\\n(?!\\s*?\\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,de=k(fe).replace(/bull/g,K).replace(/blockCode/g,/(?: {4}| {0,3}\\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}(?:\\s|$)/).replace(/html/g,/ {0,3}<[^\\n>]+>\\n/).replace(/\\|table/g,"").getRegex(),qe=k(fe).replace(/bull/g,K).replace(/blockCode/g,/(?: {4}| {0,3}\\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}(?:\\s|$)/).replace(/html/g,/ {0,3}<[^\\n>]+>\\n/).replace(/table/g,/ {0,3}\\|?(?:[:\\- ]*\\|)+[\\:\\- ]*\\n/).getRegex(),J=/^([^\\n]+(?:\\n(?!hr|heading|lheading|blockquote|fences|list|html|table|[ \\t]+\\n)[^\\n]+)*)/,ve=/^[^\\n]+/,Y=/(?!\\s*\\])(?:\\\\[\\s\\S]|[^\\[\\]\\\\])+/,De=k(/^ {0,3}\\[(label)\\]: *(?:\\n[ \\t]*)?([^<\\s][^\\s]*|<.*?>)(?:(?: +(?:\\n[ \\t]*)?| *\\n[ \\t]*)(title))? *(?:\\n+|$)/).replace("label",Y).replace("title",/(?:"(?:\\\\"?|[^"\\\\])*"|\'[^\'\\n]*(?:\\n[^\'\\n]+)*\\n?\'|\\([^()]*\\))/).getRegex(),Ze=k(/^(bull)([ \\t][^\\n]*?)?(?:\\n|$)/).replace(/bull/g,K).getRegex(),N="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",ee=/<!--(?:-?>|[\\s\\S]*?(?:-->|$))/,Oe=k("^ {0,3}(?:<(script|pre|style|textarea)[\\\\s>][\\\\s\\\\S]*?(?:</\\\\1>[^\\\\n]*\\\\n*|$)|comment[^\\\\n]*(\\\\n+|$)|<\\\\?[\\\\s\\\\S]*?(?:\\\\?>[^\\\\n]*\\\\n*|$)|<![A-Z][\\\\s\\\\S]*?(?:>[^\\\\n]*\\\\n*|$)|<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?(?:\\\\]\\\\]>[^\\\\n]*\\\\n*|$)|</?(tag)(?: +|\\\\n|/?>)[\\\\s\\\\S]*?(?:(?:\\\\n[ ]*)+\\\\n|$)|<(?!script|pre|style|textarea)([a-z][\\\\w-]*)(?:attribute)*? */?>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ ]*)+\\\\n|$)|</(?!script|pre|style|textarea)[a-z][\\\\w-]*\\\\s*>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ ]*)+\\\\n|$))","i").replace("comment",ee).replace("tag",N).replace("attribute",/ +[a-zA-Z:_][\\w.:-]*(?: *= *"[^"\\n]*"| *= *\'[^\'\\n]*\'| *= *[^\\s"\'=<>`]+)?/).getRegex(),xe=t=>k(J).replace("hr",v).replace("heading"," {0,3}#{1,6}(?:\\\\s|$)").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~~~)[^\\\\n]*\\\\n").replace("list",t).replace("html","</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",N).getRegex(),Qe=xe(/ {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]/),Ne=xe(/ {0,3}(?:[*+-]|\\d{1,9}[.)])(?:[ \\t]|\\n|$)/),He=k(/^( {0,3}> ?(paragraph|[^\\n]*)(?:\\n|$))+/).replace("paragraph",Ne).getRegex(),te={blockquote:He,code:Me,def:De,fences:Ee,heading:Be,hr:v,html:Oe,lheading:de,list:Ze,newline:Pe,paragraph:Qe,table:C,text:ve},ae=k("^ *([^\\\\n ].*)\\\\n {0,3}((?:\\\\| *)?:?-+:? *(?:\\\\| *:?-+:? *)*(?:\\\\| *)?)(?:\\\\n((?:(?! *\\\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\\\n|$))*)\\\\n*|$)").replace("hr",v).replace("heading"," {0,3}#{1,6}(?:\\\\s|$)").replace("blockquote"," {0,3}>").replace("code","(?: {4}| {0,3} )[^\\\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~~~)[^\\\\n]*\\\\n").replace("list"," {0,3}(?:[*+-]|1[.)])[ \\\\t]").replace("html","</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",N).getRegex(),je={...te,lheading:qe,table:ae,paragraph:k(J).replace("hr",v).replace("heading"," {0,3}#{1,6}(?:\\\\s|$)").replace("|lheading","").replace("table",ae).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~~~)[^\\\\n]*\\\\n").replace("list"," {0,3}(?:[*+-]|1[.)])[ \\\\t]+[^ \\\\t\\\\n]").replace("html","</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",N).getRegex()},Ge={...te,html:k(`^ *(?:comment *(?:\\\\n|\\\\s*$)|<(tag)[\\\\s\\\\S]+?</\\\\1> *(?:\\\\n{2,}|\\\\s*$)|<tag(?:"[^"]*"|\'[^\']*\'|\\\\s[^\'"/>\\\\s]*)*?/?> *(?:\\\\n{2,}|\\\\s*$))`).replace("comment",ee).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\\\b)\\\\w+(?!:|[^\\\\w\\\\s@]*@)\\\\b").getRegex(),def:/^ *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +(["(][^\\n]+[")]))? *(?:\\n+|$)/,heading:/^(#{1,6})(.*)(?:\\n+|$)/,fences:C,lheading:/^(.+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,paragraph:k(J).replace("hr",v).replace("heading",` *#{1,6} *[^\n]`).replace("lheading",de).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},We=/^\\\\([!"#$%&\'()*+,\\-./:;<=>?@\\[\\]\\\\^_`{|}~])/,Fe=/^(`+)([^`]|[^`][\\s\\S]*?[^`])\\1(?!`)/,be=/^( {2,}|\\\\)\\n(?!\\s*$)/,Xe=/^(`+|[^`])(?:(?= {2,}\\n)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*_]|\\b_|$)|[^ ](?= {2,}\\n)))/,M=/[\\p{P}\\p{S}]/u,H=/[\\s\\p{P}\\p{S}]/u,ne=/[^\\s\\p{P}\\p{S}]/u,Ue=k(/^((?![*_])punctSpace)/,"u").replace(/punctSpace/g,H).getRegex(),me=/(?!~)[\\p{P}\\p{S}]/u,Ve=/(?!~)[\\s\\p{P}\\p{S}]/u,Ke=/(?:[^\\s\\p{P}\\p{S}]|~)/u,Je=k(/link|precode-code|html/,"g").replace("link",/\\[(?:[^\\[\\]`]|(?<a>`+)[^`]+\\k<a>(?!`))*?\\]\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)]|\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)])*\\))*\\)/).replace("precode-",_e?"(?<!`)()":"(^^|[^`])").replace("code",/(?<b>`+)[^`]+\\k<b>(?!`)/).replace("html",/<(?! )[^<>]*?>/).getRegex(),we=/^(?:\\*+(?:((?!\\*)punct)|([^\\s*]))?)|^_+(?:((?!_)punct)|([^\\s_]))?/,Ye=k(we,"u").replace(/punct/g,M).getRegex(),et=k(we,"u").replace(/punct/g,me).getRegex(),ye="^[^_*]*?__[^_*]*?\\\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\\\*)punct(\\\\*+)(?=[\\\\s]|$)|notPunctSpace(\\\\*+)(?!\\\\*)(?=punctSpace|$)|(?!\\\\*)punctSpace(\\\\*+)(?=notPunctSpace)|[\\\\s](\\\\*+)(?!\\\\*)(?=punct)|(?!\\\\*)punct(\\\\*+)(?!\\\\*)(?=punct)|notPunctSpace(\\\\*+)(?=notPunctSpace)",tt=k(ye,"gu").replace(/notPunctSpace/g,ne).replace(/punctSpace/g,H).replace(/punct/g,M).getRegex(),nt=k(ye,"gu").replace(/notPunctSpace/g,Ke).replace(/punctSpace/g,Ve).replace(/punct/g,me).getRegex(),rt=k("^[^_*]*?\\\\*\\\\*[^_*]*?_[^_*]*?(?=\\\\*\\\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)","gu").replace(/notPunctSpace/g,ne).replace(/punctSpace/g,H).replace(/punct/g,M).getRegex(),st=k(/^~~?(?:((?!~)punct)|[^\\s~])/,"u").replace(/punct/g,M).getRegex(),lt="^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)",it=k(lt,"gu").replace(/notPunctSpace/g,ne).replace(/punctSpace/g,H).replace(/punct/g,M).getRegex(),at=k(/\\\\(punct)/,"gu").replace(/punct/g,M).getRegex(),ot=k(/^<(scheme:[^\\s\\x00-\\x1f<>]*|email)>/).replace("scheme",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email",/[a-zA-Z0-9.!#$%&\'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),ct=k(ee).replace("(?:-->|$)","-->").getRegex(),ht=k("^comment|^</[a-zA-Z][\\\\w:-]*\\\\s*>|^<[a-zA-Z][\\\\w-]*(?:attribute)*?\\\\s*/?>|^<\\\\?[\\\\s\\\\S]*?\\\\?>|^<![a-zA-Z]+\\\\s[\\\\s\\\\S]*?>|^<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?\\\\]\\\\]>").replace("comment",ct).replace("attribute",/\\s+[a-zA-Z:_][\\w.:-]*(?:\\s*=\\s*"[^"]*"|\\s*=\\s*\'[^\']*\'|\\s*=\\s*[^\\s"\'=<>`]+)?/).getRegex(),Z=/(?:\\[(?:\\\\[\\s\\S]|[^\\[\\]\\\\])*\\]|\\\\[\\s\\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\\])|[^\\[\\]\\\\`])*?/,ut=k(/^!?\\[(label)\\]\\(\\s*(href)(?:(?:[ \\t]+(?:\\n[ \\t]*)?|\\n[ \\t]*)(title))?\\s*\\)/).replace("label",Z).replace("href",/<(?:\\\\.|[^\\n<>\\\\])+>|[^ \\t\\n\\x00-\\x1f]+|(?=\\))/).replace("title",/"(?:\\\\"?|[^"\\\\])*"|\'(?:\\\\\'?|[^\'\\\\])*\'|\\((?:\\\\\\)?|[^)\\\\])*\\)/).getRegex(),Re=k(/^!?\\[(label)\\]\\[(ref)\\]/).replace("label",Z).replace("ref",Y).getRegex(),$e=k(/^!?\\[(ref)\\](?:\\[\\])?/).replace("ref",Y).getRegex(),pt=k("reflink|nolink(?!\\\\()","g").replace("reflink",Re).replace("nolink",$e).getRegex(),oe=/[hH][tT][tT][pP][sS]?|[fF][tT][pP]/,re={_backpedal:C,anyPunctuation:at,autolink:ot,blockSkip:Je,br:be,code:Fe,del:C,delLDelim:C,delRDelim:C,emStrongLDelim:Ye,emStrongRDelimAst:tt,emStrongRDelimUnd:rt,escape:We,link:ut,nolink:$e,punctuation:Ue,reflink:Re,reflinkSearch:pt,tag:ht,text:Xe,url:C},gt={...re,link:k(/^!?\\[(label)\\]\\((.*?)\\)/).replace("label",Z).getRegex(),reflink:k(/^!?\\[(label)\\]\\s*\\[([^\\]]*)\\]/).replace("label",Z).getRegex()},F={...re,emStrongRDelimAst:nt,emStrongLDelim:et,delLDelim:st,delRDelim:it,url:k(/^((?:protocol):\\/\\/|www\\.)(?:[a-zA-Z0-9\\-]+\\.?)+[^\\s<]*|^email/).replace("protocol",oe).replace("email",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_\'"~()&]+|\\([^)]*\\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_\'"~)]+(?!$))+/,del:/^(~~?)(?=[^\\s~])((?:\\\\[\\s\\S]|[^\\\\])*?(?:\\\\[\\s\\S]|[^\\s~\\\\]))\\1(?=[^~]|$)/,text:k(/^(`+|~+|[^`~])(?:(?=[`~])|(?= {2,}\\n)|(?=[a-zA-Z0-9.!#$%&\'*+\\/=?_`{\\|}~-]+@)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*~_]|\\b_|protocol:\\/\\/|www\\.|$)|[^ ](?= {2,}\\n)|[^a-zA-Z0-9.!#$%&\'*+\\/=?_`{\\|}~-](?=[a-zA-Z0-9.!#$%&\'*+\\/=?_`{\\|}~-]+@)))/).replace("protocol",oe).getRegex()},kt={...F,br:k(be).replace("{2,}","*").getRegex(),text:k(F.text).replace("\\\\b_","\\\\b_| {2,}\\\\n").replace(/\\{2,\\}/g,"*").getRegex()},D={normal:te,gfm:je,pedantic:Ge},B={normal:re,gfm:F,breaks:kt,pedantic:gt},ft={"&":"&","<":"<",">":">",\'"\':""","\'":"'"},ce=t=>ft[t];function S(t,e){if(e){if(x.escapeTest.test(t))return t.replace(x.escapeReplace,ce)}else if(x.escapeTestNoEncode.test(t))return t.replace(x.escapeReplaceNoEncode,ce);return t}function he(t){try{t=encodeURI(t).replace(x.percentDecode,"%")}catch{return null}return t}function ue(t,e){let n=t.replace(x.findPipe,(l,a,i)=>{let o=!1,c=a;for(;--c>=0&&i[c]==="\\\\";)o=!o;return o?"|":" |"}),s=n.split(x.splitPipe),r=0;if(s[0].trim()||s.shift(),s.length>0&&!s.at(-1)?.trim()&&s.pop(),e)if(s.length>e)s.splice(e);else for(;s.length<e;)s.push("");for(;r<s.length;r++)s[r]=s[r].trim().replace(x.slashPipe,"|");return s}function z(t,e,n){let s=t.length;if(s===0)return"";let r=0;for(;r<s;){let l=t.charAt(s-r-1);if(l===e&&!n)r++;else if(l!==e&&n)r++;else break}return t.slice(0,s-r)}function pe(t){let e=t.split(`\n`),n=e.length-1;for(;n>=0&&x.blankLine.test(e[n]);)n--;return e.length-n<=2?t:e.slice(0,n+1).join(`\n`)}function dt(t,e){if(t.indexOf(e[1])===-1)return-1;let n=0;for(let s=0;s<t.length;s++)if(t[s]==="\\\\")s++;else if(t[s]===e[0])n++;else if(t[s]===e[1]&&(n--,n<0))return s;return n>0?-2:-1}function xt(t,e=0){let n=e,s="";for(let r of t)if(r===" "){let l=4-n%4;s+=" ".repeat(l),n+=l}else s+=r,n++;return s}function ge(t,e,n,s,r){let l=e.href,a=e.title||null,i=t[1].replace(r.other.outputLinkReplace,"$1");s.state.inLink=!0;let o={type:t[0].charAt(0)==="!"?"image":"link",raw:n,href:l,title:a,text:i,tokens:s.inlineTokens(i)};return s.state.inLink=!1,o}function bt(t,e,n){let s=t.match(n.other.indentCodeCompensation);if(s===null)return e;let r=s[1];return e.split(`\n`).map(l=>{let a=l.match(n.other.beginningSpace);if(a===null)return l;let[i]=a;return i.length>=r.length?l.slice(r.length):l}).join(`\n`)}var O=class{options;rules;lexer;constructor(t){this.options=t||_}space(t){let e=this.rules.block.newline.exec(t);if(e&&e[0].length>0)return{type:"space",raw:e[0]}}code(t){let e=this.rules.block.code.exec(t);if(e){let n=this.options.pedantic?e[0]:pe(e[0]),s=n.replace(this.rules.other.codeRemoveIndent,"");return{type:"code",raw:n,codeBlockStyle:"indented",text:s}}}fences(t){let e=this.rules.block.fences.exec(t);if(e){let n=e[0],s=bt(n,e[3]||"",this.rules);return{type:"code",raw:n,lang:e[2]?e[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):e[2],text:s}}}heading(t){let e=this.rules.block.heading.exec(t);if(e){let n=e[2].trim();if(this.rules.other.endingHash.test(n)){let s=z(n,"#");(this.options.pedantic||!s||this.rules.other.endingSpaceChar.test(s))&&(n=s.trim())}return{type:"heading",raw:z(e[0],`\n`),depth:e[1].length,text:n,tokens:this.lexer.inline(n)}}}hr(t){let e=this.rules.block.hr.exec(t);if(e)return{type:"hr",raw:z(e[0],`\n`)}}blockquote(t){let e=this.rules.block.blockquote.exec(t);if(e){let n=z(e[0],`\n`).split(`\n`),s="",r="",l=[];for(;n.length>0;){let a=!1,i=[],o;for(o=0;o<n.length;o++)if(this.rules.other.blockquoteStart.test(n[o]))i.push(n[o]),a=!0;else if(!a)i.push(n[o]);else break;n=n.slice(o);let c=i.join(`\n`),u=c.replace(this.rules.other.blockquoteSetextReplace,`\n $1`).replace(this.rules.other.blockquoteSetextReplace2,"");s=s?`${s}\n${c}`:c,r=r?`${r}\n${u}`:u;let h=this.lexer.state.top;if(this.lexer.state.top=!0,this.lexer.blockTokens(u,l,!0),this.lexer.state.top=h,n.length===0)break;let p=l.at(-1);if(p?.type==="code")break;if(p?.type==="blockquote"){let d=p,f=d.raw+`\n`+n.join(`\n`),m=this.blockquote(f);l[l.length-1]=m,s=s.substring(0,s.length-d.raw.length)+m.raw,r=r.substring(0,r.length-d.text.length)+m.text;break}else if(p?.type==="list"){let d=p,f=d.raw+`\n`+n.join(`\n`),m=this.list(f);l[l.length-1]=m,s=s.substring(0,s.length-p.raw.length)+m.raw,r=r.substring(0,r.length-d.raw.length)+m.raw,n=f.substring(l.at(-1).raw.length).split(`\n`);continue}}return{type:"blockquote",raw:s,tokens:l,text:r}}}list(t){let e=this.rules.block.list.exec(t);if(e){let n=e[1].trim(),s=n.length>1,r={type:"list",raw:"",ordered:s,start:s?+n.slice(0,-1):"",loose:!1,items:[]};n=s?`\\\\d{1,9}\\\\${n.slice(-1)}`:`\\\\${n}`,this.options.pedantic&&(n=s?n:"[*+-]");let l=this.rules.other.listItemRegex(n),a=!1;for(;t;){let o=!1,c="",u="";if(!(e=l.exec(t))||this.rules.block.hr.test(t))break;c=e[0],t=t.substring(c.length);let h=xt(e[2].split(`\n`,1)[0],e[1].length),p=t.split(`\n`,1)[0],d=!h.trim(),f=0;if(this.options.pedantic?(f=2,u=h.trimStart()):d?f=e[1].length+1:(f=h.search(this.rules.other.nonSpaceChar),f=f>4?1:f,u=h.slice(f),f+=e[1].length),d&&this.rules.other.blankLine.test(p)&&(c+=p+`\n`,t=t.substring(p.length+1),o=!0),!o){let m=this.rules.other.nextBulletRegex(f),w=this.rules.other.hrRegex(f),y=this.rules.other.fencesBeginRegex(f),L=this.rules.other.headingBeginRegex(f),W=this.rules.other.htmlBeginRegex(f),A=this.rules.other.blockquoteBeginRegex(f);for(;t;){let b=t.split(`\n`,1)[0],T;if(p=b,this.options.pedantic?(p=p.replace(this.rules.other.listReplaceNesting," "),T=p):T=p.replace(this.rules.other.tabCharGlobal," "),y.test(p)||L.test(p)||W.test(p)||A.test(p)||m.test(p)||w.test(p))break;if(T.search(this.rules.other.nonSpaceChar)>=f||!p.trim())u+=`\n`+T.slice(f);else{if(d||h.replace(this.rules.other.tabCharGlobal," ").search(this.rules.other.nonSpaceChar)>=4||y.test(h)||L.test(h)||w.test(h))break;u+=`\n`+p}d=!p.trim(),c+=b+`\n`,t=t.substring(b.length+1),h=T.slice(f)}}r.loose||(a?r.loose=!0:this.rules.other.doubleBlankLine.test(c)&&(a=!0)),r.items.push({type:"list_item",raw:c,task:!!this.options.gfm&&this.rules.other.listIsTask.test(u),loose:!1,text:u,tokens:[]}),r.raw+=c}let i=r.items.at(-1);if(i)i.raw=i.raw.trimEnd(),i.text=i.text.trimEnd();else return;r.raw=r.raw.trimEnd();for(let o of r.items){this.lexer.state.top=!1,o.tokens=this.lexer.blockTokens(o.text,[]);let c=o.tokens[0];if(o.task&&(c?.type==="text"||c?.type==="paragraph")){o.text=o.text.replace(this.rules.other.listReplaceTask,""),c.raw=c.raw.replace(this.rules.other.listReplaceTask,""),c.text=c.text.replace(this.rules.other.listReplaceTask,"");for(let h=this.lexer.inlineQueue.length-1;h>=0;h--)if(this.rules.other.listIsTask.test(this.lexer.inlineQueue[h].src)){this.lexer.inlineQueue[h].src=this.lexer.inlineQueue[h].src.replace(this.rules.other.listReplaceTask,"");break}let u=this.rules.other.listTaskCheckbox.exec(o.raw);if(u){let h={type:"checkbox",raw:u[0]+" ",checked:u[0]!=="[ ]"};o.checked=h.checked,r.loose?o.tokens[0]&&["paragraph","text"].includes(o.tokens[0].type)&&"tokens"in o.tokens[0]&&o.tokens[0].tokens?(o.tokens[0].raw=h.raw+o.tokens[0].raw,o.tokens[0].text=h.raw+o.tokens[0].text,o.tokens[0].tokens.unshift(h)):o.tokens.unshift({type:"paragraph",raw:h.raw,text:h.raw,tokens:[h]}):o.tokens.unshift(h)}}else o.task&&(o.task=!1);if(!r.loose){let u=o.tokens.filter(p=>p.type==="space"),h=u.length>0&&u.some(p=>this.rules.other.anyLine.test(p.raw));r.loose=h}}if(r.loose)for(let o of r.items){o.loose=!0;for(let c of o.tokens)c.type==="text"&&(c.type="paragraph")}return r}}html(t){let e=this.rules.block.html.exec(t);if(e){let n=pe(e[0]);return{type:"html",block:!0,raw:n,pre:e[1]==="pre"||e[1]==="script"||e[1]==="style",text:n}}}def(t){let e=this.rules.block.def.exec(t);if(e){let n=e[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal," "),s=e[2]?e[2].replace(this.rules.other.hrefBrackets,"$1").replace(this.rules.inline.anyPunctuation,"$1"):"",r=e[3]?e[3].substring(1,e[3].length-1).replace(this.rules.inline.anyPunctuation,"$1"):e[3];return{type:"def",tag:n,raw:z(e[0],`\n`),href:s,title:r}}}table(t){let e=this.rules.block.table.exec(t);if(!e||!this.rules.other.tableDelimiter.test(e[2]))return;let n=ue(e[1]),s=e[2].replace(this.rules.other.tableAlignChars,"").split("|"),r=e[3]?.trim()?e[3].replace(this.rules.other.tableRowBlankLine,"").split(`\n`):[],l={type:"table",raw:z(e[0],`\n`),header:[],align:[],rows:[]};if(n.length===s.length){for(let a of s)this.rules.other.tableAlignRight.test(a)?l.align.push("right"):this.rules.other.tableAlignCenter.test(a)?l.align.push("center"):this.rules.other.tableAlignLeft.test(a)?l.align.push("left"):l.align.push(null);for(let a=0;a<n.length;a++)l.header.push({text:n[a],tokens:this.lexer.inline(n[a]),header:!0,align:l.align[a]});for(let a of r)l.rows.push(ue(a,l.header.length).map((i,o)=>({text:i,tokens:this.lexer.inline(i),header:!1,align:l.align[o]})));return l}}lheading(t){let e=this.rules.block.lheading.exec(t);if(e){let n=e[1].trim();return{type:"heading",raw:z(e[0],`\n`),depth:e[2].charAt(0)==="="?1:2,text:n,tokens:this.lexer.inline(n)}}}paragraph(t){let e=this.rules.block.paragraph.exec(t);if(e){let n=e[1].charAt(e[1].length-1)===`\n`?e[1].slice(0,-1):e[1];return{type:"paragraph",raw:e[0],text:n,tokens:this.lexer.inline(n)}}}text(t){let e=this.rules.block.text.exec(t);if(e)return{type:"text",raw:e[0],text:e[0],tokens:this.lexer.inline(e[0])}}escape(t){let e=this.rules.inline.escape.exec(t);if(e)return{type:"escape",raw:e[0],text:e[1]}}tag(t){let e=this.rules.inline.tag.exec(t);if(e)return!this.lexer.state.inLink&&this.rules.other.startATag.test(e[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&this.rules.other.endATag.test(e[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&this.rules.other.startPreScriptTag.test(e[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&this.rules.other.endPreScriptTag.test(e[0])&&(this.lexer.state.inRawBlock=!1),{type:"html",raw:e[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:e[0]}}link(t){let e=this.rules.inline.link.exec(t);if(e){let n=e[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(n)){if(!this.rules.other.endAngleBracket.test(n))return;let l=z(n.slice(0,-1),"\\\\");if((n.length-l.length)%2===0)return}else{let l=dt(e[2],"()");if(l===-2)return;if(l>-1){let a=(e[0].indexOf("!")===0?5:4)+e[1].length+l;e[2]=e[2].substring(0,l),e[0]=e[0].substring(0,a).trim(),e[3]=""}}let s=e[2],r="";if(this.options.pedantic){let l=this.rules.other.pedanticHrefTitle.exec(s);l&&(s=l[1],r=l[3])}else r=e[3]?e[3].slice(1,-1):"";return s=s.trim(),this.rules.other.startAngleBracket.test(s)&&(this.options.pedantic&&!this.rules.other.endAngleBracket.test(n)?s=s.slice(1):s=s.slice(1,-1)),ge(e,{href:s&&s.replace(this.rules.inline.anyPunctuation,"$1"),title:r&&r.replace(this.rules.inline.anyPunctuation,"$1")},e[0],this.lexer,this.rules)}}reflink(t,e){let n;if((n=this.rules.inline.reflink.exec(t))||(n=this.rules.inline.nolink.exec(t))){let s=(n[2]||n[1]).replace(this.rules.other.multipleSpaceGlobal," "),r=e[s.toLowerCase()];if(!r){let l=n[0].charAt(0);return{type:"text",raw:l,text:l}}return ge(n,r,n[0],this.lexer,this.rules)}}emStrong(t,e,n=""){let s=this.rules.inline.emStrongLDelim.exec(t);if(!(!s||!s[1]&&!s[2]&&!s[3]&&!s[4]||s[4]&&n.match(this.rules.other.unicodeAlphaNumeric))&&(!(s[1]||s[3])||!n||this.rules.inline.punctuation.exec(n))){let r=[...s[0]].length-1,l,a,i=r,o=0,c=s[0][0]==="*"?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(c.lastIndex=0,e=e.slice(-1*t.length+r);(s=c.exec(e))!==null;){if(l=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!l)continue;if(a=[...l].length,s[3]||s[4]){i+=a;continue}else if((s[5]||s[6])&&r%3&&!((r+a)%3)){o+=a;continue}if(i-=a,i>0)continue;a=Math.min(a,a+i+o);let u=[...s[0]][0].length,h=t.slice(0,r+s.index+u+a);if(Math.min(r,a)%2){let d=h.slice(1,-1);return{type:"em",raw:h,text:d,tokens:this.lexer.inlineTokens(d)}}let p=h.slice(2,-2);return{type:"strong",raw:h,text:p,tokens:this.lexer.inlineTokens(p)}}}}codespan(t){let e=this.rules.inline.code.exec(t);if(e){let n=e[2].replace(this.rules.other.newLineCharGlobal," "),s=this.rules.other.nonSpaceChar.test(n),r=this.rules.other.startingSpaceChar.test(n)&&this.rules.other.endingSpaceChar.test(n);return s&&r&&(n=n.substring(1,n.length-1)),{type:"codespan",raw:e[0],text:n}}}br(t){let e=this.rules.inline.br.exec(t);if(e)return{type:"br",raw:e[0]}}del(t,e,n=""){let s=this.rules.inline.delLDelim.exec(t);if(s&&(!s[1]||!n||this.rules.inline.punctuation.exec(n))){let r=[...s[0]].length-1,l,a,i=r,o=this.rules.inline.delRDelim;for(o.lastIndex=0,e=e.slice(-1*t.length+r);(s=o.exec(e))!==null;){if(l=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!l||(a=[...l].length,a!==r))continue;if(s[3]||s[4]){i+=a;continue}if(i-=a,i>0)continue;a=Math.min(a,a+i);let c=[...s[0]][0].length,u=t.slice(0,r+s.index+c+a),h=u.slice(r,-r);return{type:"del",raw:u,text:h,tokens:this.lexer.inlineTokens(h)}}}}autolink(t){let e=this.rules.inline.autolink.exec(t);if(e){let n,s;return e[2]==="@"?(n=e[1],s="mailto:"+n):(n=e[1],s=n),{type:"link",raw:e[0],text:n,href:s,tokens:[{type:"text",raw:n,text:n}]}}}url(t){let e;if(e=this.rules.inline.url.exec(t)){let n,s;if(e[2]==="@")n=e[0],s="mailto:"+n;else{let r;do r=e[0],e[0]=this.rules.inline._backpedal.exec(e[0])?.[0]??"";while(r!==e[0]);n=e[0],e[1]==="www."?s="http://"+e[0]:s=e[0]}return{type:"link",raw:e[0],text:n,href:s,tokens:[{type:"text",raw:n,text:n}]}}}inlineText(t){let e=this.rules.inline.text.exec(t);if(e){let n=this.lexer.state.inRawBlock;return{type:"text",raw:e[0],text:e[0],escaped:n}}}},R=class X{tokens;options;state;inlineQueue;tokenizer;constructor(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||_,this.options.tokenizer=this.options.tokenizer||new O,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};let n={other:x,block:D.normal,inline:B.normal};this.options.pedantic?(n.block=D.pedantic,n.inline=B.pedantic):this.options.gfm&&(n.block=D.gfm,this.options.breaks?n.inline=B.breaks:n.inline=B.gfm),this.tokenizer.rules=n}static get rules(){return{block:D,inline:B}}static lex(e,n){return new X(n).lex(e)}static lexInline(e,n){return new X(n).inlineTokens(e)}lex(e){e=e.replace(x.carriageReturn,`\n`),this.blockTokens(e,this.tokens);for(let n=0;n<this.inlineQueue.length;n++){let s=this.inlineQueue[n];this.inlineTokens(s.src,s.tokens)}return this.inlineQueue=[],this.tokens}blockTokens(e,n=[],s=!1){this.tokenizer.lexer=this,this.options.pedantic&&(e=e.replace(x.tabCharGlobal," ").replace(x.spaceLine,""));let r=1/0;for(;e;){if(e.length<r)r=e.length;else{this.infiniteLoopError(e.charCodeAt(0));break}let l;if(this.options.extensions?.block?.some(i=>(l=i.call({lexer:this},e,n))?(e=e.substring(l.raw.length),n.push(l),!0):!1))continue;if(l=this.tokenizer.space(e)){e=e.substring(l.raw.length);let i=n.at(-1);l.raw.length===1&&i!==void 0?i.raw+=`\n`:n.push(l);continue}if(l=this.tokenizer.code(e)){e=e.substring(l.raw.length);let i=n.at(-1);i?.type==="paragraph"||i?.type==="text"?(i.raw+=(i.raw.endsWith(`\n`)?"":`\n`)+l.raw,i.text+=`\n`+l.text,this.inlineQueue.at(-1).src=i.text):n.push(l);continue}if(l=this.tokenizer.fences(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.heading(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.hr(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.blockquote(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.list(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.html(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.def(e)){e=e.substring(l.raw.length);let i=n.at(-1);i?.type==="paragraph"||i?.type==="text"?(i.raw+=(i.raw.endsWith(`\n`)?"":`\n`)+l.raw,i.text+=`\n`+l.raw,this.inlineQueue.at(-1).src=i.text):this.tokens.links[l.tag]||(this.tokens.links[l.tag]={href:l.href,title:l.title},n.push(l));continue}if(l=this.tokenizer.table(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.lheading(e)){e=e.substring(l.raw.length),n.push(l);continue}let a=e;if(this.options.extensions?.startBlock){let i=1/0,o=e.slice(1),c;this.options.extensions.startBlock.forEach(u=>{c=u.call({lexer:this},o),typeof c=="number"&&c>=0&&(i=Math.min(i,c))}),i<1/0&&i>=0&&(a=e.substring(0,i+1))}if(this.state.top&&(l=this.tokenizer.paragraph(a))){let i=n.at(-1);s&&i?.type==="paragraph"?(i.raw+=(i.raw.endsWith(`\n`)?"":`\n`)+l.raw,i.text+=`\n`+l.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=i.text):n.push(l),s=a.length!==e.length,e=e.substring(l.raw.length);continue}if(l=this.tokenizer.text(e)){e=e.substring(l.raw.length);let i=n.at(-1);i?.type==="text"?(i.raw+=(i.raw.endsWith(`\n`)?"":`\n`)+l.raw,i.text+=`\n`+l.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=i.text):n.push(l);continue}if(e){this.infiniteLoopError(e.charCodeAt(0));break}}return this.state.top=!0,n}inline(e,n=[]){return this.inlineQueue.push({src:e,tokens:n}),n}inlineTokens(e,n=[]){this.tokenizer.lexer=this;let s=e;if(this.tokens.links){let i=Object.keys(this.tokens.links);i.length>0&&(s=s.replace(this.tokenizer.rules.inline.reflinkSearch,o=>i.includes(o.slice(o.lastIndexOf("[")+1,-1))?"["+"a".repeat(o.length-2)+"]":o))}s=s.replace(this.tokenizer.rules.inline.anyPunctuation,"++"),s=s.replace(this.tokenizer.rules.inline.blockSkip,(i,o,c)=>{let u=c?c.length:0;return i.slice(0,u)+"["+"a".repeat(i.length-u-2)+"]"}),s=this.options.hooks?.emStrongMask?.call({lexer:this},s)??s;let r=!1,l="",a=1/0;for(;e;){if(e.length<a)a=e.length;else{this.infiniteLoopError(e.charCodeAt(0));break}r||(l=""),r=!1;let i;if(this.options.extensions?.inline?.some(c=>(i=c.call({lexer:this},e,n))?(e=e.substring(i.raw.length),n.push(i),!0):!1))continue;if(i=this.tokenizer.escape(e)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.tag(e)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.link(e)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.reflink(e,this.tokens.links)){e=e.substring(i.raw.length);let c=n.at(-1);i.type==="text"&&c?.type==="text"?(c.raw+=i.raw,c.text+=i.text):n.push(i);continue}if(i=this.tokenizer.emStrong(e,s,l)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.codespan(e)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.br(e)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.del(e,s,l)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.autolink(e)){e=e.substring(i.raw.length),n.push(i);continue}if(!this.state.inLink&&(i=this.tokenizer.url(e))){e=e.substring(i.raw.length),n.push(i);continue}let o=e;if(this.options.extensions?.startInline){let c=1/0,u=e.slice(1),h;this.options.extensions.startInline.forEach(p=>{h=p.call({lexer:this},u),typeof h=="number"&&h>=0&&(c=Math.min(c,h))}),c<1/0&&c>=0&&(o=e.substring(0,c+1))}if(i=this.tokenizer.inlineText(o)){e=e.substring(i.raw.length),i.raw.slice(-1)!=="_"&&(l=i.raw.slice(-1)),r=!0;let c=n.at(-1);c?.type==="text"?(c.raw+=i.raw,c.text+=i.text):n.push(i);continue}if(e){this.infiniteLoopError(e.charCodeAt(0));break}}return n}infiniteLoopError(e){let n="Infinite loop on byte: "+e;if(this.options.silent)console.error(n);else throw new Error(n)}},Q=class{options;parser;constructor(t){this.options=t||_}space(t){return""}code({text:t,lang:e,escaped:n}){let s=(e||"").match(x.notSpaceStart)?.[0],r=t.replace(x.endingNewline,"")+`\n`;return s?\'<pre><code class="language-\'+S(s)+\'">\'+(n?r:S(r,!0))+`</code></pre>\n`:"<pre><code>"+(n?r:S(r,!0))+`</code></pre>\n`}blockquote({tokens:t}){return`<blockquote>\n${this.parser.parse(t)}</blockquote>\n`}html({text:t}){return t}def(t){return""}heading({tokens:t,depth:e}){return`<h${e}>${this.parser.parseInline(t)}</h${e}>\n`}hr(t){return`<hr>\n`}list(t){let e=t.ordered,n=t.start,s="";for(let a=0;a<t.items.length;a++){let i=t.items[a];s+=this.listitem(i)}let r=e?"ol":"ul",l=e&&n!==1?\' start="\'+n+\'"\':"";return"<"+r+l+`>\n`+s+"</"+r+`>\n`}listitem(t){return`<li>${this.parser.parse(t.tokens)}</li>\n`}checkbox({checked:t}){return"<input "+(t?\'checked="" \':"")+\'disabled="" type="checkbox"> \'}paragraph({tokens:t}){return`<p>${this.parser.parseInline(t)}</p>\n`}table(t){let e="",n="";for(let r=0;r<t.header.length;r++)n+=this.tablecell(t.header[r]);e+=this.tablerow({text:n});let s="";for(let r=0;r<t.rows.length;r++){let l=t.rows[r];n="";for(let a=0;a<l.length;a++)n+=this.tablecell(l[a]);s+=this.tablerow({text:n})}return s&&(s=`<tbody>${s}</tbody>`),`<table>\n<thead>\n`+e+`</thead>\n`+s+`</table>\n`}tablerow({text:t}){return`<tr>\n${t}</tr>\n`}tablecell(t){let e=this.parser.parseInline(t.tokens),n=t.header?"th":"td";return(t.align?`<${n} align="${t.align}">`:`<${n}>`)+e+`</${n}>\n`}strong({tokens:t}){return`<strong>${this.parser.parseInline(t)}</strong>`}em({tokens:t}){return`<em>${this.parser.parseInline(t)}</em>`}codespan({text:t}){return`<code>${S(t,!0)}</code>`}br(t){return"<br>"}del({tokens:t}){return`<del>${this.parser.parseInline(t)}</del>`}link({href:t,title:e,tokens:n}){let s=this.parser.parseInline(n),r=he(t);if(r===null)return s;t=r;let l=\'<a href="\'+t+\'"\';return e&&(l+=\' title="\'+S(e)+\'"\'),l+=">"+s+"</a>",l}image({href:t,title:e,text:n,tokens:s}){s&&(n=this.parser.parseInline(s,this.parser.textRenderer));let r=he(t);if(r===null)return S(n);t=r;let l=`<img src="${t}" alt="${S(n)}"`;return e&&(l+=` title="${S(e)}"`),l+=">",l}text(t){return"tokens"in t&&t.tokens?this.parser.parseInline(t.tokens):"escaped"in t&&t.escaped?t.text:S(t.text)}},se=class{strong({text:t}){return t}em({text:t}){return t}codespan({text:t}){return t}del({text:t}){return t}html({text:t}){return t}text({text:t}){return t}link({text:t}){return""+t}image({text:t}){return""+t}br(){return""}checkbox({raw:t}){return t}},$=class U{options;renderer;textRenderer;constructor(e){this.options=e||_,this.options.renderer=this.options.renderer||new Q,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new se}static parse(e,n){return new U(n).parse(e)}static parseInline(e,n){return new U(n).parseInline(e)}parse(e){this.renderer.parser=this;let n="";for(let s=0;s<e.length;s++){let r=e[s];if(this.options.extensions?.renderers?.[r.type]){let a=r,i=this.options.extensions.renderers[a.type].call({parser:this},a);if(i!==!1||!["space","hr","heading","code","table","blockquote","list","html","def","paragraph","text"].includes(a.type)){n+=i||"";continue}}let l=r;switch(l.type){case"space":{n+=this.renderer.space(l);break}case"hr":{n+=this.renderer.hr(l);break}case"heading":{n+=this.renderer.heading(l);break}case"code":{n+=this.renderer.code(l);break}case"table":{n+=this.renderer.table(l);break}case"blockquote":{n+=this.renderer.blockquote(l);break}case"list":{n+=this.renderer.list(l);break}case"checkbox":{n+=this.renderer.checkbox(l);break}case"html":{n+=this.renderer.html(l);break}case"def":{n+=this.renderer.def(l);break}case"paragraph":{n+=this.renderer.paragraph(l);break}case"text":{n+=this.renderer.text(l);break}default:{let a=\'Token with "\'+l.type+\'" type was not found.\';if(this.options.silent)return console.error(a),"";throw new Error(a)}}}return n}parseInline(e,n=this.renderer){this.renderer.parser=this;let s="";for(let r=0;r<e.length;r++){let l=e[r];if(this.options.extensions?.renderers?.[l.type]){let i=this.options.extensions.renderers[l.type].call({parser:this},l);if(i!==!1||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(l.type)){s+=i||"";continue}}let a=l;switch(a.type){case"escape":{s+=n.text(a);break}case"html":{s+=n.html(a);break}case"link":{s+=n.link(a);break}case"image":{s+=n.image(a);break}case"checkbox":{s+=n.checkbox(a);break}case"strong":{s+=n.strong(a);break}case"em":{s+=n.em(a);break}case"codespan":{s+=n.codespan(a);break}case"br":{s+=n.br(a);break}case"del":{s+=n.del(a);break}case"text":{s+=n.text(a);break}default:{let i=\'Token with "\'+a.type+\'" type was not found.\';if(this.options.silent)return console.error(i),"";throw new Error(i)}}}return s}},q=class{options;block;constructor(t){this.options=t||_}static passThroughHooks=new Set(["preprocess","postprocess","processAllTokens","emStrongMask"]);static passThroughHooksRespectAsync=new Set(["preprocess","postprocess","processAllTokens"]);preprocess(t){return t}postprocess(t){return t}processAllTokens(t){return t}emStrongMask(t){return t}provideLexer(t=this.block){return t?R.lex:R.lexInline}provideParser(t=this.block){return t?$.parse:$.parseInline}},mt=class{defaults=V();options=this.setOptions;parse=this.parseMarkdown(!0);parseInline=this.parseMarkdown(!1);Parser=$;Renderer=Q;TextRenderer=se;Lexer=R;Tokenizer=O;Hooks=q;constructor(...t){this.use(...t)}walkTokens(t,e){let n=[];for(let s of t)switch(n=n.concat(e.call(this,s)),s.type){case"table":{let r=s;for(let l of r.header)n=n.concat(this.walkTokens(l.tokens,e));for(let l of r.rows)for(let a of l)n=n.concat(this.walkTokens(a.tokens,e));break}case"list":{let r=s;n=n.concat(this.walkTokens(r.items,e));break}default:{let r=s;this.defaults.extensions?.childTokens?.[r.type]?this.defaults.extensions.childTokens[r.type].forEach(l=>{let a=r[l].flat(1/0);n=n.concat(this.walkTokens(a,e))}):r.tokens&&(n=n.concat(this.walkTokens(r.tokens,e)))}}return n}use(...t){let e=this.defaults.extensions||{renderers:{},childTokens:{}};return t.forEach(n=>{let s={...n};if(s.async=this.defaults.async||s.async||!1,n.extensions&&(n.extensions.forEach(r=>{if(!r.name)throw new Error("extension name required");if("renderer"in r){let l=e.renderers[r.name];l?e.renderers[r.name]=function(...a){let i=r.renderer.apply(this,a);return i===!1&&(i=l.apply(this,a)),i}:e.renderers[r.name]=r.renderer}if("tokenizer"in r){if(!r.level||r.level!=="block"&&r.level!=="inline")throw new Error("extension level must be \'block\' or \'inline\'");let l=e[r.level];l?l.unshift(r.tokenizer):e[r.level]=[r.tokenizer],r.start&&(r.level==="block"?e.startBlock?e.startBlock.push(r.start):e.startBlock=[r.start]:r.level==="inline"&&(e.startInline?e.startInline.push(r.start):e.startInline=[r.start]))}"childTokens"in r&&r.childTokens&&(e.childTokens[r.name]=r.childTokens)}),s.extensions=e),n.renderer){let r=this.defaults.renderer||new Q(this.defaults);for(let l in n.renderer){if(!(l in r))throw new Error(`renderer \'${l}\' does not exist`);if(["options","parser"].includes(l))continue;let a=l,i=n.renderer[a],o=r[a];r[a]=(...c)=>{let u=i.apply(r,c);return u===!1&&(u=o.apply(r,c)),u||""}}s.renderer=r}if(n.tokenizer){let r=this.defaults.tokenizer||new O(this.defaults);for(let l in n.tokenizer){if(!(l in r))throw new Error(`tokenizer \'${l}\' does not exist`);if(["options","rules","lexer"].includes(l))continue;let a=l,i=n.tokenizer[a],o=r[a];r[a]=(...c)=>{let u=i.apply(r,c);return u===!1&&(u=o.apply(r,c)),u}}s.tokenizer=r}if(n.hooks){let r=this.defaults.hooks||new q;for(let l in n.hooks){if(!(l in r))throw new Error(`hook \'${l}\' does not exist`);if(["options","block"].includes(l))continue;let a=l,i=n.hooks[a],o=r[a];q.passThroughHooks.has(l)?r[a]=c=>{if(this.defaults.async&&q.passThroughHooksRespectAsync.has(l))return(async()=>{let h=await i.call(r,c);return o.call(r,h)})();let u=i.call(r,c);return o.call(r,u)}:r[a]=(...c)=>{if(this.defaults.async)return(async()=>{let h=await i.apply(r,c);return h===!1&&(h=await o.apply(r,c)),h})();let u=i.apply(r,c);return u===!1&&(u=o.apply(r,c)),u}}s.hooks=r}if(n.walkTokens){let r=this.defaults.walkTokens,l=n.walkTokens;s.walkTokens=function(a){let i=[];return i.push(l.call(this,a)),r&&(i=i.concat(r.call(this,a))),i}}this.defaults={...this.defaults,...s}}),this}setOptions(t){return this.defaults={...this.defaults,...t},this}lexer(t,e){return R.lex(t,e??this.defaults)}parser(t,e){return $.parse(t,e??this.defaults)}parseMarkdown(t){return(e,n)=>{let s={...n},r={...this.defaults,...s},l=this.onError(!!r.silent,!!r.async);if(this.defaults.async===!0&&s.async===!1)return l(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(typeof e>"u"||e===null)return l(new Error("marked(): input parameter is undefined or null"));if(typeof e!="string")return l(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected"));if(r.hooks&&(r.hooks.options=r,r.hooks.block=t),r.async)return(async()=>{let a=r.hooks?await r.hooks.preprocess(e):e,i=await(r.hooks?await r.hooks.provideLexer(t):t?R.lex:R.lexInline)(a,r),o=r.hooks?await r.hooks.processAllTokens(i):i;r.walkTokens&&await Promise.all(this.walkTokens(o,r.walkTokens));let c=await(r.hooks?await r.hooks.provideParser(t):t?$.parse:$.parseInline)(o,r);return r.hooks?await r.hooks.postprocess(c):c})().catch(l);try{r.hooks&&(e=r.hooks.preprocess(e));let a=(r.hooks?r.hooks.provideLexer(t):t?R.lex:R.lexInline)(e,r);r.hooks&&(a=r.hooks.processAllTokens(a)),r.walkTokens&&this.walkTokens(a,r.walkTokens);let i=(r.hooks?r.hooks.provideParser(t):t?$.parse:$.parseInline)(a,r);return r.hooks&&(i=r.hooks.postprocess(i)),i}catch(a){return l(a)}}}onError(t,e){return n=>{if(n.message+=`\nPlease report this to https://github.com/markedjs/marked.`,t){let s="<p>An error occurred:</p><pre>"+S(n.message+"",!0)+"</pre>";return e?Promise.resolve(s):s}if(e)return Promise.reject(n);throw n}}},I=new mt;function g(t,e){return I.parse(t,e)}g.options=g.setOptions=function(t){return I.setOptions(t),g.defaults=I.defaults,ke(g.defaults),g};g.getDefaults=V;g.defaults=_;g.use=function(...t){return I.use(...t),g.defaults=I.defaults,ke(g.defaults),g};g.walkTokens=function(t,e){return I.walkTokens(t,e)};g.parseInline=I.parseInline;g.Parser=$;g.parser=$.parse;g.Renderer=Q;g.TextRenderer=se;g.Lexer=R;g.lexer=R.lex;g.Tokenizer=O;g.Hooks=q;g.parse=g;var zt=g.options,At=g.setOptions,Ct=g.use,It=g.walkTokens,_t=g.parseInline;var Pt=$.parse,Mt=R.lex;function Se(t,e,n){let s=0;for(let r=e;r<n;r++)s+=t[r].raw.length;return s}function wt(t,e){let n=t;return n.links=e,n}var yt=/^ {0,3}\\$\\$/m;function Le(t){return t.includes("$$")===!1?!1:yt.test(t)}function Rt(t,e){return t[e-2]?.type!=="list"?!0:e+1<t.length}function ze(t,e){for(let n=t.length-2;n>=e;n--)if(t[n].type==="space"&&Rt(t,n+1)!==!1)return n+1;return-1}function Ae(t){let e=t.links;if(!e)return!1;for(let n in e)return!0;return!1}function Ce(t,e,n,s,r){let l=r;for(let a=e;a<n;a++){let i=t[a].raw;if(s.startsWith(i,l)===!1)return!1;l+=i.length}return!0}function G(t,e,n){return{source:t,tail:t,tokens:e,stableCount:0,stableOffset:0,degraded:!0,degradedReason:n}}function Te(t,e){return{source:t,tail:t,tokens:e,stableCount:0,stableOffset:0,degraded:!1,degradedReason:null}}function $t(t,e){if(Ae(e))return G(t,e,"link-definition");if(t.includes("\\r"))return G(t,e,"carriage-return");if(Le(t))return G(t,e,"block-math");let n=ze(e,1);if(n<0||Ce(e,0,n,t,0)===!1)return Te(t,e);let s=Se(e,0,n);return{source:t,tail:t.slice(s),tokens:e,stableCount:n,stableOffset:s,degraded:!1,degradedReason:null}}function le(t){let e=g.lexer(t);return{tokens:e,cache:$t(t,e),charsLexed:t.length,reusedTokens:0}}function j(t,e){let n=g.lexer(t);return{tokens:n,cache:G(t,n,e),charsLexed:t.length,reusedTokens:0}}function Ie(t,e){let n=t.source+e;if(t.degraded)return j(n,t.degradedReason??"link-definition");if(e.includes("\\r"))return j(n,"carriage-return");if(t.stableCount===0)return le(n);let s=t.tail+e;if(Le(s))return j(n,"block-math");let r=g.lexer(s);if(Ae(r))return j(n,"link-definition");let l=t.tokens.slice(0,t.stableCount),a=wt([...l,...r],r.links),i=t.stableCount,o=t.stableOffset,c=s,u=ze(a,t.stableCount+1);if(u>t.stableCount&&Ce(a,t.stableCount,u,s,0)){let h=Se(a,t.stableCount,u);i=u,o=t.stableOffset+h,c=s.slice(h)}return{tokens:a,cache:{source:n,tail:c,tokens:a,stableCount:i,stableOffset:o,degraded:!1,degradedReason:null},charsLexed:s.length,reusedTokens:t.stableCount}}var Tt=0;function St(t){if(typeof t!="string"||typeof performance.mark!="function"||typeof performance.measure!="function")return null;let e=Tt++,n={name:t,startMark:`${t}:start:${e}`,endMark:`${t}:end:${e}`};try{return performance.mark(n.startMark),n}catch{return null}}function Lt(t){if(t)try{performance.mark(t.endMark),performance.measure(t.name,t.startMark,t.endMark)}catch{}finally{try{performance.clearMarks?.(t.startMark),performance.clearMarks?.(t.endMark)}catch{}}}g.use({extensions:[{name:"blockMath",level:"block",start(t){return t.match(/^ {0,3}\\$\\$/m)?.index},tokenizer(t){let e=/^ {0,3}\\$\\$([\\s\\S]+?)\\$\\$[ \\t]*(?:\\n|$)/.exec(t);if(e)return{type:"blockMath",raw:e[0],text:e[1].trim()}},renderer(t){return t.raw}},{name:"inlineMath",level:"inline",start(t){return t.match(/(?<![\\\\$])\\$(?![$\\s])/)?.index},tokenizer(t){let e=/^\\$(?![$\\s\\d])((?:\\\\\\$|[^$\\n])*?)(?<!\\s)\\$(?!\\d)/.exec(t);if(e)return{type:"inlineMath",raw:e[0],text:e[1].trim()}},renderer(t){return t.raw}}]});var E=new Map;self.onmessage=t=>{let e=t.data;if(typeof e!="object"||e===null)return;let{id:n,text:s,append:r,expectedLength:l,oldRaws:a,instance:i,baseVersion:o,dispose:c,userTimingName:u}=e;if(c===!0){typeof i=="string"&&E.delete(i);return}let h=typeof i=="string"?i:null,p=typeof o=="number"?o:null,d,f=null,m=null;if(typeof r=="string"){if(h===null||p===null){self.postMessage({id:n,needResync:!0});return}let w=E.get(h);if(!w||w.version!==p){self.postMessage({id:n,needResync:!0});return}if(typeof l=="number"&&w.lex.source.length+r.length!==l){E.delete(h),self.postMessage({id:n,needResync:!0});return}let y=w.lex;d=()=>Ie(y,r),m=y.tokens}else if(typeof s=="string"){let w=s;if(d=()=>le(w),Array.isArray(a))f=a;else if(h!==null&&p!==null){let y=E.get(h);if(y&&y.version===p)m=y.lex.tokens;else{self.postMessage({id:n,needResync:!0});return}}}else return;try{let w=typeof u=="string"?St(u):null,y=performance.now(),L;try{L=d()}finally{w&&Lt(w)}let W=performance.now()-y,A=L.tokens,b=0;if(f!==null){let T=Math.min(f.length,A.length);for(;b<T&&f[b]===A[b].raw;b++);}else if(m!==null){let T=m,ie=Math.min(T.length,A.length);for(b=Math.min(L.reusedTokens,ie);b<ie&&T[b].raw===A[b].raw;b++);}h!==null&&p!==null&&E.set(h,{version:p+1,lex:L.cache}),self.postMessage({id:n,matchLen:b,tail:A.slice(b),lexerMs:W,sourceCharsLexed:L.charsLexed})}catch(w){h!==null&&E.delete(h),self.postMessage({id:n,error:String(w)})}};})();\n';
|
|
491
|
-
|
|
492
|
-
// src/Markdown.ts
|
|
493
|
-
var now = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
494
|
-
function lexMarkdown(text, userTiming) {
|
|
495
|
-
if (!userTiming) return marked.lexer(text);
|
|
496
|
-
const timing = beginVectoUserTiming(VECTO_USER_TIMING.markdown.parse);
|
|
497
|
-
try {
|
|
498
|
-
return marked.lexer(text);
|
|
499
|
-
} finally {
|
|
500
|
-
if (timing) endVectoUserTiming(timing);
|
|
434
|
+
render(r) {
|
|
435
|
+
r.beginPath();
|
|
436
|
+
r.moveTo(0, 0);
|
|
437
|
+
r.lineTo(this.width, 0);
|
|
438
|
+
r.stroke(this.color, 1);
|
|
501
439
|
}
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
},
|
|
511
|
-
tokenizer(src) {
|
|
512
|
-
const match = /^ {0,3}\$\$([\s\S]+?)\$\$[ \t]*(?:\n|$)/.exec(src);
|
|
513
|
-
if (match) {
|
|
514
|
-
return {
|
|
515
|
-
type: "blockMath",
|
|
516
|
-
raw: match[0],
|
|
517
|
-
text: match[1].trim()
|
|
518
|
-
};
|
|
519
|
-
}
|
|
520
|
-
return void 0;
|
|
521
|
-
},
|
|
522
|
-
renderer(token) {
|
|
523
|
-
return token.raw;
|
|
524
|
-
}
|
|
525
|
-
},
|
|
526
|
-
{
|
|
527
|
-
name: "inlineMath",
|
|
528
|
-
level: "inline",
|
|
529
|
-
start(src) {
|
|
530
|
-
return src.match(/(?<![\\$])\$(?![$\s])/)?.index;
|
|
531
|
-
},
|
|
532
|
-
tokenizer(src) {
|
|
533
|
-
const match = /^\$(?![$\s\d])((?:\\\$|[^$\n])*?)(?<!\s)\$(?!\d)/.exec(src);
|
|
534
|
-
if (match) {
|
|
535
|
-
return {
|
|
536
|
-
type: "inlineMath",
|
|
537
|
-
raw: match[0],
|
|
538
|
-
text: match[1].trim()
|
|
539
|
-
};
|
|
540
|
-
}
|
|
541
|
-
return void 0;
|
|
542
|
-
},
|
|
543
|
-
renderer(token) {
|
|
544
|
-
return token.raw;
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
]
|
|
548
|
-
});
|
|
549
|
-
var mathConverter = null;
|
|
550
|
-
var mathLoad = null;
|
|
551
|
-
function interop(mod, key) {
|
|
552
|
-
const ns = mod;
|
|
553
|
-
if (typeof ns?.[key] !== "undefined") return ns;
|
|
554
|
-
const fallback = ns?.default;
|
|
555
|
-
if (fallback && typeof fallback[key] !== "undefined") return fallback;
|
|
556
|
-
throw new Error(`mathjax-full module is missing export "${key}"`);
|
|
557
|
-
}
|
|
558
|
-
function preloadMathJax() {
|
|
559
|
-
if (mathLoad) return mathLoad;
|
|
560
|
-
mathLoad = (async () => {
|
|
561
|
-
const [mathjaxMod, texMod, svgMod, adaptorMod, handlerMod, packagesMod] = await Promise.all([
|
|
562
|
-
import("mathjax-full/js/mathjax.js"),
|
|
563
|
-
import("mathjax-full/js/input/tex.js"),
|
|
564
|
-
import("mathjax-full/js/output/svg.js"),
|
|
565
|
-
import("mathjax-full/js/adaptors/liteAdaptor.js"),
|
|
566
|
-
import("mathjax-full/js/handlers/html.js"),
|
|
567
|
-
import("mathjax-full/js/input/tex/AllPackages.js")
|
|
568
|
-
]);
|
|
569
|
-
const { mathjax } = interop(mathjaxMod, "mathjax");
|
|
570
|
-
const { TeX } = interop(texMod, "TeX");
|
|
571
|
-
const { SVG } = interop(svgMod, "SVG");
|
|
572
|
-
const { liteAdaptor } = interop(adaptorMod, "liteAdaptor");
|
|
573
|
-
const { RegisterHTMLHandler } = interop(handlerMod, "RegisterHTMLHandler");
|
|
574
|
-
const { AllPackages } = interop(packagesMod, "AllPackages");
|
|
575
|
-
const adaptor = liteAdaptor();
|
|
576
|
-
RegisterHTMLHandler(adaptor);
|
|
577
|
-
const tex = new TeX({ packages: AllPackages });
|
|
578
|
-
const svg = new SVG({ fontCache: "local" });
|
|
579
|
-
const htmlMathJax = mathjax.document("", { InputJax: tex, OutputJax: svg });
|
|
580
|
-
mathConverter = (formula, displayMode, color) => convertMathToSVGDataURI(
|
|
581
|
-
formula,
|
|
582
|
-
displayMode,
|
|
583
|
-
(f, d) => adaptor.innerHTML(htmlMathJax.convert(f, { display: d })),
|
|
584
|
-
color
|
|
585
|
-
);
|
|
586
|
-
})().catch((e) => {
|
|
587
|
-
console.error("MathJax failed to load; formulas will render as TeX source", e);
|
|
588
|
-
});
|
|
589
|
-
return mathLoad;
|
|
590
|
-
}
|
|
591
|
-
function isMathJaxReady() {
|
|
592
|
-
return mathConverter !== null;
|
|
593
|
-
}
|
|
594
|
-
var EX_PER_EM = 0.4421;
|
|
595
|
-
function exToPx(ex, fontSize) {
|
|
596
|
-
return ex * fontSize * EX_PER_EM;
|
|
597
|
-
}
|
|
598
|
-
function fontSizeFromFont(font) {
|
|
599
|
-
const pxIndex = font.indexOf("px");
|
|
600
|
-
if (pxIndex <= 0) return void 0;
|
|
601
|
-
let start = pxIndex;
|
|
602
|
-
while (start > 0) {
|
|
603
|
-
const ch = font[start - 1];
|
|
604
|
-
if (ch >= "0" && ch <= "9" || ch === ".") start--;
|
|
605
|
-
else break;
|
|
440
|
+
};
|
|
441
|
+
var QuoteBorder = class extends Entity {
|
|
442
|
+
color;
|
|
443
|
+
constructor(height, color, width = 4) {
|
|
444
|
+
super();
|
|
445
|
+
this.width = width;
|
|
446
|
+
this.height = height;
|
|
447
|
+
this.color = color;
|
|
606
448
|
}
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
return Number.isFinite(size) ? size : void 0;
|
|
610
|
-
}
|
|
611
|
-
var mathCache = /* @__PURE__ */ new Map();
|
|
612
|
-
var MATH_CACHE_LIMIT = 256;
|
|
613
|
-
var inlineMathRasters = /* @__PURE__ */ new Map();
|
|
614
|
-
var inlineMathRasterWaiters = /* @__PURE__ */ new Set();
|
|
615
|
-
function ensureInlineMathRaster(uri) {
|
|
616
|
-
const existing = inlineMathRasters.get(uri);
|
|
617
|
-
if (existing) return existing;
|
|
618
|
-
const entry = { decoded: false };
|
|
619
|
-
inlineMathRasters.set(uri, entry);
|
|
620
|
-
if (typeof globalThis.Image !== "undefined") {
|
|
621
|
-
const bitmap = new globalThis.Image();
|
|
622
|
-
bitmap.onload = () => {
|
|
623
|
-
entry.decoded = true;
|
|
624
|
-
for (const notify of inlineMathRasterWaiters) notify();
|
|
625
|
-
};
|
|
626
|
-
bitmap.src = uri;
|
|
627
|
-
entry.bitmap = bitmap;
|
|
449
|
+
isPointInside() {
|
|
450
|
+
return false;
|
|
628
451
|
}
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
if (!raster.decoded || !raster.bitmap) return;
|
|
634
|
-
surface.drawImage(raster.bitmap, box.x, box.y, box.width, box.height);
|
|
635
|
-
}
|
|
636
|
-
var MATH_LANGS = /* @__PURE__ */ new Set(["math", "latex", "tex"]);
|
|
637
|
-
function containsInlineMath(token) {
|
|
638
|
-
if (token.type === "inlineMath") return true;
|
|
639
|
-
const anyToken = token;
|
|
640
|
-
if (Array.isArray(anyToken.tokens) && anyToken.tokens.some(containsInlineMath)) {
|
|
641
|
-
return true;
|
|
452
|
+
render(r) {
|
|
453
|
+
r.beginPath();
|
|
454
|
+
r.roundRect(0, 0, this.width, this.height, this.width / 2);
|
|
455
|
+
r.fill(this.color);
|
|
642
456
|
}
|
|
643
|
-
|
|
644
|
-
|
|
457
|
+
};
|
|
458
|
+
var MarkdownContainer = class extends Entity {
|
|
459
|
+
isPointInside(_globalX, _globalY) {
|
|
460
|
+
return false;
|
|
645
461
|
}
|
|
646
|
-
|
|
647
|
-
return true;
|
|
462
|
+
render(_r) {
|
|
648
463
|
}
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
464
|
+
};
|
|
465
|
+
|
|
466
|
+
// src/markdown-code.ts
|
|
467
|
+
import {
|
|
468
|
+
contentLineInHint,
|
|
469
|
+
GlyphRasterAtlas,
|
|
470
|
+
prepareContentGrid
|
|
471
|
+
} from "@vectojs/core";
|
|
472
|
+
import { measureText, UIComponent } from "@vectojs/ui";
|
|
473
|
+
|
|
474
|
+
// src/theme.ts
|
|
475
|
+
var DEFAULT_THEME = {
|
|
476
|
+
textColor: "#e2e8f0",
|
|
477
|
+
headingColor: "#f8fafc",
|
|
478
|
+
codeColor: "#a5f3fc",
|
|
479
|
+
codeBgColor: "rgba(30, 41, 59, 0.85)",
|
|
480
|
+
quoteBorderColor: "#6366f1",
|
|
481
|
+
quoteTextColor: "#e2e8f0",
|
|
482
|
+
hrColor: "rgba(148, 163, 184, 0.3)",
|
|
483
|
+
tableBgColor: "rgba(15, 15, 25, 0.4)",
|
|
484
|
+
tableHeaderBgColor: "rgba(255, 255, 255, 0.08)",
|
|
485
|
+
linkColor: "#38bdf8",
|
|
486
|
+
mathFallbackColor: "#fcd34d",
|
|
487
|
+
syntaxKeywordColor: "#c084fc",
|
|
488
|
+
syntaxStringColor: "#86efac",
|
|
489
|
+
syntaxCommentColor: "#64748b",
|
|
490
|
+
syntaxNumberColor: "#fbbf24",
|
|
491
|
+
bodyFont: "Inter, system-ui, sans-serif",
|
|
492
|
+
codeFont: 'ui-monospace, "JetBrains Mono", "Fira Code", monospace',
|
|
493
|
+
fontSize: 16,
|
|
494
|
+
headingSizes: [32, 28, 24, 20, 18, 16],
|
|
495
|
+
codeFontSize: 15,
|
|
496
|
+
tableFontSize: 14,
|
|
497
|
+
codeLineHeight: 24,
|
|
498
|
+
bodyLineHeight: 24,
|
|
499
|
+
blockGap: 16,
|
|
500
|
+
codePadding: 18,
|
|
501
|
+
codeRadius: 8,
|
|
502
|
+
listGap: 6,
|
|
503
|
+
listItemGap: 4,
|
|
504
|
+
quoteIndent: 16,
|
|
505
|
+
quoteBorderWidth: 4,
|
|
506
|
+
quoteInnerGap: 8,
|
|
507
|
+
imageRadius: 8,
|
|
508
|
+
inlineImageScale: 1.15
|
|
509
|
+
};
|
|
510
|
+
function resolveTheme(theme) {
|
|
511
|
+
const merged = { ...DEFAULT_THEME, ...theme };
|
|
512
|
+
if (theme?.tableFontSize === void 0) {
|
|
513
|
+
merged.tableFontSize = Math.max(1, merged.fontSize - 2);
|
|
653
514
|
}
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
var FENCE_OPEN_RE = /^ {0,3}(`{3,}|~{3,})/;
|
|
657
|
-
var FENCE_CLOSE_RE = /^ {0,3}(`+|~+)[ \t]*$/;
|
|
658
|
-
function isFenceClosed(raw) {
|
|
659
|
-
const lines = raw.split("\n");
|
|
660
|
-
const open = FENCE_OPEN_RE.exec(lines[0]);
|
|
661
|
-
if (!open) return false;
|
|
662
|
-
const marker = open[1][0];
|
|
663
|
-
const minLen = open[1].length;
|
|
664
|
-
for (let i = 1; i < lines.length; i++) {
|
|
665
|
-
const close = FENCE_CLOSE_RE.exec(lines[i]);
|
|
666
|
-
if (close && close[1][0] === marker && close[1].length >= minLen) return true;
|
|
515
|
+
if (theme?.quoteTextColor === void 0) {
|
|
516
|
+
merged.quoteTextColor = merged.textColor;
|
|
667
517
|
}
|
|
668
|
-
return
|
|
518
|
+
return merged;
|
|
669
519
|
}
|
|
670
|
-
function
|
|
671
|
-
|
|
520
|
+
function headingSize(theme, depth) {
|
|
521
|
+
const sizes = theme.headingSizes;
|
|
522
|
+
if (sizes.length === 0) return theme.fontSize;
|
|
523
|
+
const idx = Math.min(Math.max(depth, 1) - 1, sizes.length - 1);
|
|
524
|
+
return sizes[idx] ?? theme.fontSize;
|
|
672
525
|
}
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
if (tokens[i].type === "image") return i;
|
|
676
|
-
}
|
|
677
|
-
return -1;
|
|
678
|
-
}
|
|
679
|
-
function expectedImageParagraphChildren(tokens) {
|
|
680
|
-
let children = 0;
|
|
681
|
-
let inTextRun = false;
|
|
682
|
-
for (const token of tokens) {
|
|
683
|
-
if (token.type === "image") {
|
|
684
|
-
children++;
|
|
685
|
-
inTextRun = false;
|
|
686
|
-
} else if (!inTextRun) {
|
|
687
|
-
children++;
|
|
688
|
-
inTextRun = true;
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
return children;
|
|
692
|
-
}
|
|
693
|
-
function rendersAsMath(token) {
|
|
694
|
-
return MATH_LANGS.has((token.lang ?? "").toLowerCase()) && token.text.trim() !== "" && isFenceClosed(token.raw);
|
|
695
|
-
}
|
|
696
|
-
function renderMathToSVGDataURI(formula, displayMode, color) {
|
|
697
|
-
const key = `${displayMode ? 1 : 0}\0${color}\0${formula}`;
|
|
698
|
-
const hit = mathCache.get(key);
|
|
699
|
-
if (hit) return hit;
|
|
700
|
-
if (!mathConverter) return null;
|
|
701
|
-
const converted = mathConverter(formula, displayMode, color);
|
|
702
|
-
if (converted) {
|
|
703
|
-
if (mathCache.size >= MATH_CACHE_LIMIT) {
|
|
704
|
-
const oldest = mathCache.keys().next().value;
|
|
705
|
-
if (oldest !== void 0) mathCache.delete(oldest);
|
|
706
|
-
}
|
|
707
|
-
mathCache.set(key, converted);
|
|
708
|
-
}
|
|
709
|
-
return converted;
|
|
710
|
-
}
|
|
711
|
-
function applyMathColor(svg, color) {
|
|
712
|
-
const openTag = svg.match(/<svg\b[^>]*>/);
|
|
713
|
-
if (!openTag) return svg;
|
|
714
|
-
const tag = openTag[0];
|
|
715
|
-
const colored = /\bstyle="/.test(tag) ? tag.replace(/\bstyle="/, `style="color:${color};`) : tag.replace(/^<svg\b/, `<svg style="color:${color}"`);
|
|
716
|
-
return svg.replace(tag, colored);
|
|
717
|
-
}
|
|
718
|
-
function convertMathToSVGDataURI(formula, displayMode, typeset, color) {
|
|
719
|
-
try {
|
|
720
|
-
const svgString = applyMathColor(typeset(formula, displayMode), color);
|
|
721
|
-
const wMatch = svgString.match(/width="([^"]+)ex"/);
|
|
722
|
-
const hMatch = svgString.match(/height="([^"]+)ex"/);
|
|
723
|
-
const wEx = wMatch ? parseFloat(wMatch[1]) : 10;
|
|
724
|
-
const hEx = hMatch ? parseFloat(hMatch[1]) : 2;
|
|
725
|
-
const vMatch = svgString.match(/vertical-align:\s*(-?[\d.]+)ex/);
|
|
726
|
-
const depthEx = vMatch ? Math.max(0, -parseFloat(vMatch[1])) : 0;
|
|
727
|
-
const base64 = btoa(unescape(encodeURIComponent(svgString)));
|
|
728
|
-
return {
|
|
729
|
-
uri: `data:image/svg+xml;base64,${base64}`,
|
|
730
|
-
widthEx: wEx,
|
|
731
|
-
heightEx: hEx,
|
|
732
|
-
depthEx
|
|
733
|
-
};
|
|
734
|
-
} catch (e) {
|
|
735
|
-
console.error("MathJax error", e);
|
|
736
|
-
return null;
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
var markdownWorker = null;
|
|
740
|
-
var workerIdCounter = 0;
|
|
741
|
-
var workerInstanceCounter = 0;
|
|
742
|
-
var workerCallbacks = /* @__PURE__ */ new Map();
|
|
743
|
-
function runSyncFallback(entry) {
|
|
744
|
-
try {
|
|
745
|
-
entry.cb(0, lexMarkdown(entry.text, entry.userTiming), true);
|
|
746
|
-
} catch (err) {
|
|
747
|
-
console.warn("Markdown sync fallback parse failed", err);
|
|
748
|
-
entry.onDropped?.();
|
|
749
|
-
}
|
|
750
|
-
}
|
|
751
|
-
if (typeof Worker !== "undefined") {
|
|
752
|
-
try {
|
|
753
|
-
const blob = new Blob([WORKER_SOURCE_STRING], {
|
|
754
|
-
type: "application/javascript"
|
|
755
|
-
});
|
|
756
|
-
markdownWorker = new Worker(URL.createObjectURL(blob));
|
|
757
|
-
markdownWorker.onmessage = (e) => {
|
|
758
|
-
const { id, matchLen, tail, error, needResync, lexerMs, sourceCharsLexed } = e.data;
|
|
759
|
-
const entry = workerCallbacks.get(id);
|
|
760
|
-
if (entry) {
|
|
761
|
-
workerCallbacks.delete(id);
|
|
762
|
-
if (needResync && entry.onNeedResync) {
|
|
763
|
-
entry.onNeedResync();
|
|
764
|
-
} else if (needResync) {
|
|
765
|
-
runSyncFallback(entry);
|
|
766
|
-
} else if (!error) {
|
|
767
|
-
entry.cb(matchLen, tail, false, {
|
|
768
|
-
lexerMs: typeof lexerMs === "number" ? lexerMs : 0,
|
|
769
|
-
sourceCharsLexed: typeof sourceCharsLexed === "number" ? sourceCharsLexed : 0
|
|
770
|
-
});
|
|
771
|
-
} else {
|
|
772
|
-
runSyncFallback(entry);
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
};
|
|
776
|
-
markdownWorker.onerror = () => {
|
|
777
|
-
const pending = [...workerCallbacks.values()];
|
|
778
|
-
workerCallbacks.clear();
|
|
779
|
-
markdownWorker = null;
|
|
780
|
-
for (const entry of pending) runSyncFallback(entry);
|
|
781
|
-
};
|
|
782
|
-
} catch (err) {
|
|
783
|
-
console.warn("Failed to initialize MarkdownWorker", err);
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
var DEFAULT_THEME = {
|
|
787
|
-
textColor: "#e2e8f0",
|
|
788
|
-
headingColor: "#f8fafc",
|
|
789
|
-
codeColor: "#a5f3fc",
|
|
790
|
-
codeBgColor: "rgba(30, 41, 59, 0.85)",
|
|
791
|
-
quoteBorderColor: "#6366f1",
|
|
792
|
-
quoteTextColor: "#94a3b8",
|
|
793
|
-
hrColor: "rgba(148, 163, 184, 0.3)",
|
|
794
|
-
tableBgColor: "rgba(15, 15, 25, 0.4)",
|
|
795
|
-
tableHeaderBgColor: "rgba(255, 255, 255, 0.08)",
|
|
796
|
-
bodyFont: "Inter, system-ui, sans-serif",
|
|
797
|
-
codeFont: 'ui-monospace, "JetBrains Mono", "Fira Code", monospace',
|
|
798
|
-
fontSize: 16
|
|
799
|
-
};
|
|
800
|
-
var HorizontalRule = class extends Entity {
|
|
801
|
-
color;
|
|
802
|
-
constructor(w, color) {
|
|
803
|
-
super();
|
|
804
|
-
this.width = w;
|
|
805
|
-
this.height = 1;
|
|
806
|
-
this.color = color;
|
|
807
|
-
}
|
|
808
|
-
isPointInside() {
|
|
809
|
-
return false;
|
|
810
|
-
}
|
|
811
|
-
render(r) {
|
|
812
|
-
r.beginPath();
|
|
813
|
-
r.moveTo(0, 0);
|
|
814
|
-
r.lineTo(this.width, 0);
|
|
815
|
-
r.stroke(this.color, 1);
|
|
816
|
-
}
|
|
817
|
-
};
|
|
818
|
-
var QuoteBorder = class extends Entity {
|
|
819
|
-
color;
|
|
820
|
-
constructor(height, color) {
|
|
821
|
-
super();
|
|
822
|
-
this.width = 4;
|
|
823
|
-
this.height = height;
|
|
824
|
-
this.color = color;
|
|
825
|
-
}
|
|
826
|
-
isPointInside() {
|
|
827
|
-
return false;
|
|
828
|
-
}
|
|
829
|
-
render(r) {
|
|
830
|
-
r.beginPath();
|
|
831
|
-
r.roundRect(0, 0, this.width, this.height, 2);
|
|
832
|
-
r.fill(this.color);
|
|
833
|
-
}
|
|
834
|
-
};
|
|
835
|
-
var MarkdownContainer = class extends Entity {
|
|
836
|
-
isPointInside(_globalX, _globalY) {
|
|
837
|
-
return false;
|
|
838
|
-
}
|
|
839
|
-
render(_r) {
|
|
840
|
-
}
|
|
841
|
-
};
|
|
842
|
-
var MathBlock = class extends MarkdownContainer {
|
|
843
|
-
/**
|
|
844
|
-
* The TeX source, exactly as written between the delimiters.
|
|
845
|
-
*
|
|
846
|
-
* Also the projected text and the accessible name, so this is the one string a
|
|
847
|
-
* reader can find, select, and copy.
|
|
848
|
-
*/
|
|
849
|
-
formula;
|
|
850
|
-
/** The `data:image/svg+xml` URI of the typeset glyphs. */
|
|
851
|
-
svgUri;
|
|
852
|
-
constructor(formula, svgUri) {
|
|
853
|
-
super();
|
|
854
|
-
this.formula = formula;
|
|
855
|
-
this.svgUri = svgUri;
|
|
856
|
-
}
|
|
857
|
-
getDevtoolsDescriptor() {
|
|
858
|
-
return {
|
|
859
|
-
kind: "MathBlock",
|
|
860
|
-
groups: [
|
|
861
|
-
{
|
|
862
|
-
label: "Math",
|
|
863
|
-
fields: [{ label: "formula", value: this.formula, readOnly: true }]
|
|
864
|
-
}
|
|
865
|
-
]
|
|
866
|
-
};
|
|
867
|
-
}
|
|
868
|
-
};
|
|
526
|
+
|
|
527
|
+
// src/markdown-code.ts
|
|
869
528
|
var KEYWORD_SETS = {
|
|
870
529
|
js: /* @__PURE__ */ new Set([
|
|
871
530
|
"const",
|
|
@@ -1040,10 +699,10 @@ function highlightLine(line, lang, theme) {
|
|
|
1040
699
|
return [{ text: line, color: theme.codeColor }];
|
|
1041
700
|
}
|
|
1042
701
|
const segments = [];
|
|
1043
|
-
const KEYWORD_COLOR =
|
|
1044
|
-
const STRING_COLOR =
|
|
1045
|
-
const COMMENT_COLOR =
|
|
1046
|
-
const NUMBER_COLOR =
|
|
702
|
+
const KEYWORD_COLOR = theme.syntaxKeywordColor;
|
|
703
|
+
const STRING_COLOR = theme.syntaxStringColor;
|
|
704
|
+
const COMMENT_COLOR = theme.syntaxCommentColor;
|
|
705
|
+
const NUMBER_COLOR = theme.syntaxNumberColor;
|
|
1047
706
|
let i = 0;
|
|
1048
707
|
let buf = "";
|
|
1049
708
|
const flush = (color) => {
|
|
@@ -1126,16 +785,32 @@ var CodeBlock = class extends UIComponent {
|
|
|
1126
785
|
contentEpoch = 0;
|
|
1127
786
|
lang;
|
|
1128
787
|
theme;
|
|
1129
|
-
|
|
1130
|
-
|
|
788
|
+
/**
|
|
789
|
+
* Assigned in the constructor rather than as a field initializer: both come
|
|
790
|
+
* from `theme`, and a field initializer runs before the constructor body has
|
|
791
|
+
* a `theme` to read.
|
|
792
|
+
*/
|
|
793
|
+
lineH;
|
|
794
|
+
pad;
|
|
1131
795
|
codeFont;
|
|
1132
796
|
selectable;
|
|
797
|
+
/**
|
|
798
|
+
* @param theme Any subset of {@link MarkdownTheme}; missing keys fall back to
|
|
799
|
+
* `DEFAULT_THEME` in `./theme`. Accepting a partial theme keeps callers that were
|
|
800
|
+
* written against an earlier, smaller `MarkdownTheme` working — this class
|
|
801
|
+
* is public API, and a hand-built theme literal would otherwise start
|
|
802
|
+
* throwing `lineHeight must be a positive finite number` the moment a new
|
|
803
|
+
* size key was added.
|
|
804
|
+
*/
|
|
1133
805
|
constructor(code, lang, maxWidth, theme, selectable = true) {
|
|
1134
806
|
super();
|
|
807
|
+
const resolved = resolveTheme(theme);
|
|
1135
808
|
this.source = code;
|
|
1136
809
|
this.lang = lang;
|
|
1137
|
-
this.theme =
|
|
1138
|
-
this.
|
|
810
|
+
this.theme = resolved;
|
|
811
|
+
this.lineH = resolved.codeLineHeight;
|
|
812
|
+
this.pad = resolved.codePadding;
|
|
813
|
+
this.codeFont = `${resolved.codeFontSize}px ${resolved.codeFont}`;
|
|
1139
814
|
this.selectable = selectable;
|
|
1140
815
|
this.lines = [];
|
|
1141
816
|
this.width = maxWidth;
|
|
@@ -1265,7 +940,7 @@ var CodeBlock = class extends UIComponent {
|
|
|
1265
940
|
}
|
|
1266
941
|
render(r) {
|
|
1267
942
|
r.beginPath();
|
|
1268
|
-
r.roundRect(0, 0, this.width, this.height,
|
|
943
|
+
r.roundRect(0, 0, this.width, this.height, this.theme.codeRadius);
|
|
1269
944
|
r.fill(this.theme.codeBgColor);
|
|
1270
945
|
const grid = this.ensureGrid();
|
|
1271
946
|
const atlas = codeGlyphAtlas(r);
|
|
@@ -1345,6 +1020,302 @@ function codeAtlasStats() {
|
|
|
1345
1020
|
function codeAtlas() {
|
|
1346
1021
|
return lastCodeAtlas;
|
|
1347
1022
|
}
|
|
1023
|
+
|
|
1024
|
+
// src/markdown-math.ts
|
|
1025
|
+
var mathConverter = null;
|
|
1026
|
+
var mathLoad = null;
|
|
1027
|
+
function preloadMathJax() {
|
|
1028
|
+
if (mathLoad) return mathLoad;
|
|
1029
|
+
mathLoad = (async () => {
|
|
1030
|
+
const { emitSVG, layout } = await import("@vectojs/tex");
|
|
1031
|
+
mathConverter = (formula, displayMode, color) => convertMathToSVGDataURI(formula, displayMode, color, layout, emitSVG);
|
|
1032
|
+
})().catch((e) => {
|
|
1033
|
+
console.error("Math engine failed to load; formulas will render as TeX source", e);
|
|
1034
|
+
});
|
|
1035
|
+
return mathLoad;
|
|
1036
|
+
}
|
|
1037
|
+
function isMathJaxReady() {
|
|
1038
|
+
return mathConverter !== null;
|
|
1039
|
+
}
|
|
1040
|
+
var EX_PER_EM = 0.4421;
|
|
1041
|
+
function exToPx(ex, fontSize) {
|
|
1042
|
+
return ex * fontSize * EX_PER_EM;
|
|
1043
|
+
}
|
|
1044
|
+
function fontSizeFromFont(font) {
|
|
1045
|
+
const pxIndex = font.indexOf("px");
|
|
1046
|
+
if (pxIndex <= 0) return void 0;
|
|
1047
|
+
let start = pxIndex;
|
|
1048
|
+
while (start > 0) {
|
|
1049
|
+
const ch = font[start - 1];
|
|
1050
|
+
if (ch >= "0" && ch <= "9" || ch === ".") start--;
|
|
1051
|
+
else break;
|
|
1052
|
+
}
|
|
1053
|
+
if (start === pxIndex) return void 0;
|
|
1054
|
+
const size = parseFloat(font.slice(start, pxIndex));
|
|
1055
|
+
return Number.isFinite(size) ? size : void 0;
|
|
1056
|
+
}
|
|
1057
|
+
var mathCache = /* @__PURE__ */ new Map();
|
|
1058
|
+
var MATH_CACHE_LIMIT = 256;
|
|
1059
|
+
var inlineMathRasters = /* @__PURE__ */ new Map();
|
|
1060
|
+
var inlineMathRasterWaiters = /* @__PURE__ */ new Set();
|
|
1061
|
+
function subscribeInlineMathRaster(notify) {
|
|
1062
|
+
inlineMathRasterWaiters.add(notify);
|
|
1063
|
+
}
|
|
1064
|
+
function unsubscribeInlineMathRaster(notify) {
|
|
1065
|
+
inlineMathRasterWaiters.delete(notify);
|
|
1066
|
+
}
|
|
1067
|
+
function ensureInlineMathRaster(uri) {
|
|
1068
|
+
const existing = inlineMathRasters.get(uri);
|
|
1069
|
+
if (existing) return existing;
|
|
1070
|
+
const entry = { decoded: false };
|
|
1071
|
+
inlineMathRasters.set(uri, entry);
|
|
1072
|
+
if (typeof globalThis.Image !== "undefined") {
|
|
1073
|
+
const bitmap = new globalThis.Image();
|
|
1074
|
+
bitmap.onload = () => {
|
|
1075
|
+
entry.decoded = true;
|
|
1076
|
+
for (const notify of inlineMathRasterWaiters) notify();
|
|
1077
|
+
};
|
|
1078
|
+
bitmap.src = uri;
|
|
1079
|
+
entry.bitmap = bitmap;
|
|
1080
|
+
}
|
|
1081
|
+
return entry;
|
|
1082
|
+
}
|
|
1083
|
+
function paintInlineMath(uri, surface, box) {
|
|
1084
|
+
const raster = ensureInlineMathRaster(uri);
|
|
1085
|
+
if (!raster.decoded || !raster.bitmap) return;
|
|
1086
|
+
surface.drawImage(raster.bitmap, box.x, box.y, box.width, box.height);
|
|
1087
|
+
}
|
|
1088
|
+
var MATH_LANGS = /* @__PURE__ */ new Set(["math", "latex", "tex"]);
|
|
1089
|
+
function containsInlineMath(token) {
|
|
1090
|
+
if (token.type === "inlineMath") return true;
|
|
1091
|
+
const anyToken = token;
|
|
1092
|
+
if (Array.isArray(anyToken.tokens) && anyToken.tokens.some(containsInlineMath)) {
|
|
1093
|
+
return true;
|
|
1094
|
+
}
|
|
1095
|
+
if (Array.isArray(anyToken.items) && anyToken.items.some(containsInlineMath)) {
|
|
1096
|
+
return true;
|
|
1097
|
+
}
|
|
1098
|
+
if (Array.isArray(anyToken.header) && anyToken.header.some(containsInlineMath)) {
|
|
1099
|
+
return true;
|
|
1100
|
+
}
|
|
1101
|
+
if (Array.isArray(anyToken.rows)) {
|
|
1102
|
+
for (const row of anyToken.rows) {
|
|
1103
|
+
if (Array.isArray(row) && row.some(containsInlineMath)) return true;
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
return false;
|
|
1107
|
+
}
|
|
1108
|
+
var FENCE_OPEN_RE = /^ {0,3}(`{3,}|~{3,})/;
|
|
1109
|
+
var FENCE_CLOSE_RE = /^ {0,3}(`+|~+)[ \t]*$/;
|
|
1110
|
+
function isFenceClosed(raw) {
|
|
1111
|
+
const lines = raw.split("\n");
|
|
1112
|
+
const open = FENCE_OPEN_RE.exec(lines[0]);
|
|
1113
|
+
if (!open) return false;
|
|
1114
|
+
const marker = open[1][0];
|
|
1115
|
+
const minLen = open[1].length;
|
|
1116
|
+
for (let i = 1; i < lines.length; i++) {
|
|
1117
|
+
const close = FENCE_CLOSE_RE.exec(lines[i]);
|
|
1118
|
+
if (close && close[1][0] === marker && close[1].length >= minLen) return true;
|
|
1119
|
+
}
|
|
1120
|
+
return false;
|
|
1121
|
+
}
|
|
1122
|
+
function rendersAsMath(token) {
|
|
1123
|
+
return MATH_LANGS.has((token.lang ?? "").toLowerCase()) && token.text.trim() !== "" && isFenceClosed(token.raw);
|
|
1124
|
+
}
|
|
1125
|
+
function renderMathToSVGDataURI(formula, displayMode, color) {
|
|
1126
|
+
const key = `${displayMode ? 1 : 0}\0${color}\0${formula}`;
|
|
1127
|
+
const hit = mathCache.get(key);
|
|
1128
|
+
if (hit) return hit;
|
|
1129
|
+
if (!mathConverter) return null;
|
|
1130
|
+
const converted = mathConverter(formula, displayMode, color);
|
|
1131
|
+
if (converted) {
|
|
1132
|
+
if (mathCache.size >= MATH_CACHE_LIMIT) {
|
|
1133
|
+
const oldest = mathCache.keys().next().value;
|
|
1134
|
+
if (oldest !== void 0) mathCache.delete(oldest);
|
|
1135
|
+
}
|
|
1136
|
+
mathCache.set(key, converted);
|
|
1137
|
+
}
|
|
1138
|
+
return converted;
|
|
1139
|
+
}
|
|
1140
|
+
var MATH_PAD_EM = 0.05;
|
|
1141
|
+
var KATEX_FONT_SCALE = 1.21;
|
|
1142
|
+
var EX_PER_KATEX_EM = KATEX_FONT_SCALE / EX_PER_EM;
|
|
1143
|
+
function convertMathToSVGDataURI(formula, displayMode, color, layout, emitSVG) {
|
|
1144
|
+
try {
|
|
1145
|
+
const emitted = emitSVG(layout(formula, { displayMode }), {
|
|
1146
|
+
color,
|
|
1147
|
+
padEm: MATH_PAD_EM
|
|
1148
|
+
});
|
|
1149
|
+
if (emitted.missing.length > 0) return null;
|
|
1150
|
+
const pad2 = MATH_PAD_EM * 2;
|
|
1151
|
+
const base64 = btoa(unescape(encodeURIComponent(emitted.svg)));
|
|
1152
|
+
return {
|
|
1153
|
+
uri: `data:image/svg+xml;base64,${base64}`,
|
|
1154
|
+
widthEx: (emitted.width + pad2) * EX_PER_KATEX_EM,
|
|
1155
|
+
heightEx: (emitted.height + emitted.depth + pad2) * EX_PER_KATEX_EM,
|
|
1156
|
+
depthEx: (emitted.depth + MATH_PAD_EM) * EX_PER_KATEX_EM
|
|
1157
|
+
};
|
|
1158
|
+
} catch (e) {
|
|
1159
|
+
console.error("Math typesetting error", e);
|
|
1160
|
+
return null;
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
var MathBlock = class extends MarkdownContainer {
|
|
1164
|
+
/**
|
|
1165
|
+
* The TeX source, exactly as written between the delimiters.
|
|
1166
|
+
*
|
|
1167
|
+
* Also the projected text and the accessible name, so this is the one string a
|
|
1168
|
+
* reader can find, select, and copy.
|
|
1169
|
+
*/
|
|
1170
|
+
formula;
|
|
1171
|
+
/** The `data:image/svg+xml` URI of the typeset glyphs. */
|
|
1172
|
+
svgUri;
|
|
1173
|
+
constructor(formula, svgUri) {
|
|
1174
|
+
super();
|
|
1175
|
+
this.formula = formula;
|
|
1176
|
+
this.svgUri = svgUri;
|
|
1177
|
+
}
|
|
1178
|
+
getDevtoolsDescriptor() {
|
|
1179
|
+
return {
|
|
1180
|
+
kind: "MathBlock",
|
|
1181
|
+
groups: [
|
|
1182
|
+
{
|
|
1183
|
+
label: "Math",
|
|
1184
|
+
fields: [{ label: "formula", value: this.formula, readOnly: true }]
|
|
1185
|
+
}
|
|
1186
|
+
]
|
|
1187
|
+
};
|
|
1188
|
+
}
|
|
1189
|
+
};
|
|
1190
|
+
|
|
1191
|
+
// src/markdown-inline.ts
|
|
1192
|
+
import { OBJECT_REPLACEMENT } from "@vectojs/core";
|
|
1193
|
+
import { RichText } from "@vectojs/ui";
|
|
1194
|
+
|
|
1195
|
+
// src/markdown-image.ts
|
|
1196
|
+
function paragraphHasImage(token) {
|
|
1197
|
+
return containsImage(token.tokens);
|
|
1198
|
+
}
|
|
1199
|
+
function containsImage(tokens) {
|
|
1200
|
+
if (!tokens) return false;
|
|
1201
|
+
for (const token of tokens) {
|
|
1202
|
+
if (token.type === "image") return true;
|
|
1203
|
+
const anyToken = token;
|
|
1204
|
+
if (containsImage(anyToken.tokens)) return true;
|
|
1205
|
+
if (Array.isArray(anyToken.items) && containsImage(anyToken.items)) {
|
|
1206
|
+
return true;
|
|
1207
|
+
}
|
|
1208
|
+
const table = token;
|
|
1209
|
+
if (Array.isArray(table.header) && table.header.some((cell) => containsImage(cell.tokens))) {
|
|
1210
|
+
return true;
|
|
1211
|
+
}
|
|
1212
|
+
if (Array.isArray(table.rows) && table.rows.some((row) => row.some((cell) => containsImage(cell.tokens)))) {
|
|
1213
|
+
return true;
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
return false;
|
|
1217
|
+
}
|
|
1218
|
+
function imagesOf(tokens) {
|
|
1219
|
+
const images = [];
|
|
1220
|
+
for (const token of tokens ?? []) {
|
|
1221
|
+
if (token.type === "image") {
|
|
1222
|
+
images.push(token);
|
|
1223
|
+
continue;
|
|
1224
|
+
}
|
|
1225
|
+
images.push(...imagesOf(token.tokens));
|
|
1226
|
+
}
|
|
1227
|
+
return images;
|
|
1228
|
+
}
|
|
1229
|
+
function stripImages(token) {
|
|
1230
|
+
const children = token.tokens;
|
|
1231
|
+
if (!children) return token;
|
|
1232
|
+
const kept = [];
|
|
1233
|
+
for (const child of children) {
|
|
1234
|
+
if (child.type === "image") continue;
|
|
1235
|
+
const grandchildren = child.tokens;
|
|
1236
|
+
if (grandchildren && containsImage(grandchildren)) {
|
|
1237
|
+
const stripped = stripImages(child);
|
|
1238
|
+
const remaining = stripped.tokens;
|
|
1239
|
+
if (remaining && remaining.length > 0) kept.push(stripped);
|
|
1240
|
+
continue;
|
|
1241
|
+
}
|
|
1242
|
+
kept.push(child);
|
|
1243
|
+
}
|
|
1244
|
+
return { ...token, tokens: kept };
|
|
1245
|
+
}
|
|
1246
|
+
function liftNestedImages(tokens) {
|
|
1247
|
+
const lifted = [];
|
|
1248
|
+
for (const token of tokens) {
|
|
1249
|
+
if (token.type === "image") {
|
|
1250
|
+
lifted.push(token);
|
|
1251
|
+
continue;
|
|
1252
|
+
}
|
|
1253
|
+
const children = token.tokens;
|
|
1254
|
+
if (children && containsImage(children)) {
|
|
1255
|
+
lifted.push(...liftNestedImages(children));
|
|
1256
|
+
continue;
|
|
1257
|
+
}
|
|
1258
|
+
lifted.push(token);
|
|
1259
|
+
}
|
|
1260
|
+
return lifted;
|
|
1261
|
+
}
|
|
1262
|
+
function lastIndexOfImage(tokens) {
|
|
1263
|
+
for (let i = tokens.length - 1; i >= 0; i--) {
|
|
1264
|
+
if (tokens[i].type === "image") return i;
|
|
1265
|
+
}
|
|
1266
|
+
return -1;
|
|
1267
|
+
}
|
|
1268
|
+
var inlineImageRasters = /* @__PURE__ */ new Map();
|
|
1269
|
+
var inlineImageRasterWaiters = /* @__PURE__ */ new Set();
|
|
1270
|
+
function subscribeInlineImageRaster(notify) {
|
|
1271
|
+
inlineImageRasterWaiters.add(notify);
|
|
1272
|
+
}
|
|
1273
|
+
function unsubscribeInlineImageRaster(notify) {
|
|
1274
|
+
inlineImageRasterWaiters.delete(notify);
|
|
1275
|
+
}
|
|
1276
|
+
function ensureInlineImageRaster(src) {
|
|
1277
|
+
const existing = inlineImageRasters.get(src);
|
|
1278
|
+
if (existing) return existing;
|
|
1279
|
+
const entry = { decoded: false };
|
|
1280
|
+
inlineImageRasters.set(src, entry);
|
|
1281
|
+
if (typeof globalThis.Image !== "undefined") {
|
|
1282
|
+
const bitmap = new globalThis.Image();
|
|
1283
|
+
bitmap.onload = () => {
|
|
1284
|
+
entry.decoded = true;
|
|
1285
|
+
entry.naturalWidth = bitmap.naturalWidth || void 0;
|
|
1286
|
+
entry.naturalHeight = bitmap.naturalHeight || void 0;
|
|
1287
|
+
for (const notify of inlineImageRasterWaiters) notify();
|
|
1288
|
+
};
|
|
1289
|
+
bitmap.onerror = () => {
|
|
1290
|
+
entry.failed = true;
|
|
1291
|
+
for (const notify of inlineImageRasterWaiters) notify();
|
|
1292
|
+
};
|
|
1293
|
+
bitmap.src = src;
|
|
1294
|
+
entry.bitmap = bitmap;
|
|
1295
|
+
}
|
|
1296
|
+
return entry;
|
|
1297
|
+
}
|
|
1298
|
+
function paintInlineImage(src, surface, box) {
|
|
1299
|
+
const raster = ensureInlineImageRaster(src);
|
|
1300
|
+
if (!raster.decoded || !raster.bitmap) return;
|
|
1301
|
+
surface.drawImage(raster.bitmap, box.x, box.y, box.width, box.height);
|
|
1302
|
+
}
|
|
1303
|
+
function expectedImageParagraphChildren(tokens) {
|
|
1304
|
+
let children = 0;
|
|
1305
|
+
let inTextRun = false;
|
|
1306
|
+
for (const token of liftNestedImages(tokens)) {
|
|
1307
|
+
if (token.type === "image") {
|
|
1308
|
+
children++;
|
|
1309
|
+
inTextRun = false;
|
|
1310
|
+
} else if (!inTextRun) {
|
|
1311
|
+
children++;
|
|
1312
|
+
inTextRun = true;
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
return children;
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
// src/markdown-inline.ts
|
|
1348
1319
|
function decodeEntities(text) {
|
|
1349
1320
|
return text.replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/&/g, "&");
|
|
1350
1321
|
}
|
|
@@ -1437,17 +1408,50 @@ function collectSpans(tokens, inherited, theme, out, blockFontSize) {
|
|
|
1437
1408
|
} else {
|
|
1438
1409
|
out.push({
|
|
1439
1410
|
text: decodeEntities(t.raw),
|
|
1440
|
-
style: { ...inherited, color:
|
|
1411
|
+
style: { ...inherited, color: theme.mathFallbackColor }
|
|
1441
1412
|
});
|
|
1442
1413
|
}
|
|
1443
1414
|
break;
|
|
1444
1415
|
}
|
|
1416
|
+
case "image": {
|
|
1417
|
+
const t = token;
|
|
1418
|
+
const runSize = inherited.fontSize ?? blockFontSize ?? theme.fontSize;
|
|
1419
|
+
const raster = ensureInlineImageRaster(t.href);
|
|
1420
|
+
if (raster.failed) {
|
|
1421
|
+
out.push({ text: decodeEntities(t.text), style: inherited });
|
|
1422
|
+
break;
|
|
1423
|
+
}
|
|
1424
|
+
const height = runSize * theme.inlineImageScale;
|
|
1425
|
+
const aspect = raster.naturalWidth && raster.naturalHeight ? raster.naturalWidth / raster.naturalHeight : 1;
|
|
1426
|
+
const src = t.href;
|
|
1427
|
+
out.push({
|
|
1428
|
+
text: OBJECT_REPLACEMENT,
|
|
1429
|
+
style: inherited,
|
|
1430
|
+
object: {
|
|
1431
|
+
width: height * aspect,
|
|
1432
|
+
height,
|
|
1433
|
+
// Sits on the baseline like a cap-height glyph rather than hanging
|
|
1434
|
+
// below it; an image has no descender to align.
|
|
1435
|
+
depth: 0,
|
|
1436
|
+
// The accessible name, and what a copy yields. Without it the
|
|
1437
|
+
// invisible U+FFFC sentinel is all a screen reader receives.
|
|
1438
|
+
alt: t.text,
|
|
1439
|
+
// What this object PAINTS, which `alt` does not determine: two badges
|
|
1440
|
+
// can share alt text and differ in URL. Without it the paragraph memo
|
|
1441
|
+
// serves the first one's painter to the second and every row of a badge
|
|
1442
|
+
// column draws the first row's badge.
|
|
1443
|
+
key: src,
|
|
1444
|
+
paint: (surface, box) => paintInlineImage(src, surface, box)
|
|
1445
|
+
}
|
|
1446
|
+
});
|
|
1447
|
+
break;
|
|
1448
|
+
}
|
|
1445
1449
|
case "link": {
|
|
1446
1450
|
const t = token;
|
|
1447
1451
|
const linkStyle = {
|
|
1448
1452
|
...inherited,
|
|
1449
1453
|
href: t.href,
|
|
1450
|
-
color:
|
|
1454
|
+
color: theme.linkColor
|
|
1451
1455
|
};
|
|
1452
1456
|
if (t.tokens && t.tokens.length > 0) {
|
|
1453
1457
|
collectSpans(t.tokens, linkStyle, theme, out, blockFontSize);
|
|
@@ -1482,56 +1486,484 @@ function collectSpans(tokens, inherited, theme, out, blockFontSize) {
|
|
|
1482
1486
|
}
|
|
1483
1487
|
}
|
|
1484
1488
|
}
|
|
1485
|
-
function findUnclosedInline(text) {
|
|
1486
|
-
let best = null;
|
|
1487
|
-
const tick = text.lastIndexOf("`");
|
|
1488
|
-
if (tick !== -1 && tick < text.length - 1) {
|
|
1489
|
-
return { kind: "codespan", at: tick, contentAt: tick + 1 };
|
|
1489
|
+
function findUnclosedInline(text) {
|
|
1490
|
+
let best = null;
|
|
1491
|
+
const tick = text.lastIndexOf("`");
|
|
1492
|
+
if (tick !== -1 && tick < text.length - 1) {
|
|
1493
|
+
return { kind: "codespan", at: tick, contentAt: tick + 1 };
|
|
1494
|
+
}
|
|
1495
|
+
if (tick !== -1) return null;
|
|
1496
|
+
const emphasis = /(\*{1,2}(?!\*)|_{1,2}(?!_))(?=[^\s])/g;
|
|
1497
|
+
for (let match = emphasis.exec(text); match !== null; match = emphasis.exec(text)) {
|
|
1498
|
+
const marker = match[1];
|
|
1499
|
+
const at = match.index;
|
|
1500
|
+
if (marker[0] === "_" && at > 0 && /[\w]/.test(text[at - 1])) continue;
|
|
1501
|
+
best = {
|
|
1502
|
+
kind: marker.length === 2 ? "strong" : "em",
|
|
1503
|
+
at,
|
|
1504
|
+
contentAt: at + marker.length
|
|
1505
|
+
};
|
|
1506
|
+
}
|
|
1507
|
+
const bracket = text.lastIndexOf("[");
|
|
1508
|
+
if (bracket !== -1 && bracket < text.length - 1 && (best === null || bracket > best.at)) {
|
|
1509
|
+
const closed = /\]\([^)]*\)/.test(text.slice(bracket));
|
|
1510
|
+
if (!closed) {
|
|
1511
|
+
best = { kind: "link", at: bracket, contentAt: bracket + 1 };
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
return best;
|
|
1515
|
+
}
|
|
1516
|
+
function renderInlineToRichText(tokens, fallbackText, font, color, maxWidth, theme, selectable, onLinkClick) {
|
|
1517
|
+
const spans = [];
|
|
1518
|
+
if (tokens && tokens.length > 0) {
|
|
1519
|
+
collectSpans(tokens, {}, theme, spans, fontSizeFromFont(font));
|
|
1520
|
+
}
|
|
1521
|
+
if (spans.length === 0) {
|
|
1522
|
+
spans.push({ text: decodeEntities(fallbackText) });
|
|
1523
|
+
}
|
|
1524
|
+
return new RichText(spans, {
|
|
1525
|
+
font,
|
|
1526
|
+
color,
|
|
1527
|
+
maxWidth,
|
|
1528
|
+
linkColor: theme.linkColor,
|
|
1529
|
+
selectable,
|
|
1530
|
+
onLinkClick
|
|
1531
|
+
});
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
// src/Markdown.ts
|
|
1535
|
+
import { RichText as RichText2, Stack, Table, Text, Image, UIComponent as UIComponent3 } from "@vectojs/ui";
|
|
1536
|
+
|
|
1537
|
+
// src/blockAffordances.ts
|
|
1538
|
+
import { Button, measureText as measureText2, UIComponent as UIComponent2 } from "@vectojs/ui";
|
|
1539
|
+
var LANGUAGE_EXTENSIONS = {
|
|
1540
|
+
bash: "sh",
|
|
1541
|
+
c: "c",
|
|
1542
|
+
cpp: "cpp",
|
|
1543
|
+
cs: "cs",
|
|
1544
|
+
css: "css",
|
|
1545
|
+
diff: "diff",
|
|
1546
|
+
dockerfile: "dockerfile",
|
|
1547
|
+
go: "go",
|
|
1548
|
+
graphql: "graphql",
|
|
1549
|
+
haskell: "hs",
|
|
1550
|
+
html: "html",
|
|
1551
|
+
java: "java",
|
|
1552
|
+
javascript: "js",
|
|
1553
|
+
js: "js",
|
|
1554
|
+
json: "json",
|
|
1555
|
+
jsonc: "jsonc",
|
|
1556
|
+
jsx: "jsx",
|
|
1557
|
+
kotlin: "kt",
|
|
1558
|
+
latex: "tex",
|
|
1559
|
+
lua: "lua",
|
|
1560
|
+
make: "mk",
|
|
1561
|
+
markdown: "md",
|
|
1562
|
+
md: "md",
|
|
1563
|
+
nix: "nix",
|
|
1564
|
+
php: "php",
|
|
1565
|
+
python: "py",
|
|
1566
|
+
py: "py",
|
|
1567
|
+
ruby: "rb",
|
|
1568
|
+
rust: "rs",
|
|
1569
|
+
rs: "rs",
|
|
1570
|
+
scss: "scss",
|
|
1571
|
+
sh: "sh",
|
|
1572
|
+
shell: "sh",
|
|
1573
|
+
sql: "sql",
|
|
1574
|
+
svelte: "svelte",
|
|
1575
|
+
swift: "swift",
|
|
1576
|
+
tex: "tex",
|
|
1577
|
+
toml: "toml",
|
|
1578
|
+
ts: "ts",
|
|
1579
|
+
tsx: "tsx",
|
|
1580
|
+
typescript: "ts",
|
|
1581
|
+
vue: "vue",
|
|
1582
|
+
xml: "xml",
|
|
1583
|
+
yaml: "yaml",
|
|
1584
|
+
yml: "yaml",
|
|
1585
|
+
zig: "zig",
|
|
1586
|
+
zsh: "sh"
|
|
1587
|
+
};
|
|
1588
|
+
function extensionForLanguage(lang) {
|
|
1589
|
+
const first = lang.trim().toLowerCase().split(/[\s:,{]/)[0] ?? "";
|
|
1590
|
+
return LANGUAGE_EXTENSIONS[first] ?? "txt";
|
|
1591
|
+
}
|
|
1592
|
+
function mimeForLanguage(lang) {
|
|
1593
|
+
const ext = extensionForLanguage(lang);
|
|
1594
|
+
if (ext === "json" || ext === "jsonc") return "application/json";
|
|
1595
|
+
if (ext === "html") return "text/html";
|
|
1596
|
+
if (ext === "css") return "text/css";
|
|
1597
|
+
if (ext === "xml" || ext === "svelte" || ext === "vue") return "text/plain";
|
|
1598
|
+
return "text/plain";
|
|
1599
|
+
}
|
|
1600
|
+
function escapeCsvField(value) {
|
|
1601
|
+
let needsQuoting = false;
|
|
1602
|
+
let hasQuote = false;
|
|
1603
|
+
for (const char of value) {
|
|
1604
|
+
if (char === '"') {
|
|
1605
|
+
hasQuote = true;
|
|
1606
|
+
needsQuoting = true;
|
|
1607
|
+
break;
|
|
1608
|
+
}
|
|
1609
|
+
if (char === "," || char === "\n" || char === "\r") needsQuoting = true;
|
|
1610
|
+
}
|
|
1611
|
+
if (!needsQuoting) return value;
|
|
1612
|
+
return hasQuote ? `"${value.replace(/"/g, '""')}"` : `"${value}"`;
|
|
1613
|
+
}
|
|
1614
|
+
function escapeMarkdownTableCell(cell) {
|
|
1615
|
+
let needsEscaping = false;
|
|
1616
|
+
for (const char of cell) {
|
|
1617
|
+
if (char === "\\" || char === "|") {
|
|
1618
|
+
needsEscaping = true;
|
|
1619
|
+
break;
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1622
|
+
if (!needsEscaping) return cell;
|
|
1623
|
+
return cell.replace(/\\/g, "\\\\").replace(/\|/g, "\\|");
|
|
1624
|
+
}
|
|
1625
|
+
function tableToCsv(table) {
|
|
1626
|
+
const lines = [table.headers.map(escapeCsvField).join(",")];
|
|
1627
|
+
for (const row of table.rows) lines.push(row.map(escapeCsvField).join(","));
|
|
1628
|
+
return `\uFEFF${lines.join("\r\n")}`;
|
|
1629
|
+
}
|
|
1630
|
+
function tableToMarkdown(table) {
|
|
1631
|
+
const header = `| ${table.headers.map(escapeMarkdownTableCell).join(" | ")} |`;
|
|
1632
|
+
const divider = `| ${table.headers.map((_cell, index) => {
|
|
1633
|
+
switch (table.align[index]) {
|
|
1634
|
+
case "left":
|
|
1635
|
+
return ":---";
|
|
1636
|
+
case "center":
|
|
1637
|
+
return ":---:";
|
|
1638
|
+
case "right":
|
|
1639
|
+
return "---:";
|
|
1640
|
+
default:
|
|
1641
|
+
return "---";
|
|
1642
|
+
}
|
|
1643
|
+
}).join(" | ")} |`;
|
|
1644
|
+
const body = table.rows.map(
|
|
1645
|
+
(row) => `| ${table.headers.map((_cell, index) => escapeMarkdownTableCell(row[index] ?? "")).join(" | ")} |`
|
|
1646
|
+
);
|
|
1647
|
+
return [header, divider, ...body].join("\n");
|
|
1648
|
+
}
|
|
1649
|
+
function defaultWriteClipboard(text) {
|
|
1650
|
+
const clipboard = globalThis.navigator?.clipboard;
|
|
1651
|
+
clipboard?.writeText?.(text);
|
|
1652
|
+
}
|
|
1653
|
+
function defaultSaveFile(filename, content, mimeType) {
|
|
1654
|
+
const doc = globalThis.document;
|
|
1655
|
+
if (!doc?.body) return;
|
|
1656
|
+
const blob = new Blob([content], { type: mimeType });
|
|
1657
|
+
const url = URL.createObjectURL(blob);
|
|
1658
|
+
const anchor = doc.createElement("a");
|
|
1659
|
+
anchor.href = url;
|
|
1660
|
+
anchor.download = filename;
|
|
1661
|
+
doc.body.appendChild(anchor);
|
|
1662
|
+
anchor.click();
|
|
1663
|
+
doc.body.removeChild(anchor);
|
|
1664
|
+
URL.revokeObjectURL(url);
|
|
1665
|
+
}
|
|
1666
|
+
var BlockAffordanceButton = class _BlockAffordanceButton extends Button {
|
|
1667
|
+
constructor(label, successLabel, act, opts = {}) {
|
|
1668
|
+
super(label, { ...opts, onClick: () => this.run() });
|
|
1669
|
+
this.act = act;
|
|
1670
|
+
this.restingLabel = label;
|
|
1671
|
+
this.successLabel = successLabel;
|
|
1672
|
+
this.width = Math.max(this.width, measureText2(successLabel, this.font) + 24);
|
|
1673
|
+
}
|
|
1674
|
+
act;
|
|
1675
|
+
/** How long the confirmation label stays up, in ms. */
|
|
1676
|
+
static FEEDBACK_MS = 1600;
|
|
1677
|
+
restingLabel;
|
|
1678
|
+
successLabel;
|
|
1679
|
+
feedbackTimer;
|
|
1680
|
+
/**
|
|
1681
|
+
* Runs the action, then shows the confirmation.
|
|
1682
|
+
*
|
|
1683
|
+
* The action runs first and a throw propagates: a clipboard write the browser
|
|
1684
|
+
* rejected must not be reported as a success.
|
|
1685
|
+
*/
|
|
1686
|
+
run() {
|
|
1687
|
+
this.act();
|
|
1688
|
+
this.setTransientLabel(this.successLabel);
|
|
1689
|
+
if (this.feedbackTimer !== void 0) clearTimeout(this.feedbackTimer);
|
|
1690
|
+
this.feedbackTimer = setTimeout(() => {
|
|
1691
|
+
this.setTransientLabel(this.restingLabel);
|
|
1692
|
+
this.feedbackTimer = void 0;
|
|
1693
|
+
}, _BlockAffordanceButton.FEEDBACK_MS);
|
|
1694
|
+
}
|
|
1695
|
+
setTransientLabel(label) {
|
|
1696
|
+
this.label = label;
|
|
1697
|
+
this.textWidth = measureText2(label, this.font);
|
|
1698
|
+
this.scene?.markDirty();
|
|
1699
|
+
}
|
|
1700
|
+
/**
|
|
1701
|
+
* The label a reader hears is the one they see, transient confirmation
|
|
1702
|
+
* included, so an AT user gets the same feedback a sighted user does.
|
|
1703
|
+
*/
|
|
1704
|
+
getA11yAttributes() {
|
|
1705
|
+
return { ...super.getA11yAttributes(), label: this.label };
|
|
1706
|
+
}
|
|
1707
|
+
/** Clears the pending revert so a destroyed block leaves no timer behind. */
|
|
1708
|
+
destroy() {
|
|
1709
|
+
if (this.feedbackTimer !== void 0) {
|
|
1710
|
+
clearTimeout(this.feedbackTimer);
|
|
1711
|
+
this.feedbackTimer = void 0;
|
|
1712
|
+
}
|
|
1713
|
+
super.destroy();
|
|
1714
|
+
}
|
|
1715
|
+
};
|
|
1716
|
+
var BlockWithAffordances = class _BlockWithAffordances extends UIComponent2 {
|
|
1717
|
+
constructor(block, controls) {
|
|
1718
|
+
super();
|
|
1719
|
+
this.block = block;
|
|
1720
|
+
this.controls = controls;
|
|
1721
|
+
this.add(block);
|
|
1722
|
+
for (const control of controls) this.add(control);
|
|
1723
|
+
this.layoutAffordances();
|
|
1724
|
+
}
|
|
1725
|
+
block;
|
|
1726
|
+
controls;
|
|
1727
|
+
/** Gap between the block's edges and the controls, in px. */
|
|
1728
|
+
static INSET = 8;
|
|
1729
|
+
/** Gap between adjacent controls, in px. */
|
|
1730
|
+
static GAP = 6;
|
|
1731
|
+
/**
|
|
1732
|
+
* Places the controls right-aligned along the block's top edge.
|
|
1733
|
+
*
|
|
1734
|
+
* Laid out right-to-left from the block's right edge so the first control in
|
|
1735
|
+
* the list ends up leftmost, which keeps DOM order (and therefore tab order and
|
|
1736
|
+
* the a11y reading order) matching the visual order.
|
|
1737
|
+
*/
|
|
1738
|
+
layoutAffordances() {
|
|
1739
|
+
this.width = this.block.width;
|
|
1740
|
+
this.height = this.block.height;
|
|
1741
|
+
let right = this.block.width - _BlockWithAffordances.INSET;
|
|
1742
|
+
for (let i = this.controls.length - 1; i >= 0; i--) {
|
|
1743
|
+
const control = this.controls[i];
|
|
1744
|
+
control.x = right - control.width;
|
|
1745
|
+
control.y = _BlockWithAffordances.INSET;
|
|
1746
|
+
right = control.x - _BlockWithAffordances.GAP;
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
/**
|
|
1750
|
+
* Re-places the controls after the block's own box changed.
|
|
1751
|
+
*
|
|
1752
|
+
* Called by the owner when a block is resized or its content grew; the controls
|
|
1753
|
+
* are anchored to the right edge, so a width change moves them.
|
|
1754
|
+
*/
|
|
1755
|
+
refreshAffordances() {
|
|
1756
|
+
this.layoutAffordances();
|
|
1757
|
+
this.scene?.markDirty();
|
|
1758
|
+
}
|
|
1759
|
+
/** The wrapper is a pass-through: its size is the block's size. */
|
|
1760
|
+
getLayoutControlledProperties() {
|
|
1761
|
+
return ["x", "y"];
|
|
1762
|
+
}
|
|
1763
|
+
/**
|
|
1764
|
+
* Projected as a group so assistive technology reports one labelled region
|
|
1765
|
+
* containing the block and its controls, rather than two unrelated siblings.
|
|
1766
|
+
*/
|
|
1767
|
+
getA11yAttributes() {
|
|
1768
|
+
return { role: "group", pointerEvents: "none" };
|
|
1769
|
+
}
|
|
1770
|
+
render() {
|
|
1771
|
+
}
|
|
1772
|
+
};
|
|
1773
|
+
function tableContentOf(token) {
|
|
1774
|
+
return {
|
|
1775
|
+
headers: token.header.map((cell) => cell.text),
|
|
1776
|
+
rows: token.rows.map((row) => row.map((cell) => cell.text)),
|
|
1777
|
+
align: token.align
|
|
1778
|
+
};
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1781
|
+
// src/frontMatter.ts
|
|
1782
|
+
var OPEN_RE = /^---[ \t]*\r?\n/;
|
|
1783
|
+
var OPENER_PREFIX_RE = /^(?:-|--|---[ \t]*\r?)$/;
|
|
1784
|
+
var KEY_RE = /^[^\s:#][^:]*:(?:[ \t].*)?$/;
|
|
1785
|
+
var CLOSE_RE = /^(?:---|\.\.\.)[ \t]*$/;
|
|
1786
|
+
var MAX_PENDING_CHARS = 4096;
|
|
1787
|
+
var NONE = { kind: "none" };
|
|
1788
|
+
var PENDING = { kind: "pending" };
|
|
1789
|
+
function scanFrontMatter(text, complete) {
|
|
1790
|
+
if (text.length === 0) return PENDING;
|
|
1791
|
+
const open = OPEN_RE.exec(text);
|
|
1792
|
+
if (!open) {
|
|
1793
|
+
return !complete && OPENER_PREFIX_RE.test(text) ? PENDING : NONE;
|
|
1794
|
+
}
|
|
1795
|
+
const decide = complete || text.length > MAX_PENDING_CHARS;
|
|
1796
|
+
const contentStart = open[0].length;
|
|
1797
|
+
let cursor = contentStart;
|
|
1798
|
+
let keyChecked = false;
|
|
1799
|
+
while (cursor < text.length) {
|
|
1800
|
+
const nl = text.indexOf("\n", cursor);
|
|
1801
|
+
if (nl === -1 && !decide) return PENDING;
|
|
1802
|
+
const line = text.slice(cursor, nl === -1 ? text.length : nl).replace(/\r$/, "");
|
|
1803
|
+
if (!keyChecked) {
|
|
1804
|
+
if (!KEY_RE.test(line)) return NONE;
|
|
1805
|
+
keyChecked = true;
|
|
1806
|
+
} else if (CLOSE_RE.test(line)) {
|
|
1807
|
+
return {
|
|
1808
|
+
kind: "found",
|
|
1809
|
+
raw: text.slice(contentStart, cursor),
|
|
1810
|
+
// A closer with no trailing newline ends the document, so the body is
|
|
1811
|
+
// empty rather than starting one character past the end.
|
|
1812
|
+
bodyStart: nl === -1 ? text.length : nl + 1
|
|
1813
|
+
};
|
|
1814
|
+
}
|
|
1815
|
+
if (nl === -1) break;
|
|
1816
|
+
cursor = nl + 1;
|
|
1817
|
+
}
|
|
1818
|
+
return decide ? NONE : PENDING;
|
|
1819
|
+
}
|
|
1820
|
+
function parseFrontMatterFields(raw) {
|
|
1821
|
+
const out = {};
|
|
1822
|
+
for (const rawLine of raw.split("\n")) {
|
|
1823
|
+
const line = rawLine.replace(/\r$/, "");
|
|
1824
|
+
if (line.length === 0 || /^[\s#]/.test(line)) continue;
|
|
1825
|
+
const sep = line.indexOf(":");
|
|
1826
|
+
if (sep <= 0) continue;
|
|
1827
|
+
const value = line.slice(sep + 1);
|
|
1828
|
+
if (value.length > 0 && value[0] !== " " && value[0] !== " ") continue;
|
|
1829
|
+
out[line.slice(0, sep).trim()] = unquote(value.trim());
|
|
1490
1830
|
}
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
kind: marker.length === 2 ? "strong" : "em",
|
|
1499
|
-
at,
|
|
1500
|
-
contentAt: at + marker.length
|
|
1501
|
-
};
|
|
1831
|
+
return out;
|
|
1832
|
+
}
|
|
1833
|
+
function unquote(value) {
|
|
1834
|
+
if (value.length < 2) return value;
|
|
1835
|
+
const first = value[0];
|
|
1836
|
+
if ((first === '"' || first === "'") && value.endsWith(first)) {
|
|
1837
|
+
return value.slice(1, -1);
|
|
1502
1838
|
}
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
best = { kind: "link", at: bracket, contentAt: bracket + 1 };
|
|
1508
|
-
|
|
1839
|
+
return value;
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1842
|
+
// src/MarkdownWorkerSource.ts
|
|
1843
|
+
var WORKER_SOURCE_STRING = '"use strict";(()=>{function V(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var _=V();function ke(t){_=t}var C={exec:()=>null};function P(t){let e=[];return n=>{let s=Math.max(0,Math.min(3,n-1)),r=e[s];return r||(r=t(s),e[s]=r),r}}function k(t,e=""){let n=typeof t=="string"?t:t.source,s={replace:(r,l)=>{let a=typeof l=="string"?l:l.source;return a=a.replace(x.caret,"$1"),n=n.replace(r,a),s},getRegex:()=>new RegExp(n,e)};return s}var _e=((t="")=>{try{return!!new RegExp("(?<=1)(?<!1)"+t)}catch{return!1}})(),x={codeRemoveIndent:/^(?: {1,4}| {0,3}\\t)/gm,outputLinkReplace:/\\\\([\\[\\]])/g,indentCodeCompensation:/^(\\s+)(?:```)/,beginningSpace:/^\\s+/,endingHash:/#$/,startingSpaceChar:/^ /,endingSpaceChar:/ $/,nonSpaceChar:/[^ ]/,newLineCharGlobal:/\\n/g,tabCharGlobal:/\\t/g,multipleSpaceGlobal:/\\s+/g,blankLine:/^[ \\t]*$/,doubleBlankLine:/\\n[ \\t]*\\n[ \\t]*$/,blockquoteStart:/^ {0,3}>/,blockquoteSetextReplace:/\\n {0,3}((?:=+|-+) *)(?=\\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \\t]?/gm,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\\[[ xX]\\] +\\S/,listReplaceTask:/^\\[[ xX]\\] +/,listTaskCheckbox:/\\[[ xX]\\]/,anyLine:/\\n.*\\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\\||\\| *$/g,tableRowBlankLine:/\\n[ \\t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^<a /i,endATag:/^<\\/a>/i,startPreScriptTag:/^<(pre|code|kbd|script)(\\s|>)/i,endPreScriptTag:/^<\\/(pre|code|kbd|script)(\\s|>)/i,startAngleBracket:/^</,endAngleBracket:/>$/,pedanticHrefTitle:/^([^\'"]*[^\\s])\\s+([\'"])(.*)\\2/,unicodeAlphaNumeric:/[\\p{L}\\p{N}]/u,escapeTest:/[&<>"\']/,escapeReplace:/[&<>"\']/g,escapeTestNoEncode:/[<>"\']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/,escapeReplaceNoEncode:/[<>"\']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/g,caret:/(^|[^\\[])\\^/g,percentDecode:/%25/g,findPipe:/\\|/g,splitPipe:/ \\|/,slashPipe:/\\\\\\|/g,carriageReturn:/\\r\\n|\\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\\S*/,endingNewline:/\\n$/,listItemRegex:t=>new RegExp(`^( {0,3}${t})((?:[ ][^\\\\n]*)?(?:\\\\n|$))`),nextBulletRegex:P(t=>new RegExp(`^ {0,${t}}(?:[*+-]|\\\\d{1,9}[.)])((?:[ ][^\\\\n]*)?(?:\\\\n|$))`)),hrRegex:P(t=>new RegExp(`^ {0,${t}}((?:- *){3,}|(?:_ *){3,}|(?:\\\\* *){3,})(?:\\\\n+|$)`)),fencesBeginRegex:P(t=>new RegExp(`^ {0,${t}}(?:\\`\\`\\`|~~~)`)),headingBeginRegex:P(t=>new RegExp(`^ {0,${t}}#`)),htmlBeginRegex:P(t=>new RegExp(`^ {0,${t}}<(?:[a-z].*>|!--)`,"i")),blockquoteBeginRegex:P(t=>new RegExp(`^ {0,${t}}>`))},Pe=/^(?:[ \\t]*(?:\\n|$))+/,Me=/^((?: {4}| {0,3}\\t)[^\\n]+(?:\\n(?:[ \\t]*(?:\\n|$))*)?)+/,Ee=/^ {0,3}(`{3,}(?=[^`\\n]*(?:\\n|$))|~{3,})([^\\n]*)(?:\\n|$)(?:|([\\s\\S]*?)(?:\\n|$))(?: {0,3}\\1[~`]* *(?=\\n|$)|$)/,v=/^ {0,3}((?:-[\\t ]*){3,}|(?:_[ \\t]*){3,}|(?:\\*[ \\t]*){3,})(?:\\n+|$)/,Be=/^ {0,3}(#{1,6})(?=\\s|$)(.*)(?:\\n+|$)/,K=/ {0,3}(?:[*+-]|\\d{1,9}[.)])/,fe=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\\n(?!\\s*?\\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,de=k(fe).replace(/bull/g,K).replace(/blockCode/g,/(?: {4}| {0,3}\\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}(?:\\s|$)/).replace(/html/g,/ {0,3}<[^\\n>]+>\\n/).replace(/\\|table/g,"").getRegex(),qe=k(fe).replace(/bull/g,K).replace(/blockCode/g,/(?: {4}| {0,3}\\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}(?:\\s|$)/).replace(/html/g,/ {0,3}<[^\\n>]+>\\n/).replace(/table/g,/ {0,3}\\|?(?:[:\\- ]*\\|)+[\\:\\- ]*\\n/).getRegex(),J=/^([^\\n]+(?:\\n(?!hr|heading|lheading|blockquote|fences|list|html|table|[ \\t]+\\n)[^\\n]+)*)/,ve=/^[^\\n]+/,Y=/(?!\\s*\\])(?:\\\\[\\s\\S]|[^\\[\\]\\\\])+/,De=k(/^ {0,3}\\[(label)\\]: *(?:\\n[ \\t]*)?([^<\\s][^\\s]*|<.*?>)(?:(?: +(?:\\n[ \\t]*)?| *\\n[ \\t]*)(title))? *(?:\\n+|$)/).replace("label",Y).replace("title",/(?:"(?:\\\\"?|[^"\\\\])*"|\'[^\'\\n]*(?:\\n[^\'\\n]+)*\\n?\'|\\([^()]*\\))/).getRegex(),Ze=k(/^(bull)([ \\t][^\\n]*?)?(?:\\n|$)/).replace(/bull/g,K).getRegex(),N="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",ee=/<!--(?:-?>|[\\s\\S]*?(?:-->|$))/,Oe=k("^ {0,3}(?:<(script|pre|style|textarea)[\\\\s>][\\\\s\\\\S]*?(?:</\\\\1>[^\\\\n]*\\\\n*|$)|comment[^\\\\n]*(\\\\n+|$)|<\\\\?[\\\\s\\\\S]*?(?:\\\\?>[^\\\\n]*\\\\n*|$)|<![A-Z][\\\\s\\\\S]*?(?:>[^\\\\n]*\\\\n*|$)|<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?(?:\\\\]\\\\]>[^\\\\n]*\\\\n*|$)|</?(tag)(?: +|\\\\n|/?>)[\\\\s\\\\S]*?(?:(?:\\\\n[ ]*)+\\\\n|$)|<(?!script|pre|style|textarea)([a-z][\\\\w-]*)(?:attribute)*? */?>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ ]*)+\\\\n|$)|</(?!script|pre|style|textarea)[a-z][\\\\w-]*\\\\s*>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ ]*)+\\\\n|$))","i").replace("comment",ee).replace("tag",N).replace("attribute",/ +[a-zA-Z:_][\\w.:-]*(?: *= *"[^"\\n]*"| *= *\'[^\'\\n]*\'| *= *[^\\s"\'=<>`]+)?/).getRegex(),xe=t=>k(J).replace("hr",v).replace("heading"," {0,3}#{1,6}(?:\\\\s|$)").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~~~)[^\\\\n]*\\\\n").replace("list",t).replace("html","</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",N).getRegex(),Qe=xe(/ {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]/),Ne=xe(/ {0,3}(?:[*+-]|\\d{1,9}[.)])(?:[ \\t]|\\n|$)/),He=k(/^( {0,3}> ?(paragraph|[^\\n]*)(?:\\n|$))+/).replace("paragraph",Ne).getRegex(),te={blockquote:He,code:Me,def:De,fences:Ee,heading:Be,hr:v,html:Oe,lheading:de,list:Ze,newline:Pe,paragraph:Qe,table:C,text:ve},ae=k("^ *([^\\\\n ].*)\\\\n {0,3}((?:\\\\| *)?:?-+:? *(?:\\\\| *:?-+:? *)*(?:\\\\| *)?)(?:\\\\n((?:(?! *\\\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\\\n|$))*)\\\\n*|$)").replace("hr",v).replace("heading"," {0,3}#{1,6}(?:\\\\s|$)").replace("blockquote"," {0,3}>").replace("code","(?: {4}| {0,3} )[^\\\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~~~)[^\\\\n]*\\\\n").replace("list"," {0,3}(?:[*+-]|1[.)])[ \\\\t]").replace("html","</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",N).getRegex(),je={...te,lheading:qe,table:ae,paragraph:k(J).replace("hr",v).replace("heading"," {0,3}#{1,6}(?:\\\\s|$)").replace("|lheading","").replace("table",ae).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~~~)[^\\\\n]*\\\\n").replace("list"," {0,3}(?:[*+-]|1[.)])[ \\\\t]+[^ \\\\t\\\\n]").replace("html","</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",N).getRegex()},Ge={...te,html:k(`^ *(?:comment *(?:\\\\n|\\\\s*$)|<(tag)[\\\\s\\\\S]+?</\\\\1> *(?:\\\\n{2,}|\\\\s*$)|<tag(?:"[^"]*"|\'[^\']*\'|\\\\s[^\'"/>\\\\s]*)*?/?> *(?:\\\\n{2,}|\\\\s*$))`).replace("comment",ee).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\\\b)\\\\w+(?!:|[^\\\\w\\\\s@]*@)\\\\b").getRegex(),def:/^ *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +(["(][^\\n]+[")]))? *(?:\\n+|$)/,heading:/^(#{1,6})(.*)(?:\\n+|$)/,fences:C,lheading:/^(.+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,paragraph:k(J).replace("hr",v).replace("heading",` *#{1,6} *[^\n]`).replace("lheading",de).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},We=/^\\\\([!"#$%&\'()*+,\\-./:;<=>?@\\[\\]\\\\^_`{|}~])/,Fe=/^(`+)([^`]|[^`][\\s\\S]*?[^`])\\1(?!`)/,be=/^( {2,}|\\\\)\\n(?!\\s*$)/,Xe=/^(`+|[^`])(?:(?= {2,}\\n)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*_]|\\b_|$)|[^ ](?= {2,}\\n)))/,M=/[\\p{P}\\p{S}]/u,H=/[\\s\\p{P}\\p{S}]/u,ne=/[^\\s\\p{P}\\p{S}]/u,Ue=k(/^((?![*_])punctSpace)/,"u").replace(/punctSpace/g,H).getRegex(),me=/(?!~)[\\p{P}\\p{S}]/u,Ve=/(?!~)[\\s\\p{P}\\p{S}]/u,Ke=/(?:[^\\s\\p{P}\\p{S}]|~)/u,Je=k(/link|precode-code|html/,"g").replace("link",/\\[(?:[^\\[\\]`]|(?<a>`+)[^`]+\\k<a>(?!`))*?\\]\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)]|\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)])*\\))*\\)/).replace("precode-",_e?"(?<!`)()":"(^^|[^`])").replace("code",/(?<b>`+)[^`]+\\k<b>(?!`)/).replace("html",/<(?! )[^<>]*?>/).getRegex(),we=/^(?:\\*+(?:((?!\\*)punct)|([^\\s*]))?)|^_+(?:((?!_)punct)|([^\\s_]))?/,Ye=k(we,"u").replace(/punct/g,M).getRegex(),et=k(we,"u").replace(/punct/g,me).getRegex(),ye="^[^_*]*?__[^_*]*?\\\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\\\*)punct(\\\\*+)(?=[\\\\s]|$)|notPunctSpace(\\\\*+)(?!\\\\*)(?=punctSpace|$)|(?!\\\\*)punctSpace(\\\\*+)(?=notPunctSpace)|[\\\\s](\\\\*+)(?!\\\\*)(?=punct)|(?!\\\\*)punct(\\\\*+)(?!\\\\*)(?=punct)|notPunctSpace(\\\\*+)(?=notPunctSpace)",tt=k(ye,"gu").replace(/notPunctSpace/g,ne).replace(/punctSpace/g,H).replace(/punct/g,M).getRegex(),nt=k(ye,"gu").replace(/notPunctSpace/g,Ke).replace(/punctSpace/g,Ve).replace(/punct/g,me).getRegex(),rt=k("^[^_*]*?\\\\*\\\\*[^_*]*?_[^_*]*?(?=\\\\*\\\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)","gu").replace(/notPunctSpace/g,ne).replace(/punctSpace/g,H).replace(/punct/g,M).getRegex(),st=k(/^~~?(?:((?!~)punct)|[^\\s~])/,"u").replace(/punct/g,M).getRegex(),lt="^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)",it=k(lt,"gu").replace(/notPunctSpace/g,ne).replace(/punctSpace/g,H).replace(/punct/g,M).getRegex(),at=k(/\\\\(punct)/,"gu").replace(/punct/g,M).getRegex(),ot=k(/^<(scheme:[^\\s\\x00-\\x1f<>]*|email)>/).replace("scheme",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email",/[a-zA-Z0-9.!#$%&\'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),ct=k(ee).replace("(?:-->|$)","-->").getRegex(),ht=k("^comment|^</[a-zA-Z][\\\\w:-]*\\\\s*>|^<[a-zA-Z][\\\\w-]*(?:attribute)*?\\\\s*/?>|^<\\\\?[\\\\s\\\\S]*?\\\\?>|^<![a-zA-Z]+\\\\s[\\\\s\\\\S]*?>|^<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?\\\\]\\\\]>").replace("comment",ct).replace("attribute",/\\s+[a-zA-Z:_][\\w.:-]*(?:\\s*=\\s*"[^"]*"|\\s*=\\s*\'[^\']*\'|\\s*=\\s*[^\\s"\'=<>`]+)?/).getRegex(),Z=/(?:\\[(?:\\\\[\\s\\S]|[^\\[\\]\\\\])*\\]|\\\\[\\s\\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\\])|[^\\[\\]\\\\`])*?/,ut=k(/^!?\\[(label)\\]\\(\\s*(href)(?:(?:[ \\t]+(?:\\n[ \\t]*)?|\\n[ \\t]*)(title))?\\s*\\)/).replace("label",Z).replace("href",/<(?:\\\\.|[^\\n<>\\\\])+>|[^ \\t\\n\\x00-\\x1f]+|(?=\\))/).replace("title",/"(?:\\\\"?|[^"\\\\])*"|\'(?:\\\\\'?|[^\'\\\\])*\'|\\((?:\\\\\\)?|[^)\\\\])*\\)/).getRegex(),Re=k(/^!?\\[(label)\\]\\[(ref)\\]/).replace("label",Z).replace("ref",Y).getRegex(),$e=k(/^!?\\[(ref)\\](?:\\[\\])?/).replace("ref",Y).getRegex(),pt=k("reflink|nolink(?!\\\\()","g").replace("reflink",Re).replace("nolink",$e).getRegex(),oe=/[hH][tT][tT][pP][sS]?|[fF][tT][pP]/,re={_backpedal:C,anyPunctuation:at,autolink:ot,blockSkip:Je,br:be,code:Fe,del:C,delLDelim:C,delRDelim:C,emStrongLDelim:Ye,emStrongRDelimAst:tt,emStrongRDelimUnd:rt,escape:We,link:ut,nolink:$e,punctuation:Ue,reflink:Re,reflinkSearch:pt,tag:ht,text:Xe,url:C},gt={...re,link:k(/^!?\\[(label)\\]\\((.*?)\\)/).replace("label",Z).getRegex(),reflink:k(/^!?\\[(label)\\]\\s*\\[([^\\]]*)\\]/).replace("label",Z).getRegex()},F={...re,emStrongRDelimAst:nt,emStrongLDelim:et,delLDelim:st,delRDelim:it,url:k(/^((?:protocol):\\/\\/|www\\.)(?:[a-zA-Z0-9\\-]+\\.?)+[^\\s<]*|^email/).replace("protocol",oe).replace("email",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_\'"~()&]+|\\([^)]*\\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_\'"~)]+(?!$))+/,del:/^(~~?)(?=[^\\s~])((?:\\\\[\\s\\S]|[^\\\\])*?(?:\\\\[\\s\\S]|[^\\s~\\\\]))\\1(?=[^~]|$)/,text:k(/^(`+|~+|[^`~])(?:(?=[`~])|(?= {2,}\\n)|(?=[a-zA-Z0-9.!#$%&\'*+\\/=?_`{\\|}~-]+@)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*~_]|\\b_|protocol:\\/\\/|www\\.|$)|[^ ](?= {2,}\\n)|[^a-zA-Z0-9.!#$%&\'*+\\/=?_`{\\|}~-](?=[a-zA-Z0-9.!#$%&\'*+\\/=?_`{\\|}~-]+@)))/).replace("protocol",oe).getRegex()},kt={...F,br:k(be).replace("{2,}","*").getRegex(),text:k(F.text).replace("\\\\b_","\\\\b_| {2,}\\\\n").replace(/\\{2,\\}/g,"*").getRegex()},D={normal:te,gfm:je,pedantic:Ge},B={normal:re,gfm:F,breaks:kt,pedantic:gt},ft={"&":"&","<":"<",">":">",\'"\':""","\'":"'"},ce=t=>ft[t];function S(t,e){if(e){if(x.escapeTest.test(t))return t.replace(x.escapeReplace,ce)}else if(x.escapeTestNoEncode.test(t))return t.replace(x.escapeReplaceNoEncode,ce);return t}function he(t){try{t=encodeURI(t).replace(x.percentDecode,"%")}catch{return null}return t}function ue(t,e){let n=t.replace(x.findPipe,(l,a,i)=>{let o=!1,c=a;for(;--c>=0&&i[c]==="\\\\";)o=!o;return o?"|":" |"}),s=n.split(x.splitPipe),r=0;if(s[0].trim()||s.shift(),s.length>0&&!s.at(-1)?.trim()&&s.pop(),e)if(s.length>e)s.splice(e);else for(;s.length<e;)s.push("");for(;r<s.length;r++)s[r]=s[r].trim().replace(x.slashPipe,"|");return s}function z(t,e,n){let s=t.length;if(s===0)return"";let r=0;for(;r<s;){let l=t.charAt(s-r-1);if(l===e&&!n)r++;else if(l!==e&&n)r++;else break}return t.slice(0,s-r)}function pe(t){let e=t.split(`\n`),n=e.length-1;for(;n>=0&&x.blankLine.test(e[n]);)n--;return e.length-n<=2?t:e.slice(0,n+1).join(`\n`)}function dt(t,e){if(t.indexOf(e[1])===-1)return-1;let n=0;for(let s=0;s<t.length;s++)if(t[s]==="\\\\")s++;else if(t[s]===e[0])n++;else if(t[s]===e[1]&&(n--,n<0))return s;return n>0?-2:-1}function xt(t,e=0){let n=e,s="";for(let r of t)if(r===" "){let l=4-n%4;s+=" ".repeat(l),n+=l}else s+=r,n++;return s}function ge(t,e,n,s,r){let l=e.href,a=e.title||null,i=t[1].replace(r.other.outputLinkReplace,"$1");s.state.inLink=!0;let o={type:t[0].charAt(0)==="!"?"image":"link",raw:n,href:l,title:a,text:i,tokens:s.inlineTokens(i)};return s.state.inLink=!1,o}function bt(t,e,n){let s=t.match(n.other.indentCodeCompensation);if(s===null)return e;let r=s[1];return e.split(`\n`).map(l=>{let a=l.match(n.other.beginningSpace);if(a===null)return l;let[i]=a;return i.length>=r.length?l.slice(r.length):l}).join(`\n`)}var O=class{options;rules;lexer;constructor(t){this.options=t||_}space(t){let e=this.rules.block.newline.exec(t);if(e&&e[0].length>0)return{type:"space",raw:e[0]}}code(t){let e=this.rules.block.code.exec(t);if(e){let n=this.options.pedantic?e[0]:pe(e[0]),s=n.replace(this.rules.other.codeRemoveIndent,"");return{type:"code",raw:n,codeBlockStyle:"indented",text:s}}}fences(t){let e=this.rules.block.fences.exec(t);if(e){let n=e[0],s=bt(n,e[3]||"",this.rules);return{type:"code",raw:n,lang:e[2]?e[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):e[2],text:s}}}heading(t){let e=this.rules.block.heading.exec(t);if(e){let n=e[2].trim();if(this.rules.other.endingHash.test(n)){let s=z(n,"#");(this.options.pedantic||!s||this.rules.other.endingSpaceChar.test(s))&&(n=s.trim())}return{type:"heading",raw:z(e[0],`\n`),depth:e[1].length,text:n,tokens:this.lexer.inline(n)}}}hr(t){let e=this.rules.block.hr.exec(t);if(e)return{type:"hr",raw:z(e[0],`\n`)}}blockquote(t){let e=this.rules.block.blockquote.exec(t);if(e){let n=z(e[0],`\n`).split(`\n`),s="",r="",l=[];for(;n.length>0;){let a=!1,i=[],o;for(o=0;o<n.length;o++)if(this.rules.other.blockquoteStart.test(n[o]))i.push(n[o]),a=!0;else if(!a)i.push(n[o]);else break;n=n.slice(o);let c=i.join(`\n`),u=c.replace(this.rules.other.blockquoteSetextReplace,`\n $1`).replace(this.rules.other.blockquoteSetextReplace2,"");s=s?`${s}\n${c}`:c,r=r?`${r}\n${u}`:u;let h=this.lexer.state.top;if(this.lexer.state.top=!0,this.lexer.blockTokens(u,l,!0),this.lexer.state.top=h,n.length===0)break;let p=l.at(-1);if(p?.type==="code")break;if(p?.type==="blockquote"){let d=p,f=d.raw+`\n`+n.join(`\n`),m=this.blockquote(f);l[l.length-1]=m,s=s.substring(0,s.length-d.raw.length)+m.raw,r=r.substring(0,r.length-d.text.length)+m.text;break}else if(p?.type==="list"){let d=p,f=d.raw+`\n`+n.join(`\n`),m=this.list(f);l[l.length-1]=m,s=s.substring(0,s.length-p.raw.length)+m.raw,r=r.substring(0,r.length-d.raw.length)+m.raw,n=f.substring(l.at(-1).raw.length).split(`\n`);continue}}return{type:"blockquote",raw:s,tokens:l,text:r}}}list(t){let e=this.rules.block.list.exec(t);if(e){let n=e[1].trim(),s=n.length>1,r={type:"list",raw:"",ordered:s,start:s?+n.slice(0,-1):"",loose:!1,items:[]};n=s?`\\\\d{1,9}\\\\${n.slice(-1)}`:`\\\\${n}`,this.options.pedantic&&(n=s?n:"[*+-]");let l=this.rules.other.listItemRegex(n),a=!1;for(;t;){let o=!1,c="",u="";if(!(e=l.exec(t))||this.rules.block.hr.test(t))break;c=e[0],t=t.substring(c.length);let h=xt(e[2].split(`\n`,1)[0],e[1].length),p=t.split(`\n`,1)[0],d=!h.trim(),f=0;if(this.options.pedantic?(f=2,u=h.trimStart()):d?f=e[1].length+1:(f=h.search(this.rules.other.nonSpaceChar),f=f>4?1:f,u=h.slice(f),f+=e[1].length),d&&this.rules.other.blankLine.test(p)&&(c+=p+`\n`,t=t.substring(p.length+1),o=!0),!o){let m=this.rules.other.nextBulletRegex(f),w=this.rules.other.hrRegex(f),y=this.rules.other.fencesBeginRegex(f),L=this.rules.other.headingBeginRegex(f),W=this.rules.other.htmlBeginRegex(f),A=this.rules.other.blockquoteBeginRegex(f);for(;t;){let b=t.split(`\n`,1)[0],T;if(p=b,this.options.pedantic?(p=p.replace(this.rules.other.listReplaceNesting," "),T=p):T=p.replace(this.rules.other.tabCharGlobal," "),y.test(p)||L.test(p)||W.test(p)||A.test(p)||m.test(p)||w.test(p))break;if(T.search(this.rules.other.nonSpaceChar)>=f||!p.trim())u+=`\n`+T.slice(f);else{if(d||h.replace(this.rules.other.tabCharGlobal," ").search(this.rules.other.nonSpaceChar)>=4||y.test(h)||L.test(h)||w.test(h))break;u+=`\n`+p}d=!p.trim(),c+=b+`\n`,t=t.substring(b.length+1),h=T.slice(f)}}r.loose||(a?r.loose=!0:this.rules.other.doubleBlankLine.test(c)&&(a=!0)),r.items.push({type:"list_item",raw:c,task:!!this.options.gfm&&this.rules.other.listIsTask.test(u),loose:!1,text:u,tokens:[]}),r.raw+=c}let i=r.items.at(-1);if(i)i.raw=i.raw.trimEnd(),i.text=i.text.trimEnd();else return;r.raw=r.raw.trimEnd();for(let o of r.items){this.lexer.state.top=!1,o.tokens=this.lexer.blockTokens(o.text,[]);let c=o.tokens[0];if(o.task&&(c?.type==="text"||c?.type==="paragraph")){o.text=o.text.replace(this.rules.other.listReplaceTask,""),c.raw=c.raw.replace(this.rules.other.listReplaceTask,""),c.text=c.text.replace(this.rules.other.listReplaceTask,"");for(let h=this.lexer.inlineQueue.length-1;h>=0;h--)if(this.rules.other.listIsTask.test(this.lexer.inlineQueue[h].src)){this.lexer.inlineQueue[h].src=this.lexer.inlineQueue[h].src.replace(this.rules.other.listReplaceTask,"");break}let u=this.rules.other.listTaskCheckbox.exec(o.raw);if(u){let h={type:"checkbox",raw:u[0]+" ",checked:u[0]!=="[ ]"};o.checked=h.checked,r.loose?o.tokens[0]&&["paragraph","text"].includes(o.tokens[0].type)&&"tokens"in o.tokens[0]&&o.tokens[0].tokens?(o.tokens[0].raw=h.raw+o.tokens[0].raw,o.tokens[0].text=h.raw+o.tokens[0].text,o.tokens[0].tokens.unshift(h)):o.tokens.unshift({type:"paragraph",raw:h.raw,text:h.raw,tokens:[h]}):o.tokens.unshift(h)}}else o.task&&(o.task=!1);if(!r.loose){let u=o.tokens.filter(p=>p.type==="space"),h=u.length>0&&u.some(p=>this.rules.other.anyLine.test(p.raw));r.loose=h}}if(r.loose)for(let o of r.items){o.loose=!0;for(let c of o.tokens)c.type==="text"&&(c.type="paragraph")}return r}}html(t){let e=this.rules.block.html.exec(t);if(e){let n=pe(e[0]);return{type:"html",block:!0,raw:n,pre:e[1]==="pre"||e[1]==="script"||e[1]==="style",text:n}}}def(t){let e=this.rules.block.def.exec(t);if(e){let n=e[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal," "),s=e[2]?e[2].replace(this.rules.other.hrefBrackets,"$1").replace(this.rules.inline.anyPunctuation,"$1"):"",r=e[3]?e[3].substring(1,e[3].length-1).replace(this.rules.inline.anyPunctuation,"$1"):e[3];return{type:"def",tag:n,raw:z(e[0],`\n`),href:s,title:r}}}table(t){let e=this.rules.block.table.exec(t);if(!e||!this.rules.other.tableDelimiter.test(e[2]))return;let n=ue(e[1]),s=e[2].replace(this.rules.other.tableAlignChars,"").split("|"),r=e[3]?.trim()?e[3].replace(this.rules.other.tableRowBlankLine,"").split(`\n`):[],l={type:"table",raw:z(e[0],`\n`),header:[],align:[],rows:[]};if(n.length===s.length){for(let a of s)this.rules.other.tableAlignRight.test(a)?l.align.push("right"):this.rules.other.tableAlignCenter.test(a)?l.align.push("center"):this.rules.other.tableAlignLeft.test(a)?l.align.push("left"):l.align.push(null);for(let a=0;a<n.length;a++)l.header.push({text:n[a],tokens:this.lexer.inline(n[a]),header:!0,align:l.align[a]});for(let a of r)l.rows.push(ue(a,l.header.length).map((i,o)=>({text:i,tokens:this.lexer.inline(i),header:!1,align:l.align[o]})));return l}}lheading(t){let e=this.rules.block.lheading.exec(t);if(e){let n=e[1].trim();return{type:"heading",raw:z(e[0],`\n`),depth:e[2].charAt(0)==="="?1:2,text:n,tokens:this.lexer.inline(n)}}}paragraph(t){let e=this.rules.block.paragraph.exec(t);if(e){let n=e[1].charAt(e[1].length-1)===`\n`?e[1].slice(0,-1):e[1];return{type:"paragraph",raw:e[0],text:n,tokens:this.lexer.inline(n)}}}text(t){let e=this.rules.block.text.exec(t);if(e)return{type:"text",raw:e[0],text:e[0],tokens:this.lexer.inline(e[0])}}escape(t){let e=this.rules.inline.escape.exec(t);if(e)return{type:"escape",raw:e[0],text:e[1]}}tag(t){let e=this.rules.inline.tag.exec(t);if(e)return!this.lexer.state.inLink&&this.rules.other.startATag.test(e[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&this.rules.other.endATag.test(e[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&this.rules.other.startPreScriptTag.test(e[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&this.rules.other.endPreScriptTag.test(e[0])&&(this.lexer.state.inRawBlock=!1),{type:"html",raw:e[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:e[0]}}link(t){let e=this.rules.inline.link.exec(t);if(e){let n=e[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(n)){if(!this.rules.other.endAngleBracket.test(n))return;let l=z(n.slice(0,-1),"\\\\");if((n.length-l.length)%2===0)return}else{let l=dt(e[2],"()");if(l===-2)return;if(l>-1){let a=(e[0].indexOf("!")===0?5:4)+e[1].length+l;e[2]=e[2].substring(0,l),e[0]=e[0].substring(0,a).trim(),e[3]=""}}let s=e[2],r="";if(this.options.pedantic){let l=this.rules.other.pedanticHrefTitle.exec(s);l&&(s=l[1],r=l[3])}else r=e[3]?e[3].slice(1,-1):"";return s=s.trim(),this.rules.other.startAngleBracket.test(s)&&(this.options.pedantic&&!this.rules.other.endAngleBracket.test(n)?s=s.slice(1):s=s.slice(1,-1)),ge(e,{href:s&&s.replace(this.rules.inline.anyPunctuation,"$1"),title:r&&r.replace(this.rules.inline.anyPunctuation,"$1")},e[0],this.lexer,this.rules)}}reflink(t,e){let n;if((n=this.rules.inline.reflink.exec(t))||(n=this.rules.inline.nolink.exec(t))){let s=(n[2]||n[1]).replace(this.rules.other.multipleSpaceGlobal," "),r=e[s.toLowerCase()];if(!r){let l=n[0].charAt(0);return{type:"text",raw:l,text:l}}return ge(n,r,n[0],this.lexer,this.rules)}}emStrong(t,e,n=""){let s=this.rules.inline.emStrongLDelim.exec(t);if(!(!s||!s[1]&&!s[2]&&!s[3]&&!s[4]||s[4]&&n.match(this.rules.other.unicodeAlphaNumeric))&&(!(s[1]||s[3])||!n||this.rules.inline.punctuation.exec(n))){let r=[...s[0]].length-1,l,a,i=r,o=0,c=s[0][0]==="*"?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(c.lastIndex=0,e=e.slice(-1*t.length+r);(s=c.exec(e))!==null;){if(l=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!l)continue;if(a=[...l].length,s[3]||s[4]){i+=a;continue}else if((s[5]||s[6])&&r%3&&!((r+a)%3)){o+=a;continue}if(i-=a,i>0)continue;a=Math.min(a,a+i+o);let u=[...s[0]][0].length,h=t.slice(0,r+s.index+u+a);if(Math.min(r,a)%2){let d=h.slice(1,-1);return{type:"em",raw:h,text:d,tokens:this.lexer.inlineTokens(d)}}let p=h.slice(2,-2);return{type:"strong",raw:h,text:p,tokens:this.lexer.inlineTokens(p)}}}}codespan(t){let e=this.rules.inline.code.exec(t);if(e){let n=e[2].replace(this.rules.other.newLineCharGlobal," "),s=this.rules.other.nonSpaceChar.test(n),r=this.rules.other.startingSpaceChar.test(n)&&this.rules.other.endingSpaceChar.test(n);return s&&r&&(n=n.substring(1,n.length-1)),{type:"codespan",raw:e[0],text:n}}}br(t){let e=this.rules.inline.br.exec(t);if(e)return{type:"br",raw:e[0]}}del(t,e,n=""){let s=this.rules.inline.delLDelim.exec(t);if(s&&(!s[1]||!n||this.rules.inline.punctuation.exec(n))){let r=[...s[0]].length-1,l,a,i=r,o=this.rules.inline.delRDelim;for(o.lastIndex=0,e=e.slice(-1*t.length+r);(s=o.exec(e))!==null;){if(l=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!l||(a=[...l].length,a!==r))continue;if(s[3]||s[4]){i+=a;continue}if(i-=a,i>0)continue;a=Math.min(a,a+i);let c=[...s[0]][0].length,u=t.slice(0,r+s.index+c+a),h=u.slice(r,-r);return{type:"del",raw:u,text:h,tokens:this.lexer.inlineTokens(h)}}}}autolink(t){let e=this.rules.inline.autolink.exec(t);if(e){let n,s;return e[2]==="@"?(n=e[1],s="mailto:"+n):(n=e[1],s=n),{type:"link",raw:e[0],text:n,href:s,tokens:[{type:"text",raw:n,text:n}]}}}url(t){let e;if(e=this.rules.inline.url.exec(t)){let n,s;if(e[2]==="@")n=e[0],s="mailto:"+n;else{let r;do r=e[0],e[0]=this.rules.inline._backpedal.exec(e[0])?.[0]??"";while(r!==e[0]);n=e[0],e[1]==="www."?s="http://"+e[0]:s=e[0]}return{type:"link",raw:e[0],text:n,href:s,tokens:[{type:"text",raw:n,text:n}]}}}inlineText(t){let e=this.rules.inline.text.exec(t);if(e){let n=this.lexer.state.inRawBlock;return{type:"text",raw:e[0],text:e[0],escaped:n}}}},R=class X{tokens;options;state;inlineQueue;tokenizer;constructor(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||_,this.options.tokenizer=this.options.tokenizer||new O,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};let n={other:x,block:D.normal,inline:B.normal};this.options.pedantic?(n.block=D.pedantic,n.inline=B.pedantic):this.options.gfm&&(n.block=D.gfm,this.options.breaks?n.inline=B.breaks:n.inline=B.gfm),this.tokenizer.rules=n}static get rules(){return{block:D,inline:B}}static lex(e,n){return new X(n).lex(e)}static lexInline(e,n){return new X(n).inlineTokens(e)}lex(e){e=e.replace(x.carriageReturn,`\n`),this.blockTokens(e,this.tokens);for(let n=0;n<this.inlineQueue.length;n++){let s=this.inlineQueue[n];this.inlineTokens(s.src,s.tokens)}return this.inlineQueue=[],this.tokens}blockTokens(e,n=[],s=!1){this.tokenizer.lexer=this,this.options.pedantic&&(e=e.replace(x.tabCharGlobal," ").replace(x.spaceLine,""));let r=1/0;for(;e;){if(e.length<r)r=e.length;else{this.infiniteLoopError(e.charCodeAt(0));break}let l;if(this.options.extensions?.block?.some(i=>(l=i.call({lexer:this},e,n))?(e=e.substring(l.raw.length),n.push(l),!0):!1))continue;if(l=this.tokenizer.space(e)){e=e.substring(l.raw.length);let i=n.at(-1);l.raw.length===1&&i!==void 0?i.raw+=`\n`:n.push(l);continue}if(l=this.tokenizer.code(e)){e=e.substring(l.raw.length);let i=n.at(-1);i?.type==="paragraph"||i?.type==="text"?(i.raw+=(i.raw.endsWith(`\n`)?"":`\n`)+l.raw,i.text+=`\n`+l.text,this.inlineQueue.at(-1).src=i.text):n.push(l);continue}if(l=this.tokenizer.fences(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.heading(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.hr(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.blockquote(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.list(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.html(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.def(e)){e=e.substring(l.raw.length);let i=n.at(-1);i?.type==="paragraph"||i?.type==="text"?(i.raw+=(i.raw.endsWith(`\n`)?"":`\n`)+l.raw,i.text+=`\n`+l.raw,this.inlineQueue.at(-1).src=i.text):this.tokens.links[l.tag]||(this.tokens.links[l.tag]={href:l.href,title:l.title},n.push(l));continue}if(l=this.tokenizer.table(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.lheading(e)){e=e.substring(l.raw.length),n.push(l);continue}let a=e;if(this.options.extensions?.startBlock){let i=1/0,o=e.slice(1),c;this.options.extensions.startBlock.forEach(u=>{c=u.call({lexer:this},o),typeof c=="number"&&c>=0&&(i=Math.min(i,c))}),i<1/0&&i>=0&&(a=e.substring(0,i+1))}if(this.state.top&&(l=this.tokenizer.paragraph(a))){let i=n.at(-1);s&&i?.type==="paragraph"?(i.raw+=(i.raw.endsWith(`\n`)?"":`\n`)+l.raw,i.text+=`\n`+l.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=i.text):n.push(l),s=a.length!==e.length,e=e.substring(l.raw.length);continue}if(l=this.tokenizer.text(e)){e=e.substring(l.raw.length);let i=n.at(-1);i?.type==="text"?(i.raw+=(i.raw.endsWith(`\n`)?"":`\n`)+l.raw,i.text+=`\n`+l.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=i.text):n.push(l);continue}if(e){this.infiniteLoopError(e.charCodeAt(0));break}}return this.state.top=!0,n}inline(e,n=[]){return this.inlineQueue.push({src:e,tokens:n}),n}inlineTokens(e,n=[]){this.tokenizer.lexer=this;let s=e;if(this.tokens.links){let i=Object.keys(this.tokens.links);i.length>0&&(s=s.replace(this.tokenizer.rules.inline.reflinkSearch,o=>i.includes(o.slice(o.lastIndexOf("[")+1,-1))?"["+"a".repeat(o.length-2)+"]":o))}s=s.replace(this.tokenizer.rules.inline.anyPunctuation,"++"),s=s.replace(this.tokenizer.rules.inline.blockSkip,(i,o,c)=>{let u=c?c.length:0;return i.slice(0,u)+"["+"a".repeat(i.length-u-2)+"]"}),s=this.options.hooks?.emStrongMask?.call({lexer:this},s)??s;let r=!1,l="",a=1/0;for(;e;){if(e.length<a)a=e.length;else{this.infiniteLoopError(e.charCodeAt(0));break}r||(l=""),r=!1;let i;if(this.options.extensions?.inline?.some(c=>(i=c.call({lexer:this},e,n))?(e=e.substring(i.raw.length),n.push(i),!0):!1))continue;if(i=this.tokenizer.escape(e)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.tag(e)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.link(e)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.reflink(e,this.tokens.links)){e=e.substring(i.raw.length);let c=n.at(-1);i.type==="text"&&c?.type==="text"?(c.raw+=i.raw,c.text+=i.text):n.push(i);continue}if(i=this.tokenizer.emStrong(e,s,l)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.codespan(e)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.br(e)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.del(e,s,l)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.autolink(e)){e=e.substring(i.raw.length),n.push(i);continue}if(!this.state.inLink&&(i=this.tokenizer.url(e))){e=e.substring(i.raw.length),n.push(i);continue}let o=e;if(this.options.extensions?.startInline){let c=1/0,u=e.slice(1),h;this.options.extensions.startInline.forEach(p=>{h=p.call({lexer:this},u),typeof h=="number"&&h>=0&&(c=Math.min(c,h))}),c<1/0&&c>=0&&(o=e.substring(0,c+1))}if(i=this.tokenizer.inlineText(o)){e=e.substring(i.raw.length),i.raw.slice(-1)!=="_"&&(l=i.raw.slice(-1)),r=!0;let c=n.at(-1);c?.type==="text"?(c.raw+=i.raw,c.text+=i.text):n.push(i);continue}if(e){this.infiniteLoopError(e.charCodeAt(0));break}}return n}infiniteLoopError(e){let n="Infinite loop on byte: "+e;if(this.options.silent)console.error(n);else throw new Error(n)}},Q=class{options;parser;constructor(t){this.options=t||_}space(t){return""}code({text:t,lang:e,escaped:n}){let s=(e||"").match(x.notSpaceStart)?.[0],r=t.replace(x.endingNewline,"")+`\n`;return s?\'<pre><code class="language-\'+S(s)+\'">\'+(n?r:S(r,!0))+`</code></pre>\n`:"<pre><code>"+(n?r:S(r,!0))+`</code></pre>\n`}blockquote({tokens:t}){return`<blockquote>\n${this.parser.parse(t)}</blockquote>\n`}html({text:t}){return t}def(t){return""}heading({tokens:t,depth:e}){return`<h${e}>${this.parser.parseInline(t)}</h${e}>\n`}hr(t){return`<hr>\n`}list(t){let e=t.ordered,n=t.start,s="";for(let a=0;a<t.items.length;a++){let i=t.items[a];s+=this.listitem(i)}let r=e?"ol":"ul",l=e&&n!==1?\' start="\'+n+\'"\':"";return"<"+r+l+`>\n`+s+"</"+r+`>\n`}listitem(t){return`<li>${this.parser.parse(t.tokens)}</li>\n`}checkbox({checked:t}){return"<input "+(t?\'checked="" \':"")+\'disabled="" type="checkbox"> \'}paragraph({tokens:t}){return`<p>${this.parser.parseInline(t)}</p>\n`}table(t){let e="",n="";for(let r=0;r<t.header.length;r++)n+=this.tablecell(t.header[r]);e+=this.tablerow({text:n});let s="";for(let r=0;r<t.rows.length;r++){let l=t.rows[r];n="";for(let a=0;a<l.length;a++)n+=this.tablecell(l[a]);s+=this.tablerow({text:n})}return s&&(s=`<tbody>${s}</tbody>`),`<table>\n<thead>\n`+e+`</thead>\n`+s+`</table>\n`}tablerow({text:t}){return`<tr>\n${t}</tr>\n`}tablecell(t){let e=this.parser.parseInline(t.tokens),n=t.header?"th":"td";return(t.align?`<${n} align="${t.align}">`:`<${n}>`)+e+`</${n}>\n`}strong({tokens:t}){return`<strong>${this.parser.parseInline(t)}</strong>`}em({tokens:t}){return`<em>${this.parser.parseInline(t)}</em>`}codespan({text:t}){return`<code>${S(t,!0)}</code>`}br(t){return"<br>"}del({tokens:t}){return`<del>${this.parser.parseInline(t)}</del>`}link({href:t,title:e,tokens:n}){let s=this.parser.parseInline(n),r=he(t);if(r===null)return s;t=r;let l=\'<a href="\'+t+\'"\';return e&&(l+=\' title="\'+S(e)+\'"\'),l+=">"+s+"</a>",l}image({href:t,title:e,text:n,tokens:s}){s&&(n=this.parser.parseInline(s,this.parser.textRenderer));let r=he(t);if(r===null)return S(n);t=r;let l=`<img src="${t}" alt="${S(n)}"`;return e&&(l+=` title="${S(e)}"`),l+=">",l}text(t){return"tokens"in t&&t.tokens?this.parser.parseInline(t.tokens):"escaped"in t&&t.escaped?t.text:S(t.text)}},se=class{strong({text:t}){return t}em({text:t}){return t}codespan({text:t}){return t}del({text:t}){return t}html({text:t}){return t}text({text:t}){return t}link({text:t}){return""+t}image({text:t}){return""+t}br(){return""}checkbox({raw:t}){return t}},$=class U{options;renderer;textRenderer;constructor(e){this.options=e||_,this.options.renderer=this.options.renderer||new Q,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new se}static parse(e,n){return new U(n).parse(e)}static parseInline(e,n){return new U(n).parseInline(e)}parse(e){this.renderer.parser=this;let n="";for(let s=0;s<e.length;s++){let r=e[s];if(this.options.extensions?.renderers?.[r.type]){let a=r,i=this.options.extensions.renderers[a.type].call({parser:this},a);if(i!==!1||!["space","hr","heading","code","table","blockquote","list","html","def","paragraph","text"].includes(a.type)){n+=i||"";continue}}let l=r;switch(l.type){case"space":{n+=this.renderer.space(l);break}case"hr":{n+=this.renderer.hr(l);break}case"heading":{n+=this.renderer.heading(l);break}case"code":{n+=this.renderer.code(l);break}case"table":{n+=this.renderer.table(l);break}case"blockquote":{n+=this.renderer.blockquote(l);break}case"list":{n+=this.renderer.list(l);break}case"checkbox":{n+=this.renderer.checkbox(l);break}case"html":{n+=this.renderer.html(l);break}case"def":{n+=this.renderer.def(l);break}case"paragraph":{n+=this.renderer.paragraph(l);break}case"text":{n+=this.renderer.text(l);break}default:{let a=\'Token with "\'+l.type+\'" type was not found.\';if(this.options.silent)return console.error(a),"";throw new Error(a)}}}return n}parseInline(e,n=this.renderer){this.renderer.parser=this;let s="";for(let r=0;r<e.length;r++){let l=e[r];if(this.options.extensions?.renderers?.[l.type]){let i=this.options.extensions.renderers[l.type].call({parser:this},l);if(i!==!1||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(l.type)){s+=i||"";continue}}let a=l;switch(a.type){case"escape":{s+=n.text(a);break}case"html":{s+=n.html(a);break}case"link":{s+=n.link(a);break}case"image":{s+=n.image(a);break}case"checkbox":{s+=n.checkbox(a);break}case"strong":{s+=n.strong(a);break}case"em":{s+=n.em(a);break}case"codespan":{s+=n.codespan(a);break}case"br":{s+=n.br(a);break}case"del":{s+=n.del(a);break}case"text":{s+=n.text(a);break}default:{let i=\'Token with "\'+a.type+\'" type was not found.\';if(this.options.silent)return console.error(i),"";throw new Error(i)}}}return s}},q=class{options;block;constructor(t){this.options=t||_}static passThroughHooks=new Set(["preprocess","postprocess","processAllTokens","emStrongMask"]);static passThroughHooksRespectAsync=new Set(["preprocess","postprocess","processAllTokens"]);preprocess(t){return t}postprocess(t){return t}processAllTokens(t){return t}emStrongMask(t){return t}provideLexer(t=this.block){return t?R.lex:R.lexInline}provideParser(t=this.block){return t?$.parse:$.parseInline}},mt=class{defaults=V();options=this.setOptions;parse=this.parseMarkdown(!0);parseInline=this.parseMarkdown(!1);Parser=$;Renderer=Q;TextRenderer=se;Lexer=R;Tokenizer=O;Hooks=q;constructor(...t){this.use(...t)}walkTokens(t,e){let n=[];for(let s of t)switch(n=n.concat(e.call(this,s)),s.type){case"table":{let r=s;for(let l of r.header)n=n.concat(this.walkTokens(l.tokens,e));for(let l of r.rows)for(let a of l)n=n.concat(this.walkTokens(a.tokens,e));break}case"list":{let r=s;n=n.concat(this.walkTokens(r.items,e));break}default:{let r=s;this.defaults.extensions?.childTokens?.[r.type]?this.defaults.extensions.childTokens[r.type].forEach(l=>{let a=r[l].flat(1/0);n=n.concat(this.walkTokens(a,e))}):r.tokens&&(n=n.concat(this.walkTokens(r.tokens,e)))}}return n}use(...t){let e=this.defaults.extensions||{renderers:{},childTokens:{}};return t.forEach(n=>{let s={...n};if(s.async=this.defaults.async||s.async||!1,n.extensions&&(n.extensions.forEach(r=>{if(!r.name)throw new Error("extension name required");if("renderer"in r){let l=e.renderers[r.name];l?e.renderers[r.name]=function(...a){let i=r.renderer.apply(this,a);return i===!1&&(i=l.apply(this,a)),i}:e.renderers[r.name]=r.renderer}if("tokenizer"in r){if(!r.level||r.level!=="block"&&r.level!=="inline")throw new Error("extension level must be \'block\' or \'inline\'");let l=e[r.level];l?l.unshift(r.tokenizer):e[r.level]=[r.tokenizer],r.start&&(r.level==="block"?e.startBlock?e.startBlock.push(r.start):e.startBlock=[r.start]:r.level==="inline"&&(e.startInline?e.startInline.push(r.start):e.startInline=[r.start]))}"childTokens"in r&&r.childTokens&&(e.childTokens[r.name]=r.childTokens)}),s.extensions=e),n.renderer){let r=this.defaults.renderer||new Q(this.defaults);for(let l in n.renderer){if(!(l in r))throw new Error(`renderer \'${l}\' does not exist`);if(["options","parser"].includes(l))continue;let a=l,i=n.renderer[a],o=r[a];r[a]=(...c)=>{let u=i.apply(r,c);return u===!1&&(u=o.apply(r,c)),u||""}}s.renderer=r}if(n.tokenizer){let r=this.defaults.tokenizer||new O(this.defaults);for(let l in n.tokenizer){if(!(l in r))throw new Error(`tokenizer \'${l}\' does not exist`);if(["options","rules","lexer"].includes(l))continue;let a=l,i=n.tokenizer[a],o=r[a];r[a]=(...c)=>{let u=i.apply(r,c);return u===!1&&(u=o.apply(r,c)),u}}s.tokenizer=r}if(n.hooks){let r=this.defaults.hooks||new q;for(let l in n.hooks){if(!(l in r))throw new Error(`hook \'${l}\' does not exist`);if(["options","block"].includes(l))continue;let a=l,i=n.hooks[a],o=r[a];q.passThroughHooks.has(l)?r[a]=c=>{if(this.defaults.async&&q.passThroughHooksRespectAsync.has(l))return(async()=>{let h=await i.call(r,c);return o.call(r,h)})();let u=i.call(r,c);return o.call(r,u)}:r[a]=(...c)=>{if(this.defaults.async)return(async()=>{let h=await i.apply(r,c);return h===!1&&(h=await o.apply(r,c)),h})();let u=i.apply(r,c);return u===!1&&(u=o.apply(r,c)),u}}s.hooks=r}if(n.walkTokens){let r=this.defaults.walkTokens,l=n.walkTokens;s.walkTokens=function(a){let i=[];return i.push(l.call(this,a)),r&&(i=i.concat(r.call(this,a))),i}}this.defaults={...this.defaults,...s}}),this}setOptions(t){return this.defaults={...this.defaults,...t},this}lexer(t,e){return R.lex(t,e??this.defaults)}parser(t,e){return $.parse(t,e??this.defaults)}parseMarkdown(t){return(e,n)=>{let s={...n},r={...this.defaults,...s},l=this.onError(!!r.silent,!!r.async);if(this.defaults.async===!0&&s.async===!1)return l(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(typeof e>"u"||e===null)return l(new Error("marked(): input parameter is undefined or null"));if(typeof e!="string")return l(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected"));if(r.hooks&&(r.hooks.options=r,r.hooks.block=t),r.async)return(async()=>{let a=r.hooks?await r.hooks.preprocess(e):e,i=await(r.hooks?await r.hooks.provideLexer(t):t?R.lex:R.lexInline)(a,r),o=r.hooks?await r.hooks.processAllTokens(i):i;r.walkTokens&&await Promise.all(this.walkTokens(o,r.walkTokens));let c=await(r.hooks?await r.hooks.provideParser(t):t?$.parse:$.parseInline)(o,r);return r.hooks?await r.hooks.postprocess(c):c})().catch(l);try{r.hooks&&(e=r.hooks.preprocess(e));let a=(r.hooks?r.hooks.provideLexer(t):t?R.lex:R.lexInline)(e,r);r.hooks&&(a=r.hooks.processAllTokens(a)),r.walkTokens&&this.walkTokens(a,r.walkTokens);let i=(r.hooks?r.hooks.provideParser(t):t?$.parse:$.parseInline)(a,r);return r.hooks&&(i=r.hooks.postprocess(i)),i}catch(a){return l(a)}}}onError(t,e){return n=>{if(n.message+=`\nPlease report this to https://github.com/markedjs/marked.`,t){let s="<p>An error occurred:</p><pre>"+S(n.message+"",!0)+"</pre>";return e?Promise.resolve(s):s}if(e)return Promise.reject(n);throw n}}},I=new mt;function g(t,e){return I.parse(t,e)}g.options=g.setOptions=function(t){return I.setOptions(t),g.defaults=I.defaults,ke(g.defaults),g};g.getDefaults=V;g.defaults=_;g.use=function(...t){return I.use(...t),g.defaults=I.defaults,ke(g.defaults),g};g.walkTokens=function(t,e){return I.walkTokens(t,e)};g.parseInline=I.parseInline;g.Parser=$;g.parser=$.parse;g.Renderer=Q;g.TextRenderer=se;g.Lexer=R;g.lexer=R.lex;g.Tokenizer=O;g.Hooks=q;g.parse=g;var zt=g.options,At=g.setOptions,Ct=g.use,It=g.walkTokens,_t=g.parseInline;var Pt=$.parse,Mt=R.lex;function Se(t,e,n){let s=0;for(let r=e;r<n;r++)s+=t[r].raw.length;return s}function wt(t,e){let n=t;return n.links=e,n}var yt=/^ {0,3}\\$\\$/m;function Le(t){return t.includes("$$")===!1?!1:yt.test(t)}function Rt(t,e){return t[e-2]?.type!=="list"?!0:e+1<t.length}function ze(t,e){for(let n=t.length-2;n>=e;n--)if(t[n].type==="space"&&Rt(t,n+1)!==!1)return n+1;return-1}function Ae(t){let e=t.links;if(!e)return!1;for(let n in e)return!0;return!1}function Ce(t,e,n,s,r){let l=r;for(let a=e;a<n;a++){let i=t[a].raw;if(s.startsWith(i,l)===!1)return!1;l+=i.length}return!0}function G(t,e,n){return{source:t,tail:t,tokens:e,stableCount:0,stableOffset:0,degraded:!0,degradedReason:n}}function Te(t,e){return{source:t,tail:t,tokens:e,stableCount:0,stableOffset:0,degraded:!1,degradedReason:null}}function $t(t,e){if(Ae(e))return G(t,e,"link-definition");if(t.includes("\\r"))return G(t,e,"carriage-return");if(Le(t))return G(t,e,"block-math");let n=ze(e,1);if(n<0||Ce(e,0,n,t,0)===!1)return Te(t,e);let s=Se(e,0,n);return{source:t,tail:t.slice(s),tokens:e,stableCount:n,stableOffset:s,degraded:!1,degradedReason:null}}function le(t){let e=g.lexer(t);return{tokens:e,cache:$t(t,e),charsLexed:t.length,reusedTokens:0}}function j(t,e){let n=g.lexer(t);return{tokens:n,cache:G(t,n,e),charsLexed:t.length,reusedTokens:0}}function Ie(t,e){let n=t.source+e;if(t.degraded)return j(n,t.degradedReason??"link-definition");if(e.includes("\\r"))return j(n,"carriage-return");if(t.stableCount===0)return le(n);let s=t.tail+e;if(Le(s))return j(n,"block-math");let r=g.lexer(s);if(Ae(r))return j(n,"link-definition");let l=t.tokens.slice(0,t.stableCount),a=wt([...l,...r],r.links),i=t.stableCount,o=t.stableOffset,c=s,u=ze(a,t.stableCount+1);if(u>t.stableCount&&Ce(a,t.stableCount,u,s,0)){let h=Se(a,t.stableCount,u);i=u,o=t.stableOffset+h,c=s.slice(h)}return{tokens:a,cache:{source:n,tail:c,tokens:a,stableCount:i,stableOffset:o,degraded:!1,degradedReason:null},charsLexed:s.length,reusedTokens:t.stableCount}}var Tt=0;function St(t){if(typeof t!="string"||typeof performance.mark!="function"||typeof performance.measure!="function")return null;let e=Tt++,n={name:t,startMark:`${t}:start:${e}`,endMark:`${t}:end:${e}`};try{return performance.mark(n.startMark),n}catch{return null}}function Lt(t){if(t)try{performance.mark(t.endMark),performance.measure(t.name,t.startMark,t.endMark)}catch{}finally{try{performance.clearMarks?.(t.startMark),performance.clearMarks?.(t.endMark)}catch{}}}g.use({extensions:[{name:"blockMath",level:"block",start(t){return t.match(/^ {0,3}\\$\\$/m)?.index},tokenizer(t){let e=/^ {0,3}\\$\\$([\\s\\S]+?)\\$\\$[ \\t]*(?:\\n|$)/.exec(t);if(e)return{type:"blockMath",raw:e[0],text:e[1].trim()}},renderer(t){return t.raw}},{name:"inlineMath",level:"inline",start(t){return t.match(/(?<![\\\\$])\\$(?![$\\s])/)?.index},tokenizer(t){let e=/^\\$(?![$\\s\\d])((?:\\\\\\$|[^$\\n])*?)(?<!\\s)\\$(?!\\d)/.exec(t);if(e)return{type:"inlineMath",raw:e[0],text:e[1].trim()}},renderer(t){return t.raw}}]});var E=new Map;self.onmessage=t=>{let e=t.data;if(typeof e!="object"||e===null)return;let{id:n,text:s,append:r,expectedLength:l,oldRaws:a,instance:i,baseVersion:o,dispose:c,userTimingName:u}=e;if(c===!0){typeof i=="string"&&E.delete(i);return}let h=typeof i=="string"?i:null,p=typeof o=="number"?o:null,d,f=null,m=null;if(typeof r=="string"){if(h===null||p===null){self.postMessage({id:n,needResync:!0});return}let w=E.get(h);if(!w||w.version!==p){self.postMessage({id:n,needResync:!0});return}if(typeof l=="number"&&w.lex.source.length+r.length!==l){E.delete(h),self.postMessage({id:n,needResync:!0});return}let y=w.lex;d=()=>Ie(y,r),m=y.tokens}else if(typeof s=="string"){let w=s;if(d=()=>le(w),Array.isArray(a))f=a;else if(h!==null&&p!==null){let y=E.get(h);if(y&&y.version===p)m=y.lex.tokens;else{self.postMessage({id:n,needResync:!0});return}}}else return;try{let w=typeof u=="string"?St(u):null,y=performance.now(),L;try{L=d()}finally{w&&Lt(w)}let W=performance.now()-y,A=L.tokens,b=0;if(f!==null){let T=Math.min(f.length,A.length);for(;b<T&&f[b]===A[b].raw;b++);}else if(m!==null){let T=m,ie=Math.min(T.length,A.length);for(b=Math.min(L.reusedTokens,ie);b<ie&&T[b].raw===A[b].raw;b++);}h!==null&&p!==null&&E.set(h,{version:p+1,lex:L.cache}),self.postMessage({id:n,matchLen:b,tail:A.slice(b),lexerMs:W,sourceCharsLexed:L.charsLexed})}catch(w){h!==null&&E.delete(h),self.postMessage({id:n,error:String(w)})}};})();\n';
|
|
1844
|
+
|
|
1845
|
+
// src/Markdown.ts
|
|
1846
|
+
var now = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
1847
|
+
function lexMarkdown(text, userTiming) {
|
|
1848
|
+
if (!userTiming) return marked.lexer(text);
|
|
1849
|
+
const timing = beginVectoUserTiming(VECTO_USER_TIMING.markdown.parse);
|
|
1850
|
+
try {
|
|
1851
|
+
return marked.lexer(text);
|
|
1852
|
+
} finally {
|
|
1853
|
+
if (timing) endVectoUserTiming(timing);
|
|
1509
1854
|
}
|
|
1510
|
-
return best;
|
|
1511
1855
|
}
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1856
|
+
marked.use({
|
|
1857
|
+
extensions: [
|
|
1858
|
+
{
|
|
1859
|
+
name: "blockMath",
|
|
1860
|
+
level: "block",
|
|
1861
|
+
start(src) {
|
|
1862
|
+
return src.match(/^ {0,3}\$\$/m)?.index;
|
|
1863
|
+
},
|
|
1864
|
+
tokenizer(src) {
|
|
1865
|
+
const match = /^ {0,3}\$\$([\s\S]+?)\$\$[ \t]*(?:\n|$)/.exec(src);
|
|
1866
|
+
if (match) {
|
|
1867
|
+
return {
|
|
1868
|
+
type: "blockMath",
|
|
1869
|
+
raw: match[0],
|
|
1870
|
+
text: match[1].trim()
|
|
1871
|
+
};
|
|
1872
|
+
}
|
|
1873
|
+
return void 0;
|
|
1874
|
+
},
|
|
1875
|
+
renderer(token) {
|
|
1876
|
+
return token.raw;
|
|
1877
|
+
}
|
|
1878
|
+
},
|
|
1879
|
+
{
|
|
1880
|
+
name: "inlineMath",
|
|
1881
|
+
level: "inline",
|
|
1882
|
+
start(src) {
|
|
1883
|
+
return src.match(/(?<![\\$])\$(?![$\s])/)?.index;
|
|
1884
|
+
},
|
|
1885
|
+
tokenizer(src) {
|
|
1886
|
+
const match = /^\$(?![$\s\d])((?:\\\$|[^$\n])*?)(?<!\s)\$(?!\d)/.exec(src);
|
|
1887
|
+
if (match) {
|
|
1888
|
+
return {
|
|
1889
|
+
type: "inlineMath",
|
|
1890
|
+
raw: match[0],
|
|
1891
|
+
text: match[1].trim()
|
|
1892
|
+
};
|
|
1893
|
+
}
|
|
1894
|
+
return void 0;
|
|
1895
|
+
},
|
|
1896
|
+
renderer(token) {
|
|
1897
|
+
return token.raw;
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
]
|
|
1901
|
+
});
|
|
1902
|
+
var markdownWorker = null;
|
|
1903
|
+
var workerIdCounter = 0;
|
|
1904
|
+
var workerInstanceCounter = 0;
|
|
1905
|
+
var workerCallbacks = /* @__PURE__ */ new Map();
|
|
1906
|
+
function runSyncFallback(entry) {
|
|
1907
|
+
try {
|
|
1908
|
+
entry.cb(0, lexMarkdown(entry.text, entry.userTiming), true);
|
|
1909
|
+
} catch (err) {
|
|
1910
|
+
console.warn("Markdown sync fallback parse failed", err);
|
|
1911
|
+
entry.onDropped?.();
|
|
1516
1912
|
}
|
|
1517
|
-
|
|
1518
|
-
|
|
1913
|
+
}
|
|
1914
|
+
if (typeof Worker !== "undefined") {
|
|
1915
|
+
try {
|
|
1916
|
+
const blob = new Blob([WORKER_SOURCE_STRING], {
|
|
1917
|
+
type: "application/javascript"
|
|
1918
|
+
});
|
|
1919
|
+
markdownWorker = new Worker(URL.createObjectURL(blob));
|
|
1920
|
+
markdownWorker.onmessage = (e) => {
|
|
1921
|
+
const { id, matchLen, tail, error, needResync, lexerMs, sourceCharsLexed } = e.data;
|
|
1922
|
+
const entry = workerCallbacks.get(id);
|
|
1923
|
+
if (entry) {
|
|
1924
|
+
workerCallbacks.delete(id);
|
|
1925
|
+
if (needResync && entry.onNeedResync) {
|
|
1926
|
+
entry.onNeedResync();
|
|
1927
|
+
} else if (needResync) {
|
|
1928
|
+
runSyncFallback(entry);
|
|
1929
|
+
} else if (!error) {
|
|
1930
|
+
entry.cb(matchLen, tail, false, {
|
|
1931
|
+
lexerMs: typeof lexerMs === "number" ? lexerMs : 0,
|
|
1932
|
+
sourceCharsLexed: typeof sourceCharsLexed === "number" ? sourceCharsLexed : 0
|
|
1933
|
+
});
|
|
1934
|
+
} else {
|
|
1935
|
+
runSyncFallback(entry);
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
};
|
|
1939
|
+
markdownWorker.onerror = () => {
|
|
1940
|
+
const pending = [...workerCallbacks.values()];
|
|
1941
|
+
workerCallbacks.clear();
|
|
1942
|
+
markdownWorker = null;
|
|
1943
|
+
for (const entry of pending) runSyncFallback(entry);
|
|
1944
|
+
};
|
|
1945
|
+
} catch (err) {
|
|
1946
|
+
console.warn("Failed to initialize MarkdownWorker", err);
|
|
1519
1947
|
}
|
|
1520
|
-
return new RichText(spans, {
|
|
1521
|
-
font,
|
|
1522
|
-
color,
|
|
1523
|
-
maxWidth,
|
|
1524
|
-
linkColor: "#38bdf8",
|
|
1525
|
-
selectable,
|
|
1526
|
-
onLinkClick
|
|
1527
|
-
});
|
|
1528
1948
|
}
|
|
1529
|
-
var Markdown = class _Markdown extends
|
|
1949
|
+
var Markdown = class _Markdown extends UIComponent3 {
|
|
1530
1950
|
content;
|
|
1531
1951
|
maxWidth;
|
|
1532
1952
|
theme;
|
|
1533
1953
|
onLinkClick;
|
|
1534
1954
|
selectable;
|
|
1955
|
+
/**
|
|
1956
|
+
* Whether code blocks and tables carry copy / download controls.
|
|
1957
|
+
*
|
|
1958
|
+
* Read when a block entity is built, so it affects blocks rendered from here on
|
|
1959
|
+
* rather than retroactively; a document does not rebuild to gain or lose an
|
|
1960
|
+
* affordance.
|
|
1961
|
+
*/
|
|
1962
|
+
blockAffordances;
|
|
1963
|
+
/** Clipboard writer used by the copy controls. */
|
|
1964
|
+
writeClipboard;
|
|
1965
|
+
/** File saver used by the download controls. */
|
|
1966
|
+
saveFile;
|
|
1535
1967
|
activeBlockMetrics = null;
|
|
1536
1968
|
/**
|
|
1537
1969
|
* Called after a streamed append has re-laid-out the document.
|
|
@@ -1607,6 +2039,20 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
1607
2039
|
* field only so {@link destroy} can remove the exact closure it added.
|
|
1608
2040
|
*/
|
|
1609
2041
|
inlineMathRepaint;
|
|
2042
|
+
/**
|
|
2043
|
+
* This instance's entry in the inline-image decode waiters, or `undefined` if it
|
|
2044
|
+
* has never rendered an image. Held as a field only so {@link destroy} can remove
|
|
2045
|
+
* the exact closure it added.
|
|
2046
|
+
*/
|
|
2047
|
+
inlineImageRemeasure;
|
|
2048
|
+
/**
|
|
2049
|
+
* URLs whose decoded aspect ratio this document has already reserved a box for.
|
|
2050
|
+
*
|
|
2051
|
+
* The guard that makes the re-measure fire once per image rather than once per
|
|
2052
|
+
* decode-notification-per-image: the waiter set is module-level, so a page of
|
|
2053
|
+
* many documents tells all of them about all decodes.
|
|
2054
|
+
*/
|
|
2055
|
+
inlineImagesMeasured = /* @__PURE__ */ new Set();
|
|
1610
2056
|
/**
|
|
1611
2057
|
* True while this document is waiting on the lazy MathJax load.
|
|
1612
2058
|
*
|
|
@@ -1752,11 +2198,17 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
1752
2198
|
constructor(markdownText, opts = {}) {
|
|
1753
2199
|
super();
|
|
1754
2200
|
this.maxWidth = opts.maxWidth ?? 800;
|
|
1755
|
-
this.theme =
|
|
2201
|
+
this.theme = resolveTheme(opts.theme);
|
|
1756
2202
|
this.onLinkClick = opts.onLinkClick;
|
|
1757
2203
|
this.selectable = opts.selectable ?? true;
|
|
1758
2204
|
this._userTiming = opts.userTiming ?? false;
|
|
1759
|
-
this.
|
|
2205
|
+
this.blockAffordances = opts.blockAffordances ?? false;
|
|
2206
|
+
this.writeClipboard = opts.writeClipboard ?? defaultWriteClipboard;
|
|
2207
|
+
this.saveFile = opts.saveFile ?? defaultSaveFile;
|
|
2208
|
+
this.content = new Stack({
|
|
2209
|
+
direction: "vertical",
|
|
2210
|
+
gap: this.theme.blockGap
|
|
2211
|
+
});
|
|
1760
2212
|
this.add(this.content);
|
|
1761
2213
|
this.rawMarkdown = "";
|
|
1762
2214
|
this.setTokens([]);
|
|
@@ -1975,14 +2427,14 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
1975
2427
|
switch (token.type) {
|
|
1976
2428
|
case "heading":
|
|
1977
2429
|
case "paragraph": {
|
|
1978
|
-
if (entity instanceof
|
|
2430
|
+
if (entity instanceof RichText2) {
|
|
1979
2431
|
entity.setMaxWidth(availableWidth);
|
|
1980
2432
|
return;
|
|
1981
2433
|
}
|
|
1982
2434
|
if (entity instanceof Stack) {
|
|
1983
2435
|
entity.maxWidth = availableWidth;
|
|
1984
2436
|
for (const run of entity.children) {
|
|
1985
|
-
if (run instanceof
|
|
2437
|
+
if (run instanceof RichText2) run.setMaxWidth(availableWidth);
|
|
1986
2438
|
else if (run instanceof Image) this.refitParagraphImage(run, availableWidth);
|
|
1987
2439
|
}
|
|
1988
2440
|
entity.layout();
|
|
@@ -1998,7 +2450,7 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
1998
2450
|
const bqToken = token;
|
|
1999
2451
|
const innerStack = entity.children.find((c) => c instanceof Stack);
|
|
2000
2452
|
const border = entity.children.find((c) => c instanceof QuoteBorder);
|
|
2001
|
-
const indentStart = Math.min(
|
|
2453
|
+
const indentStart = Math.min(this.theme.quoteIndent, availableWidth);
|
|
2002
2454
|
const childWidth = Math.max(0, availableWidth - indentStart);
|
|
2003
2455
|
if (innerStack instanceof Stack && bqToken.tokens) {
|
|
2004
2456
|
let index = 0;
|
|
@@ -2025,7 +2477,7 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
2025
2477
|
case "list": {
|
|
2026
2478
|
if (!(entity instanceof Stack)) return;
|
|
2027
2479
|
for (const item of entity.children) {
|
|
2028
|
-
if (item instanceof
|
|
2480
|
+
if (item instanceof RichText2) item.setMaxWidth(availableWidth);
|
|
2029
2481
|
}
|
|
2030
2482
|
entity.layout();
|
|
2031
2483
|
return;
|
|
@@ -2101,7 +2553,98 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
2101
2553
|
this.scene?.markDirty();
|
|
2102
2554
|
};
|
|
2103
2555
|
this.inlineMathRepaint = repaint;
|
|
2104
|
-
|
|
2556
|
+
subscribeInlineMathRaster(repaint);
|
|
2557
|
+
}
|
|
2558
|
+
/**
|
|
2559
|
+
* Re-measure this document when an inline image's raster finishes decoding.
|
|
2560
|
+
*
|
|
2561
|
+
* Inline images differ from inline formulas in one way that matters: a formula's
|
|
2562
|
+
* box is known synchronously the moment it typesets, while an image's aspect
|
|
2563
|
+
* ratio arrives only with the decode. The span reserved a square until then, so a
|
|
2564
|
+
* decode that reports anything else has invalidated a WIDTH, and a repaint into
|
|
2565
|
+
* the old box would letterbox or stretch the picture.
|
|
2566
|
+
*
|
|
2567
|
+
* So this rebuilds through {@link retypesetFromTokens} — the same late-arrival
|
|
2568
|
+
* path MathJax uses — but only when a reserved width actually changed. Every live
|
|
2569
|
+
* document is notified for every decode, including images it does not contain, so
|
|
2570
|
+
* an unconditional rebuild here would be O(documents x images) full re-renders
|
|
2571
|
+
* for a page of many blocks.
|
|
2572
|
+
*
|
|
2573
|
+
* Subscribed lazily and held as a field for the same two reasons as its math
|
|
2574
|
+
* counterpart: a document with no images costs nothing, and `destroy` must remove
|
|
2575
|
+
* the exact closure it added.
|
|
2576
|
+
*/
|
|
2577
|
+
subscribeInlineImageRemeasure() {
|
|
2578
|
+
if (this.inlineImageRemeasure || this.isDestroyed) return;
|
|
2579
|
+
const remeasure = () => {
|
|
2580
|
+
if (this.isDestroyed) return;
|
|
2581
|
+
if (this.inlineImageBoxesStale()) this.retypesetFromTokens();
|
|
2582
|
+
else this.scene?.markDirty();
|
|
2583
|
+
};
|
|
2584
|
+
this.inlineImageRemeasure = remeasure;
|
|
2585
|
+
subscribeInlineImageRaster(remeasure);
|
|
2586
|
+
}
|
|
2587
|
+
/**
|
|
2588
|
+
* Whether any inline image in this document has just learned it is not square.
|
|
2589
|
+
*
|
|
2590
|
+
* An inline image's span reserves a square box before its raster decodes, because
|
|
2591
|
+
* that is the only shape available without a natural size. The decode supplies the
|
|
2592
|
+
* real aspect ratio, so a non-square image needs one rebuild to reserve the right
|
|
2593
|
+
* width — and exactly one. Every live document is notified of every decode on the
|
|
2594
|
+
* page, including images it does not contain, so this has to answer "did MY
|
|
2595
|
+
* geometry just change" and not merely "did something decode".
|
|
2596
|
+
*
|
|
2597
|
+
* Walks the tokens rather than the entity tree: the reserved box is a function of
|
|
2598
|
+
* the raster's aspect ratio, which is available here, and a token walk cannot be
|
|
2599
|
+
* confused by an entity a previous rebuild already corrected.
|
|
2600
|
+
*
|
|
2601
|
+
* Only headings and table cells are inspected. Every other context splits an image
|
|
2602
|
+
* into its own block whose `Image` entity resizes itself in `onLoad`, so a rebuild
|
|
2603
|
+
* for one of those would be pure cost.
|
|
2604
|
+
*/
|
|
2605
|
+
inlineImageBoxesStale() {
|
|
2606
|
+
const stale = (tokens) => {
|
|
2607
|
+
let changed2 = false;
|
|
2608
|
+
for (const token of tokens ?? []) {
|
|
2609
|
+
if (token.type === "image") {
|
|
2610
|
+
const href = token.href;
|
|
2611
|
+
if (this.inlineImagesMeasured.has(href)) continue;
|
|
2612
|
+
const raster = ensureInlineImageRaster(href);
|
|
2613
|
+
if (raster.failed) {
|
|
2614
|
+
this.inlineImagesMeasured.add(href);
|
|
2615
|
+
changed2 = true;
|
|
2616
|
+
continue;
|
|
2617
|
+
}
|
|
2618
|
+
if (!raster.decoded || !raster.naturalWidth || !raster.naturalHeight) {
|
|
2619
|
+
continue;
|
|
2620
|
+
}
|
|
2621
|
+
this.inlineImagesMeasured.add(href);
|
|
2622
|
+
if (raster.naturalWidth !== raster.naturalHeight) changed2 = true;
|
|
2623
|
+
continue;
|
|
2624
|
+
}
|
|
2625
|
+
if (stale(token.tokens)) {
|
|
2626
|
+
changed2 = true;
|
|
2627
|
+
}
|
|
2628
|
+
}
|
|
2629
|
+
return changed2;
|
|
2630
|
+
};
|
|
2631
|
+
let changed = false;
|
|
2632
|
+
for (const token of this.tokens) {
|
|
2633
|
+
if (token.type === "heading") {
|
|
2634
|
+
if (stale(token.tokens)) changed = true;
|
|
2635
|
+
} else if (token.type === "table") {
|
|
2636
|
+
const table = token;
|
|
2637
|
+
for (const cell of table.header) {
|
|
2638
|
+
if (stale(cell.tokens)) changed = true;
|
|
2639
|
+
}
|
|
2640
|
+
for (const row of table.rows) {
|
|
2641
|
+
for (const cell of row) {
|
|
2642
|
+
if (stale(cell.tokens)) changed = true;
|
|
2643
|
+
}
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2647
|
+
return changed;
|
|
2105
2648
|
}
|
|
2106
2649
|
destroy() {
|
|
2107
2650
|
this.isDestroyed = true;
|
|
@@ -2114,9 +2657,13 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
2114
2657
|
this.mathLoadPending = false;
|
|
2115
2658
|
this.flushAppendSettledWaiters();
|
|
2116
2659
|
if (this.inlineMathRepaint) {
|
|
2117
|
-
|
|
2660
|
+
unsubscribeInlineMathRaster(this.inlineMathRepaint);
|
|
2118
2661
|
this.inlineMathRepaint = void 0;
|
|
2119
2662
|
}
|
|
2663
|
+
if (this.inlineImageRemeasure) {
|
|
2664
|
+
unsubscribeInlineImageRaster(this.inlineImageRemeasure);
|
|
2665
|
+
this.inlineImageRemeasure = void 0;
|
|
2666
|
+
}
|
|
2120
2667
|
markdownWorker?.postMessage({
|
|
2121
2668
|
instance: this.workerInstanceId,
|
|
2122
2669
|
dispose: true
|
|
@@ -2510,11 +3057,11 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
2510
3057
|
}
|
|
2511
3058
|
/** One text run of an image-bearing paragraph, as both paths build it. */
|
|
2512
3059
|
inlineRunRichText(tokens, availableWidth, t) {
|
|
2513
|
-
return new
|
|
3060
|
+
return new RichText2(this.inlineRunSpans(tokens, t), {
|
|
2514
3061
|
font: `${t.fontSize}px ${t.bodyFont}`,
|
|
2515
3062
|
color: t.textColor,
|
|
2516
3063
|
maxWidth: availableWidth,
|
|
2517
|
-
linkColor:
|
|
3064
|
+
linkColor: t.linkColor,
|
|
2518
3065
|
selectable: this.selectable,
|
|
2519
3066
|
onLinkClick: this.onLinkClick
|
|
2520
3067
|
});
|
|
@@ -2544,6 +3091,73 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
2544
3091
|
* policy for a zero-dimension source is a separate decision from notifying
|
|
2545
3092
|
* the scene, which is the actual defect here.
|
|
2546
3093
|
*/
|
|
3094
|
+
/**
|
|
3095
|
+
* Wraps a block in its copy / download controls, or returns it untouched.
|
|
3096
|
+
*
|
|
3097
|
+
* The controls are built lazily through `make` so a document with
|
|
3098
|
+
* `blockAffordances` off pays nothing — not the closures, not the measurement
|
|
3099
|
+
* `BlockAffordanceButton` does in its constructor.
|
|
3100
|
+
*/
|
|
3101
|
+
withBlockAffordances(block, make) {
|
|
3102
|
+
if (!this.blockAffordances) return block;
|
|
3103
|
+
const controls = make();
|
|
3104
|
+
return controls.length > 0 ? new BlockWithAffordances(block, controls) : block;
|
|
3105
|
+
}
|
|
3106
|
+
/** Copy and download controls for one fenced code block. */
|
|
3107
|
+
codeBlockAffordances(source, lang) {
|
|
3108
|
+
const opts = this.affordanceButtonOptions();
|
|
3109
|
+
return [
|
|
3110
|
+
new BlockAffordanceButton("Copy code", "Copied", () => this.writeClipboard(source), opts),
|
|
3111
|
+
new BlockAffordanceButton(
|
|
3112
|
+
"Download code",
|
|
3113
|
+
"Saved",
|
|
3114
|
+
() => this.saveFile(`code.${extensionForLanguage(lang)}`, source, mimeForLanguage(lang)),
|
|
3115
|
+
opts
|
|
3116
|
+
)
|
|
3117
|
+
];
|
|
3118
|
+
}
|
|
3119
|
+
/** Copy (as Markdown) and download (as CSV) controls for one table. */
|
|
3120
|
+
tableAffordances(tblToken) {
|
|
3121
|
+
const content = tableContentOf(tblToken);
|
|
3122
|
+
const opts = this.affordanceButtonOptions();
|
|
3123
|
+
return [
|
|
3124
|
+
// Markdown rather than CSV for the clipboard: the reader copied it out of a
|
|
3125
|
+
// Markdown document and the overwhelmingly likely destination is another
|
|
3126
|
+
// one. CSV is what the download is for, where a spreadsheet is the target.
|
|
3127
|
+
new BlockAffordanceButton(
|
|
3128
|
+
"Copy table",
|
|
3129
|
+
"Copied",
|
|
3130
|
+
() => this.writeClipboard(tableToMarkdown(content)),
|
|
3131
|
+
opts
|
|
3132
|
+
),
|
|
3133
|
+
new BlockAffordanceButton(
|
|
3134
|
+
"Download table",
|
|
3135
|
+
"Saved",
|
|
3136
|
+
() => this.saveFile("table.csv", tableToCsv(content), "text/csv;charset=utf-8"),
|
|
3137
|
+
opts
|
|
3138
|
+
)
|
|
3139
|
+
];
|
|
3140
|
+
}
|
|
3141
|
+
/**
|
|
3142
|
+
* Button styling for the affordances, derived from the document theme.
|
|
3143
|
+
*
|
|
3144
|
+
* Themed rather than hardcoded so a light-theme document does not get the dark
|
|
3145
|
+
* default palette. `focusColor` is set explicitly from the theme's accent
|
|
3146
|
+
* because `Button`'s default cyan is tuned for the dark palette and reads as
|
|
3147
|
+
* off-brand elsewhere — while a focus ring is the one affordance a keyboard
|
|
3148
|
+
* user cannot do without.
|
|
3149
|
+
*/
|
|
3150
|
+
affordanceButtonOptions() {
|
|
3151
|
+
return {
|
|
3152
|
+
font: `600 12px ${this.theme.bodyFont}`,
|
|
3153
|
+
padding: 6,
|
|
3154
|
+
radius: 6,
|
|
3155
|
+
bg: this.theme.codeBgColor,
|
|
3156
|
+
hoverBg: this.theme.tableHeaderBgColor,
|
|
3157
|
+
color: this.theme.textColor,
|
|
3158
|
+
focusColor: this.theme.codeColor
|
|
3159
|
+
};
|
|
3160
|
+
}
|
|
2547
3161
|
paragraphImage(imgToken, availableWidth) {
|
|
2548
3162
|
const initialWidth = Math.min(800, availableWidth);
|
|
2549
3163
|
const initialHeight = Math.round(initialWidth * 0.6);
|
|
@@ -2551,7 +3165,7 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
2551
3165
|
width: initialWidth,
|
|
2552
3166
|
height: initialHeight,
|
|
2553
3167
|
alt: imgToken.text,
|
|
2554
|
-
radius:
|
|
3168
|
+
radius: this.theme.imageRadius,
|
|
2555
3169
|
onLoad: () => {
|
|
2556
3170
|
const bmp = img.bitmap;
|
|
2557
3171
|
if (bmp && bmp.naturalWidth && bmp.naturalHeight) {
|
|
@@ -2566,11 +3180,11 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
2566
3180
|
}
|
|
2567
3181
|
/** One table cell entity, shared by the render arm and the streamed-table path. */
|
|
2568
3182
|
tableCellRichText(cell, header, t) {
|
|
2569
|
-
return new
|
|
2570
|
-
font: `${t.
|
|
3183
|
+
return new RichText2(this.tableCellSpans(cell, t), {
|
|
3184
|
+
font: `${t.tableFontSize}px ${t.bodyFont}`,
|
|
2571
3185
|
color: header ? t.headingColor : t.textColor,
|
|
2572
3186
|
baseStyle: header ? { bold: true } : void 0,
|
|
2573
|
-
linkColor:
|
|
3187
|
+
linkColor: t.linkColor,
|
|
2574
3188
|
selectable: this.selectable,
|
|
2575
3189
|
onLinkClick: this.onLinkClick
|
|
2576
3190
|
});
|
|
@@ -2624,6 +3238,7 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
2624
3238
|
itemIsInlineOnly(item) {
|
|
2625
3239
|
const children = item.tokens;
|
|
2626
3240
|
if (!children || children.length === 0) return true;
|
|
3241
|
+
if (containsImage(children)) return false;
|
|
2627
3242
|
if (children.length === 1 && children[0].type === "paragraph") return true;
|
|
2628
3243
|
return children.every((child) => _Markdown.INLINE_ITEM_TOKENS.has(child.type));
|
|
2629
3244
|
}
|
|
@@ -2651,9 +3266,12 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
2651
3266
|
listItemBlockStack(token, index, availableWidth, t) {
|
|
2652
3267
|
const item = token.items[index];
|
|
2653
3268
|
const children = item.tokens ?? [];
|
|
2654
|
-
const stack = new Stack({ direction: "vertical", gap:
|
|
3269
|
+
const stack = new Stack({ direction: "vertical", gap: t.listItemGap });
|
|
2655
3270
|
const first = children[0];
|
|
2656
|
-
const
|
|
3271
|
+
const firstIsInline = Boolean(first) && (first.type === "text" || first.type === "paragraph");
|
|
3272
|
+
const leadHasImage = firstIsInline && containsImage(first.tokens);
|
|
3273
|
+
const leadChildren = firstIsInline ? [leadHasImage ? stripImages(first) : first] : [];
|
|
3274
|
+
const leadImages = leadHasImage ? imagesOf(first.tokens) : [];
|
|
2657
3275
|
const leadToken = {
|
|
2658
3276
|
...token,
|
|
2659
3277
|
items: token.items.map((it, i) => i === index ? { ...it, tokens: leadChildren } : it)
|
|
@@ -2666,6 +3284,13 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
2666
3284
|
indentStart: indent,
|
|
2667
3285
|
availableWidth: Math.max(1, availableWidth - indent)
|
|
2668
3286
|
};
|
|
3287
|
+
for (const image of leadImages) {
|
|
3288
|
+
const el = this.paragraphImage(image, childMetrics.availableWidth);
|
|
3289
|
+
const wrapper = new MarkdownContainer();
|
|
3290
|
+
el.x = indent;
|
|
3291
|
+
wrapper.add(el);
|
|
3292
|
+
stack.add(wrapper);
|
|
3293
|
+
}
|
|
2669
3294
|
for (let i = leadChildren.length; i < children.length; i++) {
|
|
2670
3295
|
const el = this.renderTokenWithMetrics(children[i], childMetrics);
|
|
2671
3296
|
if (!el) continue;
|
|
@@ -2713,11 +3338,11 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
2713
3338
|
}
|
|
2714
3339
|
/** Construct the `RichText` for one list item. */
|
|
2715
3340
|
listItemRichText(token, index, availableWidth, t) {
|
|
2716
|
-
return new
|
|
3341
|
+
return new RichText2(this.listItemSpans(token, index), {
|
|
2717
3342
|
font: `${t.fontSize}px ${t.bodyFont}`,
|
|
2718
3343
|
color: t.textColor,
|
|
2719
3344
|
maxWidth: availableWidth,
|
|
2720
|
-
linkColor:
|
|
3345
|
+
linkColor: t.linkColor,
|
|
2721
3346
|
selectable: this.selectable,
|
|
2722
3347
|
onLinkClick: this.onLinkClick
|
|
2723
3348
|
});
|
|
@@ -2841,7 +3466,7 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
2841
3466
|
entity.add(this.inlineRunRichText(newTail, availableWidth, t));
|
|
2842
3467
|
} else {
|
|
2843
3468
|
const tailEntity = entity.children[entity.children.length - 1];
|
|
2844
|
-
if (!(tailEntity instanceof
|
|
3469
|
+
if (!(tailEntity instanceof RichText2)) return false;
|
|
2845
3470
|
tailEntity.setSpans(this.inlineRunSpans(newTail, t));
|
|
2846
3471
|
}
|
|
2847
3472
|
const last = entity.children[entity.children.length - 1];
|
|
@@ -2894,7 +3519,7 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
2894
3519
|
if (lastRetained >= 0) {
|
|
2895
3520
|
for (let c = 0; c < oldToken.header.length; c++) {
|
|
2896
3521
|
const cell = entity.rows[lastRetained]?.[c];
|
|
2897
|
-
if (!(cell instanceof
|
|
3522
|
+
if (!(cell instanceof RichText2)) return false;
|
|
2898
3523
|
}
|
|
2899
3524
|
}
|
|
2900
3525
|
const t = this.theme;
|
|
@@ -3067,12 +3692,12 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
3067
3692
|
* queued while the first is outstanding.
|
|
3068
3693
|
*/
|
|
3069
3694
|
ensureMathJax() {
|
|
3070
|
-
if (
|
|
3695
|
+
if (isMathJaxReady() || this.mathLoadPending || this.isDestroyed) return;
|
|
3071
3696
|
this.mathLoadPending = true;
|
|
3072
3697
|
void preloadMathJax().then(() => {
|
|
3073
3698
|
this.mathLoadPending = false;
|
|
3074
3699
|
if (this.isDestroyed) return;
|
|
3075
|
-
if (
|
|
3700
|
+
if (isMathJaxReady()) this.retypesetFromTokens();
|
|
3076
3701
|
this.flushAppendSettledWaiters();
|
|
3077
3702
|
});
|
|
3078
3703
|
}
|
|
@@ -3392,10 +4017,10 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
3392
4017
|
const width = intrinsicW * scale;
|
|
3393
4018
|
const height = intrinsicH * scale;
|
|
3394
4019
|
const uri = mathData.uri;
|
|
3395
|
-
const math = new
|
|
4020
|
+
const math = new RichText2(
|
|
3396
4021
|
[
|
|
3397
4022
|
{
|
|
3398
|
-
text:
|
|
4023
|
+
text: OBJECT_REPLACEMENT2,
|
|
3399
4024
|
object: {
|
|
3400
4025
|
width,
|
|
3401
4026
|
height,
|
|
@@ -3435,15 +4060,15 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
3435
4060
|
};
|
|
3436
4061
|
const availableWidth = metrics.availableWidth;
|
|
3437
4062
|
if (containsInlineMath(token)) {
|
|
3438
|
-
if (!
|
|
4063
|
+
if (!isMathJaxReady()) this.ensureMathJax();
|
|
3439
4064
|
this.subscribeInlineMathRepaint();
|
|
3440
4065
|
}
|
|
4066
|
+
if (containsImage([token])) this.subscribeInlineImageRemeasure();
|
|
3441
4067
|
switch (token.type) {
|
|
3442
4068
|
// ── Headings ─────────────────────────────────────────────────────
|
|
3443
4069
|
case "heading": {
|
|
3444
4070
|
const hToken = token;
|
|
3445
|
-
const
|
|
3446
|
-
const size = sizes[Math.min(hToken.depth - 1, 5)];
|
|
4071
|
+
const size = headingSize(t, hToken.depth);
|
|
3447
4072
|
const headingFont = `bold ${size}px ${t.bodyFont}`;
|
|
3448
4073
|
return renderInlineToRichText(
|
|
3449
4074
|
hToken.tokens,
|
|
@@ -3473,7 +4098,7 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
3473
4098
|
}
|
|
3474
4099
|
const stack = new Stack({
|
|
3475
4100
|
direction: "vertical",
|
|
3476
|
-
gap:
|
|
4101
|
+
gap: this.theme.blockGap,
|
|
3477
4102
|
maxWidth: availableWidth
|
|
3478
4103
|
});
|
|
3479
4104
|
let currentTokens = [];
|
|
@@ -3483,7 +4108,7 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
3483
4108
|
currentTokens = [];
|
|
3484
4109
|
}
|
|
3485
4110
|
};
|
|
3486
|
-
for (const child of pToken.tokens) {
|
|
4111
|
+
for (const child of liftNestedImages(pToken.tokens)) {
|
|
3487
4112
|
if (child.type === "image") {
|
|
3488
4113
|
flushText();
|
|
3489
4114
|
stack.add(this.paragraphImage(child, availableWidth));
|
|
@@ -3511,33 +4136,51 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
3511
4136
|
const mathBlock = this.renderDisplayMath(codeToken.text, availableWidth);
|
|
3512
4137
|
if (mathBlock) return mathBlock;
|
|
3513
4138
|
}
|
|
3514
|
-
return
|
|
4139
|
+
return this.withBlockAffordances(
|
|
4140
|
+
new CodeBlock(codeToken.text, lang, availableWidth, t, this.selectable),
|
|
4141
|
+
() => this.codeBlockAffordances(codeToken.text, lang)
|
|
4142
|
+
);
|
|
3515
4143
|
}
|
|
3516
4144
|
// ── Blockquotes ──────────────────────────────────────────────────
|
|
3517
4145
|
case "blockquote": {
|
|
3518
4146
|
const bqToken = token;
|
|
3519
|
-
const innerStack = new Stack({
|
|
3520
|
-
|
|
4147
|
+
const innerStack = new Stack({
|
|
4148
|
+
direction: "vertical",
|
|
4149
|
+
gap: this.theme.quoteInnerGap
|
|
4150
|
+
});
|
|
4151
|
+
const indentStart = Math.min(this.theme.quoteIndent, availableWidth);
|
|
3521
4152
|
const childMetrics = {
|
|
3522
4153
|
marginBefore: 0,
|
|
3523
4154
|
marginAfter: 0,
|
|
3524
4155
|
indentStart,
|
|
3525
4156
|
availableWidth: Math.max(0, availableWidth - indentStart)
|
|
3526
4157
|
};
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
4158
|
+
const outerTheme = this.theme;
|
|
4159
|
+
if (t.quoteTextColor !== t.textColor) {
|
|
4160
|
+
this.theme = { ...outerTheme, textColor: t.quoteTextColor };
|
|
4161
|
+
}
|
|
4162
|
+
try {
|
|
4163
|
+
if (bqToken.tokens) {
|
|
4164
|
+
for (const inner of bqToken.tokens) {
|
|
4165
|
+
const el = this.renderTokenWithMetrics(inner, childMetrics);
|
|
4166
|
+
if (el) {
|
|
4167
|
+
const wrapper = new MarkdownContainer();
|
|
4168
|
+
el.x = childMetrics.indentStart;
|
|
4169
|
+
wrapper.add(el);
|
|
4170
|
+
wrapper.width = el.width + childMetrics.indentStart;
|
|
4171
|
+
wrapper.height = el.height;
|
|
4172
|
+
innerStack.add(wrapper);
|
|
4173
|
+
}
|
|
3537
4174
|
}
|
|
3538
4175
|
}
|
|
4176
|
+
} finally {
|
|
4177
|
+
this.theme = outerTheme;
|
|
3539
4178
|
}
|
|
3540
|
-
const border = new QuoteBorder(
|
|
4179
|
+
const border = new QuoteBorder(
|
|
4180
|
+
innerStack.height || 20,
|
|
4181
|
+
t.quoteBorderColor,
|
|
4182
|
+
t.quoteBorderWidth
|
|
4183
|
+
);
|
|
3541
4184
|
const container = new MarkdownContainer();
|
|
3542
4185
|
border.x = 0;
|
|
3543
4186
|
border.y = 0;
|
|
@@ -3552,7 +4195,10 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
3552
4195
|
// ── Lists ────────────────────────────────────────────────
|
|
3553
4196
|
case "list": {
|
|
3554
4197
|
const listToken = token;
|
|
3555
|
-
const listStack = new Stack({
|
|
4198
|
+
const listStack = new Stack({
|
|
4199
|
+
direction: "vertical",
|
|
4200
|
+
gap: this.theme.listGap
|
|
4201
|
+
});
|
|
3556
4202
|
for (let i = 0; i < listToken.items.length; i++) {
|
|
3557
4203
|
listStack.add(
|
|
3558
4204
|
this.itemIsInlineOnly(listToken.items[i]) ? this.listItemRichText(listToken, i, availableWidth, t) : this.listItemBlockStack(listToken, i, availableWidth, t)
|
|
@@ -3567,21 +4213,24 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
3567
4213
|
const rows = tblToken.rows.map(
|
|
3568
4214
|
(row) => row.map((cell) => this.tableCellRichText(cell, false, t))
|
|
3569
4215
|
);
|
|
3570
|
-
return
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
4216
|
+
return this.withBlockAffordances(
|
|
4217
|
+
new Table({
|
|
4218
|
+
headers,
|
|
4219
|
+
rows,
|
|
4220
|
+
// `| :--- | :---: | ---: |` already resolves to this on the token; it
|
|
4221
|
+
// was previously discarded, so every column rendered left-aligned.
|
|
4222
|
+
align: tblToken.align,
|
|
4223
|
+
width: availableWidth,
|
|
4224
|
+
textColor: t.textColor,
|
|
4225
|
+
headerTextColor: t.headingColor,
|
|
4226
|
+
font: `${t.tableFontSize}px ${t.bodyFont}`,
|
|
4227
|
+
borderColor: t.hrColor,
|
|
4228
|
+
bg: t.tableBgColor,
|
|
4229
|
+
headerBg: t.tableHeaderBgColor,
|
|
4230
|
+
selectable: this.selectable
|
|
4231
|
+
}),
|
|
4232
|
+
() => this.tableAffordances(tblToken)
|
|
4233
|
+
);
|
|
3585
4234
|
}
|
|
3586
4235
|
// ── Horizontal rule ──────────────────────────────────────────────
|
|
3587
4236
|
case "hr":
|
|
@@ -3604,7 +4253,7 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
3604
4253
|
font: bodyFont,
|
|
3605
4254
|
color: t.textColor,
|
|
3606
4255
|
maxWidth: availableWidth,
|
|
3607
|
-
lineHeight:
|
|
4256
|
+
lineHeight: t.bodyLineHeight,
|
|
3608
4257
|
selectable: this.selectable
|
|
3609
4258
|
});
|
|
3610
4259
|
}
|
|
@@ -3616,13 +4265,22 @@ var Markdown = class _Markdown extends UIComponent {
|
|
|
3616
4265
|
}
|
|
3617
4266
|
};
|
|
3618
4267
|
export {
|
|
4268
|
+
BlockAffordanceButton,
|
|
4269
|
+
BlockWithAffordances,
|
|
3619
4270
|
CodeBlock,
|
|
3620
4271
|
Markdown,
|
|
3621
4272
|
MathBlock,
|
|
3622
4273
|
codeAtlas,
|
|
3623
4274
|
codeAtlasStats,
|
|
4275
|
+
escapeCsvField,
|
|
4276
|
+
escapeMarkdownTableCell,
|
|
4277
|
+
extensionForLanguage,
|
|
3624
4278
|
isMathJaxReady,
|
|
4279
|
+
mimeForLanguage,
|
|
3625
4280
|
parseFrontMatterFields,
|
|
3626
4281
|
preloadMathJax,
|
|
3627
|
-
scanFrontMatter
|
|
4282
|
+
scanFrontMatter,
|
|
4283
|
+
tableContentOf,
|
|
4284
|
+
tableToCsv,
|
|
4285
|
+
tableToMarkdown
|
|
3628
4286
|
};
|