vendor: 21,583 bytes, lines 1-640
1import { p as prismExports } from './prism-python-NrKIQnfs.js'; 2 3/** 4 * marked v12.0.2 - a markdown parser 5 * Copyright (c) 2011-2024, Christopher Jeffrey. (MIT Licensed) 6 * https://github.com/markedjs/marked 7 */ 8 9/** 10 * DO NOT EDIT THIS FILE 11 * The code in this file is generated from files in ./src/ 12 */ 13 14/** 15 * Gets the original marked default options. 16 */ 17function _getDefaults() { 18 return { 19 async: false, 20 breaks: false, 21 extensions: null, 22 gfm: true, 23 hooks: null, 24 pedantic: false, 25 renderer: null, 26 silent: false, 27 tokenizer: null, 28 walkTokens: null 29 }; 30} 31let _defaults = _getDefaults(); 32function changeDefaults(newDefaults) { 33 _defaults = newDefaults; 34} 35 36/** 37 * Helpers 38 */ 39const escapeTest$1 = /[&<>"']/; 40const escapeReplace$1 = new RegExp(escapeTest$1.source, 'g'); 41const escapeTestNoEncode$1 = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/; 42const escapeReplaceNoEncode$1 = new RegExp(escapeTestNoEncode$1.source, 'g'); 43const escapeReplacements$1 = { 44 '&': '&', 45 '<': '<', 46 '>': '>', 47 '"': '"', 48 "'": ''' 49}; 50const getEscapeReplacement$1 = (ch) => escapeReplacements$1[ch]; 51function escape$1$1(html, encode) { 52 if (encode) { 53 if (escapeTest$1.test(html)) { 54 return html.replace(escapeReplace$1, getEscapeReplacement$1); 55 } 56 } 57 else { 58 if (escapeTestNoEncode$1.test(html)) { 59 return html.replace(escapeReplaceNoEncode$1, getEscapeReplacement$1); 60 } 61 } 62 return html; 63} 64const unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig; 65function unescape(html) { 66 // explicitly match decimal, hex, and named HTML entities 67 return html.replace(unescapeTest, (_, n) => { 68 n = n.toLowerCase(); 69 if (n === 'colon') 70 return ':'; 71 if (n.charAt(0) === '#') { 72 return n.charAt(1) === 'x' 73 ? String.fromCharCode(parseInt(n.substring(2), 16)) 74 : String.fromCharCode(+n.substring(1)); 75 } 76 return ''; 77 }); 78} 79const caret = /(^|[^\[])\^/g; 80function edit(regex, opt) { 81 let source = typeof regex === 'string' ? regex : regex.source; 82 opt = opt || ''; 83 const obj = { 84 replace: (name, val) => { 85 let valSource = typeof val === 'string' ? val : val.source; 86 valSource = valSource.replace(caret, '$1'); 87 source = source.replace(name, valSource); 88 return obj; 89 }, 90 getRegex: () => { 91 return new RegExp(source, opt); 92 } 93 }; 94 return obj; 95} 96function cleanUrl(href) { 97 try { 98 href = encodeURI(href).replace(/%25/g, '%'); 99 } 100 catch (e) { 101 return null; 102 } 103 return href; 104} 105const noopTest = { exec: () => null }; 106function splitCells(tableRow, count) { 107 // ensure that every cell-delimiting pipe has a space 108 // before it to distinguish it from an escaped pipe 109 const row = tableRow.replace(/\|/g, (match, offset, str) => { 110 let escaped = false; 111 let curr = offset; 112 while (--curr >= 0 && str[curr] === '\\') 113 escaped = !escaped; 114 if (escaped) { 115 // odd number of slashes means | is escaped 116 // so we leave it alone 117 return '|'; 118 } 119 else { 120 // add space before unescaped | 121 return ' |'; 122 } 123 }), cells = row.split(/ \|/); 124 let i = 0; 125 // First/last cell in a row cannot be empty if it has no leading/trailing pipe 126 if (!cells[0].trim()) { 127 cells.shift(); 128 } 129 if (cells.length > 0 && !cells[cells.length - 1].trim()) { 130 cells.pop(); 131 } 132 if (count) { 133 if (cells.length > count) { 134 cells.splice(count); 135 } 136 else { 137 while (cells.length < count) 138 cells.push(''); 139 } 140 } 141 for (; i < cells.length; i++) { 142 // leading or trailing whitespace is ignored per the gfm spec 143 cells[i] = cells[i].trim().replace(/\\\|/g, '|'); 144 } 145 return cells; 146} 147/** 148 * Remove trailing 'c's. Equivalent to str.replace(/c*$/, ''). 149 * /c*$/ is vulnerable to REDOS. 150 * 151 * @param str 152 * @param c 153 * @param invert Remove suffix of non-c chars instead. Default falsey. 154 */ 155function rtrim(str, c, invert) { 156 const l = str.length; 157 if (l === 0) { 158 return ''; 159 } 160 // Length of suffix matching the invert condition. 161 let suffLen = 0; 162 // Step left until we fail to match the invert condition. 163 while (suffLen < l) { 164 const currChar = str.charAt(l - suffLen - 1); 165 if (currChar === c && true) { 166 suffLen++; 167 } 168 else { 169 break; 170 } 171 } 172 return str.slice(0, l - suffLen); 173} 174function findClosingBracket(str, b) { 175 if (str.indexOf(b[1]) === -1) { 176 return -1; 177 } 178 let level = 0; 179 for (let i = 0; i < str.length; i++) { 180 if (str[i] === '\\') { 181 i++; 182 } 183 else if (str[i] === b[0]) { 184 level++; 185 } 186 else if (str[i] === b[1]) { 187 level--; 188 if (level < 0) { 189 return i; 190 } 191 } 192 } 193 return -1; 194} 195 196function outputLink(cap, link, raw, lexer) { 197 const href = link.href; 198 const title = link.title ? escape$1$1(link.title) : null; 199 const text = cap[1].replace(/\\([\[\]])/g, '$1'); 200 if (cap[0].charAt(0) !== '!') { 201 lexer.state.inLink = true; 202 const token = { 203 type: 'link', 204 raw, 205 href, 206 title, 207 text, 208 tokens: lexer.inlineTokens(text) 209 }; 210 lexer.state.inLink = false; 211 return token; 212 } 213 return { 214 type: 'image', 215 raw, 216 href, 217 title, 218 text: escape$1$1(text) 219 }; 220} 221function indentCodeCompensation(raw, text) { 222 const matchIndentToCode = raw.match(/^(\s+)(?:```)/); 223 if (matchIndentToCode === null) { 224 return text; 225 } 226 const indentToCode = matchIndentToCode[1]; 227 return text 228 .split('\n') 229 .map(node => { 230 const matchIndentInNode = node.match(/^\s+/); 231 if (matchIndentInNode === null) { 232 return node; 233 } 234 const [indentInNode] = matchIndentInNode; 235 if (indentInNode.length >= indentToCode.length) { 236 return node.slice(indentToCode.length); 237 } 238 return node; 239 }) 240 .join('\n'); 241} 242/** 243 * Tokenizer 244 */ 245class _Tokenizer { 246 options; 247 rules; // set by the lexer 248 lexer; // set by the lexer 249 constructor(options) { 250 this.options = options || _defaults; 251 } 252 space(src) { 253 const cap = this.rules.block.newline.exec(src); 254 if (cap && cap[0].length > 0) { 255 return { 256 type: 'space', 257 raw: cap[0] 258 }; 259 } 260 } 261 code(src) { 262 const cap = this.rules.block.code.exec(src); 263 if (cap) { 264 const text = cap[0].replace(/^ {1,4}/gm, ''); 265 return { 266 type: 'code', 267 raw: cap[0], 268 codeBlockStyle: 'indented', 269 text: !this.options.pedantic 270 ? rtrim(text, '\n') 271 : text 272 }; 273 } 274 } 275 fences(src) { 276 const cap = this.rules.block.fences.exec(src); 277 if (cap) { 278 const raw = cap[0]; 279 const text = indentCodeCompensation(raw, cap[3] || ''); 280 return { 281 type: 'code', 282 raw, 283 lang: cap[2] ? cap[2].trim().replace(this.rules.inline.anyPunctuation, '$1') : cap[2], 284 text 285 }; 286 } 287 } 288 heading(src) { 289 const cap = this.rules.block.heading.exec(src); 290 if (cap) { 291 let text = cap[2].trim(); 292 // remove trailing #s 293 if (/#$/.test(text)) { 294 const trimmed = rtrim(text, '#'); 295 if (this.options.pedantic) { 296 text = trimmed.trim(); 297 } 298 else if (!trimmed || / $/.test(trimmed)) { 299 // CommonMark requires space before trailing #s 300 text = trimmed.trim(); 301 } 302 } 303 return { 304 type: 'heading', 305 raw: cap[0], 306 depth: cap[1].length, 307 text, 308 tokens: this.lexer.inline(text) 309 }; 310 } 311 } 312 hr(src) { 313 const cap = this.rules.block.hr.exec(src); 314 if (cap) { 315 return { 316 type: 'hr', 317 raw: cap[0] 318 }; 319 } 320 } 321 blockquote(src) { 322 const cap = this.rules.block.blockquote.exec(src); 323 if (cap) { 324 // precede setext continuation with 4 spaces so it isn't a setext 325 let text = cap[0].replace(/\n {0,3}((?:=+|-+) *)(?=\n|$)/g, '\n $1'); 326 text = rtrim(text.replace(/^ *>[ \t]?/gm, ''), '\n'); 327 const top = this.lexer.state.top; 328 this.lexer.state.top = true; 329 const tokens = this.lexer.blockTokens(text); 330 this.lexer.state.top = top; 331 return { 332 type: 'blockquote', 333 raw: cap[0], 334 tokens, 335 text 336 }; 337 } 338 } 339 list(src) { 340 let cap = this.rules.block.list.exec(src); 341 if (cap) { 342 let bull = cap[1].trim(); 343 const isordered = bull.length > 1; 344 const list = { 345 type: 'list', 346 raw: '', 347 ordered: isordered, 348 start: isordered ? +bull.slice(0, -1) : '', 349 loose: false, 350 items: [] 351 }; 352 bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`; 353 if (this.options.pedantic) { 354 bull = isordered ? bull : '[*+-]'; 355 } 356 // Get next list item 357 const itemRegex = new RegExp(`^( {0,3}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))`); 358 let raw = ''; 359 let itemContents = ''; 360 let endsWithBlankLine = false; 361 // Check if current bullet point can start a new List Item 362 while (src) { 363 let endEarly = false; 364 if (!(cap = itemRegex.exec(src))) { 365 break; 366 } 367 if (this.rules.block.hr.test(src)) { // End list if bullet was actually HR (possibly move into itemRegex?) 368 break; 369 } 370 raw = cap[0]; 371 src = src.substring(raw.length); 372 let line = cap[2].split('\n', 1)[0].replace(/^\t+/, (t) => ' '.repeat(3 * t.length)); 373 let nextLine = src.split('\n', 1)[0]; 374 let indent = 0; 375 if (this.options.pedantic) { 376 indent = 2; 377 itemContents = line.trimStart(); 378 } 379 else { 380 indent = cap[2].search(/[^ ]/); // Find first non-space char 381 indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent 382 itemContents = line.slice(indent); 383 indent += cap[1].length; 384 } 385 let blankLine = false; 386 if (!line && /^ *$/.test(nextLine)) { // Items begin with at most one blank line 387 raw += nextLine + '\n'; 388 src = src.substring(nextLine.length + 1); 389 endEarly = true; 390 } 391 if (!endEarly) { 392 const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`); 393 const hrRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`); 394 const fencesBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\`\`\`|~~~)`); 395 const headingBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`); 396 // Check if following lines should be included in List Item 397 while (src) { 398 const rawLine = src.split('\n', 1)[0]; 399 nextLine = rawLine; 400 // Re-align to follow commonmark nesting rules 401 if (this.options.pedantic) { 402 nextLine = nextLine.replace(/^ {1,4}(?=( {4})*[^ ])/g, ' '); 403 } 404 // End list item if found code fences 405 if (fencesBeginRegex.test(nextLine)) { 406 break; 407 } 408 // End list item if found start of new heading 409 if (headingBeginRegex.test(nextLine)) { 410 break; 411 } 412 // End list item if found start of new bullet 413 if (nextBulletRegex.test(nextLine)) { 414 break; 415 } 416 // Horizontal rule found 417 if (hrRegex.test(src)) { 418 break; 419 } 420 if (nextLine.search(/[^ ]/) >= indent || !nextLine.trim()) { // Dedent if possible 421 itemContents += '\n' + nextLine.slice(indent); 422 } 423 else { 424 // not enough indentation 425 if (blankLine) { 426 break; 427 } 428 // paragraph continuation unless last line was a different block level element 429 if (line.search(/[^ ]/) >= 4) { // indented code block 430 break; 431 } 432 if (fencesBeginRegex.test(line)) { 433 break; 434 } 435 if (headingBeginRegex.test(line)) { 436 break; 437 } 438 if (hrRegex.test(line)) { 439 break; 440 } 441 itemContents += '\n' + nextLine; 442 } 443 if (!blankLine && !nextLine.trim()) { // Check if current line is blank 444 blankLine = true; 445 } 446 raw += rawLine + '\n'; 447 src = src.substring(rawLine.length + 1); 448 line = nextLine.slice(indent); 449 } 450 } 451 if (!list.loose) { 452 // If the previous item ended with a blank line, the list is loose 453 if (endsWithBlankLine) { 454 list.loose = true; 455 } 456 else if (/\n *\n *$/.test(raw)) { 457 endsWithBlankLine = true; 458 } 459 } 460 let istask = null; 461 let ischecked; 462 // Check for task list items 463 if (this.options.gfm) { 464 istask = /^\[[ xX]\] /.exec(itemContents); 465 if (istask) { 466 ischecked = istask[0] !== '[ ] '; 467 itemContents = itemContents.replace(/^\[[ xX]\] +/, ''); 468 } 469 } 470 list.items.push({ 471 type: 'list_item', 472 raw, 473 task: !!istask, 474 checked: ischecked, 475 loose: false, 476 text: itemContents, 477 tokens: [] 478 }); 479 list.raw += raw; 480 } 481 // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic 482 list.items[list.items.length - 1].raw = raw.trimEnd(); 483 (list.items[list.items.length - 1]).text = itemContents.trimEnd(); 484 list.raw = list.raw.trimEnd(); 485 // Item child tokens handled here at end because we needed to have the final item to trim it first 486 for (let i = 0; i < list.items.length; i++) { 487 this.lexer.state.top = false; 488 list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []); 489 if (!list.loose) { 490 // Check if list should be loose 491 const spacers = list.items[i].tokens.filter(t => t.type === 'space'); 492 const hasMultipleLineBreaks = spacers.length > 0 && spacers.some(t => /\n.*\n/.test(t.raw)); 493 list.loose = hasMultipleLineBreaks; 494 } 495 } 496 // Set all items to loose if list is loose 497 if (list.loose) { 498 for (let i = 0; i < list.items.length; i++) { 499 list.items[i].loose = true; 500 } 501 } 502 return list; 503 } 504 } 505 html(src) { 506 const cap = this.rules.block.html.exec(src); 507 if (cap) { 508 const token = { 509 type: 'html', 510 block: true, 511 raw: cap[0], 512 pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style', 513 text: cap[0] 514 }; 515 return token; 516 } 517 } 518 def(src) { 519 const cap = this.rules.block.def.exec(src); 520 if (cap) { 521 const tag = cap[1].toLowerCase().replace(/\s+/g, ' '); 522 const href = cap[2] ? cap[2].replace(/^<(.*)>$/, '$1').replace(this.rules.inline.anyPunctuation, '$1') : ''; 523 const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline.anyPunctuation, '$1') : cap[3]; 524 return { 525 type: 'def', 526 tag, 527 raw: cap[0], 528 href, 529 title 530 }; 531 } 532 } 533 table(src) { 534 const cap = this.rules.block.table.exec(src); 535 if (!cap) { 536 return; 537 } 538 if (!/[:|]/.test(cap[2])) { 539 // delimiter row must have a pipe (|) or colon (:) otherwise it is a setext heading 540 return; 541 } 542 const headers = splitCells(cap[1]); 543 const aligns = cap[2].replace(/^\||\| *$/g, '').split('|'); 544 const rows = cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : []; 545 const item = { 546 type: 'table', 547 raw: cap[0], 548 header: [], 549 align: [], 550 rows: [] 551 }; 552 if (headers.length !== aligns.length) { 553 // header and align columns must be equal, rows can be different. 554 return; 555 } 556 for (const align of aligns) { 557 if (/^ *-+: *$/.test(align)) { 558 item.align.push('right'); 559 } 560 else if (/^ *:-+: *$/.test(align)) { 561 item.align.push('center'); 562 } 563 else if (/^ *:-+ *$/.test(align)) { 564 item.align.push('left'); 565 } 566 else { 567 item.align.push(null); 568 } 569 } 570 for (const header of headers) { 571 item.header.push({ 572 text: header, 573 tokens: this.lexer.inline(header) 574 }); 575 } 576 for (const row of rows) { 577 item.rows.push(splitCells(row, item.header.length).map(cell => { 578 return { 579 text: cell, 580 tokens: this.lexer.inline(cell) 581 }; 582 })); 583 } 584 return item; 585 } 586 lheading(src) { 587 const cap = this.rules.block.lheading.exec(src); 588 if (cap) { 589 return { 590 type: 'heading', 591 raw: cap[0], 592 depth: cap[2].charAt(0) === '=' ? 1 : 2, 593 text: cap[1], 594 tokens: this.lexer.inline(cap[1]) 595 }; 596 } 597 } 598 paragraph(src) { 599 const cap = this.rules.block.paragraph.exec(src); 600 if (cap) { 601 const text = cap[1].charAt(cap[1].length - 1) === '\n' 602 ? cap[1].slice(0, -1) 603 : cap[1]; 604 return { 605 type: 'paragraph', 606 raw: cap[0], 607 text, 608 tokens: this.lexer.inline(text) 609 }; 610 } 611 } 612 text(src) { 613 const cap = this.rules.block.text.exec(src); 614 if (cap) { 615 return { 616 type: 'text', 617 raw: cap[0], 618 text: cap[0], 619 tokens: this.lexer.inline(cap[0]) 620 }; 621 } 622 } 623 escape(src) { 624 const cap = this.rules.inline.escape.exec(src); 625 if (cap) { 626 return { 627 type: 'escape', 628 raw: cap[0], 629 text: escape$1$1(cap[1]) 630 }; 631 } 632 } 633 tag(src) { 634 const cap = this.rules.inline.tag.exec(src); 635 if (cap) { 636 if (!this.lexer.state.inLink && /^<a /i.test(cap[0])) { 637 this.lexer.state.inLink = true; 638 } 639 else if (this.lexer.state.inLink && /^<\/a>/i.test(cap[0])) { 640 this.lexer.state.inLink = false;
vendor: 4,340 bytes, lines 641-743
641 } 642 if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { 643 this.lexer.state.inRawBlock = true; 644 } 645 else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { 646 this.lexer.state.inRawBlock = false; 647 } 648 return { 649 type: 'html', 650 raw: cap[0], 651 inLink: this.lexer.state.inLink, 652 inRawBlock: this.lexer.state.inRawBlock, 653 block: false, 654 text: cap[0] 655 }; 656 } 657 } 658 link(src) { 659 const cap = this.rules.inline.link.exec(src); 660 if (cap) { 661 const trimmedUrl = cap[2].trim(); 662 if (!this.options.pedantic && /^</.test(trimmedUrl)) { 663 // commonmark requires matching angle brackets 664 if (!(/>$/.test(trimmedUrl))) { 665 return; 666 } 667 // ending angle bracket cannot be escaped 668 const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\'); 669 if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) { 670 return; 671 } 672 } 673 else { 674 // find closing parenthesis 675 const lastParenIndex = findClosingBracket(cap[2], '()'); 676 if (lastParenIndex > -1) { 677 const start = cap[0].indexOf('!') === 0 ? 5 : 4; 678 const linkLen = start + cap[1].length + lastParenIndex; 679 cap[2] = cap[2].substring(0, lastParenIndex); 680 cap[0] = cap[0].substring(0, linkLen).trim(); 681 cap[3] = ''; 682 } 683 } 684 let href = cap[2]; 685 let title = ''; 686 if (this.options.pedantic) { 687 // split pedantic href and title 688 const link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href); 689 if (link) { 690 href = link[1]; 691 title = link[3]; 692 } 693 } 694 else { 695 title = cap[3] ? cap[3].slice(1, -1) : ''; 696 } 697 href = href.trim(); 698 if (/^</.test(href)) { 699 if (this.options.pedantic && !(/>$/.test(trimmedUrl))) { 700 // pedantic allows starting angle bracket without ending angle bracket 701 href = href.slice(1); 702 } 703 else { 704 href = href.slice(1, -1); 705 } 706 } 707 return outputLink(cap, { 708 href: href ? href.replace(this.rules.inline.anyPunctuation, '$1') : href, 709 title: title ? title.replace(this.rules.inline.anyPunctuation, '$1') : title 710 }, cap[0], this.lexer); 711 } 712 } 713 reflink(src, links) { 714 let cap; 715 if ((cap = this.rules.inline.reflink.exec(src)) 716 || (cap = this.rules.inline.nolink.exec(src))) { 717 const linkString = (cap[2] || cap[1]).replace(/\s+/g, ' '); 718 const link = links[linkString.toLowerCase()]; 719 if (!link) { 720 const text = cap[0].charAt(0); 721 return { 722 type: 'text', 723 raw: text, 724 text 725 }; 726 } 727 return outputLink(cap, link, cap[0], this.lexer); 728 } 729 } 730 emStrong(src, maskedSrc, prevChar = '') { 731 let match = this.rules.inline.emStrongLDelim.exec(src); 732 if (!match) 733 return; 734 // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well 735 if (match[3] && prevChar.match(/[\p{L}\p{N}]/u)) 736 return; 737 const nextChar = match[1] || match[2] || ''; 738 if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) { 739 // unicode Regex counts emoji as 1 char; spread into array for proper count (used multiple times below) 740 const lLength = [...match[0]].length - 1; 741 let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0; 742 const endReg = match[0][0] === '*' ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd; 743 endReg.lastIndex = 0;
vendor: 20,826 bytes, lines 744-1298
744 // Clip maskedSrc to same section of string as src (move to lexer?) 745 maskedSrc = maskedSrc.slice(-1 * src.length + lLength); 746 while ((match = endReg.exec(maskedSrc)) != null) { 747 rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6]; 748 if (!rDelim) 749 continue; // skip single * in __abc*abc__ 750 rLength = [...rDelim].length; 751 if (match[3] || match[4]) { // found another Left Delim 752 delimTotal += rLength; 753 continue; 754 } 755 else if (match[5] || match[6]) { // either Left or Right Delim 756 if (lLength % 3 && !((lLength + rLength) % 3)) { 757 midDelimTotal += rLength; 758 continue; // CommonMark Emphasis Rules 9-10 759 } 760 } 761 delimTotal -= rLength; 762 if (delimTotal > 0) 763 continue; // Haven't found enough closing delimiters 764 // Remove extra characters. *a*** -> *a* 765 rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal); 766 // char length can be >1 for unicode characters; 767 const lastCharLength = [...match[0]][0].length; 768 const raw = src.slice(0, lLength + match.index + lastCharLength + rLength); 769 // Create `em` if smallest delimiter has odd char count. *a*** 770 if (Math.min(lLength, rLength) % 2) { 771 const text = raw.slice(1, -1); 772 return { 773 type: 'em', 774 raw, 775 text, 776 tokens: this.lexer.inlineTokens(text) 777 }; 778 } 779 // Create 'strong' if smallest delimiter has even char count. **a*** 780 const text = raw.slice(2, -2); 781 return { 782 type: 'strong', 783 raw, 784 text, 785 tokens: this.lexer.inlineTokens(text) 786 }; 787 } 788 } 789 } 790 codespan(src) { 791 const cap = this.rules.inline.code.exec(src); 792 if (cap) { 793 let text = cap[2].replace(/\n/g, ' '); 794 const hasNonSpaceChars = /[^ ]/.test(text); 795 const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text); 796 if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) { 797 text = text.substring(1, text.length - 1); 798 } 799 text = escape$1$1(text, true); 800 return { 801 type: 'codespan', 802 raw: cap[0], 803 text 804 }; 805 } 806 } 807 br(src) { 808 const cap = this.rules.inline.br.exec(src); 809 if (cap) { 810 return { 811 type: 'br', 812 raw: cap[0] 813 }; 814 } 815 } 816 del(src) { 817 const cap = this.rules.inline.del.exec(src); 818 if (cap) { 819 return { 820 type: 'del', 821 raw: cap[0], 822 text: cap[2], 823 tokens: this.lexer.inlineTokens(cap[2]) 824 }; 825 } 826 } 827 autolink(src) { 828 const cap = this.rules.inline.autolink.exec(src); 829 if (cap) { 830 let text, href; 831 if (cap[2] === '@') { 832 text = escape$1$1(cap[1]); 833 href = 'mailto:' + text; 834 } 835 else { 836 text = escape$1$1(cap[1]); 837 href = text; 838 } 839 return { 840 type: 'link', 841 raw: cap[0], 842 text, 843 href, 844 tokens: [ 845 { 846 type: 'text', 847 raw: text, 848 text 849 } 850 ] 851 }; 852 } 853 } 854 url(src) { 855 let cap; 856 if (cap = this.rules.inline.url.exec(src)) { 857 let text, href; 858 if (cap[2] === '@') { 859 text = escape$1$1(cap[0]); 860 href = 'mailto:' + text; 861 } 862 else { 863 // do extended autolink path validation 864 let prevCapZero; 865 do { 866 prevCapZero = cap[0]; 867 cap[0] = this.rules.inline._backpedal.exec(cap[0])?.[0] ?? ''; 868 } while (prevCapZero !== cap[0]); 869 text = escape$1$1(cap[0]); 870 if (cap[1] === 'www.') { 871 href = 'http://' + cap[0]; 872 } 873 else { 874 href = cap[0]; 875 } 876 } 877 return { 878 type: 'link', 879 raw: cap[0], 880 text, 881 href, 882 tokens: [ 883 { 884 type: 'text', 885 raw: text, 886 text 887 } 888 ] 889 }; 890 } 891 } 892 inlineText(src) { 893 const cap = this.rules.inline.text.exec(src); 894 if (cap) { 895 let text; 896 if (this.lexer.state.inRawBlock) { 897 text = cap[0]; 898 } 899 else { 900 text = escape$1$1(cap[0]); 901 } 902 return { 903 type: 'text', 904 raw: cap[0], 905 text 906 }; 907 } 908 } 909} 910 911/** 912 * Block-Level Grammar 913 */ 914const newline = /^(?: *(?:\n|$))+/; 915const blockCode = /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/; 916const fences = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/; 917const hr = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/; 918const heading = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/; 919const bullet = /(?:[*+-]|\d{1,9}[.)])/; 920const lheading = edit(/^(?!bull |blockCode|fences|blockquote|heading|html)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html))+?)\n {0,3}(=+|-+) *(?:\n+|$)/) 921 .replace(/bull/g, bullet) // lists can interrupt 922 .replace(/blockCode/g, / {4}/) // indented code blocks can interrupt 923 .replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/) // fenced code blocks can interrupt 924 .replace(/blockquote/g, / {0,3}>/) // blockquote can interrupt 925 .replace(/heading/g, / {0,3}#{1,6}/) // ATX heading can interrupt 926 .replace(/html/g, / {0,3}<[^\n>]+>\n/) // block html can interrupt 927 .getRegex(); 928const _paragraph = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/; 929const blockText = /^[^\n]+/; 930const _blockLabel = /(?!\s*\])(?:\\.|[^\[\]\\])+/; 931const def = edit(/^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/) 932 .replace('label', _blockLabel) 933 .replace('title', /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/) 934 .getRegex(); 935const list = edit(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/) 936 .replace(/bull/g, bullet) 937 .getRegex(); 938const _tag = 'address|article|aside|base|basefont|blockquote|body|caption' 939 + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption' 940 + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe' 941 + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option' 942 + '|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title' 943 + '|tr|track|ul'; 944const _comment = /<!--(?:-?>|[\s\S]*?(?:-->|$))/; 945const html = edit('^ {0,3}(?:' // optional indentation 946 + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1) 947 + '|comment[^\\n]*(\\n+|$)' // (2) 948 + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3) 949 + '|<![A-Z][\\s\\S]*?(?:>\\n*|$)' // (4) 950 + '|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)' // (5) 951 + '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6) 952 + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag 953 + '|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag 954 + ')', 'i') 955 .replace('comment', _comment) 956 .replace('tag', _tag) 957 .replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/) 958 .getRegex(); 959const paragraph = edit(_paragraph) 960 .replace('hr', hr) 961 .replace('heading', ' {0,3}#{1,6}(?:\\s|$)') 962 .replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs 963 .replace('|table', '') 964 .replace('blockquote', ' {0,3}>') 965 .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n') 966 .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt 967 .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)') 968 .replace('tag', _tag) // pars can be interrupted by type (6) html blocks 969 .getRegex(); 970const blockquote = edit(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/) 971 .replace('paragraph', paragraph) 972 .getRegex(); 973/** 974 * Normal Block Grammar 975 */ 976const blockNormal = { 977 blockquote, 978 code: blockCode, 979 def, 980 fences, 981 heading, 982 hr, 983 html, 984 lheading, 985 list, 986 newline, 987 paragraph, 988 table: noopTest, 989 text: blockText 990}; 991/** 992 * GFM Block Grammar 993 */ 994const gfmTable = edit('^ *([^\\n ].*)\\n' // Header 995 + ' {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)' // Align 996 + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)') // Cells 997 .replace('hr', hr) 998 .replace('heading', ' {0,3}#{1,6}(?:\\s|$)') 999 .replace('blockquote', ' {0,3}>') 1000 .replace('code', ' {4}[^\\n]') 1001 .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n') 1002 .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt 1003 .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)') 1004 .replace('tag', _tag) // tables can be interrupted by type (6) html blocks 1005 .getRegex(); 1006const blockGfm = { 1007 ...blockNormal, 1008 table: gfmTable, 1009 paragraph: edit(_paragraph) 1010 .replace('hr', hr) 1011 .replace('heading', ' {0,3}#{1,6}(?:\\s|$)') 1012 .replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs 1013 .replace('table', gfmTable) // interrupt paragraphs with table 1014 .replace('blockquote', ' {0,3}>') 1015 .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n') 1016 .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt 1017 .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)') 1018 .replace('tag', _tag) // pars can be interrupted by type (6) html blocks 1019 .getRegex() 1020}; 1021/** 1022 * Pedantic grammar (original John Gruber's loose markdown specification) 1023 */ 1024const blockPedantic = { 1025 ...blockNormal, 1026 html: edit('^ *(?:comment *(?:\\n|\\s*$)' 1027 + '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag 1028 + '|<tag(?:"[^"]*"|\'[^\']*\'|\\s[^\'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))') 1029 .replace('comment', _comment) 1030 .replace(/tag/g, '(?!(?:' 1031 + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub' 1032 + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)' 1033 + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b') 1034 .getRegex(), 1035 def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, 1036 heading: /^(#{1,6})(.*)(?:\n+|$)/, 1037 fences: noopTest, // fences not supported 1038 lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, 1039 paragraph: edit(_paragraph) 1040 .replace('hr', hr) 1041 .replace('heading', ' *#{1,6} *[^\n]') 1042 .replace('lheading', lheading) 1043 .replace('|table', '') 1044 .replace('blockquote', ' {0,3}>') 1045 .replace('|fences', '') 1046 .replace('|list', '') 1047 .replace('|html', '') 1048 .replace('|tag', '') 1049 .getRegex() 1050}; 1051/** 1052 * Inline-Level Grammar 1053 */ 1054const escape$2 = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/; 1055const inlineCode = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/; 1056const br = /^( {2,}|\\)\n(?!\s*$)/; 1057const inlineText = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/; 1058// list of unicode punctuation marks, plus any missing characters from CommonMark spec 1059const _punctuation = '\\p{P}\\p{S}'; 1060const punctuation = edit(/^((?![*_])[\spunctuation])/, 'u') 1061 .replace(/punctuation/g, _punctuation).getRegex(); 1062// sequences em should skip over [title](link), `code`, <html> 1063const blockSkip = /\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g; 1064const emStrongLDelim = edit(/^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/, 'u') 1065 .replace(/punct/g, _punctuation) 1066 .getRegex(); 1067const emStrongRDelimAst = edit('^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)' // Skip orphan inside strong 1068 + '|[^*]+(?=[^*])' // Consume to delim 1069 + '|(?!\\*)[punct](\\*+)(?=[\\s]|$)' // (1) #*** can only be a Right Delimiter 1070 + '|[^punct\\s](\\*+)(?!\\*)(?=[punct\\s]|$)' // (2) a***#, a*** can only be a Right Delimiter 1071 + '|(?!\\*)[punct\\s](\\*+)(?=[^punct\\s])' // (3) #***a, ***a can only be Left Delimiter 1072 + '|[\\s](\\*+)(?!\\*)(?=[punct])' // (4) ***# can only be Left Delimiter 1073 + '|(?!\\*)[punct](\\*+)(?!\\*)(?=[punct])' // (5) #***# can be either Left or Right Delimiter 1074 + '|[^punct\\s](\\*+)(?=[^punct\\s])', 'gu') // (6) a***a can be either Left or Right Delimiter 1075 .replace(/punct/g, _punctuation) 1076 .getRegex(); 1077// (6) Not allowed for _ 1078const emStrongRDelimUnd = edit('^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)' // Skip orphan inside strong 1079 + '|[^_]+(?=[^_])' // Consume to delim 1080 + '|(?!_)[punct](_+)(?=[\\s]|$)' // (1) #___ can only be a Right Delimiter 1081 + '|[^punct\\s](_+)(?!_)(?=[punct\\s]|$)' // (2) a___#, a___ can only be a Right Delimiter 1082 + '|(?!_)[punct\\s](_+)(?=[^punct\\s])' // (3) #___a, ___a can only be Left Delimiter 1083 + '|[\\s](_+)(?!_)(?=[punct])' // (4) ___# can only be Left Delimiter 1084 + '|(?!_)[punct](_+)(?!_)(?=[punct])', 'gu') // (5) #___# can be either Left or Right Delimiter 1085 .replace(/punct/g, _punctuation) 1086 .getRegex(); 1087const anyPunctuation = edit(/\\([punct])/, 'gu') 1088 .replace(/punct/g, _punctuation) 1089 .getRegex(); 1090const autolink = edit(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/) 1091 .replace('scheme', /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/) 1092 .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])?)+(?![-_])/) 1093 .getRegex(); 1094const _inlineComment = edit(_comment).replace('(?:-->|$)', '-->').getRegex(); 1095const tag = edit('^comment' 1096 + '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag 1097 + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag 1098 + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?> 1099 + '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html> 1100 + '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>') // CDATA section 1101 .replace('comment', _inlineComment) 1102 .replace('attribute', /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/) 1103 .getRegex(); 1104const _inlineLabel = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/; 1105const link = edit(/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/) 1106 .replace('label', _inlineLabel) 1107 .replace('href', /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/) 1108 .replace('title', /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/) 1109 .getRegex(); 1110const reflink = edit(/^!?\[(label)\]\[(ref)\]/) 1111 .replace('label', _inlineLabel) 1112 .replace('ref', _blockLabel) 1113 .getRegex(); 1114const nolink = edit(/^!?\[(ref)\](?:\[\])?/) 1115 .replace('ref', _blockLabel) 1116 .getRegex(); 1117const reflinkSearch = edit('reflink|nolink(?!\\()', 'g') 1118 .replace('reflink', reflink) 1119 .replace('nolink', nolink) 1120 .getRegex(); 1121/** 1122 * Normal Inline Grammar 1123 */ 1124const inlineNormal = { 1125 _backpedal: noopTest, // only used for GFM url 1126 anyPunctuation, 1127 autolink, 1128 blockSkip, 1129 br, 1130 code: inlineCode, 1131 del: noopTest, 1132 emStrongLDelim, 1133 emStrongRDelimAst, 1134 emStrongRDelimUnd, 1135 escape: escape$2, 1136 link, 1137 nolink, 1138 punctuation, 1139 reflink, 1140 reflinkSearch, 1141 tag, 1142 text: inlineText, 1143 url: noopTest 1144}; 1145/** 1146 * Pedantic Inline Grammar 1147 */ 1148const inlinePedantic = { 1149 ...inlineNormal, 1150 link: edit(/^!?\[(label)\]\((.*?)\)/) 1151 .replace('label', _inlineLabel) 1152 .getRegex(), 1153 reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/) 1154 .replace('label', _inlineLabel) 1155 .getRegex() 1156}; 1157/** 1158 * GFM Inline Grammar 1159 */ 1160const inlineGfm = { 1161 ...inlineNormal, 1162 escape: edit(escape$2).replace('])', '~|])').getRegex(), 1163 url: edit(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, 'i') 1164 .replace('email', /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/) 1165 .getRegex(), 1166 _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/, 1167 del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/, 1168 text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/ 1169}; 1170/** 1171 * GFM + Line Breaks Inline Grammar 1172 */ 1173const inlineBreaks = { 1174 ...inlineGfm, 1175 br: edit(br).replace('{2,}', '*').getRegex(), 1176 text: edit(inlineGfm.text) 1177 .replace('\\b_', '\\b_| {2,}\\n') 1178 .replace(/\{2,\}/g, '*') 1179 .getRegex() 1180}; 1181/** 1182 * exports 1183 */ 1184const block = { 1185 normal: blockNormal, 1186 gfm: blockGfm, 1187 pedantic: blockPedantic 1188}; 1189const inline = { 1190 normal: inlineNormal, 1191 gfm: inlineGfm, 1192 breaks: inlineBreaks, 1193 pedantic: inlinePedantic 1194}; 1195 1196/** 1197 * Block Lexer 1198 */ 1199class _Lexer { 1200 tokens; 1201 options; 1202 state; 1203 tokenizer; 1204 inlineQueue; 1205 constructor(options) { 1206 // TokenList cannot be created in one go 1207 this.tokens = []; 1208 this.tokens.links = Object.create(null); 1209 this.options = options || _defaults; 1210 this.options.tokenizer = this.options.tokenizer || new _Tokenizer(); 1211 this.tokenizer = this.options.tokenizer; 1212 this.tokenizer.options = this.options; 1213 this.tokenizer.lexer = this; 1214 this.inlineQueue = []; 1215 this.state = { 1216 inLink: false, 1217 inRawBlock: false, 1218 top: true 1219 }; 1220 const rules = { 1221 block: block.normal, 1222 inline: inline.normal 1223 }; 1224 if (this.options.pedantic) { 1225 rules.block = block.pedantic; 1226 rules.inline = inline.pedantic; 1227 } 1228 else if (this.options.gfm) { 1229 rules.block = block.gfm; 1230 if (this.options.breaks) { 1231 rules.inline = inline.breaks; 1232 } 1233 else { 1234 rules.inline = inline.gfm; 1235 } 1236 } 1237 this.tokenizer.rules = rules; 1238 } 1239 /** 1240 * Expose Rules 1241 */ 1242 static get rules() { 1243 return { 1244 block, 1245 inline 1246 }; 1247 } 1248 /** 1249 * Static Lex Method 1250 */ 1251 static lex(src, options) { 1252 const lexer = new _Lexer(options); 1253 return lexer.lex(src); 1254 } 1255 /** 1256 * Static Lex Inline Method 1257 */ 1258 static lexInline(src, options) { 1259 const lexer = new _Lexer(options); 1260 return lexer.inlineTokens(src); 1261 } 1262 /** 1263 * Preprocessing 1264 */ 1265 lex(src) { 1266 src = src 1267 .replace(/\r\n|\r/g, '\n'); 1268 this.blockTokens(src, this.tokens); 1269 for (let i = 0; i < this.inlineQueue.length; i++) { 1270 const next = this.inlineQueue[i]; 1271 this.inlineTokens(next.src, next.tokens); 1272 } 1273 this.inlineQueue = []; 1274 return this.tokens; 1275 } 1276 blockTokens(src, tokens = []) { 1277 if (this.options.pedantic) { 1278 src = src.replace(/\t/g, ' ').replace(/^ +$/gm, ''); 1279 } 1280 else { 1281 src = src.replace(/^( *)(\t+)/gm, (_, leading, tabs) => { 1282 return leading + ' '.repeat(tabs.length); 1283 }); 1284 } 1285 let token; 1286 let lastToken; 1287 let cutSrc; 1288 let lastParagraphClipped; 1289 while (src) { 1290 if (this.options.extensions 1291 && this.options.extensions.block 1292 && this.options.extensions.block.some((extTokenizer) => { 1293 if (token = extTokenizer.call({ lexer: this }, src, tokens)) { 1294 src = src.substring(token.raw.length); 1295 tokens.push(token); 1296 return true; 1297 } 1298 return false;
vendor: 4,803 bytes, lines 1299-1414
1299 })) { 1300 continue; 1301 } 1302 // newline 1303 if (token = this.tokenizer.space(src)) { 1304 src = src.substring(token.raw.length); 1305 if (token.raw.length === 1 && tokens.length > 0) { 1306 // if there's a single \n as a spacer, it's terminating the last line, 1307 // so move it there so that we don't get unnecessary paragraph tags 1308 tokens[tokens.length - 1].raw += '\n'; 1309 } 1310 else { 1311 tokens.push(token); 1312 } 1313 continue; 1314 } 1315 // code 1316 if (token = this.tokenizer.code(src)) { 1317 src = src.substring(token.raw.length); 1318 lastToken = tokens[tokens.length - 1]; 1319 // An indented code block cannot interrupt a paragraph. 1320 if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) { 1321 lastToken.raw += '\n' + token.raw; 1322 lastToken.text += '\n' + token.text; 1323 this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; 1324 } 1325 else { 1326 tokens.push(token); 1327 } 1328 continue; 1329 } 1330 // fences 1331 if (token = this.tokenizer.fences(src)) { 1332 src = src.substring(token.raw.length); 1333 tokens.push(token); 1334 continue; 1335 } 1336 // heading 1337 if (token = this.tokenizer.heading(src)) { 1338 src = src.substring(token.raw.length); 1339 tokens.push(token); 1340 continue; 1341 } 1342 // hr 1343 if (token = this.tokenizer.hr(src)) { 1344 src = src.substring(token.raw.length); 1345 tokens.push(token); 1346 continue; 1347 } 1348 // blockquote 1349 if (token = this.tokenizer.blockquote(src)) { 1350 src = src.substring(token.raw.length); 1351 tokens.push(token); 1352 continue; 1353 } 1354 // list 1355 if (token = this.tokenizer.list(src)) { 1356 src = src.substring(token.raw.length); 1357 tokens.push(token); 1358 continue; 1359 } 1360 // html 1361 if (token = this.tokenizer.html(src)) { 1362 src = src.substring(token.raw.length); 1363 tokens.push(token); 1364 continue; 1365 } 1366 // def 1367 if (token = this.tokenizer.def(src)) { 1368 src = src.substring(token.raw.length); 1369 lastToken = tokens[tokens.length - 1]; 1370 if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) { 1371 lastToken.raw += '\n' + token.raw; 1372 lastToken.text += '\n' + token.raw; 1373 this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; 1374 } 1375 else if (!this.tokens.links[token.tag]) { 1376 this.tokens.links[token.tag] = { 1377 href: token.href, 1378 title: token.title 1379 }; 1380 } 1381 continue; 1382 } 1383 // table (gfm) 1384 if (token = this.tokenizer.table(src)) { 1385 src = src.substring(token.raw.length); 1386 tokens.push(token); 1387 continue; 1388 } 1389 // lheading 1390 if (token = this.tokenizer.lheading(src)) { 1391 src = src.substring(token.raw.length); 1392 tokens.push(token); 1393 continue; 1394 } 1395 // top-level paragraph 1396 // prevent paragraph consuming extensions by clipping 'src' to extension start 1397 cutSrc = src; 1398 if (this.options.extensions && this.options.extensions.startBlock) { 1399 let startIndex = Infinity; 1400 const tempSrc = src.slice(1); 1401 let tempStart; 1402 this.options.extensions.startBlock.forEach((getStartIndex) => { 1403 tempStart = getStartIndex.call({ lexer: this }, tempSrc); 1404 if (typeof tempStart === 'number' && tempStart >= 0) { 1405 startIndex = Math.min(startIndex, tempStart); 1406 } 1407 }); 1408 if (startIndex < Infinity && startIndex >= 0) { 1409 cutSrc = src.substring(0, startIndex + 1); 1410 } 1411 } 1412 if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) { 1413 lastToken = tokens[tokens.length - 1]; 1414 if (lastParagraphClipped && lastToken
vendor: 8,494 bytes, lines 1414-1633
1414.type === 'paragraph') { 1415 lastToken.raw += '\n' + token.raw; 1416 lastToken.text += '\n' + token.text; 1417 this.inlineQueue.pop(); 1418 this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; 1419 } 1420 else { 1421 tokens.push(token); 1422 } 1423 lastParagraphClipped = (cutSrc.length !== src.length); 1424 src = src.substring(token.raw.length); 1425 continue; 1426 } 1427 // text 1428 if (token = this.tokenizer.text(src)) { 1429 src = src.substring(token.raw.length); 1430 lastToken = tokens[tokens.length - 1]; 1431 if (lastToken && lastToken.type === 'text') { 1432 lastToken.raw += '\n' + token.raw; 1433 lastToken.text += '\n' + token.text; 1434 this.inlineQueue.pop(); 1435 this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; 1436 } 1437 else { 1438 tokens.push(token); 1439 } 1440 continue; 1441 } 1442 if (src) { 1443 const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0); 1444 if (this.options.silent) { 1445 console.error(errMsg); 1446 break; 1447 } 1448 else { 1449 throw new Error(errMsg); 1450 } 1451 } 1452 } 1453 this.state.top = true; 1454 return tokens; 1455 } 1456 inline(src, tokens = []) { 1457 this.inlineQueue.push({ src, tokens }); 1458 return tokens; 1459 } 1460 /** 1461 * Lexing/Compiling 1462 */ 1463 inlineTokens(src, tokens = []) { 1464 let token, lastToken, cutSrc; 1465 // String with links masked to avoid interference with em and strong 1466 let maskedSrc = src; 1467 let match; 1468 let keepPrevChar, prevChar; 1469 // Mask out reflinks 1470 if (this.tokens.links) { 1471 const links = Object.keys(this.tokens.links); 1472 if (links.length > 0) { 1473 while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) { 1474 if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) { 1475 maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex); 1476 } 1477 } 1478 } 1479 } 1480 // Mask out other blocks 1481 while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) { 1482 maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex); 1483 } 1484 // Mask out escaped characters 1485 while ((match = this.tokenizer.rules.inline.anyPunctuation.exec(maskedSrc)) != null) { 1486 maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex); 1487 } 1488 while (src) { 1489 if (!keepPrevChar) { 1490 prevChar = ''; 1491 } 1492 keepPrevChar = false; 1493 // extensions 1494 if (this.options.extensions 1495 && this.options.extensions.inline 1496 && this.options.extensions.inline.some((extTokenizer) => { 1497 if (token = extTokenizer.call({ lexer: this }, src, tokens)) { 1498 src = src.substring(token.raw.length); 1499 tokens.push(token); 1500 return true; 1501 } 1502 return false; 1503 })) { 1504 continue; 1505 } 1506 // escape 1507 if (token = this.tokenizer.escape(src)) { 1508 src = src.substring(token.raw.length); 1509 tokens.push(token); 1510 continue; 1511 } 1512 // tag 1513 if (token = this.tokenizer.tag(src)) { 1514 src = src.substring(token.raw.length); 1515 lastToken = tokens[tokens.length - 1]; 1516 if (lastToken && token.type === 'text' && lastToken.type === 'text') { 1517 lastToken.raw += token.raw; 1518 lastToken.text += token.text; 1519 } 1520 else { 1521 tokens.push(token); 1522 } 1523 continue; 1524 } 1525 // link 1526 if (token = this.tokenizer.link(src)) { 1527 src = src.substring(token.raw.length); 1528 tokens.push(token); 1529 continue; 1530 } 1531 // reflink, nolink 1532 if (token = this.tokenizer.reflink(src, this.tokens.links)) { 1533 src = src.substring(token.raw.length); 1534 lastToken = tokens[tokens.length - 1]; 1535 if (lastToken && token.type === 'text' && lastToken.type === 'text') { 1536 lastToken.raw += token.raw; 1537 lastToken.text += token.text; 1538 } 1539 else { 1540 tokens.push(token); 1541 } 1542 continue; 1543 } 1544 // em & strong 1545 if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) { 1546 src = src.substring(token.raw.length); 1547 tokens.push(token); 1548 continue; 1549 } 1550 // code 1551 if (token = this.tokenizer.codespan(src)) { 1552 src = src.substring(token.raw.length); 1553 tokens.push(token); 1554 continue; 1555 } 1556 // br 1557 if (token = this.tokenizer.br(src)) { 1558 src = src.substring(token.raw.length); 1559 tokens.push(token); 1560 continue; 1561 } 1562 // del (gfm) 1563 if (token = this.tokenizer.del(src)) { 1564 src = src.substring(token.raw.length); 1565 tokens.push(token); 1566 continue; 1567 } 1568 // autolink 1569 if (token = this.tokenizer.autolink(src)) { 1570 src = src.substring(token.raw.length); 1571 tokens.push(token); 1572 continue; 1573 } 1574 // url (gfm) 1575 if (!this.state.inLink && (token = this.tokenizer.url(src))) { 1576 src = src.substring(token.raw.length); 1577 tokens.push(token); 1578 continue; 1579 } 1580 // text 1581 // prevent inlineText consuming extensions by clipping 'src' to extension start 1582 cutSrc = src; 1583 if (this.options.extensions && this.options.extensions.startInline) { 1584 let startIndex = Infinity; 1585 const tempSrc = src.slice(1); 1586 let tempStart; 1587 this.options.extensions.startInline.forEach((getStartIndex) => { 1588 tempStart = getStartIndex.call({ lexer: this }, tempSrc); 1589 if (typeof tempStart === 'number' && tempStart >= 0) { 1590 startIndex = Math.min(startIndex, tempStart); 1591 } 1592 }); 1593 if (startIndex < Infinity && startIndex >= 0) { 1594 cutSrc = src.substring(0, startIndex + 1); 1595 } 1596 } 1597 if (token = this.tokenizer.inlineText(cutSrc)) { 1598 src = src.substring(token.raw.length); 1599 if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started 1600 prevChar = token.raw.slice(-1); 1601 } 1602 keepPrevChar = true; 1603 lastToken = tokens[tokens.length - 1]; 1604 if (lastToken && lastToken.type === 'text') { 1605 lastToken.raw += token.raw; 1606 lastToken.text += token.text; 1607 } 1608 else { 1609 tokens.push(token); 1610 } 1611 continue; 1612 } 1613 if (src) { 1614 const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0); 1615 if (this.options.silent) { 1616 console.error(errMsg); 1617 break; 1618 } 1619 else { 1620 throw new Error(errMsg); 1621 } 1622 } 1623 } 1624 return tokens; 1625 } 1626} 1627 1628/** 1629 * Renderer 1630 */ 1631class _Renderer { 1632 options; 1633
vendor: 15,759 bytes, lines 1633-2091
1633constructor(options) { 1634 this.options = options || _defaults; 1635 } 1636 code(code, infostring, escaped) { 1637 const lang = (infostring || '').match(/^\S*/)?.[0]; 1638 code = code.replace(/\n$/, '') + '\n'; 1639 if (!lang) { 1640 return '<pre><code>' 1641 + (escaped ? code : escape$1$1(code, true)) 1642 + '</code></pre>\n'; 1643 } 1644 return '<pre><code class="language-' 1645 + escape$1$1(lang) 1646 + '">' 1647 + (escaped ? code : escape$1$1(code, true)) 1648 + '</code></pre>\n'; 1649 } 1650 blockquote(quote) { 1651 return `<blockquote>\n${quote}</blockquote>\n`; 1652 } 1653 html(html, block) { 1654 return html; 1655 } 1656 heading(text, level, raw) { 1657 // ignore IDs 1658 return `<h${level}>${text}</h${level}>\n`; 1659 } 1660 hr() { 1661 return '<hr>\n'; 1662 } 1663 list(body, ordered, start) { 1664 const type = ordered ? 'ol' : 'ul'; 1665 const startatt = (ordered && start !== 1) ? (' start="' + start + '"') : ''; 1666 return '<' + type + startatt + '>\n' + body + '</' + type + '>\n'; 1667 } 1668 listitem(text, task, checked) { 1669 return `<li>${text}</li>\n`; 1670 } 1671 checkbox(checked) { 1672 return '<input ' 1673 + (checked ? 'checked="" ' : '') 1674 + 'disabled="" type="checkbox">'; 1675 } 1676 paragraph(text) { 1677 return `<p>${text}</p>\n`; 1678 } 1679 table(header, body) { 1680 if (body) 1681 body = `<tbody>${body}</tbody>`; 1682 return '<table>\n' 1683 + '<thead>\n' 1684 + header 1685 + '</thead>\n' 1686 + body 1687 + '</table>\n'; 1688 } 1689 tablerow(content) { 1690 return `<tr>\n${content}</tr>\n`; 1691 } 1692 tablecell(content, flags) { 1693 const type = flags.header ? 'th' : 'td'; 1694 const tag = flags.align 1695 ? `<${type} align="${flags.align}">` 1696 : `<${type}>`; 1697 return tag + content + `</${type}>\n`; 1698 } 1699 /** 1700 * span level renderer 1701 */ 1702 strong(text) { 1703 return `<strong>${text}</strong>`; 1704 } 1705 em(text) { 1706 return `<em>${text}</em>`; 1707 } 1708 codespan(text) { 1709 return `<code>${text}</code>`; 1710 } 1711 br() { 1712 return '<br>'; 1713 } 1714 del(text) { 1715 return `<del>${text}</del>`; 1716 } 1717 link(href, title, text) { 1718 const cleanHref = cleanUrl(href); 1719 if (cleanHref === null) { 1720 return text; 1721 } 1722 href = cleanHref; 1723 let out = '<a href="' + href + '"'; 1724 if (title) { 1725 out += ' title="' + title + '"'; 1726 } 1727 out += '>' + text + '</a>'; 1728 return out; 1729 } 1730 image(href, title, text) { 1731 const cleanHref = cleanUrl(href); 1732 if (cleanHref === null) { 1733 return text; 1734 } 1735 href = cleanHref; 1736 let out = `<img src="${href}" alt="${text}"`; 1737 if (title) { 1738 out += ` title="${title}"`; 1739 } 1740 out += '>'; 1741 return out; 1742 } 1743 text(text) { 1744 return text; 1745 } 1746} 1747 1748/** 1749 * TextRenderer 1750 * returns only the textual part of the token 1751 */ 1752class _TextRenderer { 1753 // no need for block level renderers 1754 strong(text) { 1755 return text; 1756 } 1757 em(text) { 1758 return text; 1759 } 1760 codespan(text) { 1761 return text; 1762 } 1763 del(text) { 1764 return text; 1765 } 1766 html(text) { 1767 return text; 1768 } 1769 text(text) { 1770 return text; 1771 } 1772 link(href, title, text) { 1773 return '' + text; 1774 } 1775 image(href, title, text) { 1776 return '' + text; 1777 } 1778 br() { 1779 return ''; 1780 } 1781} 1782 1783/** 1784 * Parsing & Compiling 1785 */ 1786class _Parser { 1787 options; 1788 renderer; 1789 textRenderer; 1790 constructor(options) { 1791 this.options = options || _defaults; 1792 this.options.renderer = this.options.renderer || new _Renderer(); 1793 this.renderer = this.options.renderer; 1794 this.renderer.options = this.options; 1795 this.textRenderer = new _TextRenderer(); 1796 } 1797 /** 1798 * Static Parse Method 1799 */ 1800 static parse(tokens, options) { 1801 const parser = new _Parser(options); 1802 return parser.parse(tokens); 1803 } 1804 /** 1805 * Static Parse Inline Method 1806 */ 1807 static parseInline(tokens, options) { 1808 const parser = new _Parser(options); 1809 return parser.parseInline(tokens); 1810 } 1811 /** 1812 * Parse Loop 1813 */ 1814 parse(tokens, top = true) { 1815 let out = ''; 1816 for (let i = 0; i < tokens.length; i++) { 1817 const token = tokens[i]; 1818 // Run any renderer extensions 1819 if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) { 1820 const genericToken = token; 1821 const ret = this.options.extensions.renderers[genericToken.type].call({ parser: this }, genericToken); 1822 if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(genericToken.type)) { 1823 out += ret || ''; 1824 continue; 1825 } 1826 } 1827 switch (token.type) { 1828 case 'space': { 1829 continue; 1830 } 1831 case 'hr': { 1832 out += this.renderer.hr(); 1833 continue; 1834 } 1835 case 'heading': { 1836 const headingToken = token; 1837 out += this.renderer.heading(this.parseInline(headingToken.tokens), headingToken.depth, unescape(this.parseInline(headingToken.tokens, this.textRenderer))); 1838 continue; 1839 } 1840 case 'code': { 1841 const codeToken = token; 1842 out += this.renderer.code(codeToken.text, codeToken.lang, !!codeToken.escaped); 1843 continue; 1844 } 1845 case 'table': { 1846 const tableToken = token; 1847 let header = ''; 1848 // header 1849 let cell = ''; 1850 for (let j = 0; j < tableToken.header.length; j++) { 1851 cell += this.renderer.tablecell(this.parseInline(tableToken.header[j].tokens), { header: true, align: tableToken.align[j] }); 1852 } 1853 header += this.renderer.tablerow(cell); 1854 let body = ''; 1855 for (let j = 0; j < tableToken.rows.length; j++) { 1856 const row = tableToken.rows[j]; 1857 cell = ''; 1858 for (let k = 0; k < row.length; k++) { 1859 cell += this.renderer.tablecell(this.parseInline(row[k].tokens), { header: false, align: tableToken.align[k] }); 1860 } 1861 body += this.renderer.tablerow(cell); 1862 } 1863 out += this.renderer.table(header, body); 1864 continue; 1865 } 1866 case 'blockquote': { 1867 const blockquoteToken = token; 1868 const body = this.parse(blockquoteToken.tokens); 1869 out += this.renderer.blockquote(body); 1870 continue; 1871 } 1872 case 'list': { 1873 const listToken = token; 1874 const ordered = listToken.ordered; 1875 const start = listToken.start; 1876 const loose = listToken.loose; 1877 let body = ''; 1878 for (let j = 0; j < listToken.items.length; j++) { 1879 const item = listToken.items[j]; 1880 const checked = item.checked; 1881 const task = item.task; 1882 let itemBody = ''; 1883 if (item.task) { 1884 const checkbox = this.renderer.checkbox(!!checked); 1885 if (loose) { 1886 if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') { 1887 item.tokens[0].text = checkbox + ' ' + item.tokens[0].text; 1888 if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') { 1889 item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text; 1890 } 1891 } 1892 else { 1893 item.tokens.unshift({ 1894 type: 'text', 1895 text: checkbox + ' ' 1896 }); 1897 } 1898 } 1899 else { 1900 itemBody += checkbox + ' '; 1901 } 1902 } 1903 itemBody += this.parse(item.tokens, loose); 1904 body += this.renderer.listitem(itemBody, task, !!checked); 1905 } 1906 out += this.renderer.list(body, ordered, start); 1907 continue; 1908 } 1909 case 'html': { 1910 const htmlToken = token; 1911 out += this.renderer.html(htmlToken.text, htmlToken.block); 1912 continue; 1913 } 1914 case 'paragraph': { 1915 const paragraphToken = token; 1916 out += this.renderer.paragraph(this.parseInline(paragraphToken.tokens)); 1917 continue; 1918 } 1919 case 'text': { 1920 let textToken = token; 1921 let body = textToken.tokens ? this.parseInline(textToken.tokens) : textToken.text; 1922 while (i + 1 < tokens.length && tokens[i + 1].type === 'text') { 1923 textToken = tokens[++i]; 1924 body += '\n' + (textToken.tokens ? this.parseInline(textToken.tokens) : textToken.text); 1925 } 1926 out += top ? this.renderer.paragraph(body) : body; 1927 continue; 1928 } 1929 default: { 1930 const errMsg = 'Token with "' + token.type + '" type was not found.'; 1931 if (this.options.silent) { 1932 console.error(errMsg); 1933 return ''; 1934 } 1935 else { 1936 throw new Error(errMsg); 1937 } 1938 } 1939 } 1940 } 1941 return out; 1942 } 1943 /** 1944 * Parse Inline Tokens 1945 */ 1946 parseInline(tokens, renderer) { 1947 renderer = renderer || this.renderer; 1948 let out = ''; 1949 for (let i = 0; i < tokens.length; i++) { 1950 const token = tokens[i]; 1951 // Run any renderer extensions 1952 if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) { 1953 const ret = this.options.extensions.renderers[token.type].call({ parser: this }, token); 1954 if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) { 1955 out += ret || ''; 1956 continue; 1957 } 1958 } 1959 switch (token.type) { 1960 case 'escape': { 1961 const escapeToken = token; 1962 out += renderer.text(escapeToken.text); 1963 break; 1964 } 1965 case 'html': { 1966 const tagToken = token; 1967 out += renderer.html(tagToken.text); 1968 break; 1969 } 1970 case 'link': { 1971 const linkToken = token; 1972 out += renderer.link(linkToken.href, linkToken.title, this.parseInline(linkToken.tokens, renderer)); 1973 break; 1974 } 1975 case 'image': { 1976 const imageToken = token; 1977 out += renderer.image(imageToken.href, imageToken.title, imageToken.text); 1978 break; 1979 } 1980 case 'strong': { 1981 const strongToken = token; 1982 out += renderer.strong(this.parseInline(strongToken.tokens, renderer)); 1983 break; 1984 } 1985 case 'em': { 1986 const emToken = token; 1987 out += renderer.em(this.parseInline(emToken.tokens, renderer)); 1988 break; 1989 } 1990 case 'codespan': { 1991 const codespanToken = token; 1992 out += renderer.codespan(codespanToken.text); 1993 break; 1994 } 1995 case 'br': { 1996 out += renderer.br(); 1997 break; 1998 } 1999 case 'del': { 2000 const delToken = token; 2001 out += renderer.del(this.parseInline(delToken.tokens, renderer)); 2002 break; 2003 } 2004 case 'text': { 2005 const textToken = token; 2006 out += renderer.text(textToken.text); 2007 break; 2008 } 2009 default: { 2010 const errMsg = 'Token with "' + token.type + '" type was not found.'; 2011 if (this.options.silent) { 2012 console.error(errMsg); 2013 return ''; 2014 } 2015 else { 2016 throw new Error(errMsg); 2017 } 2018 } 2019 } 2020 } 2021 return out; 2022 } 2023} 2024 2025class _Hooks { 2026 options; 2027 constructor(options) { 2028 this.options = options || _defaults; 2029 } 2030 static passThroughHooks = new Set([ 2031 'preprocess', 2032 'postprocess', 2033 'processAllTokens' 2034 ]); 2035 /** 2036 * Process markdown before marked 2037 */ 2038 preprocess(markdown) { 2039 return markdown; 2040 } 2041 /** 2042 * Process HTML after marked is finished 2043 */ 2044 postprocess(html) { 2045 return html; 2046 } 2047 /** 2048 * Process all tokens before walk tokens 2049 */ 2050 processAllTokens(tokens) { 2051 return tokens; 2052 } 2053} 2054 2055class Marked { 2056 defaults = _getDefaults(); 2057 options = this.setOptions; 2058 parse = this.#parseMarkdown(_Lexer.lex, _Parser.parse); 2059 parseInline = this.#parseMarkdown(_Lexer.lexInline, _Parser.parseInline); 2060 Parser = _Parser; 2061 Renderer = _Renderer; 2062 TextRenderer = _TextRenderer; 2063 Lexer = _Lexer; 2064 Tokenizer = _Tokenizer; 2065 Hooks = _Hooks; 2066 constructor(...args) { 2067 this.use(...args); 2068 } 2069 /** 2070 * Run callback for every token 2071 */ 2072 walkTokens(tokens, callback) { 2073 let values = []; 2074 for (const token of tokens) { 2075 values = values.concat(callback.call(this, token)); 2076 switch (token.type) { 2077 case 'table': { 2078 const tableToken = token; 2079 for (const cell of tableToken.header) { 2080 values = values.concat(this.walkTokens(cell.tokens, callback)); 2081 } 2082 for (const row of tableToken.rows) { 2083 for (const cell of row) { 2084 values = values.concat(this.walkTokens(cell.tokens, callback)); 2085 } 2086 } 2087 break; 2088 } 2089 case 'list': { 2090 const listToken = token; 2091 values = values.concat(this.walkTokens(listToken.items, c
vendor: 4,682 bytes, lines 2091-2186
2091allback)); 2092 break; 2093 } 2094 default: { 2095 const genericToken = token; 2096 if (this.defaults.extensions?.childTokens?.[genericToken.type]) { 2097 this.defaults.extensions.childTokens[genericToken.type].forEach((childTokens) => { 2098 const tokens = genericToken[childTokens].flat(Infinity); 2099 values = values.concat(this.walkTokens(tokens, callback)); 2100 }); 2101 } 2102 else if (genericToken.tokens) { 2103 values = values.concat(this.walkTokens(genericToken.tokens, callback)); 2104 } 2105 } 2106 } 2107 } 2108 return values; 2109 } 2110 use(...args) { 2111 const extensions = this.defaults.extensions || { renderers: {}, childTokens: {} }; 2112 args.forEach((pack) => { 2113 // copy options to new object 2114 const opts = { ...pack }; 2115 // set async to true if it was set to true before 2116 opts.async = this.defaults.async || opts.async || false; 2117 // ==-- Parse "addon" extensions --== // 2118 if (pack.extensions) { 2119 pack.extensions.forEach((ext) => { 2120 if (!ext.name) { 2121 throw new Error('extension name required'); 2122 } 2123 if ('renderer' in ext) { // Renderer extensions 2124 const prevRenderer = extensions.renderers[ext.name]; 2125 if (prevRenderer) { 2126 // Replace extension with func to run new extension but fall back if false 2127 extensions.renderers[ext.name] = function (...args) { 2128 let ret = ext.renderer.apply(this, args); 2129 if (ret === false) { 2130 ret = prevRenderer.apply(this, args); 2131 } 2132 return ret; 2133 }; 2134 } 2135 else { 2136 extensions.renderers[ext.name] = ext.renderer; 2137 } 2138 } 2139 if ('tokenizer' in ext) { // Tokenizer Extensions 2140 if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) { 2141 throw new Error("extension level must be 'block' or 'inline'"); 2142 } 2143 const extLevel = extensions[ext.level]; 2144 if (extLevel) { 2145 extLevel.unshift(ext.tokenizer); 2146 } 2147 else { 2148 extensions[ext.level] = [ext.tokenizer]; 2149 } 2150 if (ext.start) { // Function to check for start of token 2151 if (ext.level === 'block') { 2152 if (extensions.startBlock) { 2153 extensions.startBlock.push(ext.start); 2154 } 2155 else { 2156 extensions.startBlock = [ext.start]; 2157 } 2158 } 2159 else if (ext.level === 'inline') { 2160 if (extensions.startInline) { 2161 extensions.startInline.push(ext.start); 2162 } 2163 else { 2164 extensions.startInline = [ext.start]; 2165 } 2166 } 2167 } 2168 } 2169 if ('childTokens' in ext && ext.childTokens) { // Child tokens to be visited by walkTokens 2170 extensions.childTokens[ext.name] = ext.childTokens; 2171 } 2172 }); 2173 opts.extensions = extensions; 2174 } 2175 // ==-- Parse "overwrite" extensions --== // 2176 if (pack.renderer) { 2177 const renderer = this.defaults.renderer || new _Renderer(this.defaults); 2178 for (const prop in pack.renderer) { 2179 if (!(prop in renderer)) { 2180 throw new Error(`renderer '${prop}' does not exist`); 2181 } 2182 if (prop === 'options') { 2183 // ignore options property 2184 continue; 2185 } 2186 const rendererProp = prop;
2187 const rendererFunc = pack.renderer[rendererProp]; 2188 const prevRenderer = renderer[rendererProp]; 2189 // Replace renderer with func to run extension, but fall back if false 2190 renderer[rendererProp] = (...args) => { 2191 let ret = rendererFunc.apply(renderer, args); 2192 if (ret === false) { 2193 ret = prevRenderer.apply(renderer, args); 2194 } 2195 return ret || ''; 2196 }; 2197 } 2198 opts.renderer = renderer; 2199 } 2200 if (pack.tokenizer) { 2201 const tokenizer = this.defaults.tokenizer || new _Tokenizer(this.defaults); 2202 for (const prop in pack.tokenizer) { 2203 if (!(prop in tokenizer)) { 2204 throw new Error(`tokenizer '${prop}' does not exist`); 2205 } 2206 if (['options', 'rules', 'lexer'].includes(prop)) { 2207 // ignore options, rules, and lexer properties 2208 continue; 2209 } 2210 const tokenizerProp = prop; 2211 const tokenizerFunc = pack.tokenizer[tokenizerProp]; 2212 const prevTokenizer = tokenizer[tokenizerProp]; 2213 // Replace tokenizer with func to run extension, but fall back if false 2214 // @ts-expect-error cannot type tokenizer function dynamically 2215 tokenizer[tokenizerProp] = (...args) => { 2216 let ret = tokenizerFunc.apply(tokenizer, args); 2217 if (ret === false) { 2218 ret = prevTokenizer.apply(tokenizer, args); 2219 } 2220 return ret; 2221 }; 2222 } 2223 opts.tokenizer = tokenizer; 2224 } 2225 // ==-- Parse Hooks extensions --== // 2226 if (pack.hooks) { 2227 const hooks = this.defaults.hooks || new _Hooks(); 2228 for (const prop in pack.hooks) { 2229 if (!(prop in hooks)) { 2230 throw new Error(`hook '${prop}' does not exist`); 2231 } 2232 if (prop === 'options') { 2233 // ignore options property 2234 continue; 2235 } 2236 const hooksProp = prop; 2237 const hooksFunc = pack.hooks[hooksProp]; 2238 const prevHook = hooks[hooksProp]; 2239 if (_Hooks.passThroughHooks.has(prop)) { 2240 // @ts-expect-error cannot type hook function dynamically 2241 hooks[hooksProp] = (arg) => { 2242 if (this.defaults.async) { 2243 return Promise.resolve(hooksFunc.call(hooks, arg)).then(ret => { 2244 return prevHook.call(hooks, ret); 2245 }); 2246 } 2247 const ret = hooksFunc.call(hooks, arg); 2248 return prevHook.call(hooks, ret); 2249 }; 2250 } 2251 else { 2252 // @ts-expect-error cannot type hook function dynamically 2253 hooks[hooksProp] = (...args) => { 2254 let ret = hooksFunc.apply(hooks, args); 2255 if (ret === false) { 2256 ret = prevHook.apply(hooks, args); 2257 } 2258 return ret; 2259 }; 2260 } 2261 } 2262 opts.hooks = hooks; 2263 } 2264 // ==-- Parse WalkTokens extensions --== // 2265 if (pack.walkTokens) { 2266 const walkTokens = this.defaults.walkTokens; 2267 const packWalktokens = pack.walkTokens; 2268 opts.walkTokens = function (token) { 2269 let values = []; 2270 values.push(packWalktokens.call(this, token)); 2271 if (walkTokens) { 2272 values = values.concat(walkTokens.call(this, token)); 2273 } 2274 return values; 2275 }; 2276 } 2277 this.defaults = { ...this.defaults, ...opts }; 2278 }); 2279 return this; 2280 } 2281 setOptions(opt) { 2282 this.defaults = { ...this.defaults, ...opt }; 2283 return this; 2284 } 2285 lexer(src, options) { 2286 return _Lexer.lex(src, options ?? this.defaults); 2287 } 2288 parser(tokens, options) { 2289 return _Parser.parse(tokens, options ?? this.defaults); 2290 } 2291 #parseMarkdown(lexer, parser) { 2292 return (src, options) => { 2293 const origOpt = { ...options }; 2294 const opt = { ...this.defaults, ...origOpt }; 2295 // Show warning if an extension set async to true but the parse was called with async: false 2296 if (this.defaults.async === true && origOpt.async === false) { 2297 if (!opt.silent) { 2298 console.warn('marked(): The async option was set to true by an extension. The async: false option sent to parse will be ignored.'); 2299 } 2300 opt.async = true; 2301 } 2302 const throwError = this.#onError(!!opt.silent, !!opt.async); 2303 // throw error in case of non string input 2304 if (typeof src === 'undefined' || src === null) { 2305 return throwError(new Error('marked(): input parameter is undefined or null')); 2306 } 2307 if (typeof src !== 'string') { 2308 return throwError(new Error('marked(): input parameter is of type ' 2309 + Object.prototype.toString.call(src) + ', string expected')); 2310 } 2311 if (opt.hooks) { 2312 opt.hooks.options = opt; 2313 } 2314 if (opt.async) { 2315 return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src) 2316 .then(src => lexer(src, opt)) 2317 .then(tokens => opt.hooks ? opt.hooks.processAllTokens(tokens) : tokens) 2318 .then(tokens => opt.walkTokens ? Promise.all(this.walkTokens(tokens, opt.walkTokens)).then(() => tokens) : tokens) 2319 .then(tokens => parser(tokens, opt)) 2320 .then(html => opt.hooks ? opt.hooks.postprocess(html) : html) 2321 .catch(throwError); 2322 } 2323 try { 2324 if (opt.hooks) { 2325 src = opt.hooks.preprocess(src); 2326 } 2327 let tokens = lexer(src, opt); 2328 if (opt.hooks) { 2329 tokens = opt.hooks.processAllTokens(tokens); 2330 } 2331 if (opt.walkTokens) { 2332 this.walkTokens(tokens, opt.walkTokens); 2333 } 2334 let html = parser(tokens, opt); 2335 if (opt.hooks) { 2336 html = opt.hooks.postprocess(html); 2337 } 2338 return html; 2339 } 2340 catch (e) { 2341 return throwError(e); 2342 } 2343 }; 2344 } 2345 #onError(silent, async) { 2346 return (e) => { 2347 e.message += '\nPlease report this to https://github.com/markedjs/marked.'; 2348 if (silent) { 2349 const msg = '<p>An error occurred:</p><pre>' 2350 + escape$1$1(e.message + '', true) 2351 + '</pre>'; 2352 if (async) { 2353 return Promise.resolve(msg); 2354 } 2355 return msg; 2356 } 2357 if (async) { 2358 return Promise.reject(e); 2359 } 2360 throw e; 2361 }; 2362 } 2363} 2364 2365const markedInstance = new Marked(); 2366function marked(src, opt) { 2367 return markedInstance.parse(src, opt); 2368} 2369/** 2370 * Sets the default options. 2371 * 2372 * @param options Hash of options 2373 */ 2374marked.options = 2375 marked.setOptions = function (options) { 2376 markedInstance.setOptions(options); 2377 marked.defaults = markedInstance.defaults; 2378 changeDefaults(marked.defaults); 2379 return marked; 2380 }; 2381/** 2382 * Gets the original marked default options. 2383 */ 2384marked.getDefaults = _getDefaults; 2385marked.defaults = _defaults; 2386/** 2387 * Use Extension 2388 */ 2389marked.use = function (...args) { 2390 markedInstance.use(...args); 2391 marked.defaults = markedInstance.defaults; 2392 changeDefaults(marked.defaults); 2393 return marked; 2394}; 2395/** 2396 * Run callback for every token 2397 */ 2398marked.walkTokens = function (tokens, callback) { 2399 return markedInstance.walkTokens(tokens, callback); 2400}; 2401/** 2402 * Compiles markdown to HTML without enclosing `p` tag. 2403 * 2404 * @param src String of markdown source to be compiled 2405 * @param options Hash of options 2406 * @return String of compiled HTML 2407 */ 2408marked.parseInline = markedInstance.parseInline; 2409/** 2410 * Expose 2411 */ 2412marked.Parser = _Parser; 2413marked.parser = _Parser.parse; 2414marked.Renderer = _Renderer; 2415marked.TextRenderer = _TextRenderer; 2416marked.Lexer = _Lexer; 2417marked.lexer = _Lexer.lex; 2418marked.Tokenizer = _Tokenizer; 2419marked.Hooks = _Hooks; 2420marked.parse = marked; 2421marked.options; 2422marked.setOptions; 2423marked.use; 2424marked.walkTokens; 2425marked.parseInline; 2426_Parser.parse; 2427_Lexer.lex; 2428 2429function markedHighlight(options) { 2430 if (typeof options === 'function') { 2431 options = { 2432 highlight: options, 2433 }; 2434 } 2435 2436 if (!options || typeof options.highlight !== 'function') { 2437 throw new Error('Must provide highlight function'); 2438 } 2439 2440 if (typeof options.langPrefix !== 'string') { 2441 options.langPrefix = 'language-'; 2442 } 2443 2444 if (typeof options.emptyLangClass !== 'string') { 2445 options.emptyLangClass = ''; 2446 } 2447 2448 return { 2449 async: !!options.async, 2450 walkTokens(token) { 2451 if (token.type !== 'code') { 2452 return; 2453 } 2454 2455 const lang = getLang(token.lang); 2456 2457 if (options.async) { 2458 return Promise.resolve(options.highlight(token.text, lang, token.lang || '')).then(updateToken(token)); 2459 } 2460 2461 const code = options.highlight(token.text, lang, token.lang || ''); 2462 if (code instanceof Promise) { 2463 throw new Error('markedHighlight is not set to async but the highlight function is async. Set the async option to true on markedHighlight to await the async highlight function.'); 2464 } 2465 updateToken(token)(code); 2466 }, 2467 useNewRenderer: true, 2468 renderer: { 2469 code(code, infoString, escaped) { 2470 // istanbul ignore next 2471 if (typeof code === 'object') { 2472 escaped = code.escaped; 2473 infoString = code.lang; 2474 code = code.text; 2475 } 2476 const lang = getLang(infoString); 2477 const classValue = lang ? options.langPrefix + escape$1(lang) : options.emptyLangClass; 2478 const classAttr = classValue 2479 ? ` class="${classValue}"` 2480 : ''; 2481 code = code.replace(/\n$/, ''); 2482 return `<pre><code${classAttr}>${escaped ? code : escape$1(code, true)}\n</code></pre>`; 2483 }, 2484 }, 2485 }; 2486} 2487 2488function getLang(lang) { 2489 return (lang || '').match(/\S*/)[0]; 2490} 2491 2492function updateToken(token) { 2493 return (code) => { 2494 if (typeof code === 'string' && code !== token.text) { 2495 token.escaped = true; 2496 token.text = code; 2497 } 2498 }; 2499} 2500 2501// copied from marked helpers 2502const escapeTest = /[&<>"']/; 2503const escapeReplace = new RegExp(escapeTest.source, 'g'); 2504const escapeTestNoEncode = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/; 2505const escapeReplaceNoEncode = new RegExp(escapeTestNoEncode.source, 'g'); 2506const escapeReplacements = { 2507 '&': '&', 2508 '<': '<', 2509 '>': '>', 2510 '"': '"', 2511 "'": ''', 2512}; 2513const getEscapeReplacement = (ch) => escapeReplacements[ch]; 2514function escape$1(html, encode) { 2515 if (encode) { 2516 if (escapeTest.test(html)) { 2517 return html.replace(escapeReplace, getEscapeReplacement); 2518 } 2519 } else { 2520 if (escapeTestNoEncode.test(html)) { 2521 return html.replace(escapeReplaceNoEncode, getEscapeReplacement); 2522 } 2523 } 2524 2525 return html; 2526} 2527 2528// This module is generated by `script/`. 2529/* eslint-disable no-control-regex, no-misleading-character-class, no-useless-escape */ 2530const regex = /[\0-\x1F!-,\.\/:-@\[-\^`\{-\xA9\xAB-\xB4\xB6-\xB9\xBB-\xBF\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0378\u0379\u037E\u0380-\u0385\u0387\u038B\u038D\u03A2\u03F6\u0482\u0530\u0557\u0558\u055A-\u055F\u0589-\u0590\u05BE\u05C0\u05C3\u05C6\u05C8-\u05CF\u05EB-\u05EE\u05F3-\u060F\u061B-\u061F\u066A-\u066D\u06D4\u06DD\u06DE\u06E9\u06FD\u06FE\u0700-\u070F\u074B\u074C\u07B2-\u07BF\u07F6-\u07F9\u07FB\u07FC\u07FE\u07FF\u082E-\u083F\u085C-\u085
2530F\u086B-\u089F\u08B5\u08C8-\u08D2\u08E2\u0964\u0965\u0970\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09F2-\u09FB\u09FD\u09FF\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A76-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF0-\u0AF8\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B54\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B70\u0B72-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BF0-\u0BFF\u0C0D\u0C11\u0C29\u0C3A-\u0C3C\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5B-\u0C5F\u0C64\u0C65\u0C70-\u0C7F\u0C84\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDD\u0CDF\u0CE4\u0CE5\u0CF0\u0CF3-\u0CFF\u0D0D\u0D11\u0D45\u0D49\u0D4F-\u0D53\u0D58-\u0D5E\u0D64\u0D65\u0D70-\u0D79\u0D80\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DE5\u0DF0\u0DF1\u0DF4-\u0E00\u0E3B-\u0E3F\u0E4F\u0E5A-\u0E80\u0E83\u0E85\u0E8B\u0EA4\u0EA6\u0EBE\u0EBF\u0EC5\u0EC7\u0ECE\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F01-\u0F17\u0F1A-\u0F1F\u0F2A-\u0F34\u0F36\u0F38\u0F3A-\u0F3D\u0F48\u0F6D-\u0F70\u0F85\u0F98\u0FBD-\u0FC5\u0FC7-\u0FFF\u104A-\u104F\u109E\u109F\u10C6\u10C8-\u10CC\u10CE\u10CF\u10FB\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u1360-\u137F\u1390-\u139F\u13F6\u13F7\u13FE-\u1400\u166D\u166E\u1680\u169B-\u169F\u16EB-\u16ED\u16F9-\u16FF\u170D\u1715-\u171F\u1735-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17D4-\u17D6\u17D8-\u17DB\u17DE\u17DF\u17EA-\u180A\u180E\u180F\u181A-\u181F\u1879-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191F\u192C-\u192F\u193C-\u1945\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DA-\u19FF\u1A1C-\u1A1F\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1AA6\u1AA8-\u1AAF\u1AC1-\u1AFF\u1B4C-\u1B4F\u1B5A-\u1B6A\u1B74-\u1B7F\u1BF4-\u1BFF\u1C38-\u1C3F\u1C4A-\u1C4C\u1C7E\u1C7F\u1C89-\u1C8F\u1CBB\u1CBC\u1CC0-\u1CCF\u1CD3\u1CFB-\u1CFF\u1DFA\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FBD\u1FBF-\u1FC1\u1FC5\u1FCD-\u1FCF\u1FD4\u1FD5\u1FDC-\u1FDF\u1FED-\u1FF1\u1FF5\u1FFD-\u203E\u2041-\u2053\u2055-\u2070\u2072-\u207E\u2080-\u208F\u209D-\u20CF\u20F1-\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F-\u215F\u2189-\u24B5\u24EA-\u2BFF\u2C2F\u2C5F\u2CE5-\u2CEA\u2CF4-\u2CFF\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D70-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E00-\u2E2E\u2E30-\u3004\u3008-\u3020\u3030\u3036\u3037\u303D-\u3040\u3097\u3098\u309B\u309C\u30A0\u30FB\u3100-\u3104\u3130\u318F-\u319F\u31C0-\u31EF\u3200-\u33FF\u4DC0-\u4DFF\u9FFD-\u9FFF\uA48D-\uA4CF\uA4FE\uA4FF\uA60D-\uA60F\uA62C-\uA63F\uA673\uA67E\uA6F2-\uA716\uA720\uA721\uA789\uA78A\uA7C0\uA7C1\uA7CB-\uA7F4\uA828-\uA82B\uA82D-\uA83F\uA874-\uA87F\uA8C6-\uA8CF\uA8DA-\uA8DF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA954-\uA95F\uA97D-\uA97F\uA9C1-\uA9CE\uA9DA-\uA9DF\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A-\uAA5F\uAA77-\uAA79\uAAC3-\uAADA\uAADE\uAADF\uAAF0\uAAF1\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F\uAB5B\uAB6A-\uAB6F\uABEB\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uD7FF\uE000-\uF8FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB29\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBB2-\uFBD2\uFD3E-\uFD4F\uFD90\uFD91\uFDC8-\uFDEF\uFDFC-\uFDFF\uFE10-\uFE1F\uFE30-\uFE32\uFE35-\uFE4C\uFE50-\uFE6F\uFE75\uFEFD-\uFF0F\uFF1A-\uFF20\uFF3B-\uFF3E\uFF40\uFF5B-\uFF65\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFFF]|\uD800[\uDC0C\uDC27\uDC3B\uDC3E\uDC4E\uDC4F\uDC5E-\uDC7F\uDCFB-\uDD3F\uDD75-\uDDFC\uDDFE-\uDE7F\uDE9D-\uDE9F\uDED1-\uDEDF\uDEE1-\uDEFF\uDF20-\uDF2C\uDF4B-\uDF4F\uDF7B-\uDF7F\uDF9E\uDF9F\uDFC4-\uDFC7\uDFD0\uDFD6-\uDFFF]|\uD801[\uDC9E\uDC9F\uDCAA-\uDCAF\uDCD4-\uDCD7\uDCFC-\uDCFF\uDD28-\uDD2F\uDD64-\uDDFF\uD
2530F37-\uDF3F\uDF56-\uDF5F\uDF68-\uDFFF]|\uD802[\uDC06\uDC07\uDC09\uDC36\uDC39-\uDC3B\uDC3D\uDC3E\uDC56-\uDC5F\uDC77-\uDC7F\uDC9F-\uDCDF\uDCF3\uDCF6-\uDCFF\uDD16-\uDD1F\uDD3A-\uDD7F\uDDB8-\uDDBD\uDDC0-\uDDFF\uDE04\uDE07-\uDE0B\uDE14\uDE18\uDE36\uDE37\uDE3B-\uDE3E\uDE40-\uDE5F\uDE7D-\uDE7F\uDE9D-\uDEBF\uDEC8\uDEE7-\uDEFF\uDF36-\uDF3F\uDF56-\uDF5F\uDF73-\uDF7F\uDF92-\uDFFF]|\uD803[\uDC49-\uDC7F\uDCB3-\uDCBF\uDCF3-\uDCFF\uDD28-\uDD2F\uDD3A-\uDE7F\uDEAA\uDEAD-\uDEAF\uDEB2-\uDEFF\uDF1D-\uDF26\uDF28-\uDF2F\uDF51-\uDFAF\uDFC5-\uDFDF\uDFF7-\uDFFF]|\uD804[\uDC47-\uDC65\uDC70-\uDC7E\uDCBB-\uDCCF\uDCE9-\uDCEF\uDCFA-\uDCFF\uDD35\uDD40-\uDD43\uDD48-\uDD4F\uDD74\uDD75\uDD77-\uDD7F\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDFF\uDE12\uDE38-\uDE3D\uDE3F-\uDE7F\uDE87\uDE89\uDE8E\uDE9E\uDEA9-\uDEAF\uDEEB-\uDEEF\uDEFA-\uDEFF\uDF04\uDF0D\uDF0E\uDF11\uDF12\uDF29\uDF31\uDF34\uDF3A\uDF45\uDF46\uDF49\uDF4A\uDF4E\uDF4F\uDF51-\uDF56\uDF58-\uDF5C\uDF64\uDF65\uDF6D-\uDF6F\uDF75-\uDFFF]|\uD805[\uDC4B-\uDC4F\uDC5A-\uDC5D\uDC62-\uDC7F\uDCC6\uDCC8-\uDCCF\uDCDA-\uDD7F\uDDB6\uDDB7\uDDC1-\uDDD7\uDDDE-\uDDFF\uDE41-\uDE43\uDE45-\uDE4F\uDE5A-\uDE7F\uDEB9-\uDEBF\uDECA-\uDEFF\uDF1B\uDF1C\uDF2C-\uDF2F\uDF3A-\uDFFF]|\uD806[\uDC3B-\uDC9F\uDCEA-\uDCFE\uDD07\uDD08\uDD0A\uDD0B\uDD14\uDD17\uDD36\uDD39\uDD3A\uDD44-\uDD4F\uDD5A-\uDD9F\uDDA8\uDDA9\uDDD8\uDDD9\uDDE2\uDDE5-\uDDFF\uDE3F-\uDE46\uDE48-\uDE4F\uDE9A-\uDE9C\uDE9E-\uDEBF\uDEF9-\uDFFF]|\uD807[\uDC09\uDC37\uDC41-\uDC4F\uDC5A-\uDC71\uDC90\uDC91\uDCA8\uDCB7-\uDCFF\uDD07\uDD0A\uDD37-\uDD39\uDD3B\uDD3E\uDD48-\uDD4F\uDD5A-\uDD5F\uDD66\uDD69\uDD8F\uDD92\uDD99-\uDD9F\uDDAA-\uDEDF\uDEF7-\uDFAF\uDFB1-\uDFFF]|\uD808[\uDF9A-\uDFFF]|\uD809[\uDC6F-\uDC7F\uDD44-\uDFFF]|[\uD80A\uD80B\uD80E-\uD810\uD812-\uD819\uD824-\uD82B\uD82D\uD82E\uD830-\uD833\uD837\uD839\uD83D\uD83F\uD87B-\uD87D\uD87F\uD885-\uDB3F\uDB41-\uDBFF][\uDC00-\uDFFF]|\uD80D[\uDC2F-\uDFFF]|\uD811[\uDE47-\uDFFF]|\uD81A[\uDE39-\uDE3F\uDE5F\uDE6A-\uDECF\uDEEE\uDEEF\uDEF5-\uDEFF\uDF37-\uDF3F\uDF44-\uDF4F\uDF5A-\uDF62\uDF78-\uDF7C\uDF90-\uDFFF]|\uD81B[\uDC00-\uDE3F\uDE80-\uDEFF\uDF4B-\uDF4E\uDF88-\uDF8E\uDFA0-\uDFDF\uDFE2\uDFE5-\uDFEF\uDFF2-\uDFFF]|\uD821[\uDFF8-\uDFFF]|\uD823[\uDCD6-\uDCFF\uDD09-\uDFFF]|\uD82C[\uDD1F-\uDD4F\uDD53-\uDD63\uDD68-\uDD6F\uDEFC-\uDFFF]|\uD82F[\uDC6B-\uDC6F\uDC7D-\uDC7F\uDC89-\uDC8F\uDC9A-\uDC9C\uDC9F-\uDFFF]|\uD834[\uDC00-\uDD64\uDD6A-\uDD6C\uDD73-\uDD7A\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDE41\uDE45-\uDFFF]|\uD835[\uDC55\uDC9D\uDCA0\uDCA1\uDCA3\uDCA4\uDCA7\uDCA8\uDCAD\uDCBA\uDCBC\uDCC4\uDD06\uDD0B\uDD0C\uDD15\uDD1D\uDD3A\uDD3F\uDD45\uDD47-\uDD49\uDD51\uDEA6\uDEA7\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3\uDFCC\uDFCD]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85-\uDE9A\uDEA0\uDEB0-\uDFFF]|\uD838[\uDC07\uDC19\uDC1A\uDC22\uDC25\uDC2B-\uDCFF\uDD2D-\uDD2F\uDD3E\uDD3F\uDD4A-\uDD4D\uDD4F-\uDEBF\uDEFA-\uDFFF]|\uD83A[\uDCC5-\uDCCF\uDCD7-\uDCFF\uDD4C-\uDD4F\uDD5A-\uDFFF]|\uD83B[\uDC00-\uDDFF\uDE04\uDE20\uDE23\uDE25\uDE26\uDE28\uDE33\uDE38\uDE3A\uDE3C-\uDE41\uDE43-\uDE46\uDE48\uDE4A\uDE4C\uDE50\uDE53\uDE55\uDE56\uDE58\uDE5A\uDE5C\uDE5E\uDE60\uDE63\uDE65\uDE66\uDE6B\uDE73\uDE78\uDE7D\uDE7F\uDE8A\uDE9C-\uDEA0\uDEA4\uDEAA\uDEBC-\uDFFF]|\uD83C[\uDC00-\uDD2F\uDD4A-\uDD4F\uDD6A-\uDD6F\uDD8A-\uDFFF]|\uD83E[\uDC00-\uDFEF\uDFFA-\uDFFF]|\uD869[\uDEDE-\uDEFF]|\uD86D[\uDF35-\uDF3F]|\uD86E[\uDC1E\uDC1F]|\uD873[\uDEA2-\uDEAF]|\uD87A[\uDFE1-\uDFFF]|\uD87E[\uDE1E-\uDFFF]|\uD884[\uDF4B-\uDFFF]|\uDB40[\uDC00-\uDCFF\uDDF0-\uDFFF]/g; 2531 2532const own = Object.hasOwnProperty; 2533 2534/** 2535 * Slugger. 2536 */ 2537class BananaSlug { 2538 /** 2539 * Create a new slug class. 2540 */ 2541 constructor () { 2542 /** @type {Record<string, number>} */ 2543 // eslint-disable-next-line no-unused-expressions 2544 this.occurrences; 2545 2546 this.reset(); 2547 } 2548 2549 /** 2550 * Generate a unique slug. 2551 * 2552 * Tracks previously generated slugs: repeated calls with the same value 2553 * will result in different slugs. 2554 * Use the `slug` function to get same slugs. 2555 * 2556 * @param {string} value 2557 * String of text to slugify 2558 * @param {boolean} [maintainCase=false] 2559 * Keep the current case, otherwise make all lowercase 2560 * @return {string} 2561 * A unique slug string 2562 */ 2563 slug (value, maintainCase) { 2564 const self = this; 2565 let result = slug(value, maintainCase === true); 2566 const originalSlug = result; 2567 2568 while (own.call(self.occurrences, result)) { 2569 self.occurrences[originalSlug]++; 2570 result = originalSlug + '-' + self.occurrences[originalSlug]; 2571 } 2572 2573 self.occurrences[result] = 0; 2574 2575 return result 2576 } 2577 2578 /** 2579 * Reset - Forget all previous slugs 2580 * 2581 * @return void 2582 */ 2583 reset () { 2584 this.occurrences = Object.create(null); 2585 } 2586} 2587 2588/** 2589 * Generate a slug. 2590 * 2591 * Does not track previously generated slugs: repeated calls with the same value 2592 * will result in the exact same slug. 2593 * Use the `GithubSlugger` class to get unique slugs. 2594 * 2595 * @param {string} value 2596 * String of text to slugify 2597 * @param {boolean} [maintainCase=false] 2598 * Keep the current case, otherwise make all lowercase 2599 * @return {string} 2600 * A unique slug string 2601 */ 2602function slug (value, maintainCase) { 2603 if (typeof value !== 'string') return '' 2604 if (!maintainCase) value = value.toLowerCase(); 2605 return value.replace(regex, '').replace(/ /g, '-') 2606} 2607 2608let slugger$1 = new BananaSlug(); 2609 2610let headings = []; 2611 2612function gfmHeadingId({ prefix = '', globalSlugs = false } = {}) { 2613 return { 2614 headerIds: false, // prevent deprecation warning; remove this once headerIds option is removed 2615 hooks: { 2616 preprocess(src) { 2617 if (!globalSlugs) { 2618 resetHeadings(); 2619 } 2620 return src; 2621 } 2622 }, 2623 renderer: { 2624 heading(text, level, raw) { 2625 raw = raw 2626 .toLowerCase() 2627 .trim() 2628 .replace(/<[!\/a-z].*?>/gi, ''); 2629 const id = `${prefix}${slugger$1.slug(raw)}`; 2630 const heading = { level, text, id }; 2631 headings.push(heading); 2632 2633 return `<h${level} id="${id}">${text}</h${level}>\n`; 2634 } 2635 } 2636 }; 2637} 2638 2639function resetHeadings() { 2640 headings = []; 2641 slugger$1 = new BananaSlug(); 2642} 2643 2644(function (Prism) { 2645 var funcPattern = /\\(?:[^a-z()[\]]|[a-z*]+)/i; 2646 var insideEqu = { 2647 'equation-command': { 2648 pattern: funcPattern, 2649 alias: 'regex' 2650 } 2651 }; 2652 2653 Prism.languages.latex = { 2654 'comment': /%.*/, 2655 // the verbatim environment prints whitespace to the document 2656 'cdata': { 2657 pattern: /(\\begin\{((?:lstlisting|verbatim)\*?)\})[\s\S]*?(?=\\end\{\2\})/, 2658 lookbehind: true 2659 }, 2660 /* 2661 * equations can be between $$ $$ or $ $ or \( \) or \[ \] 2662 * (all are multiline) 2663 */ 2664 'equation': [ 2665 { 2666 pattern: /\$\$(?:\\[\s\S]|[^\\$])+\$\$|\$(?:\\[\s\S]|[^\\$])+\$|\\\([\s\S]*?\\\)|\\\[[\s\S]*?\\\]/, 2667 inside: insideEqu, 2668 alias: 'string' 2669 }, 2670 { 2671 pattern: /(\\begin\{((?:align|eqnarray|equation|gather|math|multline)\*?)\})[\s\S]*?(?=\\end\{\2\})/, 2672 lookbehind: true, 2673 inside: insideEqu, 2674 alias: 'string' 2675 } 2676 ], 2677 /* 2678 * arguments which are keywords or references are highlighted 2679 * as keywords 2680 */ 2681 'keyword': { 2682 pattern: /(\\(?:begin|cite|documentclass|end|label|ref|usepackage)(?:\[[^\]]+\])?\{)[^}]+(?=\})/, 2683 lookbehind: true 2684 }, 2685 'url': { 2686 pattern: /(\\url\{)[^}]+(?=\})/, 2687 lookbehind: true 2688 }, 2689 /* 2690 * section or chapter headlines are highlighted as bold so that 2691 * they stand out more 2692 */ 2693 'headline': { 2694 pattern: /(\\(?:chapter|frametitle|paragraph|part|section|subparagraph|subsection|subsubparagraph|subsubsection|subsubsubparagraph)\*?(?:\[[^\]]+\])?\{)[^}]+(?=\})/, 2695 lookbehind: true, 2696 alias: 'class-name' 2697 }, 2698 'function': { 2699 pattern: funcPattern, 2700 alias: 'selector' 2701 }, 2702 'punctuation': /[[\]{}&]/ 2703 }; 2704 2705 Prism.languages.tex = Prism.languages.latex; 2706 Prism.languages.context = Prism.languages.latex; 2707}(Prism)); 2708 2709(function (Prism) { 2710 // $ set | grep '^[A-Z][^[:space:]]*=' | cut -d= -f1 | tr '\n' '|' 2711 // + LC_ALL, RANDOM, REPLY, SECONDS. 2712 // + make sure PS1..4 are here as they are not always set, 2713 // - some useless things. 2714 var envVars = '\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_
2714CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b'; 2715 2716 var commandAfterHeredoc = { 2717 pattern: /(^(["']?)\w+\2)[ \t]+\S.*/, 2718 lookbehind: true, 2719 alias: 'punctuation', // this looks reasonably well in all themes 2720 inside: null // see below 2721 }; 2722 2723 var insideString = { 2724 'bash': commandAfterHeredoc, 2725 'environment': { 2726 pattern: RegExp('\\$' + envVars), 2727 alias: 'constant' 2728 }, 2729 'variable': [ 2730 // [0]: Arithmetic Environment 2731 { 2732 pattern: /\$?\(\([\s\S]+?\)\)/, 2733 greedy: true, 2734 inside: { 2735 // If there is a $ sign at the beginning highlight $(( and )) as variable 2736 'variable': [ 2737 { 2738 pattern: /(^\$\(\([\s\S]+)\)\)/, 2739 lookbehind: true 2740 }, 2741 /^\$\(\(/ 2742 ], 2743 'number': /\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/, 2744 // Operators according to https://www.gnu.org/software/bash/manual/bashref.html#Shell-Arithmetic 2745 'operator': /--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/, 2746 // If there is no $ sign at the beginning highlight (( and )) as punctuation 2747 'punctuation': /\(\(?|\)\)?|,|;/ 2748 } 2749 }, 2750 // [1]: Command Substitution 2751 { 2752 pattern: /\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/, 2753 greedy: true, 2754 inside: { 2755 'variable': /^\$\(|^`|\)$|`$/ 2756 } 2757 }, 2758 // [2]: Brace expansion 2759 { 2760 pattern: /\$\{[^}]+\}/, 2761 greedy: true, 2762 inside: { 2763 'operator': /:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/, 2764 'punctuation': /[\[\]]/, 2765 'environment': { 2766 pattern: RegExp('(\\{)' + envVars), 2767 lookbehind: true, 2768 alias: 'constant' 2769 } 2770 } 2771 }, 2772 /\$(?:\w+|[#?*!@$])/ 2773 ], 2774 // Escape sequences from echo and printf's manuals, and escaped quotes. 2775 'entity': /\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/ 2776 }; 2777 2778 Prism.languages.bash = { 2779 'shebang': { 2780 pattern: /^#!\s*\/.*/, 2781 alias: 'important' 2782 }, 2783 'comment': { 2784 pattern: /(^|[^"{\\$])#.*/, 2785 lookbehind: true 2786 }, 2787 'function-name': [ 2788 // a) function foo { 2789 // b) foo() { 2790 // c) function foo() { 2791 // but not âfoo {â 2792 { 2793 // a) and c) 2794 pattern: /(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/, 2795 lookbehind: true, 2796 alias: 'function' 2797 }, 2798 { 2799 // b) 2800 pattern: /\b[\w-]+(?=\s*\(\s*\)\s*\{)/, 2801 alias: 'function' 2802 } 2803 ], 2804 // Highlight variable names as variables in for and select beginnings. 2805 'for-or-select': { 2806 pattern: /(\b(?:for|select)\s+)\w+(?=\s+in\s)/, 2807 alias: 'variable', 2808 lookbehind: true 2809 }, 2810 // Highlight variable names as variables in the left-hand part 2811 // of assignments (â=â and â+=â). 2812 'assign-left': { 2813 pattern: /(^|[\s;|&]|[<>]\()\w+(?:\.\w+)*(?=\+?=)/, 2814 inside: { 2815 'environment': { 2816 pattern: RegExp('(^|[\\s;|&]|[<>]\\()' + envVars), 2817 lookbehind: true, 2818 alias: 'constant' 2819 } 2820 }, 2821 alias: 'variable', 2822 lookbehind: true 2823 }, 2824 // Highlight parameter names as variables 2825 'parameter': { 2826 pattern: /(^|\s)-{1,2}(?:\w+:[+-]?)?\w+(?:\.\w+)*(?=[=\s]|$)/, 2827 alias: 'variable', 2828 lookbehind: true 2829 }, 2830 'string': [ 2831 // Support for Here-documents https://en.wikipedia.org/wiki/Here_document 2832 { 2833 pattern: /((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/, 2834 lookbehind: true, 2835 greedy: true, 2836 inside: insideString 2837 }, 2838 // Here-document with quotes around the tag 2839 // â No expansion (so no âinsideâ). 2840 { 2841 pattern: /((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/, 2842 lookbehind: true, 2843 greedy: true, 2844 inside: { 2845 'bash': commandAfterHeredoc 2846 } 2847 }, 2848 // âNormalâ string 2849 { 2850 // https://www.gnu.org/software/bash/manual/html_node/Double-Quotes.html 2851 pattern: /(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/, 2852 lookbehind: true, 2853 greedy: true, 2854 inside: insideString 2855 }, 2856 { 2857 // https://www.gnu.org/software/bash/manual/html_node/Single-Quotes.html 2858 pattern: /(^|[^$\\])'[^']*'/, 2859 lookbehind: true, 2860 greedy: true 2861 }, 2862 { 2863 // https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html 2864 pattern: /\$'(?:[^'\\]|\\[\s\S])*'/, 2865 greedy: true, 2866 inside: { 2867 'entity': insideString.entity 2868 } 2869 } 2870 ], 2871 'environment': { 2872 pattern: RegExp('\\$?' + envVars), 2873 alias: 'constant' 2874 }, 2875 'variable': insideString.variable, 2876 'function': { 2877 pattern: /(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cargo|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|
2877ifup|import|install|ip|java|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|sysctl|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/, 2878 lookbehind: true 2879 }, 2880 'keyword': { 2881 pattern: /(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/, 2882 lookbehind: true 2883 }, 2884 // https://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html 2885 'builtin': { 2886 pattern: /(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/, 2887 lookbehind: true, 2888 // Alias added to make those easier to distinguish from strings. 2889 alias: 'class-name' 2890 }, 2891 'boolean': { 2892 pattern: /(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/, 2893 lookbehind: true 2894 }, 2895 'file-descriptor': { 2896 pattern: /\B&\d\b/, 2897 alias: 'important' 2898 }, 2899 'operator': { 2900 // Lots of redirections here, but not just that. 2901 pattern: /\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/, 2902 inside: { 2903 'file-descriptor': { 2904 pattern: /^\d/, 2905 alias: 'important' 2906 } 2907 } 2908 }, 2909 'punctuation': /\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/, 2910 'number': { 2911 pattern: /(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/, 2912 lookbehind: true 2913 } 2914 }; 2915 2916 commandAfterHeredoc.inside = Prism.languages.bash; 2917 2918 /* Patterns in command substitution. */ 2919 var toBeCopied = [ 2920 'comment', 2921 'function-name', 2922 'for-or-select', 2923 'assign-left', 2924 'parameter', 2925 'string', 2926 'environment', 2927 'function', 2928 'keyword', 2929 'builtin', 2930 'boolean', 2931 'file-descriptor', 2932 'operator', 2933 'punctuation', 2934 'number' 2935 ]; 2936 var inside = insideString.variable[1].inside; 2937 for (var i = 0; i < toBeCopied.length; i++) { 2938 inside[toBeCopied[i]] = Prism.languages.bash[toBeCopied[i]]; 2939 } 2940 2941 Prism.languages.sh = Prism.languages.bash; 2942 Prism.languages.shell = Prism.languages.bash; 2943}(Prism)); 2944 2945Prism.languages.c = Prism.languages.extend('clike', { 2946 'comment': { 2947 pattern: /\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/, 2948 greedy: true 2949 }, 2950 'string': { 2951 // https://en.cppreference.com/w/c/language/string_literal 2952 pattern: /"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/, 2953 greedy: true 2954 }, 2955 'class-name': { 2956 pattern: /(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/, 2957 lookbehind: true 2958 }, 2959 'keyword': /\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/, 2960 'function': /\b[a-z_]\w*(?=\s*\()/i, 2961 'number': /(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i, 2962 'operator': />>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/ 2963}); 2964 2965Prism.languages.insertBefore('c', 'string', { 2966 'char': { 2967 // https://en.cppreference.com/w/c/language/character_constant 2968 pattern: /'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/, 2969 greedy: true 2970 } 2971}); 2972 2973Prism.languages.insertBefore('c', 'string', { 2974 'macro': { 2975 // allow for multiline macro definitions 2976 // spaces after the # character compile fine with gcc 2977 pattern: /(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im, 2978 lookbehind: true, 2979 greedy: true, 2980 alias: 'property', 2981 inside: { 2982 'string': [ 2983 { 2984 // highlight the path of the include statement as a string 2985 pattern: /^(#\s*include\s*)<[^>]+>/, 2986 lookbehind: true 2987 }, 2988 Prism.languages.c['string'] 2989 ], 2990 'char': Prism.languages.c['char'], 2991 'comment': Prism.languages.c['comment'], 2992 'macro-name': [ 2993 { 2994 pattern: /(^#\s*define\s+)\w+\b(?!\()/i, 2995 lookbehind: true 2996 }, 2997 { 2998 pattern: /(^#\s*define\s+)\w+\b(?=\()/i, 2999 lookbehind: true,
3000 alias: 'function' 3001 } 3002 ], 3003 // highlight macro directives as keywords 3004 'directive': { 3005 pattern: /^(#\s*)[a-z]+/, 3006 lookbehind: true, 3007 alias: 'keyword' 3008 }, 3009 'directive-hash': /^#/, 3010 'punctuation': /##|\\(?=[\r\n])/, 3011 'expression': { 3012 pattern: /\S[\s\S]*/, 3013 inside: Prism.languages.c 3014 } 3015 } 3016 } 3017}); 3018 3019Prism.languages.insertBefore('c', 'function', { 3020 // highlight predefined macros as constants 3021 'constant': /\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/ 3022}); 3023 3024delete Prism.languages.c['boolean']; 3025 3026var prismCpp = {}; 3027 3028var hasRequiredPrismCpp; 3029 3030function requirePrismCpp () { 3031 if (hasRequiredPrismCpp) return prismCpp; 3032 hasRequiredPrismCpp = 1; 3033 (function (Prism) { 3034 3035 var keyword = /\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/; 3036 var modName = /\b(?!<keyword>)\w+(?:\s*\.\s*\w+)*\b/.source.replace(/<keyword>/g, function () { return keyword.source; }); 3037 3038 Prism.languages.cpp = Prism.languages.extend('c', { 3039 'class-name': [ 3040 { 3041 pattern: RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source 3042 .replace(/<keyword>/g, function () { return keyword.source; })), 3043 lookbehind: true 3044 }, 3045 // This is intended to capture the class name of method implementations like: 3046 // void foo::bar() const {} 3047 // However! The `foo` in the above example could also be a namespace, so we only capture the class name if 3048 // it starts with an uppercase letter. This approximation should give decent results. 3049 /\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/, 3050 // This will capture the class name before destructors like: 3051 // Foo::~Foo() {} 3052 /\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i, 3053 // This also intends to capture the class name of method implementations but here the class has template 3054 // parameters, so it can't be a namespace (until C++ adds generic namespaces). 3055 /\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/ 3056 ], 3057 'keyword': keyword, 3058 'number': { 3059 pattern: /(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i, 3060 greedy: true 3061 }, 3062 'operator': />>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/, 3063 'boolean': /\b(?:false|true)\b/ 3064 }); 3065 3066 Prism.languages.insertBefore('cpp', 'string', { 3067 'module': { 3068 // https://en.cppreference.com/w/cpp/language/modules 3069 pattern: RegExp( 3070 /(\b(?:import|module)\s+)/.source + 3071 '(?:' + 3072 // header-name 3073 /"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source + 3074 '|' + 3075 // module name or partition or both 3076 /<mod-name>(?:\s*:\s*<mod-name>)?|:\s*<mod-name>/.source.replace(/<mod-name>/g, function () { return modName; }) + 3077 ')' 3078 ), 3079 lookbehind: true, 3080 greedy: true, 3081 inside: { 3082 'string': /^[<"][\s\S]+/, 3083 'operator': /:/, 3084 'punctuation': /\./ 3085 } 3086 }, 3087 'raw-string': { 3088 pattern: /R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/, 3089 alias: 'string', 3090 greedy: true 3091 } 3092 }); 3093 3094 Prism.languages.insertBefore('cpp', 'keyword', { 3095 'generic-function': { 3096 pattern: /\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i, 3097 inside: { 3098 'function': /^\w+/, 3099 'generic': { 3100 pattern: /<[\s\S]+/, 3101 alias: 'class-name', 3102 inside: Prism.languages.cpp 3103 } 3104 } 3105 } 3106 }); 3107 3108 Prism.languages.insertBefore('cpp', 'operator', { 3109 'double-colon': { 3110 pattern: /::/, 3111 alias: 'punctuation' 3112 } 3113 }); 3114 3115 Prism.languages.insertBefore('cpp', 'class-name', { 3116 // the base clause is an optional list of parent classes 3117 // https://en.cppreference.com/w/cpp/language/class 3118 'base-clause': { 3119 pattern: /(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/, 3120 lookbehind: true, 3121 greedy: true, 3122 inside: Prism.languages.extend('cpp', {}) 3123 } 3124 }); 3125 3126 Prism.languages.insertBefore('inside', 'double-colon', { 3127 // All untokenized words that are not namespaces should be class names 3128 'class-name': /\b[a-z_]\w*\b(?!\s*::)/i 3129 }, Prism.languages.cpp['base-clause']); 3130 3131 }(Prism)); 3132 return prismCpp; 3133} 3134 3135requirePrismCpp(); 3136 3137// https://www.json.org/json-en.html 3138Prism.languages.json = { 3139 'property': { 3140 pattern: /(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/, 3141 lookbehind: true, 3142 greedy: true 3143 }, 3144 'string': { 3145 pattern: /(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/, 3146 lookbehind: true, 3147 greedy: true 3148 }, 3149 'comment': { 3150 pattern: /\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/, 3151 greedy: true 3152 }, 3153 'number': /-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i, 3154 'punctuation': /[{}[\],]/, 3155 'operator': /:/, 3156 'boolean': /\b(?:false|true)\b/, 3157 'null': { 3158 pattern: /\bnull\b/, 3159 alias: 'keyword' 3160 } 3161}; 3162 3163Prism.languages.webmanifest = Prism.languages.json; 3164 3165Prism.languages.sql = { 3166 'comment': { 3167 pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/, 3168 lookbehind: true 3169 }, 3170 'variable': [ 3171 { 3172 pattern: /@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/, 3173 greedy: true 3174 }, 3175 /@[\w.$]+/ 3176 ], 3177 'string': { 3178 pattern: /(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/, 3179 greedy: true, 3180 lookbehind: true 3181 }, 3182 'identifier': { 3183 pattern: /(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/, 3184 greedy: true, 3185 lookbehind: true, 3186 inside: { 3187 'punctuation': /^`|`$/ 3188 } 3189 }, 3190 'function': /\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i, // Should we highlight user defined functions too? 3191 'keyword': /\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CA
3191SE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i, 3192 'boolean': /\b(?:FALSE|NULL|TRUE)\b/i, 3193 'number': /\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i, 3194 'operator': /[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i, 3195 'punctuation': /[;[\]()`,.]/ 3196}; 3197 3198var prismJava = {}; 3199 3200var hasRequiredPrismJava; 3201 3202function requirePrismJava () { 3203 if (hasRequiredPrismJava) return prismJava; 3204 hasRequiredPrismJava = 1; 3205 (function (Prism) { 3206 3207 var keywords = /\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/; 3208 3209 // full package (optional) + parent classes (optional) 3210 var classNamePrefix = /(?:[a-z]\w*\s*\.\s*)*(?:[A-Z]\w*\s*\.\s*)*/.source; 3211 3212 // based on the java naming conventions 3213 var className = { 3214 pattern: RegExp(/(^|[^\w.])/.source + classNamePrefix + /[A-Z](?:[\d_A-Z]*[a-z]\w*)?\b/.source), 3215 lookbehind: true, 3216 inside: { 3217 'namespace': { 3218 pattern: /^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/, 3219 inside: { 3220 'punctuation': /\./ 3221 } 3222 }, 3223 'punctuation': /\./ 3224 } 3225 }; 3226 3227 Prism.languages.java = Prism.languages.extend('clike', { 3228 'string': { 3229 pattern: /(^|[^\\])"(?:\\.|[^"\\\r\n])*"/, 3230 lookbehind: true, 3231 greedy: true 3232 }, 3233 'class-name': [ 3234 className, 3235 { 3236 // variables, parameters, and constructor references 3237 // this to support class names (or generic parameters) which do not contain a lower case letter (also works for methods) 3238 pattern: RegExp(/(^|[^\w.])/.source + classNamePrefix + /[A-Z]\w*(?
3238=\s+\w+\s*[;,=()]|\s*(?:\[[\s,]*\]\s*)?::\s*new\b)/.source), 3239 lookbehind: true, 3240 inside: className.inside 3241 }, 3242 { 3243 // class names based on keyword 3244 // this to support class names (or generic parameters) which do not contain a lower case letter (also works for methods) 3245 pattern: RegExp(/(\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\s+)/.source + classNamePrefix + /[A-Z]\w*\b/.source), 3246 lookbehind: true, 3247 inside: className.inside 3248 } 3249 ], 3250 'keyword': keywords, 3251 'function': [ 3252 Prism.languages.clike.function, 3253 { 3254 pattern: /(::\s*)[a-z_]\w*/, 3255 lookbehind: true 3256 } 3257 ], 3258 'number': /\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i, 3259 'operator': { 3260 pattern: /(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m, 3261 lookbehind: true 3262 }, 3263 'constant': /\b[A-Z][A-Z_\d]+\b/ 3264 }); 3265 3266 Prism.languages.insertBefore('java', 'string', { 3267 'triple-quoted-string': { 3268 // http://openjdk.java.net/jeps/355#Description 3269 pattern: /"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/, 3270 greedy: true, 3271 alias: 'string' 3272 }, 3273 'char': { 3274 pattern: /'(?:\\.|[^'\\\r\n]){1,6}'/, 3275 greedy: true 3276 } 3277 }); 3278 3279 Prism.languages.insertBefore('java', 'class-name', { 3280 'annotation': { 3281 pattern: /(^|[^.])@\w+(?:\s*\.\s*\w+)*/, 3282 lookbehind: true, 3283 alias: 'punctuation' 3284 }, 3285 'generics': { 3286 pattern: /<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/, 3287 inside: { 3288 'class-name': className, 3289 'keyword': keywords, 3290 'punctuation': /[<>(),.:]/, 3291 'operator': /[?&|]/ 3292 } 3293 }, 3294 'import': [ 3295 { 3296 pattern: RegExp(/(\bimport\s+)/.source + classNamePrefix + /(?:[A-Z]\w*|\*)(?=\s*;)/.source), 3297 lookbehind: true, 3298 inside: { 3299 'namespace': className.inside.namespace, 3300 'punctuation': /\./, 3301 'operator': /\*/, 3302 'class-name': /\w+/ 3303 } 3304 }, 3305 { 3306 pattern: RegExp(/(\bimport\s+static\s+)/.source + classNamePrefix + /(?:\w+|\*)(?=\s*;)/.source), 3307 lookbehind: true, 3308 alias: 'static', 3309 inside: { 3310 'namespace': className.inside.namespace, 3311 'static': /\b\w+$/, 3312 'punctuation': /\./, 3313 'operator': /\*/, 3314 'class-name': /\w+/ 3315 } 3316 } 3317 ], 3318 'namespace': { 3319 pattern: RegExp( 3320 /(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!<keyword>)[a-z]\w*(?:\.[a-z]\w*)*\.?/ 3321 .source.replace(/<keyword>/g, function () { return keywords.source; })), 3322 lookbehind: true, 3323 inside: { 3324 'punctuation': /\./, 3325 } 3326 } 3327 }); 3328 }(Prism)); 3329 return prismJava; 3330} 3331 3332requirePrismJava(); 3333 3334Prism.languages.go = Prism.languages.extend('clike', { 3335 'string': { 3336 pattern: /(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/, 3337 lookbehind: true, 3338 greedy: true 3339 }, 3340 'keyword': /\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/, 3341 'boolean': /\b(?:_|false|iota|nil|true)\b/, 3342 'number': [ 3343 // binary and octal integers 3344 /\b0(?:b[01_]+|o[0-7_]+)i?\b/i, 3345 // hexadecimal integers and floats 3346 /\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i, 3347 // decimal integers and floats 3348 /(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i 3349 ], 3350 'operator': /[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./, 3351 'builtin': /\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/ 3352}); 3353 3354Prism.languages.insertBefore('go', 'string', { 3355 'char': { 3356 pattern: /'(?:\\.|[^'\\\r\n]){0,10}'/, 3357 greedy: true 3358 } 3359}); 3360 3361delete Prism.languages.go['class-name']; 3362 3363var prismRust = {}; 3364 3365var hasRequiredPrismRust; 3366 3367function requirePrismRust () { 3368 if (hasRequiredPrismRust) return prismRust; 3369 hasRequiredPrismRust = 1; 3370 (function (Prism) { 3371 3372 var multilineComment = /\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|<self>)*\*\//.source; 3373 for (var i = 0; i < 2; i++) { 3374 // support 4 levels of nested comments 3375 multilineComment = multilineComment.replace(/<self>/g, function () { return multilineComment; }); 3376 } 3377 multilineComment = multilineComment.replace(/<self>/g, function () { return /[^\s\S]/.source; }); 3378 3379 3380 Prism.languages.rust = { 3381 'comment': [ 3382 { 3383 pattern: RegExp(/(^|[^\\])/.source + multilineComment), 3384 lookbehind: true, 3385 greedy: true 3386 }, 3387 { 3388 pattern: /(^|[^\\:])\/\/.*/, 3389 lookbehind: true, 3390 greedy: true 3391 } 3392 ], 3393 'string': {
3394 pattern: /b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/, 3395 greedy: true 3396 }, 3397 'char': { 3398 pattern: /b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/, 3399 greedy: true 3400 }, 3401 'attribute': { 3402 pattern: /#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/, 3403 greedy: true, 3404 alias: 'attr-name', 3405 inside: { 3406 'string': null // see below 3407 } 3408 }, 3409 3410 // Closure params should not be confused with bitwise OR | 3411 'closure-params': { 3412 pattern: /([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/, 3413 lookbehind: true, 3414 greedy: true, 3415 inside: { 3416 'closure-punctuation': { 3417 pattern: /^\||\|$/, 3418 alias: 'punctuation' 3419 }, 3420 rest: null // see below 3421 } 3422 }, 3423 3424 'lifetime-annotation': { 3425 pattern: /'\w+/, 3426 alias: 'symbol' 3427 }, 3428 3429 'fragment-specifier': { 3430 pattern: /(\$\w+:)[a-z]+/, 3431 lookbehind: true, 3432 alias: 'punctuation' 3433 }, 3434 'variable': /\$\w+/, 3435 3436 'function-definition': { 3437 pattern: /(\bfn\s+)\w+/, 3438 lookbehind: true, 3439 alias: 'function' 3440 }, 3441 'type-definition': { 3442 pattern: /(\b(?:enum|struct|trait|type|union)\s+)\w+/, 3443 lookbehind: true, 3444 alias: 'class-name' 3445 }, 3446 'module-declaration': [ 3447 { 3448 pattern: /(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/, 3449 lookbehind: true, 3450 alias: 'namespace' 3451 }, 3452 { 3453 pattern: /(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/, 3454 lookbehind: true, 3455 alias: 'namespace', 3456 inside: { 3457 'punctuation': /::/ 3458 } 3459 } 3460 ], 3461 'keyword': [ 3462 // https://github.com/rust-lang/reference/blob/master/src/keywords.md 3463 /\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/, 3464 // primitives and str 3465 // https://doc.rust-lang.org/stable/rust-by-example/primitives.html 3466 /\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/ 3467 ], 3468 3469 // functions can technically start with an upper-case letter, but this will introduce a lot of false positives 3470 // and Rust's naming conventions recommend snake_case anyway. 3471 // https://doc.rust-lang.org/1.0.0/style/style/naming/README.html 3472 'function': /\b[a-z_]\w*(?=\s*(?:::\s*<|\())/, 3473 'macro': { 3474 pattern: /\b\w+!/, 3475 alias: 'property' 3476 }, 3477 'constant': /\b[A-Z_][A-Z_\d]+\b/, 3478 'class-name': /\b[A-Z]\w*\b/, 3479 3480 'namespace': { 3481 pattern: /(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/, 3482 inside: { 3483 'punctuation': /::/ 3484 } 3485 }, 3486 3487 // Hex, oct, bin, dec numbers with visual separators and type suffix 3488 'number': /\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/, 3489 'boolean': /\b(?:false|true)\b/, 3490 'punctuation': /->|\.\.=|\.{1,3}|::|[{}[\];(),:]/, 3491 'operator': /[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<<?=?|>>?=?|[@?]/ 3492 }; 3493 3494 Prism.languages.rust['closure-params'].inside.rest = Prism.languages.rust; 3495 Prism.languages.rust['attribute'].inside['string'] = Prism.languages.rust['string']; 3496 3497 }(Prism)); 3498 return prismRust; 3499} 3500 3501requirePrismRust(); 3502 3503var prismPhp = {}; 3504 3505/** 3506 * Original by Aaron Harun: http://aahacreative.com/2012/07/31/php-syntax-highlighting-prism/ 3507 * Modified by Miles Johnson: http://milesj.me 3508 * Rewritten by Tom Pavelec 3509 * 3510 * Supports PHP 5.3 - 8.0 3511 */ 3512 3513var hasRequiredPrismPhp; 3514 3515function requirePrismPhp () { 3516 if (hasRequiredPrismPhp) return prismPhp; 3517 hasRequiredPrismPhp = 1; 3518 (function (Prism) { 3519 var comment = /\/\*[\s\S]*?\*\/|\/\/.*|#(?!\[).*/; 3520 var constant = [ 3521 { 3522 pattern: /\b(?:false|true)\b/i, 3523 alias: 'boolean' 3524 }, 3525 { 3526 pattern: /(::\s*)\b[a-z_]\w*\b(?!\s*\()/i, 3527 greedy: true, 3528 lookbehind: true, 3529 }, 3530 { 3531 pattern: /(\b(?:case|const)\s+)\b[a-z_]\w*(?=\s*[;=])/i, 3532 greedy: true, 3533 lookbehind: true, 3534 }, 3535 /\b(?:null)\b/i, 3536 /\b[A-Z_][A-Z0-9_]*\b(?!\s*\()/, 3537 ]; 3538 var number = /\b0b[01]+(?:_[01]+)*\b|\b0o[0-7]+(?:_[0-7]+)*\b|\b0x[\da-f]+(?:_[\da-f]+)*\b|(?:\b\d+(?:_\d+)*\.?(?:\d+(?:_\d+)*)?|\B\.\d+)(?:e[+-]?\d+)?/i; 3539 var operator = /<?=>|\?\?=?|\.{3}|\??->|[!=]=?=?|::|\*\*=?|--|\+\+|&&|\|\||<<|>>|[?~]|[/^|%*&<>.+-]=?/; 3540 var punctuation = /[{}\[\](),:;]/; 3541 3542 Prism.languages.php = { 3543 'delimiter': { 3544 pattern: /\?>$|^<\?(?:php(?=\s)|=)?/i,
vendor: 4,123 bytes, lines 3545-3681
3545 alias: 'important' 3546 }, 3547 'comment': comment, 3548 'variable': /\$+(?:\w+\b|(?=\{))/, 3549 'package': { 3550 pattern: /(namespace\s+|use\s+(?:function\s+)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i, 3551 lookbehind: true, 3552 inside: { 3553 'punctuation': /\\/ 3554 } 3555 }, 3556 'class-name-definition': { 3557 pattern: /(\b(?:class|enum|interface|trait)\s+)\b[a-z_]\w*(?!\\)\b/i, 3558 lookbehind: true, 3559 alias: 'class-name' 3560 }, 3561 'function-definition': { 3562 pattern: /(\bfunction\s+)[a-z_]\w*(?=\s*\()/i, 3563 lookbehind: true, 3564 alias: 'function' 3565 }, 3566 'keyword': [ 3567 { 3568 pattern: /(\(\s*)\b(?:array|bool|boolean|float|int|integer|object|string)\b(?=\s*\))/i, 3569 alias: 'type-casting', 3570 greedy: true, 3571 lookbehind: true 3572 }, 3573 { 3574 pattern: /([(,?]\s*)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|object|self|static|string)\b(?=\s*\$)/i, 3575 alias: 'type-hint', 3576 greedy: true, 3577 lookbehind: true 3578 }, 3579 { 3580 pattern: /(\)\s*:\s*(?:\?\s*)?)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|never|object|self|static|string|void)\b/i, 3581 alias: 'return-type', 3582 greedy: true, 3583 lookbehind: true 3584 }, 3585 { 3586 pattern: /\b(?:array(?!\s*\()|bool|float|int|iterable|mixed|object|string|void)\b/i, 3587 alias: 'type-declaration', 3588 greedy: true 3589 }, 3590 { 3591 pattern: /(\|\s*)(?:false|null)\b|\b(?:false|null)(?=\s*\|)/i, 3592 alias: 'type-declaration', 3593 greedy: true, 3594 lookbehind: true 3595 }, 3596 { 3597 pattern: /\b(?:parent|self|static)(?=\s*::)/i, 3598 alias: 'static-context', 3599 greedy: true 3600 }, 3601 { 3602 // yield from 3603 pattern: /(\byield\s+)from\b/i, 3604 lookbehind: true 3605 }, 3606 // `class` is always a keyword unlike other keywords 3607 /\bclass\b/i, 3608 { 3609 // https://www.php.net/manual/en/reserved.keywords.php 3610 // 3611 // keywords cannot be preceded by "->" 3612 // the complex lookbehind means `(?<!(?:->|::)\s*)` 3613 pattern: /((?:^|[^\s>:]|(?:^|[^-])>|(?:^|[^:]):)\s*)\b(?:abstract|and|array|as|break|callable|case|catch|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|enum|eval|exit|extends|final|finally|fn|for|foreach|function|global|goto|if|implements|include|include_once|instanceof|insteadof|interface|isset|list|match|namespace|never|new|or|parent|print|private|protected|public|readonly|require|require_once|return|self|static|switch|throw|trait|try|unset|use|var|while|xor|yield|__halt_compiler)\b/i, 3614 lookbehind: true 3615 } 3616 ], 3617 'argument-name': { 3618 pattern: /([(,]\s*)\b[a-z_]\w*(?=\s*:(?!:))/i, 3619 lookbehind: true 3620 }, 3621 'class-name': [ 3622 { 3623 pattern: /(\b(?:extends|implements|instanceof|new(?!\s+self|\s+static))\s+|\bcatch\s*\()\b[a-z_]\w*(?!\\)\b/i, 3624 greedy: true, 3625 lookbehind: true 3626 }, 3627 { 3628 pattern: /(\|\s*)\b[a-z_]\w*(?!\\)\b/i, 3629 greedy: true, 3630 lookbehind: true 3631 }, 3632 { 3633 pattern: /\b[a-z_]\w*(?!\\)\b(?=\s*\|)/i, 3634 greedy: true 3635 }, 3636 { 3637 pattern: /(\|\s*)(?:\\?\b[a-z_]\w*)+\b/i, 3638 alias: 'class-name-fully-qualified', 3639 greedy: true, 3640 lookbehind: true, 3641 inside: { 3642 'punctuation': /\\/ 3643 } 3644 }, 3645 { 3646 pattern: /(?:\\?\b[a-z_]\w*)+\b(?=\s*\|)/i, 3647 alias: 'class-name-fully-qualified', 3648 greedy: true, 3649 inside: { 3650 'punctuation': /\\/ 3651 } 3652 }, 3653 { 3654 pattern: /(\b(?:extends|implements|instanceof|new(?!\s+self\b|\s+static\b))\s+|\bcatch\s*\()(?:\\?\b[a-z_]\w*)+\b(?!\\)/i, 3655 alias: 'class-name-fully-qualified', 3656 greedy: true, 3657 lookbehind: true, 3658 inside: { 3659 'punctuation': /\\/ 3660 } 3661 }, 3662 { 3663 pattern: /\b[a-z_]\w*(?=\s*\$)/i, 3664 alias: 'type-declaration', 3665 greedy: true 3666 }, 3667 { 3668 pattern: /(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i, 3669 alias: ['class-name-fully-qualified', 'type-declaration'], 3670 greedy: true, 3671 inside: { 3672 'punctuation': /\\/ 3673 } 3674 }, 3675 { 3676 pattern: /\b[a-z_]\w*(?=\s*::)/i, 3677 alias: 'static-context', 3678 greedy: true 3679 }, 3680 { 3681 pattern: /(?:\\?\b[a-z_]\w*)+(?=\s*::)/i,
3682 alias: ['class-name-fully-qualified', 'static-context'], 3683 greedy: true, 3684 inside: { 3685 'punctuation': /\\/ 3686 } 3687 }, 3688 { 3689 pattern: /([(,?]\s*)[a-z_]\w*(?=\s*\$)/i, 3690 alias: 'type-hint', 3691 greedy: true, 3692 lookbehind: true 3693 }, 3694 { 3695 pattern: /([(,?]\s*)(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i, 3696 alias: ['class-name-fully-qualified', 'type-hint'], 3697 greedy: true, 3698 lookbehind: true, 3699 inside: { 3700 'punctuation': /\\/ 3701 } 3702 }, 3703 { 3704 pattern: /(\)\s*:\s*(?:\?\s*)?)\b[a-z_]\w*(?!\\)\b/i, 3705 alias: 'return-type', 3706 greedy: true, 3707 lookbehind: true 3708 }, 3709 { 3710 pattern: /(\)\s*:\s*(?:\?\s*)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i, 3711 alias: ['class-name-fully-qualified', 'return-type'], 3712 greedy: true, 3713 lookbehind: true, 3714 inside: { 3715 'punctuation': /\\/ 3716 } 3717 } 3718 ], 3719 'constant': constant, 3720 'function': { 3721 pattern: /(^|[^\\\w])\\?[a-z_](?:[\w\\]*\w)?(?=\s*\()/i, 3722 lookbehind: true, 3723 inside: { 3724 'punctuation': /\\/ 3725 } 3726 }, 3727 'property': { 3728 pattern: /(->\s*)\w+/, 3729 lookbehind: true 3730 }, 3731 'number': number, 3732 'operator': operator, 3733 'punctuation': punctuation 3734 }; 3735 3736 var string_interpolation = { 3737 pattern: /\{\$(?:\{(?:\{[^{}]+\}|[^{}]+)\}|[^{}])+\}|(^|[^\\{])\$+(?:\w+(?:\[[^\r\n\[\]]+\]|->\w+)?)/, 3738 lookbehind: true, 3739 inside: Prism.languages.php 3740 }; 3741 3742 var string = [ 3743 { 3744 pattern: /<<<'([^']+)'[\r\n](?:.*[\r\n])*?\1;/, 3745 alias: 'nowdoc-string', 3746 greedy: true, 3747 inside: { 3748 'delimiter': { 3749 pattern: /^<<<'[^']+'|[a-z_]\w*;$/i, 3750 alias: 'symbol', 3751 inside: { 3752 'punctuation': /^<<<'?|[';]$/ 3753 } 3754 } 3755 } 3756 }, 3757 { 3758 pattern: /<<<(?:"([^"]+)"[\r\n](?:.*[\r\n])*?\1;|([a-z_]\w*)[\r\n](?:.*[\r\n])*?\2;)/i, 3759 alias: 'heredoc-string', 3760 greedy: true, 3761 inside: { 3762 'delimiter': { 3763 pattern: /^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i, 3764 alias: 'symbol', 3765 inside: { 3766 'punctuation': /^<<<"?|[";]$/ 3767 } 3768 }, 3769 'interpolation': string_interpolation 3770 } 3771 }, 3772 { 3773 pattern: /`(?:\\[\s\S]|[^\\`])*`/, 3774 alias: 'backtick-quoted-string', 3775 greedy: true 3776 }, 3777 { 3778 pattern: /'(?:\\[\s\S]|[^\\'])*'/, 3779 alias: 'single-quoted-string', 3780 greedy: true 3781 }, 3782 { 3783 pattern: /"(?:\\[\s\S]|[^\\"])*"/, 3784 alias: 'double-quoted-string', 3785 greedy: true, 3786 inside: { 3787 'interpolation': string_interpolation 3788 } 3789 } 3790 ]; 3791 3792 Prism.languages.insertBefore('php', 'variable', { 3793 'string': string, 3794 'attribute': { 3795 pattern: /#\[(?:[^"'\/#]|\/(?![*/])|\/\/.*$|#(?!\[).*$|\/\*(?:[^*]|\*(?!\/))*\*\/|"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*')+\](?=\s*[a-z$#])/im, 3796 greedy: true, 3797 inside: { 3798 'attribute-content': { 3799 pattern: /^(#\[)[\s\S]+(?=\]$)/, 3800 lookbehind: true, 3801 // inside can appear subset of php 3802 inside: { 3803 'comment': comment, 3804 'string': string, 3805 'attribute-class-name': [ 3806 { 3807 pattern: /([^:]|^)\b[a-z_]\w*(?!\\)\b/i, 3808 alias: 'class-name', 3809 greedy: true, 3810 lookbehind: true 3811 }, 3812 { 3813 pattern: /([^:]|^)(?:\\?\b[a-z_]\w*)+/i, 3814 alias: [ 3815 'class-name', 3816 'class-name-fully-qualified' 3817 ], 3818 greedy: true, 3819 lookbehind: true, 3820 inside: { 3821 'punctuation': /\\/ 3822 } 3823 } 3824 ], 3825 'constant': constant, 3826 'number': number, 3827 'operator': operator, 3828 'punctuation': punctuation 3829 } 3830 }, 3831 'delimiter': { 3832 pattern: /^#\[|\]$/, 3833 alias: 'punctuation' 3834 } 3835 } 3836 }, 3837 }); 3838 3839 Prism.hooks.add('before-tokenize', function (env) { 3840 if (!/<\?/.test(env.code)) { 3841 return; 3842 } 3843 3844 var phpPattern = /<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#(?!\[))(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|#\[|\/\*(?:[^*]|\*(?!\/))*(?:\*\/|$))*?(?:\?>|$)/g; 3845 Prism.languages['markup-templating'].buildPlaceholders(env, 'php', phpPattern); 3846 }); 3847 3848 Prism.hooks.add('after-tokenize', function (env) { 3849 Prism.languages['markup-templating'].tokenizePlaceholders(env, 'php'); 3850 }); 3851 3852 }(Prism)); 3853 return prismPhp; 3854} 3855 3856requirePrismPhp(); 3857 3858(function (Prism) { 3859 3860 // https://yaml.org/spec/1.2/spec.html#c-ns-anchor-property 3861 // https://yaml.org/spec/1.2/spec.html#c-ns-alias-node 3862 var anchorOrAlias = /[*&][^\s[\]{},]+/; 3863 // https://yaml.org/spec/1.2/spec.html#c-ns-tag-property 3864 var tag = /!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/; 3865 // https://yaml.org/spec/1.2/spec.html#c-ns-properties(n,c) 3866 var properties = '(?:' + tag.source + '(?:[ \t]+' + anchorOrAlias.source + ')?|' 3867 + anchorOrAlias.source + '(?:[ \t]+' + tag.source + ')?)'; 3868 // https://yaml.org/spec/1.2/spec.html#ns-plain(n,c) 3869 // This is a simplified version that doesn't support "#" and multiline keys 3870 // All these long scarry character classes are simplified versions of YAML's characters 3871 var plainKey = /(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-]<PLAIN>)(?:[ \t]*(?:(?![#:])<PLAIN>|:<PLAIN>))*/.source 3872 .replace(/<PLAIN>/g, function () { return /[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source; }); 3873 var string = /"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source; 3874 3875 /** 3876 * 3877 * @param {string} value 3878 * @param {string} [flags] 3879 * @returns {RegExp} 3880 */ 3881 function createValuePattern(value, flags) { 3882 flags = (flags || '').replace(/m/g, '') + 'm'; // add m flag 3883 var pattern = /([:\-,[{]\s*(?:\s<<prop>>[ \t]+)?)(?:<<value>>
3883)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source 3884 .replace(/<<prop>>/g, function () { return properties; }).replace(/<<value>>/g, function () { return value; }); 3885 return RegExp(pattern, flags); 3886 } 3887 3888 Prism.languages.yaml = { 3889 'scalar': { 3890 pattern: RegExp(/([\-:]\s*(?:\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source 3891 .replace(/<<prop>>/g, function () { return properties; })), 3892 lookbehind: true, 3893 alias: 'string' 3894 }, 3895 'comment': /#.*/, 3896 'key': { 3897 pattern: RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)<<key>>(?=\s*:\s)/.source 3898 .replace(/<<prop>>/g, function () { return properties; }) 3899 .replace(/<<key>>/g, function () { return '(?:' + plainKey + '|' + string + ')'; })), 3900 lookbehind: true, 3901 greedy: true, 3902 alias: 'atrule' 3903 }, 3904 'directive': { 3905 pattern: /(^[ \t]*)%.+/m, 3906 lookbehind: true, 3907 alias: 'important' 3908 }, 3909 'datetime': { 3910 pattern: createValuePattern(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source), 3911 lookbehind: true, 3912 alias: 'number' 3913 }, 3914 'boolean': { 3915 pattern: createValuePattern(/false|true/.source, 'i'), 3916 lookbehind: true, 3917 alias: 'important' 3918 }, 3919 'null': { 3920 pattern: createValuePattern(/null|~/.source, 'i'), 3921 lookbehind: true, 3922 alias: 'important' 3923 }, 3924 'string': { 3925 pattern: createValuePattern(string), 3926 lookbehind: true, 3927 greedy: true 3928 }, 3929 'number': { 3930 pattern: createValuePattern(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source, 'i'), 3931 lookbehind: true 3932 }, 3933 'tag': tag, 3934 'important': anchorOrAlias, 3935 'punctuation': /---|[:[\]{}\-,|>?]|\.\.\./ 3936 }; 3937 3938 Prism.languages.yml = Prism.languages.yaml; 3939 3940}(Prism)); 3941 3942(function (Prism) { 3943 3944 /** 3945 * Returns the placeholder for the given language id and index. 3946 * 3947 * @param {string} language 3948 * @param {string|number} index 3949 * @returns {string} 3950 */ 3951 function getPlaceholder(language, index) { 3952 return '___' + language.toUpperCase() + index + '___'; 3953 } 3954 3955 Object.defineProperties(Prism.languages['markup-templating'] = {}, { 3956 buildPlaceholders: { 3957 /** 3958 * Tokenize all inline templating expressions matching `placeholderPattern`. 3959 * 3960 * If `replaceFilter` is provided, only matches of `placeholderPattern` for which `replaceFilter` returns 3961 * `true` will be replaced. 3962 * 3963 * @param {object} env The environment of the `before-tokenize` hook. 3964 * @param {string} language The language id. 3965 * @param {RegExp} placeholderPattern The matches of this pattern will be replaced by placeholders. 3966 * @param {(match: string) => boolean} [replaceFilter] 3967 */ 3968 value: function (env, language, placeholderPattern, replaceFilter) { 3969 if (env.language !== language) { 3970 return; 3971 } 3972 3973 var tokenStack = env.tokenStack = []; 3974 3975 env.code = env.code.replace(placeholderPattern, function (match) { 3976 if (typeof replaceFilter === 'function' && !replaceFilter(match)) { 3977 return match; 3978 } 3979 var i = tokenStack.length; 3980 var placeholder; 3981 3982 // Check for existing strings 3983 while (env.code.indexOf(placeholder = getPlaceholder(language, i)) !== -1) { 3984 ++i; 3985 } 3986 3987 // Create a sparse array 3988 tokenStack[i] = match; 3989 3990 return placeholder; 3991 }); 3992 3993 // Switch the grammar to markup 3994 env.grammar = Prism.languages.markup; 3995 } 3996 }, 3997 tokenizePlaceholders: { 3998 /** 3999 * Replace placeholders with proper tokens after tokenizing. 4000 * 4001 * @param {object} env The environment of the `after-tokenize` hook. 4002 * @param {string} language The language id. 4003 */ 4004 value: function (env, language) { 4005 if (env.language !== language || !env.tokenStack) { 4006 return; 4007 } 4008 4009 // Switch the grammar back 4010 env.grammar = Prism.languages[language]; 4011 4012 var j = 0; 4013 var keys = Object.keys(env.tokenStack); 4014 4015 function walkTokens(tokens) { 4016 for (var i = 0; i < tokens.length; i++) { 4017 // all placeholders are replaced already 4018 if (j >= keys.length) { 4019 break; 4020 } 4021 4022 var token = tokens[i]; 4023 if (typeof token === 'string' || (token.content && typeof token.content === 'string')) { 4024 var k = keys[j]; 4025 var t = env.tokenStack[k]; 4026 var s = typeof token === 'string' ? token : token.content; 4027 var placeholder = getPlaceholder(language, k); 4028 4029 var index = s.indexOf(placeholder); 4030 if (index > -1) { 4031 ++j; 4032 4033 var before = s.substring(0, index); 4034 var middle = new Prism.Token(language, Prism.tokenize(t, env.grammar), 'language-' + language, t); 4035 var after = s.substring(index + placeholder.length); 4036 4037 var replacement = []; 4038 if (before) { 4039 replacement.push.apply(replacement, walkTokens([before])); 4040 } 4041 replacement.push(middle); 4042 if (after) { 4043 replacement.push.apply(replacement, walkTokens([after])); 4044 } 4045 4046 if (typeof token === 'string') { 4047 tokens.splice.apply(tokens, [i, 1].concat(replacement)); 4048 } else { 4049 token.content = replacement; 4050 } 4051 } 4052 } else if (token.content /* && typeof token.content !== 'string' */) { 4053 walkTokens(token.content); 4054 } 4055 } 4056 4057 return tokens; 4058 } 4059 4060 walkTokens(env.tokens); 4061 } 4062 } 4063 }); 4064 4065}(Prism)); 4066
4067const LINK_ICON_CODE = `<svg class="md-link-icon" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true" fill="currentColor"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg>`; 4068const COPY_ICON_CODE = ` 4069<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15 15" color="currentColor" aria-hidden="true" aria-label="Copy" stroke-width="1.3" width="15" height="15"> 4070 <path fill="currentColor" d="M12.728 4.545v8.182H4.545V4.545zm0 -0.909H4.545a0.909 0.909 0 0 0 -0.909 0.909v8.182a0.909 0.909 0 0 0 0.909 0.909h8.182a0.909 0.909 0 0 0 0.909 -0.909V4.545a0.909 0.909 0 0 0 -0.909 -0.909"/> 4071 <path fill="currentColor" d="M1.818 8.182H0.909V1.818a0.909 0.909 0 0 1 0.909 -0.909h6.364v0.909H1.818Z"/> 4072</svg> 4073 4074`; 4075const CHECK_ICON_CODE = `<svg xmlns="http://www.w3.org/2000/svg" width="17" height="17" viewBox="0 0 17 17" aria-hidden="true" aria-label="Copied" fill="none" stroke="currentColor" stroke-width="1.3"> 4076 <path d="m13.813 4.781 -7.438 7.438 -3.188 -3.188"/> 4077</svg> 4078`; 4079const COPY_BUTTON_CODE = `<button title="copy" class="copy_code_button"> 4080 <span class="copy-text">${COPY_ICON_CODE}</span> 4081 <span class="check">${CHECK_ICON_CODE}</span> 4082</button>`; 4083const escape_test = /[&<>"']/; 4084const escape_replace = new RegExp(escape_test.source, "g"); 4085const escape_test_no_encode = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/; 4086const escape_replace_no_encode = new RegExp(escape_test_no_encode.source, "g"); 4087const escape_replacements = { 4088 "&": "&", 4089 "<": "<", 4090 ">": ">", 4091 '"': """, 4092 "'": "'" 4093}; 4094const get_escape_replacement = (ch) => escape_replacements[ch] || ""; 4095function escape(html, encode) { 4096 if (encode) { 4097 if (escape_test.test(html)) { 4098 return html.replace(escape_replace, get_escape_replacement); 4099 } 4100 } else { 4101 if (escape_test_no_encode.test(html)) { 4102 return html.replace(escape_replace_no_encode, get_escape_replacement); 4103 } 4104 } 4105 return html; 4106} 4107function createLatexTokenizer(delimiters) { 4108 const delimiterPatterns = delimiters.map((delimiter) => ({ 4109 start: new RegExp(delimiter.left.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&")), 4110 end: new RegExp(delimiter.right.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&")) 4111 })); 4112 return { 4113 name: "latex", 4114 level: "block", 4115 start(src) { 4116 for (const pattern of delimiterPatterns) { 4117 const match = src.match(pattern.start); 4118 if (match) { 4119 return match.index; 4120 } 4121 } 4122 return -1; 4123 }, 4124 tokenizer(src, tokens) { 4125 for (const pattern of delimiterPatterns) { 4126 const match = new RegExp( 4127 `${pattern.start.source}([\\s\\S]+?)${pattern.end.source}` 4128 ).exec(src); 4129 if (match) { 4130 return { 4131 type: "latex", 4132 raw: match[0], 4133 text: match[1].trim() 4134 }; 4135 } 4136 } 4137 }, 4138 renderer(token) { 4139 return `<div class="latex-block">${token.text}</div>`; 4140 } 4141 }; 4142} 4143function createMermaidTokenizer() { 4144 return { 4145 name: "mermaid", 4146 level: "block", 4147 start(src) { 4148 return src.match(/^```mermaid\s*\n/)?.index; 4149 }, 4150 tokenizer(src) { 4151 const match = /^```mermaid\s*\n([\s\S]*?)```\s*(?:\n|$)/.exec(src); 4152 if (match) { 4153 return { 4154 type: "mermaid", 4155 raw: match[0], 4156 text: match[1].trim() 4157 }; 4158 } 4159 return void 0; 4160 }, 4161 renderer(token) { 4162 return `<div class="mermaid">${token.text}</div> 4163`; 4164 } 4165 }; 4166} 4167const renderer = { 4168 code(code, infostring, escaped) { 4169 const lang = (infostring ?? "").match(/\S*/)?.[0] ?? ""; 4170 code = code.replace(/\n$/, "") + "\n"; 4171 if (!lang || lang === "mermaid") { 4172 return '<div class="code_wrap">' + COPY_BUTTON_CODE + "<pre><code>" + (escaped ? code : escape(code, true)) + "</code></pre></div>\n"; 4173 } 4174 return '<div class="code_wrap">' + COPY_BUTTON_CODE + '<pre><code class="language-' + escape(lang) + '">' + (escaped ? code : escape(code, true)) + "</code></pre></div>\n"; 4175 } 4176}; 4177const slugger = new BananaSlug(); 4178function create_marked({ 4179 header_links, 4180 line_breaks, 4181 latex_delimiters 4182}) { 4183 const marked = new Marked(); 4184 marked.use( 4185 { 4186 gfm: true, 4187 pedantic: false, 4188 breaks: line_breaks 4189 }, 4190 markedHighlight({ 4191 highlight: (code, lang) => { 4192 if (prismExports.languages?.[lang]) { 4193 return prismExports.highlight(code, prismExports.languages[lang], lang); 4194 } 4195 return code; 4196 } 4197 }), 4198 { renderer } 4199 ); 4200 if (header_links) { 4201 marked.use(gfmHeadingId()); 4202 marked.use({ 4203 extensions: [ 4204 { 4205 name: "heading", 4206 level: "block", 4207 renderer(token) { 4208 const raw = token.raw.toLowerCase().trim().replace(/<[!\/a-z].*?>/gi, ""); 4209 const id = "h" + slugger.slug(raw); 4210 const level = token.depth; 4211 const text = this.parser.parseInline(token.tokens); 4212 return `<h${level} id="${id}"><a class="md-header-anchor" href="#${id}">${LINK_ICON_CODE}</a>${text}</h${level}> 4213`; 4214 } 4215 } 4216 ] 4217 }); 4218 } 4219 const mermaidTokenizer = createMermaidTokenizer(); 4220 const latexTokenizer = createLatexTokenizer(latex_delimiters); 4221 marked.use({ 4222 extensions: [mermaidTokenizer, latexTokenizer] 4223 }); 4224 return marked; 4225} 4226 4227/* IMPORT */ 4228/* MAIN */ 4229const cloneDeep = (value) => { 4230 return JSON.parse(JSON.stringify(value)); 4231}; 4232const isElement = (value) => { 4233 return (value.nodeType === 1); 4234}; 4235const isElementFunky = (value) => { 4236 return FUNKY_TAG_NAMES.has(value.tagName); 4237}; 4238const isElementAction = (value) => { 4239 return ('action' in value); 4240}; 4241const isElementIframe = (value) => { 4242 return (value.tagName === 'IFRAME'); 4243}; 4244const isElementFormAction = (value) => { 4245 return ('formAction' in value); 4246}; 4247const isElementHyperlink = (value) => { 4248 return ('protocol' in value); 4249}; 4250const isScriptOrDataUrl = (() => { 4251 const re = /^(?:\w+script|data):/i; 4252 return (url) => { 4253 return re.test(url); 4254 }; 4255})(); 4256const isScriptOrDataUrlLoose = (() => { 4257 const re = /(?:script|data):/i; 4258 return (url) => { 4259 return re.test(url); 4260 }; 4261})(); 4262const mergeMaps = (maps) => { 4263 const merged = {}; 4264 for (let i = 0, l = maps.length; i < l; i++) { 4265 const map = maps[i]; 4266 for (const key in map) { 4267 if (!merged[key]) { 4268 merged[key] = map[key]; 4269 } 4270 else { 4271 merged[key] = merged[key].concat(map[key]); 4272 } 4273 } 4274 } 4275 return merged; 4276}; 4277const traverseElementsBasic = (parent, callback) => {
4278 let current = parent.firstChild; 4279 while (current) { 4280 const next = current.nextSibling; 4281 if (isElement(current)) { 4282 callback(current, parent); 4283 if (current.parentNode) { // Still connected, so recurse 4284 traverseElementsBasic(current, callback); 4285 } 4286 } 4287 current = next; 4288 } 4289}; 4290const traverseElementsIterator = (parent, callback) => { 4291 const iterator = document.createNodeIterator(parent, NodeFilter.SHOW_ELEMENT); 4292 let current; 4293 while (current = iterator.nextNode()) { 4294 const parent = current.parentNode; 4295 if (!parent) 4296 continue; 4297 callback(current, parent); //TSC 4298 } 4299}; 4300const traverseElements = (parent, callback) => { 4301 const hasIterator = !!globalThis.document && !!globalThis.document.createNodeIterator; // For better WebWorker support 4302 if (hasIterator) { 4303 return traverseElementsIterator(parent, callback); 4304 } 4305 else { 4306 return traverseElementsBasic(parent, callback); 4307 } 4308}; 4309 4310/* IMPORT */ 4311/* ELEMENTS */ 4312const HTML_ELEMENTS_ALLOW = [ 4313 'a', 4314 'abbr', 4315 'acronym', 4316 'address', 4317 'area', 4318 'article', 4319 'aside', 4320 'audio', 4321 'b', 4322 'bdi', 4323 'bdo', 4324 'bgsound', 4325 'big', 4326 'blockquote', 4327 'body', 4328 'br', 4329 'button', 4330 'canvas', 4331 'caption', 4332 'center', 4333 'cite', 4334 'code', 4335 'col', 4336 'colgroup', 4337 'datalist', 4338 'dd', 4339 'del', 4340 'details', 4341 'dfn', 4342 'dialog', 4343 'dir', 4344 'div', 4345 'dl', 4346 'dt', 4347 'em', 4348 'fieldset', 4349 'figcaption', 4350 'figure', 4351 'font', 4352 'footer', 4353 'form', 4354 'h1', 4355 'h2', 4356 'h3', 4357 'h4', 4358 'h5', 4359 'h6', 4360 'head', 4361 'header', 4362 'hgroup', 4363 'hr', 4364 'html', 4365 'i', 4366 'img', 4367 'input', 4368 'ins', 4369 'kbd', 4370 'keygen', 4371 'label', 4372 'layer', 4373 'legend', 4374 'li', 4375 'link', 4376 'listing', 4377 'main', 4378 'map', 4379 'mark', 4380 'marquee', 4381 'menu', 4382 'meta', 4383 'meter', 4384 'nav', 4385 'nobr', 4386 'ol', 4387 'optgroup', 4388 'option', 4389 'output', 4390 'p', 4391 'picture', 4392 'popup', 4393 'pre', 4394 'progress', 4395 'q', 4396 'rb', 4397 'rp', 4398 'rt', 4399 'rtc', 4400 'ruby', 4401 's', 4402 'samp', 4403 'section', 4404 'select', 4405 'selectmenu', 4406 'small', 4407 'source', 4408 'span', 4409 'strike', 4410 'strong', 4411 'style', 4412 'sub', 4413 'summary', 4414 'sup', 4415 'table', 4416 'tbody', 4417 'td', 4418 'tfoot', 4419 'th', 4420 'thead', 4421 'time', 4422 'tr', 4423 'track', 4424 'tt', 4425 'u', 4426 'ul', 4427 'var', 4428 'video', 4429 'wbr' 4430]; 4431const HTML_ELEMENTS_DISALLOW = [ 4432 'basefont', 4433 'command', 4434 'data', 4435 'iframe', 4436 'image', 4437 'plaintext', 4438 'portal', 4439 'slot', 4440 // 'template', //TODO: Not exactly correct to never allow this, too strict 4441 'textarea', 4442 'title', 4443 'xmp' 4444]; 4445const HTML_ELEMENTS = new Set([ 4446 ...HTML_ELEMENTS_ALLOW, 4447 ...HTML_ELEMENTS_DISALLOW 4448]); 4449const SVG_ELEMENTS_ALLOW = [ 4450 'svg', 4451 'a', 4452 'altglyph', 4453 'altglyphdef', 4454 'altglyphitem', 4455 'animatecolor', 4456 'animatemotion', 4457 'animatetransform', 4458 'circle', 4459 'clippath', 4460 'defs', 4461 'desc', 4462 'ellipse', 4463 'filter', 4464 'font', 4465 'g', 4466 'glyph', 4467 'glyphref', 4468 'hkern', 4469 'image', 4470 'line', 4471 'lineargradient', 4472 'marker', 4473 'mask', 4474 'metadata', 4475 'mpath', 4476 'path', 4477 'pattern', 4478 'polygon', 4479 'polyline', 4480 'radialgradient', 4481 'rect', 4482 'stop', 4483 'style', 4484 'switch', 4485 'symbol', 4486 'text', 4487 'textpath', 4488 'title', 4489 'tref', 4490 'tspan', 4491 'view', 4492 'vkern', 4493 /* FILTERS */ 4494 'feBlend', 4495 'feColorMatrix', 4496 'feComponentTransfer', 4497 'feComposite', 4498 'feConvolveMatrix', 4499 'feDiffuseLighting', 4500 'feDisplacementMap', 4501 'feDistantLight', 4502 'feFlood', 4503 'feFuncA', 4504 'feFuncB', 4505 'feFuncG', 4506 'feFuncR', 4507 'feGaussianBlur', 4508 'feImage', 4509 'feMerge', 4510 'feMergeNode', 4511 'feMorphology', 4512 'feOffset', 4513 'fePointLight', 4514 'feSpecularLighting', 4515 'feSpotLight', 4516 'feTile', 4517 'feTurbulence' 4518]; 4519const SVG_ELEMENTS_DISALLOW = [ 4520 'animate', 4521 'color-profile', 4522 'cursor', 4523 'discard', 4524 'fedropshadow', 4525 'font-face', 4526 'font-face-format', 4527 'font-face-name', 4528 'font-face-src', 4529 'font-face-uri', 4530 'foreignobject', 4531 'hatch', 4532 'hatchpath', 4533 'mesh', 4534 'meshgradient', 4535 'meshpatch', 4536 'meshrow', 4537 'missing-glyph', 4538 'script', 4539 'set', 4540 'solidcolor', 4541 'unknown', 4542 'use' 4543]; 4544const SVG_ELEMENTS = new Set([ 4545 ...SVG_ELEMENTS_ALLOW, 4546 ...SVG_ELEMENTS_DISALLOW 4547]); 4548const MATH_ELEMENTS_ALLOW = [ 4549 'math', 4550 'menclose', 4551 'merror', 4552 'mfenced', 4553 'mfrac', 4554 'mglyph', 4555 'mi', 4556 'mlabeledtr', 4557 'mmultiscripts', 4558 'mn', 4559 'mo', 4560 'mover', 4561 'mpadded', 4562 'mphantom', 4563 'mroot', 4564 'mrow', 4565 'ms', 4566 'mspace', 4567 'msqrt', 4568 'mstyle', 4569 'msub', 4570 'msup', 4571 'msubsup', 4572 'mtable', 4573 'mtd', 4574 'mtext', 4575 'mtr', 4576 'munder', 4577 'munderover' 4578]; 4579const MATH_ELEMENTS_DISALLOW = [ 4580 'maction', 4581 'maligngroup', 4582 'malignmark', 4583 'mlongdiv', 4584 'mscarries', 4585 'mscarry', 4586 'msgroup', 4587 'mstack', 4588 'msline', 4589 'msrow', 4590 'semantics', 4591 'annotation', 4592 'annotation-xml', 4593 'mprescripts', 4594 'none' 4595]; 4596const MATH_ELEMENTS = new Set([ 4597 ...MATH_ELEMENTS_ALLOW, 4598 ...MATH_ELEMENTS_DISALLOW 4599]); 4600/* ATTRIBUTES */ 4601const HTML_ATTRIBUTES_ALLOW = [ 4602 'abbr', 4603 'accept', 4604 'accept-charset', 4605 'accesskey', 4606 'action', 4607 'align', 4608 'alink', 4609 'allow', 4610 'allowfullscreen', 4611 'alt', 4612 'anchor', 4613 'archive', 4614 'as', 4615 'async', 4616 'autocapitalize', 4617 'autocomplete', 4618 'autocorrect', 4619 'autofocus', 4620 'autopictureinpicture', 4621 'autoplay', 4622 'axis', 4623 'background', 4624 'behavior', 4625 'bgcolor', 4626 'border', 4627 'bordercolor', 4628 'capture', 4629 'cellpadding', 4630 'cellspacing', 4631 'challenge', 4632 'char', 4633 'charoff', 4634 'charset', 4635 'checked', 4636 'cite', 4637 'class', 4638 'classid', 4639 'clear', 4640 'code', 4641 'codebase', 4642 'codetype', 4643 'color', 4644 'cols', 4645 'colspan', 4646 'compact', 4647 'content', 4648 'contenteditable', 4649 'controls', 4650 'controlslist', 4651 'conversiondestination', 4652 'coords', 4653 'crossorigin', 4654 'csp', 4655 'data', 4656 'datetime', 4657 'declare', 4658 'decoding', 4659 'default', 4660 'defer', 4661 'dir', 4662 'direction', 4663 'dirname', 4664 'disabled', 4665 'disablepictureinpicture', 4666 'disableremoteplayback', 4667 'disallowdocumentaccess', 4668 'download', 4669 'draggable', 4670 'elementtiming', 4671 'enctype', 4672 'end', 4673 'enterkeyhint', 4674 'event', 4675 'exportparts', 4676 'face', 4677 'for', 4678 'form', 4679 'formaction', 4680 'formenctype', 4681 'formmethod', 4682 'formnovalidate', 4683 'formtarget', 4684 'frame', 4685 'frameborder', 4686 'headers', 4687 'height', 4688 'hidden', 4689 'high', 4690 'href', 4691 'hreflang', 4692 'hreftranslate', 4693 'hspace', 4694 'http-equiv', 4695 'id', 4696 'imagesizes', 4697 'imagesrcset', 4698 'importance', 4699 'impressiondata', 4700 'impressionexpiry', 4701 'incremental', 4702 'inert', 4703 'inputmode', 4704 'integrity', 4705 'invisible', 4706 'ismap', 4707 'keytype', 4708 'kind', 4709 'label', 4710 'lang', 4711 'language', 4712 'latencyhint', 4713 'leftmargin', 4714 'link', 4715 'list', 4716 'loading', 4717 'longdesc', 4718 'loop', 4719 'low', 4720 'lowsrc', 4721 'manifest', 4722 'marginheight', 4723 'marginwidth', 4724 'max', 4725 'maxlength', 4726 'mayscript', 4727 'media', 4728 'method', 4729 'min', 4730 'minlength', 4731 'multiple', 4732 'muted',
4733 'name', 4734 'nohref', 4735 'nomodule', 4736 'nonce', 4737 'noresize', 4738 'noshade', 4739 'novalidate', 4740 'nowrap', 4741 'object', 4742 'open', 4743 'optimum', 4744 'part', 4745 'pattern', 4746 'ping', 4747 'placeholder', 4748 'playsinline', 4749 'policy', 4750 'poster', 4751 'preload', 4752 'pseudo', 4753 'readonly', 4754 'referrerpolicy', 4755 'rel', 4756 'reportingorigin', 4757 'required', 4758 'resources', 4759 'rev', 4760 'reversed', 4761 'role', 4762 'rows', 4763 'rowspan', 4764 'rules', 4765 'sandbox', 4766 'scheme', 4767 'scope', 4768 'scopes', 4769 'scrollamount', 4770 'scrolldelay', 4771 'scrolling', 4772 'select', 4773 'selected', 4774 'shadowroot', 4775 'shadowrootdelegatesfocus', 4776 'shape', 4777 'size', 4778 'sizes', 4779 'slot', 4780 'span', 4781 'spellcheck', 4782 'src', 4783 'srclang', 4784 'srcset', 4785 'standby', 4786 'start', 4787 'step', 4788 'style', 4789 'summary', 4790 'tabindex', 4791 'target', 4792 'text', 4793 'title', 4794 'topmargin', 4795 'translate', 4796 'truespeed', 4797 'trusttoken', 4798 'type', 4799 'usemap', 4800 'valign', 4801 'value', 4802 'valuetype', 4803 'version', 4804 'virtualkeyboardpolicy', 4805 'vlink', 4806 'vspace', 4807 'webkitdirectory', 4808 'width', 4809 'wrap' 4810]; 4811const SVG_ATTRIBUTES_ALLOW = [ 4812 'accent-height', 4813 'accumulate', 4814 'additive', 4815 'alignment-baseline', 4816 'ascent', 4817 'attributename', 4818 'attributetype', 4819 'azimuth', 4820 'basefrequency', 4821 'baseline-shift', 4822 'begin', 4823 'bias', 4824 'by', 4825 'class', 4826 'clip', 4827 'clippathunits', 4828 'clip-path', 4829 'clip-rule', 4830 'color', 4831 'color-interpolation', 4832 'color-interpolation-filters', 4833 'color-profile', 4834 'color-rendering', 4835 'cx', 4836 'cy', 4837 'd', 4838 'dx', 4839 'dy', 4840 'diffuseconstant', 4841 'direction', 4842 'display', 4843 'divisor', 4844 'dominant-baseline', 4845 'dur', 4846 'edgemode', 4847 'elevation', 4848 'end', 4849 'fill', 4850 'fill-opacity', 4851 'fill-rule', 4852 'filter', 4853 'filterunits', 4854 'flood-color', 4855 'flood-opacity', 4856 'font-family', 4857 'font-size', 4858 'font-size-adjust', 4859 'font-stretch', 4860 'font-style', 4861 'font-variant', 4862 'font-weight', 4863 'fx', 4864 'fy', 4865 'g1', 4866 'g2', 4867 'glyph-name', 4868 'glyphref', 4869 'gradientunits', 4870 'gradienttransform', 4871 'height', 4872 'href', 4873 'id', 4874 'image-rendering', 4875 'in', 4876 'in2', 4877 'k', 4878 'k1', 4879 'k2', 4880 'k3', 4881 'k4', 4882 'kerning', 4883 'keypoints', 4884 'keysplines', 4885 'keytimes', 4886 'lang', 4887 'lengthadjust', 4888 'letter-spacing', 4889 'kernelmatrix', 4890 'kernelunitlength', 4891 'lighting-color', 4892 'local', 4893 'marker-end', 4894 'marker-mid', 4895 'marker-start', 4896 'markerheight', 4897 'markerunits', 4898 'markerwidth', 4899 'maskcontentunits', 4900 'maskunits', 4901 'max', 4902 'mask', 4903 'media', 4904 'method', 4905 'mode', 4906 'min', 4907 'name', 4908 'numoctaves', 4909 'offset', 4910 'operator', 4911 'opacity', 4912 'order', 4913 'orient', 4914 'orientation', 4915 'origin', 4916 'overflow', 4917 'paint-order', 4918 'path', 4919 'pathlength', 4920 'patterncontentunits', 4921 'patterntransform', 4922 'patternunits', 4923 'points', 4924 'preservealpha', 4925 'preserveaspectratio', 4926 'primitiveunits', 4927 'r', 4928 'rx', 4929 'ry', 4930 'radius', 4931 'refx', 4932 'refy', 4933 'repeatcount', 4934 'repeatdur', 4935 'restart', 4936 'result', 4937 'rotate', 4938 'scale', 4939 'seed', 4940 'shape-rendering', 4941 'specularconstant', 4942 'specularexponent', 4943 'spreadmethod', 4944 'startoffset', 4945 'stddeviation', 4946 'stitchtiles', 4947 'stop-color', 4948 'stop-opacity', 4949 'stroke-dasharray', 4950 'stroke-dashoffset', 4951 'stroke-linecap', 4952 'stroke-linejoin', 4953 'stroke-miterlimit', 4954 'stroke-opacity', 4955 'stroke', 4956 'stroke-width', 4957 'style', 4958 'surfacescale', 4959 'systemlanguage', 4960 'tabindex', 4961 'targetx', 4962 'targety', 4963 'transform', 4964 'transform-origin', 4965 'text-anchor', 4966 'text-decoration', 4967 'text-rendering', 4968 'textlength', 4969 'type', 4970 'u1', 4971 'u2', 4972 'unicode', 4973 'values', 4974 'viewbox', 4975 'visibility', 4976 'version', 4977 'vert-adv-y', 4978 'vert-origin-x', 4979 'vert-origin-y', 4980 'width', 4981 'word-spacing', 4982 'wrap', 4983 'writing-mode', 4984 'xchannelselector', 4985 'ychannelselector', 4986 'x', 4987 'x1', 4988 'x2', 4989 'xmlns', 4990 'y', 4991 'y1', 4992 'y2', 4993 'z', 4994 'zoomandpan' 4995]; 4996const MATH_ATTRIBUTES_ALLOW = [ 4997 'accent', 4998 'accentunder', 4999 'align', 5000 'bevelled', 5001 'close', 5002 'columnsalign', 5003 'columnlines', 5004 'columnspan', 5005 'denomalign', 5006 'depth', 5007 'dir', 5008 'display', 5009 'displaystyle', 5010 'encoding', 5011 'fence', 5012 'frame', 5013 'height', 5014 'href', 5015 'id', 5016 'largeop', 5017 'length', 5018 'linethickness', 5019 'lspace', 5020 'lquote', 5021 'mathbackground', 5022 'mathcolor', 5023 'mathsize', 5024 'mathvariant', 5025 'maxsize', 5026 'minsize', 5027 'movablelimits', 5028 'notation', 5029 'numalign', 5030 'open', 5031 'rowalign', 5032 'rowlines',
5033 'rowspacing', 5034 'rowspan', 5035 'rspace', 5036 'rquote', 5037 'scriptlevel', 5038 'scriptminsize', 5039 'scriptsizemultiplier', 5040 'selection', 5041 'separator', 5042 'separators', 5043 'stretchy', 5044 'subscriptshift', 5045 'supscriptshift', 5046 'symmetric', 5047 'voffset', 5048 'width', 5049 'xmlns' 5050]; 5051/* NAMESPACES */ 5052const NAMESPACES = { 5053 HTML: 'http://www.w3.org/1999/xhtml', 5054 SVG: 'http://www.w3.org/2000/svg', 5055 MATH: 'http://www.w3.org/1998/Math/MathML' 5056}; 5057const NAMESPACES_ELEMENTS = { 5058 [NAMESPACES.HTML]: HTML_ELEMENTS, 5059 [NAMESPACES.SVG]: SVG_ELEMENTS, 5060 [NAMESPACES.MATH]: MATH_ELEMENTS 5061}; 5062const NAMESPACES_ROOTS = { 5063 [NAMESPACES.HTML]: 'html', 5064 [NAMESPACES.SVG]: 'svg', 5065 [NAMESPACES.MATH]: 'math' 5066}; 5067const NAMESPACES_PREFIXES = { 5068 [NAMESPACES.HTML]: '', 5069 [NAMESPACES.SVG]: 'svg:', 5070 [NAMESPACES.MATH]: 'math:' 5071}; 5072/* TAG NAMES */ 5073const FUNKY_TAG_NAMES = new Set([ 5074 'A', 5075 'AREA', 5076 'BUTTON', 5077 'FORM', 5078 'IFRAME', 5079 'INPUT' 5080]); 5081/* OTHERS */ 5082const DEFAULTS = { 5083 allowComments: true, 5084 allowCustomElements: false, 5085 allowUnknownMarkup: false, 5086 allowElements: [ 5087 ...HTML_ELEMENTS_ALLOW, 5088 ...SVG_ELEMENTS_ALLOW.map(name => `svg:${name}`), 5089 ...MATH_ELEMENTS_ALLOW.map(name => `math:${name}`) 5090 ], 5091 allowAttributes: mergeMaps([ 5092 Object.fromEntries(HTML_ATTRIBUTES_ALLOW.map(name => [name, ['*']])), 5093 Object.fromEntries(SVG_ATTRIBUTES_ALLOW.map(name => [name, ['svg:*']])), 5094 Object.fromEntries(MATH_ATTRIBUTES_ALLOW.map(name => [name, ['math:*']])) 5095 ]) 5096}; 5097 5098/* IMPORT */ 5099var __classPrivateFieldSet = (undefined && undefined.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { 5100 if (kind === "m") throw new TypeError("Private method is not writable"); 5101 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); 5102 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); 5103 return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; 5104}; 5105var __classPrivateFieldGet = (undefined && undefined.__classPrivateFieldGet) || function (receiver, state, kind, f) { 5106 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); 5107 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); 5108 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); 5109}; 5110var _Amuchina_configuration, _Amuchina_allowElements, _Amuchina_allowAttributes; 5111/* MAIN */ 5112//TODO: Add a decent test suite, possibly one from an existing trusted library 5113class Amuchina { 5114 /* CONSTRUCTOR */ 5115 constructor(configuration = {}) { 5116 /* VARIABLES */ 5117 _Amuchina_configuration.set(this, void 0); 5118 _Amuchina_allowElements.set(this, void 0); 5119 _Amuchina_allowAttributes.set(this, void 0); 5120 /* API */ 5121 this.getConfiguration = () => { 5122 return cloneDeep(__classPrivateFieldGet(this, _Amuchina_configuration, "f")); 5123 }; 5124 this.sanitize = (input) => { 5125 //TODO: Support integration points (foreignObject and friends) 5126 //TODO: Support xlink:href, xml:id, xlink:title, xml:space, xmlns:xlink 5127 const allowElements = __classPrivateFieldGet(this, _Amuchina_allowElements, "f"); 5128 const allowAttributes = __classPrivateFieldGet(this, _Amuchina_allowAttributes, "f"); 5129 traverseElements(input, (node, parent) => { 5130 const namespace = node.namespaceURI || NAMESPACES.HTML; 5131 const namespaceParent = parent['namespaceURI'] || NAMESPACES.HTML; 5132 const elements = NAMESPACES_ELEMENTS[namespace]; 5133 const root = NAMESPACES_ROOTS[namespace]; 5134 const prefix = NAMESPACES_PREFIXES[namespace]; 5135 const tag = node.tagName.toLowerCase(); 5136 const tagPrefixed = `${prefix}${tag}`; 5137 const all = '*'; 5138 const allPrefixed = `${prefix}${all}`; 5139 if (!elements.has(tag) || !allowElements.has(tagPrefixed) || (namespace !== namespaceParent && tag !== root)) { 5140 parent.removeChild(node); 5141 } 5142 else { 5143 const attributes = node.getAttributeNames(); 5144 const attributesLength = attributes.length; 5145 if (attributesLength) { 5146 for (let i = 0; i < attributesLength; i++) { 5147 const attribute = attributes[i]; 5148 const allowedValues = allowAttributes[attribute]; 5149 if (!allowedValues || (!allowedValues.has(allPrefixed) && !allowedValues.has(tagPrefixed))) { 5150 node.removeAttribute(attribute); 5151 } 5152 } 5153 if (isElementFunky(node)) { 5154 if (isElementHyperlink(node)) { 5155 const href = node.getAttribute('href'); 5156 if (href && isScriptOrDataUrlLoose(href) && isScriptOrDataUrl(node.protocol)) { 5157 node.removeAttribute('href'); 5158 } 5159 } 5160 else if (isElementAction(node)) { 5161 if (isScriptOrDataUrl(node.action)) { 5162 node.removeAttribute('action'); 5163 } 5164 } 5165 else if (isElementFormAction(node)) { 5166 if (isScriptOrDataUrl(node.formAction)) { 5167 node.removeAttribute('formaction'); 5168 } 5169 } 5170 else if (isElementIframe(node)) { 5171 if (isScriptOrDataUrl(node.src)) { 5172 node.removeAttribute('formaction'); 5173 } 5174 node.setAttribute('sandbox', 'allow-scripts'); //TODO: This is kinda arbitrary, it should be customizable and more flexible 5175 } 5176 } 5177 } 5178 } 5179 }); 5180 return input; 5181 }; 5182 this.sanitizeFor = (element, input) => { 5183 throw new Error('"sanitizeFor" is not implemented yet'); 5184 }; 5185 const { allowComments, allowCustomElements, allowUnknownMarkup, blockElements, dropElements, dropAttributes } = configuration; 5186 if (allowComments === false) 5187 throw new Error('A false "allowComments" is not supported yet'); 5188 if (allowCustomElements) 5189 throw new Error('A true "allowCustomElements" is not supported yet'); 5190 if (allowUnknownMarkup) 5191 throw new Error('A true "allowUnknownMarkup" is not supported yet'); 5192 if (blockElements) 5193 throw new Error('"blockElements" is not supported yet, use "allowElements" instead'); 5194 if (dropElements) 5195 throw new Error('"dropElements" is not supported yet, use "allowElements" instead'); 5196 if (dropAttributes) 5197 throw new Error('"dropAttributes" is not supported yet, use "allowAttributes" instead'); 5198 __classPrivateFieldSet(this, _Amuchina_configuration, cloneDeep(DEFAULTS), "f"); 5199 const { allowElements, allowAttributes } = configuration; 5200 if (allowElements) 5201 __classPrivateFieldGet(this, _Amuchina_configuration, "f").allowElements = configuration.allowElements; 5202 if (allowAttributes) 5203 __classPrivateFieldGet(this, _Amuchina_configuration, "f").allowAttributes = configuration.allowAttributes; 5204 __classPrivateFieldSet(this, _Amuchina_allowElements, new Set(__classPrivateFieldGet(this, _Amuchina_configuration, "f").allowElements), "f"); 5205 __classPrivateFieldSet(this, _Amuchina_allowAttributes, Object.fromEntries(Object.entries(__classPrivateFieldGet(this, _Amuchina_configuration, "f").allowAttributes || {}).map(([element, attributes]) => [element, new Set(attributes)])), "f"); 5206 } 5207} 5208_Amuchina_configuration = new WeakMap(), _Amuchina_allowElements = new WeakMap(), _Amuchina_allowAttributes = new WeakMap(); 5209/* STATIC API */ 5210Amuchina.getDefaultConfiguration = () => { 5211 return cloneDeep(DEFAULTS); 5212}; 5213 5214export { Amuchina as A, create_marked as c }; 5215//# sourceMappingURL=MarkdownCode.svelte_svelte_type_style_lang-B29zDiob.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.