Browse Source

fix: use rollup to output js files (#2916)

Tony Brix 2 years ago
parent
commit
610bc45d96
18 changed files with 8455 additions and 7834 deletions
  1. 4 0
      .github/workflows/tests.yml
  2. 2530 2179
      lib/marked.cjs
  3. 0 0
      lib/marked.cjs.map
  4. 691 591
      lib/marked.d.ts
  5. 2511 2135
      lib/marked.esm.js
  6. 0 0
      lib/marked.esm.js.map
  7. 2555 2178
      lib/marked.umd.js
  8. 0 0
      lib/marked.umd.js.map
  9. 0 0
      marked.min.js
  10. 80 693
      package-lock.json
  11. 9 7
      package.json
  12. 49 0
      rollup.config.js
  13. 1 1
      src/helpers.ts
  14. 1 2
      src/marked.ts
  15. 6 0
      test/umd-test.js
  16. 17 0
      tsconfig-types.json
  17. 1 1
      tsconfig.json
  18. 0 47
      tsup.config.ts

+ 4 - 0
.github/workflows/tests.yml

@@ -29,6 +29,10 @@ jobs:
         run: npm run test:unit
       - name: Run Spec Tests 👩🏽‍💻
         run: npm run test:specs
+      - name: Run UMD Tests 👩🏽‍💻
+        run: npm run test:umd
+      - name: Run Types Tests 👩🏽‍💻
+        run: npm run test:types
 
   Lint:
     runs-on: ubuntu-latest

+ 2530 - 2179
lib/marked.cjs

@@ -9,2281 +9,2632 @@
  * The code in this file is generated from files in ./src/
  */
 
-"use strict";
-var __defProp = Object.defineProperty;
-var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
-var __getOwnPropNames = Object.getOwnPropertyNames;
-var __hasOwnProp = Object.prototype.hasOwnProperty;
-var __export = (target, all) => {
-  for (var name in all)
-    __defProp(target, name, { get: all[name], enumerable: true });
-};
-var __copyProps = (to, from, except, desc) => {
-  if (from && typeof from === "object" || typeof from === "function") {
-    for (let key of __getOwnPropNames(from))
-      if (!__hasOwnProp.call(to, key) && key !== except)
-        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
-  }
-  return to;
-};
-var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
-var __accessCheck = (obj, member, msg) => {
-  if (!member.has(obj))
-    throw TypeError("Cannot " + msg);
-};
-var __privateAdd = (obj, member, value) => {
-  if (member.has(obj))
-    throw TypeError("Cannot add the same private member more than once");
-  member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
-};
-var __privateMethod = (obj, member, method) => {
-  __accessCheck(obj, member, "access private method");
-  return method;
-};
-
-// src/marked.ts
-var marked_exports = {};
-__export(marked_exports, {
-  Hooks: () => _Hooks,
-  Lexer: () => _Lexer2,
-  Marked: () => Marked,
-  Parser: () => _Parser,
-  Renderer: () => _Renderer,
-  Slugger: () => _Slugger,
-  TextRenderer: () => _TextRenderer,
-  Tokenizer: () => _Tokenizer,
-  defaults: () => _defaults,
-  getDefaults: () => _getDefaults,
-  lexer: () => lexer,
-  marked: () => marked,
-  options: () => options,
-  parse: () => parse,
-  parseInline: () => parseInline,
-  parser: () => parser,
-  setOptions: () => setOptions,
-  use: () => use,
-  walkTokens: () => walkTokens
-});
-module.exports = __toCommonJS(marked_exports);
+'use strict';
 
-// src/defaults.ts
+/**
+ * Gets the original marked default options.
+ */
 function _getDefaults() {
-  return {
-    async: false,
-    baseUrl: null,
-    breaks: false,
-    extensions: null,
-    gfm: true,
-    headerIds: false,
-    headerPrefix: "",
-    highlight: null,
-    hooks: null,
-    langPrefix: "language-",
-    mangle: false,
-    pedantic: false,
-    renderer: null,
-    sanitize: false,
-    sanitizer: null,
-    silent: false,
-    smartypants: false,
-    tokenizer: null,
-    walkTokens: null,
-    xhtml: false
-  };
+    return {
+        async: false,
+        baseUrl: null,
+        breaks: false,
+        extensions: null,
+        gfm: true,
+        headerIds: false,
+        headerPrefix: '',
+        highlight: null,
+        hooks: null,
+        langPrefix: 'language-',
+        mangle: false,
+        pedantic: false,
+        renderer: null,
+        sanitize: false,
+        sanitizer: null,
+        silent: false,
+        smartypants: false,
+        tokenizer: null,
+        walkTokens: null,
+        xhtml: false
+    };
 }
-var _defaults = _getDefaults();
+exports.defaults = _getDefaults();
 function changeDefaults(newDefaults) {
-  _defaults = newDefaults;
+    exports.defaults = newDefaults;
 }
 
-// src/helpers.ts
-var escapeTest = /[&<>"']/;
-var escapeReplace = new RegExp(escapeTest.source, "g");
-var escapeTestNoEncode = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/;
-var escapeReplaceNoEncode = new RegExp(escapeTestNoEncode.source, "g");
-var escapeReplacements = {
-  "&": "&amp;",
-  "<": "&lt;",
-  ">": "&gt;",
-  '"': "&quot;",
-  "'": "&#39;"
+/**
+ * Helpers
+ */
+const escapeTest = /[&<>"']/;
+const escapeReplace = new RegExp(escapeTest.source, 'g');
+const escapeTestNoEncode = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/;
+const escapeReplaceNoEncode = new RegExp(escapeTestNoEncode.source, 'g');
+const escapeReplacements = {
+    '&': '&amp;',
+    '<': '&lt;',
+    '>': '&gt;',
+    '"': '&quot;',
+    "'": '&#39;'
 };
-var getEscapeReplacement = (ch) => escapeReplacements[ch];
+const getEscapeReplacement = (ch) => escapeReplacements[ch];
 function escape(html, encode) {
-  if (encode) {
-    if (escapeTest.test(html)) {
-      return html.replace(escapeReplace, getEscapeReplacement);
+    if (encode) {
+        if (escapeTest.test(html)) {
+            return html.replace(escapeReplace, getEscapeReplacement);
+        }
     }
-  } else {
-    if (escapeTestNoEncode.test(html)) {
-      return html.replace(escapeReplaceNoEncode, getEscapeReplacement);
+    else {
+        if (escapeTestNoEncode.test(html)) {
+            return html.replace(escapeReplaceNoEncode, getEscapeReplacement);
+        }
     }
-  }
-  return html;
+    return html;
 }
-var unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig;
+const unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig;
 function unescape(html) {
-  return html.replace(unescapeTest, (_, n) => {
-    n = n.toLowerCase();
-    if (n === "colon")
-      return ":";
-    if (n.charAt(0) === "#") {
-      return n.charAt(1) === "x" ? String.fromCharCode(parseInt(n.substring(2), 16)) : String.fromCharCode(+n.substring(1));
-    }
-    return "";
-  });
+    // explicitly match decimal, hex, and named HTML entities
+    return html.replace(unescapeTest, (_, n) => {
+        n = n.toLowerCase();
+        if (n === 'colon')
+            return ':';
+        if (n.charAt(0) === '#') {
+            return n.charAt(1) === 'x'
+                ? String.fromCharCode(parseInt(n.substring(2), 16))
+                : String.fromCharCode(+n.substring(1));
+        }
+        return '';
+    });
 }
-var caret = /(^|[^\[])\^/g;
+const caret = /(^|[^\[])\^/g;
 function edit(regex, opt) {
-  regex = typeof regex === "string" ? regex : regex.source;
-  opt = opt || "";
-  const obj = {
-    replace: (name, val) => {
-      val = typeof val === "object" && "source" in val ? val.source : val;
-      val = val.replace(caret, "$1");
-      regex = regex.replace(name, val);
-      return obj;
-    },
-    getRegex: () => {
-      return new RegExp(regex, opt);
-    }
-  };
-  return obj;
+    regex = typeof regex === 'string' ? regex : regex.source;
+    opt = opt || '';
+    const obj = {
+        replace: (name, val) => {
+            val = typeof val === 'object' && 'source' in val ? val.source : val;
+            val = val.replace(caret, '$1');
+            regex = regex.replace(name, val);
+            return obj;
+        },
+        getRegex: () => {
+            return new RegExp(regex, opt);
+        }
+    };
+    return obj;
 }
-var nonWordAndColonTest = /[^\w:]/g;
-var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
+const nonWordAndColonTest = /[^\w:]/g;
+const originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
 function cleanUrl(sanitize, base, href) {
-  if (sanitize) {
-    let prot;
+    if (sanitize) {
+        let prot;
+        try {
+            prot = decodeURIComponent(unescape(href))
+                .replace(nonWordAndColonTest, '')
+                .toLowerCase();
+        }
+        catch (e) {
+            return null;
+        }
+        if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
+            return null;
+        }
+    }
+    if (base && !originIndependentUrl.test(href)) {
+        href = resolveUrl(base, href);
+    }
     try {
-      prot = decodeURIComponent(unescape(href)).replace(nonWordAndColonTest, "").toLowerCase();
-    } catch (e) {
-      return null;
-    }
-    if (prot.indexOf("javascript:") === 0 || prot.indexOf("vbscript:") === 0 || prot.indexOf("data:") === 0) {
-      return null;
-    }
-  }
-  if (base && !originIndependentUrl.test(href)) {
-    href = resolveUrl(base, href);
-  }
-  try {
-    href = encodeURI(href).replace(/%25/g, "%");
-  } catch (e) {
-    return null;
-  }
-  return href;
+        href = encodeURI(href).replace(/%25/g, '%');
+    }
+    catch (e) {
+        return null;
+    }
+    return href;
 }
-var baseUrls = {};
-var justDomain = /^[^:]+:\/*[^/]*$/;
-var protocol = /^([^:]+:)[\s\S]*$/;
-var domain = /^([^:]+:\/*[^/]*)[\s\S]*$/;
+const baseUrls = {};
+const justDomain = /^[^:]+:\/*[^/]*$/;
+const protocol = /^([^:]+:)[\s\S]*$/;
+const domain = /^([^:]+:\/*[^/]*)[\s\S]*$/;
 function resolveUrl(base, href) {
-  if (!baseUrls[" " + base]) {
-    if (justDomain.test(base)) {
-      baseUrls[" " + base] = base + "/";
-    } else {
-      baseUrls[" " + base] = rtrim(base, "/", true);
-    }
-  }
-  base = baseUrls[" " + base];
-  const relativeBase = base.indexOf(":") === -1;
-  if (href.substring(0, 2) === "//") {
-    if (relativeBase) {
-      return href;
-    }
-    return base.replace(protocol, "$1") + href;
-  } else if (href.charAt(0) === "/") {
-    if (relativeBase) {
-      return href;
-    }
-    return base.replace(domain, "$1") + href;
-  } else {
-    return base + href;
-  }
+    if (!baseUrls[' ' + base]) {
+        // we can ignore everything in base after the last slash of its path component,
+        // but we might need to add _that_
+        // https://tools.ietf.org/html/rfc3986#section-3
+        if (justDomain.test(base)) {
+            baseUrls[' ' + base] = base + '/';
+        }
+        else {
+            baseUrls[' ' + base] = rtrim(base, '/', true);
+        }
+    }
+    base = baseUrls[' ' + base];
+    const relativeBase = base.indexOf(':') === -1;
+    if (href.substring(0, 2) === '//') {
+        if (relativeBase) {
+            return href;
+        }
+        return base.replace(protocol, '$1') + href;
+    }
+    else if (href.charAt(0) === '/') {
+        if (relativeBase) {
+            return href;
+        }
+        return base.replace(domain, '$1') + href;
+    }
+    else {
+        return base + href;
+    }
 }
-var noopTest = { exec: () => null };
+const noopTest = { exec: () => null };
 function splitCells(tableRow, count) {
-  const row = tableRow.replace(/\|/g, (match, offset, str) => {
-    let escaped = false, curr = offset;
-    while (--curr >= 0 && str[curr] === "\\")
-      escaped = !escaped;
-    if (escaped) {
-      return "|";
-    } else {
-      return " |";
-    }
-  }), cells = row.split(/ \|/);
-  let i = 0;
-  if (!cells[0].trim()) {
-    cells.shift();
-  }
-  if (cells.length > 0 && !cells[cells.length - 1].trim()) {
-    cells.pop();
-  }
-  if (cells.length > count) {
-    cells.splice(count);
-  } else {
-    while (cells.length < count)
-      cells.push("");
-  }
-  for (; i < cells.length; i++) {
-    cells[i] = cells[i].trim().replace(/\\\|/g, "|");
-  }
-  return cells;
+    // ensure that every cell-delimiting pipe has a space
+    // before it to distinguish it from an escaped pipe
+    const row = tableRow.replace(/\|/g, (match, offset, str) => {
+        let escaped = false, curr = offset;
+        while (--curr >= 0 && str[curr] === '\\')
+            escaped = !escaped;
+        if (escaped) {
+            // odd number of slashes means | is escaped
+            // so we leave it alone
+            return '|';
+        }
+        else {
+            // add space before unescaped |
+            return ' |';
+        }
+    }), cells = row.split(/ \|/);
+    let i = 0;
+    // First/last cell in a row cannot be empty if it has no leading/trailing pipe
+    if (!cells[0].trim()) {
+        cells.shift();
+    }
+    if (cells.length > 0 && !cells[cells.length - 1].trim()) {
+        cells.pop();
+    }
+    if (cells.length > count) {
+        cells.splice(count);
+    }
+    else {
+        while (cells.length < count)
+            cells.push('');
+    }
+    for (; i < cells.length; i++) {
+        // leading or trailing whitespace is ignored per the gfm spec
+        cells[i] = cells[i].trim().replace(/\\\|/g, '|');
+    }
+    return cells;
 }
+/**
+ * Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').
+ * /c*$/ is vulnerable to REDOS.
+ *
+ * @param str
+ * @param c
+ * @param invert Remove suffix of non-c chars instead. Default falsey.
+ */
 function rtrim(str, c, invert) {
-  const l = str.length;
-  if (l === 0) {
-    return "";
-  }
-  let suffLen = 0;
-  while (suffLen < l) {
-    const currChar = str.charAt(l - suffLen - 1);
-    if (currChar === c && !invert) {
-      suffLen++;
-    } else if (currChar !== c && invert) {
-      suffLen++;
-    } else {
-      break;
-    }
-  }
-  return str.slice(0, l - suffLen);
+    const l = str.length;
+    if (l === 0) {
+        return '';
+    }
+    // Length of suffix matching the invert condition.
+    let suffLen = 0;
+    // Step left until we fail to match the invert condition.
+    while (suffLen < l) {
+        const currChar = str.charAt(l - suffLen - 1);
+        if (currChar === c && !invert) {
+            suffLen++;
+        }
+        else if (currChar !== c && invert) {
+            suffLen++;
+        }
+        else {
+            break;
+        }
+    }
+    return str.slice(0, l - suffLen);
 }
 function findClosingBracket(str, b) {
-  if (str.indexOf(b[1]) === -1) {
+    if (str.indexOf(b[1]) === -1) {
+        return -1;
+    }
+    const l = str.length;
+    let level = 0, i = 0;
+    for (; i < l; i++) {
+        if (str[i] === '\\') {
+            i++;
+        }
+        else if (str[i] === b[0]) {
+            level++;
+        }
+        else if (str[i] === b[1]) {
+            level--;
+            if (level < 0) {
+                return i;
+            }
+        }
+    }
     return -1;
-  }
-  const l = str.length;
-  let level = 0, i = 0;
-  for (; i < l; i++) {
-    if (str[i] === "\\") {
-      i++;
-    } else if (str[i] === b[0]) {
-      level++;
-    } else if (str[i] === b[1]) {
-      level--;
-      if (level < 0) {
-        return i;
-      }
-    }
-  }
-  return -1;
 }
 function checkDeprecations(opt, callback) {
-  if (!opt || opt.silent) {
-    return;
-  }
-  if (callback) {
-    console.warn("marked(): callback is deprecated since version 5.0.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/using_pro#async");
-  }
-  if (opt.sanitize || opt.sanitizer) {
-    console.warn("marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options");
-  }
-  if (opt.highlight || opt.langPrefix !== "language-") {
-    console.warn("marked(): highlight and langPrefix parameters are deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-highlight.");
-  }
-  if (opt.mangle) {
-    console.warn("marked(): mangle parameter is enabled by default, but is deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install https://www.npmjs.com/package/marked-mangle, or disable by setting `{mangle: false}`.");
-  }
-  if (opt.baseUrl) {
-    console.warn("marked(): baseUrl parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-base-url.");
-  }
-  if (opt.smartypants) {
-    console.warn("marked(): smartypants parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-smartypants.");
-  }
-  if (opt.xhtml) {
-    console.warn("marked(): xhtml parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-xhtml.");
-  }
-  if (opt.headerIds || opt.headerPrefix) {
-    console.warn("marked(): headerIds and headerPrefix parameters enabled by default, but are deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install  https://www.npmjs.com/package/marked-gfm-heading-id, or disable by setting `{headerIds: false}`.");
-  }
+    if (!opt || opt.silent) {
+        return;
+    }
+    if (callback) {
+        console.warn('marked(): callback is deprecated since version 5.0.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/using_pro#async');
+    }
+    if (opt.sanitize || opt.sanitizer) {
+        console.warn('marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options');
+    }
+    if (opt.highlight || opt.langPrefix !== 'language-') {
+        console.warn('marked(): highlight and langPrefix parameters are deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-highlight.');
+    }
+    if (opt.mangle) {
+        console.warn('marked(): mangle parameter is enabled by default, but is deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install https://www.npmjs.com/package/marked-mangle, or disable by setting `{mangle: false}`.');
+    }
+    if (opt.baseUrl) {
+        console.warn('marked(): baseUrl parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-base-url.');
+    }
+    if (opt.smartypants) {
+        console.warn('marked(): smartypants parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-smartypants.');
+    }
+    if (opt.xhtml) {
+        console.warn('marked(): xhtml parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-xhtml.');
+    }
+    if (opt.headerIds || opt.headerPrefix) {
+        console.warn('marked(): headerIds and headerPrefix parameters enabled by default, but are deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install  https://www.npmjs.com/package/marked-gfm-heading-id, or disable by setting `{headerIds: false}`.');
+    }
 }
 
-// src/Tokenizer.ts
-function outputLink(cap, link, raw, lexer2) {
-  const href = link.href;
-  const title = link.title ? escape(link.title) : null;
-  const text = cap[1].replace(/\\([\[\]])/g, "$1");
-  if (cap[0].charAt(0) !== "!") {
-    lexer2.state.inLink = true;
-    const token = {
-      type: "link",
-      raw,
-      href,
-      title,
-      text,
-      tokens: lexer2.inlineTokens(text)
+function outputLink(cap, link, raw, lexer) {
+    const href = link.href;
+    const title = link.title ? escape(link.title) : null;
+    const text = cap[1].replace(/\\([\[\]])/g, '$1');
+    if (cap[0].charAt(0) !== '!') {
+        lexer.state.inLink = true;
+        const token = {
+            type: 'link',
+            raw,
+            href,
+            title,
+            text,
+            tokens: lexer.inlineTokens(text)
+        };
+        lexer.state.inLink = false;
+        return token;
+    }
+    return {
+        type: 'image',
+        raw,
+        href,
+        title,
+        text: escape(text)
     };
-    lexer2.state.inLink = false;
-    return token;
-  }
-  return {
-    type: "image",
-    raw,
-    href,
-    title,
-    text: escape(text)
-  };
 }
 function indentCodeCompensation(raw, text) {
-  const matchIndentToCode = raw.match(/^(\s+)(?:```)/);
-  if (matchIndentToCode === null) {
-    return text;
-  }
-  const indentToCode = matchIndentToCode[1];
-  return text.split("\n").map((node) => {
-    const matchIndentInNode = node.match(/^\s+/);
-    if (matchIndentInNode === null) {
-      return node;
-    }
-    const [indentInNode] = matchIndentInNode;
-    if (indentInNode.length >= indentToCode.length) {
-      return node.slice(indentToCode.length);
-    }
-    return node;
-  }).join("\n");
+    const matchIndentToCode = raw.match(/^(\s+)(?:```)/);
+    if (matchIndentToCode === null) {
+        return text;
+    }
+    const indentToCode = matchIndentToCode[1];
+    return text
+        .split('\n')
+        .map(node => {
+        const matchIndentInNode = node.match(/^\s+/);
+        if (matchIndentInNode === null) {
+            return node;
+        }
+        const [indentInNode] = matchIndentInNode;
+        if (indentInNode.length >= indentToCode.length) {
+            return node.slice(indentToCode.length);
+        }
+        return node;
+    })
+        .join('\n');
 }
-var _Tokenizer = class {
-  constructor(options2) {
-    this.options = options2 || _defaults;
-  }
-  space(src) {
-    const cap = this.rules.block.newline.exec(src);
-    if (cap && cap[0].length > 0) {
-      return {
-        type: "space",
-        raw: cap[0]
-      };
-    }
-  }
-  code(src) {
-    const cap = this.rules.block.code.exec(src);
-    if (cap) {
-      const text = cap[0].replace(/^ {1,4}/gm, "");
-      return {
-        type: "code",
-        raw: cap[0],
-        codeBlockStyle: "indented",
-        text: !this.options.pedantic ? rtrim(text, "\n") : text
-      };
-    }
-  }
-  fences(src) {
-    const cap = this.rules.block.fences.exec(src);
-    if (cap) {
-      const raw = cap[0];
-      const text = indentCodeCompensation(raw, cap[3] || "");
-      return {
-        type: "code",
-        raw,
-        lang: cap[2] ? cap[2].trim().replace(this.rules.inline._escapes, "$1") : cap[2],
-        text
-      };
-    }
-  }
-  heading(src) {
-    const cap = this.rules.block.heading.exec(src);
-    if (cap) {
-      let text = cap[2].trim();
-      if (/#$/.test(text)) {
-        const trimmed = rtrim(text, "#");
-        if (this.options.pedantic) {
-          text = trimmed.trim();
-        } else if (!trimmed || / $/.test(trimmed)) {
-          text = trimmed.trim();
-        }
-      }
-      return {
-        type: "heading",
-        raw: cap[0],
-        depth: cap[1].length,
-        text,
-        tokens: this.lexer.inline(text)
-      };
-    }
-  }
-  hr(src) {
-    const cap = this.rules.block.hr.exec(src);
-    if (cap) {
-      return {
-        type: "hr",
-        raw: cap[0]
-      };
-    }
-  }
-  blockquote(src) {
-    const cap = this.rules.block.blockquote.exec(src);
-    if (cap) {
-      const text = cap[0].replace(/^ *>[ \t]?/gm, "");
-      const top = this.lexer.state.top;
-      this.lexer.state.top = true;
-      const tokens = this.lexer.blockTokens(text);
-      this.lexer.state.top = top;
-      return {
-        type: "blockquote",
-        raw: cap[0],
-        tokens,
-        text
-      };
-    }
-  }
-  list(src) {
-    let cap = this.rules.block.list.exec(src);
-    if (cap) {
-      let raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine, line, nextLine, rawLine, itemContents, endEarly;
-      let bull = cap[1].trim();
-      const isordered = bull.length > 1;
-      const list = {
-        type: "list",
-        raw: "",
-        ordered: isordered,
-        start: isordered ? +bull.slice(0, -1) : "",
-        loose: false,
-        items: []
-      };
-      bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`;
-      if (this.options.pedantic) {
-        bull = isordered ? bull : "[*+-]";
-      }
-      const itemRegex = new RegExp(`^( {0,3}${bull})((?:[	 ][^\\n]*)?(?:\\n|$))`);
-      while (src) {
-        endEarly = false;
-        if (!(cap = itemRegex.exec(src))) {
-          break;
-        }
-        if (this.rules.block.hr.test(src)) {
-          break;
-        }
-        raw = cap[0];
-        src = src.substring(raw.length);
-        line = cap[2].split("\n", 1)[0].replace(/^\t+/, (t) => " ".repeat(3 * t.length));
-        nextLine = src.split("\n", 1)[0];
-        if (this.options.pedantic) {
-          indent = 2;
-          itemContents = line.trimLeft();
-        } else {
-          indent = cap[2].search(/[^ ]/);
-          indent = indent > 4 ? 1 : indent;
-          itemContents = line.slice(indent);
-          indent += cap[1].length;
-        }
-        blankLine = false;
-        if (!line && /^ *$/.test(nextLine)) {
-          raw += nextLine + "\n";
-          src = src.substring(nextLine.length + 1);
-          endEarly = true;
-        }
-        if (!endEarly) {
-          const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ 	][^\\n]*)?(?:\\n|$))`);
-          const hrRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`);
-          const fencesBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\`\`\`|~~~)`);
-          const headingBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`);
-          while (src) {
-            rawLine = src.split("\n", 1)[0];
-            nextLine = rawLine;
+/**
+ * Tokenizer
+ */
+class _Tokenizer {
+    options;
+    rules;
+    lexer;
+    constructor(options) {
+        this.options = options || exports.defaults;
+    }
+    space(src) {
+        const cap = this.rules.block.newline.exec(src);
+        if (cap && cap[0].length > 0) {
+            return {
+                type: 'space',
+                raw: cap[0]
+            };
+        }
+    }
+    code(src) {
+        const cap = this.rules.block.code.exec(src);
+        if (cap) {
+            const text = cap[0].replace(/^ {1,4}/gm, '');
+            return {
+                type: 'code',
+                raw: cap[0],
+                codeBlockStyle: 'indented',
+                text: !this.options.pedantic
+                    ? rtrim(text, '\n')
+                    : text
+            };
+        }
+    }
+    fences(src) {
+        const cap = this.rules.block.fences.exec(src);
+        if (cap) {
+            const raw = cap[0];
+            const text = indentCodeCompensation(raw, cap[3] || '');
+            return {
+                type: 'code',
+                raw,
+                lang: cap[2] ? cap[2].trim().replace(this.rules.inline._escapes, '$1') : cap[2],
+                text
+            };
+        }
+    }
+    heading(src) {
+        const cap = this.rules.block.heading.exec(src);
+        if (cap) {
+            let text = cap[2].trim();
+            // remove trailing #s
+            if (/#$/.test(text)) {
+                const trimmed = rtrim(text, '#');
+                if (this.options.pedantic) {
+                    text = trimmed.trim();
+                }
+                else if (!trimmed || / $/.test(trimmed)) {
+                    // CommonMark requires space before trailing #s
+                    text = trimmed.trim();
+                }
+            }
+            return {
+                type: 'heading',
+                raw: cap[0],
+                depth: cap[1].length,
+                text,
+                tokens: this.lexer.inline(text)
+            };
+        }
+    }
+    hr(src) {
+        const cap = this.rules.block.hr.exec(src);
+        if (cap) {
+            return {
+                type: 'hr',
+                raw: cap[0]
+            };
+        }
+    }
+    blockquote(src) {
+        const cap = this.rules.block.blockquote.exec(src);
+        if (cap) {
+            const text = cap[0].replace(/^ *>[ \t]?/gm, '');
+            const top = this.lexer.state.top;
+            this.lexer.state.top = true;
+            const tokens = this.lexer.blockTokens(text);
+            this.lexer.state.top = top;
+            return {
+                type: 'blockquote',
+                raw: cap[0],
+                tokens,
+                text
+            };
+        }
+    }
+    list(src) {
+        let cap = this.rules.block.list.exec(src);
+        if (cap) {
+            let raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine, line, nextLine, rawLine, itemContents, endEarly;
+            let bull = cap[1].trim();
+            const isordered = bull.length > 1;
+            const list = {
+                type: 'list',
+                raw: '',
+                ordered: isordered,
+                start: isordered ? +bull.slice(0, -1) : '',
+                loose: false,
+                items: []
+            };
+            bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`;
             if (this.options.pedantic) {
-              nextLine = nextLine.replace(/^ {1,4}(?=( {4})*[^ ])/g, "  ");
-            }
-            if (fencesBeginRegex.test(nextLine)) {
-              break;
-            }
-            if (headingBeginRegex.test(nextLine)) {
-              break;
-            }
-            if (nextBulletRegex.test(nextLine)) {
-              break;
-            }
-            if (hrRegex.test(src)) {
-              break;
-            }
-            if (nextLine.search(/[^ ]/) >= indent || !nextLine.trim()) {
-              itemContents += "\n" + nextLine.slice(indent);
-            } else {
-              if (blankLine) {
-                break;
-              }
-              if (line.search(/[^ ]/) >= 4) {
-                break;
-              }
-              if (fencesBeginRegex.test(line)) {
-                break;
-              }
-              if (headingBeginRegex.test(line)) {
-                break;
-              }
-              if (hrRegex.test(line)) {
-                break;
-              }
-              itemContents += "\n" + nextLine;
-            }
-            if (!blankLine && !nextLine.trim()) {
-              blankLine = true;
-            }
-            raw += rawLine + "\n";
-            src = src.substring(rawLine.length + 1);
-            line = nextLine.slice(indent);
-          }
-        }
-        if (!list.loose) {
-          if (endsWithBlankLine) {
-            list.loose = true;
-          } else if (/\n *\n *$/.test(raw)) {
-            endsWithBlankLine = true;
-          }
-        }
-        if (this.options.gfm) {
-          istask = /^\[[ xX]\] /.exec(itemContents);
-          if (istask) {
-            ischecked = istask[0] !== "[ ] ";
-            itemContents = itemContents.replace(/^\[[ xX]\] +/, "");
-          }
-        }
-        list.items.push({
-          type: "list_item",
-          raw,
-          task: !!istask,
-          checked: ischecked,
-          loose: false,
-          text: itemContents
-        });
-        list.raw += raw;
-      }
-      list.items[list.items.length - 1].raw = raw.trimRight();
-      list.items[list.items.length - 1].text = itemContents.trimRight();
-      list.raw = list.raw.trimRight();
-      const l = list.items.length;
-      for (i = 0; i < l; i++) {
-        this.lexer.state.top = false;
-        list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);
-        if (!list.loose) {
-          const spacers = list.items[i].tokens.filter((t) => t.type === "space");
-          const hasMultipleLineBreaks = spacers.length > 0 && spacers.some((t) => /\n.*\n/.test(t.raw));
-          list.loose = hasMultipleLineBreaks;
-        }
-      }
-      if (list.loose) {
-        for (i = 0; i < l; i++) {
-          list.items[i].loose = true;
-        }
-      }
-      return list;
-    }
-  }
-  html(src) {
-    const cap = this.rules.block.html.exec(src);
-    if (cap) {
-      const token = {
-        type: "html",
-        block: true,
-        raw: cap[0],
-        pre: !this.options.sanitizer && (cap[1] === "pre" || cap[1] === "script" || cap[1] === "style"),
-        text: cap[0]
-      };
-      if (this.options.sanitize) {
-        const text = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]);
-        const paragraph = token;
-        paragraph.type = "paragraph";
-        paragraph.text = text;
-        paragraph.tokens = this.lexer.inline(text);
-      }
-      return token;
-    }
-  }
-  def(src) {
-    const cap = this.rules.block.def.exec(src);
-    if (cap) {
-      const tag = cap[1].toLowerCase().replace(/\s+/g, " ");
-      const href = cap[2] ? cap[2].replace(/^<(.*)>$/, "$1").replace(this.rules.inline._escapes, "$1") : "";
-      const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline._escapes, "$1") : cap[3];
-      return {
-        type: "def",
-        tag,
-        raw: cap[0],
-        href,
-        title
-      };
-    }
-  }
-  table(src) {
-    const cap = this.rules.block.table.exec(src);
-    if (cap) {
-      const item = {
-        type: "table",
-        // splitCells expects a number as second argument
-        // @ts-expect-error
-        header: splitCells(cap[1]).map((c) => {
-          return { text: c };
-        }),
-        align: cap[2].replace(/^ *|\| *$/g, "").split(/ *\| */),
-        rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, "").split("\n") : []
-      };
-      if (item.header.length === item.align.length) {
-        item.raw = cap[0];
-        let l = item.align.length;
-        let i, j, k, row;
-        for (i = 0; i < l; i++) {
-          if (/^ *-+: *$/.test(item.align[i])) {
-            item.align[i] = "right";
-          } else if (/^ *:-+: *$/.test(item.align[i])) {
-            item.align[i] = "center";
-          } else if (/^ *:-+ *$/.test(item.align[i])) {
-            item.align[i] = "left";
-          } else {
-            item.align[i] = null;
-          }
-        }
-        l = item.rows.length;
-        for (i = 0; i < l; i++) {
-          item.rows[i] = splitCells(item.rows[i], item.header.length).map((c) => {
-            return { text: c };
-          });
-        }
-        l = item.header.length;
-        for (j = 0; j < l; j++) {
-          item.header[j].tokens = this.lexer.inline(item.header[j].text);
-        }
-        l = item.rows.length;
-        for (j = 0; j < l; j++) {
-          row = item.rows[j];
-          for (k = 0; k < row.length; k++) {
-            row[k].tokens = this.lexer.inline(row[k].text);
-          }
-        }
-        return item;
-      }
-    }
-  }
-  lheading(src) {
-    const cap = this.rules.block.lheading.exec(src);
-    if (cap) {
-      return {
-        type: "heading",
-        raw: cap[0],
-        depth: cap[2].charAt(0) === "=" ? 1 : 2,
-        text: cap[1],
-        tokens: this.lexer.inline(cap[1])
-      };
-    }
-  }
-  paragraph(src) {
-    const cap = this.rules.block.paragraph.exec(src);
-    if (cap) {
-      const text = cap[1].charAt(cap[1].length - 1) === "\n" ? cap[1].slice(0, -1) : cap[1];
-      return {
-        type: "paragraph",
-        raw: cap[0],
-        text,
-        tokens: this.lexer.inline(text)
-      };
-    }
-  }
-  text(src) {
-    const cap = this.rules.block.text.exec(src);
-    if (cap) {
-      return {
-        type: "text",
-        raw: cap[0],
-        text: cap[0],
-        tokens: this.lexer.inline(cap[0])
-      };
-    }
-  }
-  escape(src) {
-    const cap = this.rules.inline.escape.exec(src);
-    if (cap) {
-      return {
-        type: "escape",
-        raw: cap[0],
-        text: escape(cap[1])
-      };
-    }
-  }
-  tag(src) {
-    const cap = this.rules.inline.tag.exec(src);
-    if (cap) {
-      if (!this.lexer.state.inLink && /^<a /i.test(cap[0])) {
-        this.lexer.state.inLink = true;
-      } else if (this.lexer.state.inLink && /^<\/a>/i.test(cap[0])) {
-        this.lexer.state.inLink = false;
-      }
-      if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
-        this.lexer.state.inRawBlock = true;
-      } else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
-        this.lexer.state.inRawBlock = false;
-      }
-      return {
-        type: this.options.sanitize ? "text" : "html",
-        raw: cap[0],
-        inLink: this.lexer.state.inLink,
-        inRawBlock: this.lexer.state.inRawBlock,
-        block: false,
-        text: this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0]
-      };
-    }
-  }
-  link(src) {
-    const cap = this.rules.inline.link.exec(src);
-    if (cap) {
-      const trimmedUrl = cap[2].trim();
-      if (!this.options.pedantic && /^</.test(trimmedUrl)) {
-        if (!/>$/.test(trimmedUrl)) {
-          return;
-        }
-        const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), "\\");
-        if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {
-          return;
-        }
-      } else {
-        const lastParenIndex = findClosingBracket(cap[2], "()");
-        if (lastParenIndex > -1) {
-          const start = cap[0].indexOf("!") === 0 ? 5 : 4;
-          const linkLen = start + cap[1].length + lastParenIndex;
-          cap[2] = cap[2].substring(0, lastParenIndex);
-          cap[0] = cap[0].substring(0, linkLen).trim();
-          cap[3] = "";
-        }
-      }
-      let href = cap[2];
-      let title = "";
-      if (this.options.pedantic) {
-        const link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
-        if (link) {
-          href = link[1];
-          title = link[3];
-        }
-      } else {
-        title = cap[3] ? cap[3].slice(1, -1) : "";
-      }
-      href = href.trim();
-      if (/^</.test(href)) {
-        if (this.options.pedantic && !/>$/.test(trimmedUrl)) {
-          href = href.slice(1);
-        } else {
-          href = href.slice(1, -1);
-        }
-      }
-      return outputLink(cap, {
-        href: href ? href.replace(this.rules.inline._escapes, "$1") : href,
-        title: title ? title.replace(this.rules.inline._escapes, "$1") : title
-      }, cap[0], this.lexer);
-    }
-  }
-  reflink(src, links) {
-    let cap;
-    if ((cap = this.rules.inline.reflink.exec(src)) || (cap = this.rules.inline.nolink.exec(src))) {
-      let link = (cap[2] || cap[1]).replace(/\s+/g, " ");
-      link = links[link.toLowerCase()];
-      if (!link) {
-        const text = cap[0].charAt(0);
-        return {
-          type: "text",
-          raw: text,
-          text
-        };
-      }
-      return outputLink(cap, link, cap[0], this.lexer);
-    }
-  }
-  emStrong(src, maskedSrc, prevChar = "") {
-    let match = this.rules.inline.emStrong.lDelim.exec(src);
-    if (!match)
-      return;
-    if (match[3] && prevChar.match(/[\p{L}\p{N}]/u))
-      return;
-    const nextChar = match[1] || match[2] || "";
-    if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) {
-      const lLength = match[0].length - 1;
-      let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;
-      const endReg = match[0][0] === "*" ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;
-      endReg.lastIndex = 0;
-      maskedSrc = maskedSrc.slice(-1 * src.length + lLength);
-      while ((match = endReg.exec(maskedSrc)) != null) {
-        rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
-        if (!rDelim)
-          continue;
-        rLength = rDelim.length;
-        if (match[3] || match[4]) {
-          delimTotal += rLength;
-          continue;
-        } else if (match[5] || match[6]) {
-          if (lLength % 3 && !((lLength + rLength) % 3)) {
-            midDelimTotal += rLength;
-            continue;
-          }
-        }
-        delimTotal -= rLength;
-        if (delimTotal > 0)
-          continue;
-        rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
-        const raw = src.slice(0, lLength + match.index + rLength + 1);
-        if (Math.min(lLength, rLength) % 2) {
-          const text2 = raw.slice(1, -1);
-          return {
-            type: "em",
-            raw,
-            text: text2,
-            tokens: this.lexer.inlineTokens(text2)
-          };
+                bull = isordered ? bull : '[*+-]';
+            }
+            // Get next list item
+            const itemRegex = new RegExp(`^( {0,3}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))`);
+            // Check if current bullet point can start a new List Item
+            while (src) {
+                endEarly = false;
+                if (!(cap = itemRegex.exec(src))) {
+                    break;
+                }
+                if (this.rules.block.hr.test(src)) { // End list if bullet was actually HR (possibly move into itemRegex?)
+                    break;
+                }
+                raw = cap[0];
+                src = src.substring(raw.length);
+                line = cap[2].split('\n', 1)[0].replace(/^\t+/, (t) => ' '.repeat(3 * t.length));
+                nextLine = src.split('\n', 1)[0];
+                if (this.options.pedantic) {
+                    indent = 2;
+                    itemContents = line.trimLeft();
+                }
+                else {
+                    indent = cap[2].search(/[^ ]/); // Find first non-space char
+                    indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent
+                    itemContents = line.slice(indent);
+                    indent += cap[1].length;
+                }
+                blankLine = false;
+                if (!line && /^ *$/.test(nextLine)) { // Items begin with at most one blank line
+                    raw += nextLine + '\n';
+                    src = src.substring(nextLine.length + 1);
+                    endEarly = true;
+                }
+                if (!endEarly) {
+                    const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`);
+                    const hrRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`);
+                    const fencesBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\`\`\`|~~~)`);
+                    const headingBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`);
+                    // Check if following lines should be included in List Item
+                    while (src) {
+                        rawLine = src.split('\n', 1)[0];
+                        nextLine = rawLine;
+                        // Re-align to follow commonmark nesting rules
+                        if (this.options.pedantic) {
+                            nextLine = nextLine.replace(/^ {1,4}(?=( {4})*[^ ])/g, '  ');
+                        }
+                        // End list item if found code fences
+                        if (fencesBeginRegex.test(nextLine)) {
+                            break;
+                        }
+                        // End list item if found start of new heading
+                        if (headingBeginRegex.test(nextLine)) {
+                            break;
+                        }
+                        // End list item if found start of new bullet
+                        if (nextBulletRegex.test(nextLine)) {
+                            break;
+                        }
+                        // Horizontal rule found
+                        if (hrRegex.test(src)) {
+                            break;
+                        }
+                        if (nextLine.search(/[^ ]/) >= indent || !nextLine.trim()) { // Dedent if possible
+                            itemContents += '\n' + nextLine.slice(indent);
+                        }
+                        else {
+                            // not enough indentation
+                            if (blankLine) {
+                                break;
+                            }
+                            // paragraph continuation unless last line was a different block level element
+                            if (line.search(/[^ ]/) >= 4) { // indented code block
+                                break;
+                            }
+                            if (fencesBeginRegex.test(line)) {
+                                break;
+                            }
+                            if (headingBeginRegex.test(line)) {
+                                break;
+                            }
+                            if (hrRegex.test(line)) {
+                                break;
+                            }
+                            itemContents += '\n' + nextLine;
+                        }
+                        if (!blankLine && !nextLine.trim()) { // Check if current line is blank
+                            blankLine = true;
+                        }
+                        raw += rawLine + '\n';
+                        src = src.substring(rawLine.length + 1);
+                        line = nextLine.slice(indent);
+                    }
+                }
+                if (!list.loose) {
+                    // If the previous item ended with a blank line, the list is loose
+                    if (endsWithBlankLine) {
+                        list.loose = true;
+                    }
+                    else if (/\n *\n *$/.test(raw)) {
+                        endsWithBlankLine = true;
+                    }
+                }
+                // Check for task list items
+                if (this.options.gfm) {
+                    istask = /^\[[ xX]\] /.exec(itemContents);
+                    if (istask) {
+                        ischecked = istask[0] !== '[ ] ';
+                        itemContents = itemContents.replace(/^\[[ xX]\] +/, '');
+                    }
+                }
+                list.items.push({
+                    type: 'list_item',
+                    raw,
+                    task: !!istask,
+                    checked: ischecked,
+                    loose: false,
+                    text: itemContents
+                });
+                list.raw += raw;
+            }
+            // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic
+            list.items[list.items.length - 1].raw = raw.trimRight();
+            list.items[list.items.length - 1].text = itemContents.trimRight();
+            list.raw = list.raw.trimRight();
+            const l = list.items.length;
+            // Item child tokens handled here at end because we needed to have the final item to trim it first
+            for (i = 0; i < l; i++) {
+                this.lexer.state.top = false;
+                list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);
+                if (!list.loose) {
+                    // Check if list should be loose
+                    const spacers = list.items[i].tokens.filter(t => t.type === 'space');
+                    const hasMultipleLineBreaks = spacers.length > 0 && spacers.some(t => /\n.*\n/.test(t.raw));
+                    list.loose = hasMultipleLineBreaks;
+                }
+            }
+            // Set all items to loose if list is loose
+            if (list.loose) {
+                for (i = 0; i < l; i++) {
+                    list.items[i].loose = true;
+                }
+            }
+            return list;
+        }
+    }
+    html(src) {
+        const cap = this.rules.block.html.exec(src);
+        if (cap) {
+            const token = {
+                type: 'html',
+                block: true,
+                raw: cap[0],
+                pre: !this.options.sanitizer
+                    && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
+                text: cap[0]
+            };
+            if (this.options.sanitize) {
+                const text = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]);
+                const paragraph = token;
+                paragraph.type = 'paragraph';
+                paragraph.text = text;
+                paragraph.tokens = this.lexer.inline(text);
+            }
+            return token;
+        }
+    }
+    def(src) {
+        const cap = this.rules.block.def.exec(src);
+        if (cap) {
+            const tag = cap[1].toLowerCase().replace(/\s+/g, ' ');
+            const href = cap[2] ? cap[2].replace(/^<(.*)>$/, '$1').replace(this.rules.inline._escapes, '$1') : '';
+            const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline._escapes, '$1') : cap[3];
+            return {
+                type: 'def',
+                tag,
+                raw: cap[0],
+                href,
+                title
+            };
         }
-        const text = raw.slice(2, -2);
-        return {
-          type: "strong",
-          raw,
-          text,
-          tokens: this.lexer.inlineTokens(text)
-        };
-      }
-    }
-  }
-  codespan(src) {
-    const cap = this.rules.inline.code.exec(src);
-    if (cap) {
-      let text = cap[2].replace(/\n/g, " ");
-      const hasNonSpaceChars = /[^ ]/.test(text);
-      const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text);
-      if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
-        text = text.substring(1, text.length - 1);
-      }
-      text = escape(text, true);
-      return {
-        type: "codespan",
-        raw: cap[0],
-        text
-      };
-    }
-  }
-  br(src) {
-    const cap = this.rules.inline.br.exec(src);
-    if (cap) {
-      return {
-        type: "br",
-        raw: cap[0]
-      };
-    }
-  }
-  del(src) {
-    const cap = this.rules.inline.del.exec(src);
-    if (cap) {
-      return {
-        type: "del",
-        raw: cap[0],
-        text: cap[2],
-        tokens: this.lexer.inlineTokens(cap[2])
-      };
-    }
-  }
-  autolink(src, mangle2) {
-    const cap = this.rules.inline.autolink.exec(src);
-    if (cap) {
-      let text, href;
-      if (cap[2] === "@") {
-        text = escape(this.options.mangle ? mangle2(cap[1]) : cap[1]);
-        href = "mailto:" + text;
-      } else {
-        text = escape(cap[1]);
-        href = text;
-      }
-      return {
-        type: "link",
-        raw: cap[0],
-        text,
-        href,
-        tokens: [
-          {
-            type: "text",
-            raw: text,
-            text
-          }
-        ]
-      };
-    }
-  }
-  url(src, mangle2) {
-    let cap;
-    if (cap = this.rules.inline.url.exec(src)) {
-      let text, href;
-      if (cap[2] === "@") {
-        text = escape(this.options.mangle ? mangle2(cap[0]) : cap[0]);
-        href = "mailto:" + text;
-      } else {
-        let prevCapZero;
-        do {
-          prevCapZero = cap[0];
-          cap[0] = this.rules.inline._backpedal.exec(cap[0])[0];
-        } while (prevCapZero !== cap[0]);
-        text = escape(cap[0]);
-        if (cap[1] === "www.") {
-          href = "http://" + cap[0];
-        } else {
-          href = cap[0];
-        }
-      }
-      return {
-        type: "link",
-        raw: cap[0],
-        text,
-        href,
-        tokens: [
-          {
-            type: "text",
-            raw: text,
-            text
-          }
-        ]
-      };
-    }
-  }
-  inlineText(src, smartypants2) {
-    const cap = this.rules.inline.text.exec(src);
-    if (cap) {
-      let text;
-      if (this.lexer.state.inRawBlock) {
-        text = this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0];
-      } else {
-        text = escape(this.options.smartypants ? smartypants2(cap[0]) : cap[0]);
-      }
-      return {
-        type: "text",
-        raw: cap[0],
-        text
-      };
-    }
-  }
-};
+    }
+    table(src) {
+        const cap = this.rules.block.table.exec(src);
+        if (cap) {
+            const item = {
+                type: 'table',
+                // splitCells expects a number as second argument
+                // @ts-expect-error
+                header: splitCells(cap[1]).map(c => {
+                    return { text: c };
+                }),
+                align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
+                rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : []
+            };
+            if (item.header.length === item.align.length) {
+                item.raw = cap[0];
+                let l = item.align.length;
+                let i, j, k, row;
+                for (i = 0; i < l; i++) {
+                    if (/^ *-+: *$/.test(item.align[i])) {
+                        item.align[i] = 'right';
+                    }
+                    else if (/^ *:-+: *$/.test(item.align[i])) {
+                        item.align[i] = 'center';
+                    }
+                    else if (/^ *:-+ *$/.test(item.align[i])) {
+                        item.align[i] = 'left';
+                    }
+                    else {
+                        item.align[i] = null;
+                    }
+                }
+                l = item.rows.length;
+                for (i = 0; i < l; i++) {
+                    item.rows[i] = splitCells(item.rows[i], item.header.length).map(c => {
+                        return { text: c };
+                    });
+                }
+                // parse child tokens inside headers and cells
+                // header child tokens
+                l = item.header.length;
+                for (j = 0; j < l; j++) {
+                    item.header[j].tokens = this.lexer.inline(item.header[j].text);
+                }
+                // cell child tokens
+                l = item.rows.length;
+                for (j = 0; j < l; j++) {
+                    row = item.rows[j];
+                    for (k = 0; k < row.length; k++) {
+                        row[k].tokens = this.lexer.inline(row[k].text);
+                    }
+                }
+                return item;
+            }
+        }
+    }
+    lheading(src) {
+        const cap = this.rules.block.lheading.exec(src);
+        if (cap) {
+            return {
+                type: 'heading',
+                raw: cap[0],
+                depth: cap[2].charAt(0) === '=' ? 1 : 2,
+                text: cap[1],
+                tokens: this.lexer.inline(cap[1])
+            };
+        }
+    }
+    paragraph(src) {
+        const cap = this.rules.block.paragraph.exec(src);
+        if (cap) {
+            const text = cap[1].charAt(cap[1].length - 1) === '\n'
+                ? cap[1].slice(0, -1)
+                : cap[1];
+            return {
+                type: 'paragraph',
+                raw: cap[0],
+                text,
+                tokens: this.lexer.inline(text)
+            };
+        }
+    }
+    text(src) {
+        const cap = this.rules.block.text.exec(src);
+        if (cap) {
+            return {
+                type: 'text',
+                raw: cap[0],
+                text: cap[0],
+                tokens: this.lexer.inline(cap[0])
+            };
+        }
+    }
+    escape(src) {
+        const cap = this.rules.inline.escape.exec(src);
+        if (cap) {
+            return {
+                type: 'escape',
+                raw: cap[0],
+                text: escape(cap[1])
+            };
+        }
+    }
+    tag(src) {
+        const cap = this.rules.inline.tag.exec(src);
+        if (cap) {
+            if (!this.lexer.state.inLink && /^<a /i.test(cap[0])) {
+                this.lexer.state.inLink = true;
+            }
+            else if (this.lexer.state.inLink && /^<\/a>/i.test(cap[0])) {
+                this.lexer.state.inLink = false;
+            }
+            if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
+                this.lexer.state.inRawBlock = true;
+            }
+            else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
+                this.lexer.state.inRawBlock = false;
+            }
+            return {
+                type: this.options.sanitize
+                    ? 'text'
+                    : 'html',
+                raw: cap[0],
+                inLink: this.lexer.state.inLink,
+                inRawBlock: this.lexer.state.inRawBlock,
+                block: false,
+                text: this.options.sanitize
+                    ? (this.options.sanitizer
+                        ? this.options.sanitizer(cap[0])
+                        : escape(cap[0]))
+                    : cap[0]
+            };
+        }
+    }
+    link(src) {
+        const cap = this.rules.inline.link.exec(src);
+        if (cap) {
+            const trimmedUrl = cap[2].trim();
+            if (!this.options.pedantic && /^</.test(trimmedUrl)) {
+                // commonmark requires matching angle brackets
+                if (!(/>$/.test(trimmedUrl))) {
+                    return;
+                }
+                // ending angle bracket cannot be escaped
+                const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\');
+                if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {
+                    return;
+                }
+            }
+            else {
+                // find closing parenthesis
+                const lastParenIndex = findClosingBracket(cap[2], '()');
+                if (lastParenIndex > -1) {
+                    const start = cap[0].indexOf('!') === 0 ? 5 : 4;
+                    const linkLen = start + cap[1].length + lastParenIndex;
+                    cap[2] = cap[2].substring(0, lastParenIndex);
+                    cap[0] = cap[0].substring(0, linkLen).trim();
+                    cap[3] = '';
+                }
+            }
+            let href = cap[2];
+            let title = '';
+            if (this.options.pedantic) {
+                // split pedantic href and title
+                const link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
+                if (link) {
+                    href = link[1];
+                    title = link[3];
+                }
+            }
+            else {
+                title = cap[3] ? cap[3].slice(1, -1) : '';
+            }
+            href = href.trim();
+            if (/^</.test(href)) {
+                if (this.options.pedantic && !(/>$/.test(trimmedUrl))) {
+                    // pedantic allows starting angle bracket without ending angle bracket
+                    href = href.slice(1);
+                }
+                else {
+                    href = href.slice(1, -1);
+                }
+            }
+            return outputLink(cap, {
+                href: href ? href.replace(this.rules.inline._escapes, '$1') : href,
+                title: title ? title.replace(this.rules.inline._escapes, '$1') : title
+            }, cap[0], this.lexer);
+        }
+    }
+    reflink(src, links) {
+        let cap;
+        if ((cap = this.rules.inline.reflink.exec(src))
+            || (cap = this.rules.inline.nolink.exec(src))) {
+            let link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
+            link = links[link.toLowerCase()];
+            if (!link) {
+                const text = cap[0].charAt(0);
+                return {
+                    type: 'text',
+                    raw: text,
+                    text
+                };
+            }
+            return outputLink(cap, link, cap[0], this.lexer);
+        }
+    }
+    emStrong(src, maskedSrc, prevChar = '') {
+        let match = this.rules.inline.emStrong.lDelim.exec(src);
+        if (!match)
+            return;
+        // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well
+        if (match[3] && prevChar.match(/[\p{L}\p{N}]/u))
+            return;
+        const nextChar = match[1] || match[2] || '';
+        if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) {
+            const lLength = match[0].length - 1;
+            let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;
+            const endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;
+            endReg.lastIndex = 0;
+            // Clip maskedSrc to same section of string as src (move to lexer?)
+            maskedSrc = maskedSrc.slice(-1 * src.length + lLength);
+            while ((match = endReg.exec(maskedSrc)) != null) {
+                rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
+                if (!rDelim)
+                    continue; // skip single * in __abc*abc__
+                rLength = rDelim.length;
+                if (match[3] || match[4]) { // found another Left Delim
+                    delimTotal += rLength;
+                    continue;
+                }
+                else if (match[5] || match[6]) { // either Left or Right Delim
+                    if (lLength % 3 && !((lLength + rLength) % 3)) {
+                        midDelimTotal += rLength;
+                        continue; // CommonMark Emphasis Rules 9-10
+                    }
+                }
+                delimTotal -= rLength;
+                if (delimTotal > 0)
+                    continue; // Haven't found enough closing delimiters
+                // Remove extra characters. *a*** -> *a*
+                rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
+                const raw = src.slice(0, lLength + match.index + rLength + 1);
+                // Create `em` if smallest delimiter has odd char count. *a***
+                if (Math.min(lLength, rLength) % 2) {
+                    const text = raw.slice(1, -1);
+                    return {
+                        type: 'em',
+                        raw,
+                        text,
+                        tokens: this.lexer.inlineTokens(text)
+                    };
+                }
+                // Create 'strong' if smallest delimiter has even char count. **a***
+                const text = raw.slice(2, -2);
+                return {
+                    type: 'strong',
+                    raw,
+                    text,
+                    tokens: this.lexer.inlineTokens(text)
+                };
+            }
+        }
+    }
+    codespan(src) {
+        const cap = this.rules.inline.code.exec(src);
+        if (cap) {
+            let text = cap[2].replace(/\n/g, ' ');
+            const hasNonSpaceChars = /[^ ]/.test(text);
+            const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text);
+            if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
+                text = text.substring(1, text.length - 1);
+            }
+            text = escape(text, true);
+            return {
+                type: 'codespan',
+                raw: cap[0],
+                text
+            };
+        }
+    }
+    br(src) {
+        const cap = this.rules.inline.br.exec(src);
+        if (cap) {
+            return {
+                type: 'br',
+                raw: cap[0]
+            };
+        }
+    }
+    del(src) {
+        const cap = this.rules.inline.del.exec(src);
+        if (cap) {
+            return {
+                type: 'del',
+                raw: cap[0],
+                text: cap[2],
+                tokens: this.lexer.inlineTokens(cap[2])
+            };
+        }
+    }
+    autolink(src, mangle) {
+        const cap = this.rules.inline.autolink.exec(src);
+        if (cap) {
+            let text, href;
+            if (cap[2] === '@') {
+                text = escape(this.options.mangle ? mangle(cap[1]) : cap[1]);
+                href = 'mailto:' + text;
+            }
+            else {
+                text = escape(cap[1]);
+                href = text;
+            }
+            return {
+                type: 'link',
+                raw: cap[0],
+                text,
+                href,
+                tokens: [
+                    {
+                        type: 'text',
+                        raw: text,
+                        text
+                    }
+                ]
+            };
+        }
+    }
+    url(src, mangle) {
+        let cap;
+        if (cap = this.rules.inline.url.exec(src)) {
+            let text, href;
+            if (cap[2] === '@') {
+                text = escape(this.options.mangle ? mangle(cap[0]) : cap[0]);
+                href = 'mailto:' + text;
+            }
+            else {
+                // do extended autolink path validation
+                let prevCapZero;
+                do {
+                    prevCapZero = cap[0];
+                    cap[0] = this.rules.inline._backpedal.exec(cap[0])[0];
+                } while (prevCapZero !== cap[0]);
+                text = escape(cap[0]);
+                if (cap[1] === 'www.') {
+                    href = 'http://' + cap[0];
+                }
+                else {
+                    href = cap[0];
+                }
+            }
+            return {
+                type: 'link',
+                raw: cap[0],
+                text,
+                href,
+                tokens: [
+                    {
+                        type: 'text',
+                        raw: text,
+                        text
+                    }
+                ]
+            };
+        }
+    }
+    inlineText(src, smartypants) {
+        const cap = this.rules.inline.text.exec(src);
+        if (cap) {
+            let text;
+            if (this.lexer.state.inRawBlock) {
+                text = this.options.sanitize ? (this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0])) : cap[0];
+            }
+            else {
+                text = escape(this.options.smartypants ? smartypants(cap[0]) : cap[0]);
+            }
+            return {
+                type: 'text',
+                raw: cap[0],
+                text
+            };
+        }
+    }
+}
 
-// src/rules.ts
-var block = {
-  newline: /^(?: *(?:\n|$))+/,
-  code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
-  fences: /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,
-  hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,
-  heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,
-  blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
-  list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/,
-  html: "^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))",
-  def: /^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,
-  table: noopTest,
-  lheading: /^((?:(?!^bull ).|\n(?!\n|bull ))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
-  // regex template, placeholders will be replaced according to different paragraph
-  // interruption rules of commonmark and the original markdown spec:
-  _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,
-  text: /^[^\n]+/
+/**
+ * Block-Level Grammar
+ */
+// Not all rules are defined in the object literal
+// @ts-expect-error
+const block = {
+    newline: /^(?: *(?:\n|$))+/,
+    code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
+    fences: /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,
+    hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,
+    heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,
+    blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
+    list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/,
+    html: '^ {0,3}(?:' // optional indentation
+        + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
+        + '|comment[^\\n]*(\\n+|$)' // (2)
+        + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3)
+        + '|<![A-Z][\\s\\S]*?(?:>\\n*|$)' // (4)
+        + '|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)' // (5)
+        + '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6)
+        + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag
+        + '|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag
+        + ')',
+    def: /^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,
+    table: noopTest,
+    lheading: /^((?:(?!^bull ).|\n(?!\n|bull ))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
+    // regex template, placeholders will be replaced according to different paragraph
+    // interruption rules of commonmark and the original markdown spec:
+    _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,
+    text: /^[^\n]+/
 };
 block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
 block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;
-block.def = edit(block.def).replace("label", block._label).replace("title", block._title).getRegex();
+block.def = edit(block.def)
+    .replace('label', block._label)
+    .replace('title', block._title)
+    .getRegex();
 block.bullet = /(?:[*+-]|\d{1,9}[.)])/;
-block.listItemStart = edit(/^( *)(bull) */).replace("bull", block.bullet).getRegex();
-block.list = edit(block.list).replace(/bull/g, block.bullet).replace("hr", "\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def", "\\n+(?=" + block.def.source + ")").getRegex();
-block._tag = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul";
+block.listItemStart = edit(/^( *)(bull) */)
+    .replace('bull', block.bullet)
+    .getRegex();
+block.list = edit(block.list)
+    .replace(/bull/g, block.bullet)
+    .replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))')
+    .replace('def', '\\n+(?=' + block.def.source + ')')
+    .getRegex();
+block._tag = 'address|article|aside|base|basefont|blockquote|body|caption'
+    + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'
+    + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'
+    + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'
+    + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr'
+    + '|track|ul';
 block._comment = /<!--(?!-?>)[\s\S]*?(?:-->|$)/;
-block.html = edit(block.html, "i").replace("comment", block._comment).replace("tag", block._tag).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
-block.lheading = edit(block.lheading).replace(/bull/g, block.bullet).getRegex();
-block.paragraph = edit(block._paragraph).replace("hr", block.hr).replace("heading", " {0,3}#{1,6} ").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", block._tag).getRegex();
-block.blockquote = edit(block.blockquote).replace("paragraph", block.paragraph).getRegex();
+block.html = edit(block.html, 'i')
+    .replace('comment', block._comment)
+    .replace('tag', block._tag)
+    .replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/)
+    .getRegex();
+block.lheading = edit(block.lheading)
+    .replace(/bull/g, block.bullet) // lists can interrupt
+    .getRegex();
+block.paragraph = edit(block._paragraph)
+    .replace('hr', block.hr)
+    .replace('heading', ' {0,3}#{1,6} ')
+    .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
+    .replace('|table', '')
+    .replace('blockquote', ' {0,3}>')
+    .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
+    .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
+    .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
+    .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
+    .getRegex();
+block.blockquote = edit(block.blockquote)
+    .replace('paragraph', block.paragraph)
+    .getRegex();
+/**
+ * Normal Block Grammar
+ */
 block.normal = { ...block };
+/**
+ * GFM Block Grammar
+ */
 block.gfm = {
-  ...block.normal,
-  table: "^ *([^\\n ].*\\|.*)\\n {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)"
-  // Cells
+    ...block.normal,
+    table: '^ *([^\\n ].*\\|.*)\\n' // Header
+        + ' {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?' // Align
+        + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells
 };
-block.gfm.table = edit(block.gfm.table).replace("hr", block.hr).replace("heading", " {0,3}#{1,6} ").replace("blockquote", " {0,3}>").replace("code", " {4}[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", block._tag).getRegex();
-block.gfm.paragraph = edit(block._paragraph).replace("hr", block.hr).replace("heading", " {0,3}#{1,6} ").replace("|lheading", "").replace("table", block.gfm.table).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", block._tag).getRegex();
+block.gfm.table = edit(block.gfm.table)
+    .replace('hr', block.hr)
+    .replace('heading', ' {0,3}#{1,6} ')
+    .replace('blockquote', ' {0,3}>')
+    .replace('code', ' {4}[^\\n]')
+    .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
+    .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
+    .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
+    .replace('tag', block._tag) // tables can be interrupted by type (6) html blocks
+    .getRegex();
+block.gfm.paragraph = edit(block._paragraph)
+    .replace('hr', block.hr)
+    .replace('heading', ' {0,3}#{1,6} ')
+    .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
+    .replace('table', block.gfm.table) // interrupt paragraphs with table
+    .replace('blockquote', ' {0,3}>')
+    .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
+    .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
+    .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
+    .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
+    .getRegex();
+/**
+ * Pedantic grammar (original John Gruber's loose markdown specification)
+ */
 block.pedantic = {
-  ...block.normal,
-  html: edit(
-    `^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`
-  ).replace("comment", block._comment).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),
-  def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
-  heading: /^(#{1,6})(.*)(?:\n+|$)/,
-  fences: noopTest,
-  // fences not supported
-  lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
-  paragraph: edit(block.normal._paragraph).replace("hr", block.hr).replace("heading", " *#{1,6} *[^\n]").replace("lheading", block.lheading).replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").getRegex()
+    ...block.normal,
+    html: edit('^ *(?:comment *(?:\\n|\\s*$)'
+        + '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag
+        + '|<tag(?:"[^"]*"|\'[^\']*\'|\\s[^\'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))')
+        .replace('comment', block._comment)
+        .replace(/tag/g, '(?!(?:'
+        + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'
+        + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'
+        + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b')
+        .getRegex(),
+    def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
+    heading: /^(#{1,6})(.*)(?:\n+|$)/,
+    fences: noopTest,
+    lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
+    paragraph: edit(block.normal._paragraph)
+        .replace('hr', block.hr)
+        .replace('heading', ' *#{1,6} *[^\n]')
+        .replace('lheading', block.lheading)
+        .replace('blockquote', ' {0,3}>')
+        .replace('|fences', '')
+        .replace('|list', '')
+        .replace('|html', '')
+        .getRegex()
 };
-var inline = {
-  escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
-  autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
-  url: noopTest,
-  tag: "^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>",
-  // CDATA section
-  link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,
-  reflink: /^!?\[(label)\]\[(ref)\]/,
-  nolink: /^!?\[(ref)\](?:\[\])?/,
-  reflinkSearch: "reflink|nolink(?!\\()",
-  emStrong: {
-    lDelim: /^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/,
-    //         (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left.  (5) and (6) can be either Left or Right.
-    //         | Skip orphan inside strong      | Consume to delim | (1) #***              | (2) a***#, a***                    | (3) #***a, ***a                  | (4) ***#                 | (5) #***#                         | (6) a***a
-    rDelimAst: /^[^_*]*?__[^_*]*?\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\*)[punct](\*+)(?=[\s]|$)|[^punct\s](\*+)(?!\*)(?=[punct\s]|$)|(?!\*)[punct\s](\*+)(?=[^punct\s])|[\s](\*+)(?!\*)(?=[punct])|(?!\*)[punct](\*+)(?!\*)(?=[punct])|[^punct\s](\*+)(?=[^punct\s])/,
-    rDelimUnd: /^[^_*]*?\*\*[^_*]*?_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\s]|$)|[^punct\s](_+)(?!_)(?=[punct\s]|$)|(?!_)[punct\s](_+)(?=[^punct\s])|[\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])/
-    // ^- Not allowed for _
-  },
-  code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
-  br: /^( {2,}|\\)\n(?!\s*$)/,
-  del: noopTest,
-  text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,
-  punctuation: /^((?![*_])[\spunctuation])/
+/**
+ * Inline-Level Grammar
+ */
+// Not all rules are defined in the object literal
+// @ts-expect-error
+const inline = {
+    escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
+    autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
+    url: noopTest,
+    tag: '^comment'
+        + '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
+        + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
+        + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
+        + '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
+        + '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>',
+    link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,
+    reflink: /^!?\[(label)\]\[(ref)\]/,
+    nolink: /^!?\[(ref)\](?:\[\])?/,
+    reflinkSearch: 'reflink|nolink(?!\\()',
+    emStrong: {
+        lDelim: /^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/,
+        //         (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left.  (5) and (6) can be either Left or Right.
+        //         | Skip orphan inside strong      | Consume to delim | (1) #***              | (2) a***#, a***                    | (3) #***a, ***a                  | (4) ***#                 | (5) #***#                         | (6) a***a
+        rDelimAst: /^[^_*]*?__[^_*]*?\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\*)[punct](\*+)(?=[\s]|$)|[^punct\s](\*+)(?!\*)(?=[punct\s]|$)|(?!\*)[punct\s](\*+)(?=[^punct\s])|[\s](\*+)(?!\*)(?=[punct])|(?!\*)[punct](\*+)(?!\*)(?=[punct])|[^punct\s](\*+)(?=[^punct\s])/,
+        rDelimUnd: /^[^_*]*?\*\*[^_*]*?_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\s]|$)|[^punct\s](_+)(?!_)(?=[punct\s]|$)|(?!_)[punct\s](_+)(?=[^punct\s])|[\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])/ // ^- Not allowed for _
+    },
+    code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
+    br: /^( {2,}|\\)\n(?!\s*$)/,
+    del: noopTest,
+    text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,
+    punctuation: /^((?![*_])[\spunctuation])/
 };
-inline._punctuation = "\\p{P}$+<=>`^|~";
-inline.punctuation = edit(inline.punctuation, "u").replace(/punctuation/g, inline._punctuation).getRegex();
+// list of unicode punctuation marks, plus any missing characters from CommonMark spec
+inline._punctuation = '\\p{P}$+<=>`^|~';
+inline.punctuation = edit(inline.punctuation, 'u').replace(/punctuation/g, inline._punctuation).getRegex();
+// sequences em should skip over [title](link), `code`, <html>
 inline.blockSkip = /\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g;
 inline.anyPunctuation = /\\[punct]/g;
 inline._escapes = /\\([punct])/g;
-inline._comment = edit(block._comment).replace("(?:-->|$)", "-->").getRegex();
-inline.emStrong.lDelim = edit(inline.emStrong.lDelim, "u").replace(/punct/g, inline._punctuation).getRegex();
-inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, "gu").replace(/punct/g, inline._punctuation).getRegex();
-inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, "gu").replace(/punct/g, inline._punctuation).getRegex();
-inline.anyPunctuation = edit(inline.anyPunctuation, "gu").replace(/punct/g, inline._punctuation).getRegex();
-inline._escapes = edit(inline._escapes, "gu").replace(/punct/g, inline._punctuation).getRegex();
+inline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex();
+inline.emStrong.lDelim = edit(inline.emStrong.lDelim, 'u')
+    .replace(/punct/g, inline._punctuation)
+    .getRegex();
+inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'gu')
+    .replace(/punct/g, inline._punctuation)
+    .getRegex();
+inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, 'gu')
+    .replace(/punct/g, inline._punctuation)
+    .getRegex();
+inline.anyPunctuation = edit(inline.anyPunctuation, 'gu')
+    .replace(/punct/g, inline._punctuation)
+    .getRegex();
+inline._escapes = edit(inline._escapes, 'gu')
+    .replace(/punct/g, inline._punctuation)
+    .getRegex();
 inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;
 inline._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])?)+(?![-_])/;
-inline.autolink = edit(inline.autolink).replace("scheme", inline._scheme).replace("email", inline._email).getRegex();
+inline.autolink = edit(inline.autolink)
+    .replace('scheme', inline._scheme)
+    .replace('email', inline._email)
+    .getRegex();
 inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;
-inline.tag = edit(inline.tag).replace("comment", inline._comment).replace("attribute", inline._attribute).getRegex();
+inline.tag = edit(inline.tag)
+    .replace('comment', inline._comment)
+    .replace('attribute', inline._attribute)
+    .getRegex();
 inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
 inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/;
 inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/;
-inline.link = edit(inline.link).replace("label", inline._label).replace("href", inline._href).replace("title", inline._title).getRegex();
-inline.reflink = edit(inline.reflink).replace("label", inline._label).replace("ref", block._label).getRegex();
-inline.nolink = edit(inline.nolink).replace("ref", block._label).getRegex();
-inline.reflinkSearch = edit(inline.reflinkSearch, "g").replace("reflink", inline.reflink).replace("nolink", inline.nolink).getRegex();
+inline.link = edit(inline.link)
+    .replace('label', inline._label)
+    .replace('href', inline._href)
+    .replace('title', inline._title)
+    .getRegex();
+inline.reflink = edit(inline.reflink)
+    .replace('label', inline._label)
+    .replace('ref', block._label)
+    .getRegex();
+inline.nolink = edit(inline.nolink)
+    .replace('ref', block._label)
+    .getRegex();
+inline.reflinkSearch = edit(inline.reflinkSearch, 'g')
+    .replace('reflink', inline.reflink)
+    .replace('nolink', inline.nolink)
+    .getRegex();
+/**
+ * Normal Inline Grammar
+ */
 inline.normal = { ...inline };
+/**
+ * Pedantic Inline Grammar
+ */
 inline.pedantic = {
-  ...inline.normal,
-  strong: {
-    start: /^__|\*\*/,
-    middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
-    endAst: /\*\*(?!\*)/g,
-    endUnd: /__(?!_)/g
-  },
-  em: {
-    start: /^_|\*/,
-    middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,
-    endAst: /\*(?!\*)/g,
-    endUnd: /_(?!_)/g
-  },
-  link: edit(/^!?\[(label)\]\((.*?)\)/).replace("label", inline._label).getRegex(),
-  reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", inline._label).getRegex()
+    ...inline.normal,
+    strong: {
+        start: /^__|\*\*/,
+        middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
+        endAst: /\*\*(?!\*)/g,
+        endUnd: /__(?!_)/g
+    },
+    em: {
+        start: /^_|\*/,
+        middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,
+        endAst: /\*(?!\*)/g,
+        endUnd: /_(?!_)/g
+    },
+    link: edit(/^!?\[(label)\]\((.*?)\)/)
+        .replace('label', inline._label)
+        .getRegex(),
+    reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/)
+        .replace('label', inline._label)
+        .getRegex()
 };
+/**
+ * GFM Inline Grammar
+ */
 inline.gfm = {
-  ...inline.normal,
-  escape: edit(inline.escape).replace("])", "~|])").getRegex(),
-  _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,
-  url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
-  _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
-  del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
-  text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
+    ...inline.normal,
+    escape: edit(inline.escape).replace('])', '~|])').getRegex(),
+    _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,
+    url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
+    _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
+    del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
+    text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
 };
-inline.gfm.url = edit(inline.gfm.url, "i").replace("email", inline.gfm._extended_email).getRegex();
+inline.gfm.url = edit(inline.gfm.url, 'i')
+    .replace('email', inline.gfm._extended_email)
+    .getRegex();
+/**
+ * GFM + Line Breaks Inline Grammar
+ */
 inline.breaks = {
-  ...inline.gfm,
-  br: edit(inline.br).replace("{2,}", "*").getRegex(),
-  text: edit(inline.gfm.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex()
+    ...inline.gfm,
+    br: edit(inline.br).replace('{2,}', '*').getRegex(),
+    text: edit(inline.gfm.text)
+        .replace('\\b_', '\\b_| {2,}\\n')
+        .replace(/\{2,\}/g, '*')
+        .getRegex()
 };
 
-// src/Lexer.ts
+/**
+ * smartypants text replacement
+ */
 function smartypants(text) {
-  return text.replace(/---/g, "\u2014").replace(/--/g, "\u2013").replace(/(^|[-\u2014/(\[{"\s])'/g, "$1\u2018").replace(/'/g, "\u2019").replace(/(^|[-\u2014/(\[{\u2018\s])"/g, "$1\u201C").replace(/"/g, "\u201D").replace(/\.{3}/g, "\u2026");
+    return text
+        // em-dashes
+        .replace(/---/g, '\u2014')
+        // en-dashes
+        .replace(/--/g, '\u2013')
+        // opening singles
+        .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
+        // closing singles & apostrophes
+        .replace(/'/g, '\u2019')
+        // opening doubles
+        .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
+        // closing doubles
+        .replace(/"/g, '\u201d')
+        // ellipses
+        .replace(/\.{3}/g, '\u2026');
 }
+/**
+ * mangle email addresses
+ */
 function mangle(text) {
-  let out = "", i, ch;
-  const l = text.length;
-  for (i = 0; i < l; i++) {
-    ch = text.charCodeAt(i);
-    if (Math.random() > 0.5) {
-      ch = "x" + ch.toString(16);
-    }
-    out += "&#" + ch + ";";
-  }
-  return out;
-}
-var _Lexer2 = class __Lexer {
-  constructor(options2) {
-    this.tokens = [];
-    this.tokens.links = /* @__PURE__ */ Object.create(null);
-    this.options = options2 || _defaults;
-    this.options.tokenizer = this.options.tokenizer || new _Tokenizer();
-    this.tokenizer = this.options.tokenizer;
-    this.tokenizer.options = this.options;
-    this.tokenizer.lexer = this;
-    this.inlineQueue = [];
-    this.state = {
-      inLink: false,
-      inRawBlock: false,
-      top: true
-    };
-    const rules = {
-      block: block.normal,
-      inline: inline.normal
-    };
-    if (this.options.pedantic) {
-      rules.block = block.pedantic;
-      rules.inline = inline.pedantic;
-    } else if (this.options.gfm) {
-      rules.block = block.gfm;
-      if (this.options.breaks) {
-        rules.inline = inline.breaks;
-      } else {
-        rules.inline = inline.gfm;
-      }
-    }
-    this.tokenizer.rules = rules;
-  }
-  /**
-   * Expose Rules
-   */
-  static get rules() {
-    return {
-      block,
-      inline
-    };
-  }
-  /**
-   * Static Lex Method
-   */
-  static lex(src, options2) {
-    const lexer2 = new __Lexer(options2);
-    return lexer2.lex(src);
-  }
-  /**
-   * Static Lex Inline Method
-   */
-  static lexInline(src, options2) {
-    const lexer2 = new __Lexer(options2);
-    return lexer2.inlineTokens(src);
-  }
-  /**
-   * Preprocessing
-   */
-  lex(src) {
-    src = src.replace(/\r\n|\r/g, "\n");
-    this.blockTokens(src, this.tokens);
-    let next;
-    while (next = this.inlineQueue.shift()) {
-      this.inlineTokens(next.src, next.tokens);
-    }
-    return this.tokens;
-  }
-  blockTokens(src, tokens = []) {
-    if (this.options.pedantic) {
-      src = src.replace(/\t/g, "    ").replace(/^ +$/gm, "");
-    } else {
-      src = src.replace(/^( *)(\t+)/gm, (_, leading, tabs) => {
-        return leading + "    ".repeat(tabs.length);
-      });
-    }
-    let token, lastToken, cutSrc, lastParagraphClipped;
-    while (src) {
-      if (this.options.extensions && this.options.extensions.block && this.options.extensions.block.some((extTokenizer) => {
-        if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
-          src = src.substring(token.raw.length);
-          tokens.push(token);
-          return true;
-        }
-        return false;
-      })) {
-        continue;
-      }
-      if (token = this.tokenizer.space(src)) {
-        src = src.substring(token.raw.length);
-        if (token.raw.length === 1 && tokens.length > 0) {
-          tokens[tokens.length - 1].raw += "\n";
-        } else {
-          tokens.push(token);
-        }
-        continue;
-      }
-      if (token = this.tokenizer.code(src)) {
-        src = src.substring(token.raw.length);
-        lastToken = tokens[tokens.length - 1];
-        if (lastToken && (lastToken.type === "paragraph" || lastToken.type === "text")) {
-          lastToken.raw += "\n" + token.raw;
-          lastToken.text += "\n" + token.text;
-          this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
-        } else {
-          tokens.push(token);
-        }
-        continue;
-      }
-      if (token = this.tokenizer.fences(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.heading(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.hr(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.blockquote(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.list(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.html(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.def(src)) {
-        src = src.substring(token.raw.length);
-        lastToken = tokens[tokens.length - 1];
-        if (lastToken && (lastToken.type === "paragraph" || lastToken.type === "text")) {
-          lastToken.raw += "\n" + token.raw;
-          lastToken.text += "\n" + token.raw;
-          this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
-        } else if (!this.tokens.links[token.tag]) {
-          this.tokens.links[token.tag] = {
-            href: token.href,
-            title: token.title
-          };
-        }
-        continue;
-      }
-      if (token = this.tokenizer.table(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.lheading(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      cutSrc = src;
-      if (this.options.extensions && this.options.extensions.startBlock) {
-        let startIndex = Infinity;
-        const tempSrc = src.slice(1);
-        let tempStart;
-        this.options.extensions.startBlock.forEach((getStartIndex) => {
-          tempStart = getStartIndex.call({ lexer: this }, tempSrc);
-          if (typeof tempStart === "number" && tempStart >= 0) {
-            startIndex = Math.min(startIndex, tempStart);
-          }
-        });
-        if (startIndex < Infinity && startIndex >= 0) {
-          cutSrc = src.substring(0, startIndex + 1);
-        }
-      }
-      if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
-        lastToken = tokens[tokens.length - 1];
-        if (lastParagraphClipped && lastToken.type === "paragraph") {
-          lastToken.raw += "\n" + token.raw;
-          lastToken.text += "\n" + token.text;
-          this.inlineQueue.pop();
-          this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
-        } else {
-          tokens.push(token);
-        }
-        lastParagraphClipped = cutSrc.length !== src.length;
-        src = src.substring(token.raw.length);
-        continue;
-      }
-      if (token = this.tokenizer.text(src)) {
-        src = src.substring(token.raw.length);
-        lastToken = tokens[tokens.length - 1];
-        if (lastToken && lastToken.type === "text") {
-          lastToken.raw += "\n" + token.raw;
-          lastToken.text += "\n" + token.text;
-          this.inlineQueue.pop();
-          this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
-        } else {
-          tokens.push(token);
-        }
-        continue;
-      }
-      if (src) {
-        const errMsg = "Infinite loop on byte: " + src.charCodeAt(0);
-        if (this.options.silent) {
-          console.error(errMsg);
-          break;
-        } else {
-          throw new Error(errMsg);
-        }
-      }
-    }
-    this.state.top = true;
-    return tokens;
-  }
-  inline(src, tokens = []) {
-    this.inlineQueue.push({ src, tokens });
-    return tokens;
-  }
-  /**
-   * Lexing/Compiling
-   */
-  inlineTokens(src, tokens = []) {
-    let token, lastToken, cutSrc;
-    let maskedSrc = src;
-    let match;
-    let keepPrevChar, prevChar;
-    if (this.tokens.links) {
-      const links = Object.keys(this.tokens.links);
-      if (links.length > 0) {
-        while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
-          if (links.includes(match[0].slice(match[0].lastIndexOf("[") + 1, -1))) {
-            maskedSrc = maskedSrc.slice(0, match.index) + "[" + "a".repeat(match[0].length - 2) + "]" + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
-          }
-        }
-      }
-    }
-    while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
-      maskedSrc = maskedSrc.slice(0, match.index) + "[" + "a".repeat(match[0].length - 2) + "]" + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
-    }
-    while ((match = this.tokenizer.rules.inline.anyPunctuation.exec(maskedSrc)) != null) {
-      maskedSrc = maskedSrc.slice(0, match.index) + "++" + maskedSrc.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
-    }
-    while (src) {
-      if (!keepPrevChar) {
-        prevChar = "";
-      }
-      keepPrevChar = false;
-      if (this.options.extensions && this.options.extensions.inline && this.options.extensions.inline.some((extTokenizer) => {
-        if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
-          src = src.substring(token.raw.length);
-          tokens.push(token);
-          return true;
-        }
-        return false;
-      })) {
-        continue;
-      }
-      if (token = this.tokenizer.escape(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.tag(src)) {
-        src = src.substring(token.raw.length);
-        lastToken = tokens[tokens.length - 1];
-        if (lastToken && token.type === "text" && lastToken.type === "text") {
-          lastToken.raw += token.raw;
-          lastToken.text += token.text;
-        } else {
-          tokens.push(token);
-        }
-        continue;
-      }
-      if (token = this.tokenizer.link(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.reflink(src, this.tokens.links)) {
-        src = src.substring(token.raw.length);
-        lastToken = tokens[tokens.length - 1];
-        if (lastToken && token.type === "text" && lastToken.type === "text") {
-          lastToken.raw += token.raw;
-          lastToken.text += token.text;
-        } else {
-          tokens.push(token);
-        }
-        continue;
-      }
-      if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.codespan(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.br(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.del(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.autolink(src, mangle)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      cutSrc = src;
-      if (this.options.extensions && this.options.extensions.startInline) {
-        let startIndex = Infinity;
-        const tempSrc = src.slice(1);
-        let tempStart;
-        this.options.extensions.startInline.forEach((getStartIndex) => {
-          tempStart = getStartIndex.call({ lexer: this }, tempSrc);
-          if (typeof tempStart === "number" && tempStart >= 0) {
-            startIndex = Math.min(startIndex, tempStart);
-          }
-        });
-        if (startIndex < Infinity && startIndex >= 0) {
-          cutSrc = src.substring(0, startIndex + 1);
-        }
-      }
-      if (token = this.tokenizer.inlineText(cutSrc, smartypants)) {
-        src = src.substring(token.raw.length);
-        if (token.raw.slice(-1) !== "_") {
-          prevChar = token.raw.slice(-1);
-        }
-        keepPrevChar = true;
-        lastToken = tokens[tokens.length - 1];
-        if (lastToken && lastToken.type === "text") {
-          lastToken.raw += token.raw;
-          lastToken.text += token.text;
-        } else {
-          tokens.push(token);
-        }
-        continue;
-      }
-      if (src) {
-        const errMsg = "Infinite loop on byte: " + src.charCodeAt(0);
-        if (this.options.silent) {
-          console.error(errMsg);
-          break;
-        } else {
-          throw new Error(errMsg);
-        }
-      }
-    }
-    return tokens;
-  }
-};
-
-// src/Renderer.ts
-var _Renderer = class {
-  constructor(options2) {
-    this.options = options2 || _defaults;
-  }
-  code(code, infostring, escaped) {
-    const lang = (infostring || "").match(/\S*/)[0];
-    if (this.options.highlight) {
-      const out = this.options.highlight(code, lang);
-      if (out != null && out !== code) {
-        escaped = true;
-        code = out;
-      }
-    }
-    code = code.replace(/\n$/, "") + "\n";
-    if (!lang) {
-      return "<pre><code>" + (escaped ? code : escape(code, true)) + "</code></pre>\n";
-    }
-    return '<pre><code class="' + this.options.langPrefix + escape(lang) + '">' + (escaped ? code : escape(code, true)) + "</code></pre>\n";
-  }
-  blockquote(quote) {
-    return `<blockquote>
-${quote}</blockquote>
-`;
-  }
-  html(html, block2) {
-    return html;
-  }
-  heading(text, level, raw, slugger) {
-    if (this.options.headerIds) {
-      const id = this.options.headerPrefix + slugger.slug(raw);
-      return `<h${level} id="${id}">${text}</h${level}>
-`;
-    }
-    return `<h${level}>${text}</h${level}>
-`;
-  }
-  hr() {
-    return this.options.xhtml ? "<hr/>\n" : "<hr>\n";
-  }
-  list(body, ordered, start) {
-    const type = ordered ? "ol" : "ul", startatt = ordered && start !== 1 ? ' start="' + start + '"' : "";
-    return "<" + type + startatt + ">\n" + body + "</" + type + ">\n";
-  }
-  listitem(text, task, checked) {
-    return `<li>${text}</li>
-`;
-  }
-  checkbox(checked) {
-    return "<input " + (checked ? 'checked="" ' : "") + 'disabled="" type="checkbox"' + (this.options.xhtml ? " /" : "") + "> ";
-  }
-  paragraph(text) {
-    return `<p>${text}</p>
-`;
-  }
-  table(header, body) {
-    if (body)
-      body = `<tbody>${body}</tbody>`;
-    return "<table>\n<thead>\n" + header + "</thead>\n" + body + "</table>\n";
-  }
-  tablerow(content) {
-    return `<tr>
-${content}</tr>
-`;
-  }
-  tablecell(content, flags) {
-    const type = flags.header ? "th" : "td";
-    const tag = flags.align ? `<${type} align="${flags.align}">` : `<${type}>`;
-    return tag + content + `</${type}>
-`;
-  }
-  /**
-   * span level renderer
-   */
-  strong(text) {
-    return `<strong>${text}</strong>`;
-  }
-  em(text) {
-    return `<em>${text}</em>`;
-  }
-  codespan(text) {
-    return `<code>${text}</code>`;
-  }
-  br() {
-    return this.options.xhtml ? "<br/>" : "<br>";
-  }
-  del(text) {
-    return `<del>${text}</del>`;
-  }
-  link(href, title, text) {
-    href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
-    if (href === null) {
-      return text;
-    }
-    let out = '<a href="' + href + '"';
-    if (title) {
-      out += ' title="' + title + '"';
-    }
-    out += ">" + text + "</a>";
+    let out = '', i, ch;
+    const l = text.length;
+    for (i = 0; i < l; i++) {
+        ch = text.charCodeAt(i);
+        if (Math.random() > 0.5) {
+            ch = 'x' + ch.toString(16);
+        }
+        out += '&#' + ch + ';';
+    }
     return out;
-  }
-  image(href, title, text) {
-    href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
-    if (href === null) {
-      return text;
+}
+/**
+ * Block Lexer
+ */
+class _Lexer {
+    tokens;
+    options;
+    state;
+    tokenizer;
+    inlineQueue;
+    constructor(options) {
+        // TokenList cannot be created in one go
+        // @ts-expect-error
+        this.tokens = [];
+        this.tokens.links = Object.create(null);
+        this.options = options || exports.defaults;
+        this.options.tokenizer = this.options.tokenizer || new _Tokenizer();
+        this.tokenizer = this.options.tokenizer;
+        this.tokenizer.options = this.options;
+        this.tokenizer.lexer = this;
+        this.inlineQueue = [];
+        this.state = {
+            inLink: false,
+            inRawBlock: false,
+            top: true
+        };
+        const rules = {
+            block: block.normal,
+            inline: inline.normal
+        };
+        if (this.options.pedantic) {
+            rules.block = block.pedantic;
+            rules.inline = inline.pedantic;
+        }
+        else if (this.options.gfm) {
+            rules.block = block.gfm;
+            if (this.options.breaks) {
+                rules.inline = inline.breaks;
+            }
+            else {
+                rules.inline = inline.gfm;
+            }
+        }
+        this.tokenizer.rules = rules;
     }
-    let out = `<img src="${href}" alt="${text}"`;
-    if (title) {
-      out += ` title="${title}"`;
+    /**
+     * Expose Rules
+     */
+    static get rules() {
+        return {
+            block,
+            inline
+        };
     }
-    out += this.options.xhtml ? "/>" : ">";
-    return out;
-  }
-  text(text) {
-    return text;
-  }
-};
-
-// src/TextRenderer.ts
-var _TextRenderer = class {
-  // no need for block level renderers
-  strong(text) {
-    return text;
-  }
-  em(text) {
-    return text;
-  }
-  codespan(text) {
-    return text;
-  }
-  del(text) {
-    return text;
-  }
-  html(text) {
-    return text;
-  }
-  text(text) {
-    return text;
-  }
-  link(href, title, text) {
-    return "" + text;
-  }
-  image(href, title, text) {
-    return "" + text;
-  }
-  br() {
-    return "";
-  }
-};
+    /**
+     * Static Lex Method
+     */
+    static lex(src, options) {
+        const lexer = new _Lexer(options);
+        return lexer.lex(src);
+    }
+    /**
+     * Static Lex Inline Method
+     */
+    static lexInline(src, options) {
+        const lexer = new _Lexer(options);
+        return lexer.inlineTokens(src);
+    }
+    /**
+     * Preprocessing
+     */
+    lex(src) {
+        src = src
+            .replace(/\r\n|\r/g, '\n');
+        this.blockTokens(src, this.tokens);
+        let next;
+        while (next = this.inlineQueue.shift()) {
+            this.inlineTokens(next.src, next.tokens);
+        }
+        return this.tokens;
+    }
+    blockTokens(src, tokens = []) {
+        if (this.options.pedantic) {
+            src = src.replace(/\t/g, '    ').replace(/^ +$/gm, '');
+        }
+        else {
+            src = src.replace(/^( *)(\t+)/gm, (_, leading, tabs) => {
+                return leading + '    '.repeat(tabs.length);
+            });
+        }
+        let token, lastToken, cutSrc, lastParagraphClipped;
+        while (src) {
+            if (this.options.extensions
+                && this.options.extensions.block
+                && this.options.extensions.block.some((extTokenizer) => {
+                    if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
+                        src = src.substring(token.raw.length);
+                        tokens.push(token);
+                        return true;
+                    }
+                    return false;
+                })) {
+                continue;
+            }
+            // newline
+            if (token = this.tokenizer.space(src)) {
+                src = src.substring(token.raw.length);
+                if (token.raw.length === 1 && tokens.length > 0) {
+                    // if there's a single \n as a spacer, it's terminating the last line,
+                    // so move it there so that we don't get unecessary paragraph tags
+                    tokens[tokens.length - 1].raw += '\n';
+                }
+                else {
+                    tokens.push(token);
+                }
+                continue;
+            }
+            // code
+            if (token = this.tokenizer.code(src)) {
+                src = src.substring(token.raw.length);
+                lastToken = tokens[tokens.length - 1];
+                // An indented code block cannot interrupt a paragraph.
+                if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
+                    lastToken.raw += '\n' + token.raw;
+                    lastToken.text += '\n' + token.text;
+                    this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
+                }
+                else {
+                    tokens.push(token);
+                }
+                continue;
+            }
+            // fences
+            if (token = this.tokenizer.fences(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // heading
+            if (token = this.tokenizer.heading(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // hr
+            if (token = this.tokenizer.hr(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // blockquote
+            if (token = this.tokenizer.blockquote(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // list
+            if (token = this.tokenizer.list(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // html
+            if (token = this.tokenizer.html(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // def
+            if (token = this.tokenizer.def(src)) {
+                src = src.substring(token.raw.length);
+                lastToken = tokens[tokens.length - 1];
+                if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
+                    lastToken.raw += '\n' + token.raw;
+                    lastToken.text += '\n' + token.raw;
+                    this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
+                }
+                else if (!this.tokens.links[token.tag]) {
+                    this.tokens.links[token.tag] = {
+                        href: token.href,
+                        title: token.title
+                    };
+                }
+                continue;
+            }
+            // table (gfm)
+            if (token = this.tokenizer.table(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // lheading
+            if (token = this.tokenizer.lheading(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // top-level paragraph
+            // prevent paragraph consuming extensions by clipping 'src' to extension start
+            cutSrc = src;
+            if (this.options.extensions && this.options.extensions.startBlock) {
+                let startIndex = Infinity;
+                const tempSrc = src.slice(1);
+                let tempStart;
+                this.options.extensions.startBlock.forEach((getStartIndex) => {
+                    tempStart = getStartIndex.call({ lexer: this }, tempSrc);
+                    if (typeof tempStart === 'number' && tempStart >= 0) {
+                        startIndex = Math.min(startIndex, tempStart);
+                    }
+                });
+                if (startIndex < Infinity && startIndex >= 0) {
+                    cutSrc = src.substring(0, startIndex + 1);
+                }
+            }
+            if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
+                lastToken = tokens[tokens.length - 1];
+                if (lastParagraphClipped && lastToken.type === 'paragraph') {
+                    lastToken.raw += '\n' + token.raw;
+                    lastToken.text += '\n' + token.text;
+                    this.inlineQueue.pop();
+                    this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
+                }
+                else {
+                    tokens.push(token);
+                }
+                lastParagraphClipped = (cutSrc.length !== src.length);
+                src = src.substring(token.raw.length);
+                continue;
+            }
+            // text
+            if (token = this.tokenizer.text(src)) {
+                src = src.substring(token.raw.length);
+                lastToken = tokens[tokens.length - 1];
+                if (lastToken && lastToken.type === 'text') {
+                    lastToken.raw += '\n' + token.raw;
+                    lastToken.text += '\n' + token.text;
+                    this.inlineQueue.pop();
+                    this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
+                }
+                else {
+                    tokens.push(token);
+                }
+                continue;
+            }
+            if (src) {
+                const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
+                if (this.options.silent) {
+                    console.error(errMsg);
+                    break;
+                }
+                else {
+                    throw new Error(errMsg);
+                }
+            }
+        }
+        this.state.top = true;
+        return tokens;
+    }
+    inline(src, tokens = []) {
+        this.inlineQueue.push({ src, tokens });
+        return tokens;
+    }
+    /**
+     * Lexing/Compiling
+     */
+    inlineTokens(src, tokens = []) {
+        let token, lastToken, cutSrc;
+        // String with links masked to avoid interference with em and strong
+        let maskedSrc = src;
+        let match;
+        let keepPrevChar, prevChar;
+        // Mask out reflinks
+        if (this.tokens.links) {
+            const links = Object.keys(this.tokens.links);
+            if (links.length > 0) {
+                while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
+                    if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {
+                        maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
+                    }
+                }
+            }
+        }
+        // Mask out other blocks
+        while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
+            maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
+        }
+        // Mask out escaped characters
+        while ((match = this.tokenizer.rules.inline.anyPunctuation.exec(maskedSrc)) != null) {
+            maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
+        }
+        while (src) {
+            if (!keepPrevChar) {
+                prevChar = '';
+            }
+            keepPrevChar = false;
+            // extensions
+            if (this.options.extensions
+                && this.options.extensions.inline
+                && this.options.extensions.inline.some((extTokenizer) => {
+                    if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
+                        src = src.substring(token.raw.length);
+                        tokens.push(token);
+                        return true;
+                    }
+                    return false;
+                })) {
+                continue;
+            }
+            // escape
+            if (token = this.tokenizer.escape(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // tag
+            if (token = this.tokenizer.tag(src)) {
+                src = src.substring(token.raw.length);
+                lastToken = tokens[tokens.length - 1];
+                if (lastToken && token.type === 'text' && lastToken.type === 'text') {
+                    lastToken.raw += token.raw;
+                    lastToken.text += token.text;
+                }
+                else {
+                    tokens.push(token);
+                }
+                continue;
+            }
+            // link
+            if (token = this.tokenizer.link(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // reflink, nolink
+            if (token = this.tokenizer.reflink(src, this.tokens.links)) {
+                src = src.substring(token.raw.length);
+                lastToken = tokens[tokens.length - 1];
+                if (lastToken && token.type === 'text' && lastToken.type === 'text') {
+                    lastToken.raw += token.raw;
+                    lastToken.text += token.text;
+                }
+                else {
+                    tokens.push(token);
+                }
+                continue;
+            }
+            // em & strong
+            if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // code
+            if (token = this.tokenizer.codespan(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // br
+            if (token = this.tokenizer.br(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // del (gfm)
+            if (token = this.tokenizer.del(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // autolink
+            if (token = this.tokenizer.autolink(src, mangle)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // url (gfm)
+            if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // text
+            // prevent inlineText consuming extensions by clipping 'src' to extension start
+            cutSrc = src;
+            if (this.options.extensions && this.options.extensions.startInline) {
+                let startIndex = Infinity;
+                const tempSrc = src.slice(1);
+                let tempStart;
+                this.options.extensions.startInline.forEach((getStartIndex) => {
+                    tempStart = getStartIndex.call({ lexer: this }, tempSrc);
+                    if (typeof tempStart === 'number' && tempStart >= 0) {
+                        startIndex = Math.min(startIndex, tempStart);
+                    }
+                });
+                if (startIndex < Infinity && startIndex >= 0) {
+                    cutSrc = src.substring(0, startIndex + 1);
+                }
+            }
+            if (token = this.tokenizer.inlineText(cutSrc, smartypants)) {
+                src = src.substring(token.raw.length);
+                if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started
+                    prevChar = token.raw.slice(-1);
+                }
+                keepPrevChar = true;
+                lastToken = tokens[tokens.length - 1];
+                if (lastToken && lastToken.type === 'text') {
+                    lastToken.raw += token.raw;
+                    lastToken.text += token.text;
+                }
+                else {
+                    tokens.push(token);
+                }
+                continue;
+            }
+            if (src) {
+                const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
+                if (this.options.silent) {
+                    console.error(errMsg);
+                    break;
+                }
+                else {
+                    throw new Error(errMsg);
+                }
+            }
+        }
+        return tokens;
+    }
+}
 
-// src/Slugger.ts
-var _Slugger = class {
-  constructor() {
-    this.seen = {};
-  }
-  serialize(value) {
-    return value.toLowerCase().trim().replace(/<[!\/a-z].*?>/ig, "").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, "").replace(/\s/g, "-");
-  }
-  /**
-   * Finds the next safe (unique) slug to use
-   */
-  getNextSafeSlug(originalSlug, isDryRun) {
-    let slug = originalSlug;
-    let occurenceAccumulator = 0;
-    if (this.seen.hasOwnProperty(slug)) {
-      occurenceAccumulator = this.seen[originalSlug];
-      do {
-        occurenceAccumulator++;
-        slug = originalSlug + "-" + occurenceAccumulator;
-      } while (this.seen.hasOwnProperty(slug));
-    }
-    if (!isDryRun) {
-      this.seen[originalSlug] = occurenceAccumulator;
-      this.seen[slug] = 0;
-    }
-    return slug;
-  }
-  /**
-   * Convert string to unique id
-   */
-  slug(value, options2 = {}) {
-    const slug = this.serialize(value);
-    return this.getNextSafeSlug(slug, options2.dryrun);
-  }
-};
+/**
+ * Renderer
+ */
+class _Renderer {
+    options;
+    constructor(options) {
+        this.options = options || exports.defaults;
+    }
+    code(code, infostring, escaped) {
+        const lang = (infostring || '').match(/\S*/)[0];
+        if (this.options.highlight) {
+            const out = this.options.highlight(code, lang);
+            if (out != null && out !== code) {
+                escaped = true;
+                code = out;
+            }
+        }
+        code = code.replace(/\n$/, '') + '\n';
+        if (!lang) {
+            return '<pre><code>'
+                + (escaped ? code : escape(code, true))
+                + '</code></pre>\n';
+        }
+        return '<pre><code class="'
+            + this.options.langPrefix
+            + escape(lang)
+            + '">'
+            + (escaped ? code : escape(code, true))
+            + '</code></pre>\n';
+    }
+    blockquote(quote) {
+        return `<blockquote>\n${quote}</blockquote>\n`;
+    }
+    html(html, block) {
+        return html;
+    }
+    heading(text, level, raw, slugger) {
+        if (this.options.headerIds) {
+            const id = this.options.headerPrefix + slugger.slug(raw);
+            return `<h${level} id="${id}">${text}</h${level}>\n`;
+        }
+        // ignore IDs
+        return `<h${level}>${text}</h${level}>\n`;
+    }
+    hr() {
+        return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
+    }
+    list(body, ordered, start) {
+        const type = ordered ? 'ol' : 'ul', startatt = (ordered && start !== 1) ? (' start="' + start + '"') : '';
+        return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
+    }
+    listitem(text, task, checked) {
+        return `<li>${text}</li>\n`;
+    }
+    checkbox(checked) {
+        return '<input '
+            + (checked ? 'checked="" ' : '')
+            + 'disabled="" type="checkbox"'
+            + (this.options.xhtml ? ' /' : '')
+            + '> ';
+    }
+    paragraph(text) {
+        return `<p>${text}</p>\n`;
+    }
+    table(header, body) {
+        if (body)
+            body = `<tbody>${body}</tbody>`;
+        return '<table>\n'
+            + '<thead>\n'
+            + header
+            + '</thead>\n'
+            + body
+            + '</table>\n';
+    }
+    tablerow(content) {
+        return `<tr>\n${content}</tr>\n`;
+    }
+    tablecell(content, flags) {
+        const type = flags.header ? 'th' : 'td';
+        const tag = flags.align
+            ? `<${type} align="${flags.align}">`
+            : `<${type}>`;
+        return tag + content + `</${type}>\n`;
+    }
+    /**
+     * span level renderer
+     */
+    strong(text) {
+        return `<strong>${text}</strong>`;
+    }
+    em(text) {
+        return `<em>${text}</em>`;
+    }
+    codespan(text) {
+        return `<code>${text}</code>`;
+    }
+    br() {
+        return this.options.xhtml ? '<br/>' : '<br>';
+    }
+    del(text) {
+        return `<del>${text}</del>`;
+    }
+    link(href, title, text) {
+        href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
+        if (href === null) {
+            return text;
+        }
+        let out = '<a href="' + href + '"';
+        if (title) {
+            out += ' title="' + title + '"';
+        }
+        out += '>' + text + '</a>';
+        return out;
+    }
+    image(href, title, text) {
+        href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
+        if (href === null) {
+            return text;
+        }
+        let out = `<img src="${href}" alt="${text}"`;
+        if (title) {
+            out += ` title="${title}"`;
+        }
+        out += this.options.xhtml ? '/>' : '>';
+        return out;
+    }
+    text(text) {
+        return text;
+    }
+}
 
-// src/Parser.ts
-var _Parser = class __Parser {
-  constructor(options2) {
-    this.options = options2 || _defaults;
-    this.options.renderer = this.options.renderer || new _Renderer();
-    this.renderer = this.options.renderer;
-    this.renderer.options = this.options;
-    this.textRenderer = new _TextRenderer();
-    this.slugger = new _Slugger();
-  }
-  /**
-   * Static Parse Method
-   */
-  static parse(tokens, options2) {
-    const parser2 = new __Parser(options2);
-    return parser2.parse(tokens);
-  }
-  /**
-   * Static Parse Inline Method
-   */
-  static parseInline(tokens, options2) {
-    const parser2 = new __Parser(options2);
-    return parser2.parseInline(tokens);
-  }
-  /**
-   * Parse Loop
-   */
-  parse(tokens, top = true) {
-    let out = "", i, j, k, l2, l3, row, cell, header, body, token, ordered, start, loose, itemBody, item, checked, task, checkbox, ret;
-    const l = tokens.length;
-    for (i = 0; i < l; i++) {
-      token = tokens[i];
-      if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
-        ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
-        if (ret !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "html", "paragraph", "text"].includes(token.type)) {
-          out += ret || "";
-          continue;
-        }
-      }
-      switch (token.type) {
-        case "space": {
-          continue;
-        }
-        case "hr": {
-          out += this.renderer.hr();
-          continue;
-        }
-        case "heading": {
-          out += this.renderer.heading(
-            this.parseInline(token.tokens),
-            token.depth,
-            unescape(this.parseInline(token.tokens, this.textRenderer)),
-            this.slugger
-          );
-          continue;
-        }
-        case "code": {
-          out += this.renderer.code(
-            token.text,
-            token.lang,
-            !!token.escaped
-          );
-          continue;
-        }
-        case "table": {
-          header = "";
-          cell = "";
-          l2 = token.header.length;
-          for (j = 0; j < l2; j++) {
-            cell += this.renderer.tablecell(
-              this.parseInline(token.header[j].tokens),
-              { header: true, align: token.align[j] }
-            );
-          }
-          header += this.renderer.tablerow(cell);
-          body = "";
-          l2 = token.rows.length;
-          for (j = 0; j < l2; j++) {
-            row = token.rows[j];
-            cell = "";
-            l3 = row.length;
-            for (k = 0; k < l3; k++) {
-              cell += this.renderer.tablecell(
-                this.parseInline(row[k].tokens),
-                { header: false, align: token.align[k] }
-              );
-            }
-            body += this.renderer.tablerow(cell);
-          }
-          out += this.renderer.table(header, body);
-          continue;
-        }
-        case "blockquote": {
-          body = this.parse(token.tokens);
-          out += this.renderer.blockquote(body);
-          continue;
-        }
-        case "list": {
-          ordered = token.ordered;
-          start = token.start;
-          loose = token.loose;
-          l2 = token.items.length;
-          body = "";
-          for (j = 0; j < l2; j++) {
-            item = token.items[j];
-            checked = item.checked;
-            task = item.task;
-            itemBody = "";
-            if (item.task) {
-              checkbox = this.renderer.checkbox(!!checked);
-              if (loose) {
-                if (item.tokens.length > 0 && item.tokens[0].type === "paragraph") {
-                  item.tokens[0].text = checkbox + " " + item.tokens[0].text;
-                  if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === "text") {
-                    item.tokens[0].tokens[0].text = checkbox + " " + item.tokens[0].tokens[0].text;
-                  }
-                } else {
-                  item.tokens.unshift({
-                    type: "text",
-                    text: checkbox
-                  });
-                }
-              } else {
-                itemBody += checkbox;
-              }
-            }
-            itemBody += this.parse(item.tokens, loose);
-            body += this.renderer.listitem(itemBody, task, !!checked);
-          }
-          out += this.renderer.list(body, ordered, start);
-          continue;
-        }
-        case "html": {
-          out += this.renderer.html(token.text, token.block);
-          continue;
-        }
-        case "paragraph": {
-          out += this.renderer.paragraph(this.parseInline(token.tokens));
-          continue;
-        }
-        case "text": {
-          body = token.tokens ? this.parseInline(token.tokens) : token.text;
-          while (i + 1 < l && tokens[i + 1].type === "text") {
-            token = tokens[++i];
-            body += "\n" + (token.tokens ? this.parseInline(token.tokens) : token.text);
-          }
-          out += top ? this.renderer.paragraph(body) : body;
-          continue;
-        }
-        default: {
-          const errMsg = 'Token with "' + token.type + '" type was not found.';
-          if (this.options.silent) {
-            console.error(errMsg);
-            return "";
-          } else {
-            throw new Error(errMsg);
-          }
-        }
-      }
+/**
+ * TextRenderer
+ * returns only the textual part of the token
+ */
+class _TextRenderer {
+    // no need for block level renderers
+    strong(text) {
+        return text;
     }
-    return out;
-  }
-  /**
-   * Parse Inline Tokens
-   */
-  parseInline(tokens, renderer) {
-    renderer = renderer || this.renderer;
-    let out = "", i, token, ret;
-    const l = tokens.length;
-    for (i = 0; i < l; i++) {
-      token = tokens[i];
-      if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
-        ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
-        if (ret !== false || !["escape", "html", "link", "image", "strong", "em", "codespan", "br", "del", "text"].includes(token.type)) {
-          out += ret || "";
-          continue;
-        }
-      }
-      switch (token.type) {
-        case "escape": {
-          out += renderer.text(token.text);
-          break;
-        }
-        case "html": {
-          out += renderer.html(token.text);
-          break;
-        }
-        case "link": {
-          out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer));
-          break;
-        }
-        case "image": {
-          out += renderer.image(token.href, token.title, token.text);
-          break;
-        }
-        case "strong": {
-          out += renderer.strong(this.parseInline(token.tokens, renderer));
-          break;
-        }
-        case "em": {
-          out += renderer.em(this.parseInline(token.tokens, renderer));
-          break;
-        }
-        case "codespan": {
-          out += renderer.codespan(token.text);
-          break;
-        }
-        case "br": {
-          out += renderer.br();
-          break;
-        }
-        case "del": {
-          out += renderer.del(this.parseInline(token.tokens, renderer));
-          break;
-        }
-        case "text": {
-          out += renderer.text(token.text);
-          break;
-        }
-        default: {
-          const errMsg = 'Token with "' + token.type + '" type was not found.';
-          if (this.options.silent) {
-            console.error(errMsg);
-            return "";
-          } else {
-            throw new Error(errMsg);
-          }
-        }
-      }
+    em(text) {
+        return text;
     }
-    return out;
-  }
-};
+    codespan(text) {
+        return text;
+    }
+    del(text) {
+        return text;
+    }
+    html(text) {
+        return text;
+    }
+    text(text) {
+        return text;
+    }
+    link(href, title, text) {
+        return '' + text;
+    }
+    image(href, title, text) {
+        return '' + text;
+    }
+    br() {
+        return '';
+    }
+}
 
-// src/Hooks.ts
-var _Hooks = class {
-  constructor(options2) {
-    this.options = options2 || _defaults;
-  }
-  /**
-   * Process markdown before marked
-   */
-  preprocess(markdown) {
-    return markdown;
-  }
-  /**
-   * Process HTML after marked is finished
-   */
-  postprocess(html) {
-    return html;
-  }
-};
-_Hooks.passThroughHooks = /* @__PURE__ */ new Set([
-  "preprocess",
-  "postprocess"
-]);
+/**
+ * Slugger generates header id
+ */
+class _Slugger {
+    seen;
+    constructor() {
+        this.seen = {};
+    }
+    serialize(value) {
+        return value
+            .toLowerCase()
+            .trim()
+            // remove html tags
+            .replace(/<[!\/a-z].*?>/ig, '')
+            // remove unwanted chars
+            .replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, '')
+            .replace(/\s/g, '-');
+    }
+    /**
+     * Finds the next safe (unique) slug to use
+     */
+    getNextSafeSlug(originalSlug, isDryRun) {
+        let slug = originalSlug;
+        let occurenceAccumulator = 0;
+        if (this.seen.hasOwnProperty(slug)) {
+            occurenceAccumulator = this.seen[originalSlug];
+            do {
+                occurenceAccumulator++;
+                slug = originalSlug + '-' + occurenceAccumulator;
+            } while (this.seen.hasOwnProperty(slug));
+        }
+        if (!isDryRun) {
+            this.seen[originalSlug] = occurenceAccumulator;
+            this.seen[slug] = 0;
+        }
+        return slug;
+    }
+    /**
+     * Convert string to unique id
+     */
+    slug(value, options = {}) {
+        const slug = this.serialize(value);
+        return this.getNextSafeSlug(slug, options.dryrun);
+    }
+}
 
-// src/Instance.ts
-var _parseMarkdown, parseMarkdown_fn, _onError, onError_fn;
-var Marked = class {
-  constructor(...args) {
-    __privateAdd(this, _parseMarkdown);
-    __privateAdd(this, _onError);
-    this.defaults = _getDefaults();
-    this.options = this.setOptions;
-    this.parse = __privateMethod(this, _parseMarkdown, parseMarkdown_fn).call(this, _Lexer2.lex, _Parser.parse);
-    this.parseInline = __privateMethod(this, _parseMarkdown, parseMarkdown_fn).call(this, _Lexer2.lexInline, _Parser.parseInline);
-    this.Parser = _Parser;
-    this.parser = _Parser.parse;
-    this.Renderer = _Renderer;
-    this.TextRenderer = _TextRenderer;
-    this.Lexer = _Lexer2;
-    this.lexer = _Lexer2.lex;
-    this.Tokenizer = _Tokenizer;
-    this.Slugger = _Slugger;
-    this.Hooks = _Hooks;
-    this.use(...args);
-  }
-  /**
-   * Run callback for every token
-   */
-  walkTokens(tokens, callback) {
-    let values = [];
-    for (const token of tokens) {
-      values = values.concat(callback.call(this, token));
-      switch (token.type) {
-        case "table": {
-          for (const cell of token.header) {
-            values = values.concat(this.walkTokens(cell.tokens, callback));
-          }
-          for (const row of token.rows) {
-            for (const cell of row) {
-              values = values.concat(this.walkTokens(cell.tokens, callback));
-            }
-          }
-          break;
-        }
-        case "list": {
-          values = values.concat(this.walkTokens(token.items, callback));
-          break;
-        }
-        default: {
-          if (this.defaults.extensions && this.defaults.extensions.childTokens && this.defaults.extensions.childTokens[token.type]) {
-            this.defaults.extensions.childTokens[token.type].forEach((childTokens) => {
-              values = values.concat(this.walkTokens(token[childTokens], callback));
-            });
-          } else if (token.tokens) {
-            values = values.concat(this.walkTokens(token.tokens, callback));
-          }
-        }
-      }
-    }
-    return values;
-  }
-  use(...args) {
-    const extensions = this.defaults.extensions || { renderers: {}, childTokens: {} };
-    args.forEach((pack) => {
-      const opts = { ...pack };
-      opts.async = this.defaults.async || opts.async || false;
-      if (pack.extensions) {
-        pack.extensions.forEach((ext) => {
-          if (!ext.name) {
-            throw new Error("extension name required");
-          }
-          if ("renderer" in ext) {
-            const prevRenderer = extensions.renderers[ext.name];
-            if (prevRenderer) {
-              extensions.renderers[ext.name] = function(...args2) {
-                let ret = ext.renderer.apply(this, args2);
-                if (ret === false) {
-                  ret = prevRenderer.apply(this, args2);
-                }
-                return ret;
-              };
-            } else {
-              extensions.renderers[ext.name] = ext.renderer;
-            }
-          }
-          if ("tokenizer" in ext) {
-            if (!ext.level || ext.level !== "block" && ext.level !== "inline") {
-              throw new Error("extension level must be 'block' or 'inline'");
-            }
-            if (extensions[ext.level]) {
-              extensions[ext.level].unshift(ext.tokenizer);
-            } else {
-              extensions[ext.level] = [ext.tokenizer];
-            }
-            if (ext.start) {
-              if (ext.level === "block") {
-                if (extensions.startBlock) {
-                  extensions.startBlock.push(ext.start);
-                } else {
-                  extensions.startBlock = [ext.start];
-                }
-              } else if (ext.level === "inline") {
-                if (extensions.startInline) {
-                  extensions.startInline.push(ext.start);
-                } else {
-                  extensions.startInline = [ext.start];
-                }
-              }
-            }
-          }
-          if ("childTokens" in ext && ext.childTokens) {
-            extensions.childTokens[ext.name] = ext.childTokens;
-          }
-        });
-        opts.extensions = extensions;
-      }
-      if (pack.renderer) {
-        const renderer = this.defaults.renderer || new _Renderer(this.defaults);
-        for (const prop in pack.renderer) {
-          const prevRenderer = renderer[prop];
-          renderer[prop] = (...args2) => {
-            let ret = pack.renderer[prop].apply(renderer, args2);
-            if (ret === false) {
-              ret = prevRenderer.apply(renderer, args2);
-            }
-            return ret;
-          };
-        }
-        opts.renderer = renderer;
-      }
-      if (pack.tokenizer) {
-        const tokenizer = this.defaults.tokenizer || new _Tokenizer(this.defaults);
-        for (const prop in pack.tokenizer) {
-          const prevTokenizer = tokenizer[prop];
-          tokenizer[prop] = (...args2) => {
-            let ret = pack.tokenizer[prop].apply(tokenizer, args2);
-            if (ret === false) {
-              ret = prevTokenizer.apply(tokenizer, args2);
-            }
-            return ret;
-          };
-        }
-        opts.tokenizer = tokenizer;
-      }
-      if (pack.hooks) {
-        const hooks = this.defaults.hooks || new _Hooks();
-        for (const prop in pack.hooks) {
-          const prevHook = hooks[prop];
-          if (_Hooks.passThroughHooks.has(prop)) {
-            hooks[prop] = (arg) => {
-              if (this.defaults.async) {
-                return Promise.resolve(pack.hooks[prop].call(hooks, arg)).then((ret2) => {
-                  return prevHook.call(hooks, ret2);
-                });
-              }
-              const ret = pack.hooks[prop].call(hooks, arg);
-              return prevHook.call(hooks, ret);
-            };
-          } else {
-            hooks[prop] = (...args2) => {
-              let ret = pack.hooks[prop].apply(hooks, args2);
-              if (ret === false) {
-                ret = prevHook.apply(hooks, args2);
-              }
-              return ret;
-            };
-          }
-        }
-        opts.hooks = hooks;
-      }
-      if (pack.walkTokens) {
-        const walkTokens2 = this.defaults.walkTokens;
-        opts.walkTokens = function(token) {
-          let values = [];
-          values.push(pack.walkTokens.call(this, token));
-          if (walkTokens2) {
-            values = values.concat(walkTokens2.call(this, token));
-          }
-          return values;
-        };
-      }
-      this.defaults = { ...this.defaults, ...opts };
-    });
-    return this;
-  }
-  setOptions(opt) {
-    this.defaults = { ...this.defaults, ...opt };
-    return this;
-  }
-};
-_parseMarkdown = new WeakSet();
-parseMarkdown_fn = function(lexer2, parser2) {
-  return (src, optOrCallback, callback) => {
-    if (typeof optOrCallback === "function") {
-      callback = optOrCallback;
-      optOrCallback = null;
-    }
-    const origOpt = { ...optOrCallback };
-    const opt = { ...this.defaults, ...origOpt };
-    const throwError = __privateMethod(this, _onError, onError_fn).call(this, !!opt.silent, !!opt.async, callback);
-    if (typeof src === "undefined" || src === null) {
-      return throwError(new Error("marked(): input parameter is undefined or null"));
-    }
-    if (typeof src !== "string") {
-      return throwError(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(src) + ", string expected"));
-    }
-    checkDeprecations(opt, callback);
-    if (opt.hooks) {
-      opt.hooks.options = opt;
+/**
+ * Parsing & Compiling
+ */
+class _Parser {
+    options;
+    renderer;
+    textRenderer;
+    slugger;
+    constructor(options) {
+        this.options = options || exports.defaults;
+        this.options.renderer = this.options.renderer || new _Renderer();
+        this.renderer = this.options.renderer;
+        this.renderer.options = this.options;
+        this.textRenderer = new _TextRenderer();
+        this.slugger = new _Slugger();
+    }
+    /**
+     * Static Parse Method
+     */
+    static parse(tokens, options) {
+        const parser = new _Parser(options);
+        return parser.parse(tokens);
+    }
+    /**
+     * Static Parse Inline Method
+     */
+    static parseInline(tokens, options) {
+        const parser = new _Parser(options);
+        return parser.parseInline(tokens);
+    }
+    /**
+     * Parse Loop
+     */
+    parse(tokens, top = true) {
+        let out = '', i, j, k, l2, l3, row, cell, header, body, token, ordered, start, loose, itemBody, item, checked, task, checkbox, ret;
+        const l = tokens.length;
+        for (i = 0; i < l; i++) {
+            token = tokens[i];
+            // Run any renderer extensions
+            if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
+                ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
+                if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(token.type)) {
+                    out += ret || '';
+                    continue;
+                }
+            }
+            switch (token.type) {
+                case 'space': {
+                    continue;
+                }
+                case 'hr': {
+                    out += this.renderer.hr();
+                    continue;
+                }
+                case 'heading': {
+                    out += this.renderer.heading(this.parseInline(token.tokens), token.depth, unescape(this.parseInline(token.tokens, this.textRenderer)), this.slugger);
+                    continue;
+                }
+                case 'code': {
+                    out += this.renderer.code(token.text, token.lang, !!token.escaped);
+                    continue;
+                }
+                case 'table': {
+                    header = '';
+                    // header
+                    cell = '';
+                    l2 = token.header.length;
+                    for (j = 0; j < l2; j++) {
+                        cell += this.renderer.tablecell(this.parseInline(token.header[j].tokens), { header: true, align: token.align[j] });
+                    }
+                    header += this.renderer.tablerow(cell);
+                    body = '';
+                    l2 = token.rows.length;
+                    for (j = 0; j < l2; j++) {
+                        row = token.rows[j];
+                        cell = '';
+                        l3 = row.length;
+                        for (k = 0; k < l3; k++) {
+                            cell += this.renderer.tablecell(this.parseInline(row[k].tokens), { header: false, align: token.align[k] });
+                        }
+                        body += this.renderer.tablerow(cell);
+                    }
+                    out += this.renderer.table(header, body);
+                    continue;
+                }
+                case 'blockquote': {
+                    body = this.parse(token.tokens);
+                    out += this.renderer.blockquote(body);
+                    continue;
+                }
+                case 'list': {
+                    ordered = token.ordered;
+                    start = token.start;
+                    loose = token.loose;
+                    l2 = token.items.length;
+                    body = '';
+                    for (j = 0; j < l2; j++) {
+                        item = token.items[j];
+                        checked = item.checked;
+                        task = item.task;
+                        itemBody = '';
+                        if (item.task) {
+                            checkbox = this.renderer.checkbox(!!checked);
+                            if (loose) {
+                                if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {
+                                    item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
+                                    if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
+                                        item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text;
+                                    }
+                                }
+                                else {
+                                    item.tokens.unshift({
+                                        type: 'text',
+                                        text: checkbox
+                                    });
+                                }
+                            }
+                            else {
+                                itemBody += checkbox;
+                            }
+                        }
+                        itemBody += this.parse(item.tokens, loose);
+                        body += this.renderer.listitem(itemBody, task, !!checked);
+                    }
+                    out += this.renderer.list(body, ordered, start);
+                    continue;
+                }
+                case 'html': {
+                    out += this.renderer.html(token.text, token.block);
+                    continue;
+                }
+                case 'paragraph': {
+                    out += this.renderer.paragraph(this.parseInline(token.tokens));
+                    continue;
+                }
+                case 'text': {
+                    body = token.tokens ? this.parseInline(token.tokens) : token.text;
+                    while (i + 1 < l && tokens[i + 1].type === 'text') {
+                        token = tokens[++i];
+                        body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text);
+                    }
+                    out += top ? this.renderer.paragraph(body) : body;
+                    continue;
+                }
+                default: {
+                    const errMsg = 'Token with "' + token.type + '" type was not found.';
+                    if (this.options.silent) {
+                        console.error(errMsg);
+                        return '';
+                    }
+                    else {
+                        throw new Error(errMsg);
+                    }
+                }
+            }
+        }
+        return out;
     }
-    if (callback) {
-      const highlight = opt.highlight;
-      let tokens;
-      try {
-        if (opt.hooks) {
-          src = opt.hooks.preprocess(src);
-        }
-        tokens = lexer2(src, opt);
-      } catch (e) {
-        return throwError(e);
-      }
-      const done = (err) => {
-        let out;
-        if (!err) {
-          try {
-            if (opt.walkTokens) {
-              this.walkTokens(tokens, opt.walkTokens);
-            }
-            out = parser2(tokens, opt);
-            if (opt.hooks) {
-              out = opt.hooks.postprocess(out);
-            }
-          } catch (e) {
-            err = e;
-          }
-        }
-        opt.highlight = highlight;
-        return err ? throwError(err) : callback(null, out);
-      };
-      if (!highlight || highlight.length < 3) {
-        return done();
-      }
-      delete opt.highlight;
-      if (!tokens.length)
-        return done();
-      let pending = 0;
-      this.walkTokens(tokens, (token) => {
-        if (token.type === "code") {
-          pending++;
-          setTimeout(() => {
-            highlight(token.text, token.lang, (err, code) => {
-              if (err) {
-                return done(err);
-              }
-              if (code != null && code !== token.text) {
-                token.text = code;
-                token.escaped = true;
-              }
-              pending--;
-              if (pending === 0) {
-                done();
-              }
-            });
-          }, 0);
+    /**
+     * Parse Inline Tokens
+     */
+    parseInline(tokens, renderer) {
+        renderer = renderer || this.renderer;
+        let out = '', i, token, ret;
+        const l = tokens.length;
+        for (i = 0; i < l; i++) {
+            token = tokens[i];
+            // Run any renderer extensions
+            if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
+                ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
+                if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) {
+                    out += ret || '';
+                    continue;
+                }
+            }
+            switch (token.type) {
+                case 'escape': {
+                    out += renderer.text(token.text);
+                    break;
+                }
+                case 'html': {
+                    out += renderer.html(token.text);
+                    break;
+                }
+                case 'link': {
+                    out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer));
+                    break;
+                }
+                case 'image': {
+                    out += renderer.image(token.href, token.title, token.text);
+                    break;
+                }
+                case 'strong': {
+                    out += renderer.strong(this.parseInline(token.tokens, renderer));
+                    break;
+                }
+                case 'em': {
+                    out += renderer.em(this.parseInline(token.tokens, renderer));
+                    break;
+                }
+                case 'codespan': {
+                    out += renderer.codespan(token.text);
+                    break;
+                }
+                case 'br': {
+                    out += renderer.br();
+                    break;
+                }
+                case 'del': {
+                    out += renderer.del(this.parseInline(token.tokens, renderer));
+                    break;
+                }
+                case 'text': {
+                    out += renderer.text(token.text);
+                    break;
+                }
+                default: {
+                    const errMsg = 'Token with "' + token.type + '" type was not found.';
+                    if (this.options.silent) {
+                        console.error(errMsg);
+                        return '';
+                    }
+                    else {
+                        throw new Error(errMsg);
+                    }
+                }
+            }
         }
-      });
-      if (pending === 0) {
-        done();
-      }
-      return;
+        return out;
     }
-    if (opt.async) {
-      return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src).then((src2) => lexer2(src2, opt)).then((tokens) => opt.walkTokens ? Promise.all(this.walkTokens(tokens, opt.walkTokens)).then(() => tokens) : tokens).then((tokens) => parser2(tokens, opt)).then((html) => opt.hooks ? opt.hooks.postprocess(html) : html).catch(throwError);
+}
+
+class _Hooks {
+    options;
+    constructor(options) {
+        this.options = options || exports.defaults;
+    }
+    static passThroughHooks = new Set([
+        'preprocess',
+        'postprocess'
+    ]);
+    /**
+     * Process markdown before marked
+     */
+    preprocess(markdown) {
+        return markdown;
+    }
+    /**
+     * Process HTML after marked is finished
+     */
+    postprocess(html) {
+        return html;
     }
-    try {
-      if (opt.hooks) {
-        src = opt.hooks.preprocess(src);
-      }
-      const tokens = lexer2(src, opt);
-      if (opt.walkTokens) {
-        this.walkTokens(tokens, opt.walkTokens);
-      }
-      let html = parser2(tokens, opt);
-      if (opt.hooks) {
-        html = opt.hooks.postprocess(html);
-      }
-      return html;
-    } catch (e) {
-      return throwError(e);
-    }
-  };
-};
-_onError = new WeakSet();
-onError_fn = function(silent, async, callback) {
-  return (e) => {
-    e.message += "\nPlease report this to https://github.com/markedjs/marked.";
-    if (silent) {
-      const msg = "<p>An error occurred:</p><pre>" + escape(e.message + "", true) + "</pre>";
-      if (async) {
-        return Promise.resolve(msg);
-      }
-      if (callback) {
-        callback(null, msg);
-        return;
-      }
-      return msg;
+}
+
+class Marked {
+    defaults = _getDefaults();
+    options = this.setOptions;
+    parse = this.#parseMarkdown(_Lexer.lex, _Parser.parse);
+    parseInline = this.#parseMarkdown(_Lexer.lexInline, _Parser.parseInline);
+    Parser = _Parser;
+    parser = _Parser.parse;
+    Renderer = _Renderer;
+    TextRenderer = _TextRenderer;
+    Lexer = _Lexer;
+    lexer = _Lexer.lex;
+    Tokenizer = _Tokenizer;
+    Slugger = _Slugger;
+    Hooks = _Hooks;
+    constructor(...args) {
+        this.use(...args);
+    }
+    /**
+     * Run callback for every token
+     */
+    walkTokens(tokens, callback) {
+        let values = [];
+        for (const token of tokens) {
+            values = values.concat(callback.call(this, token));
+            switch (token.type) {
+                case 'table': {
+                    for (const cell of token.header) {
+                        values = values.concat(this.walkTokens(cell.tokens, callback));
+                    }
+                    for (const row of token.rows) {
+                        for (const cell of row) {
+                            values = values.concat(this.walkTokens(cell.tokens, callback));
+                        }
+                    }
+                    break;
+                }
+                case 'list': {
+                    values = values.concat(this.walkTokens(token.items, callback));
+                    break;
+                }
+                default: {
+                    if (this.defaults.extensions && this.defaults.extensions.childTokens && this.defaults.extensions.childTokens[token.type]) { // Walk any extensions
+                        this.defaults.extensions.childTokens[token.type].forEach((childTokens) => {
+                            values = values.concat(this.walkTokens(token[childTokens], callback));
+                        });
+                    }
+                    else if (token.tokens) {
+                        values = values.concat(this.walkTokens(token.tokens, callback));
+                    }
+                }
+            }
+        }
+        return values;
+    }
+    use(...args) {
+        const extensions = this.defaults.extensions || { renderers: {}, childTokens: {} };
+        args.forEach((pack) => {
+            // copy options to new object
+            const opts = { ...pack };
+            // set async to true if it was set to true before
+            opts.async = this.defaults.async || opts.async || false;
+            // ==-- Parse "addon" extensions --== //
+            if (pack.extensions) {
+                pack.extensions.forEach((ext) => {
+                    if (!ext.name) {
+                        throw new Error('extension name required');
+                    }
+                    if ('renderer' in ext) { // Renderer extensions
+                        const prevRenderer = extensions.renderers[ext.name];
+                        if (prevRenderer) {
+                            // Replace extension with func to run new extension but fall back if false
+                            extensions.renderers[ext.name] = function (...args) {
+                                let ret = ext.renderer.apply(this, args);
+                                if (ret === false) {
+                                    ret = prevRenderer.apply(this, args);
+                                }
+                                return ret;
+                            };
+                        }
+                        else {
+                            extensions.renderers[ext.name] = ext.renderer;
+                        }
+                    }
+                    if ('tokenizer' in ext) { // Tokenizer Extensions
+                        if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) {
+                            throw new Error("extension level must be 'block' or 'inline'");
+                        }
+                        if (extensions[ext.level]) {
+                            extensions[ext.level].unshift(ext.tokenizer);
+                        }
+                        else {
+                            extensions[ext.level] = [ext.tokenizer];
+                        }
+                        if (ext.start) { // Function to check for start of token
+                            if (ext.level === 'block') {
+                                if (extensions.startBlock) {
+                                    extensions.startBlock.push(ext.start);
+                                }
+                                else {
+                                    extensions.startBlock = [ext.start];
+                                }
+                            }
+                            else if (ext.level === 'inline') {
+                                if (extensions.startInline) {
+                                    extensions.startInline.push(ext.start);
+                                }
+                                else {
+                                    extensions.startInline = [ext.start];
+                                }
+                            }
+                        }
+                    }
+                    if ('childTokens' in ext && ext.childTokens) { // Child tokens to be visited by walkTokens
+                        extensions.childTokens[ext.name] = ext.childTokens;
+                    }
+                });
+                opts.extensions = extensions;
+            }
+            // ==-- Parse "overwrite" extensions --== //
+            if (pack.renderer) {
+                const renderer = this.defaults.renderer || new _Renderer(this.defaults);
+                for (const prop in pack.renderer) {
+                    const prevRenderer = renderer[prop];
+                    // Replace renderer with func to run extension, but fall back if false
+                    renderer[prop] = (...args) => {
+                        let ret = pack.renderer[prop].apply(renderer, args);
+                        if (ret === false) {
+                            ret = prevRenderer.apply(renderer, args);
+                        }
+                        return ret;
+                    };
+                }
+                opts.renderer = renderer;
+            }
+            if (pack.tokenizer) {
+                const tokenizer = this.defaults.tokenizer || new _Tokenizer(this.defaults);
+                for (const prop in pack.tokenizer) {
+                    const prevTokenizer = tokenizer[prop];
+                    // Replace tokenizer with func to run extension, but fall back if false
+                    tokenizer[prop] = (...args) => {
+                        let ret = pack.tokenizer[prop].apply(tokenizer, args);
+                        if (ret === false) {
+                            ret = prevTokenizer.apply(tokenizer, args);
+                        }
+                        return ret;
+                    };
+                }
+                opts.tokenizer = tokenizer;
+            }
+            // ==-- Parse Hooks extensions --== //
+            if (pack.hooks) {
+                const hooks = this.defaults.hooks || new _Hooks();
+                for (const prop in pack.hooks) {
+                    const prevHook = hooks[prop];
+                    if (_Hooks.passThroughHooks.has(prop)) {
+                        hooks[prop] = (arg) => {
+                            if (this.defaults.async) {
+                                return Promise.resolve(pack.hooks[prop].call(hooks, arg)).then(ret => {
+                                    return prevHook.call(hooks, ret);
+                                });
+                            }
+                            const ret = pack.hooks[prop].call(hooks, arg);
+                            return prevHook.call(hooks, ret);
+                        };
+                    }
+                    else {
+                        hooks[prop] = (...args) => {
+                            let ret = pack.hooks[prop].apply(hooks, args);
+                            if (ret === false) {
+                                ret = prevHook.apply(hooks, args);
+                            }
+                            return ret;
+                        };
+                    }
+                }
+                opts.hooks = hooks;
+            }
+            // ==-- Parse WalkTokens extensions --== //
+            if (pack.walkTokens) {
+                const walkTokens = this.defaults.walkTokens;
+                opts.walkTokens = function (token) {
+                    let values = [];
+                    values.push(pack.walkTokens.call(this, token));
+                    if (walkTokens) {
+                        values = values.concat(walkTokens.call(this, token));
+                    }
+                    return values;
+                };
+            }
+            this.defaults = { ...this.defaults, ...opts };
+        });
+        return this;
     }
-    if (async) {
-      return Promise.reject(e);
+    setOptions(opt) {
+        this.defaults = { ...this.defaults, ...opt };
+        return this;
     }
-    if (callback) {
-      callback(e);
-      return;
+    #parseMarkdown(lexer, parser) {
+        return (src, optOrCallback, callback) => {
+            if (typeof optOrCallback === 'function') {
+                callback = optOrCallback;
+                optOrCallback = null;
+            }
+            const origOpt = { ...optOrCallback };
+            const opt = { ...this.defaults, ...origOpt };
+            const throwError = this.#onError(!!opt.silent, !!opt.async, callback);
+            // throw error in case of non string input
+            if (typeof src === 'undefined' || src === null) {
+                return throwError(new Error('marked(): input parameter is undefined or null'));
+            }
+            if (typeof src !== 'string') {
+                return throwError(new Error('marked(): input parameter is of type '
+                    + Object.prototype.toString.call(src) + ', string expected'));
+            }
+            checkDeprecations(opt, callback);
+            if (opt.hooks) {
+                opt.hooks.options = opt;
+            }
+            if (callback) {
+                const highlight = opt.highlight;
+                let tokens;
+                try {
+                    if (opt.hooks) {
+                        src = opt.hooks.preprocess(src);
+                    }
+                    tokens = lexer(src, opt);
+                }
+                catch (e) {
+                    return throwError(e);
+                }
+                const done = (err) => {
+                    let out;
+                    if (!err) {
+                        try {
+                            if (opt.walkTokens) {
+                                this.walkTokens(tokens, opt.walkTokens);
+                            }
+                            out = parser(tokens, opt);
+                            if (opt.hooks) {
+                                out = opt.hooks.postprocess(out);
+                            }
+                        }
+                        catch (e) {
+                            err = e;
+                        }
+                    }
+                    opt.highlight = highlight;
+                    return err
+                        ? throwError(err)
+                        : callback(null, out);
+                };
+                if (!highlight || highlight.length < 3) {
+                    return done();
+                }
+                delete opt.highlight;
+                if (!tokens.length)
+                    return done();
+                let pending = 0;
+                this.walkTokens(tokens, (token) => {
+                    if (token.type === 'code') {
+                        pending++;
+                        setTimeout(() => {
+                            highlight(token.text, token.lang, (err, code) => {
+                                if (err) {
+                                    return done(err);
+                                }
+                                if (code != null && code !== token.text) {
+                                    token.text = code;
+                                    token.escaped = true;
+                                }
+                                pending--;
+                                if (pending === 0) {
+                                    done();
+                                }
+                            });
+                        }, 0);
+                    }
+                });
+                if (pending === 0) {
+                    done();
+                }
+                return;
+            }
+            if (opt.async) {
+                return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src)
+                    .then(src => lexer(src, opt))
+                    .then(tokens => opt.walkTokens ? Promise.all(this.walkTokens(tokens, opt.walkTokens)).then(() => tokens) : tokens)
+                    .then(tokens => parser(tokens, opt))
+                    .then(html => opt.hooks ? opt.hooks.postprocess(html) : html)
+                    .catch(throwError);
+            }
+            try {
+                if (opt.hooks) {
+                    src = opt.hooks.preprocess(src);
+                }
+                const tokens = lexer(src, opt);
+                if (opt.walkTokens) {
+                    this.walkTokens(tokens, opt.walkTokens);
+                }
+                let html = parser(tokens, opt);
+                if (opt.hooks) {
+                    html = opt.hooks.postprocess(html);
+                }
+                return html;
+            }
+            catch (e) {
+                return throwError(e);
+            }
+        };
     }
-    throw e;
-  };
-};
+    #onError(silent, async, callback) {
+        return (e) => {
+            e.message += '\nPlease report this to https://github.com/markedjs/marked.';
+            if (silent) {
+                const msg = '<p>An error occurred:</p><pre>'
+                    + escape(e.message + '', true)
+                    + '</pre>';
+                if (async) {
+                    return Promise.resolve(msg);
+                }
+                if (callback) {
+                    callback(null, msg);
+                    return;
+                }
+                return msg;
+            }
+            if (async) {
+                return Promise.reject(e);
+            }
+            if (callback) {
+                callback(e);
+                return;
+            }
+            throw e;
+        };
+    }
+}
 
-// src/marked.ts
-var markedInstance = new Marked();
+const markedInstance = new Marked();
 function marked(src, opt, callback) {
-  return markedInstance.parse(src, opt, callback);
+    return markedInstance.parse(src, opt, callback);
 }
-marked.options = marked.setOptions = function(options2) {
-  markedInstance.setOptions(options2);
-  marked.defaults = markedInstance.defaults;
-  changeDefaults(marked.defaults);
-  return marked;
-};
+/**
+ * Sets the default options.
+ *
+ * @param options Hash of options
+ */
+marked.options =
+    marked.setOptions = function (options) {
+        markedInstance.setOptions(options);
+        marked.defaults = markedInstance.defaults;
+        changeDefaults(marked.defaults);
+        return marked;
+    };
+/**
+ * Gets the original marked default options.
+ */
 marked.getDefaults = _getDefaults;
-marked.defaults = _defaults;
-marked.use = function(...args) {
-  markedInstance.use(...args);
-  marked.defaults = markedInstance.defaults;
-  changeDefaults(marked.defaults);
-  return marked;
+marked.defaults = exports.defaults;
+/**
+ * Use Extension
+ */
+marked.use = function (...args) {
+    markedInstance.use(...args);
+    marked.defaults = markedInstance.defaults;
+    changeDefaults(marked.defaults);
+    return marked;
 };
-marked.walkTokens = function(tokens, callback) {
-  return markedInstance.walkTokens(tokens, callback);
+/**
+ * Run callback for every token
+ */
+marked.walkTokens = function (tokens, callback) {
+    return markedInstance.walkTokens(tokens, callback);
 };
+/**
+ * Compiles markdown to HTML without enclosing `p` tag.
+ *
+ * @param src String of markdown source to be compiled
+ * @param options Hash of options
+ * @return String of compiled HTML
+ */
 marked.parseInline = markedInstance.parseInline;
+/**
+ * Expose
+ */
 marked.Parser = _Parser;
 marked.parser = _Parser.parse;
 marked.Renderer = _Renderer;
 marked.TextRenderer = _TextRenderer;
-marked.Lexer = _Lexer2;
-marked.lexer = _Lexer2.lex;
+marked.Lexer = _Lexer;
+marked.lexer = _Lexer.lex;
 marked.Tokenizer = _Tokenizer;
 marked.Slugger = _Slugger;
 marked.Hooks = _Hooks;
 marked.parse = marked;
-var options = marked.options;
-var setOptions = marked.setOptions;
-var use = marked.use;
-var walkTokens = marked.walkTokens;
-var parseInline = marked.parseInline;
-var parse = marked;
-var parser = _Parser.parse;
-var lexer = _Lexer2.lex;
-// Annotate the CommonJS export names for ESM import in node:
-0 && (module.exports = {
-  Hooks,
-  Lexer,
-  Marked,
-  Parser,
-  Renderer,
-  Slugger,
-  TextRenderer,
-  Tokenizer,
-  defaults,
-  getDefaults,
-  lexer,
-  marked,
-  options,
-  parse,
-  parseInline,
-  parser,
-  setOptions,
-  use,
-  walkTokens
-});
-//# sourceMappingURL=marked.cjs.map
+const options = marked.options;
+const setOptions = marked.setOptions;
+const use = marked.use;
+const walkTokens = marked.walkTokens;
+const parseInline = marked.parseInline;
+const parse = marked;
+const parser = _Parser.parse;
+const lexer = _Lexer.lex;
+
+exports.Hooks = _Hooks;
+exports.Lexer = _Lexer;
+exports.Marked = Marked;
+exports.Parser = _Parser;
+exports.Renderer = _Renderer;
+exports.Slugger = _Slugger;
+exports.TextRenderer = _TextRenderer;
+exports.Tokenizer = _Tokenizer;
+exports.getDefaults = _getDefaults;
+exports.lexer = lexer;
+exports.marked = marked;
+exports.options = options;
+exports.parse = parse;
+exports.parseInline = parseInline;
+exports.parser = parser;
+exports.setOptions = setOptions;
+exports.use = use;
+exports.walkTokens = walkTokens;
+//# sourceMappingURL=marked.cjs.map

File diff suppressed because it is too large
+ 0 - 0
lib/marked.cjs.map


+ 691 - 591
lib/marked.d.ts

@@ -1,624 +1,724 @@
-type Token = (Tokens.Space | Tokens.Code | Tokens.Heading | Tokens.Table | Tokens.Hr | Tokens.Blockquote | Tokens.List | Tokens.ListItem | Tokens.Paragraph | Tokens.HTML | Tokens.Text | Tokens.Def | Tokens.Escape | Tokens.Tag | Tokens.Image | Tokens.Link | Tokens.Strong | Tokens.Em | Tokens.Codespan | Tokens.Br | Tokens.Del) & {
-    loose?: boolean;
-    tokens?: Token[];
-};
-declare namespace Tokens {
-    interface Space {
-        type: 'space';
-        raw: string;
-    }
-    interface Code {
-        type: 'code';
-        raw: string;
-        codeBlockStyle?: 'indented' | undefined;
-        lang?: string | undefined;
-        text: string;
-        escaped?: boolean;
-    }
-    interface Heading {
-        type: 'heading';
-        raw: string;
-        depth: number;
-        text: string;
-        tokens: Token[];
-    }
-    interface Table {
-        type: 'table';
-        raw?: string;
-        align: Array<'center' | 'left' | 'right' | null>;
-        header: TableCell[];
-        rows: TableCell[][];
-    }
-    interface TableCell {
-        text: string;
-        tokens?: Token[];
-    }
-    interface Hr {
-        type: 'hr';
-        raw: string;
-    }
-    interface Blockquote {
-        type: 'blockquote';
-        raw: string;
-        text: string;
-        tokens: Token[];
-    }
-    interface List {
-        type: 'list';
-        raw: string;
-        ordered: boolean;
-        start: number | '';
-        loose: boolean;
-        items: ListItem[];
-    }
-    interface ListItem {
-        type: 'list_item';
-        raw: string;
-        task: boolean;
-        checked?: boolean | undefined;
-        loose: boolean;
-        text: string;
-        tokens?: Token[];
-    }
-    interface Paragraph {
-        type: 'paragraph';
-        raw: string;
-        pre?: boolean | undefined;
-        text: string;
-        tokens: Token[];
-    }
-    interface HTML {
-        type: 'html';
-        raw: string;
-        pre: boolean;
-        text: string;
-        block: boolean;
-    }
-    interface Text {
-        type: 'text';
-        raw: string;
-        text: string;
+declare module "Tokens" {
+    export type Token = (Tokens.Space | Tokens.Code | Tokens.Heading | Tokens.Table | Tokens.Hr | Tokens.Blockquote | Tokens.List | Tokens.ListItem | Tokens.Paragraph | Tokens.HTML | Tokens.Text | Tokens.Def | Tokens.Escape | Tokens.Tag | Tokens.Image | Tokens.Link | Tokens.Strong | Tokens.Em | Tokens.Codespan | Tokens.Br | Tokens.Del) & {
+        loose?: boolean;
         tokens?: Token[];
+    };
+    export namespace Tokens {
+        interface Space {
+            type: 'space';
+            raw: string;
+        }
+        interface Code {
+            type: 'code';
+            raw: string;
+            codeBlockStyle?: 'indented' | undefined;
+            lang?: string | undefined;
+            text: string;
+            escaped?: boolean;
+        }
+        interface Heading {
+            type: 'heading';
+            raw: string;
+            depth: number;
+            text: string;
+            tokens: Token[];
+        }
+        interface Table {
+            type: 'table';
+            raw?: string;
+            align: Array<'center' | 'left' | 'right' | null>;
+            header: TableCell[];
+            rows: TableCell[][];
+        }
+        interface TableCell {
+            text: string;
+            tokens?: Token[];
+        }
+        interface Hr {
+            type: 'hr';
+            raw: string;
+        }
+        interface Blockquote {
+            type: 'blockquote';
+            raw: string;
+            text: string;
+            tokens: Token[];
+        }
+        interface List {
+            type: 'list';
+            raw: string;
+            ordered: boolean;
+            start: number | '';
+            loose: boolean;
+            items: ListItem[];
+        }
+        interface ListItem {
+            type: 'list_item';
+            raw: string;
+            task: boolean;
+            checked?: boolean | undefined;
+            loose: boolean;
+            text: string;
+            tokens?: Token[];
+        }
+        interface Paragraph {
+            type: 'paragraph';
+            raw: string;
+            pre?: boolean | undefined;
+            text: string;
+            tokens: Token[];
+        }
+        interface HTML {
+            type: 'html';
+            raw: string;
+            pre: boolean;
+            text: string;
+            block: boolean;
+        }
+        interface Text {
+            type: 'text';
+            raw: string;
+            text: string;
+            tokens?: Token[];
+        }
+        interface Def {
+            type: 'def';
+            raw: string;
+            tag: string;
+            href: string;
+            title: string;
+        }
+        interface Escape {
+            type: 'escape';
+            raw: string;
+            text: string;
+        }
+        interface Tag {
+            type: 'text' | 'html';
+            raw: string;
+            inLink: boolean;
+            inRawBlock: boolean;
+            text: string;
+            block: boolean;
+        }
+        interface Link {
+            type: 'link';
+            raw: string;
+            href: string;
+            title?: string | null;
+            text: string;
+            tokens: Token[];
+        }
+        interface Image {
+            type: 'image';
+            raw: string;
+            href: string;
+            title: string | null;
+            text: string;
+        }
+        interface Strong {
+            type: 'strong';
+            raw: string;
+            text: string;
+            tokens: Token[];
+        }
+        interface Em {
+            type: 'em';
+            raw: string;
+            text: string;
+            tokens: Token[];
+        }
+        interface Codespan {
+            type: 'codespan';
+            raw: string;
+            text: string;
+        }
+        interface Br {
+            type: 'br';
+            raw: string;
+        }
+        interface Del {
+            type: 'del';
+            raw: string;
+            text: string;
+            tokens: Token[];
+        }
+        interface Generic {
+            [index: string]: any;
+            type: string;
+            raw: string;
+            tokens?: Token[] | undefined;
+        }
     }
-    interface Def {
-        type: 'def';
-        raw: string;
-        tag: string;
-        href: string;
-        title: string;
-    }
-    interface Escape {
-        type: 'escape';
-        raw: string;
-        text: string;
-    }
-    interface Tag {
-        type: 'text' | 'html';
-        raw: string;
-        inLink: boolean;
-        inRawBlock: boolean;
-        text: string;
-        block: boolean;
-    }
-    interface Link {
-        type: 'link';
-        raw: string;
-        href: string;
-        title?: string | null;
-        text: string;
-        tokens: Token[];
-    }
-    interface Image {
-        type: 'image';
-        raw: string;
-        href: string;
-        title: string | null;
-        text: string;
-    }
-    interface Strong {
-        type: 'strong';
-        raw: string;
-        text: string;
-        tokens: Token[];
-    }
-    interface Em {
-        type: 'em';
-        raw: string;
-        text: string;
-        tokens: Token[];
-    }
-    interface Codespan {
-        type: 'codespan';
-        raw: string;
-        text: string;
-    }
-    interface Br {
-        type: 'br';
-        raw: string;
-    }
-    interface Del {
-        type: 'del';
-        raw: string;
-        text: string;
-        tokens: Token[];
-    }
-    interface Generic {
-        [index: string]: any;
-        type: string;
-        raw: string;
-        tokens?: Token[] | undefined;
-    }
-}
-type Links = Record<string, Pick<Tokens.Link | Tokens.Image, 'href' | 'title'>>;
-type TokensList = Token[] & {
-    links: Links;
-};
-
-/**
- * Renderer
- */
-declare class _Renderer {
-    options: MarkedOptions;
-    constructor(options?: MarkedOptions);
-    code(code: string, infostring: string | undefined, escaped: boolean): string;
-    blockquote(quote: string): string;
-    html(html: string, block?: boolean): string;
-    heading(text: string, level: number, raw: string, slugger: _Slugger): string;
-    hr(): string;
-    list(body: string, ordered: boolean, start: number | ''): string;
-    listitem(text: string, task: boolean, checked: boolean): string;
-    checkbox(checked: boolean): string;
-    paragraph(text: string): string;
-    table(header: string, body: string): string;
-    tablerow(content: string): string;
-    tablecell(content: string, flags: {
-        header: boolean;
-        align: 'center' | 'left' | 'right' | null;
-    }): string;
-    /**
-     * span level renderer
-     */
-    strong(text: string): string;
-    em(text: string): string;
-    codespan(text: string): string;
-    br(): string;
-    del(text: string): string;
-    link(href: string, title: string | null | undefined, text: string): string;
-    image(href: string, title: string | null, text: string): string;
-    text(text: string): string;
-}
-
-/**
- * TextRenderer
- * returns only the textual part of the token
- */
-declare class _TextRenderer {
-    strong(text: string): string;
-    em(text: string): string;
-    codespan(text: string): string;
-    del(text: string): string;
-    html(text: string): string;
-    text(text: string): string;
-    link(href: string, title: string | null | undefined, text: string): string;
-    image(href: string, title: string | null, text: string): string;
-    br(): string;
-}
-
-/**
- * Slugger generates header id
- */
-declare class _Slugger {
-    seen: {
-        [slugValue: string]: number;
+    export type Links = Record<string, Pick<Tokens.Link | Tokens.Image, 'href' | 'title'>>;
+    export type TokensList = Token[] & {
+        links: Links;
     };
-    constructor();
-    serialize(value: string): string;
-    /**
-     * Finds the next safe (unique) slug to use
-     */
-    getNextSafeSlug(originalSlug: string, isDryRun: boolean | undefined): string;
-    /**
-     * Convert string to unique id
-     */
-    slug(value: string, options?: SluggerOptions): string;
 }
-
-/**
- * Parsing & Compiling
- */
-declare class _Parser {
-    options: MarkedOptions;
-    renderer: _Renderer;
-    textRenderer: _TextRenderer;
-    slugger: _Slugger;
-    constructor(options?: MarkedOptions);
-    /**
-     * Static Parse Method
-     */
-    static parse(tokens: Token[], options?: MarkedOptions): string;
-    /**
-     * Static Parse Inline Method
-     */
-    static parseInline(tokens: Token[], options?: MarkedOptions): string;
+declare module "Tokenizer" {
+    import { _Lexer } from "Lexer";
+    import type { Links, Tokens } from "Tokens";
+    import type { MarkedOptions } from "MarkedOptions";
+    /**
+     * Tokenizer
+     */
+    export class _Tokenizer {
+        options: MarkedOptions;
+        rules: any;
+        lexer: _Lexer;
+        constructor(options?: MarkedOptions);
+        space(src: string): Tokens.Space | undefined;
+        code(src: string): Tokens.Code | undefined;
+        fences(src: string): Tokens.Code | undefined;
+        heading(src: string): Tokens.Heading | undefined;
+        hr(src: string): Tokens.Hr | undefined;
+        blockquote(src: string): Tokens.Blockquote | undefined;
+        list(src: string): Tokens.List | undefined;
+        html(src: string): Tokens.HTML | Tokens.Paragraph | undefined;
+        def(src: string): Tokens.Def | undefined;
+        table(src: string): Tokens.Table | undefined;
+        lheading(src: string): Tokens.Heading | undefined;
+        paragraph(src: string): Tokens.Paragraph | undefined;
+        text(src: string): Tokens.Text | undefined;
+        escape(src: string): Tokens.Escape | undefined;
+        tag(src: string): Tokens.Tag | undefined;
+        link(src: string): Tokens.Link | Tokens.Image | undefined;
+        reflink(src: string, links: Links): Tokens.Link | Tokens.Image | Tokens.Text | undefined;
+        emStrong(src: string, maskedSrc: string, prevChar?: string): Tokens.Em | Tokens.Strong | undefined;
+        codespan(src: string): Tokens.Codespan | undefined;
+        br(src: string): Tokens.Br | undefined;
+        del(src: string): Tokens.Del | undefined;
+        autolink(src: string, mangle: (cap: string) => string): Tokens.Link | undefined;
+        url(src: string, mangle: (cap: string) => string): Tokens.Link | undefined;
+        inlineText(src: string, smartypants: (cap: string) => string): Tokens.Text | undefined;
+    }
+}
+declare module "rules" {
+    export type Rule = RegExp | string;
+    export interface Rules {
+        [ruleName: string]: Pick<RegExp, 'exec'> | Rule | Rules;
+    }
+    type BlockRuleNames = 'newline' | 'code' | 'fences' | 'hr' | 'heading' | 'blockquote' | 'list' | 'html' | 'def' | 'lheading' | '_paragraph' | 'text' | '_label' | '_title' | 'bullet' | 'listItemStart' | '_tag' | '_comment' | 'paragraph' | 'uote';
+    type BlockSubRuleNames = 'normal' | 'gfm' | 'pedantic';
+    type InlineRuleNames = 'escape' | 'autolink' | 'tag' | 'link' | 'reflink' | 'nolink' | 'reflinkSearch' | 'code' | 'br' | 'text' | '_punctuation' | 'punctuation' | 'blockSkip' | 'escapedEmSt' | '_comment' | '_escapes' | '_scheme' | '_email' | '_attribute' | '_label' | '_href' | '_title' | 'strong' | '_extended_email' | '_backpedal';
+    type InlineSubRuleNames = 'gfm' | 'emStrong' | 'normal' | 'pedantic' | 'breaks';
     /**
-     * Parse Loop
+     * Block-Level Grammar
      */
-    parse(tokens: Token[], top?: boolean): string;
+    export const block: Record<BlockRuleNames, Rule> & Record<BlockSubRuleNames, Rules> & Rules;
     /**
-     * Parse Inline Tokens
+     * Inline-Level Grammar
      */
-    parseInline(tokens: Token[], renderer?: _Renderer | _TextRenderer): string;
-}
-
-/**
- * Tokenizer
- */
-declare class _Tokenizer {
-    options: MarkedOptions;
-    rules: any;
-    lexer: _Lexer;
-    constructor(options?: MarkedOptions);
-    space(src: string): Tokens.Space | undefined;
-    code(src: string): Tokens.Code | undefined;
-    fences(src: string): Tokens.Code | undefined;
-    heading(src: string): Tokens.Heading | undefined;
-    hr(src: string): Tokens.Hr | undefined;
-    blockquote(src: string): Tokens.Blockquote | undefined;
-    list(src: string): Tokens.List | undefined;
-    html(src: string): Tokens.HTML | Tokens.Paragraph | undefined;
-    def(src: string): Tokens.Def | undefined;
-    table(src: string): Tokens.Table | undefined;
-    lheading(src: string): Tokens.Heading | undefined;
-    paragraph(src: string): Tokens.Paragraph | undefined;
-    text(src: string): Tokens.Text | undefined;
-    escape(src: string): Tokens.Escape | undefined;
-    tag(src: string): Tokens.Tag | undefined;
-    link(src: string): Tokens.Link | Tokens.Image | undefined;
-    reflink(src: string, links: Links): Tokens.Link | Tokens.Image | Tokens.Text | undefined;
-    emStrong(src: string, maskedSrc: string, prevChar?: string): Tokens.Em | Tokens.Strong | undefined;
-    codespan(src: string): Tokens.Codespan | undefined;
-    br(src: string): Tokens.Br | undefined;
-    del(src: string): Tokens.Del | undefined;
-    autolink(src: string, mangle: (cap: string) => string): Tokens.Link | undefined;
-    url(src: string, mangle: (cap: string) => string): Tokens.Link | undefined;
-    inlineText(src: string, smartypants: (cap: string) => string): Tokens.Text | undefined;
+    export const inline: Record<InlineRuleNames, Rule> & Record<InlineSubRuleNames, Rules> & Rules;
 }
-
-interface SluggerOptions {
-    /** Generates the next unique slug without updating the internal accumulator. */
-    dryrun?: boolean;
-}
-interface TokenizerThis {
-    lexer: _Lexer;
+declare module "Lexer" {
+    import type { Token, TokensList } from "Tokens";
+    import type { MarkedOptions } from "MarkedOptions";
+    import type { Rules } from "rules";
+    /**
+     * Block Lexer
+     */
+    export class _Lexer {
+        tokens: TokensList;
+        options: MarkedOptions;
+        state: {
+            inLink: boolean;
+            inRawBlock: boolean;
+            top: boolean;
+        };
+        private tokenizer;
+        private inlineQueue;
+        constructor(options?: MarkedOptions);
+        /**
+         * Expose Rules
+         */
+        static get rules(): Rules;
+        /**
+         * Static Lex Method
+         */
+        static lex(src: string, options?: MarkedOptions): TokensList;
+        /**
+         * Static Lex Inline Method
+         */
+        static lexInline(src: string, options?: MarkedOptions): Token[];
+        /**
+         * Preprocessing
+         */
+        lex(src: string): TokensList;
+        /**
+         * Lexing
+         */
+        blockTokens(src: string, tokens?: Token[]): Token[];
+        blockTokens(src: string, tokens?: TokensList): TokensList;
+        inline(src: string, tokens?: Token[]): Token[];
+        /**
+         * Lexing/Compiling
+         */
+        inlineTokens(src: string, tokens?: Token[]): Token[];
+    }
 }
-interface TokenizerExtension {
-    name: string;
-    level: 'block' | 'inline';
-    start?: ((this: TokenizerThis, src: string) => number | void) | undefined;
-    tokenizer: (this: TokenizerThis, src: string, tokens: Token[] | TokensList) => Tokens.Generic | void;
-    childTokens?: string[] | undefined;
+declare module "TextRenderer" {
+    /**
+     * TextRenderer
+     * returns only the textual part of the token
+     */
+    export class _TextRenderer {
+        strong(text: string): string;
+        em(text: string): string;
+        codespan(text: string): string;
+        del(text: string): string;
+        html(text: string): string;
+        text(text: string): string;
+        link(href: string, title: string | null | undefined, text: string): string;
+        image(href: string, title: string | null, text: string): string;
+        br(): string;
+    }
 }
-interface RendererThis {
-    parser: _Parser;
+declare module "Slugger" {
+    import type { SluggerOptions } from "MarkedOptions";
+    /**
+     * Slugger generates header id
+     */
+    export class _Slugger {
+        seen: {
+            [slugValue: string]: number;
+        };
+        constructor();
+        serialize(value: string): string;
+        /**
+         * Finds the next safe (unique) slug to use
+         */
+        getNextSafeSlug(originalSlug: string, isDryRun: boolean | undefined): string;
+        /**
+         * Convert string to unique id
+         */
+        slug(value: string, options?: SluggerOptions): string;
+    }
 }
-interface RendererExtension {
-    name: string;
-    renderer: (this: RendererThis, token: Tokens.Generic) => string | false | undefined;
+declare module "Instance" {
+    import { _Lexer } from "Lexer";
+    import { _Parser } from "Parser";
+    import { _Hooks } from "Hooks";
+    import { _Renderer } from "Renderer";
+    import { _Tokenizer } from "Tokenizer";
+    import { _TextRenderer } from "TextRenderer";
+    import { _Slugger } from "Slugger";
+    import type { MarkedExtension, MarkedOptions } from "MarkedOptions";
+    import type { Token, TokensList } from "Tokens";
+    export type ResultCallback = (error: Error | null, parseResult?: string) => undefined | void;
+    export class Marked {
+        #private;
+        defaults: MarkedOptions;
+        options: (opt: any) => this;
+        parse: (src: string, optOrCallback?: MarkedOptions | ResultCallback | undefined | null, callback?: ResultCallback | undefined) => string | Promise<string | undefined> | undefined;
+        parseInline: (src: string, optOrCallback?: MarkedOptions | ResultCallback | undefined | null, callback?: ResultCallback | undefined) => string | Promise<string | undefined> | undefined;
+        Parser: typeof _Parser;
+        parser: typeof _Parser.parse;
+        Renderer: typeof _Renderer;
+        TextRenderer: typeof _TextRenderer;
+        Lexer: typeof _Lexer;
+        lexer: typeof _Lexer.lex;
+        Tokenizer: typeof _Tokenizer;
+        Slugger: typeof _Slugger;
+        Hooks: typeof _Hooks;
+        constructor(...args: MarkedExtension[]);
+        /**
+         * Run callback for every token
+         */
+        walkTokens<T = void>(tokens: Token[] | TokensList, callback: (token: Token) => T | T[]): T[];
+        use(...args: MarkedExtension[]): this;
+        setOptions(opt: any): this;
+    }
 }
-type TokenizerAndRendererExtension = TokenizerExtension | RendererExtension | (TokenizerExtension & RendererExtension);
-type RendererApi = Omit<_Renderer, 'constructor' | 'options'>;
-type RendererObject = {
-    [K in keyof RendererApi]?: (...args: Parameters<RendererApi[K]>) => ReturnType<RendererApi[K]> | false;
-};
-type TokenizerApi = Omit<_Tokenizer, 'constructor' | 'options' | 'rules' | 'lexer'>;
-type TokenizerObject = {
-    [K in keyof TokenizerApi]?: (...args: Parameters<TokenizerApi[K]>) => ReturnType<TokenizerApi[K]> | false;
-};
-interface MarkedExtension {
-    /**
-     * True will tell marked to await any walkTokens functions before parsing the tokens and returning an HTML string.
-     */
-    async?: boolean;
-    /**
-     * A prefix URL for any relative link.
-     * @deprecated Deprecated in v5.0.0 use marked-base-url to prefix url for any relative link.
-     */
-    baseUrl?: string | undefined | null;
-    /**
-     * Enable GFM line breaks. This option requires the gfm option to be true.
-     */
-    breaks?: boolean | undefined;
-    /**
-     * Add tokenizers and renderers to marked
-     */
-    extensions?: TokenizerAndRendererExtension[] | undefined | null;
-    /**
-     * Enable GitHub flavored markdown.
-     */
-    gfm?: boolean | undefined;
-    /**
-     * Include an id attribute when emitting headings.
-     * @deprecated Deprecated in v5.0.0 use marked-gfm-heading-id to include an id attribute when emitting headings (h1, h2, h3, etc).
-     */
-    headerIds?: boolean | undefined;
-    /**
-     * Set the prefix for header tag ids.
-     * @deprecated Deprecated in v5.0.0 use marked-gfm-heading-id to add a string to prefix the id attribute when emitting headings (h1, h2, h3, etc).
-     */
-    headerPrefix?: string | undefined;
-    /**
-     * A function to highlight code blocks. The function can either be
-     * synchronous (returning a string) or asynchronous (callback invoked
-     * with an error if any occurred during highlighting and a string
-     * if highlighting was successful)
-     * @deprecated Deprecated in v5.0.0 use marked-highlight to add highlighting to code blocks.
-     */
-    highlight?: ((code: string, lang: string | undefined, callback?: (error: Error, code?: string) => void) => string | void) | null;
-    /**
-     * Hooks are methods that hook into some part of marked.
-     * preprocess is called to process markdown before sending it to marked.
-     * postprocess is called to process html after marked has finished parsing.
-     */
-    hooks?: {
-        preprocess: (markdown: string) => string;
-        postprocess: (html: string | undefined) => string | undefined;
-        options?: MarkedOptions;
-    } | null;
-    /**
-     * Set the prefix for code block classes.
-     * @deprecated Deprecated in v5.0.0 use marked-highlight to prefix the className in a <code> block. Useful for syntax highlighting.
-     */
-    langPrefix?: string | undefined;
-    /**
-     * Mangle autolinks (<email@domain.com>).
-     * @deprecated Deprecated in v5.0.0 use marked-mangle to mangle email addresses.
-     */
-    mangle?: boolean | undefined;
-    /**
-     * Conform to obscure parts of markdown.pl as much as possible. Don't fix any of the original markdown bugs or poor behavior.
-     */
-    pedantic?: boolean | undefined;
+declare module "helpers" {
+    import type { MarkedOptions } from "MarkedOptions";
+    import type { ResultCallback } from "Instance";
+    import type { Rule } from "rules";
+    export function escape(html: string, encode?: boolean): string;
+    export function unescape(html: string): string;
+    export function edit(regex: Rule, opt?: string): {
+        replace: (name: string | RegExp, val: string | RegExp) => any;
+        getRegex: () => RegExp;
+    };
+    export function cleanUrl(sanitize: boolean | undefined, base: string | undefined | null, href: string): string | null;
+    export function resolveUrl(base: string, href: string): string;
+    export const noopTest: {
+        exec: () => null;
+    };
+    export function splitCells(tableRow: string, count: number): string[];
     /**
-     * Type: object Default: new Renderer()
+     * Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').
+     * /c*$/ is vulnerable to REDOS.
      *
-     * An object containing functions to render tokens to HTML.
-     */
-    renderer?: RendererObject | undefined | null;
-    /**
-     * Sanitize the output. Ignore any HTML that has been input. If true, sanitize the HTML passed into markdownString with the sanitizer function.
-     * @deprecated Warning: This feature is deprecated and it should NOT be used as it cannot be considered secure. Instead use a sanitize library, like DOMPurify (recommended), sanitize-html or insane on the output HTML!
-     */
-    sanitize?: boolean | undefined;
-    /**
-     * Optionally sanitize found HTML with a sanitizer function.
-     * @deprecated A function to sanitize the HTML passed into markdownString.
-     */
-    sanitizer?: ((html: string) => string) | null;
-    /**
-     * Shows an HTML error message when rendering fails.
+     * @param str
+     * @param c
+     * @param invert Remove suffix of non-c chars instead. Default falsey.
      */
-    silent?: boolean | undefined;
-    /**
-     * Use smarter list behavior than the original markdown. May eventually be default with the old behavior moved into pedantic.
-     */
-    smartLists?: boolean | undefined;
-    /**
-     * Use "smart" typograhic punctuation for things like quotes and dashes.
-     * @deprecated Deprecated in v5.0.0 use marked-smartypants to use "smart" typographic punctuation for things like quotes and dashes.
-     */
-    smartypants?: boolean | undefined;
-    /**
-     * The tokenizer defines how to turn markdown text into tokens.
-     */
-    tokenizer?: TokenizerObject | undefined | null;
-    /**
-     * The walkTokens function gets called with every token.
-     * Child tokens are called before moving on to sibling tokens.
-     * Each token is passed by reference so updates are persisted when passed to the parser.
-     * The return value of the function is ignored.
-     */
-    walkTokens?: ((token: Token) => void | Promise<void>) | undefined | null;
-    /**
-     * Generate closing slash for self-closing tags (<br/> instead of <br>)
-     * @deprecated Deprecated in v5.0.0 use marked-xhtml to emit self-closing HTML tags for void elements (<br/>, <img/>, etc.) with a "/" as required by XHTML.
-     */
-    xhtml?: boolean | undefined;
+    export function rtrim(str: string, c: string, invert?: boolean): string;
+    export function findClosingBracket(str: string, b: string): number;
+    export function checkDeprecations(opt: MarkedOptions, callback?: ResultCallback): void;
 }
-interface MarkedOptions extends Omit<MarkedExtension, 'extensions' | 'renderer' | 'tokenizer' | 'walkTokens'> {
-    /**
-     * Type: object Default: new Renderer()
+declare module "marked" {
+    import { _Lexer } from "Lexer";
+    import { _Parser } from "Parser";
+    import { _Tokenizer } from "Tokenizer";
+    import { _Renderer } from "Renderer";
+    import { _TextRenderer } from "TextRenderer";
+    import { _Slugger } from "Slugger";
+    import { _Hooks } from "Hooks";
+    import { _getDefaults } from "defaults";
+    import type { MarkedExtension, MarkedOptions } from "MarkedOptions";
+    import type { Token, TokensList } from "Tokens";
+    import type { ResultCallback } from "Instance";
+    /**
+     * Compiles markdown to HTML asynchronously.
      *
-     * An object containing functions to render tokens to HTML.
+     * @param src String of markdown source to be compiled
+     * @param options Hash of options, having async: true
+     * @return Promise of string of compiled HTML
      */
-    renderer?: Omit<_Renderer, 'constructor'> | undefined | null;
+    export function marked(src: string, options: MarkedOptions & {
+        async: true;
+    }): Promise<string>;
     /**
-     * The tokenizer defines how to turn markdown text into tokens.
+     * Compiles markdown to HTML synchronously.
+     *
+     * @param src String of markdown source to be compiled
+     * @param options Optional hash of options
+     * @return String of compiled HTML
      */
-    tokenizer?: Omit<_Tokenizer, 'constructor'> | undefined | null;
+    export function marked(src: string, options?: MarkedOptions): string;
     /**
-     * The walkTokens function gets called with every token.
-     * Child tokens are called before moving on to sibling tokens.
-     * Each token is passed by reference so updates are persisted when passed to the parser.
-     * The return value of the function is ignored.
+     * Compiles markdown to HTML asynchronously with a callback.
+     *
+     * @param src String of markdown source to be compiled
+     * @param callback Function called when the markdownString has been fully parsed when using async highlighting
      */
-    walkTokens?: ((token: Token) => void | Promise<void> | Array<void | Promise<void>>) | undefined | null;
+    export function marked(src: string, callback: ResultCallback): void;
     /**
-     * Add tokenizers and renderers to marked
+     * Compiles markdown to HTML asynchronously with a callback.
+     *
+     * @param src String of markdown source to be compiled
+     * @param options Hash of options
+     * @param callback Function called when the markdownString has been fully parsed when using async highlighting
      */
-    extensions?: (TokenizerAndRendererExtension[] & {
-        renderers: Record<string, (this: RendererThis, token: Tokens.Generic) => string | false | undefined>;
-        childTokens: Record<string, string[]>;
-        block: any[];
-        inline: any[];
-        startBlock: Array<(this: TokenizerThis, src: string) => number | void>;
-        startInline: Array<(this: TokenizerThis, src: string) => number | void>;
-    }) | undefined | null;
+    export function marked(src: string, options: MarkedOptions, callback: ResultCallback): void;
+    /**
+     * Compiles markdown to HTML asynchronously with a callback.
+     *
+     * @param src String of markdown source to be compiled
+     * @param options Hash of options
+     * @param callback Function called when the markdownString has been fully parsed when using async highlighting
+     */
+    export namespace marked {
+        var options: (options: MarkedOptions) => typeof marked;
+        var setOptions: (options: MarkedOptions) => typeof marked;
+        var getDefaults: typeof _getDefaults;
+        var defaults: MarkedOptions;
+        var use: (...args: MarkedExtension[]) => typeof marked;
+        var walkTokens: <T = void>(tokens: Token[] | TokensList, callback: (token: Token) => T | T[]) => T[];
+        var parseInline: (src: string, optOrCallback?: MarkedOptions | ResultCallback | null | undefined, callback?: ResultCallback | undefined) => string | Promise<string | undefined> | undefined;
+        var Parser: typeof _Parser;
+        var parser: typeof _Parser.parse;
+        var Renderer: typeof _Renderer;
+        var TextRenderer: typeof _TextRenderer;
+        var Lexer: typeof _Lexer;
+        var lexer: typeof _Lexer.lex;
+        var Tokenizer: typeof _Tokenizer;
+        var Slugger: typeof _Slugger;
+        var Hooks: typeof _Hooks;
+        var parse: typeof marked;
+    }
+    export const options: (options: MarkedOptions) => typeof marked;
+    export const setOptions: (options: MarkedOptions) => typeof marked;
+    export const use: (...args: MarkedExtension[]) => typeof marked;
+    export const walkTokens: <T = void>(tokens: Token[] | TokensList, callback: (token: Token) => T | T[]) => T[];
+    export const parseInline: (src: string, optOrCallback?: MarkedOptions | ResultCallback | null | undefined, callback?: ResultCallback | undefined) => string | Promise<string | undefined> | undefined;
+    export const parse: typeof marked;
+    export const parser: typeof _Parser.parse;
+    export const lexer: typeof _Lexer.lex;
+    export { _defaults as defaults, _getDefaults as getDefaults } from "defaults";
+    export { _Lexer as Lexer } from "Lexer";
+    export { _Parser as Parser } from "Parser";
+    export { _Tokenizer as Tokenizer } from "Tokenizer";
+    export { _Renderer as Renderer } from "Renderer";
+    export { _TextRenderer as TextRenderer } from "TextRenderer";
+    export { _Slugger as Slugger } from "Slugger";
+    export { _Hooks as Hooks } from "Hooks";
+    export { Marked } from "Instance";
+    export type * from "MarkedOptions";
+    export type * from "rules";
+    export type * from "Tokens";
 }
-
-type Rule = RegExp | string;
-interface Rules {
-    [ruleName: string]: Pick<RegExp, 'exec'> | Rule | Rules;
+declare module "Renderer" {
+    import type { MarkedOptions } from "MarkedOptions";
+    import { Slugger } from "marked";
+    /**
+     * Renderer
+     */
+    export class _Renderer {
+        options: MarkedOptions;
+        constructor(options?: MarkedOptions);
+        code(code: string, infostring: string | undefined, escaped: boolean): string;
+        blockquote(quote: string): string;
+        html(html: string, block?: boolean): string;
+        heading(text: string, level: number, raw: string, slugger: Slugger): string;
+        hr(): string;
+        list(body: string, ordered: boolean, start: number | ''): string;
+        listitem(text: string, task: boolean, checked: boolean): string;
+        checkbox(checked: boolean): string;
+        paragraph(text: string): string;
+        table(header: string, body: string): string;
+        tablerow(content: string): string;
+        tablecell(content: string, flags: {
+            header: boolean;
+            align: 'center' | 'left' | 'right' | null;
+        }): string;
+        /**
+         * span level renderer
+         */
+        strong(text: string): string;
+        em(text: string): string;
+        codespan(text: string): string;
+        br(): string;
+        del(text: string): string;
+        link(href: string, title: string | null | undefined, text: string): string;
+        image(href: string, title: string | null, text: string): string;
+        text(text: string): string;
+    }
 }
-type BlockRuleNames = 'newline' | 'code' | 'fences' | 'hr' | 'heading' | 'blockquote' | 'list' | 'html' | 'def' | 'lheading' | '_paragraph' | 'text' | '_label' | '_title' | 'bullet' | 'listItemStart' | '_tag' | '_comment' | 'paragraph' | 'uote';
-type BlockSubRuleNames = 'normal' | 'gfm' | 'pedantic';
-type InlineRuleNames = 'escape' | 'autolink' | 'tag' | 'link' | 'reflink' | 'nolink' | 'reflinkSearch' | 'code' | 'br' | 'text' | '_punctuation' | 'punctuation' | 'blockSkip' | 'escapedEmSt' | '_comment' | '_escapes' | '_scheme' | '_email' | '_attribute' | '_label' | '_href' | '_title' | 'strong' | '_extended_email' | '_backpedal';
-type InlineSubRuleNames = 'gfm' | 'emStrong' | 'normal' | 'pedantic' | 'breaks';
-/**
- * Block-Level Grammar
- */
-declare const block: Record<BlockRuleNames, Rule> & Record<BlockSubRuleNames, Rules> & Rules;
-/**
- * Inline-Level Grammar
- */
-declare const inline: Record<InlineRuleNames, Rule> & Record<InlineSubRuleNames, Rules> & Rules;
-
-/**
- * Block Lexer
- */
-declare class _Lexer {
-    tokens: TokensList;
-    options: MarkedOptions;
-    state: {
-        inLink: boolean;
-        inRawBlock: boolean;
-        top: boolean;
-    };
-    private tokenizer;
-    private inlineQueue;
-    constructor(options?: MarkedOptions);
-    /**
-     * Expose Rules
-     */
-    static get rules(): Rules;
-    /**
-     * Static Lex Method
-     */
-    static lex(src: string, options?: MarkedOptions): TokensList;
-    /**
-     * Static Lex Inline Method
-     */
-    static lexInline(src: string, options?: MarkedOptions): Token[];
-    /**
-     * Preprocessing
-     */
-    lex(src: string): TokensList;
-    /**
-     * Lexing
-     */
-    blockTokens(src: string, tokens?: Token[]): Token[];
-    blockTokens(src: string, tokens?: TokensList): TokensList;
-    inline(src: string, tokens?: Token[]): Token[];
-    /**
-     * Lexing/Compiling
-     */
-    inlineTokens(src: string, tokens?: Token[]): Token[];
+declare module "Parser" {
+    import { _Renderer } from "Renderer";
+    import { _TextRenderer } from "TextRenderer";
+    import { _Slugger } from "Slugger";
+    import type { Token } from "Tokens";
+    import type { MarkedOptions } from "MarkedOptions";
+    /**
+     * Parsing & Compiling
+     */
+    export class _Parser {
+        options: MarkedOptions;
+        renderer: _Renderer;
+        textRenderer: _TextRenderer;
+        slugger: _Slugger;
+        constructor(options?: MarkedOptions);
+        /**
+         * Static Parse Method
+         */
+        static parse(tokens: Token[], options?: MarkedOptions): string;
+        /**
+         * Static Parse Inline Method
+         */
+        static parseInline(tokens: Token[], options?: MarkedOptions): string;
+        /**
+         * Parse Loop
+         */
+        parse(tokens: Token[], top?: boolean): string;
+        /**
+         * Parse Inline Tokens
+         */
+        parseInline(tokens: Token[], renderer?: _Renderer | _TextRenderer): string;
+    }
 }
-
-declare class _Hooks {
-    options: MarkedOptions;
-    constructor(options?: MarkedOptions);
-    static passThroughHooks: Set<string>;
-    /**
-     * Process markdown before marked
-     */
-    preprocess(markdown: string): string;
-    /**
-     * Process HTML after marked is finished
-     */
-    postprocess(html: string | undefined): string | undefined;
+declare module "MarkedOptions" {
+    import type { Token, Tokens, TokensList } from "Tokens";
+    import { _Parser } from "Parser";
+    import { _Lexer } from "Lexer";
+    import { _Renderer } from "Renderer";
+    import { _Tokenizer } from "Tokenizer";
+    export interface SluggerOptions {
+        /** Generates the next unique slug without updating the internal accumulator. */
+        dryrun?: boolean;
+    }
+    export interface TokenizerThis {
+        lexer: _Lexer;
+    }
+    export interface TokenizerExtension {
+        name: string;
+        level: 'block' | 'inline';
+        start?: ((this: TokenizerThis, src: string) => number | void) | undefined;
+        tokenizer: (this: TokenizerThis, src: string, tokens: Token[] | TokensList) => Tokens.Generic | void;
+        childTokens?: string[] | undefined;
+    }
+    export interface RendererThis {
+        parser: _Parser;
+    }
+    export interface RendererExtension {
+        name: string;
+        renderer: (this: RendererThis, token: Tokens.Generic) => string | false | undefined;
+    }
+    export type TokenizerAndRendererExtension = TokenizerExtension | RendererExtension | (TokenizerExtension & RendererExtension);
+    type RendererApi = Omit<_Renderer, 'constructor' | 'options'>;
+    type RendererObject = {
+        [K in keyof RendererApi]?: (...args: Parameters<RendererApi[K]>) => ReturnType<RendererApi[K]> | false;
+    };
+    type TokenizerApi = Omit<_Tokenizer, 'constructor' | 'options' | 'rules' | 'lexer'>;
+    type TokenizerObject = {
+        [K in keyof TokenizerApi]?: (...args: Parameters<TokenizerApi[K]>) => ReturnType<TokenizerApi[K]> | false;
+    };
+    export interface MarkedExtension {
+        /**
+         * True will tell marked to await any walkTokens functions before parsing the tokens and returning an HTML string.
+         */
+        async?: boolean;
+        /**
+         * A prefix URL for any relative link.
+         * @deprecated Deprecated in v5.0.0 use marked-base-url to prefix url for any relative link.
+         */
+        baseUrl?: string | undefined | null;
+        /**
+         * Enable GFM line breaks. This option requires the gfm option to be true.
+         */
+        breaks?: boolean | undefined;
+        /**
+         * Add tokenizers and renderers to marked
+         */
+        extensions?: TokenizerAndRendererExtension[] | undefined | null;
+        /**
+         * Enable GitHub flavored markdown.
+         */
+        gfm?: boolean | undefined;
+        /**
+         * Include an id attribute when emitting headings.
+         * @deprecated Deprecated in v5.0.0 use marked-gfm-heading-id to include an id attribute when emitting headings (h1, h2, h3, etc).
+         */
+        headerIds?: boolean | undefined;
+        /**
+         * Set the prefix for header tag ids.
+         * @deprecated Deprecated in v5.0.0 use marked-gfm-heading-id to add a string to prefix the id attribute when emitting headings (h1, h2, h3, etc).
+         */
+        headerPrefix?: string | undefined;
+        /**
+         * A function to highlight code blocks. The function can either be
+         * synchronous (returning a string) or asynchronous (callback invoked
+         * with an error if any occurred during highlighting and a string
+         * if highlighting was successful)
+         * @deprecated Deprecated in v5.0.0 use marked-highlight to add highlighting to code blocks.
+         */
+        highlight?: ((code: string, lang: string | undefined, callback?: (error: Error, code?: string) => void) => string | void) | null;
+        /**
+         * Hooks are methods that hook into some part of marked.
+         * preprocess is called to process markdown before sending it to marked.
+         * postprocess is called to process html after marked has finished parsing.
+         */
+        hooks?: {
+            preprocess: (markdown: string) => string;
+            postprocess: (html: string | undefined) => string | undefined;
+            options?: MarkedOptions;
+        } | null;
+        /**
+         * Set the prefix for code block classes.
+         * @deprecated Deprecated in v5.0.0 use marked-highlight to prefix the className in a <code> block. Useful for syntax highlighting.
+         */
+        langPrefix?: string | undefined;
+        /**
+         * Mangle autolinks (<email@domain.com>).
+         * @deprecated Deprecated in v5.0.0 use marked-mangle to mangle email addresses.
+         */
+        mangle?: boolean | undefined;
+        /**
+         * Conform to obscure parts of markdown.pl as much as possible. Don't fix any of the original markdown bugs or poor behavior.
+         */
+        pedantic?: boolean | undefined;
+        /**
+         * Type: object Default: new Renderer()
+         *
+         * An object containing functions to render tokens to HTML.
+         */
+        renderer?: RendererObject | undefined | null;
+        /**
+         * Sanitize the output. Ignore any HTML that has been input. If true, sanitize the HTML passed into markdownString with the sanitizer function.
+         * @deprecated Warning: This feature is deprecated and it should NOT be used as it cannot be considered secure. Instead use a sanitize library, like DOMPurify (recommended), sanitize-html or insane on the output HTML!
+         */
+        sanitize?: boolean | undefined;
+        /**
+         * Optionally sanitize found HTML with a sanitizer function.
+         * @deprecated A function to sanitize the HTML passed into markdownString.
+         */
+        sanitizer?: ((html: string) => string) | null;
+        /**
+         * Shows an HTML error message when rendering fails.
+         */
+        silent?: boolean | undefined;
+        /**
+         * Use smarter list behavior than the original markdown. May eventually be default with the old behavior moved into pedantic.
+         */
+        smartLists?: boolean | undefined;
+        /**
+         * Use "smart" typograhic punctuation for things like quotes and dashes.
+         * @deprecated Deprecated in v5.0.0 use marked-smartypants to use "smart" typographic punctuation for things like quotes and dashes.
+         */
+        smartypants?: boolean | undefined;
+        /**
+         * The tokenizer defines how to turn markdown text into tokens.
+         */
+        tokenizer?: TokenizerObject | undefined | null;
+        /**
+         * The walkTokens function gets called with every token.
+         * Child tokens are called before moving on to sibling tokens.
+         * Each token is passed by reference so updates are persisted when passed to the parser.
+         * The return value of the function is ignored.
+         */
+        walkTokens?: ((token: Token) => void | Promise<void>) | undefined | null;
+        /**
+         * Generate closing slash for self-closing tags (<br/> instead of <br>)
+         * @deprecated Deprecated in v5.0.0 use marked-xhtml to emit self-closing HTML tags for void elements (<br/>, <img/>, etc.) with a "/" as required by XHTML.
+         */
+        xhtml?: boolean | undefined;
+    }
+    export interface MarkedOptions extends Omit<MarkedExtension, 'extensions' | 'renderer' | 'tokenizer' | 'walkTokens'> {
+        /**
+         * Type: object Default: new Renderer()
+         *
+         * An object containing functions to render tokens to HTML.
+         */
+        renderer?: Omit<_Renderer, 'constructor'> | undefined | null;
+        /**
+         * The tokenizer defines how to turn markdown text into tokens.
+         */
+        tokenizer?: Omit<_Tokenizer, 'constructor'> | undefined | null;
+        /**
+         * The walkTokens function gets called with every token.
+         * Child tokens are called before moving on to sibling tokens.
+         * Each token is passed by reference so updates are persisted when passed to the parser.
+         * The return value of the function is ignored.
+         */
+        walkTokens?: ((token: Token) => void | Promise<void> | Array<void | Promise<void>>) | undefined | null;
+        /**
+         * Add tokenizers and renderers to marked
+         */
+        extensions?: (TokenizerAndRendererExtension[] & {
+            renderers: Record<string, (this: RendererThis, token: Tokens.Generic) => string | false | undefined>;
+            childTokens: Record<string, string[]>;
+            block: any[];
+            inline: any[];
+            startBlock: Array<(this: TokenizerThis, src: string) => number | void>;
+            startInline: Array<(this: TokenizerThis, src: string) => number | void>;
+        }) | undefined | null;
+    }
 }
-
-type ResultCallback$1 = (error: Error | null, parseResult?: string) => undefined | void;
-declare class Marked {
-    #private;
-    defaults: MarkedOptions;
-    options: (opt: any) => this;
-    parse: (src: string, optOrCallback?: MarkedOptions | ResultCallback$1 | undefined | null, callback?: ResultCallback$1 | undefined) => string | Promise<string | undefined> | undefined;
-    parseInline: (src: string, optOrCallback?: MarkedOptions | ResultCallback$1 | undefined | null, callback?: ResultCallback$1 | undefined) => string | Promise<string | undefined> | undefined;
-    Parser: typeof _Parser;
-    parser: typeof _Parser.parse;
-    Renderer: typeof _Renderer;
-    TextRenderer: typeof _TextRenderer;
-    Lexer: typeof _Lexer;
-    lexer: typeof _Lexer.lex;
-    Tokenizer: typeof _Tokenizer;
-    Slugger: typeof _Slugger;
-    Hooks: typeof _Hooks;
-    constructor(...args: MarkedExtension[]);
+declare module "defaults" {
+    import type { MarkedOptions } from "MarkedOptions";
     /**
-     * Run callback for every token
+     * Gets the original marked default options.
      */
-    walkTokens<T = void>(tokens: Token[] | TokensList, callback: (token: Token) => T | T[]): T[];
-    use(...args: MarkedExtension[]): this;
-    setOptions(opt: any): this;
+    export function _getDefaults(): MarkedOptions;
+    export let _defaults: MarkedOptions;
+    export function changeDefaults(newDefaults: MarkedOptions): void;
 }
-
-/**
- * Gets the original marked default options.
- */
-declare function _getDefaults(): MarkedOptions;
-declare let _defaults: MarkedOptions;
-
-type ResultCallback = (error: Error | null, parseResult?: string) => undefined | void;
-/**
- * Compiles markdown to HTML asynchronously.
- *
- * @param src String of markdown source to be compiled
- * @param options Hash of options, having async: true
- * @return Promise of string of compiled HTML
- */
-declare function marked(src: string, options: MarkedOptions & {
-    async: true;
-}): Promise<string>;
-/**
- * Compiles markdown to HTML synchronously.
- *
- * @param src String of markdown source to be compiled
- * @param options Optional hash of options
- * @return String of compiled HTML
- */
-declare function marked(src: string, options?: MarkedOptions): string;
-/**
- * Compiles markdown to HTML asynchronously with a callback.
- *
- * @param src String of markdown source to be compiled
- * @param callback Function called when the markdownString has been fully parsed when using async highlighting
- */
-declare function marked(src: string, callback: ResultCallback): void;
-/**
- * Compiles markdown to HTML asynchronously with a callback.
- *
- * @param src String of markdown source to be compiled
- * @param options Hash of options
- * @param callback Function called when the markdownString has been fully parsed when using async highlighting
- */
-declare function marked(src: string, options: MarkedOptions, callback: ResultCallback): void;
-declare namespace marked {
-    var options: (options: MarkedOptions) => typeof marked;
-    var setOptions: (options: MarkedOptions) => typeof marked;
-    var getDefaults: typeof _getDefaults;
-    var defaults: MarkedOptions;
-    var use: (...args: MarkedExtension[]) => typeof marked;
-    var walkTokens: <T = void>(tokens: TokensList | Token[], callback: (token: Token) => T | T[]) => T[];
-    var parseInline: (src: string, optOrCallback?: MarkedOptions | ResultCallback$1 | null | undefined, callback?: ResultCallback$1 | undefined) => string | Promise<string | undefined> | undefined;
-    var Parser: typeof _Parser;
-    var parser: typeof _Parser.parse;
-    var Renderer: typeof _Renderer;
-    var TextRenderer: typeof _TextRenderer;
-    var Lexer: typeof _Lexer;
-    var lexer: typeof _Lexer.lex;
-    var Tokenizer: typeof _Tokenizer;
-    var Slugger: typeof _Slugger;
-    var Hooks: typeof _Hooks;
-    var parse: typeof marked;
+declare module "Hooks" {
+    import type { MarkedOptions } from "MarkedOptions";
+    export class _Hooks {
+        options: MarkedOptions;
+        constructor(options?: MarkedOptions);
+        static passThroughHooks: Set<string>;
+        /**
+         * Process markdown before marked
+         */
+        preprocess(markdown: string): string;
+        /**
+         * Process HTML after marked is finished
+         */
+        postprocess(html: string | undefined): string | undefined;
+    }
 }
-declare const options: (options: MarkedOptions) => typeof marked;
-declare const setOptions: (options: MarkedOptions) => typeof marked;
-declare const use: (...args: MarkedExtension[]) => typeof marked;
-declare const walkTokens: <T = void>(tokens: Token[] | TokensList, callback: (token: Token) => T | T[]) => T[];
-declare const parseInline: (src: string, optOrCallback?: MarkedOptions | ResultCallback$1 | null | undefined, callback?: ResultCallback$1 | undefined) => string | Promise<string | undefined> | undefined;
-declare const parse: typeof marked;
-declare const parser: typeof _Parser.parse;
-declare const lexer: typeof _Lexer.lex;
-
-export { _Hooks as Hooks, _Lexer as Lexer, Links, Marked, MarkedExtension, MarkedOptions, _Parser as Parser, _Renderer as Renderer, RendererExtension, RendererThis, ResultCallback, Rule, Rules, _Slugger as Slugger, SluggerOptions, _TextRenderer as TextRenderer, Token, _Tokenizer as Tokenizer, TokenizerAndRendererExtension, TokenizerExtension, TokenizerThis, Tokens, TokensList, block, _defaults as defaults, _getDefaults as getDefaults, inline, lexer, marked, options, parse, parseInline, parser, setOptions, use, walkTokens };

+ 2511 - 2135
lib/marked.esm.js

@@ -9,2237 +9,2613 @@
  * The code in this file is generated from files in ./src/
  */
 
-var __accessCheck = (obj, member, msg) => {
-  if (!member.has(obj))
-    throw TypeError("Cannot " + msg);
-};
-var __privateAdd = (obj, member, value) => {
-  if (member.has(obj))
-    throw TypeError("Cannot add the same private member more than once");
-  member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
-};
-var __privateMethod = (obj, member, method) => {
-  __accessCheck(obj, member, "access private method");
-  return method;
-};
-
-// src/defaults.ts
+/**
+ * Gets the original marked default options.
+ */
 function _getDefaults() {
-  return {
-    async: false,
-    baseUrl: null,
-    breaks: false,
-    extensions: null,
-    gfm: true,
-    headerIds: false,
-    headerPrefix: "",
-    highlight: null,
-    hooks: null,
-    langPrefix: "language-",
-    mangle: false,
-    pedantic: false,
-    renderer: null,
-    sanitize: false,
-    sanitizer: null,
-    silent: false,
-    smartypants: false,
-    tokenizer: null,
-    walkTokens: null,
-    xhtml: false
-  };
+    return {
+        async: false,
+        baseUrl: null,
+        breaks: false,
+        extensions: null,
+        gfm: true,
+        headerIds: false,
+        headerPrefix: '',
+        highlight: null,
+        hooks: null,
+        langPrefix: 'language-',
+        mangle: false,
+        pedantic: false,
+        renderer: null,
+        sanitize: false,
+        sanitizer: null,
+        silent: false,
+        smartypants: false,
+        tokenizer: null,
+        walkTokens: null,
+        xhtml: false
+    };
 }
-var _defaults = _getDefaults();
+let _defaults = _getDefaults();
 function changeDefaults(newDefaults) {
-  _defaults = newDefaults;
+    _defaults = newDefaults;
 }
 
-// src/helpers.ts
-var escapeTest = /[&<>"']/;
-var escapeReplace = new RegExp(escapeTest.source, "g");
-var escapeTestNoEncode = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/;
-var escapeReplaceNoEncode = new RegExp(escapeTestNoEncode.source, "g");
-var escapeReplacements = {
-  "&": "&amp;",
-  "<": "&lt;",
-  ">": "&gt;",
-  '"': "&quot;",
-  "'": "&#39;"
+/**
+ * Helpers
+ */
+const escapeTest = /[&<>"']/;
+const escapeReplace = new RegExp(escapeTest.source, 'g');
+const escapeTestNoEncode = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/;
+const escapeReplaceNoEncode = new RegExp(escapeTestNoEncode.source, 'g');
+const escapeReplacements = {
+    '&': '&amp;',
+    '<': '&lt;',
+    '>': '&gt;',
+    '"': '&quot;',
+    "'": '&#39;'
 };
-var getEscapeReplacement = (ch) => escapeReplacements[ch];
+const getEscapeReplacement = (ch) => escapeReplacements[ch];
 function escape(html, encode) {
-  if (encode) {
-    if (escapeTest.test(html)) {
-      return html.replace(escapeReplace, getEscapeReplacement);
+    if (encode) {
+        if (escapeTest.test(html)) {
+            return html.replace(escapeReplace, getEscapeReplacement);
+        }
     }
-  } else {
-    if (escapeTestNoEncode.test(html)) {
-      return html.replace(escapeReplaceNoEncode, getEscapeReplacement);
+    else {
+        if (escapeTestNoEncode.test(html)) {
+            return html.replace(escapeReplaceNoEncode, getEscapeReplacement);
+        }
     }
-  }
-  return html;
+    return html;
 }
-var unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig;
+const unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig;
 function unescape(html) {
-  return html.replace(unescapeTest, (_, n) => {
-    n = n.toLowerCase();
-    if (n === "colon")
-      return ":";
-    if (n.charAt(0) === "#") {
-      return n.charAt(1) === "x" ? String.fromCharCode(parseInt(n.substring(2), 16)) : String.fromCharCode(+n.substring(1));
-    }
-    return "";
-  });
+    // explicitly match decimal, hex, and named HTML entities
+    return html.replace(unescapeTest, (_, n) => {
+        n = n.toLowerCase();
+        if (n === 'colon')
+            return ':';
+        if (n.charAt(0) === '#') {
+            return n.charAt(1) === 'x'
+                ? String.fromCharCode(parseInt(n.substring(2), 16))
+                : String.fromCharCode(+n.substring(1));
+        }
+        return '';
+    });
 }
-var caret = /(^|[^\[])\^/g;
+const caret = /(^|[^\[])\^/g;
 function edit(regex, opt) {
-  regex = typeof regex === "string" ? regex : regex.source;
-  opt = opt || "";
-  const obj = {
-    replace: (name, val) => {
-      val = typeof val === "object" && "source" in val ? val.source : val;
-      val = val.replace(caret, "$1");
-      regex = regex.replace(name, val);
-      return obj;
-    },
-    getRegex: () => {
-      return new RegExp(regex, opt);
-    }
-  };
-  return obj;
+    regex = typeof regex === 'string' ? regex : regex.source;
+    opt = opt || '';
+    const obj = {
+        replace: (name, val) => {
+            val = typeof val === 'object' && 'source' in val ? val.source : val;
+            val = val.replace(caret, '$1');
+            regex = regex.replace(name, val);
+            return obj;
+        },
+        getRegex: () => {
+            return new RegExp(regex, opt);
+        }
+    };
+    return obj;
 }
-var nonWordAndColonTest = /[^\w:]/g;
-var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
+const nonWordAndColonTest = /[^\w:]/g;
+const originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
 function cleanUrl(sanitize, base, href) {
-  if (sanitize) {
-    let prot;
+    if (sanitize) {
+        let prot;
+        try {
+            prot = decodeURIComponent(unescape(href))
+                .replace(nonWordAndColonTest, '')
+                .toLowerCase();
+        }
+        catch (e) {
+            return null;
+        }
+        if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
+            return null;
+        }
+    }
+    if (base && !originIndependentUrl.test(href)) {
+        href = resolveUrl(base, href);
+    }
     try {
-      prot = decodeURIComponent(unescape(href)).replace(nonWordAndColonTest, "").toLowerCase();
-    } catch (e) {
-      return null;
-    }
-    if (prot.indexOf("javascript:") === 0 || prot.indexOf("vbscript:") === 0 || prot.indexOf("data:") === 0) {
-      return null;
-    }
-  }
-  if (base && !originIndependentUrl.test(href)) {
-    href = resolveUrl(base, href);
-  }
-  try {
-    href = encodeURI(href).replace(/%25/g, "%");
-  } catch (e) {
-    return null;
-  }
-  return href;
+        href = encodeURI(href).replace(/%25/g, '%');
+    }
+    catch (e) {
+        return null;
+    }
+    return href;
 }
-var baseUrls = {};
-var justDomain = /^[^:]+:\/*[^/]*$/;
-var protocol = /^([^:]+:)[\s\S]*$/;
-var domain = /^([^:]+:\/*[^/]*)[\s\S]*$/;
+const baseUrls = {};
+const justDomain = /^[^:]+:\/*[^/]*$/;
+const protocol = /^([^:]+:)[\s\S]*$/;
+const domain = /^([^:]+:\/*[^/]*)[\s\S]*$/;
 function resolveUrl(base, href) {
-  if (!baseUrls[" " + base]) {
-    if (justDomain.test(base)) {
-      baseUrls[" " + base] = base + "/";
-    } else {
-      baseUrls[" " + base] = rtrim(base, "/", true);
-    }
-  }
-  base = baseUrls[" " + base];
-  const relativeBase = base.indexOf(":") === -1;
-  if (href.substring(0, 2) === "//") {
-    if (relativeBase) {
-      return href;
-    }
-    return base.replace(protocol, "$1") + href;
-  } else if (href.charAt(0) === "/") {
-    if (relativeBase) {
-      return href;
-    }
-    return base.replace(domain, "$1") + href;
-  } else {
-    return base + href;
-  }
+    if (!baseUrls[' ' + base]) {
+        // we can ignore everything in base after the last slash of its path component,
+        // but we might need to add _that_
+        // https://tools.ietf.org/html/rfc3986#section-3
+        if (justDomain.test(base)) {
+            baseUrls[' ' + base] = base + '/';
+        }
+        else {
+            baseUrls[' ' + base] = rtrim(base, '/', true);
+        }
+    }
+    base = baseUrls[' ' + base];
+    const relativeBase = base.indexOf(':') === -1;
+    if (href.substring(0, 2) === '//') {
+        if (relativeBase) {
+            return href;
+        }
+        return base.replace(protocol, '$1') + href;
+    }
+    else if (href.charAt(0) === '/') {
+        if (relativeBase) {
+            return href;
+        }
+        return base.replace(domain, '$1') + href;
+    }
+    else {
+        return base + href;
+    }
 }
-var noopTest = { exec: () => null };
+const noopTest = { exec: () => null };
 function splitCells(tableRow, count) {
-  const row = tableRow.replace(/\|/g, (match, offset, str) => {
-    let escaped = false, curr = offset;
-    while (--curr >= 0 && str[curr] === "\\")
-      escaped = !escaped;
-    if (escaped) {
-      return "|";
-    } else {
-      return " |";
-    }
-  }), cells = row.split(/ \|/);
-  let i = 0;
-  if (!cells[0].trim()) {
-    cells.shift();
-  }
-  if (cells.length > 0 && !cells[cells.length - 1].trim()) {
-    cells.pop();
-  }
-  if (cells.length > count) {
-    cells.splice(count);
-  } else {
-    while (cells.length < count)
-      cells.push("");
-  }
-  for (; i < cells.length; i++) {
-    cells[i] = cells[i].trim().replace(/\\\|/g, "|");
-  }
-  return cells;
+    // ensure that every cell-delimiting pipe has a space
+    // before it to distinguish it from an escaped pipe
+    const row = tableRow.replace(/\|/g, (match, offset, str) => {
+        let escaped = false, curr = offset;
+        while (--curr >= 0 && str[curr] === '\\')
+            escaped = !escaped;
+        if (escaped) {
+            // odd number of slashes means | is escaped
+            // so we leave it alone
+            return '|';
+        }
+        else {
+            // add space before unescaped |
+            return ' |';
+        }
+    }), cells = row.split(/ \|/);
+    let i = 0;
+    // First/last cell in a row cannot be empty if it has no leading/trailing pipe
+    if (!cells[0].trim()) {
+        cells.shift();
+    }
+    if (cells.length > 0 && !cells[cells.length - 1].trim()) {
+        cells.pop();
+    }
+    if (cells.length > count) {
+        cells.splice(count);
+    }
+    else {
+        while (cells.length < count)
+            cells.push('');
+    }
+    for (; i < cells.length; i++) {
+        // leading or trailing whitespace is ignored per the gfm spec
+        cells[i] = cells[i].trim().replace(/\\\|/g, '|');
+    }
+    return cells;
 }
+/**
+ * Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').
+ * /c*$/ is vulnerable to REDOS.
+ *
+ * @param str
+ * @param c
+ * @param invert Remove suffix of non-c chars instead. Default falsey.
+ */
 function rtrim(str, c, invert) {
-  const l = str.length;
-  if (l === 0) {
-    return "";
-  }
-  let suffLen = 0;
-  while (suffLen < l) {
-    const currChar = str.charAt(l - suffLen - 1);
-    if (currChar === c && !invert) {
-      suffLen++;
-    } else if (currChar !== c && invert) {
-      suffLen++;
-    } else {
-      break;
-    }
-  }
-  return str.slice(0, l - suffLen);
+    const l = str.length;
+    if (l === 0) {
+        return '';
+    }
+    // Length of suffix matching the invert condition.
+    let suffLen = 0;
+    // Step left until we fail to match the invert condition.
+    while (suffLen < l) {
+        const currChar = str.charAt(l - suffLen - 1);
+        if (currChar === c && !invert) {
+            suffLen++;
+        }
+        else if (currChar !== c && invert) {
+            suffLen++;
+        }
+        else {
+            break;
+        }
+    }
+    return str.slice(0, l - suffLen);
 }
 function findClosingBracket(str, b) {
-  if (str.indexOf(b[1]) === -1) {
+    if (str.indexOf(b[1]) === -1) {
+        return -1;
+    }
+    const l = str.length;
+    let level = 0, i = 0;
+    for (; i < l; i++) {
+        if (str[i] === '\\') {
+            i++;
+        }
+        else if (str[i] === b[0]) {
+            level++;
+        }
+        else if (str[i] === b[1]) {
+            level--;
+            if (level < 0) {
+                return i;
+            }
+        }
+    }
     return -1;
-  }
-  const l = str.length;
-  let level = 0, i = 0;
-  for (; i < l; i++) {
-    if (str[i] === "\\") {
-      i++;
-    } else if (str[i] === b[0]) {
-      level++;
-    } else if (str[i] === b[1]) {
-      level--;
-      if (level < 0) {
-        return i;
-      }
-    }
-  }
-  return -1;
 }
 function checkDeprecations(opt, callback) {
-  if (!opt || opt.silent) {
-    return;
-  }
-  if (callback) {
-    console.warn("marked(): callback is deprecated since version 5.0.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/using_pro#async");
-  }
-  if (opt.sanitize || opt.sanitizer) {
-    console.warn("marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options");
-  }
-  if (opt.highlight || opt.langPrefix !== "language-") {
-    console.warn("marked(): highlight and langPrefix parameters are deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-highlight.");
-  }
-  if (opt.mangle) {
-    console.warn("marked(): mangle parameter is enabled by default, but is deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install https://www.npmjs.com/package/marked-mangle, or disable by setting `{mangle: false}`.");
-  }
-  if (opt.baseUrl) {
-    console.warn("marked(): baseUrl parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-base-url.");
-  }
-  if (opt.smartypants) {
-    console.warn("marked(): smartypants parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-smartypants.");
-  }
-  if (opt.xhtml) {
-    console.warn("marked(): xhtml parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-xhtml.");
-  }
-  if (opt.headerIds || opt.headerPrefix) {
-    console.warn("marked(): headerIds and headerPrefix parameters enabled by default, but are deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install  https://www.npmjs.com/package/marked-gfm-heading-id, or disable by setting `{headerIds: false}`.");
-  }
+    if (!opt || opt.silent) {
+        return;
+    }
+    if (callback) {
+        console.warn('marked(): callback is deprecated since version 5.0.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/using_pro#async');
+    }
+    if (opt.sanitize || opt.sanitizer) {
+        console.warn('marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options');
+    }
+    if (opt.highlight || opt.langPrefix !== 'language-') {
+        console.warn('marked(): highlight and langPrefix parameters are deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-highlight.');
+    }
+    if (opt.mangle) {
+        console.warn('marked(): mangle parameter is enabled by default, but is deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install https://www.npmjs.com/package/marked-mangle, or disable by setting `{mangle: false}`.');
+    }
+    if (opt.baseUrl) {
+        console.warn('marked(): baseUrl parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-base-url.');
+    }
+    if (opt.smartypants) {
+        console.warn('marked(): smartypants parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-smartypants.');
+    }
+    if (opt.xhtml) {
+        console.warn('marked(): xhtml parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-xhtml.');
+    }
+    if (opt.headerIds || opt.headerPrefix) {
+        console.warn('marked(): headerIds and headerPrefix parameters enabled by default, but are deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install  https://www.npmjs.com/package/marked-gfm-heading-id, or disable by setting `{headerIds: false}`.');
+    }
 }
 
-// src/Tokenizer.ts
-function outputLink(cap, link, raw, lexer2) {
-  const href = link.href;
-  const title = link.title ? escape(link.title) : null;
-  const text = cap[1].replace(/\\([\[\]])/g, "$1");
-  if (cap[0].charAt(0) !== "!") {
-    lexer2.state.inLink = true;
-    const token = {
-      type: "link",
-      raw,
-      href,
-      title,
-      text,
-      tokens: lexer2.inlineTokens(text)
+function outputLink(cap, link, raw, lexer) {
+    const href = link.href;
+    const title = link.title ? escape(link.title) : null;
+    const text = cap[1].replace(/\\([\[\]])/g, '$1');
+    if (cap[0].charAt(0) !== '!') {
+        lexer.state.inLink = true;
+        const token = {
+            type: 'link',
+            raw,
+            href,
+            title,
+            text,
+            tokens: lexer.inlineTokens(text)
+        };
+        lexer.state.inLink = false;
+        return token;
+    }
+    return {
+        type: 'image',
+        raw,
+        href,
+        title,
+        text: escape(text)
     };
-    lexer2.state.inLink = false;
-    return token;
-  }
-  return {
-    type: "image",
-    raw,
-    href,
-    title,
-    text: escape(text)
-  };
 }
 function indentCodeCompensation(raw, text) {
-  const matchIndentToCode = raw.match(/^(\s+)(?:```)/);
-  if (matchIndentToCode === null) {
-    return text;
-  }
-  const indentToCode = matchIndentToCode[1];
-  return text.split("\n").map((node) => {
-    const matchIndentInNode = node.match(/^\s+/);
-    if (matchIndentInNode === null) {
-      return node;
-    }
-    const [indentInNode] = matchIndentInNode;
-    if (indentInNode.length >= indentToCode.length) {
-      return node.slice(indentToCode.length);
-    }
-    return node;
-  }).join("\n");
+    const matchIndentToCode = raw.match(/^(\s+)(?:```)/);
+    if (matchIndentToCode === null) {
+        return text;
+    }
+    const indentToCode = matchIndentToCode[1];
+    return text
+        .split('\n')
+        .map(node => {
+        const matchIndentInNode = node.match(/^\s+/);
+        if (matchIndentInNode === null) {
+            return node;
+        }
+        const [indentInNode] = matchIndentInNode;
+        if (indentInNode.length >= indentToCode.length) {
+            return node.slice(indentToCode.length);
+        }
+        return node;
+    })
+        .join('\n');
 }
-var _Tokenizer = class {
-  constructor(options2) {
-    this.options = options2 || _defaults;
-  }
-  space(src) {
-    const cap = this.rules.block.newline.exec(src);
-    if (cap && cap[0].length > 0) {
-      return {
-        type: "space",
-        raw: cap[0]
-      };
-    }
-  }
-  code(src) {
-    const cap = this.rules.block.code.exec(src);
-    if (cap) {
-      const text = cap[0].replace(/^ {1,4}/gm, "");
-      return {
-        type: "code",
-        raw: cap[0],
-        codeBlockStyle: "indented",
-        text: !this.options.pedantic ? rtrim(text, "\n") : text
-      };
-    }
-  }
-  fences(src) {
-    const cap = this.rules.block.fences.exec(src);
-    if (cap) {
-      const raw = cap[0];
-      const text = indentCodeCompensation(raw, cap[3] || "");
-      return {
-        type: "code",
-        raw,
-        lang: cap[2] ? cap[2].trim().replace(this.rules.inline._escapes, "$1") : cap[2],
-        text
-      };
-    }
-  }
-  heading(src) {
-    const cap = this.rules.block.heading.exec(src);
-    if (cap) {
-      let text = cap[2].trim();
-      if (/#$/.test(text)) {
-        const trimmed = rtrim(text, "#");
-        if (this.options.pedantic) {
-          text = trimmed.trim();
-        } else if (!trimmed || / $/.test(trimmed)) {
-          text = trimmed.trim();
-        }
-      }
-      return {
-        type: "heading",
-        raw: cap[0],
-        depth: cap[1].length,
-        text,
-        tokens: this.lexer.inline(text)
-      };
-    }
-  }
-  hr(src) {
-    const cap = this.rules.block.hr.exec(src);
-    if (cap) {
-      return {
-        type: "hr",
-        raw: cap[0]
-      };
-    }
-  }
-  blockquote(src) {
-    const cap = this.rules.block.blockquote.exec(src);
-    if (cap) {
-      const text = cap[0].replace(/^ *>[ \t]?/gm, "");
-      const top = this.lexer.state.top;
-      this.lexer.state.top = true;
-      const tokens = this.lexer.blockTokens(text);
-      this.lexer.state.top = top;
-      return {
-        type: "blockquote",
-        raw: cap[0],
-        tokens,
-        text
-      };
-    }
-  }
-  list(src) {
-    let cap = this.rules.block.list.exec(src);
-    if (cap) {
-      let raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine, line, nextLine, rawLine, itemContents, endEarly;
-      let bull = cap[1].trim();
-      const isordered = bull.length > 1;
-      const list = {
-        type: "list",
-        raw: "",
-        ordered: isordered,
-        start: isordered ? +bull.slice(0, -1) : "",
-        loose: false,
-        items: []
-      };
-      bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`;
-      if (this.options.pedantic) {
-        bull = isordered ? bull : "[*+-]";
-      }
-      const itemRegex = new RegExp(`^( {0,3}${bull})((?:[	 ][^\\n]*)?(?:\\n|$))`);
-      while (src) {
-        endEarly = false;
-        if (!(cap = itemRegex.exec(src))) {
-          break;
-        }
-        if (this.rules.block.hr.test(src)) {
-          break;
-        }
-        raw = cap[0];
-        src = src.substring(raw.length);
-        line = cap[2].split("\n", 1)[0].replace(/^\t+/, (t) => " ".repeat(3 * t.length));
-        nextLine = src.split("\n", 1)[0];
-        if (this.options.pedantic) {
-          indent = 2;
-          itemContents = line.trimLeft();
-        } else {
-          indent = cap[2].search(/[^ ]/);
-          indent = indent > 4 ? 1 : indent;
-          itemContents = line.slice(indent);
-          indent += cap[1].length;
-        }
-        blankLine = false;
-        if (!line && /^ *$/.test(nextLine)) {
-          raw += nextLine + "\n";
-          src = src.substring(nextLine.length + 1);
-          endEarly = true;
-        }
-        if (!endEarly) {
-          const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ 	][^\\n]*)?(?:\\n|$))`);
-          const hrRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`);
-          const fencesBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\`\`\`|~~~)`);
-          const headingBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`);
-          while (src) {
-            rawLine = src.split("\n", 1)[0];
-            nextLine = rawLine;
+/**
+ * Tokenizer
+ */
+class _Tokenizer {
+    options;
+    rules;
+    lexer;
+    constructor(options) {
+        this.options = options || _defaults;
+    }
+    space(src) {
+        const cap = this.rules.block.newline.exec(src);
+        if (cap && cap[0].length > 0) {
+            return {
+                type: 'space',
+                raw: cap[0]
+            };
+        }
+    }
+    code(src) {
+        const cap = this.rules.block.code.exec(src);
+        if (cap) {
+            const text = cap[0].replace(/^ {1,4}/gm, '');
+            return {
+                type: 'code',
+                raw: cap[0],
+                codeBlockStyle: 'indented',
+                text: !this.options.pedantic
+                    ? rtrim(text, '\n')
+                    : text
+            };
+        }
+    }
+    fences(src) {
+        const cap = this.rules.block.fences.exec(src);
+        if (cap) {
+            const raw = cap[0];
+            const text = indentCodeCompensation(raw, cap[3] || '');
+            return {
+                type: 'code',
+                raw,
+                lang: cap[2] ? cap[2].trim().replace(this.rules.inline._escapes, '$1') : cap[2],
+                text
+            };
+        }
+    }
+    heading(src) {
+        const cap = this.rules.block.heading.exec(src);
+        if (cap) {
+            let text = cap[2].trim();
+            // remove trailing #s
+            if (/#$/.test(text)) {
+                const trimmed = rtrim(text, '#');
+                if (this.options.pedantic) {
+                    text = trimmed.trim();
+                }
+                else if (!trimmed || / $/.test(trimmed)) {
+                    // CommonMark requires space before trailing #s
+                    text = trimmed.trim();
+                }
+            }
+            return {
+                type: 'heading',
+                raw: cap[0],
+                depth: cap[1].length,
+                text,
+                tokens: this.lexer.inline(text)
+            };
+        }
+    }
+    hr(src) {
+        const cap = this.rules.block.hr.exec(src);
+        if (cap) {
+            return {
+                type: 'hr',
+                raw: cap[0]
+            };
+        }
+    }
+    blockquote(src) {
+        const cap = this.rules.block.blockquote.exec(src);
+        if (cap) {
+            const text = cap[0].replace(/^ *>[ \t]?/gm, '');
+            const top = this.lexer.state.top;
+            this.lexer.state.top = true;
+            const tokens = this.lexer.blockTokens(text);
+            this.lexer.state.top = top;
+            return {
+                type: 'blockquote',
+                raw: cap[0],
+                tokens,
+                text
+            };
+        }
+    }
+    list(src) {
+        let cap = this.rules.block.list.exec(src);
+        if (cap) {
+            let raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine, line, nextLine, rawLine, itemContents, endEarly;
+            let bull = cap[1].trim();
+            const isordered = bull.length > 1;
+            const list = {
+                type: 'list',
+                raw: '',
+                ordered: isordered,
+                start: isordered ? +bull.slice(0, -1) : '',
+                loose: false,
+                items: []
+            };
+            bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`;
             if (this.options.pedantic) {
-              nextLine = nextLine.replace(/^ {1,4}(?=( {4})*[^ ])/g, "  ");
-            }
-            if (fencesBeginRegex.test(nextLine)) {
-              break;
-            }
-            if (headingBeginRegex.test(nextLine)) {
-              break;
-            }
-            if (nextBulletRegex.test(nextLine)) {
-              break;
-            }
-            if (hrRegex.test(src)) {
-              break;
-            }
-            if (nextLine.search(/[^ ]/) >= indent || !nextLine.trim()) {
-              itemContents += "\n" + nextLine.slice(indent);
-            } else {
-              if (blankLine) {
-                break;
-              }
-              if (line.search(/[^ ]/) >= 4) {
-                break;
-              }
-              if (fencesBeginRegex.test(line)) {
-                break;
-              }
-              if (headingBeginRegex.test(line)) {
-                break;
-              }
-              if (hrRegex.test(line)) {
-                break;
-              }
-              itemContents += "\n" + nextLine;
-            }
-            if (!blankLine && !nextLine.trim()) {
-              blankLine = true;
-            }
-            raw += rawLine + "\n";
-            src = src.substring(rawLine.length + 1);
-            line = nextLine.slice(indent);
-          }
-        }
-        if (!list.loose) {
-          if (endsWithBlankLine) {
-            list.loose = true;
-          } else if (/\n *\n *$/.test(raw)) {
-            endsWithBlankLine = true;
-          }
-        }
-        if (this.options.gfm) {
-          istask = /^\[[ xX]\] /.exec(itemContents);
-          if (istask) {
-            ischecked = istask[0] !== "[ ] ";
-            itemContents = itemContents.replace(/^\[[ xX]\] +/, "");
-          }
-        }
-        list.items.push({
-          type: "list_item",
-          raw,
-          task: !!istask,
-          checked: ischecked,
-          loose: false,
-          text: itemContents
-        });
-        list.raw += raw;
-      }
-      list.items[list.items.length - 1].raw = raw.trimRight();
-      list.items[list.items.length - 1].text = itemContents.trimRight();
-      list.raw = list.raw.trimRight();
-      const l = list.items.length;
-      for (i = 0; i < l; i++) {
-        this.lexer.state.top = false;
-        list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);
-        if (!list.loose) {
-          const spacers = list.items[i].tokens.filter((t) => t.type === "space");
-          const hasMultipleLineBreaks = spacers.length > 0 && spacers.some((t) => /\n.*\n/.test(t.raw));
-          list.loose = hasMultipleLineBreaks;
-        }
-      }
-      if (list.loose) {
-        for (i = 0; i < l; i++) {
-          list.items[i].loose = true;
-        }
-      }
-      return list;
-    }
-  }
-  html(src) {
-    const cap = this.rules.block.html.exec(src);
-    if (cap) {
-      const token = {
-        type: "html",
-        block: true,
-        raw: cap[0],
-        pre: !this.options.sanitizer && (cap[1] === "pre" || cap[1] === "script" || cap[1] === "style"),
-        text: cap[0]
-      };
-      if (this.options.sanitize) {
-        const text = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]);
-        const paragraph = token;
-        paragraph.type = "paragraph";
-        paragraph.text = text;
-        paragraph.tokens = this.lexer.inline(text);
-      }
-      return token;
-    }
-  }
-  def(src) {
-    const cap = this.rules.block.def.exec(src);
-    if (cap) {
-      const tag = cap[1].toLowerCase().replace(/\s+/g, " ");
-      const href = cap[2] ? cap[2].replace(/^<(.*)>$/, "$1").replace(this.rules.inline._escapes, "$1") : "";
-      const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline._escapes, "$1") : cap[3];
-      return {
-        type: "def",
-        tag,
-        raw: cap[0],
-        href,
-        title
-      };
-    }
-  }
-  table(src) {
-    const cap = this.rules.block.table.exec(src);
-    if (cap) {
-      const item = {
-        type: "table",
-        // splitCells expects a number as second argument
-        // @ts-expect-error
-        header: splitCells(cap[1]).map((c) => {
-          return { text: c };
-        }),
-        align: cap[2].replace(/^ *|\| *$/g, "").split(/ *\| */),
-        rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, "").split("\n") : []
-      };
-      if (item.header.length === item.align.length) {
-        item.raw = cap[0];
-        let l = item.align.length;
-        let i, j, k, row;
-        for (i = 0; i < l; i++) {
-          if (/^ *-+: *$/.test(item.align[i])) {
-            item.align[i] = "right";
-          } else if (/^ *:-+: *$/.test(item.align[i])) {
-            item.align[i] = "center";
-          } else if (/^ *:-+ *$/.test(item.align[i])) {
-            item.align[i] = "left";
-          } else {
-            item.align[i] = null;
-          }
-        }
-        l = item.rows.length;
-        for (i = 0; i < l; i++) {
-          item.rows[i] = splitCells(item.rows[i], item.header.length).map((c) => {
-            return { text: c };
-          });
-        }
-        l = item.header.length;
-        for (j = 0; j < l; j++) {
-          item.header[j].tokens = this.lexer.inline(item.header[j].text);
-        }
-        l = item.rows.length;
-        for (j = 0; j < l; j++) {
-          row = item.rows[j];
-          for (k = 0; k < row.length; k++) {
-            row[k].tokens = this.lexer.inline(row[k].text);
-          }
-        }
-        return item;
-      }
-    }
-  }
-  lheading(src) {
-    const cap = this.rules.block.lheading.exec(src);
-    if (cap) {
-      return {
-        type: "heading",
-        raw: cap[0],
-        depth: cap[2].charAt(0) === "=" ? 1 : 2,
-        text: cap[1],
-        tokens: this.lexer.inline(cap[1])
-      };
-    }
-  }
-  paragraph(src) {
-    const cap = this.rules.block.paragraph.exec(src);
-    if (cap) {
-      const text = cap[1].charAt(cap[1].length - 1) === "\n" ? cap[1].slice(0, -1) : cap[1];
-      return {
-        type: "paragraph",
-        raw: cap[0],
-        text,
-        tokens: this.lexer.inline(text)
-      };
-    }
-  }
-  text(src) {
-    const cap = this.rules.block.text.exec(src);
-    if (cap) {
-      return {
-        type: "text",
-        raw: cap[0],
-        text: cap[0],
-        tokens: this.lexer.inline(cap[0])
-      };
-    }
-  }
-  escape(src) {
-    const cap = this.rules.inline.escape.exec(src);
-    if (cap) {
-      return {
-        type: "escape",
-        raw: cap[0],
-        text: escape(cap[1])
-      };
-    }
-  }
-  tag(src) {
-    const cap = this.rules.inline.tag.exec(src);
-    if (cap) {
-      if (!this.lexer.state.inLink && /^<a /i.test(cap[0])) {
-        this.lexer.state.inLink = true;
-      } else if (this.lexer.state.inLink && /^<\/a>/i.test(cap[0])) {
-        this.lexer.state.inLink = false;
-      }
-      if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
-        this.lexer.state.inRawBlock = true;
-      } else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
-        this.lexer.state.inRawBlock = false;
-      }
-      return {
-        type: this.options.sanitize ? "text" : "html",
-        raw: cap[0],
-        inLink: this.lexer.state.inLink,
-        inRawBlock: this.lexer.state.inRawBlock,
-        block: false,
-        text: this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0]
-      };
-    }
-  }
-  link(src) {
-    const cap = this.rules.inline.link.exec(src);
-    if (cap) {
-      const trimmedUrl = cap[2].trim();
-      if (!this.options.pedantic && /^</.test(trimmedUrl)) {
-        if (!/>$/.test(trimmedUrl)) {
-          return;
-        }
-        const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), "\\");
-        if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {
-          return;
-        }
-      } else {
-        const lastParenIndex = findClosingBracket(cap[2], "()");
-        if (lastParenIndex > -1) {
-          const start = cap[0].indexOf("!") === 0 ? 5 : 4;
-          const linkLen = start + cap[1].length + lastParenIndex;
-          cap[2] = cap[2].substring(0, lastParenIndex);
-          cap[0] = cap[0].substring(0, linkLen).trim();
-          cap[3] = "";
-        }
-      }
-      let href = cap[2];
-      let title = "";
-      if (this.options.pedantic) {
-        const link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
-        if (link) {
-          href = link[1];
-          title = link[3];
-        }
-      } else {
-        title = cap[3] ? cap[3].slice(1, -1) : "";
-      }
-      href = href.trim();
-      if (/^</.test(href)) {
-        if (this.options.pedantic && !/>$/.test(trimmedUrl)) {
-          href = href.slice(1);
-        } else {
-          href = href.slice(1, -1);
-        }
-      }
-      return outputLink(cap, {
-        href: href ? href.replace(this.rules.inline._escapes, "$1") : href,
-        title: title ? title.replace(this.rules.inline._escapes, "$1") : title
-      }, cap[0], this.lexer);
-    }
-  }
-  reflink(src, links) {
-    let cap;
-    if ((cap = this.rules.inline.reflink.exec(src)) || (cap = this.rules.inline.nolink.exec(src))) {
-      let link = (cap[2] || cap[1]).replace(/\s+/g, " ");
-      link = links[link.toLowerCase()];
-      if (!link) {
-        const text = cap[0].charAt(0);
-        return {
-          type: "text",
-          raw: text,
-          text
-        };
-      }
-      return outputLink(cap, link, cap[0], this.lexer);
-    }
-  }
-  emStrong(src, maskedSrc, prevChar = "") {
-    let match = this.rules.inline.emStrong.lDelim.exec(src);
-    if (!match)
-      return;
-    if (match[3] && prevChar.match(/[\p{L}\p{N}]/u))
-      return;
-    const nextChar = match[1] || match[2] || "";
-    if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) {
-      const lLength = match[0].length - 1;
-      let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;
-      const endReg = match[0][0] === "*" ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;
-      endReg.lastIndex = 0;
-      maskedSrc = maskedSrc.slice(-1 * src.length + lLength);
-      while ((match = endReg.exec(maskedSrc)) != null) {
-        rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
-        if (!rDelim)
-          continue;
-        rLength = rDelim.length;
-        if (match[3] || match[4]) {
-          delimTotal += rLength;
-          continue;
-        } else if (match[5] || match[6]) {
-          if (lLength % 3 && !((lLength + rLength) % 3)) {
-            midDelimTotal += rLength;
-            continue;
-          }
-        }
-        delimTotal -= rLength;
-        if (delimTotal > 0)
-          continue;
-        rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
-        const raw = src.slice(0, lLength + match.index + rLength + 1);
-        if (Math.min(lLength, rLength) % 2) {
-          const text2 = raw.slice(1, -1);
-          return {
-            type: "em",
-            raw,
-            text: text2,
-            tokens: this.lexer.inlineTokens(text2)
-          };
+                bull = isordered ? bull : '[*+-]';
+            }
+            // Get next list item
+            const itemRegex = new RegExp(`^( {0,3}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))`);
+            // Check if current bullet point can start a new List Item
+            while (src) {
+                endEarly = false;
+                if (!(cap = itemRegex.exec(src))) {
+                    break;
+                }
+                if (this.rules.block.hr.test(src)) { // End list if bullet was actually HR (possibly move into itemRegex?)
+                    break;
+                }
+                raw = cap[0];
+                src = src.substring(raw.length);
+                line = cap[2].split('\n', 1)[0].replace(/^\t+/, (t) => ' '.repeat(3 * t.length));
+                nextLine = src.split('\n', 1)[0];
+                if (this.options.pedantic) {
+                    indent = 2;
+                    itemContents = line.trimLeft();
+                }
+                else {
+                    indent = cap[2].search(/[^ ]/); // Find first non-space char
+                    indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent
+                    itemContents = line.slice(indent);
+                    indent += cap[1].length;
+                }
+                blankLine = false;
+                if (!line && /^ *$/.test(nextLine)) { // Items begin with at most one blank line
+                    raw += nextLine + '\n';
+                    src = src.substring(nextLine.length + 1);
+                    endEarly = true;
+                }
+                if (!endEarly) {
+                    const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`);
+                    const hrRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`);
+                    const fencesBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\`\`\`|~~~)`);
+                    const headingBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`);
+                    // Check if following lines should be included in List Item
+                    while (src) {
+                        rawLine = src.split('\n', 1)[0];
+                        nextLine = rawLine;
+                        // Re-align to follow commonmark nesting rules
+                        if (this.options.pedantic) {
+                            nextLine = nextLine.replace(/^ {1,4}(?=( {4})*[^ ])/g, '  ');
+                        }
+                        // End list item if found code fences
+                        if (fencesBeginRegex.test(nextLine)) {
+                            break;
+                        }
+                        // End list item if found start of new heading
+                        if (headingBeginRegex.test(nextLine)) {
+                            break;
+                        }
+                        // End list item if found start of new bullet
+                        if (nextBulletRegex.test(nextLine)) {
+                            break;
+                        }
+                        // Horizontal rule found
+                        if (hrRegex.test(src)) {
+                            break;
+                        }
+                        if (nextLine.search(/[^ ]/) >= indent || !nextLine.trim()) { // Dedent if possible
+                            itemContents += '\n' + nextLine.slice(indent);
+                        }
+                        else {
+                            // not enough indentation
+                            if (blankLine) {
+                                break;
+                            }
+                            // paragraph continuation unless last line was a different block level element
+                            if (line.search(/[^ ]/) >= 4) { // indented code block
+                                break;
+                            }
+                            if (fencesBeginRegex.test(line)) {
+                                break;
+                            }
+                            if (headingBeginRegex.test(line)) {
+                                break;
+                            }
+                            if (hrRegex.test(line)) {
+                                break;
+                            }
+                            itemContents += '\n' + nextLine;
+                        }
+                        if (!blankLine && !nextLine.trim()) { // Check if current line is blank
+                            blankLine = true;
+                        }
+                        raw += rawLine + '\n';
+                        src = src.substring(rawLine.length + 1);
+                        line = nextLine.slice(indent);
+                    }
+                }
+                if (!list.loose) {
+                    // If the previous item ended with a blank line, the list is loose
+                    if (endsWithBlankLine) {
+                        list.loose = true;
+                    }
+                    else if (/\n *\n *$/.test(raw)) {
+                        endsWithBlankLine = true;
+                    }
+                }
+                // Check for task list items
+                if (this.options.gfm) {
+                    istask = /^\[[ xX]\] /.exec(itemContents);
+                    if (istask) {
+                        ischecked = istask[0] !== '[ ] ';
+                        itemContents = itemContents.replace(/^\[[ xX]\] +/, '');
+                    }
+                }
+                list.items.push({
+                    type: 'list_item',
+                    raw,
+                    task: !!istask,
+                    checked: ischecked,
+                    loose: false,
+                    text: itemContents
+                });
+                list.raw += raw;
+            }
+            // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic
+            list.items[list.items.length - 1].raw = raw.trimRight();
+            list.items[list.items.length - 1].text = itemContents.trimRight();
+            list.raw = list.raw.trimRight();
+            const l = list.items.length;
+            // Item child tokens handled here at end because we needed to have the final item to trim it first
+            for (i = 0; i < l; i++) {
+                this.lexer.state.top = false;
+                list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);
+                if (!list.loose) {
+                    // Check if list should be loose
+                    const spacers = list.items[i].tokens.filter(t => t.type === 'space');
+                    const hasMultipleLineBreaks = spacers.length > 0 && spacers.some(t => /\n.*\n/.test(t.raw));
+                    list.loose = hasMultipleLineBreaks;
+                }
+            }
+            // Set all items to loose if list is loose
+            if (list.loose) {
+                for (i = 0; i < l; i++) {
+                    list.items[i].loose = true;
+                }
+            }
+            return list;
+        }
+    }
+    html(src) {
+        const cap = this.rules.block.html.exec(src);
+        if (cap) {
+            const token = {
+                type: 'html',
+                block: true,
+                raw: cap[0],
+                pre: !this.options.sanitizer
+                    && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
+                text: cap[0]
+            };
+            if (this.options.sanitize) {
+                const text = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]);
+                const paragraph = token;
+                paragraph.type = 'paragraph';
+                paragraph.text = text;
+                paragraph.tokens = this.lexer.inline(text);
+            }
+            return token;
+        }
+    }
+    def(src) {
+        const cap = this.rules.block.def.exec(src);
+        if (cap) {
+            const tag = cap[1].toLowerCase().replace(/\s+/g, ' ');
+            const href = cap[2] ? cap[2].replace(/^<(.*)>$/, '$1').replace(this.rules.inline._escapes, '$1') : '';
+            const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline._escapes, '$1') : cap[3];
+            return {
+                type: 'def',
+                tag,
+                raw: cap[0],
+                href,
+                title
+            };
         }
-        const text = raw.slice(2, -2);
-        return {
-          type: "strong",
-          raw,
-          text,
-          tokens: this.lexer.inlineTokens(text)
-        };
-      }
-    }
-  }
-  codespan(src) {
-    const cap = this.rules.inline.code.exec(src);
-    if (cap) {
-      let text = cap[2].replace(/\n/g, " ");
-      const hasNonSpaceChars = /[^ ]/.test(text);
-      const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text);
-      if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
-        text = text.substring(1, text.length - 1);
-      }
-      text = escape(text, true);
-      return {
-        type: "codespan",
-        raw: cap[0],
-        text
-      };
-    }
-  }
-  br(src) {
-    const cap = this.rules.inline.br.exec(src);
-    if (cap) {
-      return {
-        type: "br",
-        raw: cap[0]
-      };
-    }
-  }
-  del(src) {
-    const cap = this.rules.inline.del.exec(src);
-    if (cap) {
-      return {
-        type: "del",
-        raw: cap[0],
-        text: cap[2],
-        tokens: this.lexer.inlineTokens(cap[2])
-      };
-    }
-  }
-  autolink(src, mangle2) {
-    const cap = this.rules.inline.autolink.exec(src);
-    if (cap) {
-      let text, href;
-      if (cap[2] === "@") {
-        text = escape(this.options.mangle ? mangle2(cap[1]) : cap[1]);
-        href = "mailto:" + text;
-      } else {
-        text = escape(cap[1]);
-        href = text;
-      }
-      return {
-        type: "link",
-        raw: cap[0],
-        text,
-        href,
-        tokens: [
-          {
-            type: "text",
-            raw: text,
-            text
-          }
-        ]
-      };
-    }
-  }
-  url(src, mangle2) {
-    let cap;
-    if (cap = this.rules.inline.url.exec(src)) {
-      let text, href;
-      if (cap[2] === "@") {
-        text = escape(this.options.mangle ? mangle2(cap[0]) : cap[0]);
-        href = "mailto:" + text;
-      } else {
-        let prevCapZero;
-        do {
-          prevCapZero = cap[0];
-          cap[0] = this.rules.inline._backpedal.exec(cap[0])[0];
-        } while (prevCapZero !== cap[0]);
-        text = escape(cap[0]);
-        if (cap[1] === "www.") {
-          href = "http://" + cap[0];
-        } else {
-          href = cap[0];
-        }
-      }
-      return {
-        type: "link",
-        raw: cap[0],
-        text,
-        href,
-        tokens: [
-          {
-            type: "text",
-            raw: text,
-            text
-          }
-        ]
-      };
-    }
-  }
-  inlineText(src, smartypants2) {
-    const cap = this.rules.inline.text.exec(src);
-    if (cap) {
-      let text;
-      if (this.lexer.state.inRawBlock) {
-        text = this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0];
-      } else {
-        text = escape(this.options.smartypants ? smartypants2(cap[0]) : cap[0]);
-      }
-      return {
-        type: "text",
-        raw: cap[0],
-        text
-      };
-    }
-  }
-};
+    }
+    table(src) {
+        const cap = this.rules.block.table.exec(src);
+        if (cap) {
+            const item = {
+                type: 'table',
+                // splitCells expects a number as second argument
+                // @ts-expect-error
+                header: splitCells(cap[1]).map(c => {
+                    return { text: c };
+                }),
+                align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
+                rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : []
+            };
+            if (item.header.length === item.align.length) {
+                item.raw = cap[0];
+                let l = item.align.length;
+                let i, j, k, row;
+                for (i = 0; i < l; i++) {
+                    if (/^ *-+: *$/.test(item.align[i])) {
+                        item.align[i] = 'right';
+                    }
+                    else if (/^ *:-+: *$/.test(item.align[i])) {
+                        item.align[i] = 'center';
+                    }
+                    else if (/^ *:-+ *$/.test(item.align[i])) {
+                        item.align[i] = 'left';
+                    }
+                    else {
+                        item.align[i] = null;
+                    }
+                }
+                l = item.rows.length;
+                for (i = 0; i < l; i++) {
+                    item.rows[i] = splitCells(item.rows[i], item.header.length).map(c => {
+                        return { text: c };
+                    });
+                }
+                // parse child tokens inside headers and cells
+                // header child tokens
+                l = item.header.length;
+                for (j = 0; j < l; j++) {
+                    item.header[j].tokens = this.lexer.inline(item.header[j].text);
+                }
+                // cell child tokens
+                l = item.rows.length;
+                for (j = 0; j < l; j++) {
+                    row = item.rows[j];
+                    for (k = 0; k < row.length; k++) {
+                        row[k].tokens = this.lexer.inline(row[k].text);
+                    }
+                }
+                return item;
+            }
+        }
+    }
+    lheading(src) {
+        const cap = this.rules.block.lheading.exec(src);
+        if (cap) {
+            return {
+                type: 'heading',
+                raw: cap[0],
+                depth: cap[2].charAt(0) === '=' ? 1 : 2,
+                text: cap[1],
+                tokens: this.lexer.inline(cap[1])
+            };
+        }
+    }
+    paragraph(src) {
+        const cap = this.rules.block.paragraph.exec(src);
+        if (cap) {
+            const text = cap[1].charAt(cap[1].length - 1) === '\n'
+                ? cap[1].slice(0, -1)
+                : cap[1];
+            return {
+                type: 'paragraph',
+                raw: cap[0],
+                text,
+                tokens: this.lexer.inline(text)
+            };
+        }
+    }
+    text(src) {
+        const cap = this.rules.block.text.exec(src);
+        if (cap) {
+            return {
+                type: 'text',
+                raw: cap[0],
+                text: cap[0],
+                tokens: this.lexer.inline(cap[0])
+            };
+        }
+    }
+    escape(src) {
+        const cap = this.rules.inline.escape.exec(src);
+        if (cap) {
+            return {
+                type: 'escape',
+                raw: cap[0],
+                text: escape(cap[1])
+            };
+        }
+    }
+    tag(src) {
+        const cap = this.rules.inline.tag.exec(src);
+        if (cap) {
+            if (!this.lexer.state.inLink && /^<a /i.test(cap[0])) {
+                this.lexer.state.inLink = true;
+            }
+            else if (this.lexer.state.inLink && /^<\/a>/i.test(cap[0])) {
+                this.lexer.state.inLink = false;
+            }
+            if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
+                this.lexer.state.inRawBlock = true;
+            }
+            else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
+                this.lexer.state.inRawBlock = false;
+            }
+            return {
+                type: this.options.sanitize
+                    ? 'text'
+                    : 'html',
+                raw: cap[0],
+                inLink: this.lexer.state.inLink,
+                inRawBlock: this.lexer.state.inRawBlock,
+                block: false,
+                text: this.options.sanitize
+                    ? (this.options.sanitizer
+                        ? this.options.sanitizer(cap[0])
+                        : escape(cap[0]))
+                    : cap[0]
+            };
+        }
+    }
+    link(src) {
+        const cap = this.rules.inline.link.exec(src);
+        if (cap) {
+            const trimmedUrl = cap[2].trim();
+            if (!this.options.pedantic && /^</.test(trimmedUrl)) {
+                // commonmark requires matching angle brackets
+                if (!(/>$/.test(trimmedUrl))) {
+                    return;
+                }
+                // ending angle bracket cannot be escaped
+                const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\');
+                if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {
+                    return;
+                }
+            }
+            else {
+                // find closing parenthesis
+                const lastParenIndex = findClosingBracket(cap[2], '()');
+                if (lastParenIndex > -1) {
+                    const start = cap[0].indexOf('!') === 0 ? 5 : 4;
+                    const linkLen = start + cap[1].length + lastParenIndex;
+                    cap[2] = cap[2].substring(0, lastParenIndex);
+                    cap[0] = cap[0].substring(0, linkLen).trim();
+                    cap[3] = '';
+                }
+            }
+            let href = cap[2];
+            let title = '';
+            if (this.options.pedantic) {
+                // split pedantic href and title
+                const link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
+                if (link) {
+                    href = link[1];
+                    title = link[3];
+                }
+            }
+            else {
+                title = cap[3] ? cap[3].slice(1, -1) : '';
+            }
+            href = href.trim();
+            if (/^</.test(href)) {
+                if (this.options.pedantic && !(/>$/.test(trimmedUrl))) {
+                    // pedantic allows starting angle bracket without ending angle bracket
+                    href = href.slice(1);
+                }
+                else {
+                    href = href.slice(1, -1);
+                }
+            }
+            return outputLink(cap, {
+                href: href ? href.replace(this.rules.inline._escapes, '$1') : href,
+                title: title ? title.replace(this.rules.inline._escapes, '$1') : title
+            }, cap[0], this.lexer);
+        }
+    }
+    reflink(src, links) {
+        let cap;
+        if ((cap = this.rules.inline.reflink.exec(src))
+            || (cap = this.rules.inline.nolink.exec(src))) {
+            let link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
+            link = links[link.toLowerCase()];
+            if (!link) {
+                const text = cap[0].charAt(0);
+                return {
+                    type: 'text',
+                    raw: text,
+                    text
+                };
+            }
+            return outputLink(cap, link, cap[0], this.lexer);
+        }
+    }
+    emStrong(src, maskedSrc, prevChar = '') {
+        let match = this.rules.inline.emStrong.lDelim.exec(src);
+        if (!match)
+            return;
+        // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well
+        if (match[3] && prevChar.match(/[\p{L}\p{N}]/u))
+            return;
+        const nextChar = match[1] || match[2] || '';
+        if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) {
+            const lLength = match[0].length - 1;
+            let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;
+            const endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;
+            endReg.lastIndex = 0;
+            // Clip maskedSrc to same section of string as src (move to lexer?)
+            maskedSrc = maskedSrc.slice(-1 * src.length + lLength);
+            while ((match = endReg.exec(maskedSrc)) != null) {
+                rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
+                if (!rDelim)
+                    continue; // skip single * in __abc*abc__
+                rLength = rDelim.length;
+                if (match[3] || match[4]) { // found another Left Delim
+                    delimTotal += rLength;
+                    continue;
+                }
+                else if (match[5] || match[6]) { // either Left or Right Delim
+                    if (lLength % 3 && !((lLength + rLength) % 3)) {
+                        midDelimTotal += rLength;
+                        continue; // CommonMark Emphasis Rules 9-10
+                    }
+                }
+                delimTotal -= rLength;
+                if (delimTotal > 0)
+                    continue; // Haven't found enough closing delimiters
+                // Remove extra characters. *a*** -> *a*
+                rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
+                const raw = src.slice(0, lLength + match.index + rLength + 1);
+                // Create `em` if smallest delimiter has odd char count. *a***
+                if (Math.min(lLength, rLength) % 2) {
+                    const text = raw.slice(1, -1);
+                    return {
+                        type: 'em',
+                        raw,
+                        text,
+                        tokens: this.lexer.inlineTokens(text)
+                    };
+                }
+                // Create 'strong' if smallest delimiter has even char count. **a***
+                const text = raw.slice(2, -2);
+                return {
+                    type: 'strong',
+                    raw,
+                    text,
+                    tokens: this.lexer.inlineTokens(text)
+                };
+            }
+        }
+    }
+    codespan(src) {
+        const cap = this.rules.inline.code.exec(src);
+        if (cap) {
+            let text = cap[2].replace(/\n/g, ' ');
+            const hasNonSpaceChars = /[^ ]/.test(text);
+            const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text);
+            if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
+                text = text.substring(1, text.length - 1);
+            }
+            text = escape(text, true);
+            return {
+                type: 'codespan',
+                raw: cap[0],
+                text
+            };
+        }
+    }
+    br(src) {
+        const cap = this.rules.inline.br.exec(src);
+        if (cap) {
+            return {
+                type: 'br',
+                raw: cap[0]
+            };
+        }
+    }
+    del(src) {
+        const cap = this.rules.inline.del.exec(src);
+        if (cap) {
+            return {
+                type: 'del',
+                raw: cap[0],
+                text: cap[2],
+                tokens: this.lexer.inlineTokens(cap[2])
+            };
+        }
+    }
+    autolink(src, mangle) {
+        const cap = this.rules.inline.autolink.exec(src);
+        if (cap) {
+            let text, href;
+            if (cap[2] === '@') {
+                text = escape(this.options.mangle ? mangle(cap[1]) : cap[1]);
+                href = 'mailto:' + text;
+            }
+            else {
+                text = escape(cap[1]);
+                href = text;
+            }
+            return {
+                type: 'link',
+                raw: cap[0],
+                text,
+                href,
+                tokens: [
+                    {
+                        type: 'text',
+                        raw: text,
+                        text
+                    }
+                ]
+            };
+        }
+    }
+    url(src, mangle) {
+        let cap;
+        if (cap = this.rules.inline.url.exec(src)) {
+            let text, href;
+            if (cap[2] === '@') {
+                text = escape(this.options.mangle ? mangle(cap[0]) : cap[0]);
+                href = 'mailto:' + text;
+            }
+            else {
+                // do extended autolink path validation
+                let prevCapZero;
+                do {
+                    prevCapZero = cap[0];
+                    cap[0] = this.rules.inline._backpedal.exec(cap[0])[0];
+                } while (prevCapZero !== cap[0]);
+                text = escape(cap[0]);
+                if (cap[1] === 'www.') {
+                    href = 'http://' + cap[0];
+                }
+                else {
+                    href = cap[0];
+                }
+            }
+            return {
+                type: 'link',
+                raw: cap[0],
+                text,
+                href,
+                tokens: [
+                    {
+                        type: 'text',
+                        raw: text,
+                        text
+                    }
+                ]
+            };
+        }
+    }
+    inlineText(src, smartypants) {
+        const cap = this.rules.inline.text.exec(src);
+        if (cap) {
+            let text;
+            if (this.lexer.state.inRawBlock) {
+                text = this.options.sanitize ? (this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0])) : cap[0];
+            }
+            else {
+                text = escape(this.options.smartypants ? smartypants(cap[0]) : cap[0]);
+            }
+            return {
+                type: 'text',
+                raw: cap[0],
+                text
+            };
+        }
+    }
+}
 
-// src/rules.ts
-var block = {
-  newline: /^(?: *(?:\n|$))+/,
-  code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
-  fences: /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,
-  hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,
-  heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,
-  blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
-  list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/,
-  html: "^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))",
-  def: /^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,
-  table: noopTest,
-  lheading: /^((?:(?!^bull ).|\n(?!\n|bull ))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
-  // regex template, placeholders will be replaced according to different paragraph
-  // interruption rules of commonmark and the original markdown spec:
-  _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,
-  text: /^[^\n]+/
+/**
+ * Block-Level Grammar
+ */
+// Not all rules are defined in the object literal
+// @ts-expect-error
+const block = {
+    newline: /^(?: *(?:\n|$))+/,
+    code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
+    fences: /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,
+    hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,
+    heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,
+    blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
+    list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/,
+    html: '^ {0,3}(?:' // optional indentation
+        + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
+        + '|comment[^\\n]*(\\n+|$)' // (2)
+        + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3)
+        + '|<![A-Z][\\s\\S]*?(?:>\\n*|$)' // (4)
+        + '|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)' // (5)
+        + '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6)
+        + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag
+        + '|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag
+        + ')',
+    def: /^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,
+    table: noopTest,
+    lheading: /^((?:(?!^bull ).|\n(?!\n|bull ))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
+    // regex template, placeholders will be replaced according to different paragraph
+    // interruption rules of commonmark and the original markdown spec:
+    _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,
+    text: /^[^\n]+/
 };
 block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
 block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;
-block.def = edit(block.def).replace("label", block._label).replace("title", block._title).getRegex();
+block.def = edit(block.def)
+    .replace('label', block._label)
+    .replace('title', block._title)
+    .getRegex();
 block.bullet = /(?:[*+-]|\d{1,9}[.)])/;
-block.listItemStart = edit(/^( *)(bull) */).replace("bull", block.bullet).getRegex();
-block.list = edit(block.list).replace(/bull/g, block.bullet).replace("hr", "\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def", "\\n+(?=" + block.def.source + ")").getRegex();
-block._tag = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul";
+block.listItemStart = edit(/^( *)(bull) */)
+    .replace('bull', block.bullet)
+    .getRegex();
+block.list = edit(block.list)
+    .replace(/bull/g, block.bullet)
+    .replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))')
+    .replace('def', '\\n+(?=' + block.def.source + ')')
+    .getRegex();
+block._tag = 'address|article|aside|base|basefont|blockquote|body|caption'
+    + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'
+    + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'
+    + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'
+    + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr'
+    + '|track|ul';
 block._comment = /<!--(?!-?>)[\s\S]*?(?:-->|$)/;
-block.html = edit(block.html, "i").replace("comment", block._comment).replace("tag", block._tag).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
-block.lheading = edit(block.lheading).replace(/bull/g, block.bullet).getRegex();
-block.paragraph = edit(block._paragraph).replace("hr", block.hr).replace("heading", " {0,3}#{1,6} ").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", block._tag).getRegex();
-block.blockquote = edit(block.blockquote).replace("paragraph", block.paragraph).getRegex();
+block.html = edit(block.html, 'i')
+    .replace('comment', block._comment)
+    .replace('tag', block._tag)
+    .replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/)
+    .getRegex();
+block.lheading = edit(block.lheading)
+    .replace(/bull/g, block.bullet) // lists can interrupt
+    .getRegex();
+block.paragraph = edit(block._paragraph)
+    .replace('hr', block.hr)
+    .replace('heading', ' {0,3}#{1,6} ')
+    .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
+    .replace('|table', '')
+    .replace('blockquote', ' {0,3}>')
+    .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
+    .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
+    .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
+    .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
+    .getRegex();
+block.blockquote = edit(block.blockquote)
+    .replace('paragraph', block.paragraph)
+    .getRegex();
+/**
+ * Normal Block Grammar
+ */
 block.normal = { ...block };
+/**
+ * GFM Block Grammar
+ */
 block.gfm = {
-  ...block.normal,
-  table: "^ *([^\\n ].*\\|.*)\\n {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)"
-  // Cells
+    ...block.normal,
+    table: '^ *([^\\n ].*\\|.*)\\n' // Header
+        + ' {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?' // Align
+        + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells
 };
-block.gfm.table = edit(block.gfm.table).replace("hr", block.hr).replace("heading", " {0,3}#{1,6} ").replace("blockquote", " {0,3}>").replace("code", " {4}[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", block._tag).getRegex();
-block.gfm.paragraph = edit(block._paragraph).replace("hr", block.hr).replace("heading", " {0,3}#{1,6} ").replace("|lheading", "").replace("table", block.gfm.table).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", block._tag).getRegex();
+block.gfm.table = edit(block.gfm.table)
+    .replace('hr', block.hr)
+    .replace('heading', ' {0,3}#{1,6} ')
+    .replace('blockquote', ' {0,3}>')
+    .replace('code', ' {4}[^\\n]')
+    .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
+    .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
+    .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
+    .replace('tag', block._tag) // tables can be interrupted by type (6) html blocks
+    .getRegex();
+block.gfm.paragraph = edit(block._paragraph)
+    .replace('hr', block.hr)
+    .replace('heading', ' {0,3}#{1,6} ')
+    .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
+    .replace('table', block.gfm.table) // interrupt paragraphs with table
+    .replace('blockquote', ' {0,3}>')
+    .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
+    .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
+    .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
+    .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
+    .getRegex();
+/**
+ * Pedantic grammar (original John Gruber's loose markdown specification)
+ */
 block.pedantic = {
-  ...block.normal,
-  html: edit(
-    `^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`
-  ).replace("comment", block._comment).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),
-  def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
-  heading: /^(#{1,6})(.*)(?:\n+|$)/,
-  fences: noopTest,
-  // fences not supported
-  lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
-  paragraph: edit(block.normal._paragraph).replace("hr", block.hr).replace("heading", " *#{1,6} *[^\n]").replace("lheading", block.lheading).replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").getRegex()
+    ...block.normal,
+    html: edit('^ *(?:comment *(?:\\n|\\s*$)'
+        + '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag
+        + '|<tag(?:"[^"]*"|\'[^\']*\'|\\s[^\'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))')
+        .replace('comment', block._comment)
+        .replace(/tag/g, '(?!(?:'
+        + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'
+        + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'
+        + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b')
+        .getRegex(),
+    def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
+    heading: /^(#{1,6})(.*)(?:\n+|$)/,
+    fences: noopTest,
+    lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
+    paragraph: edit(block.normal._paragraph)
+        .replace('hr', block.hr)
+        .replace('heading', ' *#{1,6} *[^\n]')
+        .replace('lheading', block.lheading)
+        .replace('blockquote', ' {0,3}>')
+        .replace('|fences', '')
+        .replace('|list', '')
+        .replace('|html', '')
+        .getRegex()
 };
-var inline = {
-  escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
-  autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
-  url: noopTest,
-  tag: "^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>",
-  // CDATA section
-  link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,
-  reflink: /^!?\[(label)\]\[(ref)\]/,
-  nolink: /^!?\[(ref)\](?:\[\])?/,
-  reflinkSearch: "reflink|nolink(?!\\()",
-  emStrong: {
-    lDelim: /^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/,
-    //         (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left.  (5) and (6) can be either Left or Right.
-    //         | Skip orphan inside strong      | Consume to delim | (1) #***              | (2) a***#, a***                    | (3) #***a, ***a                  | (4) ***#                 | (5) #***#                         | (6) a***a
-    rDelimAst: /^[^_*]*?__[^_*]*?\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\*)[punct](\*+)(?=[\s]|$)|[^punct\s](\*+)(?!\*)(?=[punct\s]|$)|(?!\*)[punct\s](\*+)(?=[^punct\s])|[\s](\*+)(?!\*)(?=[punct])|(?!\*)[punct](\*+)(?!\*)(?=[punct])|[^punct\s](\*+)(?=[^punct\s])/,
-    rDelimUnd: /^[^_*]*?\*\*[^_*]*?_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\s]|$)|[^punct\s](_+)(?!_)(?=[punct\s]|$)|(?!_)[punct\s](_+)(?=[^punct\s])|[\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])/
-    // ^- Not allowed for _
-  },
-  code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
-  br: /^( {2,}|\\)\n(?!\s*$)/,
-  del: noopTest,
-  text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,
-  punctuation: /^((?![*_])[\spunctuation])/
+/**
+ * Inline-Level Grammar
+ */
+// Not all rules are defined in the object literal
+// @ts-expect-error
+const inline = {
+    escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
+    autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
+    url: noopTest,
+    tag: '^comment'
+        + '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
+        + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
+        + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
+        + '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
+        + '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>',
+    link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,
+    reflink: /^!?\[(label)\]\[(ref)\]/,
+    nolink: /^!?\[(ref)\](?:\[\])?/,
+    reflinkSearch: 'reflink|nolink(?!\\()',
+    emStrong: {
+        lDelim: /^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/,
+        //         (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left.  (5) and (6) can be either Left or Right.
+        //         | Skip orphan inside strong      | Consume to delim | (1) #***              | (2) a***#, a***                    | (3) #***a, ***a                  | (4) ***#                 | (5) #***#                         | (6) a***a
+        rDelimAst: /^[^_*]*?__[^_*]*?\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\*)[punct](\*+)(?=[\s]|$)|[^punct\s](\*+)(?!\*)(?=[punct\s]|$)|(?!\*)[punct\s](\*+)(?=[^punct\s])|[\s](\*+)(?!\*)(?=[punct])|(?!\*)[punct](\*+)(?!\*)(?=[punct])|[^punct\s](\*+)(?=[^punct\s])/,
+        rDelimUnd: /^[^_*]*?\*\*[^_*]*?_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\s]|$)|[^punct\s](_+)(?!_)(?=[punct\s]|$)|(?!_)[punct\s](_+)(?=[^punct\s])|[\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])/ // ^- Not allowed for _
+    },
+    code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
+    br: /^( {2,}|\\)\n(?!\s*$)/,
+    del: noopTest,
+    text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,
+    punctuation: /^((?![*_])[\spunctuation])/
 };
-inline._punctuation = "\\p{P}$+<=>`^|~";
-inline.punctuation = edit(inline.punctuation, "u").replace(/punctuation/g, inline._punctuation).getRegex();
+// list of unicode punctuation marks, plus any missing characters from CommonMark spec
+inline._punctuation = '\\p{P}$+<=>`^|~';
+inline.punctuation = edit(inline.punctuation, 'u').replace(/punctuation/g, inline._punctuation).getRegex();
+// sequences em should skip over [title](link), `code`, <html>
 inline.blockSkip = /\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g;
 inline.anyPunctuation = /\\[punct]/g;
 inline._escapes = /\\([punct])/g;
-inline._comment = edit(block._comment).replace("(?:-->|$)", "-->").getRegex();
-inline.emStrong.lDelim = edit(inline.emStrong.lDelim, "u").replace(/punct/g, inline._punctuation).getRegex();
-inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, "gu").replace(/punct/g, inline._punctuation).getRegex();
-inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, "gu").replace(/punct/g, inline._punctuation).getRegex();
-inline.anyPunctuation = edit(inline.anyPunctuation, "gu").replace(/punct/g, inline._punctuation).getRegex();
-inline._escapes = edit(inline._escapes, "gu").replace(/punct/g, inline._punctuation).getRegex();
+inline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex();
+inline.emStrong.lDelim = edit(inline.emStrong.lDelim, 'u')
+    .replace(/punct/g, inline._punctuation)
+    .getRegex();
+inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'gu')
+    .replace(/punct/g, inline._punctuation)
+    .getRegex();
+inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, 'gu')
+    .replace(/punct/g, inline._punctuation)
+    .getRegex();
+inline.anyPunctuation = edit(inline.anyPunctuation, 'gu')
+    .replace(/punct/g, inline._punctuation)
+    .getRegex();
+inline._escapes = edit(inline._escapes, 'gu')
+    .replace(/punct/g, inline._punctuation)
+    .getRegex();
 inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;
 inline._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])?)+(?![-_])/;
-inline.autolink = edit(inline.autolink).replace("scheme", inline._scheme).replace("email", inline._email).getRegex();
+inline.autolink = edit(inline.autolink)
+    .replace('scheme', inline._scheme)
+    .replace('email', inline._email)
+    .getRegex();
 inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;
-inline.tag = edit(inline.tag).replace("comment", inline._comment).replace("attribute", inline._attribute).getRegex();
+inline.tag = edit(inline.tag)
+    .replace('comment', inline._comment)
+    .replace('attribute', inline._attribute)
+    .getRegex();
 inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
 inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/;
 inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/;
-inline.link = edit(inline.link).replace("label", inline._label).replace("href", inline._href).replace("title", inline._title).getRegex();
-inline.reflink = edit(inline.reflink).replace("label", inline._label).replace("ref", block._label).getRegex();
-inline.nolink = edit(inline.nolink).replace("ref", block._label).getRegex();
-inline.reflinkSearch = edit(inline.reflinkSearch, "g").replace("reflink", inline.reflink).replace("nolink", inline.nolink).getRegex();
+inline.link = edit(inline.link)
+    .replace('label', inline._label)
+    .replace('href', inline._href)
+    .replace('title', inline._title)
+    .getRegex();
+inline.reflink = edit(inline.reflink)
+    .replace('label', inline._label)
+    .replace('ref', block._label)
+    .getRegex();
+inline.nolink = edit(inline.nolink)
+    .replace('ref', block._label)
+    .getRegex();
+inline.reflinkSearch = edit(inline.reflinkSearch, 'g')
+    .replace('reflink', inline.reflink)
+    .replace('nolink', inline.nolink)
+    .getRegex();
+/**
+ * Normal Inline Grammar
+ */
 inline.normal = { ...inline };
+/**
+ * Pedantic Inline Grammar
+ */
 inline.pedantic = {
-  ...inline.normal,
-  strong: {
-    start: /^__|\*\*/,
-    middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
-    endAst: /\*\*(?!\*)/g,
-    endUnd: /__(?!_)/g
-  },
-  em: {
-    start: /^_|\*/,
-    middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,
-    endAst: /\*(?!\*)/g,
-    endUnd: /_(?!_)/g
-  },
-  link: edit(/^!?\[(label)\]\((.*?)\)/).replace("label", inline._label).getRegex(),
-  reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", inline._label).getRegex()
+    ...inline.normal,
+    strong: {
+        start: /^__|\*\*/,
+        middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
+        endAst: /\*\*(?!\*)/g,
+        endUnd: /__(?!_)/g
+    },
+    em: {
+        start: /^_|\*/,
+        middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,
+        endAst: /\*(?!\*)/g,
+        endUnd: /_(?!_)/g
+    },
+    link: edit(/^!?\[(label)\]\((.*?)\)/)
+        .replace('label', inline._label)
+        .getRegex(),
+    reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/)
+        .replace('label', inline._label)
+        .getRegex()
 };
+/**
+ * GFM Inline Grammar
+ */
 inline.gfm = {
-  ...inline.normal,
-  escape: edit(inline.escape).replace("])", "~|])").getRegex(),
-  _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,
-  url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
-  _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
-  del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
-  text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
+    ...inline.normal,
+    escape: edit(inline.escape).replace('])', '~|])').getRegex(),
+    _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,
+    url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
+    _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
+    del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
+    text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
 };
-inline.gfm.url = edit(inline.gfm.url, "i").replace("email", inline.gfm._extended_email).getRegex();
+inline.gfm.url = edit(inline.gfm.url, 'i')
+    .replace('email', inline.gfm._extended_email)
+    .getRegex();
+/**
+ * GFM + Line Breaks Inline Grammar
+ */
 inline.breaks = {
-  ...inline.gfm,
-  br: edit(inline.br).replace("{2,}", "*").getRegex(),
-  text: edit(inline.gfm.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex()
+    ...inline.gfm,
+    br: edit(inline.br).replace('{2,}', '*').getRegex(),
+    text: edit(inline.gfm.text)
+        .replace('\\b_', '\\b_| {2,}\\n')
+        .replace(/\{2,\}/g, '*')
+        .getRegex()
 };
 
-// src/Lexer.ts
+/**
+ * smartypants text replacement
+ */
 function smartypants(text) {
-  return text.replace(/---/g, "\u2014").replace(/--/g, "\u2013").replace(/(^|[-\u2014/(\[{"\s])'/g, "$1\u2018").replace(/'/g, "\u2019").replace(/(^|[-\u2014/(\[{\u2018\s])"/g, "$1\u201C").replace(/"/g, "\u201D").replace(/\.{3}/g, "\u2026");
+    return text
+        // em-dashes
+        .replace(/---/g, '\u2014')
+        // en-dashes
+        .replace(/--/g, '\u2013')
+        // opening singles
+        .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
+        // closing singles & apostrophes
+        .replace(/'/g, '\u2019')
+        // opening doubles
+        .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
+        // closing doubles
+        .replace(/"/g, '\u201d')
+        // ellipses
+        .replace(/\.{3}/g, '\u2026');
 }
+/**
+ * mangle email addresses
+ */
 function mangle(text) {
-  let out = "", i, ch;
-  const l = text.length;
-  for (i = 0; i < l; i++) {
-    ch = text.charCodeAt(i);
-    if (Math.random() > 0.5) {
-      ch = "x" + ch.toString(16);
-    }
-    out += "&#" + ch + ";";
-  }
-  return out;
-}
-var _Lexer2 = class __Lexer {
-  constructor(options2) {
-    this.tokens = [];
-    this.tokens.links = /* @__PURE__ */ Object.create(null);
-    this.options = options2 || _defaults;
-    this.options.tokenizer = this.options.tokenizer || new _Tokenizer();
-    this.tokenizer = this.options.tokenizer;
-    this.tokenizer.options = this.options;
-    this.tokenizer.lexer = this;
-    this.inlineQueue = [];
-    this.state = {
-      inLink: false,
-      inRawBlock: false,
-      top: true
-    };
-    const rules = {
-      block: block.normal,
-      inline: inline.normal
-    };
-    if (this.options.pedantic) {
-      rules.block = block.pedantic;
-      rules.inline = inline.pedantic;
-    } else if (this.options.gfm) {
-      rules.block = block.gfm;
-      if (this.options.breaks) {
-        rules.inline = inline.breaks;
-      } else {
-        rules.inline = inline.gfm;
-      }
-    }
-    this.tokenizer.rules = rules;
-  }
-  /**
-   * Expose Rules
-   */
-  static get rules() {
-    return {
-      block,
-      inline
-    };
-  }
-  /**
-   * Static Lex Method
-   */
-  static lex(src, options2) {
-    const lexer2 = new __Lexer(options2);
-    return lexer2.lex(src);
-  }
-  /**
-   * Static Lex Inline Method
-   */
-  static lexInline(src, options2) {
-    const lexer2 = new __Lexer(options2);
-    return lexer2.inlineTokens(src);
-  }
-  /**
-   * Preprocessing
-   */
-  lex(src) {
-    src = src.replace(/\r\n|\r/g, "\n");
-    this.blockTokens(src, this.tokens);
-    let next;
-    while (next = this.inlineQueue.shift()) {
-      this.inlineTokens(next.src, next.tokens);
-    }
-    return this.tokens;
-  }
-  blockTokens(src, tokens = []) {
-    if (this.options.pedantic) {
-      src = src.replace(/\t/g, "    ").replace(/^ +$/gm, "");
-    } else {
-      src = src.replace(/^( *)(\t+)/gm, (_, leading, tabs) => {
-        return leading + "    ".repeat(tabs.length);
-      });
-    }
-    let token, lastToken, cutSrc, lastParagraphClipped;
-    while (src) {
-      if (this.options.extensions && this.options.extensions.block && this.options.extensions.block.some((extTokenizer) => {
-        if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
-          src = src.substring(token.raw.length);
-          tokens.push(token);
-          return true;
-        }
-        return false;
-      })) {
-        continue;
-      }
-      if (token = this.tokenizer.space(src)) {
-        src = src.substring(token.raw.length);
-        if (token.raw.length === 1 && tokens.length > 0) {
-          tokens[tokens.length - 1].raw += "\n";
-        } else {
-          tokens.push(token);
-        }
-        continue;
-      }
-      if (token = this.tokenizer.code(src)) {
-        src = src.substring(token.raw.length);
-        lastToken = tokens[tokens.length - 1];
-        if (lastToken && (lastToken.type === "paragraph" || lastToken.type === "text")) {
-          lastToken.raw += "\n" + token.raw;
-          lastToken.text += "\n" + token.text;
-          this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
-        } else {
-          tokens.push(token);
-        }
-        continue;
-      }
-      if (token = this.tokenizer.fences(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.heading(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.hr(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.blockquote(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.list(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.html(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.def(src)) {
-        src = src.substring(token.raw.length);
-        lastToken = tokens[tokens.length - 1];
-        if (lastToken && (lastToken.type === "paragraph" || lastToken.type === "text")) {
-          lastToken.raw += "\n" + token.raw;
-          lastToken.text += "\n" + token.raw;
-          this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
-        } else if (!this.tokens.links[token.tag]) {
-          this.tokens.links[token.tag] = {
-            href: token.href,
-            title: token.title
-          };
-        }
-        continue;
-      }
-      if (token = this.tokenizer.table(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.lheading(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      cutSrc = src;
-      if (this.options.extensions && this.options.extensions.startBlock) {
-        let startIndex = Infinity;
-        const tempSrc = src.slice(1);
-        let tempStart;
-        this.options.extensions.startBlock.forEach((getStartIndex) => {
-          tempStart = getStartIndex.call({ lexer: this }, tempSrc);
-          if (typeof tempStart === "number" && tempStart >= 0) {
-            startIndex = Math.min(startIndex, tempStart);
-          }
-        });
-        if (startIndex < Infinity && startIndex >= 0) {
-          cutSrc = src.substring(0, startIndex + 1);
-        }
-      }
-      if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
-        lastToken = tokens[tokens.length - 1];
-        if (lastParagraphClipped && lastToken.type === "paragraph") {
-          lastToken.raw += "\n" + token.raw;
-          lastToken.text += "\n" + token.text;
-          this.inlineQueue.pop();
-          this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
-        } else {
-          tokens.push(token);
-        }
-        lastParagraphClipped = cutSrc.length !== src.length;
-        src = src.substring(token.raw.length);
-        continue;
-      }
-      if (token = this.tokenizer.text(src)) {
-        src = src.substring(token.raw.length);
-        lastToken = tokens[tokens.length - 1];
-        if (lastToken && lastToken.type === "text") {
-          lastToken.raw += "\n" + token.raw;
-          lastToken.text += "\n" + token.text;
-          this.inlineQueue.pop();
-          this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
-        } else {
-          tokens.push(token);
-        }
-        continue;
-      }
-      if (src) {
-        const errMsg = "Infinite loop on byte: " + src.charCodeAt(0);
-        if (this.options.silent) {
-          console.error(errMsg);
-          break;
-        } else {
-          throw new Error(errMsg);
-        }
-      }
-    }
-    this.state.top = true;
-    return tokens;
-  }
-  inline(src, tokens = []) {
-    this.inlineQueue.push({ src, tokens });
-    return tokens;
-  }
-  /**
-   * Lexing/Compiling
-   */
-  inlineTokens(src, tokens = []) {
-    let token, lastToken, cutSrc;
-    let maskedSrc = src;
-    let match;
-    let keepPrevChar, prevChar;
-    if (this.tokens.links) {
-      const links = Object.keys(this.tokens.links);
-      if (links.length > 0) {
-        while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
-          if (links.includes(match[0].slice(match[0].lastIndexOf("[") + 1, -1))) {
-            maskedSrc = maskedSrc.slice(0, match.index) + "[" + "a".repeat(match[0].length - 2) + "]" + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
-          }
-        }
-      }
-    }
-    while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
-      maskedSrc = maskedSrc.slice(0, match.index) + "[" + "a".repeat(match[0].length - 2) + "]" + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
-    }
-    while ((match = this.tokenizer.rules.inline.anyPunctuation.exec(maskedSrc)) != null) {
-      maskedSrc = maskedSrc.slice(0, match.index) + "++" + maskedSrc.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
-    }
-    while (src) {
-      if (!keepPrevChar) {
-        prevChar = "";
-      }
-      keepPrevChar = false;
-      if (this.options.extensions && this.options.extensions.inline && this.options.extensions.inline.some((extTokenizer) => {
-        if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
-          src = src.substring(token.raw.length);
-          tokens.push(token);
-          return true;
-        }
-        return false;
-      })) {
-        continue;
-      }
-      if (token = this.tokenizer.escape(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.tag(src)) {
-        src = src.substring(token.raw.length);
-        lastToken = tokens[tokens.length - 1];
-        if (lastToken && token.type === "text" && lastToken.type === "text") {
-          lastToken.raw += token.raw;
-          lastToken.text += token.text;
-        } else {
-          tokens.push(token);
-        }
-        continue;
-      }
-      if (token = this.tokenizer.link(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.reflink(src, this.tokens.links)) {
-        src = src.substring(token.raw.length);
-        lastToken = tokens[tokens.length - 1];
-        if (lastToken && token.type === "text" && lastToken.type === "text") {
-          lastToken.raw += token.raw;
-          lastToken.text += token.text;
-        } else {
-          tokens.push(token);
-        }
-        continue;
-      }
-      if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.codespan(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.br(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.del(src)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (token = this.tokenizer.autolink(src, mangle)) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) {
-        src = src.substring(token.raw.length);
-        tokens.push(token);
-        continue;
-      }
-      cutSrc = src;
-      if (this.options.extensions && this.options.extensions.startInline) {
-        let startIndex = Infinity;
-        const tempSrc = src.slice(1);
-        let tempStart;
-        this.options.extensions.startInline.forEach((getStartIndex) => {
-          tempStart = getStartIndex.call({ lexer: this }, tempSrc);
-          if (typeof tempStart === "number" && tempStart >= 0) {
-            startIndex = Math.min(startIndex, tempStart);
-          }
-        });
-        if (startIndex < Infinity && startIndex >= 0) {
-          cutSrc = src.substring(0, startIndex + 1);
-        }
-      }
-      if (token = this.tokenizer.inlineText(cutSrc, smartypants)) {
-        src = src.substring(token.raw.length);
-        if (token.raw.slice(-1) !== "_") {
-          prevChar = token.raw.slice(-1);
-        }
-        keepPrevChar = true;
-        lastToken = tokens[tokens.length - 1];
-        if (lastToken && lastToken.type === "text") {
-          lastToken.raw += token.raw;
-          lastToken.text += token.text;
-        } else {
-          tokens.push(token);
-        }
-        continue;
-      }
-      if (src) {
-        const errMsg = "Infinite loop on byte: " + src.charCodeAt(0);
-        if (this.options.silent) {
-          console.error(errMsg);
-          break;
-        } else {
-          throw new Error(errMsg);
-        }
-      }
-    }
-    return tokens;
-  }
-};
-
-// src/Renderer.ts
-var _Renderer = class {
-  constructor(options2) {
-    this.options = options2 || _defaults;
-  }
-  code(code, infostring, escaped) {
-    const lang = (infostring || "").match(/\S*/)[0];
-    if (this.options.highlight) {
-      const out = this.options.highlight(code, lang);
-      if (out != null && out !== code) {
-        escaped = true;
-        code = out;
-      }
-    }
-    code = code.replace(/\n$/, "") + "\n";
-    if (!lang) {
-      return "<pre><code>" + (escaped ? code : escape(code, true)) + "</code></pre>\n";
-    }
-    return '<pre><code class="' + this.options.langPrefix + escape(lang) + '">' + (escaped ? code : escape(code, true)) + "</code></pre>\n";
-  }
-  blockquote(quote) {
-    return `<blockquote>
-${quote}</blockquote>
-`;
-  }
-  html(html, block2) {
-    return html;
-  }
-  heading(text, level, raw, slugger) {
-    if (this.options.headerIds) {
-      const id = this.options.headerPrefix + slugger.slug(raw);
-      return `<h${level} id="${id}">${text}</h${level}>
-`;
-    }
-    return `<h${level}>${text}</h${level}>
-`;
-  }
-  hr() {
-    return this.options.xhtml ? "<hr/>\n" : "<hr>\n";
-  }
-  list(body, ordered, start) {
-    const type = ordered ? "ol" : "ul", startatt = ordered && start !== 1 ? ' start="' + start + '"' : "";
-    return "<" + type + startatt + ">\n" + body + "</" + type + ">\n";
-  }
-  listitem(text, task, checked) {
-    return `<li>${text}</li>
-`;
-  }
-  checkbox(checked) {
-    return "<input " + (checked ? 'checked="" ' : "") + 'disabled="" type="checkbox"' + (this.options.xhtml ? " /" : "") + "> ";
-  }
-  paragraph(text) {
-    return `<p>${text}</p>
-`;
-  }
-  table(header, body) {
-    if (body)
-      body = `<tbody>${body}</tbody>`;
-    return "<table>\n<thead>\n" + header + "</thead>\n" + body + "</table>\n";
-  }
-  tablerow(content) {
-    return `<tr>
-${content}</tr>
-`;
-  }
-  tablecell(content, flags) {
-    const type = flags.header ? "th" : "td";
-    const tag = flags.align ? `<${type} align="${flags.align}">` : `<${type}>`;
-    return tag + content + `</${type}>
-`;
-  }
-  /**
-   * span level renderer
-   */
-  strong(text) {
-    return `<strong>${text}</strong>`;
-  }
-  em(text) {
-    return `<em>${text}</em>`;
-  }
-  codespan(text) {
-    return `<code>${text}</code>`;
-  }
-  br() {
-    return this.options.xhtml ? "<br/>" : "<br>";
-  }
-  del(text) {
-    return `<del>${text}</del>`;
-  }
-  link(href, title, text) {
-    href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
-    if (href === null) {
-      return text;
-    }
-    let out = '<a href="' + href + '"';
-    if (title) {
-      out += ' title="' + title + '"';
-    }
-    out += ">" + text + "</a>";
+    let out = '', i, ch;
+    const l = text.length;
+    for (i = 0; i < l; i++) {
+        ch = text.charCodeAt(i);
+        if (Math.random() > 0.5) {
+            ch = 'x' + ch.toString(16);
+        }
+        out += '&#' + ch + ';';
+    }
     return out;
-  }
-  image(href, title, text) {
-    href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
-    if (href === null) {
-      return text;
+}
+/**
+ * Block Lexer
+ */
+class _Lexer {
+    tokens;
+    options;
+    state;
+    tokenizer;
+    inlineQueue;
+    constructor(options) {
+        // TokenList cannot be created in one go
+        // @ts-expect-error
+        this.tokens = [];
+        this.tokens.links = Object.create(null);
+        this.options = options || _defaults;
+        this.options.tokenizer = this.options.tokenizer || new _Tokenizer();
+        this.tokenizer = this.options.tokenizer;
+        this.tokenizer.options = this.options;
+        this.tokenizer.lexer = this;
+        this.inlineQueue = [];
+        this.state = {
+            inLink: false,
+            inRawBlock: false,
+            top: true
+        };
+        const rules = {
+            block: block.normal,
+            inline: inline.normal
+        };
+        if (this.options.pedantic) {
+            rules.block = block.pedantic;
+            rules.inline = inline.pedantic;
+        }
+        else if (this.options.gfm) {
+            rules.block = block.gfm;
+            if (this.options.breaks) {
+                rules.inline = inline.breaks;
+            }
+            else {
+                rules.inline = inline.gfm;
+            }
+        }
+        this.tokenizer.rules = rules;
     }
-    let out = `<img src="${href}" alt="${text}"`;
-    if (title) {
-      out += ` title="${title}"`;
+    /**
+     * Expose Rules
+     */
+    static get rules() {
+        return {
+            block,
+            inline
+        };
     }
-    out += this.options.xhtml ? "/>" : ">";
-    return out;
-  }
-  text(text) {
-    return text;
-  }
-};
-
-// src/TextRenderer.ts
-var _TextRenderer = class {
-  // no need for block level renderers
-  strong(text) {
-    return text;
-  }
-  em(text) {
-    return text;
-  }
-  codespan(text) {
-    return text;
-  }
-  del(text) {
-    return text;
-  }
-  html(text) {
-    return text;
-  }
-  text(text) {
-    return text;
-  }
-  link(href, title, text) {
-    return "" + text;
-  }
-  image(href, title, text) {
-    return "" + text;
-  }
-  br() {
-    return "";
-  }
-};
+    /**
+     * Static Lex Method
+     */
+    static lex(src, options) {
+        const lexer = new _Lexer(options);
+        return lexer.lex(src);
+    }
+    /**
+     * Static Lex Inline Method
+     */
+    static lexInline(src, options) {
+        const lexer = new _Lexer(options);
+        return lexer.inlineTokens(src);
+    }
+    /**
+     * Preprocessing
+     */
+    lex(src) {
+        src = src
+            .replace(/\r\n|\r/g, '\n');
+        this.blockTokens(src, this.tokens);
+        let next;
+        while (next = this.inlineQueue.shift()) {
+            this.inlineTokens(next.src, next.tokens);
+        }
+        return this.tokens;
+    }
+    blockTokens(src, tokens = []) {
+        if (this.options.pedantic) {
+            src = src.replace(/\t/g, '    ').replace(/^ +$/gm, '');
+        }
+        else {
+            src = src.replace(/^( *)(\t+)/gm, (_, leading, tabs) => {
+                return leading + '    '.repeat(tabs.length);
+            });
+        }
+        let token, lastToken, cutSrc, lastParagraphClipped;
+        while (src) {
+            if (this.options.extensions
+                && this.options.extensions.block
+                && this.options.extensions.block.some((extTokenizer) => {
+                    if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
+                        src = src.substring(token.raw.length);
+                        tokens.push(token);
+                        return true;
+                    }
+                    return false;
+                })) {
+                continue;
+            }
+            // newline
+            if (token = this.tokenizer.space(src)) {
+                src = src.substring(token.raw.length);
+                if (token.raw.length === 1 && tokens.length > 0) {
+                    // if there's a single \n as a spacer, it's terminating the last line,
+                    // so move it there so that we don't get unecessary paragraph tags
+                    tokens[tokens.length - 1].raw += '\n';
+                }
+                else {
+                    tokens.push(token);
+                }
+                continue;
+            }
+            // code
+            if (token = this.tokenizer.code(src)) {
+                src = src.substring(token.raw.length);
+                lastToken = tokens[tokens.length - 1];
+                // An indented code block cannot interrupt a paragraph.
+                if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
+                    lastToken.raw += '\n' + token.raw;
+                    lastToken.text += '\n' + token.text;
+                    this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
+                }
+                else {
+                    tokens.push(token);
+                }
+                continue;
+            }
+            // fences
+            if (token = this.tokenizer.fences(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // heading
+            if (token = this.tokenizer.heading(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // hr
+            if (token = this.tokenizer.hr(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // blockquote
+            if (token = this.tokenizer.blockquote(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // list
+            if (token = this.tokenizer.list(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // html
+            if (token = this.tokenizer.html(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // def
+            if (token = this.tokenizer.def(src)) {
+                src = src.substring(token.raw.length);
+                lastToken = tokens[tokens.length - 1];
+                if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
+                    lastToken.raw += '\n' + token.raw;
+                    lastToken.text += '\n' + token.raw;
+                    this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
+                }
+                else if (!this.tokens.links[token.tag]) {
+                    this.tokens.links[token.tag] = {
+                        href: token.href,
+                        title: token.title
+                    };
+                }
+                continue;
+            }
+            // table (gfm)
+            if (token = this.tokenizer.table(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // lheading
+            if (token = this.tokenizer.lheading(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // top-level paragraph
+            // prevent paragraph consuming extensions by clipping 'src' to extension start
+            cutSrc = src;
+            if (this.options.extensions && this.options.extensions.startBlock) {
+                let startIndex = Infinity;
+                const tempSrc = src.slice(1);
+                let tempStart;
+                this.options.extensions.startBlock.forEach((getStartIndex) => {
+                    tempStart = getStartIndex.call({ lexer: this }, tempSrc);
+                    if (typeof tempStart === 'number' && tempStart >= 0) {
+                        startIndex = Math.min(startIndex, tempStart);
+                    }
+                });
+                if (startIndex < Infinity && startIndex >= 0) {
+                    cutSrc = src.substring(0, startIndex + 1);
+                }
+            }
+            if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
+                lastToken = tokens[tokens.length - 1];
+                if (lastParagraphClipped && lastToken.type === 'paragraph') {
+                    lastToken.raw += '\n' + token.raw;
+                    lastToken.text += '\n' + token.text;
+                    this.inlineQueue.pop();
+                    this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
+                }
+                else {
+                    tokens.push(token);
+                }
+                lastParagraphClipped = (cutSrc.length !== src.length);
+                src = src.substring(token.raw.length);
+                continue;
+            }
+            // text
+            if (token = this.tokenizer.text(src)) {
+                src = src.substring(token.raw.length);
+                lastToken = tokens[tokens.length - 1];
+                if (lastToken && lastToken.type === 'text') {
+                    lastToken.raw += '\n' + token.raw;
+                    lastToken.text += '\n' + token.text;
+                    this.inlineQueue.pop();
+                    this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
+                }
+                else {
+                    tokens.push(token);
+                }
+                continue;
+            }
+            if (src) {
+                const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
+                if (this.options.silent) {
+                    console.error(errMsg);
+                    break;
+                }
+                else {
+                    throw new Error(errMsg);
+                }
+            }
+        }
+        this.state.top = true;
+        return tokens;
+    }
+    inline(src, tokens = []) {
+        this.inlineQueue.push({ src, tokens });
+        return tokens;
+    }
+    /**
+     * Lexing/Compiling
+     */
+    inlineTokens(src, tokens = []) {
+        let token, lastToken, cutSrc;
+        // String with links masked to avoid interference with em and strong
+        let maskedSrc = src;
+        let match;
+        let keepPrevChar, prevChar;
+        // Mask out reflinks
+        if (this.tokens.links) {
+            const links = Object.keys(this.tokens.links);
+            if (links.length > 0) {
+                while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
+                    if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {
+                        maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
+                    }
+                }
+            }
+        }
+        // Mask out other blocks
+        while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
+            maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
+        }
+        // Mask out escaped characters
+        while ((match = this.tokenizer.rules.inline.anyPunctuation.exec(maskedSrc)) != null) {
+            maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
+        }
+        while (src) {
+            if (!keepPrevChar) {
+                prevChar = '';
+            }
+            keepPrevChar = false;
+            // extensions
+            if (this.options.extensions
+                && this.options.extensions.inline
+                && this.options.extensions.inline.some((extTokenizer) => {
+                    if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
+                        src = src.substring(token.raw.length);
+                        tokens.push(token);
+                        return true;
+                    }
+                    return false;
+                })) {
+                continue;
+            }
+            // escape
+            if (token = this.tokenizer.escape(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // tag
+            if (token = this.tokenizer.tag(src)) {
+                src = src.substring(token.raw.length);
+                lastToken = tokens[tokens.length - 1];
+                if (lastToken && token.type === 'text' && lastToken.type === 'text') {
+                    lastToken.raw += token.raw;
+                    lastToken.text += token.text;
+                }
+                else {
+                    tokens.push(token);
+                }
+                continue;
+            }
+            // link
+            if (token = this.tokenizer.link(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // reflink, nolink
+            if (token = this.tokenizer.reflink(src, this.tokens.links)) {
+                src = src.substring(token.raw.length);
+                lastToken = tokens[tokens.length - 1];
+                if (lastToken && token.type === 'text' && lastToken.type === 'text') {
+                    lastToken.raw += token.raw;
+                    lastToken.text += token.text;
+                }
+                else {
+                    tokens.push(token);
+                }
+                continue;
+            }
+            // em & strong
+            if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // code
+            if (token = this.tokenizer.codespan(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // br
+            if (token = this.tokenizer.br(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // del (gfm)
+            if (token = this.tokenizer.del(src)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // autolink
+            if (token = this.tokenizer.autolink(src, mangle)) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // url (gfm)
+            if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) {
+                src = src.substring(token.raw.length);
+                tokens.push(token);
+                continue;
+            }
+            // text
+            // prevent inlineText consuming extensions by clipping 'src' to extension start
+            cutSrc = src;
+            if (this.options.extensions && this.options.extensions.startInline) {
+                let startIndex = Infinity;
+                const tempSrc = src.slice(1);
+                let tempStart;
+                this.options.extensions.startInline.forEach((getStartIndex) => {
+                    tempStart = getStartIndex.call({ lexer: this }, tempSrc);
+                    if (typeof tempStart === 'number' && tempStart >= 0) {
+                        startIndex = Math.min(startIndex, tempStart);
+                    }
+                });
+                if (startIndex < Infinity && startIndex >= 0) {
+                    cutSrc = src.substring(0, startIndex + 1);
+                }
+            }
+            if (token = this.tokenizer.inlineText(cutSrc, smartypants)) {
+                src = src.substring(token.raw.length);
+                if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started
+                    prevChar = token.raw.slice(-1);
+                }
+                keepPrevChar = true;
+                lastToken = tokens[tokens.length - 1];
+                if (lastToken && lastToken.type === 'text') {
+                    lastToken.raw += token.raw;
+                    lastToken.text += token.text;
+                }
+                else {
+                    tokens.push(token);
+                }
+                continue;
+            }
+            if (src) {
+                const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
+                if (this.options.silent) {
+                    console.error(errMsg);
+                    break;
+                }
+                else {
+                    throw new Error(errMsg);
+                }
+            }
+        }
+        return tokens;
+    }
+}
 
-// src/Slugger.ts
-var _Slugger = class {
-  constructor() {
-    this.seen = {};
-  }
-  serialize(value) {
-    return value.toLowerCase().trim().replace(/<[!\/a-z].*?>/ig, "").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, "").replace(/\s/g, "-");
-  }
-  /**
-   * Finds the next safe (unique) slug to use
-   */
-  getNextSafeSlug(originalSlug, isDryRun) {
-    let slug = originalSlug;
-    let occurenceAccumulator = 0;
-    if (this.seen.hasOwnProperty(slug)) {
-      occurenceAccumulator = this.seen[originalSlug];
-      do {
-        occurenceAccumulator++;
-        slug = originalSlug + "-" + occurenceAccumulator;
-      } while (this.seen.hasOwnProperty(slug));
-    }
-    if (!isDryRun) {
-      this.seen[originalSlug] = occurenceAccumulator;
-      this.seen[slug] = 0;
-    }
-    return slug;
-  }
-  /**
-   * Convert string to unique id
-   */
-  slug(value, options2 = {}) {
-    const slug = this.serialize(value);
-    return this.getNextSafeSlug(slug, options2.dryrun);
-  }
-};
+/**
+ * Renderer
+ */
+class _Renderer {
+    options;
+    constructor(options) {
+        this.options = options || _defaults;
+    }
+    code(code, infostring, escaped) {
+        const lang = (infostring || '').match(/\S*/)[0];
+        if (this.options.highlight) {
+            const out = this.options.highlight(code, lang);
+            if (out != null && out !== code) {
+                escaped = true;
+                code = out;
+            }
+        }
+        code = code.replace(/\n$/, '') + '\n';
+        if (!lang) {
+            return '<pre><code>'
+                + (escaped ? code : escape(code, true))
+                + '</code></pre>\n';
+        }
+        return '<pre><code class="'
+            + this.options.langPrefix
+            + escape(lang)
+            + '">'
+            + (escaped ? code : escape(code, true))
+            + '</code></pre>\n';
+    }
+    blockquote(quote) {
+        return `<blockquote>\n${quote}</blockquote>\n`;
+    }
+    html(html, block) {
+        return html;
+    }
+    heading(text, level, raw, slugger) {
+        if (this.options.headerIds) {
+            const id = this.options.headerPrefix + slugger.slug(raw);
+            return `<h${level} id="${id}">${text}</h${level}>\n`;
+        }
+        // ignore IDs
+        return `<h${level}>${text}</h${level}>\n`;
+    }
+    hr() {
+        return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
+    }
+    list(body, ordered, start) {
+        const type = ordered ? 'ol' : 'ul', startatt = (ordered && start !== 1) ? (' start="' + start + '"') : '';
+        return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
+    }
+    listitem(text, task, checked) {
+        return `<li>${text}</li>\n`;
+    }
+    checkbox(checked) {
+        return '<input '
+            + (checked ? 'checked="" ' : '')
+            + 'disabled="" type="checkbox"'
+            + (this.options.xhtml ? ' /' : '')
+            + '> ';
+    }
+    paragraph(text) {
+        return `<p>${text}</p>\n`;
+    }
+    table(header, body) {
+        if (body)
+            body = `<tbody>${body}</tbody>`;
+        return '<table>\n'
+            + '<thead>\n'
+            + header
+            + '</thead>\n'
+            + body
+            + '</table>\n';
+    }
+    tablerow(content) {
+        return `<tr>\n${content}</tr>\n`;
+    }
+    tablecell(content, flags) {
+        const type = flags.header ? 'th' : 'td';
+        const tag = flags.align
+            ? `<${type} align="${flags.align}">`
+            : `<${type}>`;
+        return tag + content + `</${type}>\n`;
+    }
+    /**
+     * span level renderer
+     */
+    strong(text) {
+        return `<strong>${text}</strong>`;
+    }
+    em(text) {
+        return `<em>${text}</em>`;
+    }
+    codespan(text) {
+        return `<code>${text}</code>`;
+    }
+    br() {
+        return this.options.xhtml ? '<br/>' : '<br>';
+    }
+    del(text) {
+        return `<del>${text}</del>`;
+    }
+    link(href, title, text) {
+        href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
+        if (href === null) {
+            return text;
+        }
+        let out = '<a href="' + href + '"';
+        if (title) {
+            out += ' title="' + title + '"';
+        }
+        out += '>' + text + '</a>';
+        return out;
+    }
+    image(href, title, text) {
+        href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
+        if (href === null) {
+            return text;
+        }
+        let out = `<img src="${href}" alt="${text}"`;
+        if (title) {
+            out += ` title="${title}"`;
+        }
+        out += this.options.xhtml ? '/>' : '>';
+        return out;
+    }
+    text(text) {
+        return text;
+    }
+}
 
-// src/Parser.ts
-var _Parser = class __Parser {
-  constructor(options2) {
-    this.options = options2 || _defaults;
-    this.options.renderer = this.options.renderer || new _Renderer();
-    this.renderer = this.options.renderer;
-    this.renderer.options = this.options;
-    this.textRenderer = new _TextRenderer();
-    this.slugger = new _Slugger();
-  }
-  /**
-   * Static Parse Method
-   */
-  static parse(tokens, options2) {
-    const parser2 = new __Parser(options2);
-    return parser2.parse(tokens);
-  }
-  /**
-   * Static Parse Inline Method
-   */
-  static parseInline(tokens, options2) {
-    const parser2 = new __Parser(options2);
-    return parser2.parseInline(tokens);
-  }
-  /**
-   * Parse Loop
-   */
-  parse(tokens, top = true) {
-    let out = "", i, j, k, l2, l3, row, cell, header, body, token, ordered, start, loose, itemBody, item, checked, task, checkbox, ret;
-    const l = tokens.length;
-    for (i = 0; i < l; i++) {
-      token = tokens[i];
-      if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
-        ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
-        if (ret !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "html", "paragraph", "text"].includes(token.type)) {
-          out += ret || "";
-          continue;
-        }
-      }
-      switch (token.type) {
-        case "space": {
-          continue;
-        }
-        case "hr": {
-          out += this.renderer.hr();
-          continue;
-        }
-        case "heading": {
-          out += this.renderer.heading(
-            this.parseInline(token.tokens),
-            token.depth,
-            unescape(this.parseInline(token.tokens, this.textRenderer)),
-            this.slugger
-          );
-          continue;
-        }
-        case "code": {
-          out += this.renderer.code(
-            token.text,
-            token.lang,
-            !!token.escaped
-          );
-          continue;
-        }
-        case "table": {
-          header = "";
-          cell = "";
-          l2 = token.header.length;
-          for (j = 0; j < l2; j++) {
-            cell += this.renderer.tablecell(
-              this.parseInline(token.header[j].tokens),
-              { header: true, align: token.align[j] }
-            );
-          }
-          header += this.renderer.tablerow(cell);
-          body = "";
-          l2 = token.rows.length;
-          for (j = 0; j < l2; j++) {
-            row = token.rows[j];
-            cell = "";
-            l3 = row.length;
-            for (k = 0; k < l3; k++) {
-              cell += this.renderer.tablecell(
-                this.parseInline(row[k].tokens),
-                { header: false, align: token.align[k] }
-              );
-            }
-            body += this.renderer.tablerow(cell);
-          }
-          out += this.renderer.table(header, body);
-          continue;
-        }
-        case "blockquote": {
-          body = this.parse(token.tokens);
-          out += this.renderer.blockquote(body);
-          continue;
-        }
-        case "list": {
-          ordered = token.ordered;
-          start = token.start;
-          loose = token.loose;
-          l2 = token.items.length;
-          body = "";
-          for (j = 0; j < l2; j++) {
-            item = token.items[j];
-            checked = item.checked;
-            task = item.task;
-            itemBody = "";
-            if (item.task) {
-              checkbox = this.renderer.checkbox(!!checked);
-              if (loose) {
-                if (item.tokens.length > 0 && item.tokens[0].type === "paragraph") {
-                  item.tokens[0].text = checkbox + " " + item.tokens[0].text;
-                  if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === "text") {
-                    item.tokens[0].tokens[0].text = checkbox + " " + item.tokens[0].tokens[0].text;
-                  }
-                } else {
-                  item.tokens.unshift({
-                    type: "text",
-                    text: checkbox
-                  });
-                }
-              } else {
-                itemBody += checkbox;
-              }
-            }
-            itemBody += this.parse(item.tokens, loose);
-            body += this.renderer.listitem(itemBody, task, !!checked);
-          }
-          out += this.renderer.list(body, ordered, start);
-          continue;
-        }
-        case "html": {
-          out += this.renderer.html(token.text, token.block);
-          continue;
-        }
-        case "paragraph": {
-          out += this.renderer.paragraph(this.parseInline(token.tokens));
-          continue;
-        }
-        case "text": {
-          body = token.tokens ? this.parseInline(token.tokens) : token.text;
-          while (i + 1 < l && tokens[i + 1].type === "text") {
-            token = tokens[++i];
-            body += "\n" + (token.tokens ? this.parseInline(token.tokens) : token.text);
-          }
-          out += top ? this.renderer.paragraph(body) : body;
-          continue;
-        }
-        default: {
-          const errMsg = 'Token with "' + token.type + '" type was not found.';
-          if (this.options.silent) {
-            console.error(errMsg);
-            return "";
-          } else {
-            throw new Error(errMsg);
-          }
-        }
-      }
+/**
+ * TextRenderer
+ * returns only the textual part of the token
+ */
+class _TextRenderer {
+    // no need for block level renderers
+    strong(text) {
+        return text;
     }
-    return out;
-  }
-  /**
-   * Parse Inline Tokens
-   */
-  parseInline(tokens, renderer) {
-    renderer = renderer || this.renderer;
-    let out = "", i, token, ret;
-    const l = tokens.length;
-    for (i = 0; i < l; i++) {
-      token = tokens[i];
-      if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
-        ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
-        if (ret !== false || !["escape", "html", "link", "image", "strong", "em", "codespan", "br", "del", "text"].includes(token.type)) {
-          out += ret || "";
-          continue;
-        }
-      }
-      switch (token.type) {
-        case "escape": {
-          out += renderer.text(token.text);
-          break;
-        }
-        case "html": {
-          out += renderer.html(token.text);
-          break;
-        }
-        case "link": {
-          out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer));
-          break;
-        }
-        case "image": {
-          out += renderer.image(token.href, token.title, token.text);
-          break;
-        }
-        case "strong": {
-          out += renderer.strong(this.parseInline(token.tokens, renderer));
-          break;
-        }
-        case "em": {
-          out += renderer.em(this.parseInline(token.tokens, renderer));
-          break;
-        }
-        case "codespan": {
-          out += renderer.codespan(token.text);
-          break;
-        }
-        case "br": {
-          out += renderer.br();
-          break;
-        }
-        case "del": {
-          out += renderer.del(this.parseInline(token.tokens, renderer));
-          break;
-        }
-        case "text": {
-          out += renderer.text(token.text);
-          break;
-        }
-        default: {
-          const errMsg = 'Token with "' + token.type + '" type was not found.';
-          if (this.options.silent) {
-            console.error(errMsg);
-            return "";
-          } else {
-            throw new Error(errMsg);
-          }
-        }
-      }
+    em(text) {
+        return text;
     }
-    return out;
-  }
-};
+    codespan(text) {
+        return text;
+    }
+    del(text) {
+        return text;
+    }
+    html(text) {
+        return text;
+    }
+    text(text) {
+        return text;
+    }
+    link(href, title, text) {
+        return '' + text;
+    }
+    image(href, title, text) {
+        return '' + text;
+    }
+    br() {
+        return '';
+    }
+}
 
-// src/Hooks.ts
-var _Hooks = class {
-  constructor(options2) {
-    this.options = options2 || _defaults;
-  }
-  /**
-   * Process markdown before marked
-   */
-  preprocess(markdown) {
-    return markdown;
-  }
-  /**
-   * Process HTML after marked is finished
-   */
-  postprocess(html) {
-    return html;
-  }
-};
-_Hooks.passThroughHooks = /* @__PURE__ */ new Set([
-  "preprocess",
-  "postprocess"
-]);
+/**
+ * Slugger generates header id
+ */
+class _Slugger {
+    seen;
+    constructor() {
+        this.seen = {};
+    }
+    serialize(value) {
+        return value
+            .toLowerCase()
+            .trim()
+            // remove html tags
+            .replace(/<[!\/a-z].*?>/ig, '')
+            // remove unwanted chars
+            .replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, '')
+            .replace(/\s/g, '-');
+    }
+    /**
+     * Finds the next safe (unique) slug to use
+     */
+    getNextSafeSlug(originalSlug, isDryRun) {
+        let slug = originalSlug;
+        let occurenceAccumulator = 0;
+        if (this.seen.hasOwnProperty(slug)) {
+            occurenceAccumulator = this.seen[originalSlug];
+            do {
+                occurenceAccumulator++;
+                slug = originalSlug + '-' + occurenceAccumulator;
+            } while (this.seen.hasOwnProperty(slug));
+        }
+        if (!isDryRun) {
+            this.seen[originalSlug] = occurenceAccumulator;
+            this.seen[slug] = 0;
+        }
+        return slug;
+    }
+    /**
+     * Convert string to unique id
+     */
+    slug(value, options = {}) {
+        const slug = this.serialize(value);
+        return this.getNextSafeSlug(slug, options.dryrun);
+    }
+}
 
-// src/Instance.ts
-var _parseMarkdown, parseMarkdown_fn, _onError, onError_fn;
-var Marked = class {
-  constructor(...args) {
-    __privateAdd(this, _parseMarkdown);
-    __privateAdd(this, _onError);
-    this.defaults = _getDefaults();
-    this.options = this.setOptions;
-    this.parse = __privateMethod(this, _parseMarkdown, parseMarkdown_fn).call(this, _Lexer2.lex, _Parser.parse);
-    this.parseInline = __privateMethod(this, _parseMarkdown, parseMarkdown_fn).call(this, _Lexer2.lexInline, _Parser.parseInline);
-    this.Parser = _Parser;
-    this.parser = _Parser.parse;
-    this.Renderer = _Renderer;
-    this.TextRenderer = _TextRenderer;
-    this.Lexer = _Lexer2;
-    this.lexer = _Lexer2.lex;
-    this.Tokenizer = _Tokenizer;
-    this.Slugger = _Slugger;
-    this.Hooks = _Hooks;
-    this.use(...args);
-  }
-  /**
-   * Run callback for every token
-   */
-  walkTokens(tokens, callback) {
-    let values = [];
-    for (const token of tokens) {
-      values = values.concat(callback.call(this, token));
-      switch (token.type) {
-        case "table": {
-          for (const cell of token.header) {
-            values = values.concat(this.walkTokens(cell.tokens, callback));
-          }
-          for (const row of token.rows) {
-            for (const cell of row) {
-              values = values.concat(this.walkTokens(cell.tokens, callback));
-            }
-          }
-          break;
-        }
-        case "list": {
-          values = values.concat(this.walkTokens(token.items, callback));
-          break;
-        }
-        default: {
-          if (this.defaults.extensions && this.defaults.extensions.childTokens && this.defaults.extensions.childTokens[token.type]) {
-            this.defaults.extensions.childTokens[token.type].forEach((childTokens) => {
-              values = values.concat(this.walkTokens(token[childTokens], callback));
-            });
-          } else if (token.tokens) {
-            values = values.concat(this.walkTokens(token.tokens, callback));
-          }
-        }
-      }
-    }
-    return values;
-  }
-  use(...args) {
-    const extensions = this.defaults.extensions || { renderers: {}, childTokens: {} };
-    args.forEach((pack) => {
-      const opts = { ...pack };
-      opts.async = this.defaults.async || opts.async || false;
-      if (pack.extensions) {
-        pack.extensions.forEach((ext) => {
-          if (!ext.name) {
-            throw new Error("extension name required");
-          }
-          if ("renderer" in ext) {
-            const prevRenderer = extensions.renderers[ext.name];
-            if (prevRenderer) {
-              extensions.renderers[ext.name] = function(...args2) {
-                let ret = ext.renderer.apply(this, args2);
-                if (ret === false) {
-                  ret = prevRenderer.apply(this, args2);
-                }
-                return ret;
-              };
-            } else {
-              extensions.renderers[ext.name] = ext.renderer;
-            }
-          }
-          if ("tokenizer" in ext) {
-            if (!ext.level || ext.level !== "block" && ext.level !== "inline") {
-              throw new Error("extension level must be 'block' or 'inline'");
-            }
-            if (extensions[ext.level]) {
-              extensions[ext.level].unshift(ext.tokenizer);
-            } else {
-              extensions[ext.level] = [ext.tokenizer];
-            }
-            if (ext.start) {
-              if (ext.level === "block") {
-                if (extensions.startBlock) {
-                  extensions.startBlock.push(ext.start);
-                } else {
-                  extensions.startBlock = [ext.start];
-                }
-              } else if (ext.level === "inline") {
-                if (extensions.startInline) {
-                  extensions.startInline.push(ext.start);
-                } else {
-                  extensions.startInline = [ext.start];
-                }
-              }
-            }
-          }
-          if ("childTokens" in ext && ext.childTokens) {
-            extensions.childTokens[ext.name] = ext.childTokens;
-          }
-        });
-        opts.extensions = extensions;
-      }
-      if (pack.renderer) {
-        const renderer = this.defaults.renderer || new _Renderer(this.defaults);
-        for (const prop in pack.renderer) {
-          const prevRenderer = renderer[prop];
-          renderer[prop] = (...args2) => {
-            let ret = pack.renderer[prop].apply(renderer, args2);
-            if (ret === false) {
-              ret = prevRenderer.apply(renderer, args2);
-            }
-            return ret;
-          };
-        }
-        opts.renderer = renderer;
-      }
-      if (pack.tokenizer) {
-        const tokenizer = this.defaults.tokenizer || new _Tokenizer(this.defaults);
-        for (const prop in pack.tokenizer) {
-          const prevTokenizer = tokenizer[prop];
-          tokenizer[prop] = (...args2) => {
-            let ret = pack.tokenizer[prop].apply(tokenizer, args2);
-            if (ret === false) {
-              ret = prevTokenizer.apply(tokenizer, args2);
-            }
-            return ret;
-          };
-        }
-        opts.tokenizer = tokenizer;
-      }
-      if (pack.hooks) {
-        const hooks = this.defaults.hooks || new _Hooks();
-        for (const prop in pack.hooks) {
-          const prevHook = hooks[prop];
-          if (_Hooks.passThroughHooks.has(prop)) {
-            hooks[prop] = (arg) => {
-              if (this.defaults.async) {
-                return Promise.resolve(pack.hooks[prop].call(hooks, arg)).then((ret2) => {
-                  return prevHook.call(hooks, ret2);
-                });
-              }
-              const ret = pack.hooks[prop].call(hooks, arg);
-              return prevHook.call(hooks, ret);
-            };
-          } else {
-            hooks[prop] = (...args2) => {
-              let ret = pack.hooks[prop].apply(hooks, args2);
-              if (ret === false) {
-                ret = prevHook.apply(hooks, args2);
-              }
-              return ret;
-            };
-          }
-        }
-        opts.hooks = hooks;
-      }
-      if (pack.walkTokens) {
-        const walkTokens2 = this.defaults.walkTokens;
-        opts.walkTokens = function(token) {
-          let values = [];
-          values.push(pack.walkTokens.call(this, token));
-          if (walkTokens2) {
-            values = values.concat(walkTokens2.call(this, token));
-          }
-          return values;
-        };
-      }
-      this.defaults = { ...this.defaults, ...opts };
-    });
-    return this;
-  }
-  setOptions(opt) {
-    this.defaults = { ...this.defaults, ...opt };
-    return this;
-  }
-};
-_parseMarkdown = new WeakSet();
-parseMarkdown_fn = function(lexer2, parser2) {
-  return (src, optOrCallback, callback) => {
-    if (typeof optOrCallback === "function") {
-      callback = optOrCallback;
-      optOrCallback = null;
-    }
-    const origOpt = { ...optOrCallback };
-    const opt = { ...this.defaults, ...origOpt };
-    const throwError = __privateMethod(this, _onError, onError_fn).call(this, !!opt.silent, !!opt.async, callback);
-    if (typeof src === "undefined" || src === null) {
-      return throwError(new Error("marked(): input parameter is undefined or null"));
-    }
-    if (typeof src !== "string") {
-      return throwError(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(src) + ", string expected"));
-    }
-    checkDeprecations(opt, callback);
-    if (opt.hooks) {
-      opt.hooks.options = opt;
+/**
+ * Parsing & Compiling
+ */
+class _Parser {
+    options;
+    renderer;
+    textRenderer;
+    slugger;
+    constructor(options) {
+        this.options = options || _defaults;
+        this.options.renderer = this.options.renderer || new _Renderer();
+        this.renderer = this.options.renderer;
+        this.renderer.options = this.options;
+        this.textRenderer = new _TextRenderer();
+        this.slugger = new _Slugger();
+    }
+    /**
+     * Static Parse Method
+     */
+    static parse(tokens, options) {
+        const parser = new _Parser(options);
+        return parser.parse(tokens);
+    }
+    /**
+     * Static Parse Inline Method
+     */
+    static parseInline(tokens, options) {
+        const parser = new _Parser(options);
+        return parser.parseInline(tokens);
+    }
+    /**
+     * Parse Loop
+     */
+    parse(tokens, top = true) {
+        let out = '', i, j, k, l2, l3, row, cell, header, body, token, ordered, start, loose, itemBody, item, checked, task, checkbox, ret;
+        const l = tokens.length;
+        for (i = 0; i < l; i++) {
+            token = tokens[i];
+            // Run any renderer extensions
+            if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
+                ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
+                if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(token.type)) {
+                    out += ret || '';
+                    continue;
+                }
+            }
+            switch (token.type) {
+                case 'space': {
+                    continue;
+                }
+                case 'hr': {
+                    out += this.renderer.hr();
+                    continue;
+                }
+                case 'heading': {
+                    out += this.renderer.heading(this.parseInline(token.tokens), token.depth, unescape(this.parseInline(token.tokens, this.textRenderer)), this.slugger);
+                    continue;
+                }
+                case 'code': {
+                    out += this.renderer.code(token.text, token.lang, !!token.escaped);
+                    continue;
+                }
+                case 'table': {
+                    header = '';
+                    // header
+                    cell = '';
+                    l2 = token.header.length;
+                    for (j = 0; j < l2; j++) {
+                        cell += this.renderer.tablecell(this.parseInline(token.header[j].tokens), { header: true, align: token.align[j] });
+                    }
+                    header += this.renderer.tablerow(cell);
+                    body = '';
+                    l2 = token.rows.length;
+                    for (j = 0; j < l2; j++) {
+                        row = token.rows[j];
+                        cell = '';
+                        l3 = row.length;
+                        for (k = 0; k < l3; k++) {
+                            cell += this.renderer.tablecell(this.parseInline(row[k].tokens), { header: false, align: token.align[k] });
+                        }
+                        body += this.renderer.tablerow(cell);
+                    }
+                    out += this.renderer.table(header, body);
+                    continue;
+                }
+                case 'blockquote': {
+                    body = this.parse(token.tokens);
+                    out += this.renderer.blockquote(body);
+                    continue;
+                }
+                case 'list': {
+                    ordered = token.ordered;
+                    start = token.start;
+                    loose = token.loose;
+                    l2 = token.items.length;
+                    body = '';
+                    for (j = 0; j < l2; j++) {
+                        item = token.items[j];
+                        checked = item.checked;
+                        task = item.task;
+                        itemBody = '';
+                        if (item.task) {
+                            checkbox = this.renderer.checkbox(!!checked);
+                            if (loose) {
+                                if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {
+                                    item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
+                                    if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
+                                        item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text;
+                                    }
+                                }
+                                else {
+                                    item.tokens.unshift({
+                                        type: 'text',
+                                        text: checkbox
+                                    });
+                                }
+                            }
+                            else {
+                                itemBody += checkbox;
+                            }
+                        }
+                        itemBody += this.parse(item.tokens, loose);
+                        body += this.renderer.listitem(itemBody, task, !!checked);
+                    }
+                    out += this.renderer.list(body, ordered, start);
+                    continue;
+                }
+                case 'html': {
+                    out += this.renderer.html(token.text, token.block);
+                    continue;
+                }
+                case 'paragraph': {
+                    out += this.renderer.paragraph(this.parseInline(token.tokens));
+                    continue;
+                }
+                case 'text': {
+                    body = token.tokens ? this.parseInline(token.tokens) : token.text;
+                    while (i + 1 < l && tokens[i + 1].type === 'text') {
+                        token = tokens[++i];
+                        body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text);
+                    }
+                    out += top ? this.renderer.paragraph(body) : body;
+                    continue;
+                }
+                default: {
+                    const errMsg = 'Token with "' + token.type + '" type was not found.';
+                    if (this.options.silent) {
+                        console.error(errMsg);
+                        return '';
+                    }
+                    else {
+                        throw new Error(errMsg);
+                    }
+                }
+            }
+        }
+        return out;
     }
-    if (callback) {
-      const highlight = opt.highlight;
-      let tokens;
-      try {
-        if (opt.hooks) {
-          src = opt.hooks.preprocess(src);
-        }
-        tokens = lexer2(src, opt);
-      } catch (e) {
-        return throwError(e);
-      }
-      const done = (err) => {
-        let out;
-        if (!err) {
-          try {
-            if (opt.walkTokens) {
-              this.walkTokens(tokens, opt.walkTokens);
-            }
-            out = parser2(tokens, opt);
-            if (opt.hooks) {
-              out = opt.hooks.postprocess(out);
-            }
-          } catch (e) {
-            err = e;
-          }
-        }
-        opt.highlight = highlight;
-        return err ? throwError(err) : callback(null, out);
-      };
-      if (!highlight || highlight.length < 3) {
-        return done();
-      }
-      delete opt.highlight;
-      if (!tokens.length)
-        return done();
-      let pending = 0;
-      this.walkTokens(tokens, (token) => {
-        if (token.type === "code") {
-          pending++;
-          setTimeout(() => {
-            highlight(token.text, token.lang, (err, code) => {
-              if (err) {
-                return done(err);
-              }
-              if (code != null && code !== token.text) {
-                token.text = code;
-                token.escaped = true;
-              }
-              pending--;
-              if (pending === 0) {
-                done();
-              }
-            });
-          }, 0);
+    /**
+     * Parse Inline Tokens
+     */
+    parseInline(tokens, renderer) {
+        renderer = renderer || this.renderer;
+        let out = '', i, token, ret;
+        const l = tokens.length;
+        for (i = 0; i < l; i++) {
+            token = tokens[i];
+            // Run any renderer extensions
+            if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
+                ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
+                if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) {
+                    out += ret || '';
+                    continue;
+                }
+            }
+            switch (token.type) {
+                case 'escape': {
+                    out += renderer.text(token.text);
+                    break;
+                }
+                case 'html': {
+                    out += renderer.html(token.text);
+                    break;
+                }
+                case 'link': {
+                    out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer));
+                    break;
+                }
+                case 'image': {
+                    out += renderer.image(token.href, token.title, token.text);
+                    break;
+                }
+                case 'strong': {
+                    out += renderer.strong(this.parseInline(token.tokens, renderer));
+                    break;
+                }
+                case 'em': {
+                    out += renderer.em(this.parseInline(token.tokens, renderer));
+                    break;
+                }
+                case 'codespan': {
+                    out += renderer.codespan(token.text);
+                    break;
+                }
+                case 'br': {
+                    out += renderer.br();
+                    break;
+                }
+                case 'del': {
+                    out += renderer.del(this.parseInline(token.tokens, renderer));
+                    break;
+                }
+                case 'text': {
+                    out += renderer.text(token.text);
+                    break;
+                }
+                default: {
+                    const errMsg = 'Token with "' + token.type + '" type was not found.';
+                    if (this.options.silent) {
+                        console.error(errMsg);
+                        return '';
+                    }
+                    else {
+                        throw new Error(errMsg);
+                    }
+                }
+            }
         }
-      });
-      if (pending === 0) {
-        done();
-      }
-      return;
+        return out;
     }
-    if (opt.async) {
-      return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src).then((src2) => lexer2(src2, opt)).then((tokens) => opt.walkTokens ? Promise.all(this.walkTokens(tokens, opt.walkTokens)).then(() => tokens) : tokens).then((tokens) => parser2(tokens, opt)).then((html) => opt.hooks ? opt.hooks.postprocess(html) : html).catch(throwError);
+}
+
+class _Hooks {
+    options;
+    constructor(options) {
+        this.options = options || _defaults;
+    }
+    static passThroughHooks = new Set([
+        'preprocess',
+        'postprocess'
+    ]);
+    /**
+     * Process markdown before marked
+     */
+    preprocess(markdown) {
+        return markdown;
+    }
+    /**
+     * Process HTML after marked is finished
+     */
+    postprocess(html) {
+        return html;
     }
-    try {
-      if (opt.hooks) {
-        src = opt.hooks.preprocess(src);
-      }
-      const tokens = lexer2(src, opt);
-      if (opt.walkTokens) {
-        this.walkTokens(tokens, opt.walkTokens);
-      }
-      let html = parser2(tokens, opt);
-      if (opt.hooks) {
-        html = opt.hooks.postprocess(html);
-      }
-      return html;
-    } catch (e) {
-      return throwError(e);
-    }
-  };
-};
-_onError = new WeakSet();
-onError_fn = function(silent, async, callback) {
-  return (e) => {
-    e.message += "\nPlease report this to https://github.com/markedjs/marked.";
-    if (silent) {
-      const msg = "<p>An error occurred:</p><pre>" + escape(e.message + "", true) + "</pre>";
-      if (async) {
-        return Promise.resolve(msg);
-      }
-      if (callback) {
-        callback(null, msg);
-        return;
-      }
-      return msg;
+}
+
+class Marked {
+    defaults = _getDefaults();
+    options = this.setOptions;
+    parse = this.#parseMarkdown(_Lexer.lex, _Parser.parse);
+    parseInline = this.#parseMarkdown(_Lexer.lexInline, _Parser.parseInline);
+    Parser = _Parser;
+    parser = _Parser.parse;
+    Renderer = _Renderer;
+    TextRenderer = _TextRenderer;
+    Lexer = _Lexer;
+    lexer = _Lexer.lex;
+    Tokenizer = _Tokenizer;
+    Slugger = _Slugger;
+    Hooks = _Hooks;
+    constructor(...args) {
+        this.use(...args);
+    }
+    /**
+     * Run callback for every token
+     */
+    walkTokens(tokens, callback) {
+        let values = [];
+        for (const token of tokens) {
+            values = values.concat(callback.call(this, token));
+            switch (token.type) {
+                case 'table': {
+                    for (const cell of token.header) {
+                        values = values.concat(this.walkTokens(cell.tokens, callback));
+                    }
+                    for (const row of token.rows) {
+                        for (const cell of row) {
+                            values = values.concat(this.walkTokens(cell.tokens, callback));
+                        }
+                    }
+                    break;
+                }
+                case 'list': {
+                    values = values.concat(this.walkTokens(token.items, callback));
+                    break;
+                }
+                default: {
+                    if (this.defaults.extensions && this.defaults.extensions.childTokens && this.defaults.extensions.childTokens[token.type]) { // Walk any extensions
+                        this.defaults.extensions.childTokens[token.type].forEach((childTokens) => {
+                            values = values.concat(this.walkTokens(token[childTokens], callback));
+                        });
+                    }
+                    else if (token.tokens) {
+                        values = values.concat(this.walkTokens(token.tokens, callback));
+                    }
+                }
+            }
+        }
+        return values;
+    }
+    use(...args) {
+        const extensions = this.defaults.extensions || { renderers: {}, childTokens: {} };
+        args.forEach((pack) => {
+            // copy options to new object
+            const opts = { ...pack };
+            // set async to true if it was set to true before
+            opts.async = this.defaults.async || opts.async || false;
+            // ==-- Parse "addon" extensions --== //
+            if (pack.extensions) {
+                pack.extensions.forEach((ext) => {
+                    if (!ext.name) {
+                        throw new Error('extension name required');
+                    }
+                    if ('renderer' in ext) { // Renderer extensions
+                        const prevRenderer = extensions.renderers[ext.name];
+                        if (prevRenderer) {
+                            // Replace extension with func to run new extension but fall back if false
+                            extensions.renderers[ext.name] = function (...args) {
+                                let ret = ext.renderer.apply(this, args);
+                                if (ret === false) {
+                                    ret = prevRenderer.apply(this, args);
+                                }
+                                return ret;
+                            };
+                        }
+                        else {
+                            extensions.renderers[ext.name] = ext.renderer;
+                        }
+                    }
+                    if ('tokenizer' in ext) { // Tokenizer Extensions
+                        if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) {
+                            throw new Error("extension level must be 'block' or 'inline'");
+                        }
+                        if (extensions[ext.level]) {
+                            extensions[ext.level].unshift(ext.tokenizer);
+                        }
+                        else {
+                            extensions[ext.level] = [ext.tokenizer];
+                        }
+                        if (ext.start) { // Function to check for start of token
+                            if (ext.level === 'block') {
+                                if (extensions.startBlock) {
+                                    extensions.startBlock.push(ext.start);
+                                }
+                                else {
+                                    extensions.startBlock = [ext.start];
+                                }
+                            }
+                            else if (ext.level === 'inline') {
+                                if (extensions.startInline) {
+                                    extensions.startInline.push(ext.start);
+                                }
+                                else {
+                                    extensions.startInline = [ext.start];
+                                }
+                            }
+                        }
+                    }
+                    if ('childTokens' in ext && ext.childTokens) { // Child tokens to be visited by walkTokens
+                        extensions.childTokens[ext.name] = ext.childTokens;
+                    }
+                });
+                opts.extensions = extensions;
+            }
+            // ==-- Parse "overwrite" extensions --== //
+            if (pack.renderer) {
+                const renderer = this.defaults.renderer || new _Renderer(this.defaults);
+                for (const prop in pack.renderer) {
+                    const prevRenderer = renderer[prop];
+                    // Replace renderer with func to run extension, but fall back if false
+                    renderer[prop] = (...args) => {
+                        let ret = pack.renderer[prop].apply(renderer, args);
+                        if (ret === false) {
+                            ret = prevRenderer.apply(renderer, args);
+                        }
+                        return ret;
+                    };
+                }
+                opts.renderer = renderer;
+            }
+            if (pack.tokenizer) {
+                const tokenizer = this.defaults.tokenizer || new _Tokenizer(this.defaults);
+                for (const prop in pack.tokenizer) {
+                    const prevTokenizer = tokenizer[prop];
+                    // Replace tokenizer with func to run extension, but fall back if false
+                    tokenizer[prop] = (...args) => {
+                        let ret = pack.tokenizer[prop].apply(tokenizer, args);
+                        if (ret === false) {
+                            ret = prevTokenizer.apply(tokenizer, args);
+                        }
+                        return ret;
+                    };
+                }
+                opts.tokenizer = tokenizer;
+            }
+            // ==-- Parse Hooks extensions --== //
+            if (pack.hooks) {
+                const hooks = this.defaults.hooks || new _Hooks();
+                for (const prop in pack.hooks) {
+                    const prevHook = hooks[prop];
+                    if (_Hooks.passThroughHooks.has(prop)) {
+                        hooks[prop] = (arg) => {
+                            if (this.defaults.async) {
+                                return Promise.resolve(pack.hooks[prop].call(hooks, arg)).then(ret => {
+                                    return prevHook.call(hooks, ret);
+                                });
+                            }
+                            const ret = pack.hooks[prop].call(hooks, arg);
+                            return prevHook.call(hooks, ret);
+                        };
+                    }
+                    else {
+                        hooks[prop] = (...args) => {
+                            let ret = pack.hooks[prop].apply(hooks, args);
+                            if (ret === false) {
+                                ret = prevHook.apply(hooks, args);
+                            }
+                            return ret;
+                        };
+                    }
+                }
+                opts.hooks = hooks;
+            }
+            // ==-- Parse WalkTokens extensions --== //
+            if (pack.walkTokens) {
+                const walkTokens = this.defaults.walkTokens;
+                opts.walkTokens = function (token) {
+                    let values = [];
+                    values.push(pack.walkTokens.call(this, token));
+                    if (walkTokens) {
+                        values = values.concat(walkTokens.call(this, token));
+                    }
+                    return values;
+                };
+            }
+            this.defaults = { ...this.defaults, ...opts };
+        });
+        return this;
     }
-    if (async) {
-      return Promise.reject(e);
+    setOptions(opt) {
+        this.defaults = { ...this.defaults, ...opt };
+        return this;
     }
-    if (callback) {
-      callback(e);
-      return;
+    #parseMarkdown(lexer, parser) {
+        return (src, optOrCallback, callback) => {
+            if (typeof optOrCallback === 'function') {
+                callback = optOrCallback;
+                optOrCallback = null;
+            }
+            const origOpt = { ...optOrCallback };
+            const opt = { ...this.defaults, ...origOpt };
+            const throwError = this.#onError(!!opt.silent, !!opt.async, callback);
+            // throw error in case of non string input
+            if (typeof src === 'undefined' || src === null) {
+                return throwError(new Error('marked(): input parameter is undefined or null'));
+            }
+            if (typeof src !== 'string') {
+                return throwError(new Error('marked(): input parameter is of type '
+                    + Object.prototype.toString.call(src) + ', string expected'));
+            }
+            checkDeprecations(opt, callback);
+            if (opt.hooks) {
+                opt.hooks.options = opt;
+            }
+            if (callback) {
+                const highlight = opt.highlight;
+                let tokens;
+                try {
+                    if (opt.hooks) {
+                        src = opt.hooks.preprocess(src);
+                    }
+                    tokens = lexer(src, opt);
+                }
+                catch (e) {
+                    return throwError(e);
+                }
+                const done = (err) => {
+                    let out;
+                    if (!err) {
+                        try {
+                            if (opt.walkTokens) {
+                                this.walkTokens(tokens, opt.walkTokens);
+                            }
+                            out = parser(tokens, opt);
+                            if (opt.hooks) {
+                                out = opt.hooks.postprocess(out);
+                            }
+                        }
+                        catch (e) {
+                            err = e;
+                        }
+                    }
+                    opt.highlight = highlight;
+                    return err
+                        ? throwError(err)
+                        : callback(null, out);
+                };
+                if (!highlight || highlight.length < 3) {
+                    return done();
+                }
+                delete opt.highlight;
+                if (!tokens.length)
+                    return done();
+                let pending = 0;
+                this.walkTokens(tokens, (token) => {
+                    if (token.type === 'code') {
+                        pending++;
+                        setTimeout(() => {
+                            highlight(token.text, token.lang, (err, code) => {
+                                if (err) {
+                                    return done(err);
+                                }
+                                if (code != null && code !== token.text) {
+                                    token.text = code;
+                                    token.escaped = true;
+                                }
+                                pending--;
+                                if (pending === 0) {
+                                    done();
+                                }
+                            });
+                        }, 0);
+                    }
+                });
+                if (pending === 0) {
+                    done();
+                }
+                return;
+            }
+            if (opt.async) {
+                return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src)
+                    .then(src => lexer(src, opt))
+                    .then(tokens => opt.walkTokens ? Promise.all(this.walkTokens(tokens, opt.walkTokens)).then(() => tokens) : tokens)
+                    .then(tokens => parser(tokens, opt))
+                    .then(html => opt.hooks ? opt.hooks.postprocess(html) : html)
+                    .catch(throwError);
+            }
+            try {
+                if (opt.hooks) {
+                    src = opt.hooks.preprocess(src);
+                }
+                const tokens = lexer(src, opt);
+                if (opt.walkTokens) {
+                    this.walkTokens(tokens, opt.walkTokens);
+                }
+                let html = parser(tokens, opt);
+                if (opt.hooks) {
+                    html = opt.hooks.postprocess(html);
+                }
+                return html;
+            }
+            catch (e) {
+                return throwError(e);
+            }
+        };
     }
-    throw e;
-  };
-};
+    #onError(silent, async, callback) {
+        return (e) => {
+            e.message += '\nPlease report this to https://github.com/markedjs/marked.';
+            if (silent) {
+                const msg = '<p>An error occurred:</p><pre>'
+                    + escape(e.message + '', true)
+                    + '</pre>';
+                if (async) {
+                    return Promise.resolve(msg);
+                }
+                if (callback) {
+                    callback(null, msg);
+                    return;
+                }
+                return msg;
+            }
+            if (async) {
+                return Promise.reject(e);
+            }
+            if (callback) {
+                callback(e);
+                return;
+            }
+            throw e;
+        };
+    }
+}
 
-// src/marked.ts
-var markedInstance = new Marked();
+const markedInstance = new Marked();
 function marked(src, opt, callback) {
-  return markedInstance.parse(src, opt, callback);
+    return markedInstance.parse(src, opt, callback);
 }
-marked.options = marked.setOptions = function(options2) {
-  markedInstance.setOptions(options2);
-  marked.defaults = markedInstance.defaults;
-  changeDefaults(marked.defaults);
-  return marked;
-};
+/**
+ * Sets the default options.
+ *
+ * @param options Hash of options
+ */
+marked.options =
+    marked.setOptions = function (options) {
+        markedInstance.setOptions(options);
+        marked.defaults = markedInstance.defaults;
+        changeDefaults(marked.defaults);
+        return marked;
+    };
+/**
+ * Gets the original marked default options.
+ */
 marked.getDefaults = _getDefaults;
 marked.defaults = _defaults;
-marked.use = function(...args) {
-  markedInstance.use(...args);
-  marked.defaults = markedInstance.defaults;
-  changeDefaults(marked.defaults);
-  return marked;
+/**
+ * Use Extension
+ */
+marked.use = function (...args) {
+    markedInstance.use(...args);
+    marked.defaults = markedInstance.defaults;
+    changeDefaults(marked.defaults);
+    return marked;
 };
-marked.walkTokens = function(tokens, callback) {
-  return markedInstance.walkTokens(tokens, callback);
+/**
+ * Run callback for every token
+ */
+marked.walkTokens = function (tokens, callback) {
+    return markedInstance.walkTokens(tokens, callback);
 };
+/**
+ * Compiles markdown to HTML without enclosing `p` tag.
+ *
+ * @param src String of markdown source to be compiled
+ * @param options Hash of options
+ * @return String of compiled HTML
+ */
 marked.parseInline = markedInstance.parseInline;
+/**
+ * Expose
+ */
 marked.Parser = _Parser;
 marked.parser = _Parser.parse;
 marked.Renderer = _Renderer;
 marked.TextRenderer = _TextRenderer;
-marked.Lexer = _Lexer2;
-marked.lexer = _Lexer2.lex;
+marked.Lexer = _Lexer;
+marked.lexer = _Lexer.lex;
 marked.Tokenizer = _Tokenizer;
 marked.Slugger = _Slugger;
 marked.Hooks = _Hooks;
 marked.parse = marked;
-var options = marked.options;
-var setOptions = marked.setOptions;
-var use = marked.use;
-var walkTokens = marked.walkTokens;
-var parseInline = marked.parseInline;
-var parse = marked;
-var parser = _Parser.parse;
-var lexer = _Lexer2.lex;
-export {
-  _Hooks as Hooks,
-  _Lexer2 as Lexer,
-  Marked,
-  _Parser as Parser,
-  _Renderer as Renderer,
-  _Slugger as Slugger,
-  _TextRenderer as TextRenderer,
-  _Tokenizer as Tokenizer,
-  _defaults as defaults,
-  _getDefaults as getDefaults,
-  lexer,
-  marked,
-  options,
-  parse,
-  parseInline,
-  parser,
-  setOptions,
-  use,
-  walkTokens
-};
-//# sourceMappingURL=marked.esm.js.map
+const options = marked.options;
+const setOptions = marked.setOptions;
+const use = marked.use;
+const walkTokens = marked.walkTokens;
+const parseInline = marked.parseInline;
+const parse = marked;
+const parser = _Parser.parse;
+const lexer = _Lexer.lex;
+
+export { _Hooks as Hooks, _Lexer as Lexer, Marked, _Parser as Parser, _Renderer as Renderer, _Slugger as Slugger, _TextRenderer as TextRenderer, _Tokenizer as Tokenizer, _defaults as defaults, _getDefaults as getDefaults, lexer, marked, options, parse, parseInline, parser, setOptions, use, walkTokens };
+//# sourceMappingURL=marked.esm.js.map

File diff suppressed because it is too large
+ 0 - 0
lib/marked.esm.js.map


+ 2555 - 2178
lib/marked.umd.js

@@ -9,2261 +9,2638 @@
  * The code in this file is generated from files in ./src/
  */
 
-"use strict";
-var marked = (() => {
-  var __defProp = Object.defineProperty;
-  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
-  var __getOwnPropNames = Object.getOwnPropertyNames;
-  var __hasOwnProp = Object.prototype.hasOwnProperty;
-  var __export = (target, all) => {
-    for (var name in all)
-      __defProp(target, name, { get: all[name], enumerable: true });
-  };
-  var __copyProps = (to, from, except, desc) => {
-    if (from && typeof from === "object" || typeof from === "function") {
-      for (let key of __getOwnPropNames(from))
-        if (!__hasOwnProp.call(to, key) && key !== except)
-          __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
-    }
-    return to;
-  };
-  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
-  var __accessCheck = (obj, member, msg) => {
-    if (!member.has(obj))
-      throw TypeError("Cannot " + msg);
-  };
-  var __privateAdd = (obj, member, value) => {
-    if (member.has(obj))
-      throw TypeError("Cannot add the same private member more than once");
-    member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
-  };
-  var __privateMethod = (obj, member, method) => {
-    __accessCheck(obj, member, "access private method");
-    return method;
-  };
-
-  // src/marked.ts
-  var marked_exports = {};
-  __export(marked_exports, {
-    Hooks: () => _Hooks,
-    Lexer: () => _Lexer2,
-    Marked: () => Marked,
-    Parser: () => _Parser,
-    Renderer: () => _Renderer,
-    Slugger: () => _Slugger,
-    TextRenderer: () => _TextRenderer,
-    Tokenizer: () => _Tokenizer,
-    defaults: () => _defaults,
-    getDefaults: () => _getDefaults,
-    lexer: () => lexer,
-    marked: () => marked,
-    options: () => options,
-    parse: () => parse,
-    parseInline: () => parseInline,
-    parser: () => parser,
-    setOptions: () => setOptions,
-    use: () => use,
-    walkTokens: () => walkTokens
-  });
+(function (global, factory) {
+    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+    typeof define === 'function' && define.amd ? define(['exports'], factory) :
+    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.marked = {}));
+})(this, (function (exports) { 'use strict';
 
-  // src/defaults.ts
-  function _getDefaults() {
-    return {
-      async: false,
-      baseUrl: null,
-      breaks: false,
-      extensions: null,
-      gfm: true,
-      headerIds: false,
-      headerPrefix: "",
-      highlight: null,
-      hooks: null,
-      langPrefix: "language-",
-      mangle: false,
-      pedantic: false,
-      renderer: null,
-      sanitize: false,
-      sanitizer: null,
-      silent: false,
-      smartypants: false,
-      tokenizer: null,
-      walkTokens: null,
-      xhtml: false
-    };
-  }
-  var _defaults = _getDefaults();
-  function changeDefaults(newDefaults) {
-    _defaults = newDefaults;
-  }
-
-  // src/helpers.ts
-  var escapeTest = /[&<>"']/;
-  var escapeReplace = new RegExp(escapeTest.source, "g");
-  var escapeTestNoEncode = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/;
-  var escapeReplaceNoEncode = new RegExp(escapeTestNoEncode.source, "g");
-  var escapeReplacements = {
-    "&": "&amp;",
-    "<": "&lt;",
-    ">": "&gt;",
-    '"': "&quot;",
-    "'": "&#39;"
-  };
-  var getEscapeReplacement = (ch) => escapeReplacements[ch];
-  function escape(html, encode) {
-    if (encode) {
-      if (escapeTest.test(html)) {
-        return html.replace(escapeReplace, getEscapeReplacement);
-      }
-    } else {
-      if (escapeTestNoEncode.test(html)) {
-        return html.replace(escapeReplaceNoEncode, getEscapeReplacement);
-      }
-    }
-    return html;
-  }
-  var unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig;
-  function unescape(html) {
-    return html.replace(unescapeTest, (_, n) => {
-      n = n.toLowerCase();
-      if (n === "colon")
-        return ":";
-      if (n.charAt(0) === "#") {
-        return n.charAt(1) === "x" ? String.fromCharCode(parseInt(n.substring(2), 16)) : String.fromCharCode(+n.substring(1));
-      }
-      return "";
-    });
-  }
-  var caret = /(^|[^\[])\^/g;
-  function edit(regex, opt) {
-    regex = typeof regex === "string" ? regex : regex.source;
-    opt = opt || "";
-    const obj = {
-      replace: (name, val) => {
-        val = typeof val === "object" && "source" in val ? val.source : val;
-        val = val.replace(caret, "$1");
-        regex = regex.replace(name, val);
-        return obj;
-      },
-      getRegex: () => {
-        return new RegExp(regex, opt);
-      }
-    };
-    return obj;
-  }
-  var nonWordAndColonTest = /[^\w:]/g;
-  var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
-  function cleanUrl(sanitize, base, href) {
-    if (sanitize) {
-      let prot;
-      try {
-        prot = decodeURIComponent(unescape(href)).replace(nonWordAndColonTest, "").toLowerCase();
-      } catch (e) {
-        return null;
-      }
-      if (prot.indexOf("javascript:") === 0 || prot.indexOf("vbscript:") === 0 || prot.indexOf("data:") === 0) {
-        return null;
-      }
-    }
-    if (base && !originIndependentUrl.test(href)) {
-      href = resolveUrl(base, href);
-    }
-    try {
-      href = encodeURI(href).replace(/%25/g, "%");
-    } catch (e) {
-      return null;
-    }
-    return href;
-  }
-  var baseUrls = {};
-  var justDomain = /^[^:]+:\/*[^/]*$/;
-  var protocol = /^([^:]+:)[\s\S]*$/;
-  var domain = /^([^:]+:\/*[^/]*)[\s\S]*$/;
-  function resolveUrl(base, href) {
-    if (!baseUrls[" " + base]) {
-      if (justDomain.test(base)) {
-        baseUrls[" " + base] = base + "/";
-      } else {
-        baseUrls[" " + base] = rtrim(base, "/", true);
-      }
-    }
-    base = baseUrls[" " + base];
-    const relativeBase = base.indexOf(":") === -1;
-    if (href.substring(0, 2) === "//") {
-      if (relativeBase) {
-        return href;
-      }
-      return base.replace(protocol, "$1") + href;
-    } else if (href.charAt(0) === "/") {
-      if (relativeBase) {
-        return href;
-      }
-      return base.replace(domain, "$1") + href;
-    } else {
-      return base + href;
-    }
-  }
-  var noopTest = { exec: () => null };
-  function splitCells(tableRow, count) {
-    const row = tableRow.replace(/\|/g, (match, offset, str) => {
-      let escaped = false, curr = offset;
-      while (--curr >= 0 && str[curr] === "\\")
-        escaped = !escaped;
-      if (escaped) {
-        return "|";
-      } else {
-        return " |";
-      }
-    }), cells = row.split(/ \|/);
-    let i = 0;
-    if (!cells[0].trim()) {
-      cells.shift();
-    }
-    if (cells.length > 0 && !cells[cells.length - 1].trim()) {
-      cells.pop();
-    }
-    if (cells.length > count) {
-      cells.splice(count);
-    } else {
-      while (cells.length < count)
-        cells.push("");
-    }
-    for (; i < cells.length; i++) {
-      cells[i] = cells[i].trim().replace(/\\\|/g, "|");
-    }
-    return cells;
-  }
-  function rtrim(str, c, invert) {
-    const l = str.length;
-    if (l === 0) {
-      return "";
-    }
-    let suffLen = 0;
-    while (suffLen < l) {
-      const currChar = str.charAt(l - suffLen - 1);
-      if (currChar === c && !invert) {
-        suffLen++;
-      } else if (currChar !== c && invert) {
-        suffLen++;
-      } else {
-        break;
-      }
-    }
-    return str.slice(0, l - suffLen);
-  }
-  function findClosingBracket(str, b) {
-    if (str.indexOf(b[1]) === -1) {
-      return -1;
-    }
-    const l = str.length;
-    let level = 0, i = 0;
-    for (; i < l; i++) {
-      if (str[i] === "\\") {
-        i++;
-      } else if (str[i] === b[0]) {
-        level++;
-      } else if (str[i] === b[1]) {
-        level--;
-        if (level < 0) {
-          return i;
-        }
-      }
-    }
-    return -1;
-  }
-  function checkDeprecations(opt, callback) {
-    if (!opt || opt.silent) {
-      return;
-    }
-    if (callback) {
-      console.warn("marked(): callback is deprecated since version 5.0.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/using_pro#async");
-    }
-    if (opt.sanitize || opt.sanitizer) {
-      console.warn("marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options");
-    }
-    if (opt.highlight || opt.langPrefix !== "language-") {
-      console.warn("marked(): highlight and langPrefix parameters are deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-highlight.");
-    }
-    if (opt.mangle) {
-      console.warn("marked(): mangle parameter is enabled by default, but is deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install https://www.npmjs.com/package/marked-mangle, or disable by setting `{mangle: false}`.");
-    }
-    if (opt.baseUrl) {
-      console.warn("marked(): baseUrl parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-base-url.");
-    }
-    if (opt.smartypants) {
-      console.warn("marked(): smartypants parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-smartypants.");
-    }
-    if (opt.xhtml) {
-      console.warn("marked(): xhtml parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-xhtml.");
+    /**
+     * Gets the original marked default options.
+     */
+    function _getDefaults() {
+        return {
+            async: false,
+            baseUrl: null,
+            breaks: false,
+            extensions: null,
+            gfm: true,
+            headerIds: false,
+            headerPrefix: '',
+            highlight: null,
+            hooks: null,
+            langPrefix: 'language-',
+            mangle: false,
+            pedantic: false,
+            renderer: null,
+            sanitize: false,
+            sanitizer: null,
+            silent: false,
+            smartypants: false,
+            tokenizer: null,
+            walkTokens: null,
+            xhtml: false
+        };
     }
-    if (opt.headerIds || opt.headerPrefix) {
-      console.warn("marked(): headerIds and headerPrefix parameters enabled by default, but are deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install  https://www.npmjs.com/package/marked-gfm-heading-id, or disable by setting `{headerIds: false}`.");
+    exports.defaults = _getDefaults();
+    function changeDefaults(newDefaults) {
+        exports.defaults = newDefaults;
     }
-  }
 
-  // src/Tokenizer.ts
-  function outputLink(cap, link, raw, lexer2) {
-    const href = link.href;
-    const title = link.title ? escape(link.title) : null;
-    const text = cap[1].replace(/\\([\[\]])/g, "$1");
-    if (cap[0].charAt(0) !== "!") {
-      lexer2.state.inLink = true;
-      const token = {
-        type: "link",
-        raw,
-        href,
-        title,
-        text,
-        tokens: lexer2.inlineTokens(text)
-      };
-      lexer2.state.inLink = false;
-      return token;
-    }
-    return {
-      type: "image",
-      raw,
-      href,
-      title,
-      text: escape(text)
+    /**
+     * Helpers
+     */
+    const escapeTest = /[&<>"']/;
+    const escapeReplace = new RegExp(escapeTest.source, 'g');
+    const escapeTestNoEncode = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/;
+    const escapeReplaceNoEncode = new RegExp(escapeTestNoEncode.source, 'g');
+    const escapeReplacements = {
+        '&': '&amp;',
+        '<': '&lt;',
+        '>': '&gt;',
+        '"': '&quot;',
+        "'": '&#39;'
     };
-  }
-  function indentCodeCompensation(raw, text) {
-    const matchIndentToCode = raw.match(/^(\s+)(?:```)/);
-    if (matchIndentToCode === null) {
-      return text;
-    }
-    const indentToCode = matchIndentToCode[1];
-    return text.split("\n").map((node) => {
-      const matchIndentInNode = node.match(/^\s+/);
-      if (matchIndentInNode === null) {
-        return node;
-      }
-      const [indentInNode] = matchIndentInNode;
-      if (indentInNode.length >= indentToCode.length) {
-        return node.slice(indentToCode.length);
-      }
-      return node;
-    }).join("\n");
-  }
-  var _Tokenizer = class {
-    constructor(options2) {
-      this.options = options2 || _defaults;
-    }
-    space(src) {
-      const cap = this.rules.block.newline.exec(src);
-      if (cap && cap[0].length > 0) {
-        return {
-          type: "space",
-          raw: cap[0]
-        };
-      }
+    const getEscapeReplacement = (ch) => escapeReplacements[ch];
+    function escape(html, encode) {
+        if (encode) {
+            if (escapeTest.test(html)) {
+                return html.replace(escapeReplace, getEscapeReplacement);
+            }
+        }
+        else {
+            if (escapeTestNoEncode.test(html)) {
+                return html.replace(escapeReplaceNoEncode, getEscapeReplacement);
+            }
+        }
+        return html;
     }
-    code(src) {
-      const cap = this.rules.block.code.exec(src);
-      if (cap) {
-        const text = cap[0].replace(/^ {1,4}/gm, "");
-        return {
-          type: "code",
-          raw: cap[0],
-          codeBlockStyle: "indented",
-          text: !this.options.pedantic ? rtrim(text, "\n") : text
-        };
-      }
+    const unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig;
+    function unescape(html) {
+        // explicitly match decimal, hex, and named HTML entities
+        return html.replace(unescapeTest, (_, n) => {
+            n = n.toLowerCase();
+            if (n === 'colon')
+                return ':';
+            if (n.charAt(0) === '#') {
+                return n.charAt(1) === 'x'
+                    ? String.fromCharCode(parseInt(n.substring(2), 16))
+                    : String.fromCharCode(+n.substring(1));
+            }
+            return '';
+        });
     }
-    fences(src) {
-      const cap = this.rules.block.fences.exec(src);
-      if (cap) {
-        const raw = cap[0];
-        const text = indentCodeCompensation(raw, cap[3] || "");
-        return {
-          type: "code",
-          raw,
-          lang: cap[2] ? cap[2].trim().replace(this.rules.inline._escapes, "$1") : cap[2],
-          text
+    const caret = /(^|[^\[])\^/g;
+    function edit(regex, opt) {
+        regex = typeof regex === 'string' ? regex : regex.source;
+        opt = opt || '';
+        const obj = {
+            replace: (name, val) => {
+                val = typeof val === 'object' && 'source' in val ? val.source : val;
+                val = val.replace(caret, '$1');
+                regex = regex.replace(name, val);
+                return obj;
+            },
+            getRegex: () => {
+                return new RegExp(regex, opt);
+            }
         };
-      }
+        return obj;
     }
-    heading(src) {
-      const cap = this.rules.block.heading.exec(src);
-      if (cap) {
-        let text = cap[2].trim();
-        if (/#$/.test(text)) {
-          const trimmed = rtrim(text, "#");
-          if (this.options.pedantic) {
-            text = trimmed.trim();
-          } else if (!trimmed || / $/.test(trimmed)) {
-            text = trimmed.trim();
-          }
+    const nonWordAndColonTest = /[^\w:]/g;
+    const originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
+    function cleanUrl(sanitize, base, href) {
+        if (sanitize) {
+            let prot;
+            try {
+                prot = decodeURIComponent(unescape(href))
+                    .replace(nonWordAndColonTest, '')
+                    .toLowerCase();
+            }
+            catch (e) {
+                return null;
+            }
+            if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
+                return null;
+            }
         }
-        return {
-          type: "heading",
-          raw: cap[0],
-          depth: cap[1].length,
-          text,
-          tokens: this.lexer.inline(text)
-        };
-      }
-    }
-    hr(src) {
-      const cap = this.rules.block.hr.exec(src);
-      if (cap) {
-        return {
-          type: "hr",
-          raw: cap[0]
-        };
-      }
+        if (base && !originIndependentUrl.test(href)) {
+            href = resolveUrl(base, href);
+        }
+        try {
+            href = encodeURI(href).replace(/%25/g, '%');
+        }
+        catch (e) {
+            return null;
+        }
+        return href;
     }
-    blockquote(src) {
-      const cap = this.rules.block.blockquote.exec(src);
-      if (cap) {
-        const text = cap[0].replace(/^ *>[ \t]?/gm, "");
-        const top = this.lexer.state.top;
-        this.lexer.state.top = true;
-        const tokens = this.lexer.blockTokens(text);
-        this.lexer.state.top = top;
-        return {
-          type: "blockquote",
-          raw: cap[0],
-          tokens,
-          text
-        };
-      }
+    const baseUrls = {};
+    const justDomain = /^[^:]+:\/*[^/]*$/;
+    const protocol = /^([^:]+:)[\s\S]*$/;
+    const domain = /^([^:]+:\/*[^/]*)[\s\S]*$/;
+    function resolveUrl(base, href) {
+        if (!baseUrls[' ' + base]) {
+            // we can ignore everything in base after the last slash of its path component,
+            // but we might need to add _that_
+            // https://tools.ietf.org/html/rfc3986#section-3
+            if (justDomain.test(base)) {
+                baseUrls[' ' + base] = base + '/';
+            }
+            else {
+                baseUrls[' ' + base] = rtrim(base, '/', true);
+            }
+        }
+        base = baseUrls[' ' + base];
+        const relativeBase = base.indexOf(':') === -1;
+        if (href.substring(0, 2) === '//') {
+            if (relativeBase) {
+                return href;
+            }
+            return base.replace(protocol, '$1') + href;
+        }
+        else if (href.charAt(0) === '/') {
+            if (relativeBase) {
+                return href;
+            }
+            return base.replace(domain, '$1') + href;
+        }
+        else {
+            return base + href;
+        }
+    }
+    const noopTest = { exec: () => null };
+    function splitCells(tableRow, count) {
+        // ensure that every cell-delimiting pipe has a space
+        // before it to distinguish it from an escaped pipe
+        const row = tableRow.replace(/\|/g, (match, offset, str) => {
+            let escaped = false, curr = offset;
+            while (--curr >= 0 && str[curr] === '\\')
+                escaped = !escaped;
+            if (escaped) {
+                // odd number of slashes means | is escaped
+                // so we leave it alone
+                return '|';
+            }
+            else {
+                // add space before unescaped |
+                return ' |';
+            }
+        }), cells = row.split(/ \|/);
+        let i = 0;
+        // First/last cell in a row cannot be empty if it has no leading/trailing pipe
+        if (!cells[0].trim()) {
+            cells.shift();
+        }
+        if (cells.length > 0 && !cells[cells.length - 1].trim()) {
+            cells.pop();
+        }
+        if (cells.length > count) {
+            cells.splice(count);
+        }
+        else {
+            while (cells.length < count)
+                cells.push('');
+        }
+        for (; i < cells.length; i++) {
+            // leading or trailing whitespace is ignored per the gfm spec
+            cells[i] = cells[i].trim().replace(/\\\|/g, '|');
+        }
+        return cells;
     }
-    list(src) {
-      let cap = this.rules.block.list.exec(src);
-      if (cap) {
-        let raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine, line, nextLine, rawLine, itemContents, endEarly;
-        let bull = cap[1].trim();
-        const isordered = bull.length > 1;
-        const list = {
-          type: "list",
-          raw: "",
-          ordered: isordered,
-          start: isordered ? +bull.slice(0, -1) : "",
-          loose: false,
-          items: []
-        };
-        bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`;
-        if (this.options.pedantic) {
-          bull = isordered ? bull : "[*+-]";
-        }
-        const itemRegex = new RegExp(`^( {0,3}${bull})((?:[	 ][^\\n]*)?(?:\\n|$))`);
-        while (src) {
-          endEarly = false;
-          if (!(cap = itemRegex.exec(src))) {
-            break;
-          }
-          if (this.rules.block.hr.test(src)) {
-            break;
-          }
-          raw = cap[0];
-          src = src.substring(raw.length);
-          line = cap[2].split("\n", 1)[0].replace(/^\t+/, (t) => " ".repeat(3 * t.length));
-          nextLine = src.split("\n", 1)[0];
-          if (this.options.pedantic) {
-            indent = 2;
-            itemContents = line.trimLeft();
-          } else {
-            indent = cap[2].search(/[^ ]/);
-            indent = indent > 4 ? 1 : indent;
-            itemContents = line.slice(indent);
-            indent += cap[1].length;
-          }
-          blankLine = false;
-          if (!line && /^ *$/.test(nextLine)) {
-            raw += nextLine + "\n";
-            src = src.substring(nextLine.length + 1);
-            endEarly = true;
-          }
-          if (!endEarly) {
-            const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ 	][^\\n]*)?(?:\\n|$))`);
-            const hrRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`);
-            const fencesBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\`\`\`|~~~)`);
-            const headingBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`);
-            while (src) {
-              rawLine = src.split("\n", 1)[0];
-              nextLine = rawLine;
-              if (this.options.pedantic) {
-                nextLine = nextLine.replace(/^ {1,4}(?=( {4})*[^ ])/g, "  ");
-              }
-              if (fencesBeginRegex.test(nextLine)) {
-                break;
-              }
-              if (headingBeginRegex.test(nextLine)) {
-                break;
-              }
-              if (nextBulletRegex.test(nextLine)) {
-                break;
-              }
-              if (hrRegex.test(src)) {
+    /**
+     * Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').
+     * /c*$/ is vulnerable to REDOS.
+     *
+     * @param str
+     * @param c
+     * @param invert Remove suffix of non-c chars instead. Default falsey.
+     */
+    function rtrim(str, c, invert) {
+        const l = str.length;
+        if (l === 0) {
+            return '';
+        }
+        // Length of suffix matching the invert condition.
+        let suffLen = 0;
+        // Step left until we fail to match the invert condition.
+        while (suffLen < l) {
+            const currChar = str.charAt(l - suffLen - 1);
+            if (currChar === c && !invert) {
+                suffLen++;
+            }
+            else if (currChar !== c && invert) {
+                suffLen++;
+            }
+            else {
                 break;
-              }
-              if (nextLine.search(/[^ ]/) >= indent || !nextLine.trim()) {
-                itemContents += "\n" + nextLine.slice(indent);
-              } else {
-                if (blankLine) {
-                  break;
-                }
-                if (line.search(/[^ ]/) >= 4) {
-                  break;
-                }
-                if (fencesBeginRegex.test(line)) {
-                  break;
-                }
-                if (headingBeginRegex.test(line)) {
-                  break;
-                }
-                if (hrRegex.test(line)) {
-                  break;
-                }
-                itemContents += "\n" + nextLine;
-              }
-              if (!blankLine && !nextLine.trim()) {
-                blankLine = true;
-              }
-              raw += rawLine + "\n";
-              src = src.substring(rawLine.length + 1);
-              line = nextLine.slice(indent);
-            }
-          }
-          if (!list.loose) {
-            if (endsWithBlankLine) {
-              list.loose = true;
-            } else if (/\n *\n *$/.test(raw)) {
-              endsWithBlankLine = true;
-            }
-          }
-          if (this.options.gfm) {
-            istask = /^\[[ xX]\] /.exec(itemContents);
-            if (istask) {
-              ischecked = istask[0] !== "[ ] ";
-              itemContents = itemContents.replace(/^\[[ xX]\] +/, "");
-            }
-          }
-          list.items.push({
-            type: "list_item",
-            raw,
-            task: !!istask,
-            checked: ischecked,
-            loose: false,
-            text: itemContents
-          });
-          list.raw += raw;
-        }
-        list.items[list.items.length - 1].raw = raw.trimRight();
-        list.items[list.items.length - 1].text = itemContents.trimRight();
-        list.raw = list.raw.trimRight();
-        const l = list.items.length;
-        for (i = 0; i < l; i++) {
-          this.lexer.state.top = false;
-          list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);
-          if (!list.loose) {
-            const spacers = list.items[i].tokens.filter((t) => t.type === "space");
-            const hasMultipleLineBreaks = spacers.length > 0 && spacers.some((t) => /\n.*\n/.test(t.raw));
-            list.loose = hasMultipleLineBreaks;
-          }
-        }
-        if (list.loose) {
-          for (i = 0; i < l; i++) {
-            list.items[i].loose = true;
-          }
-        }
-        return list;
-      }
-    }
-    html(src) {
-      const cap = this.rules.block.html.exec(src);
-      if (cap) {
-        const token = {
-          type: "html",
-          block: true,
-          raw: cap[0],
-          pre: !this.options.sanitizer && (cap[1] === "pre" || cap[1] === "script" || cap[1] === "style"),
-          text: cap[0]
-        };
-        if (this.options.sanitize) {
-          const text = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]);
-          const paragraph = token;
-          paragraph.type = "paragraph";
-          paragraph.text = text;
-          paragraph.tokens = this.lexer.inline(text);
-        }
-        return token;
-      }
-    }
-    def(src) {
-      const cap = this.rules.block.def.exec(src);
-      if (cap) {
-        const tag = cap[1].toLowerCase().replace(/\s+/g, " ");
-        const href = cap[2] ? cap[2].replace(/^<(.*)>$/, "$1").replace(this.rules.inline._escapes, "$1") : "";
-        const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline._escapes, "$1") : cap[3];
-        return {
-          type: "def",
-          tag,
-          raw: cap[0],
-          href,
-          title
-        };
-      }
-    }
-    table(src) {
-      const cap = this.rules.block.table.exec(src);
-      if (cap) {
-        const item = {
-          type: "table",
-          // splitCells expects a number as second argument
-          // @ts-expect-error
-          header: splitCells(cap[1]).map((c) => {
-            return { text: c };
-          }),
-          align: cap[2].replace(/^ *|\| *$/g, "").split(/ *\| */),
-          rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, "").split("\n") : []
-        };
-        if (item.header.length === item.align.length) {
-          item.raw = cap[0];
-          let l = item.align.length;
-          let i, j, k, row;
-          for (i = 0; i < l; i++) {
-            if (/^ *-+: *$/.test(item.align[i])) {
-              item.align[i] = "right";
-            } else if (/^ *:-+: *$/.test(item.align[i])) {
-              item.align[i] = "center";
-            } else if (/^ *:-+ *$/.test(item.align[i])) {
-              item.align[i] = "left";
-            } else {
-              item.align[i] = null;
-            }
-          }
-          l = item.rows.length;
-          for (i = 0; i < l; i++) {
-            item.rows[i] = splitCells(item.rows[i], item.header.length).map((c) => {
-              return { text: c };
-            });
-          }
-          l = item.header.length;
-          for (j = 0; j < l; j++) {
-            item.header[j].tokens = this.lexer.inline(item.header[j].text);
-          }
-          l = item.rows.length;
-          for (j = 0; j < l; j++) {
-            row = item.rows[j];
-            for (k = 0; k < row.length; k++) {
-              row[k].tokens = this.lexer.inline(row[k].text);
-            }
-          }
-          return item;
-        }
-      }
-    }
-    lheading(src) {
-      const cap = this.rules.block.lheading.exec(src);
-      if (cap) {
-        return {
-          type: "heading",
-          raw: cap[0],
-          depth: cap[2].charAt(0) === "=" ? 1 : 2,
-          text: cap[1],
-          tokens: this.lexer.inline(cap[1])
-        };
-      }
-    }
-    paragraph(src) {
-      const cap = this.rules.block.paragraph.exec(src);
-      if (cap) {
-        const text = cap[1].charAt(cap[1].length - 1) === "\n" ? cap[1].slice(0, -1) : cap[1];
-        return {
-          type: "paragraph",
-          raw: cap[0],
-          text,
-          tokens: this.lexer.inline(text)
-        };
-      }
-    }
-    text(src) {
-      const cap = this.rules.block.text.exec(src);
-      if (cap) {
-        return {
-          type: "text",
-          raw: cap[0],
-          text: cap[0],
-          tokens: this.lexer.inline(cap[0])
-        };
-      }
-    }
-    escape(src) {
-      const cap = this.rules.inline.escape.exec(src);
-      if (cap) {
-        return {
-          type: "escape",
-          raw: cap[0],
-          text: escape(cap[1])
-        };
-      }
+            }
+        }
+        return str.slice(0, l - suffLen);
     }
-    tag(src) {
-      const cap = this.rules.inline.tag.exec(src);
-      if (cap) {
-        if (!this.lexer.state.inLink && /^<a /i.test(cap[0])) {
-          this.lexer.state.inLink = true;
-        } else if (this.lexer.state.inLink && /^<\/a>/i.test(cap[0])) {
-          this.lexer.state.inLink = false;
-        }
-        if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
-          this.lexer.state.inRawBlock = true;
-        } else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
-          this.lexer.state.inRawBlock = false;
+    function findClosingBracket(str, b) {
+        if (str.indexOf(b[1]) === -1) {
+            return -1;
         }
-        return {
-          type: this.options.sanitize ? "text" : "html",
-          raw: cap[0],
-          inLink: this.lexer.state.inLink,
-          inRawBlock: this.lexer.state.inRawBlock,
-          block: false,
-          text: this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0]
-        };
-      }
+        const l = str.length;
+        let level = 0, i = 0;
+        for (; i < l; i++) {
+            if (str[i] === '\\') {
+                i++;
+            }
+            else if (str[i] === b[0]) {
+                level++;
+            }
+            else if (str[i] === b[1]) {
+                level--;
+                if (level < 0) {
+                    return i;
+                }
+            }
+        }
+        return -1;
     }
-    link(src) {
-      const cap = this.rules.inline.link.exec(src);
-      if (cap) {
-        const trimmedUrl = cap[2].trim();
-        if (!this.options.pedantic && /^</.test(trimmedUrl)) {
-          if (!/>$/.test(trimmedUrl)) {
+    function checkDeprecations(opt, callback) {
+        if (!opt || opt.silent) {
             return;
-          }
-          const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), "\\");
-          if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {
-            return;
-          }
-        } else {
-          const lastParenIndex = findClosingBracket(cap[2], "()");
-          if (lastParenIndex > -1) {
-            const start = cap[0].indexOf("!") === 0 ? 5 : 4;
-            const linkLen = start + cap[1].length + lastParenIndex;
-            cap[2] = cap[2].substring(0, lastParenIndex);
-            cap[0] = cap[0].substring(0, linkLen).trim();
-            cap[3] = "";
-          }
-        }
-        let href = cap[2];
-        let title = "";
-        if (this.options.pedantic) {
-          const link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
-          if (link) {
-            href = link[1];
-            title = link[3];
-          }
-        } else {
-          title = cap[3] ? cap[3].slice(1, -1) : "";
-        }
-        href = href.trim();
-        if (/^</.test(href)) {
-          if (this.options.pedantic && !/>$/.test(trimmedUrl)) {
-            href = href.slice(1);
-          } else {
-            href = href.slice(1, -1);
-          }
-        }
-        return outputLink(cap, {
-          href: href ? href.replace(this.rules.inline._escapes, "$1") : href,
-          title: title ? title.replace(this.rules.inline._escapes, "$1") : title
-        }, cap[0], this.lexer);
-      }
-    }
-    reflink(src, links) {
-      let cap;
-      if ((cap = this.rules.inline.reflink.exec(src)) || (cap = this.rules.inline.nolink.exec(src))) {
-        let link = (cap[2] || cap[1]).replace(/\s+/g, " ");
-        link = links[link.toLowerCase()];
-        if (!link) {
-          const text = cap[0].charAt(0);
-          return {
-            type: "text",
-            raw: text,
-            text
-          };
-        }
-        return outputLink(cap, link, cap[0], this.lexer);
-      }
+        }
+        if (callback) {
+            console.warn('marked(): callback is deprecated since version 5.0.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/using_pro#async');
+        }
+        if (opt.sanitize || opt.sanitizer) {
+            console.warn('marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options');
+        }
+        if (opt.highlight || opt.langPrefix !== 'language-') {
+            console.warn('marked(): highlight and langPrefix parameters are deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-highlight.');
+        }
+        if (opt.mangle) {
+            console.warn('marked(): mangle parameter is enabled by default, but is deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install https://www.npmjs.com/package/marked-mangle, or disable by setting `{mangle: false}`.');
+        }
+        if (opt.baseUrl) {
+            console.warn('marked(): baseUrl parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-base-url.');
+        }
+        if (opt.smartypants) {
+            console.warn('marked(): smartypants parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-smartypants.');
+        }
+        if (opt.xhtml) {
+            console.warn('marked(): xhtml parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-xhtml.');
+        }
+        if (opt.headerIds || opt.headerPrefix) {
+            console.warn('marked(): headerIds and headerPrefix parameters enabled by default, but are deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install  https://www.npmjs.com/package/marked-gfm-heading-id, or disable by setting `{headerIds: false}`.');
+        }
     }
-    emStrong(src, maskedSrc, prevChar = "") {
-      let match = this.rules.inline.emStrong.lDelim.exec(src);
-      if (!match)
-        return;
-      if (match[3] && prevChar.match(/[\p{L}\p{N}]/u))
-        return;
-      const nextChar = match[1] || match[2] || "";
-      if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) {
-        const lLength = match[0].length - 1;
-        let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;
-        const endReg = match[0][0] === "*" ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;
-        endReg.lastIndex = 0;
-        maskedSrc = maskedSrc.slice(-1 * src.length + lLength);
-        while ((match = endReg.exec(maskedSrc)) != null) {
-          rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
-          if (!rDelim)
-            continue;
-          rLength = rDelim.length;
-          if (match[3] || match[4]) {
-            delimTotal += rLength;
-            continue;
-          } else if (match[5] || match[6]) {
-            if (lLength % 3 && !((lLength + rLength) % 3)) {
-              midDelimTotal += rLength;
-              continue;
-            }
-          }
-          delimTotal -= rLength;
-          if (delimTotal > 0)
-            continue;
-          rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
-          const raw = src.slice(0, lLength + match.index + rLength + 1);
-          if (Math.min(lLength, rLength) % 2) {
-            const text2 = raw.slice(1, -1);
-            return {
-              type: "em",
-              raw,
-              text: text2,
-              tokens: this.lexer.inlineTokens(text2)
+
+    function outputLink(cap, link, raw, lexer) {
+        const href = link.href;
+        const title = link.title ? escape(link.title) : null;
+        const text = cap[1].replace(/\\([\[\]])/g, '$1');
+        if (cap[0].charAt(0) !== '!') {
+            lexer.state.inLink = true;
+            const token = {
+                type: 'link',
+                raw,
+                href,
+                title,
+                text,
+                tokens: lexer.inlineTokens(text)
             };
-          }
-          const text = raw.slice(2, -2);
-          return {
-            type: "strong",
-            raw,
-            text,
-            tokens: this.lexer.inlineTokens(text)
-          };
+            lexer.state.inLink = false;
+            return token;
         }
-      }
-    }
-    codespan(src) {
-      const cap = this.rules.inline.code.exec(src);
-      if (cap) {
-        let text = cap[2].replace(/\n/g, " ");
-        const hasNonSpaceChars = /[^ ]/.test(text);
-        const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text);
-        if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
-          text = text.substring(1, text.length - 1);
-        }
-        text = escape(text, true);
         return {
-          type: "codespan",
-          raw: cap[0],
-          text
-        };
-      }
-    }
-    br(src) {
-      const cap = this.rules.inline.br.exec(src);
-      if (cap) {
-        return {
-          type: "br",
-          raw: cap[0]
+            type: 'image',
+            raw,
+            href,
+            title,
+            text: escape(text)
         };
-      }
     }
-    del(src) {
-      const cap = this.rules.inline.del.exec(src);
-      if (cap) {
-        return {
-          type: "del",
-          raw: cap[0],
-          text: cap[2],
-          tokens: this.lexer.inlineTokens(cap[2])
-        };
-      }
+    function indentCodeCompensation(raw, text) {
+        const matchIndentToCode = raw.match(/^(\s+)(?:```)/);
+        if (matchIndentToCode === null) {
+            return text;
+        }
+        const indentToCode = matchIndentToCode[1];
+        return text
+            .split('\n')
+            .map(node => {
+            const matchIndentInNode = node.match(/^\s+/);
+            if (matchIndentInNode === null) {
+                return node;
+            }
+            const [indentInNode] = matchIndentInNode;
+            if (indentInNode.length >= indentToCode.length) {
+                return node.slice(indentToCode.length);
+            }
+            return node;
+        })
+            .join('\n');
     }
-    autolink(src, mangle2) {
-      const cap = this.rules.inline.autolink.exec(src);
-      if (cap) {
-        let text, href;
-        if (cap[2] === "@") {
-          text = escape(this.options.mangle ? mangle2(cap[1]) : cap[1]);
-          href = "mailto:" + text;
-        } else {
-          text = escape(cap[1]);
-          href = text;
+    /**
+     * Tokenizer
+     */
+    class _Tokenizer {
+        options;
+        rules;
+        lexer;
+        constructor(options) {
+            this.options = options || exports.defaults;
+        }
+        space(src) {
+            const cap = this.rules.block.newline.exec(src);
+            if (cap && cap[0].length > 0) {
+                return {
+                    type: 'space',
+                    raw: cap[0]
+                };
+            }
         }
-        return {
-          type: "link",
-          raw: cap[0],
-          text,
-          href,
-          tokens: [
-            {
-              type: "text",
-              raw: text,
-              text
-            }
-          ]
-        };
-      }
-    }
-    url(src, mangle2) {
-      let cap;
-      if (cap = this.rules.inline.url.exec(src)) {
-        let text, href;
-        if (cap[2] === "@") {
-          text = escape(this.options.mangle ? mangle2(cap[0]) : cap[0]);
-          href = "mailto:" + text;
-        } else {
-          let prevCapZero;
-          do {
-            prevCapZero = cap[0];
-            cap[0] = this.rules.inline._backpedal.exec(cap[0])[0];
-          } while (prevCapZero !== cap[0]);
-          text = escape(cap[0]);
-          if (cap[1] === "www.") {
-            href = "http://" + cap[0];
-          } else {
-            href = cap[0];
-          }
+        code(src) {
+            const cap = this.rules.block.code.exec(src);
+            if (cap) {
+                const text = cap[0].replace(/^ {1,4}/gm, '');
+                return {
+                    type: 'code',
+                    raw: cap[0],
+                    codeBlockStyle: 'indented',
+                    text: !this.options.pedantic
+                        ? rtrim(text, '\n')
+                        : text
+                };
+            }
         }
-        return {
-          type: "link",
-          raw: cap[0],
-          text,
-          href,
-          tokens: [
-            {
-              type: "text",
-              raw: text,
-              text
-            }
-          ]
-        };
-      }
-    }
-    inlineText(src, smartypants2) {
-      const cap = this.rules.inline.text.exec(src);
-      if (cap) {
-        let text;
-        if (this.lexer.state.inRawBlock) {
-          text = this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0];
-        } else {
-          text = escape(this.options.smartypants ? smartypants2(cap[0]) : cap[0]);
+        fences(src) {
+            const cap = this.rules.block.fences.exec(src);
+            if (cap) {
+                const raw = cap[0];
+                const text = indentCodeCompensation(raw, cap[3] || '');
+                return {
+                    type: 'code',
+                    raw,
+                    lang: cap[2] ? cap[2].trim().replace(this.rules.inline._escapes, '$1') : cap[2],
+                    text
+                };
+            }
+        }
+        heading(src) {
+            const cap = this.rules.block.heading.exec(src);
+            if (cap) {
+                let text = cap[2].trim();
+                // remove trailing #s
+                if (/#$/.test(text)) {
+                    const trimmed = rtrim(text, '#');
+                    if (this.options.pedantic) {
+                        text = trimmed.trim();
+                    }
+                    else if (!trimmed || / $/.test(trimmed)) {
+                        // CommonMark requires space before trailing #s
+                        text = trimmed.trim();
+                    }
+                }
+                return {
+                    type: 'heading',
+                    raw: cap[0],
+                    depth: cap[1].length,
+                    text,
+                    tokens: this.lexer.inline(text)
+                };
+            }
+        }
+        hr(src) {
+            const cap = this.rules.block.hr.exec(src);
+            if (cap) {
+                return {
+                    type: 'hr',
+                    raw: cap[0]
+                };
+            }
+        }
+        blockquote(src) {
+            const cap = this.rules.block.blockquote.exec(src);
+            if (cap) {
+                const text = cap[0].replace(/^ *>[ \t]?/gm, '');
+                const top = this.lexer.state.top;
+                this.lexer.state.top = true;
+                const tokens = this.lexer.blockTokens(text);
+                this.lexer.state.top = top;
+                return {
+                    type: 'blockquote',
+                    raw: cap[0],
+                    tokens,
+                    text
+                };
+            }
+        }
+        list(src) {
+            let cap = this.rules.block.list.exec(src);
+            if (cap) {
+                let raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine, line, nextLine, rawLine, itemContents, endEarly;
+                let bull = cap[1].trim();
+                const isordered = bull.length > 1;
+                const list = {
+                    type: 'list',
+                    raw: '',
+                    ordered: isordered,
+                    start: isordered ? +bull.slice(0, -1) : '',
+                    loose: false,
+                    items: []
+                };
+                bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`;
+                if (this.options.pedantic) {
+                    bull = isordered ? bull : '[*+-]';
+                }
+                // Get next list item
+                const itemRegex = new RegExp(`^( {0,3}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))`);
+                // Check if current bullet point can start a new List Item
+                while (src) {
+                    endEarly = false;
+                    if (!(cap = itemRegex.exec(src))) {
+                        break;
+                    }
+                    if (this.rules.block.hr.test(src)) { // End list if bullet was actually HR (possibly move into itemRegex?)
+                        break;
+                    }
+                    raw = cap[0];
+                    src = src.substring(raw.length);
+                    line = cap[2].split('\n', 1)[0].replace(/^\t+/, (t) => ' '.repeat(3 * t.length));
+                    nextLine = src.split('\n', 1)[0];
+                    if (this.options.pedantic) {
+                        indent = 2;
+                        itemContents = line.trimLeft();
+                    }
+                    else {
+                        indent = cap[2].search(/[^ ]/); // Find first non-space char
+                        indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent
+                        itemContents = line.slice(indent);
+                        indent += cap[1].length;
+                    }
+                    blankLine = false;
+                    if (!line && /^ *$/.test(nextLine)) { // Items begin with at most one blank line
+                        raw += nextLine + '\n';
+                        src = src.substring(nextLine.length + 1);
+                        endEarly = true;
+                    }
+                    if (!endEarly) {
+                        const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`);
+                        const hrRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`);
+                        const fencesBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\`\`\`|~~~)`);
+                        const headingBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`);
+                        // Check if following lines should be included in List Item
+                        while (src) {
+                            rawLine = src.split('\n', 1)[0];
+                            nextLine = rawLine;
+                            // Re-align to follow commonmark nesting rules
+                            if (this.options.pedantic) {
+                                nextLine = nextLine.replace(/^ {1,4}(?=( {4})*[^ ])/g, '  ');
+                            }
+                            // End list item if found code fences
+                            if (fencesBeginRegex.test(nextLine)) {
+                                break;
+                            }
+                            // End list item if found start of new heading
+                            if (headingBeginRegex.test(nextLine)) {
+                                break;
+                            }
+                            // End list item if found start of new bullet
+                            if (nextBulletRegex.test(nextLine)) {
+                                break;
+                            }
+                            // Horizontal rule found
+                            if (hrRegex.test(src)) {
+                                break;
+                            }
+                            if (nextLine.search(/[^ ]/) >= indent || !nextLine.trim()) { // Dedent if possible
+                                itemContents += '\n' + nextLine.slice(indent);
+                            }
+                            else {
+                                // not enough indentation
+                                if (blankLine) {
+                                    break;
+                                }
+                                // paragraph continuation unless last line was a different block level element
+                                if (line.search(/[^ ]/) >= 4) { // indented code block
+                                    break;
+                                }
+                                if (fencesBeginRegex.test(line)) {
+                                    break;
+                                }
+                                if (headingBeginRegex.test(line)) {
+                                    break;
+                                }
+                                if (hrRegex.test(line)) {
+                                    break;
+                                }
+                                itemContents += '\n' + nextLine;
+                            }
+                            if (!blankLine && !nextLine.trim()) { // Check if current line is blank
+                                blankLine = true;
+                            }
+                            raw += rawLine + '\n';
+                            src = src.substring(rawLine.length + 1);
+                            line = nextLine.slice(indent);
+                        }
+                    }
+                    if (!list.loose) {
+                        // If the previous item ended with a blank line, the list is loose
+                        if (endsWithBlankLine) {
+                            list.loose = true;
+                        }
+                        else if (/\n *\n *$/.test(raw)) {
+                            endsWithBlankLine = true;
+                        }
+                    }
+                    // Check for task list items
+                    if (this.options.gfm) {
+                        istask = /^\[[ xX]\] /.exec(itemContents);
+                        if (istask) {
+                            ischecked = istask[0] !== '[ ] ';
+                            itemContents = itemContents.replace(/^\[[ xX]\] +/, '');
+                        }
+                    }
+                    list.items.push({
+                        type: 'list_item',
+                        raw,
+                        task: !!istask,
+                        checked: ischecked,
+                        loose: false,
+                        text: itemContents
+                    });
+                    list.raw += raw;
+                }
+                // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic
+                list.items[list.items.length - 1].raw = raw.trimRight();
+                list.items[list.items.length - 1].text = itemContents.trimRight();
+                list.raw = list.raw.trimRight();
+                const l = list.items.length;
+                // Item child tokens handled here at end because we needed to have the final item to trim it first
+                for (i = 0; i < l; i++) {
+                    this.lexer.state.top = false;
+                    list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);
+                    if (!list.loose) {
+                        // Check if list should be loose
+                        const spacers = list.items[i].tokens.filter(t => t.type === 'space');
+                        const hasMultipleLineBreaks = spacers.length > 0 && spacers.some(t => /\n.*\n/.test(t.raw));
+                        list.loose = hasMultipleLineBreaks;
+                    }
+                }
+                // Set all items to loose if list is loose
+                if (list.loose) {
+                    for (i = 0; i < l; i++) {
+                        list.items[i].loose = true;
+                    }
+                }
+                return list;
+            }
+        }
+        html(src) {
+            const cap = this.rules.block.html.exec(src);
+            if (cap) {
+                const token = {
+                    type: 'html',
+                    block: true,
+                    raw: cap[0],
+                    pre: !this.options.sanitizer
+                        && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
+                    text: cap[0]
+                };
+                if (this.options.sanitize) {
+                    const text = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]);
+                    const paragraph = token;
+                    paragraph.type = 'paragraph';
+                    paragraph.text = text;
+                    paragraph.tokens = this.lexer.inline(text);
+                }
+                return token;
+            }
+        }
+        def(src) {
+            const cap = this.rules.block.def.exec(src);
+            if (cap) {
+                const tag = cap[1].toLowerCase().replace(/\s+/g, ' ');
+                const href = cap[2] ? cap[2].replace(/^<(.*)>$/, '$1').replace(this.rules.inline._escapes, '$1') : '';
+                const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline._escapes, '$1') : cap[3];
+                return {
+                    type: 'def',
+                    tag,
+                    raw: cap[0],
+                    href,
+                    title
+                };
+            }
+        }
+        table(src) {
+            const cap = this.rules.block.table.exec(src);
+            if (cap) {
+                const item = {
+                    type: 'table',
+                    // splitCells expects a number as second argument
+                    // @ts-expect-error
+                    header: splitCells(cap[1]).map(c => {
+                        return { text: c };
+                    }),
+                    align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
+                    rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : []
+                };
+                if (item.header.length === item.align.length) {
+                    item.raw = cap[0];
+                    let l = item.align.length;
+                    let i, j, k, row;
+                    for (i = 0; i < l; i++) {
+                        if (/^ *-+: *$/.test(item.align[i])) {
+                            item.align[i] = 'right';
+                        }
+                        else if (/^ *:-+: *$/.test(item.align[i])) {
+                            item.align[i] = 'center';
+                        }
+                        else if (/^ *:-+ *$/.test(item.align[i])) {
+                            item.align[i] = 'left';
+                        }
+                        else {
+                            item.align[i] = null;
+                        }
+                    }
+                    l = item.rows.length;
+                    for (i = 0; i < l; i++) {
+                        item.rows[i] = splitCells(item.rows[i], item.header.length).map(c => {
+                            return { text: c };
+                        });
+                    }
+                    // parse child tokens inside headers and cells
+                    // header child tokens
+                    l = item.header.length;
+                    for (j = 0; j < l; j++) {
+                        item.header[j].tokens = this.lexer.inline(item.header[j].text);
+                    }
+                    // cell child tokens
+                    l = item.rows.length;
+                    for (j = 0; j < l; j++) {
+                        row = item.rows[j];
+                        for (k = 0; k < row.length; k++) {
+                            row[k].tokens = this.lexer.inline(row[k].text);
+                        }
+                    }
+                    return item;
+                }
+            }
+        }
+        lheading(src) {
+            const cap = this.rules.block.lheading.exec(src);
+            if (cap) {
+                return {
+                    type: 'heading',
+                    raw: cap[0],
+                    depth: cap[2].charAt(0) === '=' ? 1 : 2,
+                    text: cap[1],
+                    tokens: this.lexer.inline(cap[1])
+                };
+            }
+        }
+        paragraph(src) {
+            const cap = this.rules.block.paragraph.exec(src);
+            if (cap) {
+                const text = cap[1].charAt(cap[1].length - 1) === '\n'
+                    ? cap[1].slice(0, -1)
+                    : cap[1];
+                return {
+                    type: 'paragraph',
+                    raw: cap[0],
+                    text,
+                    tokens: this.lexer.inline(text)
+                };
+            }
+        }
+        text(src) {
+            const cap = this.rules.block.text.exec(src);
+            if (cap) {
+                return {
+                    type: 'text',
+                    raw: cap[0],
+                    text: cap[0],
+                    tokens: this.lexer.inline(cap[0])
+                };
+            }
+        }
+        escape(src) {
+            const cap = this.rules.inline.escape.exec(src);
+            if (cap) {
+                return {
+                    type: 'escape',
+                    raw: cap[0],
+                    text: escape(cap[1])
+                };
+            }
+        }
+        tag(src) {
+            const cap = this.rules.inline.tag.exec(src);
+            if (cap) {
+                if (!this.lexer.state.inLink && /^<a /i.test(cap[0])) {
+                    this.lexer.state.inLink = true;
+                }
+                else if (this.lexer.state.inLink && /^<\/a>/i.test(cap[0])) {
+                    this.lexer.state.inLink = false;
+                }
+                if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
+                    this.lexer.state.inRawBlock = true;
+                }
+                else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
+                    this.lexer.state.inRawBlock = false;
+                }
+                return {
+                    type: this.options.sanitize
+                        ? 'text'
+                        : 'html',
+                    raw: cap[0],
+                    inLink: this.lexer.state.inLink,
+                    inRawBlock: this.lexer.state.inRawBlock,
+                    block: false,
+                    text: this.options.sanitize
+                        ? (this.options.sanitizer
+                            ? this.options.sanitizer(cap[0])
+                            : escape(cap[0]))
+                        : cap[0]
+                };
+            }
+        }
+        link(src) {
+            const cap = this.rules.inline.link.exec(src);
+            if (cap) {
+                const trimmedUrl = cap[2].trim();
+                if (!this.options.pedantic && /^</.test(trimmedUrl)) {
+                    // commonmark requires matching angle brackets
+                    if (!(/>$/.test(trimmedUrl))) {
+                        return;
+                    }
+                    // ending angle bracket cannot be escaped
+                    const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\');
+                    if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {
+                        return;
+                    }
+                }
+                else {
+                    // find closing parenthesis
+                    const lastParenIndex = findClosingBracket(cap[2], '()');
+                    if (lastParenIndex > -1) {
+                        const start = cap[0].indexOf('!') === 0 ? 5 : 4;
+                        const linkLen = start + cap[1].length + lastParenIndex;
+                        cap[2] = cap[2].substring(0, lastParenIndex);
+                        cap[0] = cap[0].substring(0, linkLen).trim();
+                        cap[3] = '';
+                    }
+                }
+                let href = cap[2];
+                let title = '';
+                if (this.options.pedantic) {
+                    // split pedantic href and title
+                    const link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
+                    if (link) {
+                        href = link[1];
+                        title = link[3];
+                    }
+                }
+                else {
+                    title = cap[3] ? cap[3].slice(1, -1) : '';
+                }
+                href = href.trim();
+                if (/^</.test(href)) {
+                    if (this.options.pedantic && !(/>$/.test(trimmedUrl))) {
+                        // pedantic allows starting angle bracket without ending angle bracket
+                        href = href.slice(1);
+                    }
+                    else {
+                        href = href.slice(1, -1);
+                    }
+                }
+                return outputLink(cap, {
+                    href: href ? href.replace(this.rules.inline._escapes, '$1') : href,
+                    title: title ? title.replace(this.rules.inline._escapes, '$1') : title
+                }, cap[0], this.lexer);
+            }
+        }
+        reflink(src, links) {
+            let cap;
+            if ((cap = this.rules.inline.reflink.exec(src))
+                || (cap = this.rules.inline.nolink.exec(src))) {
+                let link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
+                link = links[link.toLowerCase()];
+                if (!link) {
+                    const text = cap[0].charAt(0);
+                    return {
+                        type: 'text',
+                        raw: text,
+                        text
+                    };
+                }
+                return outputLink(cap, link, cap[0], this.lexer);
+            }
+        }
+        emStrong(src, maskedSrc, prevChar = '') {
+            let match = this.rules.inline.emStrong.lDelim.exec(src);
+            if (!match)
+                return;
+            // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well
+            if (match[3] && prevChar.match(/[\p{L}\p{N}]/u))
+                return;
+            const nextChar = match[1] || match[2] || '';
+            if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) {
+                const lLength = match[0].length - 1;
+                let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;
+                const endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;
+                endReg.lastIndex = 0;
+                // Clip maskedSrc to same section of string as src (move to lexer?)
+                maskedSrc = maskedSrc.slice(-1 * src.length + lLength);
+                while ((match = endReg.exec(maskedSrc)) != null) {
+                    rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
+                    if (!rDelim)
+                        continue; // skip single * in __abc*abc__
+                    rLength = rDelim.length;
+                    if (match[3] || match[4]) { // found another Left Delim
+                        delimTotal += rLength;
+                        continue;
+                    }
+                    else if (match[5] || match[6]) { // either Left or Right Delim
+                        if (lLength % 3 && !((lLength + rLength) % 3)) {
+                            midDelimTotal += rLength;
+                            continue; // CommonMark Emphasis Rules 9-10
+                        }
+                    }
+                    delimTotal -= rLength;
+                    if (delimTotal > 0)
+                        continue; // Haven't found enough closing delimiters
+                    // Remove extra characters. *a*** -> *a*
+                    rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
+                    const raw = src.slice(0, lLength + match.index + rLength + 1);
+                    // Create `em` if smallest delimiter has odd char count. *a***
+                    if (Math.min(lLength, rLength) % 2) {
+                        const text = raw.slice(1, -1);
+                        return {
+                            type: 'em',
+                            raw,
+                            text,
+                            tokens: this.lexer.inlineTokens(text)
+                        };
+                    }
+                    // Create 'strong' if smallest delimiter has even char count. **a***
+                    const text = raw.slice(2, -2);
+                    return {
+                        type: 'strong',
+                        raw,
+                        text,
+                        tokens: this.lexer.inlineTokens(text)
+                    };
+                }
+            }
+        }
+        codespan(src) {
+            const cap = this.rules.inline.code.exec(src);
+            if (cap) {
+                let text = cap[2].replace(/\n/g, ' ');
+                const hasNonSpaceChars = /[^ ]/.test(text);
+                const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text);
+                if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
+                    text = text.substring(1, text.length - 1);
+                }
+                text = escape(text, true);
+                return {
+                    type: 'codespan',
+                    raw: cap[0],
+                    text
+                };
+            }
+        }
+        br(src) {
+            const cap = this.rules.inline.br.exec(src);
+            if (cap) {
+                return {
+                    type: 'br',
+                    raw: cap[0]
+                };
+            }
+        }
+        del(src) {
+            const cap = this.rules.inline.del.exec(src);
+            if (cap) {
+                return {
+                    type: 'del',
+                    raw: cap[0],
+                    text: cap[2],
+                    tokens: this.lexer.inlineTokens(cap[2])
+                };
+            }
+        }
+        autolink(src, mangle) {
+            const cap = this.rules.inline.autolink.exec(src);
+            if (cap) {
+                let text, href;
+                if (cap[2] === '@') {
+                    text = escape(this.options.mangle ? mangle(cap[1]) : cap[1]);
+                    href = 'mailto:' + text;
+                }
+                else {
+                    text = escape(cap[1]);
+                    href = text;
+                }
+                return {
+                    type: 'link',
+                    raw: cap[0],
+                    text,
+                    href,
+                    tokens: [
+                        {
+                            type: 'text',
+                            raw: text,
+                            text
+                        }
+                    ]
+                };
+            }
+        }
+        url(src, mangle) {
+            let cap;
+            if (cap = this.rules.inline.url.exec(src)) {
+                let text, href;
+                if (cap[2] === '@') {
+                    text = escape(this.options.mangle ? mangle(cap[0]) : cap[0]);
+                    href = 'mailto:' + text;
+                }
+                else {
+                    // do extended autolink path validation
+                    let prevCapZero;
+                    do {
+                        prevCapZero = cap[0];
+                        cap[0] = this.rules.inline._backpedal.exec(cap[0])[0];
+                    } while (prevCapZero !== cap[0]);
+                    text = escape(cap[0]);
+                    if (cap[1] === 'www.') {
+                        href = 'http://' + cap[0];
+                    }
+                    else {
+                        href = cap[0];
+                    }
+                }
+                return {
+                    type: 'link',
+                    raw: cap[0],
+                    text,
+                    href,
+                    tokens: [
+                        {
+                            type: 'text',
+                            raw: text,
+                            text
+                        }
+                    ]
+                };
+            }
+        }
+        inlineText(src, smartypants) {
+            const cap = this.rules.inline.text.exec(src);
+            if (cap) {
+                let text;
+                if (this.lexer.state.inRawBlock) {
+                    text = this.options.sanitize ? (this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0])) : cap[0];
+                }
+                else {
+                    text = escape(this.options.smartypants ? smartypants(cap[0]) : cap[0]);
+                }
+                return {
+                    type: 'text',
+                    raw: cap[0],
+                    text
+                };
+            }
         }
-        return {
-          type: "text",
-          raw: cap[0],
-          text
-        };
-      }
     }
-  };
 
-  // src/rules.ts
-  var block = {
-    newline: /^(?: *(?:\n|$))+/,
-    code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
-    fences: /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,
-    hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,
-    heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,
-    blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
-    list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/,
-    html: "^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))",
-    def: /^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,
-    table: noopTest,
-    lheading: /^((?:(?!^bull ).|\n(?!\n|bull ))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
-    // regex template, placeholders will be replaced according to different paragraph
-    // interruption rules of commonmark and the original markdown spec:
-    _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,
-    text: /^[^\n]+/
-  };
-  block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
-  block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;
-  block.def = edit(block.def).replace("label", block._label).replace("title", block._title).getRegex();
-  block.bullet = /(?:[*+-]|\d{1,9}[.)])/;
-  block.listItemStart = edit(/^( *)(bull) */).replace("bull", block.bullet).getRegex();
-  block.list = edit(block.list).replace(/bull/g, block.bullet).replace("hr", "\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def", "\\n+(?=" + block.def.source + ")").getRegex();
-  block._tag = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul";
-  block._comment = /<!--(?!-?>)[\s\S]*?(?:-->|$)/;
-  block.html = edit(block.html, "i").replace("comment", block._comment).replace("tag", block._tag).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
-  block.lheading = edit(block.lheading).replace(/bull/g, block.bullet).getRegex();
-  block.paragraph = edit(block._paragraph).replace("hr", block.hr).replace("heading", " {0,3}#{1,6} ").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", block._tag).getRegex();
-  block.blockquote = edit(block.blockquote).replace("paragraph", block.paragraph).getRegex();
-  block.normal = { ...block };
-  block.gfm = {
-    ...block.normal,
-    table: "^ *([^\\n ].*\\|.*)\\n {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)"
-    // Cells
-  };
-  block.gfm.table = edit(block.gfm.table).replace("hr", block.hr).replace("heading", " {0,3}#{1,6} ").replace("blockquote", " {0,3}>").replace("code", " {4}[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", block._tag).getRegex();
-  block.gfm.paragraph = edit(block._paragraph).replace("hr", block.hr).replace("heading", " {0,3}#{1,6} ").replace("|lheading", "").replace("table", block.gfm.table).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", block._tag).getRegex();
-  block.pedantic = {
-    ...block.normal,
-    html: edit(
-      `^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`
-    ).replace("comment", block._comment).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),
-    def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
-    heading: /^(#{1,6})(.*)(?:\n+|$)/,
-    fences: noopTest,
-    // fences not supported
-    lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
-    paragraph: edit(block.normal._paragraph).replace("hr", block.hr).replace("heading", " *#{1,6} *[^\n]").replace("lheading", block.lheading).replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").getRegex()
-  };
-  var inline = {
-    escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
-    autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
-    url: noopTest,
-    tag: "^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>",
-    // CDATA section
-    link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,
-    reflink: /^!?\[(label)\]\[(ref)\]/,
-    nolink: /^!?\[(ref)\](?:\[\])?/,
-    reflinkSearch: "reflink|nolink(?!\\()",
-    emStrong: {
-      lDelim: /^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/,
-      //         (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left.  (5) and (6) can be either Left or Right.
-      //         | Skip orphan inside strong      | Consume to delim | (1) #***              | (2) a***#, a***                    | (3) #***a, ***a                  | (4) ***#                 | (5) #***#                         | (6) a***a
-      rDelimAst: /^[^_*]*?__[^_*]*?\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\*)[punct](\*+)(?=[\s]|$)|[^punct\s](\*+)(?!\*)(?=[punct\s]|$)|(?!\*)[punct\s](\*+)(?=[^punct\s])|[\s](\*+)(?!\*)(?=[punct])|(?!\*)[punct](\*+)(?!\*)(?=[punct])|[^punct\s](\*+)(?=[^punct\s])/,
-      rDelimUnd: /^[^_*]*?\*\*[^_*]*?_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\s]|$)|[^punct\s](_+)(?!_)(?=[punct\s]|$)|(?!_)[punct\s](_+)(?=[^punct\s])|[\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])/
-      // ^- Not allowed for _
-    },
-    code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
-    br: /^( {2,}|\\)\n(?!\s*$)/,
-    del: noopTest,
-    text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,
-    punctuation: /^((?![*_])[\spunctuation])/
-  };
-  inline._punctuation = "\\p{P}$+<=>`^|~";
-  inline.punctuation = edit(inline.punctuation, "u").replace(/punctuation/g, inline._punctuation).getRegex();
-  inline.blockSkip = /\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g;
-  inline.anyPunctuation = /\\[punct]/g;
-  inline._escapes = /\\([punct])/g;
-  inline._comment = edit(block._comment).replace("(?:-->|$)", "-->").getRegex();
-  inline.emStrong.lDelim = edit(inline.emStrong.lDelim, "u").replace(/punct/g, inline._punctuation).getRegex();
-  inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, "gu").replace(/punct/g, inline._punctuation).getRegex();
-  inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, "gu").replace(/punct/g, inline._punctuation).getRegex();
-  inline.anyPunctuation = edit(inline.anyPunctuation, "gu").replace(/punct/g, inline._punctuation).getRegex();
-  inline._escapes = edit(inline._escapes, "gu").replace(/punct/g, inline._punctuation).getRegex();
-  inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;
-  inline._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])?)+(?![-_])/;
-  inline.autolink = edit(inline.autolink).replace("scheme", inline._scheme).replace("email", inline._email).getRegex();
-  inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;
-  inline.tag = edit(inline.tag).replace("comment", inline._comment).replace("attribute", inline._attribute).getRegex();
-  inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
-  inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/;
-  inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/;
-  inline.link = edit(inline.link).replace("label", inline._label).replace("href", inline._href).replace("title", inline._title).getRegex();
-  inline.reflink = edit(inline.reflink).replace("label", inline._label).replace("ref", block._label).getRegex();
-  inline.nolink = edit(inline.nolink).replace("ref", block._label).getRegex();
-  inline.reflinkSearch = edit(inline.reflinkSearch, "g").replace("reflink", inline.reflink).replace("nolink", inline.nolink).getRegex();
-  inline.normal = { ...inline };
-  inline.pedantic = {
-    ...inline.normal,
-    strong: {
-      start: /^__|\*\*/,
-      middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
-      endAst: /\*\*(?!\*)/g,
-      endUnd: /__(?!_)/g
-    },
-    em: {
-      start: /^_|\*/,
-      middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,
-      endAst: /\*(?!\*)/g,
-      endUnd: /_(?!_)/g
-    },
-    link: edit(/^!?\[(label)\]\((.*?)\)/).replace("label", inline._label).getRegex(),
-    reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", inline._label).getRegex()
-  };
-  inline.gfm = {
-    ...inline.normal,
-    escape: edit(inline.escape).replace("])", "~|])").getRegex(),
-    _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,
-    url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
-    _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
-    del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
-    text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
-  };
-  inline.gfm.url = edit(inline.gfm.url, "i").replace("email", inline.gfm._extended_email).getRegex();
-  inline.breaks = {
-    ...inline.gfm,
-    br: edit(inline.br).replace("{2,}", "*").getRegex(),
-    text: edit(inline.gfm.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex()
-  };
-
-  // src/Lexer.ts
-  function smartypants(text) {
-    return text.replace(/---/g, "\u2014").replace(/--/g, "\u2013").replace(/(^|[-\u2014/(\[{"\s])'/g, "$1\u2018").replace(/'/g, "\u2019").replace(/(^|[-\u2014/(\[{\u2018\s])"/g, "$1\u201C").replace(/"/g, "\u201D").replace(/\.{3}/g, "\u2026");
-  }
-  function mangle(text) {
-    let out = "", i, ch;
-    const l = text.length;
-    for (i = 0; i < l; i++) {
-      ch = text.charCodeAt(i);
-      if (Math.random() > 0.5) {
-        ch = "x" + ch.toString(16);
-      }
-      out += "&#" + ch + ";";
-    }
-    return out;
-  }
-  var _Lexer2 = class __Lexer {
-    constructor(options2) {
-      this.tokens = [];
-      this.tokens.links = /* @__PURE__ */ Object.create(null);
-      this.options = options2 || _defaults;
-      this.options.tokenizer = this.options.tokenizer || new _Tokenizer();
-      this.tokenizer = this.options.tokenizer;
-      this.tokenizer.options = this.options;
-      this.tokenizer.lexer = this;
-      this.inlineQueue = [];
-      this.state = {
-        inLink: false,
-        inRawBlock: false,
-        top: true
-      };
-      const rules = {
-        block: block.normal,
-        inline: inline.normal
-      };
-      if (this.options.pedantic) {
-        rules.block = block.pedantic;
-        rules.inline = inline.pedantic;
-      } else if (this.options.gfm) {
-        rules.block = block.gfm;
-        if (this.options.breaks) {
-          rules.inline = inline.breaks;
-        } else {
-          rules.inline = inline.gfm;
-        }
-      }
-      this.tokenizer.rules = rules;
-    }
     /**
-     * Expose Rules
+     * Block-Level Grammar
      */
-    static get rules() {
-      return {
-        block,
-        inline
-      };
-    }
+    // Not all rules are defined in the object literal
+    // @ts-expect-error
+    const block = {
+        newline: /^(?: *(?:\n|$))+/,
+        code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
+        fences: /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,
+        hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,
+        heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,
+        blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
+        list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/,
+        html: '^ {0,3}(?:' // optional indentation
+            + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
+            + '|comment[^\\n]*(\\n+|$)' // (2)
+            + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3)
+            + '|<![A-Z][\\s\\S]*?(?:>\\n*|$)' // (4)
+            + '|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)' // (5)
+            + '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6)
+            + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag
+            + '|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag
+            + ')',
+        def: /^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,
+        table: noopTest,
+        lheading: /^((?:(?!^bull ).|\n(?!\n|bull ))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
+        // regex template, placeholders will be replaced according to different paragraph
+        // interruption rules of commonmark and the original markdown spec:
+        _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,
+        text: /^[^\n]+/
+    };
+    block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
+    block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;
+    block.def = edit(block.def)
+        .replace('label', block._label)
+        .replace('title', block._title)
+        .getRegex();
+    block.bullet = /(?:[*+-]|\d{1,9}[.)])/;
+    block.listItemStart = edit(/^( *)(bull) */)
+        .replace('bull', block.bullet)
+        .getRegex();
+    block.list = edit(block.list)
+        .replace(/bull/g, block.bullet)
+        .replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))')
+        .replace('def', '\\n+(?=' + block.def.source + ')')
+        .getRegex();
+    block._tag = 'address|article|aside|base|basefont|blockquote|body|caption'
+        + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'
+        + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'
+        + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'
+        + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr'
+        + '|track|ul';
+    block._comment = /<!--(?!-?>)[\s\S]*?(?:-->|$)/;
+    block.html = edit(block.html, 'i')
+        .replace('comment', block._comment)
+        .replace('tag', block._tag)
+        .replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/)
+        .getRegex();
+    block.lheading = edit(block.lheading)
+        .replace(/bull/g, block.bullet) // lists can interrupt
+        .getRegex();
+    block.paragraph = edit(block._paragraph)
+        .replace('hr', block.hr)
+        .replace('heading', ' {0,3}#{1,6} ')
+        .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
+        .replace('|table', '')
+        .replace('blockquote', ' {0,3}>')
+        .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
+        .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
+        .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
+        .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
+        .getRegex();
+    block.blockquote = edit(block.blockquote)
+        .replace('paragraph', block.paragraph)
+        .getRegex();
     /**
-     * Static Lex Method
+     * Normal Block Grammar
      */
-    static lex(src, options2) {
-      const lexer2 = new __Lexer(options2);
-      return lexer2.lex(src);
-    }
+    block.normal = { ...block };
     /**
-     * Static Lex Inline Method
+     * GFM Block Grammar
      */
-    static lexInline(src, options2) {
-      const lexer2 = new __Lexer(options2);
-      return lexer2.inlineTokens(src);
-    }
+    block.gfm = {
+        ...block.normal,
+        table: '^ *([^\\n ].*\\|.*)\\n' // Header
+            + ' {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?' // Align
+            + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells
+    };
+    block.gfm.table = edit(block.gfm.table)
+        .replace('hr', block.hr)
+        .replace('heading', ' {0,3}#{1,6} ')
+        .replace('blockquote', ' {0,3}>')
+        .replace('code', ' {4}[^\\n]')
+        .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
+        .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
+        .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
+        .replace('tag', block._tag) // tables can be interrupted by type (6) html blocks
+        .getRegex();
+    block.gfm.paragraph = edit(block._paragraph)
+        .replace('hr', block.hr)
+        .replace('heading', ' {0,3}#{1,6} ')
+        .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
+        .replace('table', block.gfm.table) // interrupt paragraphs with table
+        .replace('blockquote', ' {0,3}>')
+        .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
+        .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
+        .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
+        .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
+        .getRegex();
     /**
-     * Preprocessing
+     * Pedantic grammar (original John Gruber's loose markdown specification)
      */
-    lex(src) {
-      src = src.replace(/\r\n|\r/g, "\n");
-      this.blockTokens(src, this.tokens);
-      let next;
-      while (next = this.inlineQueue.shift()) {
-        this.inlineTokens(next.src, next.tokens);
-      }
-      return this.tokens;
-    }
-    blockTokens(src, tokens = []) {
-      if (this.options.pedantic) {
-        src = src.replace(/\t/g, "    ").replace(/^ +$/gm, "");
-      } else {
-        src = src.replace(/^( *)(\t+)/gm, (_, leading, tabs) => {
-          return leading + "    ".repeat(tabs.length);
-        });
-      }
-      let token, lastToken, cutSrc, lastParagraphClipped;
-      while (src) {
-        if (this.options.extensions && this.options.extensions.block && this.options.extensions.block.some((extTokenizer) => {
-          if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
-            src = src.substring(token.raw.length);
-            tokens.push(token);
-            return true;
-          }
-          return false;
-        })) {
-          continue;
-        }
-        if (token = this.tokenizer.space(src)) {
-          src = src.substring(token.raw.length);
-          if (token.raw.length === 1 && tokens.length > 0) {
-            tokens[tokens.length - 1].raw += "\n";
-          } else {
-            tokens.push(token);
-          }
-          continue;
-        }
-        if (token = this.tokenizer.code(src)) {
-          src = src.substring(token.raw.length);
-          lastToken = tokens[tokens.length - 1];
-          if (lastToken && (lastToken.type === "paragraph" || lastToken.type === "text")) {
-            lastToken.raw += "\n" + token.raw;
-            lastToken.text += "\n" + token.text;
-            this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
-          } else {
-            tokens.push(token);
-          }
-          continue;
-        }
-        if (token = this.tokenizer.fences(src)) {
-          src = src.substring(token.raw.length);
-          tokens.push(token);
-          continue;
-        }
-        if (token = this.tokenizer.heading(src)) {
-          src = src.substring(token.raw.length);
-          tokens.push(token);
-          continue;
-        }
-        if (token = this.tokenizer.hr(src)) {
-          src = src.substring(token.raw.length);
-          tokens.push(token);
-          continue;
-        }
-        if (token = this.tokenizer.blockquote(src)) {
-          src = src.substring(token.raw.length);
-          tokens.push(token);
-          continue;
-        }
-        if (token = this.tokenizer.list(src)) {
-          src = src.substring(token.raw.length);
-          tokens.push(token);
-          continue;
-        }
-        if (token = this.tokenizer.html(src)) {
-          src = src.substring(token.raw.length);
-          tokens.push(token);
-          continue;
-        }
-        if (token = this.tokenizer.def(src)) {
-          src = src.substring(token.raw.length);
-          lastToken = tokens[tokens.length - 1];
-          if (lastToken && (lastToken.type === "paragraph" || lastToken.type === "text")) {
-            lastToken.raw += "\n" + token.raw;
-            lastToken.text += "\n" + token.raw;
-            this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
-          } else if (!this.tokens.links[token.tag]) {
-            this.tokens.links[token.tag] = {
-              href: token.href,
-              title: token.title
-            };
-          }
-          continue;
-        }
-        if (token = this.tokenizer.table(src)) {
-          src = src.substring(token.raw.length);
-          tokens.push(token);
-          continue;
-        }
-        if (token = this.tokenizer.lheading(src)) {
-          src = src.substring(token.raw.length);
-          tokens.push(token);
-          continue;
-        }
-        cutSrc = src;
-        if (this.options.extensions && this.options.extensions.startBlock) {
-          let startIndex = Infinity;
-          const tempSrc = src.slice(1);
-          let tempStart;
-          this.options.extensions.startBlock.forEach((getStartIndex) => {
-            tempStart = getStartIndex.call({ lexer: this }, tempSrc);
-            if (typeof tempStart === "number" && tempStart >= 0) {
-              startIndex = Math.min(startIndex, tempStart);
-            }
-          });
-          if (startIndex < Infinity && startIndex >= 0) {
-            cutSrc = src.substring(0, startIndex + 1);
-          }
-        }
-        if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
-          lastToken = tokens[tokens.length - 1];
-          if (lastParagraphClipped && lastToken.type === "paragraph") {
-            lastToken.raw += "\n" + token.raw;
-            lastToken.text += "\n" + token.text;
-            this.inlineQueue.pop();
-            this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
-          } else {
-            tokens.push(token);
-          }
-          lastParagraphClipped = cutSrc.length !== src.length;
-          src = src.substring(token.raw.length);
-          continue;
-        }
-        if (token = this.tokenizer.text(src)) {
-          src = src.substring(token.raw.length);
-          lastToken = tokens[tokens.length - 1];
-          if (lastToken && lastToken.type === "text") {
-            lastToken.raw += "\n" + token.raw;
-            lastToken.text += "\n" + token.text;
-            this.inlineQueue.pop();
-            this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
-          } else {
-            tokens.push(token);
-          }
-          continue;
-        }
-        if (src) {
-          const errMsg = "Infinite loop on byte: " + src.charCodeAt(0);
-          if (this.options.silent) {
-            console.error(errMsg);
-            break;
-          } else {
-            throw new Error(errMsg);
-          }
-        }
-      }
-      this.state.top = true;
-      return tokens;
-    }
-    inline(src, tokens = []) {
-      this.inlineQueue.push({ src, tokens });
-      return tokens;
-    }
+    block.pedantic = {
+        ...block.normal,
+        html: edit('^ *(?:comment *(?:\\n|\\s*$)'
+            + '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag
+            + '|<tag(?:"[^"]*"|\'[^\']*\'|\\s[^\'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))')
+            .replace('comment', block._comment)
+            .replace(/tag/g, '(?!(?:'
+            + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'
+            + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'
+            + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b')
+            .getRegex(),
+        def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
+        heading: /^(#{1,6})(.*)(?:\n+|$)/,
+        fences: noopTest,
+        lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
+        paragraph: edit(block.normal._paragraph)
+            .replace('hr', block.hr)
+            .replace('heading', ' *#{1,6} *[^\n]')
+            .replace('lheading', block.lheading)
+            .replace('blockquote', ' {0,3}>')
+            .replace('|fences', '')
+            .replace('|list', '')
+            .replace('|html', '')
+            .getRegex()
+    };
+    /**
+     * Inline-Level Grammar
+     */
+    // Not all rules are defined in the object literal
+    // @ts-expect-error
+    const inline = {
+        escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
+        autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
+        url: noopTest,
+        tag: '^comment'
+            + '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
+            + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
+            + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
+            + '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
+            + '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>',
+        link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,
+        reflink: /^!?\[(label)\]\[(ref)\]/,
+        nolink: /^!?\[(ref)\](?:\[\])?/,
+        reflinkSearch: 'reflink|nolink(?!\\()',
+        emStrong: {
+            lDelim: /^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/,
+            //         (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left.  (5) and (6) can be either Left or Right.
+            //         | Skip orphan inside strong      | Consume to delim | (1) #***              | (2) a***#, a***                    | (3) #***a, ***a                  | (4) ***#                 | (5) #***#                         | (6) a***a
+            rDelimAst: /^[^_*]*?__[^_*]*?\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\*)[punct](\*+)(?=[\s]|$)|[^punct\s](\*+)(?!\*)(?=[punct\s]|$)|(?!\*)[punct\s](\*+)(?=[^punct\s])|[\s](\*+)(?!\*)(?=[punct])|(?!\*)[punct](\*+)(?!\*)(?=[punct])|[^punct\s](\*+)(?=[^punct\s])/,
+            rDelimUnd: /^[^_*]*?\*\*[^_*]*?_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\s]|$)|[^punct\s](_+)(?!_)(?=[punct\s]|$)|(?!_)[punct\s](_+)(?=[^punct\s])|[\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])/ // ^- Not allowed for _
+        },
+        code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
+        br: /^( {2,}|\\)\n(?!\s*$)/,
+        del: noopTest,
+        text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,
+        punctuation: /^((?![*_])[\spunctuation])/
+    };
+    // list of unicode punctuation marks, plus any missing characters from CommonMark spec
+    inline._punctuation = '\\p{P}$+<=>`^|~';
+    inline.punctuation = edit(inline.punctuation, 'u').replace(/punctuation/g, inline._punctuation).getRegex();
+    // sequences em should skip over [title](link), `code`, <html>
+    inline.blockSkip = /\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g;
+    inline.anyPunctuation = /\\[punct]/g;
+    inline._escapes = /\\([punct])/g;
+    inline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex();
+    inline.emStrong.lDelim = edit(inline.emStrong.lDelim, 'u')
+        .replace(/punct/g, inline._punctuation)
+        .getRegex();
+    inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'gu')
+        .replace(/punct/g, inline._punctuation)
+        .getRegex();
+    inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, 'gu')
+        .replace(/punct/g, inline._punctuation)
+        .getRegex();
+    inline.anyPunctuation = edit(inline.anyPunctuation, 'gu')
+        .replace(/punct/g, inline._punctuation)
+        .getRegex();
+    inline._escapes = edit(inline._escapes, 'gu')
+        .replace(/punct/g, inline._punctuation)
+        .getRegex();
+    inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;
+    inline._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])?)+(?![-_])/;
+    inline.autolink = edit(inline.autolink)
+        .replace('scheme', inline._scheme)
+        .replace('email', inline._email)
+        .getRegex();
+    inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;
+    inline.tag = edit(inline.tag)
+        .replace('comment', inline._comment)
+        .replace('attribute', inline._attribute)
+        .getRegex();
+    inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
+    inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/;
+    inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/;
+    inline.link = edit(inline.link)
+        .replace('label', inline._label)
+        .replace('href', inline._href)
+        .replace('title', inline._title)
+        .getRegex();
+    inline.reflink = edit(inline.reflink)
+        .replace('label', inline._label)
+        .replace('ref', block._label)
+        .getRegex();
+    inline.nolink = edit(inline.nolink)
+        .replace('ref', block._label)
+        .getRegex();
+    inline.reflinkSearch = edit(inline.reflinkSearch, 'g')
+        .replace('reflink', inline.reflink)
+        .replace('nolink', inline.nolink)
+        .getRegex();
     /**
-     * Lexing/Compiling
+     * Normal Inline Grammar
      */
-    inlineTokens(src, tokens = []) {
-      let token, lastToken, cutSrc;
-      let maskedSrc = src;
-      let match;
-      let keepPrevChar, prevChar;
-      if (this.tokens.links) {
-        const links = Object.keys(this.tokens.links);
-        if (links.length > 0) {
-          while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
-            if (links.includes(match[0].slice(match[0].lastIndexOf("[") + 1, -1))) {
-              maskedSrc = maskedSrc.slice(0, match.index) + "[" + "a".repeat(match[0].length - 2) + "]" + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
-            }
-          }
-        }
-      }
-      while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
-        maskedSrc = maskedSrc.slice(0, match.index) + "[" + "a".repeat(match[0].length - 2) + "]" + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
-      }
-      while ((match = this.tokenizer.rules.inline.anyPunctuation.exec(maskedSrc)) != null) {
-        maskedSrc = maskedSrc.slice(0, match.index) + "++" + maskedSrc.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
-      }
-      while (src) {
-        if (!keepPrevChar) {
-          prevChar = "";
-        }
-        keepPrevChar = false;
-        if (this.options.extensions && this.options.extensions.inline && this.options.extensions.inline.some((extTokenizer) => {
-          if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
-            src = src.substring(token.raw.length);
-            tokens.push(token);
-            return true;
-          }
-          return false;
-        })) {
-          continue;
-        }
-        if (token = this.tokenizer.escape(src)) {
-          src = src.substring(token.raw.length);
-          tokens.push(token);
-          continue;
-        }
-        if (token = this.tokenizer.tag(src)) {
-          src = src.substring(token.raw.length);
-          lastToken = tokens[tokens.length - 1];
-          if (lastToken && token.type === "text" && lastToken.type === "text") {
-            lastToken.raw += token.raw;
-            lastToken.text += token.text;
-          } else {
-            tokens.push(token);
-          }
-          continue;
-        }
-        if (token = this.tokenizer.link(src)) {
-          src = src.substring(token.raw.length);
-          tokens.push(token);
-          continue;
-        }
-        if (token = this.tokenizer.reflink(src, this.tokens.links)) {
-          src = src.substring(token.raw.length);
-          lastToken = tokens[tokens.length - 1];
-          if (lastToken && token.type === "text" && lastToken.type === "text") {
-            lastToken.raw += token.raw;
-            lastToken.text += token.text;
-          } else {
-            tokens.push(token);
-          }
-          continue;
-        }
-        if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
-          src = src.substring(token.raw.length);
-          tokens.push(token);
-          continue;
-        }
-        if (token = this.tokenizer.codespan(src)) {
-          src = src.substring(token.raw.length);
-          tokens.push(token);
-          continue;
-        }
-        if (token = this.tokenizer.br(src)) {
-          src = src.substring(token.raw.length);
-          tokens.push(token);
-          continue;
-        }
-        if (token = this.tokenizer.del(src)) {
-          src = src.substring(token.raw.length);
-          tokens.push(token);
-          continue;
-        }
-        if (token = this.tokenizer.autolink(src, mangle)) {
-          src = src.substring(token.raw.length);
-          tokens.push(token);
-          continue;
-        }
-        if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) {
-          src = src.substring(token.raw.length);
-          tokens.push(token);
-          continue;
-        }
-        cutSrc = src;
-        if (this.options.extensions && this.options.extensions.startInline) {
-          let startIndex = Infinity;
-          const tempSrc = src.slice(1);
-          let tempStart;
-          this.options.extensions.startInline.forEach((getStartIndex) => {
-            tempStart = getStartIndex.call({ lexer: this }, tempSrc);
-            if (typeof tempStart === "number" && tempStart >= 0) {
-              startIndex = Math.min(startIndex, tempStart);
-            }
-          });
-          if (startIndex < Infinity && startIndex >= 0) {
-            cutSrc = src.substring(0, startIndex + 1);
-          }
-        }
-        if (token = this.tokenizer.inlineText(cutSrc, smartypants)) {
-          src = src.substring(token.raw.length);
-          if (token.raw.slice(-1) !== "_") {
-            prevChar = token.raw.slice(-1);
-          }
-          keepPrevChar = true;
-          lastToken = tokens[tokens.length - 1];
-          if (lastToken && lastToken.type === "text") {
-            lastToken.raw += token.raw;
-            lastToken.text += token.text;
-          } else {
-            tokens.push(token);
-          }
-          continue;
-        }
-        if (src) {
-          const errMsg = "Infinite loop on byte: " + src.charCodeAt(0);
-          if (this.options.silent) {
-            console.error(errMsg);
-            break;
-          } else {
-            throw new Error(errMsg);
-          }
-        }
-      }
-      return tokens;
-    }
-  };
-
-  // src/Renderer.ts
-  var _Renderer = class {
-    constructor(options2) {
-      this.options = options2 || _defaults;
-    }
-    code(code, infostring, escaped) {
-      const lang = (infostring || "").match(/\S*/)[0];
-      if (this.options.highlight) {
-        const out = this.options.highlight(code, lang);
-        if (out != null && out !== code) {
-          escaped = true;
-          code = out;
-        }
-      }
-      code = code.replace(/\n$/, "") + "\n";
-      if (!lang) {
-        return "<pre><code>" + (escaped ? code : escape(code, true)) + "</code></pre>\n";
-      }
-      return '<pre><code class="' + this.options.langPrefix + escape(lang) + '">' + (escaped ? code : escape(code, true)) + "</code></pre>\n";
-    }
-    blockquote(quote) {
-      return `<blockquote>
-${quote}</blockquote>
-`;
-    }
-    html(html, block2) {
-      return html;
-    }
-    heading(text, level, raw, slugger) {
-      if (this.options.headerIds) {
-        const id = this.options.headerPrefix + slugger.slug(raw);
-        return `<h${level} id="${id}">${text}</h${level}>
-`;
-      }
-      return `<h${level}>${text}</h${level}>
-`;
-    }
-    hr() {
-      return this.options.xhtml ? "<hr/>\n" : "<hr>\n";
-    }
-    list(body, ordered, start) {
-      const type = ordered ? "ol" : "ul", startatt = ordered && start !== 1 ? ' start="' + start + '"' : "";
-      return "<" + type + startatt + ">\n" + body + "</" + type + ">\n";
-    }
-    listitem(text, task, checked) {
-      return `<li>${text}</li>
-`;
-    }
-    checkbox(checked) {
-      return "<input " + (checked ? 'checked="" ' : "") + 'disabled="" type="checkbox"' + (this.options.xhtml ? " /" : "") + "> ";
-    }
-    paragraph(text) {
-      return `<p>${text}</p>
-`;
-    }
-    table(header, body) {
-      if (body)
-        body = `<tbody>${body}</tbody>`;
-      return "<table>\n<thead>\n" + header + "</thead>\n" + body + "</table>\n";
-    }
-    tablerow(content) {
-      return `<tr>
-${content}</tr>
-`;
-    }
-    tablecell(content, flags) {
-      const type = flags.header ? "th" : "td";
-      const tag = flags.align ? `<${type} align="${flags.align}">` : `<${type}>`;
-      return tag + content + `</${type}>
-`;
-    }
+    inline.normal = { ...inline };
     /**
-     * span level renderer
+     * Pedantic Inline Grammar
      */
-    strong(text) {
-      return `<strong>${text}</strong>`;
-    }
-    em(text) {
-      return `<em>${text}</em>`;
-    }
-    codespan(text) {
-      return `<code>${text}</code>`;
-    }
-    br() {
-      return this.options.xhtml ? "<br/>" : "<br>";
-    }
-    del(text) {
-      return `<del>${text}</del>`;
-    }
-    link(href, title, text) {
-      href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
-      if (href === null) {
-        return text;
-      }
-      let out = '<a href="' + href + '"';
-      if (title) {
-        out += ' title="' + title + '"';
-      }
-      out += ">" + text + "</a>";
-      return out;
-    }
-    image(href, title, text) {
-      href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
-      if (href === null) {
-        return text;
-      }
-      let out = `<img src="${href}" alt="${text}"`;
-      if (title) {
-        out += ` title="${title}"`;
-      }
-      out += this.options.xhtml ? "/>" : ">";
-      return out;
-    }
-    text(text) {
-      return text;
-    }
-  };
-
-  // src/TextRenderer.ts
-  var _TextRenderer = class {
-    // no need for block level renderers
-    strong(text) {
-      return text;
-    }
-    em(text) {
-      return text;
-    }
-    codespan(text) {
-      return text;
-    }
-    del(text) {
-      return text;
-    }
-    html(text) {
-      return text;
-    }
-    text(text) {
-      return text;
-    }
-    link(href, title, text) {
-      return "" + text;
-    }
-    image(href, title, text) {
-      return "" + text;
-    }
-    br() {
-      return "";
-    }
-  };
-
-  // src/Slugger.ts
-  var _Slugger = class {
-    constructor() {
-      this.seen = {};
-    }
-    serialize(value) {
-      return value.toLowerCase().trim().replace(/<[!\/a-z].*?>/ig, "").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, "").replace(/\s/g, "-");
-    }
+    inline.pedantic = {
+        ...inline.normal,
+        strong: {
+            start: /^__|\*\*/,
+            middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
+            endAst: /\*\*(?!\*)/g,
+            endUnd: /__(?!_)/g
+        },
+        em: {
+            start: /^_|\*/,
+            middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,
+            endAst: /\*(?!\*)/g,
+            endUnd: /_(?!_)/g
+        },
+        link: edit(/^!?\[(label)\]\((.*?)\)/)
+            .replace('label', inline._label)
+            .getRegex(),
+        reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/)
+            .replace('label', inline._label)
+            .getRegex()
+    };
     /**
-     * Finds the next safe (unique) slug to use
+     * GFM Inline Grammar
      */
-    getNextSafeSlug(originalSlug, isDryRun) {
-      let slug = originalSlug;
-      let occurenceAccumulator = 0;
-      if (this.seen.hasOwnProperty(slug)) {
-        occurenceAccumulator = this.seen[originalSlug];
-        do {
-          occurenceAccumulator++;
-          slug = originalSlug + "-" + occurenceAccumulator;
-        } while (this.seen.hasOwnProperty(slug));
-      }
-      if (!isDryRun) {
-        this.seen[originalSlug] = occurenceAccumulator;
-        this.seen[slug] = 0;
-      }
-      return slug;
-    }
+    inline.gfm = {
+        ...inline.normal,
+        escape: edit(inline.escape).replace('])', '~|])').getRegex(),
+        _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,
+        url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
+        _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
+        del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
+        text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
+    };
+    inline.gfm.url = edit(inline.gfm.url, 'i')
+        .replace('email', inline.gfm._extended_email)
+        .getRegex();
     /**
-     * Convert string to unique id
+     * GFM + Line Breaks Inline Grammar
      */
-    slug(value, options2 = {}) {
-      const slug = this.serialize(value);
-      return this.getNextSafeSlug(slug, options2.dryrun);
-    }
-  };
+    inline.breaks = {
+        ...inline.gfm,
+        br: edit(inline.br).replace('{2,}', '*').getRegex(),
+        text: edit(inline.gfm.text)
+            .replace('\\b_', '\\b_| {2,}\\n')
+            .replace(/\{2,\}/g, '*')
+            .getRegex()
+    };
 
-  // src/Parser.ts
-  var _Parser = class __Parser {
-    constructor(options2) {
-      this.options = options2 || _defaults;
-      this.options.renderer = this.options.renderer || new _Renderer();
-      this.renderer = this.options.renderer;
-      this.renderer.options = this.options;
-      this.textRenderer = new _TextRenderer();
-      this.slugger = new _Slugger();
-    }
     /**
-     * Static Parse Method
+     * smartypants text replacement
      */
-    static parse(tokens, options2) {
-      const parser2 = new __Parser(options2);
-      return parser2.parse(tokens);
+    function smartypants(text) {
+        return text
+            // em-dashes
+            .replace(/---/g, '\u2014')
+            // en-dashes
+            .replace(/--/g, '\u2013')
+            // opening singles
+            .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
+            // closing singles & apostrophes
+            .replace(/'/g, '\u2019')
+            // opening doubles
+            .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
+            // closing doubles
+            .replace(/"/g, '\u201d')
+            // ellipses
+            .replace(/\.{3}/g, '\u2026');
     }
     /**
-     * Static Parse Inline Method
+     * mangle email addresses
      */
-    static parseInline(tokens, options2) {
-      const parser2 = new __Parser(options2);
-      return parser2.parseInline(tokens);
+    function mangle(text) {
+        let out = '', i, ch;
+        const l = text.length;
+        for (i = 0; i < l; i++) {
+            ch = text.charCodeAt(i);
+            if (Math.random() > 0.5) {
+                ch = 'x' + ch.toString(16);
+            }
+            out += '&#' + ch + ';';
+        }
+        return out;
     }
     /**
-     * Parse Loop
+     * Block Lexer
      */
-    parse(tokens, top = true) {
-      let out = "", i, j, k, l2, l3, row, cell, header, body, token, ordered, start, loose, itemBody, item, checked, task, checkbox, ret;
-      const l = tokens.length;
-      for (i = 0; i < l; i++) {
-        token = tokens[i];
-        if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
-          ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
-          if (ret !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "html", "paragraph", "text"].includes(token.type)) {
-            out += ret || "";
-            continue;
-          }
-        }
-        switch (token.type) {
-          case "space": {
-            continue;
-          }
-          case "hr": {
-            out += this.renderer.hr();
-            continue;
-          }
-          case "heading": {
-            out += this.renderer.heading(
-              this.parseInline(token.tokens),
-              token.depth,
-              unescape(this.parseInline(token.tokens, this.textRenderer)),
-              this.slugger
-            );
-            continue;
-          }
-          case "code": {
-            out += this.renderer.code(
-              token.text,
-              token.lang,
-              !!token.escaped
-            );
-            continue;
-          }
-          case "table": {
-            header = "";
-            cell = "";
-            l2 = token.header.length;
-            for (j = 0; j < l2; j++) {
-              cell += this.renderer.tablecell(
-                this.parseInline(token.header[j].tokens),
-                { header: true, align: token.align[j] }
-              );
-            }
-            header += this.renderer.tablerow(cell);
-            body = "";
-            l2 = token.rows.length;
-            for (j = 0; j < l2; j++) {
-              row = token.rows[j];
-              cell = "";
-              l3 = row.length;
-              for (k = 0; k < l3; k++) {
-                cell += this.renderer.tablecell(
-                  this.parseInline(row[k].tokens),
-                  { header: false, align: token.align[k] }
-                );
-              }
-              body += this.renderer.tablerow(cell);
-            }
-            out += this.renderer.table(header, body);
-            continue;
-          }
-          case "blockquote": {
-            body = this.parse(token.tokens);
-            out += this.renderer.blockquote(body);
-            continue;
-          }
-          case "list": {
-            ordered = token.ordered;
-            start = token.start;
-            loose = token.loose;
-            l2 = token.items.length;
-            body = "";
-            for (j = 0; j < l2; j++) {
-              item = token.items[j];
-              checked = item.checked;
-              task = item.task;
-              itemBody = "";
-              if (item.task) {
-                checkbox = this.renderer.checkbox(!!checked);
-                if (loose) {
-                  if (item.tokens.length > 0 && item.tokens[0].type === "paragraph") {
-                    item.tokens[0].text = checkbox + " " + item.tokens[0].text;
-                    if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === "text") {
-                      item.tokens[0].tokens[0].text = checkbox + " " + item.tokens[0].tokens[0].text;
-                    }
-                  } else {
-                    item.tokens.unshift({
-                      type: "text",
-                      text: checkbox
+    class _Lexer {
+        tokens;
+        options;
+        state;
+        tokenizer;
+        inlineQueue;
+        constructor(options) {
+            // TokenList cannot be created in one go
+            // @ts-expect-error
+            this.tokens = [];
+            this.tokens.links = Object.create(null);
+            this.options = options || exports.defaults;
+            this.options.tokenizer = this.options.tokenizer || new _Tokenizer();
+            this.tokenizer = this.options.tokenizer;
+            this.tokenizer.options = this.options;
+            this.tokenizer.lexer = this;
+            this.inlineQueue = [];
+            this.state = {
+                inLink: false,
+                inRawBlock: false,
+                top: true
+            };
+            const rules = {
+                block: block.normal,
+                inline: inline.normal
+            };
+            if (this.options.pedantic) {
+                rules.block = block.pedantic;
+                rules.inline = inline.pedantic;
+            }
+            else if (this.options.gfm) {
+                rules.block = block.gfm;
+                if (this.options.breaks) {
+                    rules.inline = inline.breaks;
+                }
+                else {
+                    rules.inline = inline.gfm;
+                }
+            }
+            this.tokenizer.rules = rules;
+        }
+        /**
+         * Expose Rules
+         */
+        static get rules() {
+            return {
+                block,
+                inline
+            };
+        }
+        /**
+         * Static Lex Method
+         */
+        static lex(src, options) {
+            const lexer = new _Lexer(options);
+            return lexer.lex(src);
+        }
+        /**
+         * Static Lex Inline Method
+         */
+        static lexInline(src, options) {
+            const lexer = new _Lexer(options);
+            return lexer.inlineTokens(src);
+        }
+        /**
+         * Preprocessing
+         */
+        lex(src) {
+            src = src
+                .replace(/\r\n|\r/g, '\n');
+            this.blockTokens(src, this.tokens);
+            let next;
+            while (next = this.inlineQueue.shift()) {
+                this.inlineTokens(next.src, next.tokens);
+            }
+            return this.tokens;
+        }
+        blockTokens(src, tokens = []) {
+            if (this.options.pedantic) {
+                src = src.replace(/\t/g, '    ').replace(/^ +$/gm, '');
+            }
+            else {
+                src = src.replace(/^( *)(\t+)/gm, (_, leading, tabs) => {
+                    return leading + '    '.repeat(tabs.length);
+                });
+            }
+            let token, lastToken, cutSrc, lastParagraphClipped;
+            while (src) {
+                if (this.options.extensions
+                    && this.options.extensions.block
+                    && this.options.extensions.block.some((extTokenizer) => {
+                        if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
+                            src = src.substring(token.raw.length);
+                            tokens.push(token);
+                            return true;
+                        }
+                        return false;
+                    })) {
+                    continue;
+                }
+                // newline
+                if (token = this.tokenizer.space(src)) {
+                    src = src.substring(token.raw.length);
+                    if (token.raw.length === 1 && tokens.length > 0) {
+                        // if there's a single \n as a spacer, it's terminating the last line,
+                        // so move it there so that we don't get unecessary paragraph tags
+                        tokens[tokens.length - 1].raw += '\n';
+                    }
+                    else {
+                        tokens.push(token);
+                    }
+                    continue;
+                }
+                // code
+                if (token = this.tokenizer.code(src)) {
+                    src = src.substring(token.raw.length);
+                    lastToken = tokens[tokens.length - 1];
+                    // An indented code block cannot interrupt a paragraph.
+                    if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
+                        lastToken.raw += '\n' + token.raw;
+                        lastToken.text += '\n' + token.text;
+                        this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
+                    }
+                    else {
+                        tokens.push(token);
+                    }
+                    continue;
+                }
+                // fences
+                if (token = this.tokenizer.fences(src)) {
+                    src = src.substring(token.raw.length);
+                    tokens.push(token);
+                    continue;
+                }
+                // heading
+                if (token = this.tokenizer.heading(src)) {
+                    src = src.substring(token.raw.length);
+                    tokens.push(token);
+                    continue;
+                }
+                // hr
+                if (token = this.tokenizer.hr(src)) {
+                    src = src.substring(token.raw.length);
+                    tokens.push(token);
+                    continue;
+                }
+                // blockquote
+                if (token = this.tokenizer.blockquote(src)) {
+                    src = src.substring(token.raw.length);
+                    tokens.push(token);
+                    continue;
+                }
+                // list
+                if (token = this.tokenizer.list(src)) {
+                    src = src.substring(token.raw.length);
+                    tokens.push(token);
+                    continue;
+                }
+                // html
+                if (token = this.tokenizer.html(src)) {
+                    src = src.substring(token.raw.length);
+                    tokens.push(token);
+                    continue;
+                }
+                // def
+                if (token = this.tokenizer.def(src)) {
+                    src = src.substring(token.raw.length);
+                    lastToken = tokens[tokens.length - 1];
+                    if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
+                        lastToken.raw += '\n' + token.raw;
+                        lastToken.text += '\n' + token.raw;
+                        this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
+                    }
+                    else if (!this.tokens.links[token.tag]) {
+                        this.tokens.links[token.tag] = {
+                            href: token.href,
+                            title: token.title
+                        };
+                    }
+                    continue;
+                }
+                // table (gfm)
+                if (token = this.tokenizer.table(src)) {
+                    src = src.substring(token.raw.length);
+                    tokens.push(token);
+                    continue;
+                }
+                // lheading
+                if (token = this.tokenizer.lheading(src)) {
+                    src = src.substring(token.raw.length);
+                    tokens.push(token);
+                    continue;
+                }
+                // top-level paragraph
+                // prevent paragraph consuming extensions by clipping 'src' to extension start
+                cutSrc = src;
+                if (this.options.extensions && this.options.extensions.startBlock) {
+                    let startIndex = Infinity;
+                    const tempSrc = src.slice(1);
+                    let tempStart;
+                    this.options.extensions.startBlock.forEach((getStartIndex) => {
+                        tempStart = getStartIndex.call({ lexer: this }, tempSrc);
+                        if (typeof tempStart === 'number' && tempStart >= 0) {
+                            startIndex = Math.min(startIndex, tempStart);
+                        }
+                    });
+                    if (startIndex < Infinity && startIndex >= 0) {
+                        cutSrc = src.substring(0, startIndex + 1);
+                    }
+                }
+                if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
+                    lastToken = tokens[tokens.length - 1];
+                    if (lastParagraphClipped && lastToken.type === 'paragraph') {
+                        lastToken.raw += '\n' + token.raw;
+                        lastToken.text += '\n' + token.text;
+                        this.inlineQueue.pop();
+                        this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
+                    }
+                    else {
+                        tokens.push(token);
+                    }
+                    lastParagraphClipped = (cutSrc.length !== src.length);
+                    src = src.substring(token.raw.length);
+                    continue;
+                }
+                // text
+                if (token = this.tokenizer.text(src)) {
+                    src = src.substring(token.raw.length);
+                    lastToken = tokens[tokens.length - 1];
+                    if (lastToken && lastToken.type === 'text') {
+                        lastToken.raw += '\n' + token.raw;
+                        lastToken.text += '\n' + token.text;
+                        this.inlineQueue.pop();
+                        this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
+                    }
+                    else {
+                        tokens.push(token);
+                    }
+                    continue;
+                }
+                if (src) {
+                    const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
+                    if (this.options.silent) {
+                        console.error(errMsg);
+                        break;
+                    }
+                    else {
+                        throw new Error(errMsg);
+                    }
+                }
+            }
+            this.state.top = true;
+            return tokens;
+        }
+        inline(src, tokens = []) {
+            this.inlineQueue.push({ src, tokens });
+            return tokens;
+        }
+        /**
+         * Lexing/Compiling
+         */
+        inlineTokens(src, tokens = []) {
+            let token, lastToken, cutSrc;
+            // String with links masked to avoid interference with em and strong
+            let maskedSrc = src;
+            let match;
+            let keepPrevChar, prevChar;
+            // Mask out reflinks
+            if (this.tokens.links) {
+                const links = Object.keys(this.tokens.links);
+                if (links.length > 0) {
+                    while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
+                        if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {
+                            maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
+                        }
+                    }
+                }
+            }
+            // Mask out other blocks
+            while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
+                maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
+            }
+            // Mask out escaped characters
+            while ((match = this.tokenizer.rules.inline.anyPunctuation.exec(maskedSrc)) != null) {
+                maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
+            }
+            while (src) {
+                if (!keepPrevChar) {
+                    prevChar = '';
+                }
+                keepPrevChar = false;
+                // extensions
+                if (this.options.extensions
+                    && this.options.extensions.inline
+                    && this.options.extensions.inline.some((extTokenizer) => {
+                        if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
+                            src = src.substring(token.raw.length);
+                            tokens.push(token);
+                            return true;
+                        }
+                        return false;
+                    })) {
+                    continue;
+                }
+                // escape
+                if (token = this.tokenizer.escape(src)) {
+                    src = src.substring(token.raw.length);
+                    tokens.push(token);
+                    continue;
+                }
+                // tag
+                if (token = this.tokenizer.tag(src)) {
+                    src = src.substring(token.raw.length);
+                    lastToken = tokens[tokens.length - 1];
+                    if (lastToken && token.type === 'text' && lastToken.type === 'text') {
+                        lastToken.raw += token.raw;
+                        lastToken.text += token.text;
+                    }
+                    else {
+                        tokens.push(token);
+                    }
+                    continue;
+                }
+                // link
+                if (token = this.tokenizer.link(src)) {
+                    src = src.substring(token.raw.length);
+                    tokens.push(token);
+                    continue;
+                }
+                // reflink, nolink
+                if (token = this.tokenizer.reflink(src, this.tokens.links)) {
+                    src = src.substring(token.raw.length);
+                    lastToken = tokens[tokens.length - 1];
+                    if (lastToken && token.type === 'text' && lastToken.type === 'text') {
+                        lastToken.raw += token.raw;
+                        lastToken.text += token.text;
+                    }
+                    else {
+                        tokens.push(token);
+                    }
+                    continue;
+                }
+                // em & strong
+                if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
+                    src = src.substring(token.raw.length);
+                    tokens.push(token);
+                    continue;
+                }
+                // code
+                if (token = this.tokenizer.codespan(src)) {
+                    src = src.substring(token.raw.length);
+                    tokens.push(token);
+                    continue;
+                }
+                // br
+                if (token = this.tokenizer.br(src)) {
+                    src = src.substring(token.raw.length);
+                    tokens.push(token);
+                    continue;
+                }
+                // del (gfm)
+                if (token = this.tokenizer.del(src)) {
+                    src = src.substring(token.raw.length);
+                    tokens.push(token);
+                    continue;
+                }
+                // autolink
+                if (token = this.tokenizer.autolink(src, mangle)) {
+                    src = src.substring(token.raw.length);
+                    tokens.push(token);
+                    continue;
+                }
+                // url (gfm)
+                if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) {
+                    src = src.substring(token.raw.length);
+                    tokens.push(token);
+                    continue;
+                }
+                // text
+                // prevent inlineText consuming extensions by clipping 'src' to extension start
+                cutSrc = src;
+                if (this.options.extensions && this.options.extensions.startInline) {
+                    let startIndex = Infinity;
+                    const tempSrc = src.slice(1);
+                    let tempStart;
+                    this.options.extensions.startInline.forEach((getStartIndex) => {
+                        tempStart = getStartIndex.call({ lexer: this }, tempSrc);
+                        if (typeof tempStart === 'number' && tempStart >= 0) {
+                            startIndex = Math.min(startIndex, tempStart);
+                        }
                     });
-                  }
-                } else {
-                  itemBody += checkbox;
-                }
-              }
-              itemBody += this.parse(item.tokens, loose);
-              body += this.renderer.listitem(itemBody, task, !!checked);
-            }
-            out += this.renderer.list(body, ordered, start);
-            continue;
-          }
-          case "html": {
-            out += this.renderer.html(token.text, token.block);
-            continue;
-          }
-          case "paragraph": {
-            out += this.renderer.paragraph(this.parseInline(token.tokens));
-            continue;
-          }
-          case "text": {
-            body = token.tokens ? this.parseInline(token.tokens) : token.text;
-            while (i + 1 < l && tokens[i + 1].type === "text") {
-              token = tokens[++i];
-              body += "\n" + (token.tokens ? this.parseInline(token.tokens) : token.text);
-            }
-            out += top ? this.renderer.paragraph(body) : body;
-            continue;
-          }
-          default: {
-            const errMsg = 'Token with "' + token.type + '" type was not found.';
-            if (this.options.silent) {
-              console.error(errMsg);
-              return "";
-            } else {
-              throw new Error(errMsg);
-            }
-          }
-        }
-      }
-      return out;
+                    if (startIndex < Infinity && startIndex >= 0) {
+                        cutSrc = src.substring(0, startIndex + 1);
+                    }
+                }
+                if (token = this.tokenizer.inlineText(cutSrc, smartypants)) {
+                    src = src.substring(token.raw.length);
+                    if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started
+                        prevChar = token.raw.slice(-1);
+                    }
+                    keepPrevChar = true;
+                    lastToken = tokens[tokens.length - 1];
+                    if (lastToken && lastToken.type === 'text') {
+                        lastToken.raw += token.raw;
+                        lastToken.text += token.text;
+                    }
+                    else {
+                        tokens.push(token);
+                    }
+                    continue;
+                }
+                if (src) {
+                    const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
+                    if (this.options.silent) {
+                        console.error(errMsg);
+                        break;
+                    }
+                    else {
+                        throw new Error(errMsg);
+                    }
+                }
+            }
+            return tokens;
+        }
     }
+
     /**
-     * Parse Inline Tokens
+     * Renderer
      */
-    parseInline(tokens, renderer) {
-      renderer = renderer || this.renderer;
-      let out = "", i, token, ret;
-      const l = tokens.length;
-      for (i = 0; i < l; i++) {
-        token = tokens[i];
-        if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
-          ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
-          if (ret !== false || !["escape", "html", "link", "image", "strong", "em", "codespan", "br", "del", "text"].includes(token.type)) {
-            out += ret || "";
-            continue;
-          }
-        }
-        switch (token.type) {
-          case "escape": {
-            out += renderer.text(token.text);
-            break;
-          }
-          case "html": {
-            out += renderer.html(token.text);
-            break;
-          }
-          case "link": {
-            out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer));
-            break;
-          }
-          case "image": {
-            out += renderer.image(token.href, token.title, token.text);
-            break;
-          }
-          case "strong": {
-            out += renderer.strong(this.parseInline(token.tokens, renderer));
-            break;
-          }
-          case "em": {
-            out += renderer.em(this.parseInline(token.tokens, renderer));
-            break;
-          }
-          case "codespan": {
-            out += renderer.codespan(token.text);
-            break;
-          }
-          case "br": {
-            out += renderer.br();
-            break;
-          }
-          case "del": {
-            out += renderer.del(this.parseInline(token.tokens, renderer));
-            break;
-          }
-          case "text": {
-            out += renderer.text(token.text);
-            break;
-          }
-          default: {
-            const errMsg = 'Token with "' + token.type + '" type was not found.';
-            if (this.options.silent) {
-              console.error(errMsg);
-              return "";
-            } else {
-              throw new Error(errMsg);
-            }
-          }
-        }
-      }
-      return out;
+    class _Renderer {
+        options;
+        constructor(options) {
+            this.options = options || exports.defaults;
+        }
+        code(code, infostring, escaped) {
+            const lang = (infostring || '').match(/\S*/)[0];
+            if (this.options.highlight) {
+                const out = this.options.highlight(code, lang);
+                if (out != null && out !== code) {
+                    escaped = true;
+                    code = out;
+                }
+            }
+            code = code.replace(/\n$/, '') + '\n';
+            if (!lang) {
+                return '<pre><code>'
+                    + (escaped ? code : escape(code, true))
+                    + '</code></pre>\n';
+            }
+            return '<pre><code class="'
+                + this.options.langPrefix
+                + escape(lang)
+                + '">'
+                + (escaped ? code : escape(code, true))
+                + '</code></pre>\n';
+        }
+        blockquote(quote) {
+            return `<blockquote>\n${quote}</blockquote>\n`;
+        }
+        html(html, block) {
+            return html;
+        }
+        heading(text, level, raw, slugger) {
+            if (this.options.headerIds) {
+                const id = this.options.headerPrefix + slugger.slug(raw);
+                return `<h${level} id="${id}">${text}</h${level}>\n`;
+            }
+            // ignore IDs
+            return `<h${level}>${text}</h${level}>\n`;
+        }
+        hr() {
+            return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
+        }
+        list(body, ordered, start) {
+            const type = ordered ? 'ol' : 'ul', startatt = (ordered && start !== 1) ? (' start="' + start + '"') : '';
+            return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
+        }
+        listitem(text, task, checked) {
+            return `<li>${text}</li>\n`;
+        }
+        checkbox(checked) {
+            return '<input '
+                + (checked ? 'checked="" ' : '')
+                + 'disabled="" type="checkbox"'
+                + (this.options.xhtml ? ' /' : '')
+                + '> ';
+        }
+        paragraph(text) {
+            return `<p>${text}</p>\n`;
+        }
+        table(header, body) {
+            if (body)
+                body = `<tbody>${body}</tbody>`;
+            return '<table>\n'
+                + '<thead>\n'
+                + header
+                + '</thead>\n'
+                + body
+                + '</table>\n';
+        }
+        tablerow(content) {
+            return `<tr>\n${content}</tr>\n`;
+        }
+        tablecell(content, flags) {
+            const type = flags.header ? 'th' : 'td';
+            const tag = flags.align
+                ? `<${type} align="${flags.align}">`
+                : `<${type}>`;
+            return tag + content + `</${type}>\n`;
+        }
+        /**
+         * span level renderer
+         */
+        strong(text) {
+            return `<strong>${text}</strong>`;
+        }
+        em(text) {
+            return `<em>${text}</em>`;
+        }
+        codespan(text) {
+            return `<code>${text}</code>`;
+        }
+        br() {
+            return this.options.xhtml ? '<br/>' : '<br>';
+        }
+        del(text) {
+            return `<del>${text}</del>`;
+        }
+        link(href, title, text) {
+            href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
+            if (href === null) {
+                return text;
+            }
+            let out = '<a href="' + href + '"';
+            if (title) {
+                out += ' title="' + title + '"';
+            }
+            out += '>' + text + '</a>';
+            return out;
+        }
+        image(href, title, text) {
+            href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
+            if (href === null) {
+                return text;
+            }
+            let out = `<img src="${href}" alt="${text}"`;
+            if (title) {
+                out += ` title="${title}"`;
+            }
+            out += this.options.xhtml ? '/>' : '>';
+            return out;
+        }
+        text(text) {
+            return text;
+        }
     }
-  };
 
-  // src/Hooks.ts
-  var _Hooks = class {
-    constructor(options2) {
-      this.options = options2 || _defaults;
-    }
     /**
-     * Process markdown before marked
+     * TextRenderer
+     * returns only the textual part of the token
      */
-    preprocess(markdown) {
-      return markdown;
+    class _TextRenderer {
+        // no need for block level renderers
+        strong(text) {
+            return text;
+        }
+        em(text) {
+            return text;
+        }
+        codespan(text) {
+            return text;
+        }
+        del(text) {
+            return text;
+        }
+        html(text) {
+            return text;
+        }
+        text(text) {
+            return text;
+        }
+        link(href, title, text) {
+            return '' + text;
+        }
+        image(href, title, text) {
+            return '' + text;
+        }
+        br() {
+            return '';
+        }
     }
+
     /**
-     * Process HTML after marked is finished
+     * Slugger generates header id
      */
-    postprocess(html) {
-      return html;
+    class _Slugger {
+        seen;
+        constructor() {
+            this.seen = {};
+        }
+        serialize(value) {
+            return value
+                .toLowerCase()
+                .trim()
+                // remove html tags
+                .replace(/<[!\/a-z].*?>/ig, '')
+                // remove unwanted chars
+                .replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, '')
+                .replace(/\s/g, '-');
+        }
+        /**
+         * Finds the next safe (unique) slug to use
+         */
+        getNextSafeSlug(originalSlug, isDryRun) {
+            let slug = originalSlug;
+            let occurenceAccumulator = 0;
+            if (this.seen.hasOwnProperty(slug)) {
+                occurenceAccumulator = this.seen[originalSlug];
+                do {
+                    occurenceAccumulator++;
+                    slug = originalSlug + '-' + occurenceAccumulator;
+                } while (this.seen.hasOwnProperty(slug));
+            }
+            if (!isDryRun) {
+                this.seen[originalSlug] = occurenceAccumulator;
+                this.seen[slug] = 0;
+            }
+            return slug;
+        }
+        /**
+         * Convert string to unique id
+         */
+        slug(value, options = {}) {
+            const slug = this.serialize(value);
+            return this.getNextSafeSlug(slug, options.dryrun);
+        }
     }
-  };
-  _Hooks.passThroughHooks = /* @__PURE__ */ new Set([
-    "preprocess",
-    "postprocess"
-  ]);
 
-  // src/Instance.ts
-  var _parseMarkdown, parseMarkdown_fn, _onError, onError_fn;
-  var Marked = class {
-    constructor(...args) {
-      __privateAdd(this, _parseMarkdown);
-      __privateAdd(this, _onError);
-      this.defaults = _getDefaults();
-      this.options = this.setOptions;
-      this.parse = __privateMethod(this, _parseMarkdown, parseMarkdown_fn).call(this, _Lexer2.lex, _Parser.parse);
-      this.parseInline = __privateMethod(this, _parseMarkdown, parseMarkdown_fn).call(this, _Lexer2.lexInline, _Parser.parseInline);
-      this.Parser = _Parser;
-      this.parser = _Parser.parse;
-      this.Renderer = _Renderer;
-      this.TextRenderer = _TextRenderer;
-      this.Lexer = _Lexer2;
-      this.lexer = _Lexer2.lex;
-      this.Tokenizer = _Tokenizer;
-      this.Slugger = _Slugger;
-      this.Hooks = _Hooks;
-      this.use(...args);
-    }
     /**
-     * Run callback for every token
+     * Parsing & Compiling
      */
-    walkTokens(tokens, callback) {
-      let values = [];
-      for (const token of tokens) {
-        values = values.concat(callback.call(this, token));
-        switch (token.type) {
-          case "table": {
-            for (const cell of token.header) {
-              values = values.concat(this.walkTokens(cell.tokens, callback));
-            }
-            for (const row of token.rows) {
-              for (const cell of row) {
-                values = values.concat(this.walkTokens(cell.tokens, callback));
-              }
-            }
-            break;
-          }
-          case "list": {
-            values = values.concat(this.walkTokens(token.items, callback));
-            break;
-          }
-          default: {
-            if (this.defaults.extensions && this.defaults.extensions.childTokens && this.defaults.extensions.childTokens[token.type]) {
-              this.defaults.extensions.childTokens[token.type].forEach((childTokens) => {
-                values = values.concat(this.walkTokens(token[childTokens], callback));
-              });
-            } else if (token.tokens) {
-              values = values.concat(this.walkTokens(token.tokens, callback));
-            }
-          }
-        }
-      }
-      return values;
+    class _Parser {
+        options;
+        renderer;
+        textRenderer;
+        slugger;
+        constructor(options) {
+            this.options = options || exports.defaults;
+            this.options.renderer = this.options.renderer || new _Renderer();
+            this.renderer = this.options.renderer;
+            this.renderer.options = this.options;
+            this.textRenderer = new _TextRenderer();
+            this.slugger = new _Slugger();
+        }
+        /**
+         * Static Parse Method
+         */
+        static parse(tokens, options) {
+            const parser = new _Parser(options);
+            return parser.parse(tokens);
+        }
+        /**
+         * Static Parse Inline Method
+         */
+        static parseInline(tokens, options) {
+            const parser = new _Parser(options);
+            return parser.parseInline(tokens);
+        }
+        /**
+         * Parse Loop
+         */
+        parse(tokens, top = true) {
+            let out = '', i, j, k, l2, l3, row, cell, header, body, token, ordered, start, loose, itemBody, item, checked, task, checkbox, ret;
+            const l = tokens.length;
+            for (i = 0; i < l; i++) {
+                token = tokens[i];
+                // Run any renderer extensions
+                if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
+                    ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
+                    if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(token.type)) {
+                        out += ret || '';
+                        continue;
+                    }
+                }
+                switch (token.type) {
+                    case 'space': {
+                        continue;
+                    }
+                    case 'hr': {
+                        out += this.renderer.hr();
+                        continue;
+                    }
+                    case 'heading': {
+                        out += this.renderer.heading(this.parseInline(token.tokens), token.depth, unescape(this.parseInline(token.tokens, this.textRenderer)), this.slugger);
+                        continue;
+                    }
+                    case 'code': {
+                        out += this.renderer.code(token.text, token.lang, !!token.escaped);
+                        continue;
+                    }
+                    case 'table': {
+                        header = '';
+                        // header
+                        cell = '';
+                        l2 = token.header.length;
+                        for (j = 0; j < l2; j++) {
+                            cell += this.renderer.tablecell(this.parseInline(token.header[j].tokens), { header: true, align: token.align[j] });
+                        }
+                        header += this.renderer.tablerow(cell);
+                        body = '';
+                        l2 = token.rows.length;
+                        for (j = 0; j < l2; j++) {
+                            row = token.rows[j];
+                            cell = '';
+                            l3 = row.length;
+                            for (k = 0; k < l3; k++) {
+                                cell += this.renderer.tablecell(this.parseInline(row[k].tokens), { header: false, align: token.align[k] });
+                            }
+                            body += this.renderer.tablerow(cell);
+                        }
+                        out += this.renderer.table(header, body);
+                        continue;
+                    }
+                    case 'blockquote': {
+                        body = this.parse(token.tokens);
+                        out += this.renderer.blockquote(body);
+                        continue;
+                    }
+                    case 'list': {
+                        ordered = token.ordered;
+                        start = token.start;
+                        loose = token.loose;
+                        l2 = token.items.length;
+                        body = '';
+                        for (j = 0; j < l2; j++) {
+                            item = token.items[j];
+                            checked = item.checked;
+                            task = item.task;
+                            itemBody = '';
+                            if (item.task) {
+                                checkbox = this.renderer.checkbox(!!checked);
+                                if (loose) {
+                                    if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {
+                                        item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
+                                        if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
+                                            item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text;
+                                        }
+                                    }
+                                    else {
+                                        item.tokens.unshift({
+                                            type: 'text',
+                                            text: checkbox
+                                        });
+                                    }
+                                }
+                                else {
+                                    itemBody += checkbox;
+                                }
+                            }
+                            itemBody += this.parse(item.tokens, loose);
+                            body += this.renderer.listitem(itemBody, task, !!checked);
+                        }
+                        out += this.renderer.list(body, ordered, start);
+                        continue;
+                    }
+                    case 'html': {
+                        out += this.renderer.html(token.text, token.block);
+                        continue;
+                    }
+                    case 'paragraph': {
+                        out += this.renderer.paragraph(this.parseInline(token.tokens));
+                        continue;
+                    }
+                    case 'text': {
+                        body = token.tokens ? this.parseInline(token.tokens) : token.text;
+                        while (i + 1 < l && tokens[i + 1].type === 'text') {
+                            token = tokens[++i];
+                            body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text);
+                        }
+                        out += top ? this.renderer.paragraph(body) : body;
+                        continue;
+                    }
+                    default: {
+                        const errMsg = 'Token with "' + token.type + '" type was not found.';
+                        if (this.options.silent) {
+                            console.error(errMsg);
+                            return '';
+                        }
+                        else {
+                            throw new Error(errMsg);
+                        }
+                    }
+                }
+            }
+            return out;
+        }
+        /**
+         * Parse Inline Tokens
+         */
+        parseInline(tokens, renderer) {
+            renderer = renderer || this.renderer;
+            let out = '', i, token, ret;
+            const l = tokens.length;
+            for (i = 0; i < l; i++) {
+                token = tokens[i];
+                // Run any renderer extensions
+                if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
+                    ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
+                    if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) {
+                        out += ret || '';
+                        continue;
+                    }
+                }
+                switch (token.type) {
+                    case 'escape': {
+                        out += renderer.text(token.text);
+                        break;
+                    }
+                    case 'html': {
+                        out += renderer.html(token.text);
+                        break;
+                    }
+                    case 'link': {
+                        out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer));
+                        break;
+                    }
+                    case 'image': {
+                        out += renderer.image(token.href, token.title, token.text);
+                        break;
+                    }
+                    case 'strong': {
+                        out += renderer.strong(this.parseInline(token.tokens, renderer));
+                        break;
+                    }
+                    case 'em': {
+                        out += renderer.em(this.parseInline(token.tokens, renderer));
+                        break;
+                    }
+                    case 'codespan': {
+                        out += renderer.codespan(token.text);
+                        break;
+                    }
+                    case 'br': {
+                        out += renderer.br();
+                        break;
+                    }
+                    case 'del': {
+                        out += renderer.del(this.parseInline(token.tokens, renderer));
+                        break;
+                    }
+                    case 'text': {
+                        out += renderer.text(token.text);
+                        break;
+                    }
+                    default: {
+                        const errMsg = 'Token with "' + token.type + '" type was not found.';
+                        if (this.options.silent) {
+                            console.error(errMsg);
+                            return '';
+                        }
+                        else {
+                            throw new Error(errMsg);
+                        }
+                    }
+                }
+            }
+            return out;
+        }
     }
-    use(...args) {
-      const extensions = this.defaults.extensions || { renderers: {}, childTokens: {} };
-      args.forEach((pack) => {
-        const opts = { ...pack };
-        opts.async = this.defaults.async || opts.async || false;
-        if (pack.extensions) {
-          pack.extensions.forEach((ext) => {
-            if (!ext.name) {
-              throw new Error("extension name required");
-            }
-            if ("renderer" in ext) {
-              const prevRenderer = extensions.renderers[ext.name];
-              if (prevRenderer) {
-                extensions.renderers[ext.name] = function(...args2) {
-                  let ret = ext.renderer.apply(this, args2);
-                  if (ret === false) {
-                    ret = prevRenderer.apply(this, args2);
-                  }
-                  return ret;
-                };
-              } else {
-                extensions.renderers[ext.name] = ext.renderer;
-              }
-            }
-            if ("tokenizer" in ext) {
-              if (!ext.level || ext.level !== "block" && ext.level !== "inline") {
-                throw new Error("extension level must be 'block' or 'inline'");
-              }
-              if (extensions[ext.level]) {
-                extensions[ext.level].unshift(ext.tokenizer);
-              } else {
-                extensions[ext.level] = [ext.tokenizer];
-              }
-              if (ext.start) {
-                if (ext.level === "block") {
-                  if (extensions.startBlock) {
-                    extensions.startBlock.push(ext.start);
-                  } else {
-                    extensions.startBlock = [ext.start];
-                  }
-                } else if (ext.level === "inline") {
-                  if (extensions.startInline) {
-                    extensions.startInline.push(ext.start);
-                  } else {
-                    extensions.startInline = [ext.start];
-                  }
-                }
-              }
-            }
-            if ("childTokens" in ext && ext.childTokens) {
-              extensions.childTokens[ext.name] = ext.childTokens;
-            }
-          });
-          opts.extensions = extensions;
-        }
-        if (pack.renderer) {
-          const renderer = this.defaults.renderer || new _Renderer(this.defaults);
-          for (const prop in pack.renderer) {
-            const prevRenderer = renderer[prop];
-            renderer[prop] = (...args2) => {
-              let ret = pack.renderer[prop].apply(renderer, args2);
-              if (ret === false) {
-                ret = prevRenderer.apply(renderer, args2);
-              }
-              return ret;
-            };
-          }
-          opts.renderer = renderer;
-        }
-        if (pack.tokenizer) {
-          const tokenizer = this.defaults.tokenizer || new _Tokenizer(this.defaults);
-          for (const prop in pack.tokenizer) {
-            const prevTokenizer = tokenizer[prop];
-            tokenizer[prop] = (...args2) => {
-              let ret = pack.tokenizer[prop].apply(tokenizer, args2);
-              if (ret === false) {
-                ret = prevTokenizer.apply(tokenizer, args2);
-              }
-              return ret;
-            };
-          }
-          opts.tokenizer = tokenizer;
-        }
-        if (pack.hooks) {
-          const hooks = this.defaults.hooks || new _Hooks();
-          for (const prop in pack.hooks) {
-            const prevHook = hooks[prop];
-            if (_Hooks.passThroughHooks.has(prop)) {
-              hooks[prop] = (arg) => {
-                if (this.defaults.async) {
-                  return Promise.resolve(pack.hooks[prop].call(hooks, arg)).then((ret2) => {
-                    return prevHook.call(hooks, ret2);
-                  });
-                }
-                const ret = pack.hooks[prop].call(hooks, arg);
-                return prevHook.call(hooks, ret);
-              };
-            } else {
-              hooks[prop] = (...args2) => {
-                let ret = pack.hooks[prop].apply(hooks, args2);
-                if (ret === false) {
-                  ret = prevHook.apply(hooks, args2);
-                }
-                return ret;
-              };
-            }
-          }
-          opts.hooks = hooks;
-        }
-        if (pack.walkTokens) {
-          const walkTokens2 = this.defaults.walkTokens;
-          opts.walkTokens = function(token) {
+
+    class _Hooks {
+        options;
+        constructor(options) {
+            this.options = options || exports.defaults;
+        }
+        static passThroughHooks = new Set([
+            'preprocess',
+            'postprocess'
+        ]);
+        /**
+         * Process markdown before marked
+         */
+        preprocess(markdown) {
+            return markdown;
+        }
+        /**
+         * Process HTML after marked is finished
+         */
+        postprocess(html) {
+            return html;
+        }
+    }
+
+    class Marked {
+        defaults = _getDefaults();
+        options = this.setOptions;
+        parse = this.#parseMarkdown(_Lexer.lex, _Parser.parse);
+        parseInline = this.#parseMarkdown(_Lexer.lexInline, _Parser.parseInline);
+        Parser = _Parser;
+        parser = _Parser.parse;
+        Renderer = _Renderer;
+        TextRenderer = _TextRenderer;
+        Lexer = _Lexer;
+        lexer = _Lexer.lex;
+        Tokenizer = _Tokenizer;
+        Slugger = _Slugger;
+        Hooks = _Hooks;
+        constructor(...args) {
+            this.use(...args);
+        }
+        /**
+         * Run callback for every token
+         */
+        walkTokens(tokens, callback) {
             let values = [];
-            values.push(pack.walkTokens.call(this, token));
-            if (walkTokens2) {
-              values = values.concat(walkTokens2.call(this, token));
+            for (const token of tokens) {
+                values = values.concat(callback.call(this, token));
+                switch (token.type) {
+                    case 'table': {
+                        for (const cell of token.header) {
+                            values = values.concat(this.walkTokens(cell.tokens, callback));
+                        }
+                        for (const row of token.rows) {
+                            for (const cell of row) {
+                                values = values.concat(this.walkTokens(cell.tokens, callback));
+                            }
+                        }
+                        break;
+                    }
+                    case 'list': {
+                        values = values.concat(this.walkTokens(token.items, callback));
+                        break;
+                    }
+                    default: {
+                        if (this.defaults.extensions && this.defaults.extensions.childTokens && this.defaults.extensions.childTokens[token.type]) { // Walk any extensions
+                            this.defaults.extensions.childTokens[token.type].forEach((childTokens) => {
+                                values = values.concat(this.walkTokens(token[childTokens], callback));
+                            });
+                        }
+                        else if (token.tokens) {
+                            values = values.concat(this.walkTokens(token.tokens, callback));
+                        }
+                    }
+                }
             }
             return values;
-          };
         }
-        this.defaults = { ...this.defaults, ...opts };
-      });
-      return this;
+        use(...args) {
+            const extensions = this.defaults.extensions || { renderers: {}, childTokens: {} };
+            args.forEach((pack) => {
+                // copy options to new object
+                const opts = { ...pack };
+                // set async to true if it was set to true before
+                opts.async = this.defaults.async || opts.async || false;
+                // ==-- Parse "addon" extensions --== //
+                if (pack.extensions) {
+                    pack.extensions.forEach((ext) => {
+                        if (!ext.name) {
+                            throw new Error('extension name required');
+                        }
+                        if ('renderer' in ext) { // Renderer extensions
+                            const prevRenderer = extensions.renderers[ext.name];
+                            if (prevRenderer) {
+                                // Replace extension with func to run new extension but fall back if false
+                                extensions.renderers[ext.name] = function (...args) {
+                                    let ret = ext.renderer.apply(this, args);
+                                    if (ret === false) {
+                                        ret = prevRenderer.apply(this, args);
+                                    }
+                                    return ret;
+                                };
+                            }
+                            else {
+                                extensions.renderers[ext.name] = ext.renderer;
+                            }
+                        }
+                        if ('tokenizer' in ext) { // Tokenizer Extensions
+                            if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) {
+                                throw new Error("extension level must be 'block' or 'inline'");
+                            }
+                            if (extensions[ext.level]) {
+                                extensions[ext.level].unshift(ext.tokenizer);
+                            }
+                            else {
+                                extensions[ext.level] = [ext.tokenizer];
+                            }
+                            if (ext.start) { // Function to check for start of token
+                                if (ext.level === 'block') {
+                                    if (extensions.startBlock) {
+                                        extensions.startBlock.push(ext.start);
+                                    }
+                                    else {
+                                        extensions.startBlock = [ext.start];
+                                    }
+                                }
+                                else if (ext.level === 'inline') {
+                                    if (extensions.startInline) {
+                                        extensions.startInline.push(ext.start);
+                                    }
+                                    else {
+                                        extensions.startInline = [ext.start];
+                                    }
+                                }
+                            }
+                        }
+                        if ('childTokens' in ext && ext.childTokens) { // Child tokens to be visited by walkTokens
+                            extensions.childTokens[ext.name] = ext.childTokens;
+                        }
+                    });
+                    opts.extensions = extensions;
+                }
+                // ==-- Parse "overwrite" extensions --== //
+                if (pack.renderer) {
+                    const renderer = this.defaults.renderer || new _Renderer(this.defaults);
+                    for (const prop in pack.renderer) {
+                        const prevRenderer = renderer[prop];
+                        // Replace renderer with func to run extension, but fall back if false
+                        renderer[prop] = (...args) => {
+                            let ret = pack.renderer[prop].apply(renderer, args);
+                            if (ret === false) {
+                                ret = prevRenderer.apply(renderer, args);
+                            }
+                            return ret;
+                        };
+                    }
+                    opts.renderer = renderer;
+                }
+                if (pack.tokenizer) {
+                    const tokenizer = this.defaults.tokenizer || new _Tokenizer(this.defaults);
+                    for (const prop in pack.tokenizer) {
+                        const prevTokenizer = tokenizer[prop];
+                        // Replace tokenizer with func to run extension, but fall back if false
+                        tokenizer[prop] = (...args) => {
+                            let ret = pack.tokenizer[prop].apply(tokenizer, args);
+                            if (ret === false) {
+                                ret = prevTokenizer.apply(tokenizer, args);
+                            }
+                            return ret;
+                        };
+                    }
+                    opts.tokenizer = tokenizer;
+                }
+                // ==-- Parse Hooks extensions --== //
+                if (pack.hooks) {
+                    const hooks = this.defaults.hooks || new _Hooks();
+                    for (const prop in pack.hooks) {
+                        const prevHook = hooks[prop];
+                        if (_Hooks.passThroughHooks.has(prop)) {
+                            hooks[prop] = (arg) => {
+                                if (this.defaults.async) {
+                                    return Promise.resolve(pack.hooks[prop].call(hooks, arg)).then(ret => {
+                                        return prevHook.call(hooks, ret);
+                                    });
+                                }
+                                const ret = pack.hooks[prop].call(hooks, arg);
+                                return prevHook.call(hooks, ret);
+                            };
+                        }
+                        else {
+                            hooks[prop] = (...args) => {
+                                let ret = pack.hooks[prop].apply(hooks, args);
+                                if (ret === false) {
+                                    ret = prevHook.apply(hooks, args);
+                                }
+                                return ret;
+                            };
+                        }
+                    }
+                    opts.hooks = hooks;
+                }
+                // ==-- Parse WalkTokens extensions --== //
+                if (pack.walkTokens) {
+                    const walkTokens = this.defaults.walkTokens;
+                    opts.walkTokens = function (token) {
+                        let values = [];
+                        values.push(pack.walkTokens.call(this, token));
+                        if (walkTokens) {
+                            values = values.concat(walkTokens.call(this, token));
+                        }
+                        return values;
+                    };
+                }
+                this.defaults = { ...this.defaults, ...opts };
+            });
+            return this;
+        }
+        setOptions(opt) {
+            this.defaults = { ...this.defaults, ...opt };
+            return this;
+        }
+        #parseMarkdown(lexer, parser) {
+            return (src, optOrCallback, callback) => {
+                if (typeof optOrCallback === 'function') {
+                    callback = optOrCallback;
+                    optOrCallback = null;
+                }
+                const origOpt = { ...optOrCallback };
+                const opt = { ...this.defaults, ...origOpt };
+                const throwError = this.#onError(!!opt.silent, !!opt.async, callback);
+                // throw error in case of non string input
+                if (typeof src === 'undefined' || src === null) {
+                    return throwError(new Error('marked(): input parameter is undefined or null'));
+                }
+                if (typeof src !== 'string') {
+                    return throwError(new Error('marked(): input parameter is of type '
+                        + Object.prototype.toString.call(src) + ', string expected'));
+                }
+                checkDeprecations(opt, callback);
+                if (opt.hooks) {
+                    opt.hooks.options = opt;
+                }
+                if (callback) {
+                    const highlight = opt.highlight;
+                    let tokens;
+                    try {
+                        if (opt.hooks) {
+                            src = opt.hooks.preprocess(src);
+                        }
+                        tokens = lexer(src, opt);
+                    }
+                    catch (e) {
+                        return throwError(e);
+                    }
+                    const done = (err) => {
+                        let out;
+                        if (!err) {
+                            try {
+                                if (opt.walkTokens) {
+                                    this.walkTokens(tokens, opt.walkTokens);
+                                }
+                                out = parser(tokens, opt);
+                                if (opt.hooks) {
+                                    out = opt.hooks.postprocess(out);
+                                }
+                            }
+                            catch (e) {
+                                err = e;
+                            }
+                        }
+                        opt.highlight = highlight;
+                        return err
+                            ? throwError(err)
+                            : callback(null, out);
+                    };
+                    if (!highlight || highlight.length < 3) {
+                        return done();
+                    }
+                    delete opt.highlight;
+                    if (!tokens.length)
+                        return done();
+                    let pending = 0;
+                    this.walkTokens(tokens, (token) => {
+                        if (token.type === 'code') {
+                            pending++;
+                            setTimeout(() => {
+                                highlight(token.text, token.lang, (err, code) => {
+                                    if (err) {
+                                        return done(err);
+                                    }
+                                    if (code != null && code !== token.text) {
+                                        token.text = code;
+                                        token.escaped = true;
+                                    }
+                                    pending--;
+                                    if (pending === 0) {
+                                        done();
+                                    }
+                                });
+                            }, 0);
+                        }
+                    });
+                    if (pending === 0) {
+                        done();
+                    }
+                    return;
+                }
+                if (opt.async) {
+                    return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src)
+                        .then(src => lexer(src, opt))
+                        .then(tokens => opt.walkTokens ? Promise.all(this.walkTokens(tokens, opt.walkTokens)).then(() => tokens) : tokens)
+                        .then(tokens => parser(tokens, opt))
+                        .then(html => opt.hooks ? opt.hooks.postprocess(html) : html)
+                        .catch(throwError);
+                }
+                try {
+                    if (opt.hooks) {
+                        src = opt.hooks.preprocess(src);
+                    }
+                    const tokens = lexer(src, opt);
+                    if (opt.walkTokens) {
+                        this.walkTokens(tokens, opt.walkTokens);
+                    }
+                    let html = parser(tokens, opt);
+                    if (opt.hooks) {
+                        html = opt.hooks.postprocess(html);
+                    }
+                    return html;
+                }
+                catch (e) {
+                    return throwError(e);
+                }
+            };
+        }
+        #onError(silent, async, callback) {
+            return (e) => {
+                e.message += '\nPlease report this to https://github.com/markedjs/marked.';
+                if (silent) {
+                    const msg = '<p>An error occurred:</p><pre>'
+                        + escape(e.message + '', true)
+                        + '</pre>';
+                    if (async) {
+                        return Promise.resolve(msg);
+                    }
+                    if (callback) {
+                        callback(null, msg);
+                        return;
+                    }
+                    return msg;
+                }
+                if (async) {
+                    return Promise.reject(e);
+                }
+                if (callback) {
+                    callback(e);
+                    return;
+                }
+                throw e;
+            };
+        }
     }
-    setOptions(opt) {
-      this.defaults = { ...this.defaults, ...opt };
-      return this;
+
+    const markedInstance = new Marked();
+    function marked(src, opt, callback) {
+        return markedInstance.parse(src, opt, callback);
     }
-  };
-  _parseMarkdown = new WeakSet();
-  parseMarkdown_fn = function(lexer2, parser2) {
-    return (src, optOrCallback, callback) => {
-      if (typeof optOrCallback === "function") {
-        callback = optOrCallback;
-        optOrCallback = null;
-      }
-      const origOpt = { ...optOrCallback };
-      const opt = { ...this.defaults, ...origOpt };
-      const throwError = __privateMethod(this, _onError, onError_fn).call(this, !!opt.silent, !!opt.async, callback);
-      if (typeof src === "undefined" || src === null) {
-        return throwError(new Error("marked(): input parameter is undefined or null"));
-      }
-      if (typeof src !== "string") {
-        return throwError(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(src) + ", string expected"));
-      }
-      checkDeprecations(opt, callback);
-      if (opt.hooks) {
-        opt.hooks.options = opt;
-      }
-      if (callback) {
-        const highlight = opt.highlight;
-        let tokens;
-        try {
-          if (opt.hooks) {
-            src = opt.hooks.preprocess(src);
-          }
-          tokens = lexer2(src, opt);
-        } catch (e) {
-          return throwError(e);
-        }
-        const done = (err) => {
-          let out;
-          if (!err) {
-            try {
-              if (opt.walkTokens) {
-                this.walkTokens(tokens, opt.walkTokens);
-              }
-              out = parser2(tokens, opt);
-              if (opt.hooks) {
-                out = opt.hooks.postprocess(out);
-              }
-            } catch (e) {
-              err = e;
-            }
-          }
-          opt.highlight = highlight;
-          return err ? throwError(err) : callback(null, out);
+    /**
+     * Sets the default options.
+     *
+     * @param options Hash of options
+     */
+    marked.options =
+        marked.setOptions = function (options) {
+            markedInstance.setOptions(options);
+            marked.defaults = markedInstance.defaults;
+            changeDefaults(marked.defaults);
+            return marked;
         };
-        if (!highlight || highlight.length < 3) {
-          return done();
-        }
-        delete opt.highlight;
-        if (!tokens.length)
-          return done();
-        let pending = 0;
-        this.walkTokens(tokens, (token) => {
-          if (token.type === "code") {
-            pending++;
-            setTimeout(() => {
-              highlight(token.text, token.lang, (err, code) => {
-                if (err) {
-                  return done(err);
-                }
-                if (code != null && code !== token.text) {
-                  token.text = code;
-                  token.escaped = true;
-                }
-                pending--;
-                if (pending === 0) {
-                  done();
-                }
-              });
-            }, 0);
-          }
-        });
-        if (pending === 0) {
-          done();
-        }
-        return;
-      }
-      if (opt.async) {
-        return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src).then((src2) => lexer2(src2, opt)).then((tokens) => opt.walkTokens ? Promise.all(this.walkTokens(tokens, opt.walkTokens)).then(() => tokens) : tokens).then((tokens) => parser2(tokens, opt)).then((html) => opt.hooks ? opt.hooks.postprocess(html) : html).catch(throwError);
-      }
-      try {
-        if (opt.hooks) {
-          src = opt.hooks.preprocess(src);
-        }
-        const tokens = lexer2(src, opt);
-        if (opt.walkTokens) {
-          this.walkTokens(tokens, opt.walkTokens);
-        }
-        let html = parser2(tokens, opt);
-        if (opt.hooks) {
-          html = opt.hooks.postprocess(html);
-        }
-        return html;
-      } catch (e) {
-        return throwError(e);
-      }
+    /**
+     * Gets the original marked default options.
+     */
+    marked.getDefaults = _getDefaults;
+    marked.defaults = exports.defaults;
+    /**
+     * Use Extension
+     */
+    marked.use = function (...args) {
+        markedInstance.use(...args);
+        marked.defaults = markedInstance.defaults;
+        changeDefaults(marked.defaults);
+        return marked;
     };
-  };
-  _onError = new WeakSet();
-  onError_fn = function(silent, async, callback) {
-    return (e) => {
-      e.message += "\nPlease report this to https://github.com/markedjs/marked.";
-      if (silent) {
-        const msg = "<p>An error occurred:</p><pre>" + escape(e.message + "", true) + "</pre>";
-        if (async) {
-          return Promise.resolve(msg);
-        }
-        if (callback) {
-          callback(null, msg);
-          return;
-        }
-        return msg;
-      }
-      if (async) {
-        return Promise.reject(e);
-      }
-      if (callback) {
-        callback(e);
-        return;
-      }
-      throw e;
+    /**
+     * Run callback for every token
+     */
+    marked.walkTokens = function (tokens, callback) {
+        return markedInstance.walkTokens(tokens, callback);
     };
-  };
+    /**
+     * Compiles markdown to HTML without enclosing `p` tag.
+     *
+     * @param src String of markdown source to be compiled
+     * @param options Hash of options
+     * @return String of compiled HTML
+     */
+    marked.parseInline = markedInstance.parseInline;
+    /**
+     * Expose
+     */
+    marked.Parser = _Parser;
+    marked.parser = _Parser.parse;
+    marked.Renderer = _Renderer;
+    marked.TextRenderer = _TextRenderer;
+    marked.Lexer = _Lexer;
+    marked.lexer = _Lexer.lex;
+    marked.Tokenizer = _Tokenizer;
+    marked.Slugger = _Slugger;
+    marked.Hooks = _Hooks;
+    marked.parse = marked;
+    const options = marked.options;
+    const setOptions = marked.setOptions;
+    const use = marked.use;
+    const walkTokens = marked.walkTokens;
+    const parseInline = marked.parseInline;
+    const parse = marked;
+    const parser = _Parser.parse;
+    const lexer = _Lexer.lex;
+
+    exports.Hooks = _Hooks;
+    exports.Lexer = _Lexer;
+    exports.Marked = Marked;
+    exports.Parser = _Parser;
+    exports.Renderer = _Renderer;
+    exports.Slugger = _Slugger;
+    exports.TextRenderer = _TextRenderer;
+    exports.Tokenizer = _Tokenizer;
+    exports.getDefaults = _getDefaults;
+    exports.lexer = lexer;
+    exports.marked = marked;
+    exports.options = options;
+    exports.parse = parse;
+    exports.parseInline = parseInline;
+    exports.parser = parser;
+    exports.setOptions = setOptions;
+    exports.use = use;
+    exports.walkTokens = walkTokens;
 
-  // src/marked.ts
-  var markedInstance = new Marked();
-  function marked(src, opt, callback) {
-    return markedInstance.parse(src, opt, callback);
-  }
-  marked.options = marked.setOptions = function(options2) {
-    markedInstance.setOptions(options2);
-    marked.defaults = markedInstance.defaults;
-    changeDefaults(marked.defaults);
-    return marked;
-  };
-  marked.getDefaults = _getDefaults;
-  marked.defaults = _defaults;
-  marked.use = function(...args) {
-    markedInstance.use(...args);
-    marked.defaults = markedInstance.defaults;
-    changeDefaults(marked.defaults);
-    return marked;
-  };
-  marked.walkTokens = function(tokens, callback) {
-    return markedInstance.walkTokens(tokens, callback);
-  };
-  marked.parseInline = markedInstance.parseInline;
-  marked.Parser = _Parser;
-  marked.parser = _Parser.parse;
-  marked.Renderer = _Renderer;
-  marked.TextRenderer = _TextRenderer;
-  marked.Lexer = _Lexer2;
-  marked.lexer = _Lexer2.lex;
-  marked.Tokenizer = _Tokenizer;
-  marked.Slugger = _Slugger;
-  marked.Hooks = _Hooks;
-  marked.parse = marked;
-  var options = marked.options;
-  var setOptions = marked.setOptions;
-  var use = marked.use;
-  var walkTokens = marked.walkTokens;
-  var parseInline = marked.parseInline;
-  var parse = marked;
-  var parser = _Parser.parse;
-  var lexer = _Lexer2.lex;
-  return __toCommonJS(marked_exports);
-})();
-//# sourceMappingURL=marked.umd.js.map
+}));
+//# sourceMappingURL=marked.umd.js.map

File diff suppressed because it is too large
+ 0 - 0
lib/marked.umd.js.map


File diff suppressed because it is too large
+ 0 - 0
marked.min.js


File diff suppressed because it is too large
+ 80 - 693
package-lock.json


+ 9 - 7
package.json

@@ -46,6 +46,7 @@
   ],
   "devDependencies": {
     "@markedjs/html-differ": "^4.0.2",
+    "@rollup/plugin-typescript": "^11.1.2",
     "@semantic-release/commit-analyzer": "^10.0.1",
     "@semantic-release/git": "^10.0.1",
     "@semantic-release/github": "^9.0.4",
@@ -67,31 +68,32 @@
     "markdown-it": "13.0.1",
     "node-fetch": "^3.3.2",
     "recheck": "^4.4.5",
+    "rollup": "^3.27.0",
     "semantic-release": "^21.0.7",
     "titleize": "^3.0.0",
     "ts-expect": "^1.3.0",
     "ts-node": "^10.9.1",
-    "tsup": "^7.1.0",
     "typescript": "5.1.6",
-    "uglify-js": "^3.17.4",
-    "vuln-regex-detector": "^1.3.0"
+    "uglify-js": "^3.17.4"
   },
   "scripts": {
     "test": "cross-env NODE_OPTIONS=--loader=ts-node/esm jasmine --config=jasmine.json",
-    "test:all": "npm test && npm run test:lint",
+    "test:all": "npm test && npm run test:umd && npm run test:types && npm run test:lint",
     "test:unit": "npm test -- test/unit/**/*-spec.js",
     "test:specs": "npm test -- test/specs/**/*-spec.js",
     "test:lint": "eslint .",
     "test:redos": "node test/recheck.js > vuln.js",
+    "test:types": "tsc --project tsconfig-type-test.json",
+    "test:umd": "node test/umd-test.js",
     "test:update": "node test/update-specs.js",
     "rules": "node test/rules.js",
     "bench": "npm run build && node test/bench.js",
     "lint": "eslint --fix .",
-    "type-check": "tsc",
     "build:reset": "git checkout upstream/master lib/marked.cjs lib/marked.umd.js lib/marked.esm.js marked.min.js",
-    "build": "npm run type-check && tsup && npm run build:verify && npm run minify",
+    "build": "npm run rollup && npm run minify",
     "build:docs": "node build-docs.js",
-    "build:verify": "tsc --project tsconfig-type-test.json",
+    "build:types": "tsc --project tsconfig-types.json",
+    "rollup": "rollup -c rollup.config.js",
     "minify": "uglifyjs lib/marked.umd.js -cm  --comments /Copyright/ -o marked.min.js"
   },
   "engines": {

+ 49 - 0
rollup.config.js

@@ -0,0 +1,49 @@
+import typescript from '@rollup/plugin-typescript';
+import { defineConfig } from 'rollup';
+import fs from 'fs';
+
+const pkg = JSON.parse(fs.readFileSync('./package.json'));
+const version = process.env.SEMANTIC_RELEASE_NEXT_VERSION || pkg.version;
+
+console.log('building version:', version);
+
+const banner = `/**
+ * marked v${version} - a markdown parser
+ * Copyright (c) 2011-${new Date().getFullYear()}, Christopher Jeffrey. (MIT Licensed)
+ * https://github.com/markedjs/marked
+ */
+
+/**
+ * DO NOT EDIT THIS FILE
+ * The code in this file is generated from files in ./src/
+ */
+`;
+
+export default defineConfig([
+  {
+    input: 'src/marked.ts',
+    output: [{
+      file: 'lib/marked.esm.js',
+      format: 'esm',
+      sourcemap: true,
+      banner
+    },
+    {
+      file: 'lib/marked.umd.js',
+      format: 'umd',
+      name: 'marked',
+      sourcemap: true,
+      banner
+    },
+    {
+      file: 'lib/marked.cjs',
+      format: 'cjs',
+      name: 'marked',
+      sourcemap: true,
+      banner
+    }],
+    plugins: [
+      typescript()
+    ]
+  }
+]);

+ 1 - 1
src/helpers.ts

@@ -1,5 +1,5 @@
 import type { MarkedOptions } from './MarkedOptions.ts';
-import type { ResultCallback } from './marked.ts';
+import type { ResultCallback } from './Instance.ts';
 import type { Rule } from './rules.ts';
 
 /**

+ 1 - 2
src/marked.ts

@@ -13,8 +13,7 @@ import {
 } from './defaults.ts';
 import type { MarkedExtension, MarkedOptions } from './MarkedOptions.ts';
 import type { Token, TokensList } from './Tokens.ts';
-
-export type ResultCallback = (error: Error | null, parseResult?: string) => undefined | void;
+import type { ResultCallback } from './Instance.ts';
 
 const markedInstance = new Marked();
 

+ 6 - 0
test/umd-test.js

@@ -0,0 +1,6 @@
+import '../lib/marked.umd.js';
+
+// eslint-disable-next-line no-undef
+if (!marked.parse('# test').includes('<h1')) {
+  throw new Error('Invalid markdown');
+}

+ 17 - 0
tsconfig-types.json

@@ -0,0 +1,17 @@
+{
+  "compilerOptions": {
+    "target": "es2022",
+    "module": "NodeNext",
+    "strict": true,
+    "declaration": true,
+    "emitDeclarationOnly": true,
+    "allowSyntheticDefaultImports": true,
+    "moduleResolution": "NodeNext",
+    "noImplicitAny": false,
+    "allowImportingTsExtensions": true,
+    "outFile": "lib/marked.d.ts"
+  },
+  "include": [
+    "src/*.ts"
+  ]
+}

+ 1 - 1
tsconfig.json

@@ -1,6 +1,6 @@
 {
   "compilerOptions": {
-    "target": "es2021",
+    "target": "es2022",
     "module": "NodeNext",
     "isolatedModules": true,
     "strict": true,

+ 0 - 47
tsup.config.ts

@@ -1,47 +0,0 @@
-import { defineConfig } from 'tsup';
-import fs from 'fs';
-
-const pkg = JSON.parse(String(fs.readFileSync('./package.json')));
-const version = process.env.SEMANTIC_RELEASE_NEXT_VERSION || pkg.version;
-
-console.log('building version:', version);
-
-const banner = `/**
- * marked v${version} - a markdown parser
- * Copyright (c) 2011-${new Date().getFullYear()}, Christopher Jeffrey. (MIT Licensed)
- * https://github.com/markedjs/marked
- */
-
-/**
- * DO NOT EDIT THIS FILE
- * The code in this file is generated from files in ./src/
- */
-`;
-
-export default defineConfig({
-  entry: ['src/marked.ts'],
-  splitting: false,
-  sourcemap: true,
-  clean: true,
-  format: ['cjs', 'esm', 'iife'],
-  globalName: 'marked',
-  banner: {
-    js: banner
-  },
-  outDir: 'lib',
-  outExtension({ format }) {
-    if (format === 'cjs') {
-      return {
-        js: '.cjs'
-      };
-    } else if (format === 'iife') {
-      return {
-        js: '.umd.js'
-      };
-    }
-    return {
-      js: `.${format}.js`
-    };
-  },
-  dts: true
-});

Some files were not shown because too many files changed in this diff