{"version":3,"sources":["../src/markdown.ts","../src/components/data/markdownEscape.ts"],"sourcesContent":["// React-free entry (`@flytedan/flytebot-design-system/markdown`): safe to import on a server.\nexport { escapeMarkdown, markdownToText } from \"./components/data/markdownEscape\";\n","/* DS-7: the one definition of the markdown escape rule, shared by the renderer\n   (Markdown.tsx) and by `escapeMarkdown` (a React-free entry, so a server can import it). */\n\n/** CommonMark: a backslash before any ASCII punctuation character makes it literal. */\nexport const ESCAPABLE = /\\\\([!-/:-@[-`{-~])/g;\n\n/* An escaped character is swapped for a private-use stand-in (U+E000 + its code) before any\n   syntax pattern runs, so no pattern can see it, then swapped back where text is emitted. */\nconst STAND_IN_BASE = 0xe000;\nconst STAND_IN = /[-]/g;\n\n/** Hide every escaped character from the syntax patterns. Stray stand-ins already in the input are neutralised first. */\nexport const hideEscapes = (s: string): string =>\n  s.replace(STAND_IN, \"�\").replace(ESCAPABLE, (_, c: string) => String.fromCharCode(STAND_IN_BASE + c.charCodeAt(0)));\n\n/** Put escaped characters back as the literal character. */\nexport const showEscapes = (s: string): string => s.replace(STAND_IN, (c) => String.fromCharCode(c.charCodeAt(0) - STAND_IN_BASE));\n\n/** Put escaped characters back with their backslash (a code span keeps its source verbatim). */\nexport const showEscapesRaw = (s: string): string => s.replace(STAND_IN, (c) => \"\\\\\" + String.fromCharCode(c.charCodeAt(0) - STAND_IN_BASE));\n\n/**\n * Backslash-escape text so `Markdown` / `MarkdownInline` render it as exactly that text:\n * every character the renderer reads as inline syntax, the `:` that starts a bare-URL or\n * mailto autolink, and any block marker (heading, quote, list, rule, table, fence) at the\n * start of a line.\n */\nexport function escapeMarkdown(text: string): string {\n  return String(text == null ? \"\" : text)\n    .replace(/\\r\\n?/g, \"\\n\")\n    .replace(/[\\\\`*_[\\]()<>!|~^]/g, \"\\\\$&\")\n    .replace(/\\b(https?|mailto|tel):/gi, \"$1\\\\:\")\n    .split(\"\\n\")\n    .map((line) =>\n      line\n        // heading, quote, bullet, rule, fence-like markers: escape the first marker character\n        .replace(/^(\\s*)([#>+-])/, \"$1\\\\$2\")\n        // ordered list: escape the dot or paren after the number\n        .replace(/^(\\s*\\d{1,9})([.)])/, \"$1\\\\$2\")\n        // task item `[ ]` is already covered by escaping `[`\n    )\n    .join(\"\\n\");\n}\n\nconst TABLE_ROW = /^\\s*\\|.*\\|\\s*$/;\nconst TABLE_SEPARATOR = /^\\s*\\|(\\s*:?-{3,}:?\\s*\\|)+\\s*$/;\nconst LIST_MARKER = /^\\s*(?:[-*+]|\\d{1,9}[.)])\\s+/;\n\n/* DS-12: table pipes, the separator row and list markers are layout, not words. Escaped pipes\n   and markers are already hidden, so they stay literal. Fenced code is left untouched. */\nfunction stripBlockSyntax(s: string): string {\n  let inFence = false;\n  return s\n    .split(\"\\n\")\n    .flatMap((line) => {\n      if (/^\\s*```/.test(line)) inFence = !inFence;\n      if (inFence || /^\\s*```/.test(line)) return [line];\n      if (TABLE_SEPARATOR.test(line)) return [];\n      if (TABLE_ROW.test(line)) {\n        return [line.trim().slice(1, -1).split(\"|\").map((c) => c.trim()).filter(Boolean).join(\" \")];\n      }\n      return [line.replace(LIST_MARKER, \"\")];\n    })\n    .join(\"\\n\");\n}\n\n/**\n * Strip markdown to the plain text the renderer shows — for search, copy actions, titles and\n * previews. Escaped characters become literal text; only real syntax is removed, so\n * `markdownToText(escapeMarkdown(x)) === x`. A code span keeps its source verbatim.\n */\nexport function markdownToText(src: string): string {\n  return showEscapes(\n    stripBlockSyntax(hideEscapes(String(src == null ? \"\" : src)))\n      .replace(/```[\\w+#-]*\\n?([\\s\\S]*?)```/g, (_, c: string) => showEscapesRaw(c))\n      .replace(/`([^`]+)`/g, (_, c: string) => showEscapesRaw(c))\n      .replace(/!\\[([^\\]]*)\\]\\([^)]*\\)/g, \"$1\")\n      .replace(/\\[([^\\]]+)\\]\\([^)]*\\)/g, \"$1\")\n      .replace(/^\\s{0,3}#{1,6}\\s+/gm, \"\")\n      .replace(/\\*\\*\\*([^*]+)\\*\\*\\*|\\*\\*([^*]+)\\*\\*|__([^_]+)__/g, \"$1$2$3\")\n      .replace(/(^|\\W)[*_]([^*_\\n]+)[*_](\\W|$)/g, \"$1$2$3\")\n      .replace(/~~([^~]+)~~/g, \"$1\")\n      .replace(/^\\s*>\\s?/gm, \"\")\n      .trim(),\n  );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACIO,IAAM,YAAY;AAIzB,IAAM,gBAAgB;AACtB,IAAM,WAAW;AAGV,IAAM,cAAc,CAAC,MAC1B,EAAE,QAAQ,UAAU,QAAG,EAAE,QAAQ,WAAW,CAAC,GAAG,MAAc,OAAO,aAAa,gBAAgB,EAAE,WAAW,CAAC,CAAC,CAAC;AAG7G,IAAM,cAAc,CAAC,MAAsB,EAAE,QAAQ,UAAU,CAAC,MAAM,OAAO,aAAa,EAAE,WAAW,CAAC,IAAI,aAAa,CAAC;AAG1H,IAAM,iBAAiB,CAAC,MAAsB,EAAE,QAAQ,UAAU,CAAC,MAAM,OAAO,OAAO,aAAa,EAAE,WAAW,CAAC,IAAI,aAAa,CAAC;AAQpI,SAAS,eAAe,MAAsB;AACnD,SAAO,OAAO,QAAQ,OAAO,KAAK,IAAI,EACnC,QAAQ,UAAU,IAAI,EACtB,QAAQ,uBAAuB,MAAM,EACrC,QAAQ,4BAA4B,OAAO,EAC3C,MAAM,IAAI,EACV;AAAA,IAAI,CAAC,SACJ,KAEG,QAAQ,kBAAkB,QAAQ,EAElC,QAAQ,uBAAuB,QAAQ;AAAA;AAAA,EAE5C,EACC,KAAK,IAAI;AACd;AAEA,IAAM,YAAY;AAClB,IAAM,kBAAkB;AACxB,IAAM,cAAc;AAIpB,SAAS,iBAAiB,GAAmB;AAC3C,MAAI,UAAU;AACd,SAAO,EACJ,MAAM,IAAI,EACV,QAAQ,CAAC,SAAS;AACjB,QAAI,UAAU,KAAK,IAAI,EAAG,WAAU,CAAC;AACrC,QAAI,WAAW,UAAU,KAAK,IAAI,EAAG,QAAO,CAAC,IAAI;AACjD,QAAI,gBAAgB,KAAK,IAAI,EAAG,QAAO,CAAC;AACxC,QAAI,UAAU,KAAK,IAAI,GAAG;AACxB,aAAO,CAAC,KAAK,KAAK,EAAE,MAAM,GAAG,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,CAAC;AAAA,IAC5F;AACA,WAAO,CAAC,KAAK,QAAQ,aAAa,EAAE,CAAC;AAAA,EACvC,CAAC,EACA,KAAK,IAAI;AACd;AAOO,SAAS,eAAe,KAAqB;AAClD,SAAO;AAAA,IACL,iBAAiB,YAAY,OAAO,OAAO,OAAO,KAAK,GAAG,CAAC,CAAC,EACzD,QAAQ,gCAAgC,CAAC,GAAG,MAAc,eAAe,CAAC,CAAC,EAC3E,QAAQ,cAAc,CAAC,GAAG,MAAc,eAAe,CAAC,CAAC,EACzD,QAAQ,2BAA2B,IAAI,EACvC,QAAQ,0BAA0B,IAAI,EACtC,QAAQ,uBAAuB,EAAE,EACjC,QAAQ,oDAAoD,QAAQ,EACpE,QAAQ,mCAAmC,QAAQ,EACnD,QAAQ,gBAAgB,IAAI,EAC5B,QAAQ,cAAc,EAAE,EACxB,KAAK;AAAA,EACV;AACF;","names":[]}