@notectl/core 2.2.6 → 2.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (544) hide show
  1. package/README.md +1 -1
  2. package/THIRD-PARTY-NOTICES.md +129 -0
  3. package/dist/chunks/{AlignmentPlugin-DeD4C4EP.mjs → AlignmentPlugin-C9Rr_R-g.mjs} +2 -2
  4. package/dist/chunks/{AlignmentPlugin-DeD4C4EP.mjs.map → AlignmentPlugin-C9Rr_R-g.mjs.map} +1 -1
  5. package/dist/chunks/{AttrRegistry-DcDVyzLm.mjs → AttrRegistry-B3zB02z9.mjs} +2 -2
  6. package/dist/chunks/AttrRegistry-B3zB02z9.mjs.map +1 -0
  7. package/dist/chunks/AttributedMarkCommands-BCvmqeFZ.mjs +2 -0
  8. package/dist/chunks/{AttributedMarkCommands-D4W2Jgpj.mjs.map → AttributedMarkCommands-BCvmqeFZ.mjs.map} +1 -1
  9. package/dist/chunks/{BidiIsolationPlugin-BddRbDCN.mjs → BidiIsolationPlugin-Cw2KMk-H.mjs} +2 -2
  10. package/dist/chunks/{BidiIsolationPlugin-BddRbDCN.mjs.map → BidiIsolationPlugin-Cw2KMk-H.mjs.map} +1 -1
  11. package/dist/chunks/BlockInsertion-CYH2gRkY.mjs +2 -0
  12. package/dist/chunks/BlockInsertion-CYH2gRkY.mjs.map +1 -0
  13. package/dist/chunks/BlockquotePlugin-0bZSbkyo.mjs +2 -0
  14. package/dist/chunks/{BlockquotePlugin-4V7KV_Sb.mjs.map → BlockquotePlugin-0bZSbkyo.mjs.map} +1 -1
  15. package/dist/chunks/CaretNavigationPlugin-BPZ9b6XR.mjs +2 -0
  16. package/dist/chunks/CaretNavigationPlugin-BPZ9b6XR.mjs.map +1 -0
  17. package/dist/chunks/CodeBlockPlugin-BCJ3faXx.mjs +2 -0
  18. package/dist/chunks/CodeBlockPlugin-BCJ3faXx.mjs.map +1 -0
  19. package/dist/chunks/{ColorGrid-DPNiXxpD.mjs → ColorGrid-DQEkJ-0y.mjs} +2 -2
  20. package/dist/chunks/{ColorGrid-DPNiXxpD.mjs.map → ColorGrid-DQEkJ-0y.mjs.map} +1 -1
  21. package/dist/chunks/{ColorPickerPopup-lcf3jS6G.mjs → ColorPickerPopup-CyF26zIU.mjs} +2 -2
  22. package/dist/chunks/{ColorPickerPopup-lcf3jS6G.mjs.map → ColorPickerPopup-CyF26zIU.mjs.map} +1 -1
  23. package/dist/chunks/Commands-D5ND50PQ.mjs +2 -0
  24. package/dist/chunks/Commands-D5ND50PQ.mjs.map +1 -0
  25. package/dist/chunks/ContentModel-NpAj7vGW.mjs +2 -0
  26. package/dist/chunks/ContentModel-NpAj7vGW.mjs.map +1 -0
  27. package/dist/chunks/Decoration-BOP1TAUd.mjs +2 -0
  28. package/dist/chunks/Decoration-BOP1TAUd.mjs.map +1 -0
  29. package/dist/chunks/{DirectionDetection-C7XE0nxW.mjs → DirectionDetection-CDVSEWQ6.mjs} +2 -2
  30. package/dist/chunks/{DirectionDetection-C7XE0nxW.mjs.map → DirectionDetection-CDVSEWQ6.mjs.map} +1 -1
  31. package/dist/chunks/Document-827l3P80.mjs +2 -0
  32. package/dist/chunks/Document-827l3P80.mjs.map +1 -0
  33. package/dist/chunks/DocumentParser-D2tr3ZKn.mjs +2 -0
  34. package/dist/chunks/DocumentParser-D2tr3ZKn.mjs.map +1 -0
  35. package/dist/chunks/EditorEventBoundary-zpYRxryo.mjs +2 -0
  36. package/dist/chunks/EditorEventBoundary-zpYRxryo.mjs.map +1 -0
  37. package/dist/chunks/{FontPlugin-DQMj65Bc.mjs → FontPlugin-D041tiLe.mjs} +2 -2
  38. package/dist/chunks/{FontPlugin-DQMj65Bc.mjs.map → FontPlugin-D041tiLe.mjs.map} +1 -1
  39. package/dist/chunks/{FontSizePlugin-9StCjEfN.mjs → FontSizePlugin-8CAvj1RD.mjs} +2 -2
  40. package/dist/chunks/FontSizePlugin-8CAvj1RD.mjs.map +1 -0
  41. package/dist/chunks/FormulaPlugin-DJ39BtqV.mjs +2 -0
  42. package/dist/chunks/FormulaPlugin-DJ39BtqV.mjs.map +1 -0
  43. package/dist/chunks/GapCursorNavigation-DCWOmopl.mjs +2 -0
  44. package/dist/chunks/{GapCursorNavigation-ycNzuQVH.mjs.map → GapCursorNavigation-DCWOmopl.mjs.map} +1 -1
  45. package/dist/chunks/GapCursorPlugin-2iR6506y.mjs +2 -0
  46. package/dist/chunks/{GapCursorPlugin-Zvxjnr82.mjs.map → GapCursorPlugin-2iR6506y.mjs.map} +1 -1
  47. package/dist/chunks/HTMLUtils-Bhg3_P8B.mjs +2 -0
  48. package/dist/chunks/HTMLUtils-Bhg3_P8B.mjs.map +1 -0
  49. package/dist/chunks/{HardBreakPlugin-9DOyCyyM.mjs → HardBreakPlugin-vniSvTgq.mjs} +2 -2
  50. package/dist/chunks/{HardBreakPlugin-9DOyCyyM.mjs.map → HardBreakPlugin-vniSvTgq.mjs.map} +1 -1
  51. package/dist/chunks/HeadingPlugin-DUKsLuMd.mjs +2 -0
  52. package/dist/chunks/{HeadingPlugin-BuGoM9Rz.mjs.map → HeadingPlugin-DUKsLuMd.mjs.map} +1 -1
  53. package/dist/chunks/{HighlightPlugin-C6pHifVz.mjs → HighlightPlugin-DRTAE1N5.mjs} +2 -2
  54. package/dist/chunks/{HighlightPlugin-C6pHifVz.mjs.map → HighlightPlugin-DRTAE1N5.mjs.map} +1 -1
  55. package/dist/chunks/HorizontalRulePlugin-B9OvwrKB.mjs +2 -0
  56. package/dist/chunks/HorizontalRulePlugin-B9OvwrKB.mjs.map +1 -0
  57. package/dist/chunks/ImagePlugin-CwxTRr6d.mjs +2 -0
  58. package/dist/chunks/{ImagePlugin-KpkuE2LH.mjs.map → ImagePlugin-CwxTRr6d.mjs.map} +1 -1
  59. package/dist/chunks/{InlineCodePlugin-DMr4O7c7.mjs → InlineCodePlugin-uxgMUX_E.mjs} +2 -2
  60. package/dist/chunks/InlineCodePlugin-uxgMUX_E.mjs.map +1 -0
  61. package/dist/chunks/InlineStyleMarkSpec-CjSRj4f_.mjs +2 -0
  62. package/dist/chunks/{InlineStyleMarkSpec-C6LJT7kp.mjs.map → InlineStyleMarkSpec-CjSRj4f_.mjs.map} +1 -1
  63. package/dist/chunks/LinkPlugin-CvWHbSkb.mjs +2 -0
  64. package/dist/chunks/LinkPlugin-CvWHbSkb.mjs.map +1 -0
  65. package/dist/chunks/ListPlugin-BchSFWVn.mjs +2 -0
  66. package/dist/chunks/ListPlugin-BchSFWVn.mjs.map +1 -0
  67. package/dist/chunks/MarkInputRule-Bdi8KPus.mjs +2 -0
  68. package/dist/chunks/MarkInputRule-Bdi8KPus.mjs.map +1 -0
  69. package/dist/chunks/MarkdownHTMLRegistry-Q7l0d6Ma.mjs +2 -0
  70. package/dist/chunks/MarkdownHTMLRegistry-Q7l0d6Ma.mjs.map +1 -0
  71. package/dist/chunks/MarkdownParser-Dp62mfUq.mjs +2 -0
  72. package/dist/chunks/MarkdownParser-Dp62mfUq.mjs.map +1 -0
  73. package/dist/chunks/MarkdownSerializer-DBELFAeo.mjs +2 -0
  74. package/dist/chunks/MarkdownSerializer-DBELFAeo.mjs.map +1 -0
  75. package/dist/chunks/MathFont-BS8IwYh2.mjs +2 -0
  76. package/dist/chunks/MathFont-BS8IwYh2.mjs.map +1 -0
  77. package/dist/chunks/{NodeResolver-ChgLF_IP.mjs → NodeResolver-Dleih-8R.mjs} +2 -2
  78. package/dist/chunks/{NodeResolver-ChgLF_IP.mjs.map → NodeResolver-Dleih-8R.mjs.map} +1 -1
  79. package/dist/chunks/NodeSelectionCommands-WH5snxr_.mjs +2 -0
  80. package/dist/chunks/{NodeSelectionCommands-Dj4VxLdD.mjs.map → NodeSelectionCommands-WH5snxr_.mjs.map} +1 -1
  81. package/dist/chunks/{PopupManager-DUtaK3WX.mjs → PopupManager-Cj86uDEB.mjs} +2 -2
  82. package/dist/chunks/{PopupManager-DUtaK3WX.mjs.map → PopupManager-Cj86uDEB.mjs.map} +1 -1
  83. package/dist/chunks/PopupPositioning-BFh6Ed1D.mjs +2 -0
  84. package/dist/chunks/{PopupPositioning-BB97-__N.mjs.map → PopupPositioning-BFh6Ed1D.mjs.map} +1 -1
  85. package/dist/chunks/PrintPlugin-D2javl_d.mjs +2 -0
  86. package/dist/chunks/PrintPlugin-D2javl_d.mjs.map +1 -0
  87. package/dist/chunks/{RangeIterator-o8v3msQe.mjs → RangeIterator-DP7Ud3Gp.mjs} +2 -2
  88. package/dist/chunks/{RangeIterator-o8v3msQe.mjs.map → RangeIterator-DP7Ud3Gp.mjs.map} +1 -1
  89. package/dist/chunks/SchemaRegistry-CkBN-1yW.mjs +2 -0
  90. package/dist/chunks/SchemaRegistry-CkBN-1yW.mjs.map +1 -0
  91. package/dist/chunks/SimpleMark-gTQaSJcO.mjs +2 -0
  92. package/dist/chunks/{SimpleMark-CaQtFAau.mjs.map → SimpleMark-gTQaSJcO.mjs.map} +1 -1
  93. package/dist/chunks/SmartPastePlugin-BvJQ-fOz.mjs +2 -0
  94. package/dist/chunks/SmartPastePlugin-BvJQ-fOz.mjs.map +1 -0
  95. package/dist/chunks/StarterFonts-BDQPg-cu.mjs +2 -0
  96. package/dist/chunks/StarterFonts-BDQPg-cu.mjs.map +1 -0
  97. package/dist/chunks/StrikethroughPlugin-BdrG1TTY.mjs +2 -0
  98. package/dist/chunks/StrikethroughPlugin-BdrG1TTY.mjs.map +1 -0
  99. package/dist/chunks/StyleRuntime-DW6omotc.mjs +2 -0
  100. package/dist/chunks/StyleRuntime-DW6omotc.mjs.map +1 -0
  101. package/dist/chunks/{SuperSubPlugin-DVP7VnIz.mjs → SuperSubPlugin-DTZB0Y3D.mjs} +2 -2
  102. package/dist/chunks/{SuperSubPlugin-DVP7VnIz.mjs.map → SuperSubPlugin-DTZB0Y3D.mjs.map} +1 -1
  103. package/dist/chunks/TableDimensions-BBhjHNjQ.mjs +2 -0
  104. package/dist/chunks/TableDimensions-BBhjHNjQ.mjs.map +1 -0
  105. package/dist/chunks/TablePlugin-CPvg9YZS.mjs +2 -0
  106. package/dist/chunks/TablePlugin-CPvg9YZS.mjs.map +1 -0
  107. package/dist/chunks/TextColorPlugin-Ckg3KWvb.mjs +2 -0
  108. package/dist/chunks/{TextColorPlugin-CEfZQ6Md.mjs.map → TextColorPlugin-Ckg3KWvb.mjs.map} +1 -1
  109. package/dist/chunks/TextDirectionAutoPlugin-DRGbgTlx.mjs +2 -0
  110. package/dist/chunks/{TextDirectionAutoPlugin-CzWJjrvG.mjs.map → TextDirectionAutoPlugin-DRGbgTlx.mjs.map} +1 -1
  111. package/dist/chunks/TextDirectionPlugin-BCeYyJHo.mjs +2 -0
  112. package/dist/chunks/{TextDirectionPlugin-DHB88HKf.mjs.map → TextDirectionPlugin-BCeYyJHo.mjs.map} +1 -1
  113. package/dist/chunks/TextFormattingPlugin-BhRxSC8q.mjs +2 -0
  114. package/dist/chunks/TextFormattingPlugin-BhRxSC8q.mjs.map +1 -0
  115. package/dist/chunks/ThemeEngine-BUVo_zaT.mjs +3 -0
  116. package/dist/chunks/ThemeEngine-BUVo_zaT.mjs.map +1 -0
  117. package/dist/chunks/ToolbarPlugin-dmTj1jIz.mjs +2 -0
  118. package/dist/chunks/{ToolbarPlugin-DVGrFf8v.mjs.map → ToolbarPlugin-dmTj1jIz.mjs.map} +1 -1
  119. package/dist/chunks/VideoPlugin-BugkI7-m.mjs +2 -0
  120. package/dist/chunks/VideoPlugin-BugkI7-m.mjs.map +1 -0
  121. package/dist/chunks/WordBoundary-CFpIJDNP.mjs +2 -0
  122. package/dist/chunks/{WordBoundary-DxeMBRyP.mjs.map → WordBoundary-CFpIJDNP.mjs.map} +1 -1
  123. package/dist/chunks/XmlSupport-DIXH5on9.mjs +2 -0
  124. package/dist/chunks/XmlSupport-DIXH5on9.mjs.map +1 -0
  125. package/dist/chunks/ar-Dg9PdDet.mjs +2 -0
  126. package/dist/chunks/ar-Dg9PdDet.mjs.map +1 -0
  127. package/dist/chunks/ar-eOA3UmiE.mjs +2 -0
  128. package/dist/chunks/{ar-BTShmP2E.mjs.map → ar-eOA3UmiE.mjs.map} +1 -1
  129. package/dist/chunks/de-DJ5EkXQo.mjs +2 -0
  130. package/dist/chunks/de-DJ5EkXQo.mjs.map +1 -0
  131. package/dist/chunks/{de-C--bRmjW.mjs → de-DRbhnS4T.mjs} +2 -2
  132. package/dist/chunks/{de-C--bRmjW.mjs.map → de-DRbhnS4T.mjs.map} +1 -1
  133. package/dist/chunks/{es-DFUVd7eO.mjs → es-BQ9dox_E.mjs} +2 -2
  134. package/dist/chunks/{es-DFUVd7eO.mjs.map → es-BQ9dox_E.mjs.map} +1 -1
  135. package/dist/chunks/es-CEAJj7aB.mjs +2 -0
  136. package/dist/chunks/es-CEAJj7aB.mjs.map +1 -0
  137. package/dist/chunks/fr-DhWQzZy3.mjs +2 -0
  138. package/dist/chunks/fr-DhWQzZy3.mjs.map +1 -0
  139. package/dist/chunks/{fr-BaXKyPmX.mjs → fr-NVOinLyF.mjs} +2 -2
  140. package/dist/chunks/{fr-BaXKyPmX.mjs.map → fr-NVOinLyF.mjs.map} +1 -1
  141. package/dist/chunks/full-JM0-SwWy.mjs +2 -0
  142. package/dist/chunks/{full-BBl7mvwH.mjs.map → full-JM0-SwWy.mjs.map} +1 -1
  143. package/dist/chunks/hi-BsZzSMfL.mjs +2 -0
  144. package/dist/chunks/hi-BsZzSMfL.mjs.map +1 -0
  145. package/dist/chunks/{hi-aH9HZG23.mjs → hi-DrC2H81d.mjs} +2 -2
  146. package/dist/chunks/{hi-aH9HZG23.mjs.map → hi-DrC2H81d.mjs.map} +1 -1
  147. package/dist/chunks/minimal-DSlR2A27.mjs +2 -0
  148. package/dist/chunks/{minimal-CtnR4dqp.mjs.map → minimal-DSlR2A27.mjs.map} +1 -1
  149. package/dist/chunks/pt-BuZ7acHF.mjs +2 -0
  150. package/dist/chunks/pt-BuZ7acHF.mjs.map +1 -0
  151. package/dist/chunks/{pt-Hy-0Xnnc.mjs → pt-CFrcl1v_.mjs} +2 -2
  152. package/dist/chunks/{pt-Hy-0Xnnc.mjs.map → pt-CFrcl1v_.mjs.map} +1 -1
  153. package/dist/chunks/register-BjsdJ3Aq.mjs +2 -0
  154. package/dist/chunks/register-BjsdJ3Aq.mjs.map +1 -0
  155. package/dist/chunks/rolldown-runtime-H_PjY6_i.mjs +1 -0
  156. package/dist/chunks/ru-CsP6mLxp.mjs +2 -0
  157. package/dist/chunks/ru-CsP6mLxp.mjs.map +1 -0
  158. package/dist/chunks/{ru-BFpEOrVp.mjs → ru-gxbzqLL8.mjs} +2 -2
  159. package/dist/chunks/{ru-BFpEOrVp.mjs.map → ru-gxbzqLL8.mjs.map} +1 -1
  160. package/dist/chunks/src-5GKFQ2mQ.mjs +2 -0
  161. package/dist/chunks/src-5GKFQ2mQ.mjs.map +1 -0
  162. package/dist/chunks/xml-BsV44TrJ.mjs +2 -0
  163. package/dist/chunks/xml-BsV44TrJ.mjs.map +1 -0
  164. package/dist/chunks/zh-BFZOM3lF.mjs +2 -0
  165. package/dist/chunks/{zh-BjoyjClN.mjs.map → zh-BFZOM3lF.mjs.map} +1 -1
  166. package/dist/chunks/zh-CiIyOm6U.mjs +2 -0
  167. package/dist/chunks/zh-CiIyOm6U.mjs.map +1 -0
  168. package/dist/commands/BlockInsertion.d.ts +5 -3
  169. package/dist/commands/BlockInsertion.d.ts.map +1 -1
  170. package/dist/commands/SelectionDeletion.d.ts +13 -2
  171. package/dist/commands/SelectionDeletion.d.ts.map +1 -1
  172. package/dist/editor/ContentSerializer.d.ts +21 -0
  173. package/dist/editor/ContentSerializer.d.ts.map +1 -1
  174. package/dist/editor/EditorConfig.d.ts +17 -0
  175. package/dist/editor/EditorConfig.d.ts.map +1 -1
  176. package/dist/editor/EditorConfigController.d.ts +10 -0
  177. package/dist/editor/EditorConfigController.d.ts.map +1 -1
  178. package/dist/editor/EditorInitializer.d.ts +4 -0
  179. package/dist/editor/EditorInitializer.d.ts.map +1 -1
  180. package/dist/editor/EditorLocale.d.ts +2 -0
  181. package/dist/editor/EditorLocale.d.ts.map +1 -1
  182. package/dist/editor/MarkdownMode.d.ts +46 -0
  183. package/dist/editor/MarkdownMode.d.ts.map +1 -0
  184. package/dist/editor/NotectlEditor.d.ts +24 -0
  185. package/dist/editor/NotectlEditor.d.ts.map +1 -1
  186. package/dist/editor/locales/ar.d.ts.map +1 -1
  187. package/dist/editor/locales/de.d.ts.map +1 -1
  188. package/dist/editor/locales/es.d.ts.map +1 -1
  189. package/dist/editor/locales/fr.d.ts.map +1 -1
  190. package/dist/editor/locales/hi.d.ts.map +1 -1
  191. package/dist/editor/locales/pt.d.ts.map +1 -1
  192. package/dist/editor/locales/ru.d.ts.map +1 -1
  193. package/dist/editor/locales/zh.d.ts.map +1 -1
  194. package/dist/editor/styles/list.d.ts +1 -1
  195. package/dist/editor/styles/list.d.ts.map +1 -1
  196. package/dist/editor/styles/table.d.ts +1 -1
  197. package/dist/editor/styles/table.d.ts.map +1 -1
  198. package/dist/fonts/math.d.ts +3 -0
  199. package/dist/fonts/math.d.ts.map +1 -0
  200. package/dist/fonts/math.mjs +1 -0
  201. package/dist/fonts/starter.d.ts +3 -0
  202. package/dist/fonts/starter.d.ts.map +1 -0
  203. package/dist/fonts/starter.mjs +1 -0
  204. package/dist/fonts.d.ts +4 -4
  205. package/dist/fonts.mjs +1 -1
  206. package/dist/full.d.ts +1 -1
  207. package/dist/full.mjs +1 -1
  208. package/dist/html.d.ts +1 -0
  209. package/dist/html.d.ts.map +1 -1
  210. package/dist/html.mjs +1 -1
  211. package/dist/index.d.ts +7 -6
  212. package/dist/index.d.ts.map +1 -1
  213. package/dist/input/ClipboardHandler.d.ts +2 -0
  214. package/dist/input/ClipboardHandler.d.ts.map +1 -1
  215. package/dist/input/InputHandler.d.ts +7 -0
  216. package/dist/input/InputHandler.d.ts.map +1 -1
  217. package/dist/input/InputManager.d.ts +10 -0
  218. package/dist/input/InputManager.d.ts.map +1 -1
  219. package/dist/input/KeyboardHandler.d.ts.map +1 -1
  220. package/dist/input/MarkdownPasteDetector.d.ts +26 -0
  221. package/dist/input/MarkdownPasteDetector.d.ts.map +1 -0
  222. package/dist/input/PasteHTMLHandler.d.ts +18 -1
  223. package/dist/input/PasteHTMLHandler.d.ts.map +1 -1
  224. package/dist/input/PasteHandler.d.ts +30 -0
  225. package/dist/input/PasteHandler.d.ts.map +1 -1
  226. package/dist/input/PasteRichBlockHandler.d.ts.map +1 -1
  227. package/dist/input/SelectionDocument.d.ts +2 -1
  228. package/dist/input/SelectionDocument.d.ts.map +1 -1
  229. package/dist/markdown.d.ts +17 -0
  230. package/dist/markdown.d.ts.map +1 -0
  231. package/dist/markdown.mjs +1 -0
  232. package/dist/model/AttrRegistry.d.ts +2 -2
  233. package/dist/model/AttrRegistry.d.ts.map +1 -1
  234. package/dist/model/ContentModel.d.ts +12 -0
  235. package/dist/model/ContentModel.d.ts.map +1 -1
  236. package/dist/model/Document.d.ts +28 -3
  237. package/dist/model/Document.d.ts.map +1 -1
  238. package/dist/model/HTMLUtils.d.ts +15 -0
  239. package/dist/model/HTMLUtils.d.ts.map +1 -1
  240. package/dist/model/InlineNodeSpec.d.ts +7 -1
  241. package/dist/model/InlineNodeSpec.d.ts.map +1 -1
  242. package/dist/model/InputRule.d.ts +11 -0
  243. package/dist/model/InputRule.d.ts.map +1 -1
  244. package/dist/model/MarkSpec.d.ts +7 -1
  245. package/dist/model/MarkSpec.d.ts.map +1 -1
  246. package/dist/model/MarkdownSyntaxRegistry.d.ts +51 -0
  247. package/dist/model/MarkdownSyntaxRegistry.d.ts.map +1 -0
  248. package/dist/model/NodeSpec.d.ts +47 -1
  249. package/dist/model/NodeSpec.d.ts.map +1 -1
  250. package/dist/model/RichBlockData.d.ts +2 -0
  251. package/dist/model/RichBlockData.d.ts.map +1 -1
  252. package/dist/model/SchemaRegistry.d.ts.map +1 -1
  253. package/dist/model/TableDimensions.d.ts +11 -0
  254. package/dist/model/TableDimensions.d.ts.map +1 -0
  255. package/dist/notectl-core.mjs +1 -1
  256. package/dist/notectl-core.umd.js +1 -1
  257. package/dist/notectl-core.umd.js.map +1 -1
  258. package/dist/platform/EditorEventBoundary.d.ts +12 -0
  259. package/dist/platform/EditorEventBoundary.d.ts.map +1 -0
  260. package/dist/plugins/Plugin.d.ts +7 -0
  261. package/dist/plugins/Plugin.d.ts.map +1 -1
  262. package/dist/plugins/PluginContextFactory.d.ts +2 -0
  263. package/dist/plugins/PluginContextFactory.d.ts.map +1 -1
  264. package/dist/plugins/PluginManager.d.ts +2 -0
  265. package/dist/plugins/PluginManager.d.ts.map +1 -1
  266. package/dist/plugins/alignment.mjs +1 -1
  267. package/dist/plugins/bidi-isolation.mjs +1 -1
  268. package/dist/plugins/blockquote/BlockquotePlugin.d.ts +2 -0
  269. package/dist/plugins/blockquote/BlockquotePlugin.d.ts.map +1 -1
  270. package/dist/plugins/blockquote.mjs +1 -1
  271. package/dist/plugins/caret-navigation.mjs +1 -1
  272. package/dist/plugins/code-block/CodeBlockHighlighting.d.ts.map +1 -1
  273. package/dist/plugins/code-block/CodeBlockTypes.d.ts +2 -0
  274. package/dist/plugins/code-block/CodeBlockTypes.d.ts.map +1 -1
  275. package/dist/plugins/code-block.mjs +1 -1
  276. package/dist/plugins/font-size/FontSizeOperations.d.ts.map +1 -1
  277. package/dist/plugins/font-size.mjs +1 -1
  278. package/dist/plugins/font.mjs +1 -1
  279. package/dist/plugins/formula/DisplayMathNodeSpec.d.ts.map +1 -1
  280. package/dist/plugins/formula/FormulaInputRules.d.ts.map +1 -1
  281. package/dist/plugins/formula/FormulaMarkdownSyntax.d.ts +4 -0
  282. package/dist/plugins/formula/FormulaMarkdownSyntax.d.ts.map +1 -0
  283. package/dist/plugins/formula/FormulaPlugin.d.ts.map +1 -1
  284. package/dist/plugins/formula/FormulaTypes.d.ts +3 -1
  285. package/dist/plugins/formula/FormulaTypes.d.ts.map +1 -1
  286. package/dist/plugins/formula/InlineMathNodeSpec.d.ts.map +1 -1
  287. package/dist/plugins/formula.mjs +1 -1
  288. package/dist/plugins/gap-cursor.mjs +1 -1
  289. package/dist/plugins/hard-break.mjs +1 -1
  290. package/dist/plugins/heading/HeadingPlugin.d.ts +2 -0
  291. package/dist/plugins/heading/HeadingPlugin.d.ts.map +1 -1
  292. package/dist/plugins/heading.mjs +1 -1
  293. package/dist/plugins/highlight.mjs +1 -1
  294. package/dist/plugins/horizontal-rule/HorizontalRulePlugin.d.ts +2 -0
  295. package/dist/plugins/horizontal-rule/HorizontalRulePlugin.d.ts.map +1 -1
  296. package/dist/plugins/horizontal-rule.mjs +1 -1
  297. package/dist/plugins/image/ImagePlugin.d.ts +14 -0
  298. package/dist/plugins/image/ImagePlugin.d.ts.map +1 -1
  299. package/dist/plugins/image.mjs +1 -1
  300. package/dist/plugins/inline-code/InlineCodePlugin.d.ts.map +1 -1
  301. package/dist/plugins/inline-code.mjs +1 -1
  302. package/dist/plugins/language.mjs +1 -1
  303. package/dist/plugins/link/LinkPlugin.d.ts +14 -0
  304. package/dist/plugins/link/LinkPlugin.d.ts.map +1 -1
  305. package/dist/plugins/link.mjs +1 -1
  306. package/dist/plugins/list/ListCommands.d.ts +5 -1
  307. package/dist/plugins/list/ListCommands.d.ts.map +1 -1
  308. package/dist/plugins/list/ListInputRules.d.ts.map +1 -1
  309. package/dist/plugins/list/ListItemContext.d.ts +27 -0
  310. package/dist/plugins/list/ListItemContext.d.ts.map +1 -0
  311. package/dist/plugins/list/ListKeyboardHandlers.d.ts.map +1 -1
  312. package/dist/plugins/list/ListPlugin.d.ts +2 -0
  313. package/dist/plugins/list/ListPlugin.d.ts.map +1 -1
  314. package/dist/plugins/list/ListToolbarItems.d.ts.map +1 -1
  315. package/dist/plugins/list.mjs +1 -1
  316. package/dist/plugins/print/PrintContentPreparer.d.ts.map +1 -1
  317. package/dist/plugins/print/PrintDestinationBridge.d.ts +23 -0
  318. package/dist/plugins/print/PrintDestinationBridge.d.ts.map +1 -0
  319. package/dist/plugins/print/PrintHostStyles.d.ts.map +1 -1
  320. package/dist/plugins/print/PrintServiceImpl.d.ts +5 -1
  321. package/dist/plugins/print/PrintServiceImpl.d.ts.map +1 -1
  322. package/dist/plugins/print/PrintStyleCollector.d.ts.map +1 -1
  323. package/dist/plugins/print.mjs +1 -1
  324. package/dist/plugins/shared/MarkInputRule.d.ts +9 -0
  325. package/dist/plugins/shared/MarkInputRule.d.ts.map +1 -0
  326. package/dist/plugins/shared/PopupPositioning.d.ts +2 -0
  327. package/dist/plugins/shared/PopupPositioning.d.ts.map +1 -1
  328. package/dist/plugins/shared/index.d.ts +1 -0
  329. package/dist/plugins/shared/index.d.ts.map +1 -1
  330. package/dist/plugins/shared.mjs +1 -1
  331. package/dist/plugins/smart-paste/SmartPastePlugin.d.ts.map +1 -1
  332. package/dist/plugins/smart-paste.mjs +1 -1
  333. package/dist/plugins/strikethrough/StrikethroughPlugin.d.ts +2 -0
  334. package/dist/plugins/strikethrough/StrikethroughPlugin.d.ts.map +1 -1
  335. package/dist/plugins/strikethrough.mjs +1 -1
  336. package/dist/plugins/super-sub.mjs +1 -1
  337. package/dist/plugins/table/TableClipboard.d.ts +8 -0
  338. package/dist/plugins/table/TableClipboard.d.ts.map +1 -0
  339. package/dist/plugins/table/TableCommands.d.ts.map +1 -1
  340. package/dist/plugins/table/TableContextMenu.d.ts +11 -1
  341. package/dist/plugins/table/TableContextMenu.d.ts.map +1 -1
  342. package/dist/plugins/table/TableControls.d.ts +6 -1
  343. package/dist/plugins/table/TableControls.d.ts.map +1 -1
  344. package/dist/plugins/table/TableControlsDOM.d.ts +11 -2
  345. package/dist/plugins/table/TableControlsDOM.d.ts.map +1 -1
  346. package/dist/plugins/table/TableControlsLayout.d.ts +12 -3
  347. package/dist/plugins/table/TableControlsLayout.d.ts.map +1 -1
  348. package/dist/plugins/table/TableGrid.d.ts +57 -0
  349. package/dist/plugins/table/TableGrid.d.ts.map +1 -0
  350. package/dist/plugins/table/TableHelpers.d.ts +4 -0
  351. package/dist/plugins/table/TableHelpers.d.ts.map +1 -1
  352. package/dist/plugins/table/TableLocale.d.ts +30 -0
  353. package/dist/plugins/table/TableLocale.d.ts.map +1 -1
  354. package/dist/plugins/table/TableNavigation.d.ts +5 -1
  355. package/dist/plugins/table/TableNavigation.d.ts.map +1 -1
  356. package/dist/plugins/table/TableNodeViews.d.ts +13 -1
  357. package/dist/plugins/table/TableNodeViews.d.ts.map +1 -1
  358. package/dist/plugins/table/TablePlugin.d.ts +21 -1
  359. package/dist/plugins/table/TablePlugin.d.ts.map +1 -1
  360. package/dist/plugins/table/TableSelection.d.ts.map +1 -1
  361. package/dist/plugins/table/TableSizeEditor.d.ts +11 -0
  362. package/dist/plugins/table/TableSizeEditor.d.ts.map +1 -0
  363. package/dist/plugins/table/TableSizing.d.ts +70 -0
  364. package/dist/plugins/table/TableSizing.d.ts.map +1 -0
  365. package/dist/plugins/table/index.d.ts +3 -1
  366. package/dist/plugins/table/index.d.ts.map +1 -1
  367. package/dist/plugins/table/locales/ar.d.ts.map +1 -1
  368. package/dist/plugins/table/locales/de.d.ts.map +1 -1
  369. package/dist/plugins/table/locales/es.d.ts.map +1 -1
  370. package/dist/plugins/table/locales/fr.d.ts.map +1 -1
  371. package/dist/plugins/table/locales/hi.d.ts.map +1 -1
  372. package/dist/plugins/table/locales/pt.d.ts.map +1 -1
  373. package/dist/plugins/table/locales/ru.d.ts.map +1 -1
  374. package/dist/plugins/table/locales/zh.d.ts.map +1 -1
  375. package/dist/plugins/table.mjs +1 -1
  376. package/dist/plugins/text-color.mjs +1 -1
  377. package/dist/plugins/text-direction-auto.mjs +1 -1
  378. package/dist/plugins/text-direction.mjs +1 -1
  379. package/dist/plugins/text-formatting/TextFormattingPlugin.d.ts +9 -0
  380. package/dist/plugins/text-formatting/TextFormattingPlugin.d.ts.map +1 -1
  381. package/dist/plugins/text-formatting.mjs +1 -1
  382. package/dist/plugins/toolbar.mjs +1 -1
  383. package/dist/plugins/video/VideoCommands.d.ts.map +1 -1
  384. package/dist/plugins/video.mjs +1 -1
  385. package/dist/presets/full.d.ts +1 -1
  386. package/dist/presets/full.mjs +1 -1
  387. package/dist/presets/minimal.d.ts +1 -1
  388. package/dist/presets/minimal.mjs +1 -1
  389. package/dist/presets.d.ts +1 -1
  390. package/dist/presets.mjs +1 -1
  391. package/dist/register.d.ts +3 -0
  392. package/dist/register.d.ts.map +1 -0
  393. package/dist/register.mjs +1 -0
  394. package/dist/serialization/DocumentParser.d.ts.map +1 -1
  395. package/dist/serialization/DocumentSerializer.d.ts +2 -0
  396. package/dist/serialization/DocumentSerializer.d.ts.map +1 -1
  397. package/dist/serialization/HTMLSanitization.d.ts +15 -0
  398. package/dist/serialization/HTMLSanitization.d.ts.map +1 -0
  399. package/dist/serialization/MarkSerializer.d.ts +12 -0
  400. package/dist/serialization/MarkSerializer.d.ts.map +1 -1
  401. package/dist/serialization/MarkdownParser.d.ts +6 -0
  402. package/dist/serialization/MarkdownParser.d.ts.map +1 -0
  403. package/dist/serialization/MarkdownSerializer.d.ts +12 -0
  404. package/dist/serialization/MarkdownSerializer.d.ts.map +1 -0
  405. package/dist/serialization/MarkdownTypes.d.ts +59 -0
  406. package/dist/serialization/MarkdownTypes.d.ts.map +1 -0
  407. package/dist/serialization/TableDimensions.d.ts +37 -0
  408. package/dist/serialization/TableDimensions.d.ts.map +1 -0
  409. package/dist/serialization/markdown/BlockSerializers.d.ts +7 -0
  410. package/dist/serialization/markdown/BlockSerializers.d.ts.map +1 -0
  411. package/dist/serialization/markdown/BlockTokenizer.d.ts +54 -0
  412. package/dist/serialization/markdown/BlockTokenizer.d.ts.map +1 -0
  413. package/dist/serialization/markdown/GfmAutolink.d.ts +20 -0
  414. package/dist/serialization/markdown/GfmAutolink.d.ts.map +1 -0
  415. package/dist/serialization/markdown/GfmTableParser.d.ts +26 -0
  416. package/dist/serialization/markdown/GfmTableParser.d.ts.map +1 -0
  417. package/dist/serialization/markdown/InlineAst.d.ts +34 -0
  418. package/dist/serialization/markdown/InlineAst.d.ts.map +1 -0
  419. package/dist/serialization/markdown/InlineSerializers.d.ts +5 -0
  420. package/dist/serialization/markdown/InlineSerializers.d.ts.map +1 -0
  421. package/dist/serialization/markdown/InlineTokenizer.d.ts +5 -0
  422. package/dist/serialization/markdown/InlineTokenizer.d.ts.map +1 -0
  423. package/dist/serialization/markdown/LinkReferenceExtractor.d.ts +37 -0
  424. package/dist/serialization/markdown/LinkReferenceExtractor.d.ts.map +1 -0
  425. package/dist/serialization/markdown/MarkdownContext.d.ts +32 -0
  426. package/dist/serialization/markdown/MarkdownContext.d.ts.map +1 -0
  427. package/dist/serialization/markdown/MarkdownEntities.d.ts +33 -0
  428. package/dist/serialization/markdown/MarkdownEntities.d.ts.map +1 -0
  429. package/dist/serialization/markdown/MarkdownEscape.d.ts +33 -0
  430. package/dist/serialization/markdown/MarkdownEscape.d.ts.map +1 -0
  431. package/dist/serialization/markdown/MarkdownHTMLRegistry.d.ts +4 -0
  432. package/dist/serialization/markdown/MarkdownHTMLRegistry.d.ts.map +1 -0
  433. package/dist/serialization/markdown/MarkdownParseContext.d.ts +23 -0
  434. package/dist/serialization/markdown/MarkdownParseContext.d.ts.map +1 -0
  435. package/dist/state/Mapping.d.ts +33 -10
  436. package/dist/state/Mapping.d.ts.map +1 -1
  437. package/dist/state/StepApplication.d.ts +3 -1
  438. package/dist/state/StepApplication.d.ts.map +1 -1
  439. package/dist/state/StepHandlers.d.ts.map +1 -1
  440. package/dist/state/StepInversion.d.ts +2 -1
  441. package/dist/state/StepInversion.d.ts.map +1 -1
  442. package/dist/state/StepMapping.d.ts +3 -2
  443. package/dist/state/StepMapping.d.ts.map +1 -1
  444. package/dist/state/StepMaps.d.ts +3 -2
  445. package/dist/state/StepMaps.d.ts.map +1 -1
  446. package/dist/state/Steps.d.ts +34 -2
  447. package/dist/state/Steps.d.ts.map +1 -1
  448. package/dist/state/TransactionBuilder.d.ts +7 -1
  449. package/dist/state/TransactionBuilder.d.ts.map +1 -1
  450. package/dist/test/MarkdownConformanceUtils.d.ts +12 -0
  451. package/dist/test/MarkdownConformanceUtils.d.ts.map +1 -0
  452. package/dist/view/BlockRendering.d.ts +5 -0
  453. package/dist/view/BlockRendering.d.ts.map +1 -1
  454. package/dist/view/DecorationRendering.d.ts +6 -0
  455. package/dist/view/DecorationRendering.d.ts.map +1 -1
  456. package/dist/view/EditorViewEvents.d.ts.map +1 -1
  457. package/dist/view/Reconciler.d.ts.map +1 -1
  458. package/package.json +28 -214
  459. package/dist/chunks/AttrRegistry-DcDVyzLm.mjs.map +0 -1
  460. package/dist/chunks/AttributedMarkCommands-D4W2Jgpj.mjs +0 -2
  461. package/dist/chunks/BlockInsertion-6rR9tIGP.mjs +0 -2
  462. package/dist/chunks/BlockInsertion-6rR9tIGP.mjs.map +0 -1
  463. package/dist/chunks/BlockquotePlugin-4V7KV_Sb.mjs +0 -2
  464. package/dist/chunks/CaretNavigationPlugin-C6XBwp0N.mjs +0 -2
  465. package/dist/chunks/CaretNavigationPlugin-C6XBwp0N.mjs.map +0 -1
  466. package/dist/chunks/CodeBlockPlugin-3V2K3RBe.mjs +0 -2
  467. package/dist/chunks/CodeBlockPlugin-3V2K3RBe.mjs.map +0 -1
  468. package/dist/chunks/Commands-BIIpx_Zd.mjs +0 -2
  469. package/dist/chunks/Commands-BIIpx_Zd.mjs.map +0 -1
  470. package/dist/chunks/Decoration-ZeyVfwJB.mjs +0 -2
  471. package/dist/chunks/Decoration-ZeyVfwJB.mjs.map +0 -1
  472. package/dist/chunks/Document-r7vLOAGA.mjs +0 -2
  473. package/dist/chunks/Document-r7vLOAGA.mjs.map +0 -1
  474. package/dist/chunks/DocumentParser-CcTSeT1B.mjs +0 -2
  475. package/dist/chunks/DocumentParser-CcTSeT1B.mjs.map +0 -1
  476. package/dist/chunks/FontSizePlugin-9StCjEfN.mjs.map +0 -1
  477. package/dist/chunks/FormulaPlugin-CV5VUxkb.mjs +0 -2
  478. package/dist/chunks/FormulaPlugin-CV5VUxkb.mjs.map +0 -1
  479. package/dist/chunks/GapCursorNavigation-ycNzuQVH.mjs +0 -2
  480. package/dist/chunks/GapCursorPlugin-Zvxjnr82.mjs +0 -2
  481. package/dist/chunks/HTMLUtils-C6B4UT00.mjs +0 -2
  482. package/dist/chunks/HTMLUtils-C6B4UT00.mjs.map +0 -1
  483. package/dist/chunks/HeadingPlugin-BuGoM9Rz.mjs +0 -2
  484. package/dist/chunks/HorizontalRulePlugin-0FjHPZuA.mjs +0 -2
  485. package/dist/chunks/HorizontalRulePlugin-0FjHPZuA.mjs.map +0 -1
  486. package/dist/chunks/ImagePlugin-KpkuE2LH.mjs +0 -2
  487. package/dist/chunks/InlineCodePlugin-DMr4O7c7.mjs.map +0 -1
  488. package/dist/chunks/InlineStyleMarkSpec-C6LJT7kp.mjs +0 -2
  489. package/dist/chunks/LinkPlugin-DvZ3MPgL.mjs +0 -2
  490. package/dist/chunks/LinkPlugin-DvZ3MPgL.mjs.map +0 -1
  491. package/dist/chunks/ListPlugin-2yl6KiTK.mjs +0 -2
  492. package/dist/chunks/ListPlugin-2yl6KiTK.mjs.map +0 -1
  493. package/dist/chunks/NodeSelectionCommands-Dj4VxLdD.mjs +0 -2
  494. package/dist/chunks/PopupPositioning-BB97-__N.mjs +0 -2
  495. package/dist/chunks/PrintPlugin-DyIZDY3Q.mjs +0 -2
  496. package/dist/chunks/PrintPlugin-DyIZDY3Q.mjs.map +0 -1
  497. package/dist/chunks/PrintTypes-CxU69qu3.mjs +0 -3
  498. package/dist/chunks/PrintTypes-CxU69qu3.mjs.map +0 -1
  499. package/dist/chunks/SimpleMark-CaQtFAau.mjs +0 -2
  500. package/dist/chunks/SmartPastePlugin-Bi_wpTCV.mjs +0 -2
  501. package/dist/chunks/SmartPastePlugin-Bi_wpTCV.mjs.map +0 -1
  502. package/dist/chunks/StrikethroughPlugin-BLKDRWtf.mjs +0 -2
  503. package/dist/chunks/StrikethroughPlugin-BLKDRWtf.mjs.map +0 -1
  504. package/dist/chunks/StyleRuntime-BFKu52mS.mjs +0 -2
  505. package/dist/chunks/StyleRuntime-BFKu52mS.mjs.map +0 -1
  506. package/dist/chunks/TablePlugin-BTH9VRZq.mjs +0 -2
  507. package/dist/chunks/TablePlugin-BTH9VRZq.mjs.map +0 -1
  508. package/dist/chunks/TextColorPlugin-CEfZQ6Md.mjs +0 -2
  509. package/dist/chunks/TextDirectionAutoPlugin-CzWJjrvG.mjs +0 -2
  510. package/dist/chunks/TextDirectionPlugin-DHB88HKf.mjs +0 -2
  511. package/dist/chunks/TextFormattingPlugin-Cubp3e7f.mjs +0 -2
  512. package/dist/chunks/TextFormattingPlugin-Cubp3e7f.mjs.map +0 -1
  513. package/dist/chunks/ToolbarPlugin-DVGrFf8v.mjs +0 -2
  514. package/dist/chunks/VideoPlugin-B3uf1Dwp.mjs +0 -2
  515. package/dist/chunks/VideoPlugin-B3uf1Dwp.mjs.map +0 -1
  516. package/dist/chunks/WordBoundary-DxeMBRyP.mjs +0 -2
  517. package/dist/chunks/XmlDetector-D7TQpw-e.mjs +0 -2
  518. package/dist/chunks/XmlDetector-D7TQpw-e.mjs.map +0 -1
  519. package/dist/chunks/XmlSupport-BYiRwlkK.mjs +0 -2
  520. package/dist/chunks/XmlSupport-BYiRwlkK.mjs.map +0 -1
  521. package/dist/chunks/ar-BTShmP2E.mjs +0 -2
  522. package/dist/chunks/ar-jbplYWkC.mjs +0 -2
  523. package/dist/chunks/ar-jbplYWkC.mjs.map +0 -1
  524. package/dist/chunks/de-DN-e6G5A.mjs +0 -2
  525. package/dist/chunks/de-DN-e6G5A.mjs.map +0 -1
  526. package/dist/chunks/es-CM55WeEN.mjs +0 -2
  527. package/dist/chunks/es-CM55WeEN.mjs.map +0 -1
  528. package/dist/chunks/fonts-DQC6Uj4r.mjs +0 -2
  529. package/dist/chunks/fonts-DQC6Uj4r.mjs.map +0 -1
  530. package/dist/chunks/fr-C_2i5Ono.mjs +0 -2
  531. package/dist/chunks/fr-C_2i5Ono.mjs.map +0 -1
  532. package/dist/chunks/full-BBl7mvwH.mjs +0 -2
  533. package/dist/chunks/hi-C9fvG91d.mjs +0 -2
  534. package/dist/chunks/hi-C9fvG91d.mjs.map +0 -1
  535. package/dist/chunks/minimal-CtnR4dqp.mjs +0 -2
  536. package/dist/chunks/pt-GqLw5tN0.mjs +0 -2
  537. package/dist/chunks/pt-GqLw5tN0.mjs.map +0 -1
  538. package/dist/chunks/ru-4g_qsaLr.mjs +0 -2
  539. package/dist/chunks/ru-4g_qsaLr.mjs.map +0 -1
  540. package/dist/chunks/src-C89Cw7ni.mjs +0 -2
  541. package/dist/chunks/src-C89Cw7ni.mjs.map +0 -1
  542. package/dist/chunks/zh-BjoyjClN.mjs +0 -2
  543. package/dist/chunks/zh-DeZP08HI.mjs +0 -2
  544. package/dist/chunks/zh-DeZP08HI.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownParser-Dp62mfUq.mjs","names":[],"sources":["../../src/serialization/markdown/InlineAst.ts","../../src/serialization/markdown/GfmAutolink.ts","../../src/serialization/markdown/LinkReferenceExtractor.ts","../../src/serialization/markdown/InlineTokenizer.ts","../../src/serialization/markdown/MarkdownParseContext.ts","../../src/serialization/MarkdownParser.ts"],"sourcesContent":["/**\n * Inline AST node model + linked-list helpers shared by the inline parser.\n *\n * A doubly-linked list of nodes is used during parsing so the emphasis\n * delimiter-stack algorithm runs in linear time (no array splicing), which is\n * the ReDoS-safety guarantee for untrusted pasted Markdown (D1).\n */\n\n/** Inline AST node kind. */\nexport type InlineKind =\n\t| 'text'\n\t| 'code'\n\t| 'softbreak'\n\t| 'hardbreak'\n\t| 'emph'\n\t| 'strong'\n\t| 'strike'\n\t| 'highlight'\n\t| 'sup'\n\t| 'sub'\n\t| 'link'\n\t| 'image'\n\t| 'inline_node'\n\t| 'html_inline';\n\n/** A single inline AST node (mutable; linked into a sibling list). */\nexport interface InlineAstNode {\n\ttype: InlineKind;\n\t/** Literal text for `text` / `code` / `html_inline`. */\n\tliteral: string;\n\t/** Container children (`emph`, `strong`, `link`, …). */\n\tchildren: InlineAstNode[];\n\t/** Link/image destination + title. */\n\thref: string;\n\ttitle: string;\n\t/** Image alt text (plain). */\n\talt: string;\n\t/** Generic inline-node passthrough (plugin extensions, e.g. math). */\n\tinlineType: string;\n\tattrs: Record<string, string | number | boolean>;\n\tprev: InlineAstNode | null;\n\tnext: InlineAstNode | null;\n}\n\n/** Creates a fresh inline AST node of the given kind. */\nexport function makeNode(type: InlineKind, literal = ''): InlineAstNode {\n\treturn {\n\t\ttype,\n\t\tliteral,\n\t\tchildren: [],\n\t\thref: '',\n\t\ttitle: '',\n\t\talt: '',\n\t\tinlineType: '',\n\t\tattrs: {},\n\t\tprev: null,\n\t\tnext: null,\n\t};\n}\n\n/** Appends `node` after `target` in the sibling linked list. */\nexport function insertAfter(target: InlineAstNode, node: InlineAstNode): void {\n\tnode.prev = target;\n\tnode.next = target.next;\n\tif (target.next) target.next.prev = node;\n\ttarget.next = node;\n}\n\n/** Removes `node` from its sibling linked list. */\nexport function unlink(node: InlineAstNode): void {\n\tif (node.prev) node.prev.next = node.next;\n\tif (node.next) node.next.prev = node.prev;\n\tnode.prev = null;\n\tnode.next = null;\n}\n","/**\n * GFM extended autolinks: `www.`, `http(s)://`, `mailto:`/`xmpp:`, bare emails.\n *\n * Implements the GFM \"autolinks (extension)\" rules rather than a naive URL\n * regex: valid-domain checks (at least one period, no underscore in the last\n * two segments), trailing-punctuation trimming, closing-paren balancing, and\n * trailing entity-reference stripping. Two integration points:\n *\n * - `matchGfmAutolinkAt` runs inside the inline parser's dispatch and scans the\n * raw source. Matching before emphasis processing keeps URLs with `_` / `~`\n * in their path intact instead of fragmenting them into delimiter runs.\n * - `applyGfmEmailAutolinks` is a post-pass over the resolved inline AST for\n * bare `user@host.tld` emails: the local part may contain delimiter\n * characters, so the surrounding text is only whole again after emphasis\n * resolution has turned unused delimiters back into plain text.\n *\n * Every scan here is a bounded forward/backward walk (linear time, D1).\n */\n\nimport { type InlineAstNode, makeNode } from './InlineAst.js';\n\n/** A matched GFM autolink: destination, display text, and source length. */\nexport interface GfmAutolinkMatch {\n\treadonly href: string;\n\treadonly display: string;\n\treadonly length: number;\n}\n\n/** Trailing characters GFM never counts as part of an autolink. */\nconst TRIMMABLE_PUNCTUATION = '?!.,:*_~';\n\n/** Characters that may precede an autolink (besides start-of-text). */\nconst BOUNDARY = /[\\s*_~(]/;\n\n/** One domain segment: alphanumerics, underscores, hyphens. */\nconst DOMAIN_SEGMENT = /^[a-zA-Z0-9_-]+$/;\n\n/** Bare email form (sticky, for in-source scans after a `mailto:`/`xmpp:` scheme). */\nconst EMAIL_AT = /[a-zA-Z0-9.+_-]+@[a-zA-Z0-9_-]+(?:\\.[a-zA-Z0-9_-]+)+/y;\n\nconst EMAIL_LOCAL_CHAR = /[a-zA-Z0-9.+_-]/;\nconst EMAIL_DOMAIN_CHAR = /[a-zA-Z0-9_-]/;\n\n/** Cheap pre-check: whether `pos` could start a GFM autolink (boundary + prefix). */\nexport function isGfmAutolinkCandidate(text: string, pos: number): boolean {\n\tconst ch: string = text[pos] ?? '';\n\tif (ch !== 'h' && ch !== 'w' && ch !== 'm' && ch !== 'x' && ch !== 'f') return false;\n\tif (pos > 0 && !BOUNDARY.test(text[pos - 1] ?? '')) return false;\n\treturn (\n\t\ttext.startsWith('http://', pos) ||\n\t\ttext.startsWith('https://', pos) ||\n\t\ttext.startsWith('ftp://', pos) ||\n\t\ttext.startsWith('www.', pos) ||\n\t\ttext.startsWith('mailto:', pos) ||\n\t\ttext.startsWith('xmpp:', pos)\n\t);\n}\n\n/** Matches a GFM autolink at `pos` (boundary included in the check), or null. */\nexport function matchGfmAutolinkAt(text: string, pos: number): GfmAutolinkMatch | null {\n\tif (!isGfmAutolinkCandidate(text, pos)) return null;\n\tif (\n\t\ttext.startsWith('http://', pos) ||\n\t\ttext.startsWith('https://', pos) ||\n\t\ttext.startsWith('ftp://', pos)\n\t) {\n\t\treturn matchUrl(text, pos);\n\t}\n\tif (text.startsWith('www.', pos)) return matchWww(text, pos);\n\treturn matchProtocolEmail(text, pos);\n}\n\n/** The raw autolink candidate at `pos`: the trimmed run up to whitespace or `<`. */\nfunction linkCandidate(text: string, pos: number): string {\n\tlet end: number = pos;\n\twhile (end < text.length) {\n\t\tconst ch: string = text[end] ?? '';\n\t\tif (ch === '<' || /\\s/.test(ch)) break;\n\t\tend++;\n\t}\n\treturn trimTrailing(text.slice(pos, end));\n}\n\nfunction matchUrl(text: string, pos: number): GfmAutolinkMatch | null {\n\tconst candidate: string = linkCandidate(text, pos);\n\tconst schemeLength: number = text.startsWith('https://', pos)\n\t\t? 8\n\t\t: text.startsWith('http://', pos)\n\t\t\t? 7\n\t\t\t: 6;\n\tif (!isValidDomain(hostOf(candidate.slice(schemeLength)))) return null;\n\treturn { href: candidate, display: candidate, length: candidate.length };\n}\n\nfunction matchWww(text: string, pos: number): GfmAutolinkMatch | null {\n\tconst candidate: string = linkCandidate(text, pos);\n\tif (!isValidDomain(hostOf(candidate))) return null;\n\treturn { href: `http://${candidate}`, display: candidate, length: candidate.length };\n}\n\n/** `mailto:` / `xmpp:` + email; the scheme is part of both href and display. */\nfunction matchProtocolEmail(text: string, pos: number): GfmAutolinkMatch | null {\n\tconst schemeLength: number = text.startsWith('mailto:', pos) ? 7 : 5;\n\tEMAIL_AT.lastIndex = pos + schemeLength;\n\tconst match: RegExpExecArray | null = EMAIL_AT.exec(text);\n\tconst email: string | undefined = match?.[0];\n\tif (!email || !isValidEmailEnd(email)) return null;\n\tconst full: string = text.slice(pos, pos + schemeLength + email.length);\n\treturn { href: full, display: full, length: full.length };\n}\n\n/** The host part of a candidate (up to the first `/ ? # :`). */\nfunction hostOf(rest: string): string {\n\tconst end: number = rest.search(/[/?#:]/);\n\treturn end === -1 ? rest : rest.slice(0, end);\n}\n\n/** GFM valid domain: >= 2 segments, no underscore in the last two segments. */\nfunction isValidDomain(domain: string): boolean {\n\tconst segments: string[] = domain.split('.');\n\tif (segments.length < 2) return false;\n\tif (!segments.every((segment) => DOMAIN_SEGMENT.test(segment))) return false;\n\treturn !segments.slice(-2).some((segment) => segment.includes('_'));\n}\n\n/** GFM email rule: the last character must not be `-` or `_`. */\nfunction isValidEmailEnd(email: string): boolean {\n\treturn !email.endsWith('-') && !email.endsWith('_');\n}\n\n/**\n * GFM trailing trims, applied until stable: trailing punctuation, an excess\n * closing paren (only while the candidate holds more `)` than `(`), and a\n * trailing entity reference (`&copy;`). Each pass removes at least one\n * character via a bounded backward scan, so the whole trim is linear.\n */\nfunction trimTrailing(candidate: string): string {\n\tlet open = 0;\n\tlet close = 0;\n\tfor (const ch of candidate) {\n\t\tif (ch === '(') open++;\n\t\telse if (ch === ')') close++;\n\t}\n\tlet end: number = candidate.length;\n\twhile (end > 0) {\n\t\tconst ch: string = candidate[end - 1] ?? '';\n\t\tif (TRIMMABLE_PUNCTUATION.includes(ch)) {\n\t\t\tend--;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === ')' && close > open) {\n\t\t\tend--;\n\t\t\tclose--;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === ';') {\n\t\t\tlet j: number = end - 2;\n\t\t\twhile (j > 0 && /[a-zA-Z0-9]/.test(candidate[j] ?? '')) j--;\n\t\t\tif (candidate[j] === '&' && j < end - 2) {\n\t\t\t\tend = j;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tbreak;\n\t}\n\treturn candidate.slice(0, end);\n}\n\n/**\n * Post-pass over the resolved inline AST: turns bare `user@host.tld` emails in\n * plain text into `mailto:` links. Adjacent text nodes (including leftover\n * delimiter runs) are merged first so a local part like `a_b` is scanned as one\n * string. Subtrees that must not be linkified (links, images, code, raw HTML,\n * plugin inline nodes) are skipped.\n */\nexport function applyGfmEmailAutolinks(nodes: InlineAstNode[]): void {\n\tmergeAdjacentAstText(nodes);\n\tfor (let i = 0; i < nodes.length; i++) {\n\t\tconst node: InlineAstNode | undefined = nodes[i];\n\t\tif (!node || skipsEmailScan(node.type)) continue;\n\t\tif (node.type === 'text') {\n\t\t\tconst split: InlineAstNode[] | null = splitEmails(node.literal);\n\t\t\tif (split) {\n\t\t\t\tnodes.splice(i, 1, ...split);\n\t\t\t\ti += split.length - 1;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (node.children.length > 0) applyGfmEmailAutolinks(node.children);\n\t}\n}\n\nfunction skipsEmailScan(type: InlineAstNode['type']): boolean {\n\treturn (\n\t\ttype === 'link' ||\n\t\ttype === 'image' ||\n\t\ttype === 'code' ||\n\t\ttype === 'html_inline' ||\n\t\ttype === 'inline_node'\n\t);\n}\n\n/**\n * Merges adjacent text siblings in place (delimiter leftovers are text too).\n * Single compaction pass — no per-merge splice, which would go quadratic on a\n * long run of unmatched delimiters (D1).\n */\nfunction mergeAdjacentAstText(nodes: InlineAstNode[]): void {\n\tlet write = 0;\n\tfor (const node of nodes) {\n\t\tconst prev: InlineAstNode | undefined = write > 0 ? nodes[write - 1] : undefined;\n\t\tif (prev && prev.type === 'text' && node.type === 'text') {\n\t\t\tprev.literal += node.literal;\n\t\t\tcontinue;\n\t\t}\n\t\tnodes[write] = node;\n\t\twrite++;\n\t}\n\tnodes.length = write;\n}\n\n/**\n * Splits a literal into text/link nodes around bare emails, or null if none.\n * Anchored on each `@` with bounded back/forward scans instead of a global\n * regex: a `X+@` pattern backtracks quadratically over long runs of local-part\n * characters (the ReDoS fuzz suite catches exactly that, D1).\n */\nfunction splitEmails(literal: string): InlineAstNode[] | null {\n\tconst out: InlineAstNode[] = [];\n\tlet cursor = 0;\n\tlet at: number = literal.indexOf('@');\n\twhile (at !== -1) {\n\t\tlet start: number = at;\n\t\twhile (start > cursor && EMAIL_LOCAL_CHAR.test(literal[start - 1] ?? '')) start--;\n\t\tlet end: number = at + 1;\n\t\twhile (\n\t\t\tend < literal.length &&\n\t\t\t(EMAIL_DOMAIN_CHAR.test(literal[end] ?? '') || literal[end] === '.')\n\t\t) {\n\t\t\tend++;\n\t\t}\n\t\t// Trailing periods are punctuation, not part of the address.\n\t\twhile (end > at + 1 && literal[end - 1] === '.') end--;\n\t\tconst email: string = literal.slice(start, end);\n\t\tif (start < at && isValidBareEmail(email, end - at - 1)) {\n\t\t\tif (start > cursor) out.push(makeNode('text', literal.slice(cursor, start)));\n\t\t\tconst link: InlineAstNode = makeNode('link');\n\t\t\tlink.href = `mailto:${email}`;\n\t\t\tlink.children = [makeNode('text', email)];\n\t\t\tout.push(link);\n\t\t\tcursor = end;\n\t\t\tat = literal.indexOf('@', end);\n\t\t\tcontinue;\n\t\t}\n\t\tat = literal.indexOf('@', at + 1);\n\t}\n\tif (out.length === 0) return null;\n\tif (cursor < literal.length) out.push(makeNode('text', literal.slice(cursor)));\n\treturn out;\n}\n\n/** Validates a scanned bare email: >= 2 domain segments, valid end character. */\nfunction isValidBareEmail(email: string, domainLength: number): boolean {\n\tif (domainLength <= 0) return false;\n\tconst domain: string = email.slice(email.indexOf('@') + 1);\n\tconst segments: string[] = domain.split('.');\n\tif (segments.length < 2) return false;\n\tif (segments.some((segment) => segment === '')) return false;\n\treturn isValidEmailEnd(email);\n}\n","/**\n * Link reference definition extraction (`[label]: dest \"title\"`).\n *\n * Runs as a pre-pass over the source before block tokenization, mirroring how\n * commonmark.js resolves references before inline parsing. CommonMark rules\n * honored here:\n *\n * - A definition never interrupts an open paragraph (a def-shaped line that\n * lazily continues a paragraph stays paragraph text).\n * - Def-shaped lines inside fenced code are code and survive verbatim.\n * - The destination may sit on the line after the label, and a title may sit\n * on its own following line (multi-line labels and multi-line titles are not\n * supported; such lines stay paragraph text, which never drops content).\n * - Titles honor backslash escapes; destinations and titles decode escapes and\n * entity references; labels match case-folded (Unicode, `ẞ` ↔ `SS`).\n * - A definition inside a blockquote is recognized too; the quote marker line\n * is kept so the (now empty) container survives.\n *\n * First definition of a label wins, as per spec.\n */\n\nimport { ATX_HEADING, THEMATIC_BREAK, matchFenceOpen } from './BlockTokenizer.js';\nimport { decodeEscapesAndEntities } from './MarkdownEntities.js';\n\n/** A link reference definition target. */\nexport interface LinkRef {\n\treadonly href: string;\n\treadonly title?: string;\n}\n\n/** `[label]:` at up to 3 spaces indent; the label may hold escaped brackets. */\nconst LABEL_LINE = /^ {0,3}\\[((?:\\\\.|[^\\\\[\\]])+)\\]:(.*)$/;\n\n/** One or more blockquote markers prefixing a line. */\nconst BLOCKQUOTE_PREFIX = /^( {0,3}(?:> ?)+)(.*)$/;\n\n/** A line holding nothing but a link title (for the title-on-next-line form). */\nconst TITLE_LINE =\n\t/^[ \\t]*(?:\"((?:\\\\.|[^\"\\\\])*)\"|'((?:\\\\.|[^'\\\\])*)'|\\(((?:\\\\.|[^()\\\\])*)\\))[ \\t]*$/;\n\nconst FENCE_CLOSE = /^ {0,3}(`{3,}|~{3,})[ \\t]*$/;\n\n/**\n * Case-folds a reference label for matching. `toUpperCase().toLowerCase()`\n * approximates Unicode case folding (it maps `ẞ`/`ß` and `SS` to the same\n * string), which plain `toLowerCase()` does not.\n */\nexport function foldReferenceLabel(label: string): string {\n\treturn label\n\t\t.trim()\n\t\t.replace(/[ \\t\\n]+/g, ' ')\n\t\t.toLowerCase()\n\t\t.toUpperCase()\n\t\t.toLowerCase();\n}\n\n/** Removes link reference definitions from the source and returns them as a map. */\nexport function extractLinkReferences(source: string): {\n\tsource: string;\n\tlinkRefs: Map<string, LinkRef>;\n} {\n\tconst linkRefs = new Map<string, LinkRef>();\n\tconst lines: string[] = source.split('\\n');\n\tconst kept: string[] = [];\n\tlet fence: { char: string; len: number } | null = null;\n\t// Whether a paragraph is open above the next line: a definition is only\n\t// recognized at a block boundary (document start, after a blank line, a\n\t// heading, a thematic break, a fence, or another definition).\n\tlet openParagraph = false;\n\tlet i = 0;\n\n\twhile (i < lines.length) {\n\t\tconst line: string = lines[i] ?? '';\n\n\t\tif (fence) {\n\t\t\tkept.push(line);\n\t\t\tconst close: RegExpMatchArray | null = line.match(FENCE_CLOSE);\n\t\t\tconst run: string | undefined = close?.[1];\n\t\t\tif (run && run[0] === fence.char && run.length >= fence.len) fence = null;\n\t\t\topenParagraph = false;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tconst open: RegExpMatchArray | null = matchFenceOpen(line);\n\t\tif (open?.[1]) {\n\t\t\tfence = { char: open[1][0] ?? '`', len: open[1].length };\n\t\t\tkept.push(line);\n\t\t\topenParagraph = false;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst consumed: number = openParagraph ? 0 : tryDefinition(lines, i, '', linkRefs, kept);\n\t\tif (consumed > 0) {\n\t\t\ti += consumed;\n\t\t\tcontinue;\n\t\t}\n\n\t\tkept.push(line);\n\t\t// A blank line or a complete block (heading, thematic break) closes any open\n\t\t// paragraph; every other non-blank line keeps one open. Deliberate keep-bias:\n\t\t// a def-shaped line after, e.g., a table row or setext underline is preserved\n\t\t// as text rather than registered, which never drops content (D3).\n\t\topenParagraph = line.trim() !== '' && !ATX_HEADING.test(line) && !THEMATIC_BREAK.test(line);\n\t\ti++;\n\t}\n\treturn { source: kept.join('\\n'), linkRefs };\n}\n\n/**\n * Tries to consume a definition starting at `lines[start]`, registering it and\n * pushing any kept container-prefix line. Returns the number of source lines\n * consumed (0 = no definition here).\n */\nfunction tryDefinition(\n\tlines: readonly string[],\n\tstart: number,\n\tprefix: string,\n\tlinkRefs: Map<string, LinkRef>,\n\tkept: string[],\n): number {\n\tconst line: string = lines[start] ?? '';\n\n\tconst label: RegExpMatchArray | null = line.match(LABEL_LINE);\n\tif (!label) {\n\t\t// A definition nested in a blockquote: strip the marker(s) and retry once.\n\t\tif (prefix === '') {\n\t\t\tconst quoted: RegExpMatchArray | null = line.match(BLOCKQUOTE_PREFIX);\n\t\t\tif (quoted?.[1] && LABEL_LINE.test(quoted[2] ?? '')) {\n\t\t\t\tconst inner: string[] = [];\n\t\t\t\tconst consumed: number = tryDefinition([quoted[2] ?? ''], 0, quoted[1], linkRefs, inner);\n\t\t\t\tif (consumed > 0) {\n\t\t\t\t\t// Keep the bare marker so the blockquote container survives.\n\t\t\t\t\tkept.push(quoted[1].trimEnd());\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t}\n\n\tconst labelText: string = label[1] ?? '';\n\tlet rest: string = (label[2] ?? '').trim();\n\tlet consumed = 1;\n\n\t// Destination on the next line (only supported outside containers).\n\tif (rest === '' && prefix === '') {\n\t\tconst next: string = lines[start + consumed] ?? '';\n\t\tif (next.trim() === '') return 0;\n\t\trest = next.trim();\n\t\tconsumed++;\n\t}\n\tif (rest === '') return 0;\n\n\tconst dest = scanDestination(rest);\n\tif (!dest) return 0;\n\tconst afterDest: string = rest.slice(dest.end).trim();\n\n\tlet title: string | undefined;\n\tif (afterDest !== '') {\n\t\tconst inline: RegExpMatchArray | null = afterDest.match(TITLE_LINE);\n\t\tif (!inline) return 0; // Junk after the destination: not a definition.\n\t\ttitle = titleFrom(inline);\n\t} else if (prefix === '') {\n\t\t// Optional title on its own next line.\n\t\tconst next: string = lines[start + consumed] ?? '';\n\t\tconst nextTitle: RegExpMatchArray | null = next.match(TITLE_LINE);\n\t\tif (nextTitle) {\n\t\t\ttitle = titleFrom(nextTitle);\n\t\t\tconsumed++;\n\t\t}\n\t}\n\n\tconst key: string = foldReferenceLabel(labelText);\n\tif (key !== '' && !linkRefs.has(key)) {\n\t\tlinkRefs.set(key, title !== undefined ? { href: dest.href, title } : { href: dest.href });\n\t}\n\treturn consumed;\n}\n\nfunction titleFrom(match: RegExpMatchArray): string {\n\treturn decodeEscapesAndEntities(match[1] ?? match[2] ?? match[3] ?? '');\n}\n\n/** Scans a definition destination: `<angle>` or a bare paren-balanced run. */\nfunction scanDestination(rest: string): { href: string; end: number } | null {\n\tif (rest[0] === '<') {\n\t\tlet i = 1;\n\t\twhile (i < rest.length) {\n\t\t\tconst ch: string = rest[i] ?? '';\n\t\t\tif (ch === '\\\\') {\n\t\t\t\ti += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (ch === '>') {\n\t\t\t\treturn { href: decodeEscapesAndEntities(rest.slice(1, i)), end: i + 1 };\n\t\t\t}\n\t\t\tif (ch === '<') return null;\n\t\t\ti++;\n\t\t}\n\t\treturn null;\n\t}\n\tlet depth = 0;\n\tlet i = 0;\n\twhile (i < rest.length) {\n\t\tconst ch: string = rest[i] ?? '';\n\t\tif (ch === ' ' || ch === '\\t') break;\n\t\tif (ch === '\\\\') {\n\t\t\ti += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === '(') depth++;\n\t\tif (ch === ')') {\n\t\t\tif (depth === 0) break;\n\t\t\tdepth--;\n\t\t}\n\t\ti++;\n\t}\n\tif (i === 0) return null;\n\treturn { href: decodeEscapesAndEntities(rest.slice(0, i)), end: i };\n}\n","/**\n * Inline Markdown parser: a linear-time, delimiter-stack tokenizer (the\n * CommonMark reference approach), producing an inline AST that is then flattened\n * into notectl's `(TextNode | InlineNode)[]` mark-set model.\n *\n * Linear-time and backtracking-free by construction: emphasis runs through a\n * doubly-linked delimiter stack, code spans / autolinks / inline HTML are\n * forward scans, and there is no catastrophic-backtracking regex. This is the\n * ReDoS-safety guarantee for untrusted pasted Markdown (D1).\n *\n * Marks with no Markdown form round-trip through inline HTML produced by the\n * serializer's fallback: a balanced `<u>…</u>` / `<span style>…</span>` run is\n * captured and re-parsed via the HTML parser, recovering the original mark (D3).\n */\n\nimport type { InlineNode, Mark, TextNode } from '../../model/Document.js';\nimport { createInlineNode, createTextNode } from '../../model/Document.js';\nimport { type InlineTypeName, inlineType, markType } from '../../model/TypeBrands.js';\nimport { parseHTMLToDocument } from '../DocumentParser.js';\nimport {\n\ttype GfmAutolinkMatch,\n\tapplyGfmEmailAutolinks,\n\tisGfmAutolinkCandidate,\n\tmatchGfmAutolinkAt,\n} from './GfmAutolink.js';\nimport { type InlineAstNode, type InlineKind, insertAfter, makeNode, unlink } from './InlineAst.js';\nimport { foldReferenceLabel } from './LinkReferenceExtractor.js';\nimport {\n\tdecodeEntitiesOnly,\n\tdecodeEntity,\n\tdecodeEscapesAndEntities,\n\tmatchEntityAt,\n} from './MarkdownEntities.js';\nimport { resolveMarkdownHTMLRegistry } from './MarkdownHTMLRegistry.js';\nimport type { ParseContext } from './MarkdownParseContext.js';\n\n// --- Delimiter / bracket stacks ---\n\ninterface Delimiter {\n\tcc: string;\n\tnumdelims: number;\n\torigdelims: number;\n\tnode: InlineAstNode;\n\tcanOpen: boolean;\n\tcanClose: boolean;\n\tprev: Delimiter | null;\n\tnext: Delimiter | null;\n}\n\ninterface Bracket {\n\tnode: InlineAstNode;\n\tprev: Bracket | null;\n\tprevDelim: Delimiter | null;\n\tindex: number;\n\timage: boolean;\n\tactive: boolean;\n}\n\n/** Upper bound on an inline link destination scan (ReDoS guard; real URLs are short). */\nconst MAX_DESTINATION_LENGTH = 8192;\n\n/** Unicode punctuation + symbols, per CommonMark 0.30+ flanking rules. */\nconst UNICODE_PUNCTUATION = /[\\p{P}\\p{S}]/u;\nconst ASCII_PUNCTUATION = /[!-/:-@[-`{-~]/;\nconst ESCAPABLE = /[!-/:-@[-`{-~]/;\nconst INLINE_HTML_TAGS: ReadonlySet<string> = new Set([\n\t'u',\n\t'sup',\n\t'sub',\n\t'span',\n\t'mark',\n\t'b',\n\t'i',\n\t'em',\n\t'strong',\n\t'code',\n\t's',\n\t'del',\n\t'small',\n\t'abbr',\n\t'kbd',\n\t'a',\n]);\n\nfunction isWhitespace(ch: string): boolean {\n\treturn ch === '' || /\\s/.test(ch);\n}\n\n/** Flanking punctuation test; ASCII fast path, Unicode classes beyond it. */\nfunction isPunct(ch: string): boolean {\n\tif (ch === '') return false;\n\tif (ch.charCodeAt(0) < 128) return ASCII_PUNCTUATION.test(ch);\n\treturn UNICODE_PUNCTUATION.test(ch);\n}\n\n/** The inline parser. One instance per inline string. */\nclass InlineParser {\n\tprivate pos = 0;\n\tprivate readonly text: string;\n\tprivate readonly len: number;\n\tprivate readonly ctx: ParseContext;\n\tprivate delimiters: Delimiter | null = null;\n\tprivate brackets: Bracket | null = null;\n\t/** Tail of the output sibling list, so self-linking tokens can extend it. */\n\tprivate tail: InlineAstNode | null = null;\n\n\tconstructor(text: string, ctx: ParseContext) {\n\t\tthis.text = text;\n\t\tthis.len = text.length;\n\t\tthis.ctx = ctx;\n\t}\n\n\t/** Parses the inline string into a list of top-level AST nodes. */\n\tparse(): InlineAstNode[] {\n\t\tconst root: InlineAstNode = makeNode('text');\n\t\tthis.tail = root;\n\n\t\twhile (this.pos < this.len) {\n\t\t\tconst node: InlineAstNode | null = this.parseToken();\n\t\t\tif (node) this.appendNode(node);\n\t\t}\n\n\t\tthis.processEmphasis(null);\n\t\treturn collectSiblings(root);\n\t}\n\n\t/** Links a freshly produced token at the tail of the sibling list. */\n\tprivate appendNode(node: InlineAstNode): void {\n\t\tif (this.tail) insertAfter(this.tail, node);\n\t\tthis.tail = node;\n\t}\n\n\t/** Dispatches on the current character, returning the produced node (already linked for delims). */\n\tprivate parseToken(): InlineAstNode | null {\n\t\tconst ch: string = this.text[this.pos] ?? '';\n\t\tswitch (ch) {\n\t\t\tcase '\\n':\n\t\t\t\treturn this.parseNewline();\n\t\t\tcase '\\\\':\n\t\t\t\treturn this.parseBackslash();\n\t\t\tcase '`':\n\t\t\t\treturn this.parseBackticks();\n\t\t\tcase '*':\n\t\t\tcase '_':\n\t\t\tcase '~':\n\t\t\tcase '=':\n\t\t\tcase '^':\n\t\t\t\treturn this.parseDelimiterRun(ch);\n\t\t\tcase '[':\n\t\t\t\treturn this.parseOpenBracket(false);\n\t\t\tcase '!':\n\t\t\t\tif (this.text[this.pos + 1] === '[') return this.parseOpenBracket(true);\n\t\t\t\tthis.pos++;\n\t\t\t\treturn makeNode('text', '!');\n\t\t\tcase ']':\n\t\t\t\treturn this.parseCloseBracket();\n\t\t\tcase '<':\n\t\t\t\treturn this.parseLessThan();\n\t\t\tcase '&':\n\t\t\t\treturn this.parseEntity();\n\t\t\tdefault: {\n\t\t\t\tconst auto: InlineAstNode | null = this.parseGfmAutolink();\n\t\t\t\tif (auto) return auto;\n\t\t\t\tconst ext: InlineAstNode | null = this.parseExtension();\n\t\t\t\tif (ext) return ext;\n\t\t\t\treturn this.parseString();\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Plain text up to the next significant character. */\n\tprivate parseString(): InlineAstNode {\n\t\tconst start: number = this.pos;\n\t\tthis.pos++;\n\t\twhile (this.pos < this.len) {\n\t\t\tconst ch: string = this.text[this.pos] ?? '';\n\t\t\tif ('\\n\\\\`*_~=^[]!<&'.includes(ch)) break;\n\t\t\tif (this.matchesGfmAutolinkStart()) break;\n\t\t\tif (this.matchesExtensionStart()) break;\n\t\t\tthis.pos++;\n\t\t}\n\t\treturn makeNode('text', this.text.slice(start, this.pos));\n\t}\n\n\t/**\n\t * GFM extended autolink (`www.`, `http(s)://`, `mailto:`/`xmpp:`) at the\n\t * current position, scanned on the raw source (#199). Skipped inside an open\n\t * bracket: explicit `[text](url)` syntax wins there, and a link must never\n\t * nest inside another link. Bare emails are handled in a post-pass instead\n\t * (see `applyGfmEmailAutolinks`).\n\t */\n\tprivate parseGfmAutolink(): InlineAstNode | null {\n\t\tif (!this.ctx.opts.gfm || this.brackets) return null;\n\t\tconst match: GfmAutolinkMatch | null = matchGfmAutolinkAt(this.text, this.pos);\n\t\tif (!match) return null;\n\t\tthis.pos += match.length;\n\t\tconst node: InlineAstNode = makeNode('link');\n\t\tnode.href = match.href;\n\t\tnode.children = [makeNode('text', match.display)];\n\t\treturn node;\n\t}\n\n\tprivate matchesGfmAutolinkStart(): boolean {\n\t\tif (!this.ctx.opts.gfm || this.brackets) return false;\n\t\treturn isGfmAutolinkCandidate(this.text, this.pos);\n\t}\n\n\t/** Plugin syntax extensions (e.g. formula `$...$`). */\n\tprivate parseExtension(): InlineAstNode | null {\n\t\tfor (const ext of this.ctx.opts.syntaxExtensions) {\n\t\t\tconst match = ext.matchInline?.(this.text, this.pos);\n\t\t\tif (match) {\n\t\t\t\tthis.pos += match.length;\n\t\t\t\tconst node: InlineAstNode = makeNode('inline_node');\n\t\t\t\tnode.inlineType = match.type;\n\t\t\t\tnode.attrs = match.attrs;\n\t\t\t\treturn node;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tprivate matchesExtensionStart(): boolean {\n\t\tfor (const ext of this.ctx.opts.syntaxExtensions) {\n\t\t\tif (ext.matchInline?.(this.text, this.pos)) return true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * A newline produces a soft break, unless the line above ends in two or more\n\t * spaces: that is CommonMark's second hard-break form (#193). The trailing\n\t * whitespace lives in the previously emitted text node (the block tokenizer\n\t * preserves interior trailing spaces for exactly this check) and is stripped\n\t * either way — line-end whitespace is never content. The backslash form is\n\t * handled in `parseBackslash`.\n\t */\n\tprivate parseNewline(): InlineAstNode {\n\t\tthis.pos++;\n\t\t// Skip leading spaces of the next line.\n\t\twhile (this.text[this.pos] === ' ') this.pos++;\n\t\tconst prev: InlineAstNode | null = this.tail;\n\t\tif (prev && prev.type === 'text' && prev.literal.endsWith(' ')) {\n\t\t\tconst hard: boolean = prev.literal.endsWith(' ');\n\t\t\tprev.literal = prev.literal.replace(/[ \\t]+$/, '');\n\t\t\treturn makeNode(hard ? 'hardbreak' : 'softbreak');\n\t\t}\n\t\treturn makeNode('softbreak');\n\t}\n\n\tprivate parseBackslash(): InlineAstNode {\n\t\tthis.pos++;\n\t\tconst next: string = this.text[this.pos] ?? '';\n\t\tif (next === '\\n') {\n\t\t\tthis.pos++;\n\t\t\twhile (this.text[this.pos] === ' ') this.pos++;\n\t\t\treturn makeNode('hardbreak');\n\t\t}\n\t\tif (ESCAPABLE.test(next)) {\n\t\t\tthis.pos++;\n\t\t\treturn makeNode('text', next);\n\t\t}\n\t\treturn makeNode('text', '\\\\');\n\t}\n\n\t/** A backtick code span; falls back to literal backticks if unclosed. */\n\tprivate parseBackticks(): InlineAstNode {\n\t\tconst start: number = this.pos;\n\t\tlet count = 0;\n\t\twhile (this.text[this.pos] === '`') {\n\t\t\tcount++;\n\t\t\tthis.pos++;\n\t\t}\n\t\tconst fence: string = '`'.repeat(count);\n\t\tconst after: number = this.pos;\n\t\tlet search: number = after;\n\t\twhile (search < this.len) {\n\t\t\tconst idx: number = this.text.indexOf(fence, search);\n\t\t\tif (idx === -1) break;\n\t\t\t// Require an exact-length run (not part of a longer run).\n\t\t\tif (this.text[idx - 1] !== '`' && this.text[idx + count] !== '`') {\n\t\t\t\tlet content: string = this.text.slice(after, idx).replace(/\\n/g, ' ');\n\t\t\t\tif (\n\t\t\t\t\tcontent.length > 2 &&\n\t\t\t\t\tcontent.startsWith(' ') &&\n\t\t\t\t\tcontent.endsWith(' ') &&\n\t\t\t\t\tcontent.trim() !== ''\n\t\t\t\t) {\n\t\t\t\t\tcontent = content.slice(1, -1);\n\t\t\t\t}\n\t\t\t\tthis.pos = idx + count;\n\t\t\t\treturn makeNode('code', content);\n\t\t\t}\n\t\t\tsearch = idx + 1;\n\t\t}\n\t\t// No closer: treat the opening run as literal text.\n\t\tthis.pos = after;\n\t\treturn makeNode('text', this.text.slice(start, after));\n\t}\n\n\t/** A run of emphasis/extension delimiters; records a stack entry. */\n\tprivate parseDelimiterRun(cc: string): InlineAstNode {\n\t\tconst { numdelims, canOpen, canClose } = this.scanDelims(cc);\n\t\tconst node: InlineAstNode = makeNode('text', cc.repeat(numdelims));\n\t\tconst delim: Delimiter = {\n\t\t\tcc,\n\t\t\tnumdelims,\n\t\t\torigdelims: numdelims,\n\t\t\tnode,\n\t\t\tcanOpen,\n\t\t\tcanClose,\n\t\t\tprev: this.delimiters,\n\t\t\tnext: null,\n\t\t};\n\t\tif (this.delimiters) this.delimiters.next = delim;\n\t\tthis.delimiters = delim;\n\t\treturn node;\n\t}\n\n\t/** Counts a delimiter run and computes its flanking flags. */\n\tprivate scanDelims(cc: string): { numdelims: number; canOpen: boolean; canClose: boolean } {\n\t\tconst start: number = this.pos;\n\t\twhile (this.text[this.pos] === cc) this.pos++;\n\t\tconst numdelims: number = this.pos - start;\n\n\t\tconst before: string = start === 0 ? '' : (this.text[start - 1] ?? '');\n\t\tconst after: string = this.text[this.pos] ?? '';\n\t\tconst beforeWs: boolean = isWhitespace(before);\n\t\tconst afterWs: boolean = isWhitespace(after);\n\t\tconst beforePunct: boolean = isPunct(before);\n\t\tconst afterPunct: boolean = isPunct(after);\n\n\t\tconst leftFlanking: boolean = !afterWs && (!afterPunct || beforeWs || beforePunct);\n\t\tconst rightFlanking: boolean = !beforeWs && (!beforePunct || afterWs || afterPunct);\n\n\t\tlet canOpen: boolean;\n\t\tlet canClose: boolean;\n\t\tif (cc === '_') {\n\t\t\tcanOpen = leftFlanking && (!rightFlanking || beforePunct);\n\t\t\tcanClose = rightFlanking && (!leftFlanking || afterPunct);\n\t\t} else {\n\t\t\tcanOpen = leftFlanking;\n\t\t\tcanClose = rightFlanking;\n\t\t}\n\t\treturn { numdelims, canOpen, canClose };\n\t}\n\n\t/** `[` or `![`: push a bracket and emit its literal text node. */\n\tprivate parseOpenBracket(image: boolean): InlineAstNode {\n\t\tconst literal: string = image ? '![' : '[';\n\t\tthis.pos += literal.length;\n\t\tconst node: InlineAstNode = makeNode('text', literal);\n\t\tthis.brackets = {\n\t\t\tnode,\n\t\t\tprev: this.brackets,\n\t\t\tprevDelim: this.delimiters,\n\t\t\tindex: this.pos,\n\t\t\timage,\n\t\t\tactive: true,\n\t\t};\n\t\treturn node;\n\t}\n\n\t/** `]`: resolve a link/image against the open bracket, or emit literal `]`. */\n\tprivate parseCloseBracket(): InlineAstNode | null {\n\t\tthis.pos++;\n\t\tconst opener: Bracket | null = this.brackets;\n\t\tif (!opener || !opener.active) {\n\t\t\tif (opener) this.brackets = opener.prev;\n\t\t\treturn makeNode('text', ']');\n\t\t}\n\n\t\tconst dest: { href: string; title: string } | null = this.parseLinkTarget(opener);\n\t\tif (!dest) {\n\t\t\tthis.brackets = opener.prev;\n\t\t\treturn makeNode('text', ']');\n\t\t}\n\n\t\tconst wrapper: InlineAstNode = makeNode(opener.image ? 'image' : 'link');\n\t\twrapper.href = dest.href;\n\t\twrapper.title = dest.title;\n\n\t\t// Resolve emphasis inside the bracketed range first. The emphasis algorithm\n\t\t// walks the sibling linked list, so it must run while the bracket contents\n\t\t// are still linked, before they are detached into the wrapper's children.\n\t\tthis.processEmphasis(opener.prevDelim);\n\n\t\t// Move the (now emphasis-resolved) nodes between the opener and now into the wrapper.\n\t\tlet node: InlineAstNode | null = opener.node.next;\n\t\twhile (node) {\n\t\t\tconst next: InlineAstNode | null = node.next;\n\t\t\tunlink(node);\n\t\t\twrapper.children.push(node);\n\t\t\tnode = next;\n\t\t}\n\t\tif (opener.image) {\n\t\t\twrapper.alt = astPlainText(wrapper.children);\n\t\t\twrapper.children = [];\n\t\t}\n\n\t\t// The wrapper takes the opener's place and becomes the new tail. It is linked\n\t\t// here, so the parse loop must not append it again (returning null prevents the\n\t\t// double-link that would otherwise corrupt the wrapper's sibling pointers).\n\t\tinsertAfter(opener.node, wrapper);\n\t\tunlink(opener.node);\n\t\tthis.tail = wrapper;\n\n\t\t// Links cannot contain other links.\n\t\tif (!opener.image) {\n\t\t\tlet b: Bracket | null = opener.prev;\n\t\t\twhile (b) {\n\t\t\t\tif (!b.image) b.active = false;\n\t\t\t\tb = b.prev;\n\t\t\t}\n\t\t}\n\t\tthis.brackets = opener.prev;\n\t\treturn null;\n\t}\n\n\t/** Parses an inline `(dest \"title\")` or a reference `[label]` target. */\n\tprivate parseLinkTarget(opener: Bracket): { href: string; title: string } | null {\n\t\tif (this.text[this.pos] === '(') {\n\t\t\tconst inline = this.parseInlineDestination();\n\t\t\tif (inline) return inline;\n\t\t}\n\t\t// Reference link: [label][ref], [label][], or shortcut [label].\n\t\tconst label: string = this.text.slice(opener.index, this.pos - 1);\n\t\tlet ref: string = label;\n\t\tlet explicitRef = false;\n\t\t// Position to advance to *only* when the reference resolves. A failed\n\t\t// lookup must leave `this.pos` at the `]` so the trailing `[ref]` re-parses\n\t\t// as literal text — otherwise `[text][missing]` silently drops `[missing]`.\n\t\tlet resolvedEnd: number = this.pos;\n\t\tif (this.text[this.pos] === '[') {\n\t\t\tconst close: number = this.text.indexOf(']', this.pos + 1);\n\t\t\tif (close !== -1) {\n\t\t\t\tconst explicit: string = this.text.slice(this.pos + 1, close);\n\t\t\t\tif (explicit.trim() !== '') {\n\t\t\t\t\tref = explicit;\n\t\t\t\t\texplicitRef = true;\n\t\t\t\t}\n\t\t\t\tresolvedEnd = close + 1;\n\t\t\t}\n\t\t}\n\t\t// CommonMark forbids unescaped `[` inside a reference label. For shortcut\n\t\t// and collapsed forms the bracket text is the label; a full reference\n\t\t// (`[text][ref]`) may hold anything in its text part.\n\t\tif (!explicitRef && ref.includes('[')) return null;\n\t\tconst found = this.ctx.linkRefs.get(foldReferenceLabel(ref));\n\t\tif (found) {\n\t\t\tthis.pos = resolvedEnd;\n\t\t\treturn { href: found.href, title: found.title ?? '' };\n\t\t}\n\t\treturn null;\n\t}\n\n\t/** Parses `(url \"title\")` starting at the current `(`; returns null if malformed. */\n\tprivate parseInlineDestination(): { href: string; title: string } | null {\n\t\tlet i: number = this.pos + 1;\n\t\twhile (this.text[i] === ' ' || this.text[i] === '\\n') i++;\n\n\t\tlet href = '';\n\t\tif (this.text[i] === '<') {\n\t\t\t// Angle destination: ends at the first unescaped `>`; `<` and newlines\n\t\t\t// are not allowed inside. Escapes and entities decode afterwards.\n\t\t\tlet end: number = i + 1;\n\t\t\tconst angleLimit: number = Math.min(this.len, i + 1 + MAX_DESTINATION_LENGTH);\n\t\t\twhile (end < angleLimit) {\n\t\t\t\tconst ch: string = this.text[end] ?? '';\n\t\t\t\tif (ch === '\\\\' && ESCAPABLE.test(this.text[end + 1] ?? '')) {\n\t\t\t\t\tend += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (ch === '>' || ch === '<' || ch === '\\n') break;\n\t\t\t\tend++;\n\t\t\t}\n\t\t\tif (this.text[end] !== '>') return null;\n\t\t\thref = decodeEscapesAndEntities(this.text.slice(i + 1, end));\n\t\t\ti = end + 1;\n\t\t} else {\n\t\t\tlet depth = 0;\n\t\t\t// Bound the destination scan: real URLs are short, and an unbounded scan\n\t\t\t// over adversarial input (`](](]( …` with no closing paren) is quadratic.\n\t\t\tconst limit: number = Math.min(this.len, i + MAX_DESTINATION_LENGTH);\n\t\t\twhile (i < limit) {\n\t\t\t\tconst ch: string = this.text[i] ?? '';\n\t\t\t\tif (ch === '\\\\' && ESCAPABLE.test(this.text[i + 1] ?? '')) {\n\t\t\t\t\thref += this.text[i + 1];\n\t\t\t\t\ti += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (ch === '(') depth++;\n\t\t\t\telse if (ch === ')') {\n\t\t\t\t\tif (depth === 0) break;\n\t\t\t\t\tdepth--;\n\t\t\t\t} else if (ch === ' ' || ch === '\\t' || ch === '\\n' || ch === '[' || ch === ']') {\n\t\t\t\t\t// Only ASCII whitespace ends a bare destination (a non-breaking\n\t\t\t\t\t// space is part of it, per CommonMark); `[`/`]` are not valid there\n\t\t\t\t\t// (real URLs percent-encode them) and bailing here keeps degenerate\n\t\t\t\t\t// `](](]( …` input linear instead of quadratic (D1 ReDoS guard).\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\thref += ch;\n\t\t\t\ti++;\n\t\t\t}\n\t\t\t// Scan hit the length cap without resolving a closing paren: not a link.\n\t\t\tif (i >= limit && this.text[i] !== ')') return null;\n\t\t\thref = decodeEntitiesOnly(href);\n\t\t}\n\n\t\twhile (this.text[i] === ' ' || this.text[i] === '\\n') i++;\n\t\tlet title = '';\n\t\tconst open: string = this.text[i] ?? '';\n\t\tif (open === '\"' || open === \"'\" || open === '(') {\n\t\t\tconst parsed: { title: string; next: number } | null = this.parseLinkTitle(i);\n\t\t\tif (!parsed) return null;\n\t\t\ttitle = parsed.title;\n\t\t\ti = parsed.next;\n\t\t}\n\t\twhile (this.text[i] === ' ' || this.text[i] === '\\n') i++;\n\t\tif (this.text[i] !== ')') return null;\n\t\tthis.pos = i + 1;\n\t\treturn { href, title };\n\t}\n\n\t/**\n\t * Parses a link/image title that starts at its opening delimiter (`\"`, `'`,\n\t * or `(`), honoring backslash escapes so an escaped closing delimiter stays\n\t * part of the title (e.g. `\"a\\\"b\"` is the title `a\"b`). Mirrors the serializer\n\t * which escapes the delimiter on output, so titles round-trip losslessly.\n\t * Returns the unescaped title and the index just past the closing delimiter,\n\t * or null if it is never closed within the scan bound (D1 ReDoS guard).\n\t */\n\tprivate parseLinkTitle(start: number): { title: string; next: number } | null {\n\t\tconst open: string = this.text[start] ?? '';\n\t\tconst close: string = open === '(' ? ')' : open;\n\t\tlet title = '';\n\t\tlet i: number = start + 1;\n\t\tconst limit: number = Math.min(this.len, start + 1 + MAX_DESTINATION_LENGTH);\n\t\twhile (i < limit) {\n\t\t\tconst ch: string = this.text[i] ?? '';\n\t\t\tif (ch === '\\\\' && ESCAPABLE.test(this.text[i + 1] ?? '')) {\n\t\t\t\ttitle += this.text[i + 1];\n\t\t\t\ti += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (ch === close) return { title: decodeEntitiesOnly(title), next: i + 1 };\n\t\t\ttitle += ch;\n\t\t\ti++;\n\t\t}\n\t\treturn null;\n\t}\n\n\t/** `&`: decodes an HTML entity reference, or emits a literal `&`. */\n\tprivate parseEntity(): InlineAstNode {\n\t\tconst match: RegExpExecArray | null = matchEntityAt(this.text, this.pos);\n\t\tif (!match?.[1]) {\n\t\t\tthis.pos++;\n\t\t\treturn makeNode('text', '&');\n\t\t}\n\t\tthis.pos += match[0].length;\n\t\treturn makeNode('text', decodeEntity(match[1]));\n\t}\n\n\t/** `<`: autolink, inline HTML (balanced fallback run), or literal. */\n\tprivate parseLessThan(): InlineAstNode {\n\t\tconst auto: InlineAstNode | null = this.parseAutolink();\n\t\tif (auto) return auto;\n\t\tconst html: InlineAstNode | null = this.parseInlineHtml();\n\t\tif (html) return html;\n\t\tthis.pos++;\n\t\treturn makeNode('text', '<');\n\t}\n\n\tprivate parseAutolink(): InlineAstNode | null {\n\t\tconst rest: string = this.text.slice(this.pos);\n\t\tconst uri: RegExpMatchArray | null = rest.match(/^<([a-zA-Z][a-zA-Z0-9+.-]{1,31}:[^<>\\s]*)>/);\n\t\tif (uri?.[1]) {\n\t\t\tthis.pos += uri[0].length;\n\t\t\tconst node: InlineAstNode = makeNode('link');\n\t\t\tnode.href = uri[1];\n\t\t\tnode.children = [makeNode('text', uri[1])];\n\t\t\treturn node;\n\t\t}\n\t\tconst email: RegExpMatchArray | null = rest.match(\n\t\t\t/^<([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])?)*)>/,\n\t\t);\n\t\tif (email?.[1]) {\n\t\t\tthis.pos += email[0].length;\n\t\t\tconst node: InlineAstNode = makeNode('link');\n\t\t\tnode.href = `mailto:${email[1]}`;\n\t\t\tnode.children = [makeNode('text', email[1])];\n\t\t\treturn node;\n\t\t}\n\t\treturn null;\n\t}\n\n\t/** Captures a balanced inline-HTML fallback run (`<u>…</u>`) or a single tag. */\n\tprivate parseInlineHtml(): InlineAstNode | null {\n\t\tconst rest: string = this.text.slice(this.pos);\n\t\tconst open: RegExpMatchArray | null = rest.match(/^<([a-zA-Z][a-zA-Z0-9-]*)(?:\\s[^<>]*)?>/);\n\t\tif (!open?.[1]) {\n\t\t\tconst comment: RegExpMatchArray | null = rest.match(/^<!--[\\s\\S]*?-->/);\n\t\t\tif (comment) {\n\t\t\t\tthis.pos += comment[0].length;\n\t\t\t\treturn makeNode('html_inline', normalizeHtmlLiteral(comment[0]));\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\tconst tag: string = open[1].toLowerCase();\n\t\tif (INLINE_HTML_TAGS.has(tag)) {\n\t\t\tconst closeTag = `</${tag}>`;\n\t\t\tconst closeIdx: number = this.text.toLowerCase().indexOf(closeTag, this.pos + open[0].length);\n\t\t\tif (closeIdx !== -1) {\n\t\t\t\tconst end: number = closeIdx + closeTag.length;\n\t\t\t\tconst html: string = this.text.slice(this.pos, end);\n\t\t\t\tthis.pos = end;\n\t\t\t\treturn makeNode('html_inline', normalizeHtmlLiteral(html));\n\t\t\t}\n\t\t}\n\t\tthis.pos += open[0].length;\n\t\treturn makeNode('html_inline', normalizeHtmlLiteral(open[0]));\n\t}\n\n\t/**\n\t * The CommonMark emphasis algorithm: walk closers, match against openers,\n\t * wrap the enclosed nodes, honoring the rule-of-three for `*` / `_`.\n\t *\n\t * `openersBottom` is the CommonMark \"lower bound for opener searches\" cache.\n\t * It must be keyed by `(delimiter char, canOpen, origdelims % 3)` — exactly\n\t * the bucketing used by the reference implementation — because the rule-of-\n\t * three test depends on both flags. Keying by the character alone lets a\n\t * `canOpen=false` closer that fails lower the bound for a later `canOpen=true`\n\t * closer of a different length class, silently dropping valid emphasis (e.g.\n\t * `**a*b*c**` would lose all of its bold/italic).\n\t */\n\tprivate processEmphasis(stackBottom: Delimiter | null): void {\n\t\tconst openersBottom = new Map<string, Delimiter | null>();\n\t\tconst bottomFor = (d: Delimiter): Delimiter | null => {\n\t\t\tconst key: string = emphBottomKey(d);\n\t\t\treturn openersBottom.has(key) ? (openersBottom.get(key) ?? null) : stackBottom;\n\t\t};\n\n\t\tlet closer: Delimiter | null = stackBottom ? stackBottom.next : this.firstDelimiter();\n\t\twhile (closer) {\n\t\t\tif (!closer.canClose) {\n\t\t\t\tcloser = closer.next;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst cc: string = closer.cc;\n\t\t\tlet opener: Delimiter | null = closer.prev;\n\t\t\tlet openerFound = false;\n\t\t\tconst bottom: Delimiter | null = bottomFor(closer);\n\t\t\twhile (opener && opener !== stackBottom && opener !== bottom) {\n\t\t\t\tif (opener.cc === cc && opener.canOpen && this.emphMatches(opener, closer)) {\n\t\t\t\t\topenerFound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\topener = opener.prev;\n\t\t\t}\n\n\t\t\tif (!openerFound) {\n\t\t\t\topenersBottom.set(emphBottomKey(closer), closer.prev);\n\t\t\t\tif (!closer.canOpen) this.removeDelimiter(closer);\n\t\t\t\tcloser = closer.next;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst matchedOpener: Delimiter = opener as Delimiter;\n\t\t\tconst use: number = this.wrapCount(cc, matchedOpener, closer);\n\t\t\tif (use === 0) {\n\t\t\t\tcloser = closer.next;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tthis.wrapEmphasis(cc, matchedOpener, closer, use);\n\n\t\t\tmatchedOpener.numdelims -= use;\n\t\t\tcloser.numdelims -= use;\n\t\t\tmatchedOpener.node.literal = matchedOpener.node.literal.slice(use);\n\t\t\tcloser.node.literal = closer.node.literal.slice(use);\n\n\t\t\tthis.removeDelimitersBetween(matchedOpener, closer);\n\t\t\tif (matchedOpener.numdelims === 0) this.removeDelimiter(matchedOpener);\n\t\t\tif (closer.numdelims === 0) {\n\t\t\t\tconst next: Delimiter | null = closer.next;\n\t\t\t\tthis.removeDelimiter(closer);\n\t\t\t\tcloser = next;\n\t\t\t}\n\t\t}\n\n\t\t// Remove all delimiters above stackBottom.\n\t\twhile (this.delimiters && this.delimiters !== stackBottom) {\n\t\t\tthis.removeDelimiter(this.delimiters);\n\t\t}\n\t}\n\n\tprivate firstDelimiter(): Delimiter | null {\n\t\tlet d: Delimiter | null = this.delimiters;\n\t\twhile (d?.prev) d = d.prev;\n\t\treturn d;\n\t}\n\n\t/** Rule-of-three test for `*` / `_`; other delimiters always match. */\n\tprivate emphMatches(opener: Delimiter, closer: Delimiter): boolean {\n\t\tif (opener.cc !== '*' && opener.cc !== '_') return true;\n\t\tconst oddMatch: boolean =\n\t\t\t(closer.canOpen || opener.canClose) &&\n\t\t\tcloser.origdelims % 3 !== 0 &&\n\t\t\t(opener.origdelims + closer.origdelims) % 3 === 0;\n\t\treturn !oddMatch;\n\t}\n\n\t/** How many delimiters this match consumes (and implicitly which wrapper kind). */\n\tprivate wrapCount(cc: string, opener: Delimiter, closer: Delimiter): number {\n\t\tconst both2: boolean = opener.numdelims >= 2 && closer.numdelims >= 2;\n\t\tif (cc === '*' || cc === '_') return both2 ? 2 : 1;\n\t\tif (cc === '~') {\n\t\t\tif (this.ctx.opts.gfm && both2) return 2;\n\t\t\treturn this.ctx.opts.extendedInlineSyntax ? 1 : 0;\n\t\t}\n\t\tif (cc === '=') return this.ctx.opts.extendedInlineSyntax && both2 ? 2 : 0;\n\t\tif (cc === '^') return this.ctx.opts.extendedInlineSyntax ? 1 : 0;\n\t\treturn 0;\n\t}\n\n\tprivate wrapKind(cc: string, use: number): InlineKind {\n\t\tif (cc === '*' || cc === '_') return use === 2 ? 'strong' : 'emph';\n\t\tif (cc === '~') return use === 2 ? 'strike' : 'sub';\n\t\tif (cc === '=') return 'highlight';\n\t\treturn 'sup';\n\t}\n\n\t/** Moves nodes between opener and closer into a new wrapper node. */\n\tprivate wrapEmphasis(cc: string, opener: Delimiter, closer: Delimiter, use: number): void {\n\t\tconst wrapper: InlineAstNode = makeNode(this.wrapKind(cc, use));\n\t\tlet node: InlineAstNode | null = opener.node.next;\n\t\twhile (node && node !== closer.node) {\n\t\t\tconst next: InlineAstNode | null = node.next;\n\t\t\tunlink(node);\n\t\t\twrapper.children.push(node);\n\t\t\tnode = next;\n\t\t}\n\t\tinsertAfter(opener.node, wrapper);\n\t}\n\n\tprivate removeDelimitersBetween(opener: Delimiter, closer: Delimiter): void {\n\t\tlet d: Delimiter | null = closer.prev;\n\t\twhile (d && d !== opener) {\n\t\t\tconst prev: Delimiter | null = d.prev;\n\t\t\tthis.removeDelimiter(d);\n\t\t\td = prev;\n\t\t}\n\t}\n\n\tprivate removeDelimiter(delim: Delimiter): void {\n\t\tif (delim.prev) delim.prev.next = delim.next;\n\t\tif (delim.next) delim.next.prev = delim.prev;\n\t\tif (!delim.next) this.delimiters = delim.prev;\n\t}\n}\n\n/**\n * The `openersBottom` bucket key for a closer: `(char, canOpen, origdelims % 3)`,\n * mirroring the CommonMark reference implementation's index (`base + (canOpen ?\n * 3 : 0) + (origdelims % 3)`). `origdelims` is used, not the live `numdelims`, so\n * the key is stable across the delimiter's consumption.\n */\nfunction emphBottomKey(d: Delimiter): string {\n\treturn `${d.cc}${d.canOpen ? 1 : 0}${d.origdelims % 3}`;\n}\n\n/**\n * Normalizes newlines inside a captured raw-HTML run to single spaces. The\n * literal is opaque to the engine; on re-import the newlines would become soft\n * breaks (spaces) anyway, so normalizing here keeps `md → doc → md` a fixpoint.\n */\nfunction normalizeHtmlLiteral(html: string): string {\n\treturn html.replace(/\\n[ \\t]*/g, ' ');\n}\n\n/** Collects the sibling list after the synthetic root into an array. */\nfunction collectSiblings(root: InlineAstNode): InlineAstNode[] {\n\tconst out: InlineAstNode[] = [];\n\tlet node: InlineAstNode | null = root.next;\n\twhile (node) {\n\t\tout.push(node);\n\t\tnode = node.next;\n\t}\n\treturn out;\n}\n\n/** Extracts the plain-text content of an AST subtree (for image alt text). */\nfunction astPlainText(nodes: readonly InlineAstNode[]): string {\n\tlet out = '';\n\tfor (const node of nodes) {\n\t\tif (node.type === 'text' || node.type === 'code') out += node.literal;\n\t\telse if (node.type === 'softbreak' || node.type === 'hardbreak') out += ' ';\n\t\telse if (node.children.length) out += astPlainText(node.children);\n\t\telse if (node.alt) out += node.alt;\n\t}\n\treturn out;\n}\n\n// --- Flatten AST → notectl inline content ---\n\nconst KIND_TO_MARK: Partial<Record<InlineKind, string>> = {\n\temph: 'italic',\n\tstrong: 'bold',\n\tstrike: 'strikethrough',\n\thighlight: 'highlight',\n\tsup: 'superscript',\n\tsub: 'subscript',\n};\n\n/** Whether a mark type is usable (no registry means tests; allow all). */\nfunction markAllowed(ctx: ParseContext, type: string): boolean {\n\treturn !ctx.registry || ctx.registry.getMarkSpec(type) !== undefined;\n}\n\nfunction flatten(\n\tnodes: readonly InlineAstNode[],\n\tmarks: readonly Mark[],\n\tctx: ParseContext,\n\tout: (TextNode | InlineNode)[],\n): void {\n\tfor (const node of nodes) {\n\t\tflattenNode(node, marks, ctx, out);\n\t}\n}\n\nfunction flattenNode(\n\tnode: InlineAstNode,\n\tmarks: readonly Mark[],\n\tctx: ParseContext,\n\tout: (TextNode | InlineNode)[],\n): void {\n\tswitch (node.type) {\n\t\tcase 'text':\n\t\t\tif (node.literal) out.push(createTextNode(node.literal, [...marks]));\n\t\t\treturn;\n\t\tcase 'softbreak':\n\t\t\tout.push(createTextNode(' ', [...marks]));\n\t\t\treturn;\n\t\tcase 'hardbreak':\n\t\t\tout.push(createInlineNode(inlineType('hard_break'), {}));\n\t\t\treturn;\n\t\tcase 'code':\n\t\t\tout.push(createTextNode(node.literal, withMark(marks, ctx, 'code')));\n\t\t\treturn;\n\t\tcase 'link': {\n\t\t\tconst attrs: Record<string, string> = { href: node.href };\n\t\t\tif (node.title) attrs.title = node.title;\n\t\t\tflatten(node.children, withMark(marks, ctx, 'link', attrs), ctx, out);\n\t\t\treturn;\n\t\t}\n\t\tcase 'image': {\n\t\t\tpushImage(node, marks, ctx, out);\n\t\t\treturn;\n\t\t}\n\t\tcase 'inline_node':\n\t\t\tout.push(\n\t\t\t\tcreateInlineNode(inlineType(node.inlineType) as InlineTypeName, node.attrs, [...marks]),\n\t\t\t);\n\t\t\treturn;\n\t\tcase 'html_inline':\n\t\t\tpushInlineHtml(node.literal, marks, ctx, out);\n\t\t\treturn;\n\t\tdefault: {\n\t\t\tconst markName: string | undefined = KIND_TO_MARK[node.type];\n\t\t\tif (markName) {\n\t\t\t\tflatten(node.children, withMark(marks, ctx, markName), ctx, out);\n\t\t\t} else {\n\t\t\t\tflatten(node.children, marks, ctx, out);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/** Returns `marks` plus a new mark of `type` (with attrs), if the schema allows it. */\nfunction withMark(\n\tmarks: readonly Mark[],\n\tctx: ParseContext,\n\ttype: string,\n\tattrs?: Record<string, string | number | boolean>,\n): Mark[] {\n\tif (!markAllowed(ctx, type)) return [...marks];\n\tconst mark: Mark = attrs ? { type: markType(type), attrs } : { type: markType(type) };\n\treturn [...marks, mark];\n}\n\n/** Emits an inline image node, or degrades to alt text when unavailable. */\nfunction pushImage(\n\tnode: InlineAstNode,\n\tmarks: readonly Mark[],\n\tctx: ParseContext,\n\tout: (TextNode | InlineNode)[],\n): void {\n\tconst hasInlineImage: boolean =\n\t\t!ctx.registry || ctx.registry.getInlineNodeSpec('image_inline') !== undefined;\n\tif (hasInlineImage) {\n\t\tconst attrs: Record<string, string> = { src: node.href, alt: node.alt };\n\t\tif (node.title) attrs.title = node.title;\n\t\t// Carry the surrounding marks (e.g. a `link` from `[![alt](src)](url)`) so a\n\t\t// linked inline image keeps its link instead of silently dropping it.\n\t\tout.push(createInlineNode(inlineType('image_inline'), attrs, [...marks]));\n\t\treturn;\n\t}\n\tif (node.alt) out.push(createTextNode(node.alt, [...marks]));\n}\n\n/** Re-parses an inline-HTML fallback run via the HTML parser to recover marks. */\nfunction pushInlineHtml(\n\thtml: string,\n\tmarks: readonly Mark[],\n\tctx: ParseContext,\n\tout: (TextNode | InlineNode)[],\n): void {\n\t// The HTML parser treats a lone <br> in a paragraph as an empty-block\n\t// placeholder. Here the paragraph is synthetic, so it is a real hard break.\n\tconst hardBreakAllowed: boolean =\n\t\t!ctx.registry || ctx.registry.getInlineNodeSpec('hard_break') !== undefined;\n\tif (hardBreakAllowed && /^<br\\s*\\/?>$/i.test(html.trim())) {\n\t\tout.push(createInlineNode(inlineType('hard_break'), {}, [...marks]));\n\t\treturn;\n\t}\n\tconst doc = parseHTMLToDocument(`<p>${html}</p>`, resolveMarkdownHTMLRegistry(ctx.registry));\n\tconst block = doc.children[0];\n\tif (!block) return;\n\tlet emitted = false;\n\tfor (const child of block.children) {\n\t\tif ('text' in child && child.text !== '') {\n\t\t\tout.push(createTextNode(child.text, mergeMarks(marks, child.marks)));\n\t\t\temitted = true;\n\t\t} else if ('inlineType' in child) {\n\t\t\tout.push(createInlineNode(child.inlineType, child.attrs, mergeMarks(marks, child.marks)));\n\t\t\temitted = true;\n\t\t}\n\t}\n\t// An unknown/empty HTML element has no baseline model representation. Keep\n\t// it literal on registry-free calls instead of silently dropping input.\n\tif (!emitted && !ctx.registry) out.push(createTextNode(html, [...marks]));\n}\n\n/** Merges two mark lists, de-duplicating by type. */\nfunction mergeMarks(outer: readonly Mark[], inner: readonly Mark[]): Mark[] {\n\tconst result: Mark[] = [...outer];\n\tfor (const mark of inner) {\n\t\tif (!result.some((m) => m.type === mark.type)) result.push(mark);\n\t}\n\treturn result;\n}\n\n/** Merges adjacent text nodes that share an identical mark set. */\nfunction mergeAdjacentText(nodes: readonly (TextNode | InlineNode)[]): (TextNode | InlineNode)[] {\n\tconst result: (TextNode | InlineNode)[] = [];\n\tfor (const node of nodes) {\n\t\tconst prev = result[result.length - 1];\n\t\tif ('text' in node && prev && 'text' in prev && sameMarkTypes(prev.marks, node.marks)) {\n\t\t\tresult[result.length - 1] = { type: 'text', text: prev.text + node.text, marks: prev.marks };\n\t\t} else {\n\t\t\tresult.push(node);\n\t\t}\n\t}\n\treturn result;\n}\n\n/** Structural equality of two mark lists (type + attrs, order-independent). */\nfunction sameMarkTypes(a: readonly Mark[], b: readonly Mark[]): boolean {\n\tif (a.length !== b.length) return false;\n\tconst key = (m: Mark): string => `${m.type}:${JSON.stringify(m.attrs ?? {})}`;\n\tconst setB = new Set(b.map(key));\n\treturn a.every((m) => setB.has(key(m)));\n}\n\n/** Parses inline Markdown into text/inline nodes (linear-time, ReDoS-safe). */\nexport function parseInline(text: string, ctx: ParseContext): (TextNode | InlineNode)[] {\n\tconst ast: InlineAstNode[] = new InlineParser(text, ctx).parse();\n\tif (ctx.opts.gfm) applyGfmEmailAutolinks(ast);\n\tconst out: (TextNode | InlineNode)[] = [];\n\tflatten(ast, [], ctx, out);\n\tconst merged: (TextNode | InlineNode)[] = mergeAdjacentText(out);\n\treturn merged.length > 0 ? merged : [createTextNode('')];\n}\n","/**\n * Resolved parse options and the context threaded through the Markdown parser.\n * Mirrors `MarkdownContext.ts` on the serialize side.\n */\n\nimport type { SchemaRegistry } from '../../model/SchemaRegistry.js';\nimport type { MarkdownParseOptions, MarkdownSyntaxExtension } from '../MarkdownTypes.js';\n\n/** Fully-resolved parse options (no `undefined`). */\nexport interface ResolvedParseOptions {\n\treadonly flavor: 'commonmark' | 'gfm';\n\treadonly gfm: boolean;\n\treadonly extendedInlineSyntax: boolean;\n\treadonly htmlFallback: boolean;\n\treadonly syntaxExtensions: readonly MarkdownSyntaxExtension[];\n}\n\n/** Internal context shared by the block and inline parsers. */\nexport interface ParseContext {\n\treadonly registry?: SchemaRegistry;\n\treadonly opts: ResolvedParseOptions;\n\t/** Link reference definitions collected from the source (`[ref]: url \"title\"`). */\n\treadonly linkRefs: ReadonlyMap<string, { readonly href: string; readonly title?: string }>;\n}\n\n/** Resolves user-facing parse options into a complete settings object with defaults. */\nexport function resolveParseOptions(options?: MarkdownParseOptions): ResolvedParseOptions {\n\tconst flavor: 'commonmark' | 'gfm' = options?.flavor ?? 'gfm';\n\treturn {\n\t\tflavor,\n\t\tgfm: flavor === 'gfm',\n\t\textendedInlineSyntax: options?.extendedInlineSyntax ?? false,\n\t\thtmlFallback: options?.htmlFallback !== false,\n\t\tsyntaxExtensions: options?.syntaxExtensions ?? [],\n\t};\n}\n","/**\n * MarkdownParser: converts a Markdown string into an immutable Document.\n *\n * Mirrors `DocumentParser.ts` (HTML) but is reached **only** via dynamic\n * `import()` so it stays code-split out of the core bundle (D13). The grammar is\n * centralized (CommonMark is a global, context-sensitive grammar that cannot be\n * decomposed into per-spec rules, D4); tokens map to schema node types by name\n * through the registry. Raw HTML blocks delegate to `parseHTMLToDocument` so the\n * superset round-trip stays lossless (D3). Plugin syntax (`$...$`) is contributed\n * via `options.syntaxExtensions`, never hard-coded here.\n */\n\nimport { hoistDisallowedBlocks } from '../model/ContentModel.js';\nimport type { BlockNode, Document, InlineNode, TextNode } from '../model/Document.js';\nimport {\n\tcreateBlockNode,\n\tcreateDocument,\n\tcreateTextNode,\n\tisInlineNode,\n} from '../model/Document.js';\nimport type { SchemaRegistry } from '../model/SchemaRegistry.js';\nimport { type NodeTypeName, nodeType } from '../model/TypeBrands.js';\nimport { parseHTMLToDocument } from './DocumentParser.js';\nimport type { MarkdownParseOptions } from './MarkdownTypes.js';\nimport type { BlockToken } from './markdown/BlockTokenizer.js';\nimport { tokenizeBlocks } from './markdown/BlockTokenizer.js';\nimport type { ColumnAlign } from './markdown/GfmTableParser.js';\nimport { parseInline } from './markdown/InlineTokenizer.js';\nimport { extractLinkReferences } from './markdown/LinkReferenceExtractor.js';\nimport { resolveMarkdownHTMLRegistry } from './markdown/MarkdownHTMLRegistry.js';\nimport { type ParseContext, resolveParseOptions } from './markdown/MarkdownParseContext.js';\n\n/** Parses a Markdown string into a Document. */\nexport function parseMarkdownToDocument(\n\tmarkdown: string,\n\tregistry?: SchemaRegistry,\n\toptions?: MarkdownParseOptions,\n): Document {\n\tconst normalized: string = markdown.replace(/\\r\\n?/g, '\\n');\n\tconst { source, linkRefs } = extractLinkReferences(normalized);\n\n\tconst ctx: ParseContext = {\n\t\tregistry,\n\t\topts: resolveParseOptions(options),\n\t\tlinkRefs,\n\t};\n\n\tconst tokens: BlockToken[] = tokenizeBlocks(source, ctx.opts.gfm, ctx.opts.syntaxExtensions);\n\tconst blocks: BlockNode[] = tokensToBlocks(tokens, ctx);\n\tif (blocks.length === 0) return createDocument();\n\tconst doc: Document = createDocument(blocks);\n\t// A container item can only hold the block types its schema allows; an\n\t// importer that nested (say) a table under an item is repaired by hoisting the\n\t// disallowed block up to a valid ancestor (#194).\n\treturn registry ? hoistDisallowedBlocks(doc, registry) : doc;\n}\n\n/** Converts a list of block tokens into Document block nodes. */\nfunction tokensToBlocks(tokens: readonly BlockToken[], ctx: ParseContext): BlockNode[] {\n\tconst blocks: BlockNode[] = [];\n\tfor (const token of tokens) {\n\t\tappendToken(token, blocks, ctx);\n\t}\n\treturn blocks;\n}\n\n/** Appends the block node(s) produced by a single token. */\nfunction appendToken(token: BlockToken, blocks: BlockNode[], ctx: ParseContext): void {\n\tswitch (token.type) {\n\t\tcase 'heading':\n\t\t\tblocks.push(makeBlock('heading', parseInline(token.text, ctx), ctx, { level: token.level }));\n\t\t\treturn;\n\t\tcase 'paragraph': {\n\t\t\tconst inline: (TextNode | InlineNode)[] = parseInline(token.text, ctx);\n\t\t\tconst image: BlockNode | null = promoteStandaloneImage(inline, ctx);\n\t\t\tblocks.push(image ?? makeBlock('paragraph', inline, ctx));\n\t\t\treturn;\n\t\t}\n\t\tcase 'table':\n\t\t\tblocks.push(buildTable(token.aligns, token.header, token.rows, ctx));\n\t\t\treturn;\n\t\tcase 'extension_block':\n\t\t\tblocks.push(makeBlock(token.nodeType, [createTextNode('')], ctx, token.attrs));\n\t\t\treturn;\n\t\tcase 'code_block':\n\t\t\tblocks.push(\n\t\t\t\tmakeBlock('code_block', [createTextNode(token.code)], ctx, { language: token.language }),\n\t\t\t);\n\t\t\treturn;\n\t\tcase 'hr':\n\t\t\tblocks.push(makeBlock('horizontal_rule', [createTextNode('')], ctx));\n\t\t\treturn;\n\t\tcase 'list_item': {\n\t\t\tconst attrs: Record<string, string | number | boolean> = {\n\t\t\t\tlistType: token.listType,\n\t\t\t\tindent: token.indent,\n\t\t\t\tchecked: token.checked,\n\t\t\t};\n\t\t\tif (token.children && token.children.length > 0) {\n\t\t\t\t// Multi-block item (#194): a container whose children are blocks.\n\t\t\t\tconst children: BlockNode[] = tokensToBlocks(token.children, ctx);\n\t\t\t\tif (ctx.registry && !ctx.registry.getNodeSpec('list_item')) {\n\t\t\t\t\t// Type unavailable: degrade to the children as top-level blocks.\n\t\t\t\t\tblocks.push(...children);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tblocks.push(createBlockNode(nodeType('list_item'), children, undefined, attrs));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tblocks.push(makeBlock('list_item', parseInline(token.text, ctx), ctx, attrs));\n\t\t\treturn;\n\t\t}\n\t\tcase 'blockquote': {\n\t\t\tconst children: BlockNode[] = tokensToBlocks(token.children, ctx);\n\t\t\tif (children.length === 0) {\n\t\t\t\tchildren.push(createBlockNode(nodeType('paragraph'), [createTextNode('')]));\n\t\t\t}\n\t\t\tblocks.push(makeContainer('blockquote', children, ctx));\n\t\t\treturn;\n\t\t}\n\t\tcase 'html':\n\t\t\t// A comment-only block produces no content (and must not leave a stray\n\t\t\t// empty paragraph between blocks, e.g. two lists split by `<!-- -->`).\n\t\t\tif (isCommentOnly(token.html)) return;\n\t\t\tfor (const block of parseHTMLToDocument(token.html, resolveMarkdownHTMLRegistry(ctx.registry))\n\t\t\t\t.children) {\n\t\t\t\tblocks.push(block);\n\t\t\t}\n\t\t\treturn;\n\t}\n}\n\n/** Whether an HTML block consists solely of comments (linear manual scan). */\nfunction isCommentOnly(html: string): boolean {\n\tlet rest: string = html.trim();\n\twhile (rest.startsWith('<!--')) {\n\t\tconst end: number = rest.indexOf('-->');\n\t\tif (end === -1) return false;\n\t\trest = rest.slice(end + 3).trim();\n\t}\n\treturn rest === '';\n}\n\n/** Builds a leaf block, falling back to a paragraph if the type is unavailable. */\nfunction makeBlock(\n\ttype: string,\n\tchildren: readonly (TextNode | InlineNode)[],\n\tctx: ParseContext,\n\tattrs?: Record<string, string | number | boolean>,\n): BlockNode {\n\tconst resolved: NodeTypeName = resolveType(type, ctx);\n\tconst childList: readonly (TextNode | InlineNode)[] =\n\t\tchildren.length > 0 ? children : [createTextNode('')];\n\treturn createBlockNode(\n\t\tresolved,\n\t\tchildList,\n\t\tundefined,\n\t\tattrs && resolved === nodeType(type) ? attrs : undefined,\n\t);\n}\n\n/** Builds a container block (block children), falling back to a paragraph if unavailable. */\nfunction makeContainer(type: string, children: readonly BlockNode[], ctx: ParseContext): BlockNode {\n\tconst resolved: NodeTypeName = resolveType(type, ctx);\n\tif (resolved !== nodeType(type)) {\n\t\t// Type unavailable: degrade to the container's children inline (best effort).\n\t\treturn children[0] ?? createBlockNode(nodeType('paragraph'), [createTextNode('')]);\n\t}\n\treturn createBlockNode(resolved, children);\n}\n\n/** Resolves a desired node type against the registry, falling back to paragraph. */\nfunction resolveType(type: string, ctx: ParseContext): NodeTypeName {\n\tif (ctx.registry && !ctx.registry.getNodeSpec(type)) return nodeType('paragraph');\n\treturn nodeType(type);\n}\n\n/**\n * Promotes a paragraph holding only a single inline image to a block `image`\n * node, matching the serializer (a standalone-image line becomes a block image).\n * Returns null when the paragraph is not a lone image or `image` is unavailable.\n * A marked image (e.g. a linked `[![alt](src)](url)`) is never promoted: the\n * block `image` node cannot hold a mark, so promotion would drop the link.\n */\nfunction promoteStandaloneImage(\n\tinline: readonly (TextNode | InlineNode)[],\n\tctx: ParseContext,\n): BlockNode | null {\n\tif (inline.length !== 1) return null;\n\tconst only = inline[0];\n\tif (!only || !isInlineNode(only) || only.inlineType !== 'image_inline') return null;\n\tif (only.marks.length > 0) return null;\n\tif (ctx.registry && !ctx.registry.getNodeSpec('image')) return null;\n\n\tconst attrs: Record<string, string | number | boolean> = {\n\t\tsrc: String(only.attrs.src ?? ''),\n\t\talt: String(only.attrs.alt ?? ''),\n\t\talign: 'center',\n\t};\n\tif (only.attrs.title) attrs.title = String(only.attrs.title);\n\treturn createBlockNode(nodeType('image'), [createTextNode('')], undefined, attrs);\n}\n\n/** Builds a GFM table node (table → table_row → table_cell → paragraph). */\nfunction buildTable(\n\taligns: readonly ColumnAlign[],\n\theader: readonly string[],\n\trows: readonly (readonly string[])[],\n\tctx: ParseContext,\n): BlockNode {\n\tif (ctx.registry && !ctx.registry.getNodeSpec('table')) {\n\t\t// No table support: degrade to a paragraph per row so content is never lost.\n\t\tconst lines: string = [header, ...rows].map((r) => r.join(' | ')).join('\\n');\n\t\treturn makeBlock('paragraph', parseInline(lines, ctx), ctx);\n\t}\n\n\tconst buildRow = (cells: readonly string[]): BlockNode => {\n\t\tconst tableCells: BlockNode[] = cells.map((cell, col) => {\n\t\t\tconst align: ColumnAlign = aligns[col] ?? null;\n\t\t\tconst paragraph: BlockNode = createBlockNode(\n\t\t\t\tnodeType('paragraph'),\n\t\t\t\tparseInline(cell, ctx),\n\t\t\t\tundefined,\n\t\t\t\talign ? { align } : undefined,\n\t\t\t);\n\t\t\treturn createBlockNode(nodeType('table_cell'), [paragraph]);\n\t\t});\n\t\treturn createBlockNode(nodeType('table_row'), tableCells);\n\t};\n\n\t// GFM normalizes every body row to the header's column count: overlong rows\n\t// drop their extra cells, short rows are padded with empty cells. Keeping rows\n\t// ragged would break the per-column model invariant the table tools rely on\n\t// (column insert/delete and cell navigation index by a fixed colIndex per row).\n\tconst columnCount: number = header.length;\n\tconst normalizeRow = (cells: readonly string[]): readonly string[] => {\n\t\tif (cells.length === columnCount) return cells;\n\t\tconst normalized: string[] = cells.slice(0, columnCount);\n\t\twhile (normalized.length < columnCount) normalized.push('');\n\t\treturn normalized;\n\t};\n\n\tconst tableRows: BlockNode[] = [\n\t\tbuildRow(header),\n\t\t...rows.map((row) => buildRow(normalizeRow(row))),\n\t];\n\treturn createBlockNode(nodeType('table'), tableRows);\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{t}from"./rolldown-runtime-H_PjY6_i.mjs";import{o as n}from"./HTMLUtils-Bhg3_P8B.mjs";import{E as e,O as r,T as o,_ as s,b as i,p as l,u as c}from"./Document-827l3P80.mjs";import{r as a}from"./AttrRegistry-B3zB02z9.mjs";import{_ as u,a as f,h as p,i as h,v as m}from"./TableDimensions-BBhjHNjQ.mjs";import{a as g,i as $,o as d,r as k,t as y}from"./MarkdownHTMLRegistry-Q7l0d6Ma.mjs";function b(t){const n=t?.flavor??"gfm";return{flavor:n,gfm:"gfm"===n,htmlFallback:!1!==t?.htmlFallback,headingStyle:t?.headingStyle??"atx",bullet:t?.bullet??"-",emphasis:t?.emphasis??"*",codeFence:t?.codeFence??"```",listIndent:t?.listIndent??2}}function S(t){return{flavor:t.flavor,htmlFallback:t.htmlFallback}}var x=new Set(["\\","`","*","[","]","<",">"]);function v(t,n){const e=t[n-1],r=t[n+1];return void 0!==e&&void 0!==r&&/\w/.test(e)&&/\w/.test(r)}function M(t,n){let e="";for(let r=0;r<t.length;r++){const o=t[r]??"";x.has(o)?e+=`\\${o}`:"_"!==o||v(t,r)?e+="~"===o&&n?"\\~":"&"!==o?o:"&amp;":e+="\\_"}return e}var F=/^(\s*)([#>])/,T=/^(\s*)([-*+])(\s)/,j=/^(\s*)(\d{1,9})([.)])(\s)/;function w(t){return F.test(t)?t.replace(F,(t,n,e)=>`${n}\\${e}`):T.test(t)?t.replace(T,(t,n,e,r)=>`${n}\\${e}${r}`):j.test(t)?t.replace(j,(t,n,e,r,o)=>`${n}${e}\\${r}${o}`):function(t){return d.test(t)||$.test(t)||g.test(t)||k.test(t)}(t)?t.replace(/\S/,t=>`\\${t}`):t}function L(t){return/[\s()]/.test(t)?`<${t.replace(/([<>])/g,"\\$1")}>`:t}function _(t){return t.replace(/(["\\])/g,"\\$1")}var H={styleAttr:t=>t?` style="${t}"`:""};function I(t,n){const e=t.type;return"link"===e||"bold"===e||"italic"===e||!("strikethrough"!==e||!n)}function N(t,n){const e=n.opts.emphasis;switch(t.type){case"bold":return{open:e.repeat(2),close:e.repeat(2)};case"italic":return{open:e,close:e};case"strikethrough":return{open:"~~",close:"~~"};default:{const n=String(t.attrs?.href??""),e=String(t.attrs?.title??"");return{open:"[",close:`](${L(n)}${e?` "${_(e)}"`:""})`}}}}function O(t){return"link"!==t.type}function A(t,n){return t.type===n.type&&JSON.stringify(t.attrs??{})===JSON.stringify(n.attrs??{})}function D(t,n){const e=[],r=[];for(const o of t.marks)I(o,n)&&("link"===o.type?e.push(o):r.push(o));return[...e,...r]}function W(t,n){const e=[],r=[...t];for(let o=r.length-1;o>=0;o--){const t=r[o];t&&!O(t)&&(e.push(t),r.splice(o,1))}for(const o of n){if(!O(o))continue;const t=r.findIndex(t=>A(t,o));if(-1!==t){const n=r[t];n&&e.push(n),r.splice(t,1)}}for(const o of r)e.push(o);return e}function z(t,n){if(""===t.text)return"";if(t.marks.some(t=>"code"===t.type))return function(t){const n=function(t){let n=0,e=0;for(const r of t)"`"===r?(e++,n=Math.max(n,e)):e=0;return"`".repeat(n+1)}(t);return`${n}${t.startsWith("`")||t.endsWith("`")||t.length>0&&0===t.trim().length?` ${t} `:t}${n}`}(t.text);const e=n.opts.gfm,r=t.marks.filter(t=>!I(t,e)&&"code"!==t.type);return r.length>0&&n.opts.htmlFallback?m(t.text,r,y(n.registry),n.markOrder,H):M(t.text,e)}function J(t,n){if("hard_break"===t.inlineType)return"\\\n";if("image_inline"===t.inlineType)return function(t,n){const e=String(t.attrs.src??""),r=String(t.attrs.alt??""),o=String(t.attrs.title??""),s=o?` "${_(o)}"`:"";return`![${M(r,n.opts.gfm)}](${L(e)}${s})`}(t,n);const e=n.registry?.getInlineNodeSpec(t.inlineType),r=e?.toMarkdown?.(t,S(n.opts));return null!=r?r:n.opts.htmlFallback&&e?.toHTMLString?e.toHTMLString(t):""}function P(t){const n=[];for(const e of t){const t=n[n.length-1];!o(e)&&t&&!o(t)&&r(t.marks,e.marks)?n[n.length-1]={type:"text",text:t.text+e.text,marks:t.marks}:n.push(e)}return n}function R(t,n){return!(!t||o(t))&&t.marks.some(t=>A(t,n))}function q(t,n){return 0===n.length?[...t]:t.filter(t=>!n.some(n=>A(n,t)))}function B(t,n,e,r,o){const s=t.marks.filter(t=>function(t,n){return I(t,n)&&"link"!==t.type}(t,r));if(0===s.length)return void o.push(t);const i=t.text,l=function(t){let n=0;for(;n<t.length&&/\s/.test(t[n]);)n++;return n}(i);if(l===i.length){const r=s.filter(t=>!(R(n,t)&&R(e,t)));return void o.push(c(i,q(t.marks,r)))}const a=function(t){let n=t.length;for(;n>0&&/\s/.test(t[n-1]);)n--;return t.length-n}(i),u=i.slice(0,l),f=i.slice(l,i.length-a),p=i.slice(i.length-a);if(u){const e=s.filter(t=>!R(n,t));o.push(c(u,q(t.marks,e)))}if(o.push(c(f,t.marks)),p){const n=s.filter(t=>!R(e,t));o.push(c(p,q(t.marks,n)))}}function E(t,n){const e=n.opts.gfm,r=function(t,n){const e=[];for(let r=0;r<t.length;r++){const s=t[r];s&&(o(s)?e.push(s):B(s,t[r-1],t[r+1],n,e))}return P(e)}(P(t),e);let s="",i=[];const l=t=>{for(let e=i.length-1;e>=t;e--){const t=i[e];t&&(s+=N(t,n).close)}i=i.slice(0,t)};for(const c of r){const t=W(D(c,e),i);let r=0;for(;r<i.length&&r<t.length&&A(i[r],t[r]);)r++;l(r);for(let e=r;e<t.length;e++){const r=t[e];r&&(s+=N(r,n).open,i.push(r))}s+=o(c)?J(c,n):z(c,n)}return l(0),s}function U(t,n){const e=[];let r=0;for(;r<t.length;){const o=t[r];if(o)if(a(o,"list_item")){const o=[];for(;r<t.length;){const n=t[r];if(!n||!a(n,"list_item"))break;o.push(n),r++}e.push(n.opts.htmlFallback&&o.some(G)?K(o,n):V(o,n))}else e.push(C(o,n)),r++;else r++}return e.filter(t=>t.length>0).join("\n\n")}function C(t,n){if(n.opts.htmlFallback&&G(t))return K([t],n);const r=t.type;return"paragraph"===r?function(t,n){const e=E(i(t),n);return""===e.trim()?"":e.split("\n").map(w).join("\n")}(t,n):"heading"===r?function(t,n){const e=function(t){return t<1?1:t>6?6:Math.floor(t)}(t.attrs?.level??1),r=E(i(t),n).replace(/\n/g," ");if("setext"===n.opts.headingStyle&&e<=2&&""!==r)return`${r}\n${(1===e?"=":"-").repeat(Math.max(3,r.length))}`;const o="#".repeat(e);return r?`${o} ${r}`:o}(t,n):"code_block"===r?function(t,n){const e=String(t.attrs?.language??""),r=s(t),o=n.opts.codeFence[0]??"`",i=o.repeat(Math.max(3,function(t,n){let e=0,r=0;for(const o of t)o===n?(r++,e=Math.max(e,r)):r=0;return e}(r,o)+1));return`${i}${e}\n${r}\n${i}`}(t,n):"horizontal_rule"===r?n.inListItem?"***":"---":"image"===r?function(t,n){const e=String(t.attrs?.src??""),r=String(t.attrs?.alt??""),o=String(t.attrs?.title??""),s=t.attrs?.width,i=t.attrs?.height,l=t.attrs?.align;if((void 0!==s||void 0!==i||void 0!==l&&"center"!==l)&&n.opts.htmlFallback){const e=n.registry?.getNodeSpec("image")?.toHTML?.(t,"");if(e)return e}const c=o?` "${_(o)}"`:"";return`![${M(r,n.opts.gfm)}](${L(e)}${c})`}(t,n):"blockquote"===r?function(t,n){return U(l(t),n).split("\n").map(t=>""===t?">":`> ${t}`).join("\n")}(t,n):"table"===r?function(t,n){const e=l(t);if(0===e.length)return"";if(!n.opts.gfm&&n.opts.htmlFallback)return K([t],n);if(n.opts.htmlFallback&&(function(t){for(const n of t)for(const t of l(n)){const n=t.attrs?.colspan,e=t.attrs?.rowspan;if((n??1)>1||(e??1)>1)return!0}return!1}(e)||function(t,n){return!!h(t.attrs?.columnWidthsPx)||n.some(t=>void 0!==f(t.attrs?.minHeightPx))}(t,e)))return K([t],n);const r=e.map(t=>l(t).map(t=>function(t,n){return l(t).map(t=>E(i(t),n)).join(" ").replace(/\n/g," ").replace(/\|/g,"\\|").trim()}(t,n))),o=r.reduce((t,n)=>Math.max(t,n.length),0);if(0===o)return"";const s=t=>{const n=[...t];for(;n.length<o;)n.push("");return`| ${n.join(" | ")} |`},c=e[0],a=Array.from({length:o},(t,n)=>{return e=function(t,n){if(!t)return;const e=l(t)[n];return e?l(e)[0]?.attrs?.align:void 0}(c,n),"start"===e?":---":"center"===e?":---:":"end"===e?"---:":"---";var e}),u=[];u.push(s(r[0]??[])),u.push(`| ${a.join(" | ")} |`);for(let i=1;i<r.length;i++)u.push(s(r[i]??[]));return u.join("\n")}(t,n):"title"===r?Q(t,n,1):"subtitle"===r?Q(t,n,2):function(t,n){const r=n.registry?.getNodeSpec(t.type),o=e(t)?E(i(t),n):U(l(t),n),s=r?.toMarkdown?.(t,o,S(n.opts));return null!=s?s:n.opts.htmlFallback&&r?.toHTML?r.toHTML(t,o):o}(t,n)}function G(t){return!!n(t.htmlId)||l(t).some(G)}function K(t,n){return p({children:t},y(n.registry),{includeBlockIds:!1})}function Q(t,n,e){if(n.opts.htmlFallback){const e=E(i(t),n),r=n.registry?.getNodeSpec(t.type)?.toHTML?.(t,e);if(r)return r}const r=E(i(t),n).replace(/\n/g," "),o="#".repeat(e);return r?`${o} ${r}`:o}function V(t,n){const r=[],o=[],s=[];let c=-1;for(const a of t){const t=String(a.attrs?.listType??"bullet"),u=Math.max(0,a.attrs?.indent??0),f=Math.min(u,c+1);c=f;const p=0===f?0:s[f-1]??0,h=" ".repeat(p);let m;if(o.length=f+1,s.length=f+1,"ordered"===t)o[f]=(o[f]??0)+1,m=`${o[f]}.`;else if("checklist"===t){const t=!0===a.attrs?.checked;m=`${n.opts.bullet} [${t?"x":" "}]`}else m=n.opts.bullet;const g="checklist"===t?n.opts.bullet.length+1:m.length+1;if(s[f]=p+g,e(a)){const t=w(E(i(a),n).replace(/\n/g," "));r.push(t?`${h}${m} ${t}`:`${h}${m}`);continue}const $=U(l(a),{...n,inListItem:!0});if(""===$){r.push(`${h}${m}`);continue}const d=" ".repeat(s[f]??p+g),k=$.split("\n");r.push(`${h}${m} ${k[0]??""}`);for(let n=1;n<k.length;n++){const t=k[n]??"";r.push(""===t?"":`${d}${t}`)}}return r.join("\n")}var X=/* @__PURE__ */t({serializeDocumentToMarkdown:()=>Y});function Y(t,n,e){const r={registry:n,opts:b(e),markOrder:n?u(n):void 0};return function(t){const n=t.trim();return n.length>0?`${n}\n`:""}(U(t.children,r))}export{Y as n,X as t};
2
+ //# sourceMappingURL=MarkdownSerializer-DBELFAeo.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownSerializer-DBELFAeo.mjs","names":[],"sources":["../../src/serialization/markdown/MarkdownContext.ts","../../src/serialization/markdown/MarkdownEscape.ts","../../src/serialization/markdown/InlineSerializers.ts","../../src/serialization/markdown/BlockSerializers.ts","../../src/serialization/MarkdownSerializer.ts"],"sourcesContent":["/**\n * Resolved serialization options and the context threaded through the Markdown\n * serializer. Kept separate from the serializer modules so block/inline\n * serializers can share the type without a circular import.\n */\n\nimport type { MarkdownExportContext } from '../../model/NodeSpec.js';\nimport type { SchemaRegistry } from '../../model/SchemaRegistry.js';\nimport type { MarkdownSerializeOptions } from '../MarkdownTypes.js';\n\n/** Fully-resolved serialization options (no `undefined`). */\nexport interface ResolvedSerializeOptions {\n\treadonly flavor: 'commonmark' | 'gfm';\n\treadonly gfm: boolean;\n\treadonly htmlFallback: boolean;\n\treadonly headingStyle: 'atx' | 'setext';\n\treadonly bullet: string;\n\treadonly emphasis: string;\n\treadonly codeFence: string;\n\treadonly listIndent: number;\n}\n\n/** Internal context shared by all serialization helpers. */\nexport interface SerContext {\n\treadonly registry?: SchemaRegistry;\n\treadonly opts: ResolvedSerializeOptions;\n\t/** Precomputed mark rank map (built once per pass) for HTML-fallback marks. */\n\treadonly markOrder?: Map<string, number>;\n\t/**\n\t * True while serializing the block children of a list item (#194): thematic\n\t * breaks emit `***` there, because `---` on an indented continuation line\n\t * would re-parse as a setext underline or a bullet marker.\n\t */\n\treadonly inListItem?: boolean;\n}\n\n/** Resolves user-facing options into a complete settings object with defaults. */\nexport function resolveSerializeOptions(\n\toptions?: MarkdownSerializeOptions,\n): ResolvedSerializeOptions {\n\tconst flavor: 'commonmark' | 'gfm' = options?.flavor ?? 'gfm';\n\treturn {\n\t\tflavor,\n\t\tgfm: flavor === 'gfm',\n\t\thtmlFallback: options?.htmlFallback !== false,\n\t\theadingStyle: options?.headingStyle ?? 'atx',\n\t\tbullet: options?.bullet ?? '-',\n\t\temphasis: options?.emphasis ?? '*',\n\t\tcodeFence: options?.codeFence ?? '```',\n\t\tlistIndent: options?.listIndent ?? 2,\n\t};\n}\n\n/** Builds the public {@link MarkdownExportContext} passed to per-spec hooks. */\nexport function exportContext(opts: ResolvedSerializeOptions): MarkdownExportContext {\n\treturn { flavor: opts.flavor, htmlFallback: opts.htmlFallback };\n}\n","/**\n * CommonMark escaping rules for Markdown serialization.\n *\n * Escaping is contextual: inline text backslash-escapes characters that would\n * otherwise start emphasis/code/links, while the start of a line additionally\n * escapes block markers (`#`, `>`, `-`, …) so prose never accidentally becomes\n * a heading or list on re-parse. Output stays minimal: we do not escape every\n * punctuation character, only those that are actually ambiguous in context.\n */\n\nimport { FENCE_OPEN, SETEXT_H1, SETEXT_H2, THEMATIC_BREAK } from './BlockTokenizer.js';\n\n/** Inline specials that always need escaping in text content. */\nconst ALWAYS_ESCAPE = new Set(['\\\\', '`', '*', '[', ']', '<', '>']);\n\n/** Whether the character at `i` sits between two word characters (intra-word). */\nfunction isIntraWord(text: string, i: number): boolean {\n\tconst prev: string | undefined = text[i - 1];\n\tconst next: string | undefined = text[i + 1];\n\tif (prev === undefined || next === undefined) return false;\n\treturn /\\w/.test(prev) && /\\w/.test(next);\n}\n\n/**\n * Escapes inline text so it round-trips as literal content. `~` is escaped only\n * for GFM (where `~~` is strikethrough); `_` is escaped only when it is not\n * intra-word, matching CommonMark's emphasis rules (so `a_b_c` stays literal).\n */\nexport function escapeInline(text: string, gfm: boolean): string {\n\tlet out = '';\n\tfor (let i = 0; i < text.length; i++) {\n\t\tconst ch: string = text[i] ?? '';\n\t\tif (ALWAYS_ESCAPE.has(ch)) {\n\t\t\tout += `\\\\${ch}`;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === '_' && !isIntraWord(text, i)) {\n\t\t\tout += '\\\\_';\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === '~' && gfm) {\n\t\t\tout += '\\\\~';\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === '&') {\n\t\t\tout += '&amp;';\n\t\t\tcontinue;\n\t\t}\n\t\tout += ch;\n\t}\n\treturn out;\n}\n\n/** Pattern matching a leading block marker that must be escaped in paragraph text. */\nconst LINE_START_MARKER = /^(\\s*)([#>])/;\n/** Pattern matching a leading list bullet (`- `, `* `, `+ `). */\nconst LINE_START_BULLET = /^(\\s*)([-*+])(\\s)/;\n/** Pattern matching a leading ordered marker (`1.` / `1)`). */\nconst LINE_START_ORDERED = /^(\\s*)(\\d{1,9})([.)])(\\s)/;\n\n/**\n * Whether a whole line would re-parse as a block construct that spans the entire\n * line: a thematic break, a setext underline, or an opening code fence. These\n * carry no trailing content marker (unlike `#`/`-`/`1.`), so they slip past the\n * leading-marker rules above. Backtick fences and `*`/`_`/`~` breaks are already\n * neutralized by inline escaping (they arrive backslash-prefixed); what reaches\n * here is `-`/`=` runs and, under CommonMark, `~~~` fences.\n */\nfunction reparsesAsBlockLine(line: string): boolean {\n\treturn (\n\t\tTHEMATIC_BREAK.test(line) ||\n\t\tSETEXT_H1.test(line) ||\n\t\tSETEXT_H2.test(line) ||\n\t\tFENCE_OPEN.test(line)\n\t);\n}\n\n/**\n * Escapes leading block markers at the start of a paragraph line so the text\n * does not re-parse as a heading, blockquote, list, thematic break, setext\n * underline, or code fence.\n */\nexport function escapeLineStart(line: string): string {\n\tif (LINE_START_MARKER.test(line)) {\n\t\treturn line.replace(LINE_START_MARKER, (_m, ws: string, marker: string) => `${ws}\\\\${marker}`);\n\t}\n\tif (LINE_START_BULLET.test(line)) {\n\t\treturn line.replace(\n\t\t\tLINE_START_BULLET,\n\t\t\t(_m, ws: string, marker: string, sp: string) => `${ws}\\\\${marker}${sp}`,\n\t\t);\n\t}\n\tif (LINE_START_ORDERED.test(line)) {\n\t\treturn line.replace(\n\t\t\tLINE_START_ORDERED,\n\t\t\t(_m, ws: string, num: string, marker: string, sp: string) => `${ws}${num}\\\\${marker}${sp}`,\n\t\t);\n\t}\n\tif (reparsesAsBlockLine(line)) {\n\t\t// Backslash the first non-space character: that breaks the run so the line\n\t\t// stays a paragraph, and `\\-` / `\\=` / `\\~` decode back to the literal char.\n\t\treturn line.replace(/\\S/, (ch) => `\\\\${ch}`);\n\t}\n\treturn line;\n}\n\n/** Escapes the destination of a link/image so spaces and parens stay intact. */\nexport function escapeLinkDestination(url: string): string {\n\tif (/[\\s()]/.test(url)) {\n\t\treturn `<${url.replace(/([<>])/g, '\\\\$1')}>`;\n\t}\n\treturn url;\n}\n\n/** Escapes a link/image title for the `\"...\"` form. */\nexport function escapeLinkTitle(title: string): string {\n\treturn title.replace(/([\"\\\\])/g, '\\\\$1');\n}\n\n/**\n * Picks a backtick fence long enough to wrap `content` as an inline code span.\n * CommonMark requires a fence longer than any backtick run inside the content.\n */\nexport function codeSpanFence(content: string): string {\n\tlet longest = 0;\n\tlet current = 0;\n\tfor (const ch of content) {\n\t\tif (ch === '`') {\n\t\t\tcurrent++;\n\t\t\tlongest = Math.max(longest, current);\n\t\t} else {\n\t\t\tcurrent = 0;\n\t\t}\n\t}\n\treturn '`'.repeat(longest + 1);\n}\n\n/** Wraps `content` in a correctly sized inline code span, padding when needed. */\nexport function wrapCodeSpan(content: string): string {\n\tconst fence: string = codeSpanFence(content);\n\t// Pad with a space when content starts/ends with a backtick or is all spaces,\n\t// per CommonMark's code-span stripping rule.\n\tconst needsPad: boolean =\n\t\tcontent.startsWith('`') ||\n\t\tcontent.endsWith('`') ||\n\t\t(content.length > 0 && content.trim().length === 0);\n\tconst inner: string = needsPad ? ` ${content} ` : content;\n\treturn `${fence}${inner}${fence}`;\n}\n","/**\n * Inline Markdown serialization: marks (emphasis nesting), code spans, links and\n * inline nodes. Marks with no portable Markdown form (underline, highlight, …)\n * fall back to raw inline HTML via the existing `MarkSerializer` (D3).\n *\n * Emphasis delimiters are emitted with a ProseMirror-markdown-style\n * reconciliation: shared \"mixable\" marks keep their open position across\n * adjacent text runs, so the serializer never produces ambiguous adjacent\n * delimiters (e.g. `**a*****b***`) that would mis-parse on round-trip.\n */\n\nimport type { InlineNode, Mark, TextNode } from '../../model/Document.js';\nimport { createTextNode, isInlineNode, markSetsEqual } from '../../model/Document.js';\nimport type { HTMLExportContext } from '../../model/NodeSpec.js';\nimport { serializeMarksToHTML } from '../MarkSerializer.js';\nimport { type SerContext, exportContext } from './MarkdownContext.js';\nimport {\n\tescapeInline,\n\tescapeLinkDestination,\n\tescapeLinkTitle,\n\twrapCodeSpan,\n} from './MarkdownEscape.js';\nimport { resolveMarkdownHTMLRegistry } from './MarkdownHTMLRegistry.js';\n\n/** Inline HTML export context (inline-style mode) for HTML-fallback marks. */\nconst INLINE_HTML_CTX: HTMLExportContext = {\n\tstyleAttr: (declarations: string) => (declarations ? ` style=\"${declarations}\"` : ''),\n};\n\n/** Whether a mark is serialized as a Markdown delimiter (vs. HTML fallback / code). */\nfunction isStackMark(mark: Mark, gfm: boolean): boolean {\n\tconst t: string = mark.type;\n\tif (t === 'link' || t === 'bold' || t === 'italic') return true;\n\tif (t === 'strikethrough' && gfm) return true;\n\treturn false;\n}\n\n/** Returns the open/close delimiter pair for a stack mark. */\nfunction delimiters(mark: Mark, ctx: SerContext): { open: string; close: string } {\n\tconst emphasis: string = ctx.opts.emphasis;\n\tswitch (mark.type) {\n\t\tcase 'bold':\n\t\t\treturn { open: emphasis.repeat(2), close: emphasis.repeat(2) };\n\t\tcase 'italic':\n\t\t\treturn { open: emphasis, close: emphasis };\n\t\tcase 'strikethrough':\n\t\t\treturn { open: '~~', close: '~~' };\n\t\tdefault: {\n\t\t\t// link\n\t\t\tconst href: string = String(mark.attrs?.href ?? '');\n\t\t\tconst title: string = String(mark.attrs?.title ?? '');\n\t\t\tconst dest: string = escapeLinkDestination(href);\n\t\t\tconst titlePart: string = title ? ` \"${escapeLinkTitle(title)}\"` : '';\n\t\t\treturn { open: '[', close: `](${dest}${titlePart})` };\n\t\t}\n\t}\n}\n\n/** Mixable marks may be reordered to keep shared marks open; link may not. */\nfunction isMixable(mark: Mark): boolean {\n\treturn mark.type !== 'link';\n}\n\n/** Structural equality for stack marks (type + attrs). */\nfunction marksEqual(a: Mark, b: Mark): boolean {\n\tif (a.type !== b.type) return false;\n\treturn JSON.stringify(a.attrs ?? {}) === JSON.stringify(b.attrs ?? {});\n}\n\n/** Collects the stack (delimiter) marks of a text or inline node, link outermost. */\nfunction stackMarksOf(node: TextNode | InlineNode, gfm: boolean): Mark[] {\n\tconst link: Mark[] = [];\n\tconst emphasis: Mark[] = [];\n\tfor (const mark of node.marks) {\n\t\tif (!isStackMark(mark, gfm)) continue;\n\t\tif (mark.type === 'link') link.push(mark);\n\t\telse emphasis.push(mark);\n\t}\n\treturn [...link, ...emphasis];\n}\n\n/**\n * Reorders a node's stack marks so that mixable marks already open (in `active`)\n * keep their position, minimizing close/reopen churn. Link stays outermost.\n */\nfunction reorderToActive(marks: readonly Mark[], active: readonly Mark[]): Mark[] {\n\tconst result: Mark[] = [];\n\tconst remaining: Mark[] = [...marks];\n\n\t// Non-mixable (link) first, preserving its position.\n\tfor (let i = remaining.length - 1; i >= 0; i--) {\n\t\tconst mark = remaining[i];\n\t\tif (mark && !isMixable(mark)) {\n\t\t\tresult.push(mark);\n\t\t\tremaining.splice(i, 1);\n\t\t}\n\t}\n\n\t// Then mixable marks already active, in active order.\n\tfor (const a of active) {\n\t\tif (!isMixable(a)) continue;\n\t\tconst idx: number = remaining.findIndex((m) => marksEqual(m, a));\n\t\tif (idx !== -1) {\n\t\t\tconst found = remaining[idx];\n\t\t\tif (found) result.push(found);\n\t\t\tremaining.splice(idx, 1);\n\t\t}\n\t}\n\n\t// Finally any new mixable marks.\n\tfor (const m of remaining) result.push(m);\n\treturn result;\n}\n\n/** Renders the literal content of a text node (code span, HTML-fallback, or escaped text). */\nfunction renderTextContent(node: TextNode, ctx: SerContext): string {\n\tif (node.text === '') return '';\n\n\tconst hasCode: boolean = node.marks.some((m) => m.type === 'code');\n\tif (hasCode) return wrapCodeSpan(node.text);\n\n\tconst gfm: boolean = ctx.opts.gfm;\n\tconst fallbackMarks: Mark[] = node.marks.filter((m) => !isStackMark(m, gfm) && m.type !== 'code');\n\n\tif (fallbackMarks.length > 0 && ctx.opts.htmlFallback) {\n\t\treturn serializeMarksToHTML(\n\t\t\tnode.text,\n\t\t\tfallbackMarks,\n\t\t\tresolveMarkdownHTMLRegistry(ctx.registry),\n\t\t\tctx.markOrder,\n\t\t\tINLINE_HTML_CTX,\n\t\t);\n\t}\n\t// htmlFallback off: keep text, drop styling.\n\treturn escapeInline(node.text, gfm);\n}\n\n/** Serializes a single inline node (hard break, inline image, math, plugin extensions). */\nfunction serializeInlineNode(node: InlineNode, ctx: SerContext): string {\n\tif (node.inlineType === 'hard_break') return '\\\\\\n';\n\tif (node.inlineType === 'image_inline') return serializeInlineImage(node, ctx);\n\n\tconst spec = ctx.registry?.getInlineNodeSpec(node.inlineType);\n\tconst md: string | null | undefined = spec?.toMarkdown?.(node, exportContext(ctx.opts));\n\tif (md != null) return md;\n\n\tif (ctx.opts.htmlFallback && spec?.toHTMLString) return spec.toHTMLString(node);\n\treturn '';\n}\n\n/** Serializes an inline image node to `![alt](src \"title\")` (engine-owned standard construct). */\nfunction serializeInlineImage(node: InlineNode, ctx: SerContext): string {\n\tconst src: string = String(node.attrs.src ?? '');\n\tconst alt: string = String(node.attrs.alt ?? '');\n\tconst title: string = String(node.attrs.title ?? '');\n\tconst titlePart: string = title ? ` \"${escapeLinkTitle(title)}\"` : '';\n\treturn `![${escapeInline(alt, ctx.opts.gfm)}](${escapeLinkDestination(src)}${titlePart})`;\n}\n\n/** Merges adjacent text nodes with identical mark sets; inline nodes are boundaries. */\nfunction mergeAdjacent(children: readonly (TextNode | InlineNode)[]): (TextNode | InlineNode)[] {\n\tconst result: (TextNode | InlineNode)[] = [];\n\tfor (const child of children) {\n\t\tconst prev = result[result.length - 1];\n\t\tif (\n\t\t\t!isInlineNode(child) &&\n\t\t\tprev &&\n\t\t\t!isInlineNode(prev) &&\n\t\t\tmarkSetsEqual(prev.marks, child.marks)\n\t\t) {\n\t\t\tresult[result.length - 1] = { type: 'text', text: prev.text + child.text, marks: prev.marks };\n\t\t} else {\n\t\t\tresult.push(child);\n\t\t}\n\t}\n\treturn result;\n}\n\n/** A flanking-sensitive emphasis mark (bold/italic/strike) whose delimiters must hug non-whitespace. */\nfunction isFlankingMark(mark: Mark, gfm: boolean): boolean {\n\treturn isStackMark(mark, gfm) && mark.type !== 'link';\n}\n\n/** Whether a sibling carries a mark equal to `mark` (false for inline nodes / no sibling). */\nfunction siblingHasMark(node: TextNode | InlineNode | undefined, mark: Mark): boolean {\n\tif (!node || isInlineNode(node)) return false;\n\treturn node.marks.some((m) => marksEqual(m, mark));\n}\n\n/** Length of the leading run of ASCII/Unicode whitespace in `text`. */\nfunction leadingWhitespace(text: string): number {\n\tlet i = 0;\n\twhile (i < text.length && /\\s/.test(text[i] as string)) i++;\n\treturn i;\n}\n\n/** Length of the trailing run of whitespace in `text`. */\nfunction trailingWhitespace(text: string): number {\n\tlet i: number = text.length;\n\twhile (i > 0 && /\\s/.test(text[i - 1] as string)) i--;\n\treturn text.length - i;\n}\n\n/** Returns `marks` with every mark in `strip` removed. */\nfunction withoutMarks(marks: readonly Mark[], strip: readonly Mark[]): Mark[] {\n\tif (strip.length === 0) return [...marks];\n\treturn marks.filter((m) => !strip.some((s) => marksEqual(s, m)));\n}\n\n/** Splits one text node's edge whitespace out of its flanking emphasis marks. */\nfunction expelNodeWhitespace(\n\tnode: TextNode,\n\tprev: TextNode | InlineNode | undefined,\n\tnext: TextNode | InlineNode | undefined,\n\tgfm: boolean,\n\tout: (TextNode | InlineNode)[],\n): void {\n\tconst flanking: Mark[] = node.marks.filter((m) => isFlankingMark(m, gfm));\n\tif (flanking.length === 0) {\n\t\tout.push(node);\n\t\treturn;\n\t}\n\n\tconst text: string = node.text;\n\tconst leadLen: number = leadingWhitespace(text);\n\n\t// All whitespace: a flanking mark survives only when interior on BOTH sides\n\t// (a same-mark neighbor before and after); otherwise it is expelled.\n\tif (leadLen === text.length) {\n\t\tconst strip: Mark[] = flanking.filter(\n\t\t\t(m) => !(siblingHasMark(prev, m) && siblingHasMark(next, m)),\n\t\t);\n\t\tout.push(createTextNode(text, withoutMarks(node.marks, strip)));\n\t\treturn;\n\t}\n\n\tconst trailLen: number = trailingWhitespace(text);\n\tconst lead: string = text.slice(0, leadLen);\n\tconst core: string = text.slice(leadLen, text.length - trailLen);\n\tconst trail: string = text.slice(text.length - trailLen);\n\n\tif (lead) {\n\t\tconst strip: Mark[] = flanking.filter((m) => !siblingHasMark(prev, m));\n\t\tout.push(createTextNode(lead, withoutMarks(node.marks, strip)));\n\t}\n\tout.push(createTextNode(core, node.marks));\n\tif (trail) {\n\t\tconst strip: Mark[] = flanking.filter((m) => !siblingHasMark(next, m));\n\t\tout.push(createTextNode(trail, withoutMarks(node.marks, strip)));\n\t}\n}\n\n/**\n * Expels whitespace from the edges of flanking-sensitive emphasis spans\n * (bold/italic/strikethrough). A `**` delimiter that hugs whitespace\n * (`**end **`) is not flanking, so CommonMark — and this engine's own parser —\n * read it literally, breaking the round-trip. Whitespace at a mark's span\n * boundary is moved outside the mark; whitespace interior to a span is kept.\n */\nfunction expelEdgeWhitespace(\n\tchildren: readonly (TextNode | InlineNode)[],\n\tgfm: boolean,\n): (TextNode | InlineNode)[] {\n\tconst out: (TextNode | InlineNode)[] = [];\n\tfor (let i = 0; i < children.length; i++) {\n\t\tconst child = children[i];\n\t\tif (!child) continue;\n\t\tif (isInlineNode(child)) {\n\t\t\tout.push(child);\n\t\t\tcontinue;\n\t\t}\n\t\texpelNodeWhitespace(child, children[i - 1], children[i + 1], gfm, out);\n\t}\n\treturn mergeAdjacent(out);\n}\n\n/** Serializes inline children of a leaf block to a Markdown string. */\nexport function serializeInlineContent(\n\tchildren: readonly (TextNode | InlineNode)[],\n\tctx: SerContext,\n): string {\n\tconst gfm: boolean = ctx.opts.gfm;\n\tconst merged: (TextNode | InlineNode)[] = expelEdgeWhitespace(mergeAdjacent(children), gfm);\n\tlet out = '';\n\tlet active: Mark[] = [];\n\n\tconst closeFrom = (keep: number): void => {\n\t\tfor (let i = active.length - 1; i >= keep; i--) {\n\t\t\tconst mark = active[i];\n\t\t\tif (mark) out += delimiters(mark, ctx).close;\n\t\t}\n\t\tactive = active.slice(0, keep);\n\t};\n\n\tfor (const child of merged) {\n\t\t// Inline nodes carry stack marks too (e.g. a `link` on an inline image), so\n\t\t// they flow through the same open/close reconciliation as text. The only\n\t\t// difference is the literal content emitted between the delimiters.\n\t\tconst target: Mark[] = reorderToActive(stackMarksOf(child, gfm), active);\n\n\t\tlet keep = 0;\n\t\twhile (\n\t\t\tkeep < active.length &&\n\t\t\tkeep < target.length &&\n\t\t\tmarksEqual(active[keep] as Mark, target[keep] as Mark)\n\t\t) {\n\t\t\tkeep++;\n\t\t}\n\t\tcloseFrom(keep);\n\t\tfor (let i = keep; i < target.length; i++) {\n\t\t\tconst mark = target[i];\n\t\t\tif (!mark) continue;\n\t\t\tout += delimiters(mark, ctx).open;\n\t\t\tactive.push(mark);\n\t\t}\n\n\t\tout += isInlineNode(child) ? serializeInlineNode(child, ctx) : renderTextContent(child, ctx);\n\t}\n\n\tcloseFrom(0);\n\treturn out;\n}\n","/**\n * Block-level Markdown serialization.\n *\n * Leaf/self-contained blocks (paragraph, heading, code_block, horizontal_rule,\n * image) have built-in emitters keyed by type name — the same centralized,\n * by-type-name mapping the importer uses, and the shape `prosemirror-markdown`\n * uses. Container/structural blocks (blockquote, list, table) are engine-owned\n * because their children need per-line prefixing/indentation that cannot be\n * composed from a wrapper (D12): each container serializes its own children and\n * applies its prefix to those known lines (never a post-hoc regex on assembled\n * output). Unknown/superset blocks defer to the per-spec `toMarkdown` hook, then\n * to a raw-HTML fallback via `toHTML` (D3, D4).\n */\n\nimport { isNodeOfType } from '../../model/AttrRegistry.js';\nimport type { BlockNode } from '../../model/Document.js';\nimport {\n\tgetBlockChildren,\n\tgetBlockText,\n\tgetInlineChildren,\n\tisLeafBlock,\n} from '../../model/Document.js';\nimport { normalizeHTMLId } from '../../model/HTMLUtils.js';\nimport { serializeDocumentToHTML } from '../DocumentSerializer.js';\nimport {\n\thasExplicitTableColumnWidth,\n\tnormalizeSerializedTableDimensionPx,\n} from '../TableDimensions.js';\nimport { serializeInlineContent } from './InlineSerializers.js';\nimport { type SerContext, exportContext } from './MarkdownContext.js';\nimport {\n\tescapeInline,\n\tescapeLineStart,\n\tescapeLinkDestination,\n\tescapeLinkTitle,\n} from './MarkdownEscape.js';\nimport { resolveMarkdownHTMLRegistry } from './MarkdownHTMLRegistry.js';\n\n/** Serializes a sequence of blocks, grouping consecutive list items, joined by blank lines. */\nexport function serializeBlocks(blocks: readonly BlockNode[], ctx: SerContext): string {\n\tconst parts: string[] = [];\n\tlet i = 0;\n\twhile (i < blocks.length) {\n\t\tconst block: BlockNode | undefined = blocks[i];\n\t\tif (!block) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (isNodeOfType(block, 'list_item')) {\n\t\t\tconst items: BlockNode[] = [];\n\t\t\twhile (i < blocks.length) {\n\t\t\t\tconst item: BlockNode | undefined = blocks[i];\n\t\t\t\tif (!item || !isNodeOfType(item, 'list_item')) break;\n\t\t\t\titems.push(item);\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tparts.push(\n\t\t\t\tctx.opts.htmlFallback && items.some(hasHTMLIdInTree)\n\t\t\t\t\t? serializeHTMLFallback(items, ctx)\n\t\t\t\t\t: serializeListGroup(items, ctx),\n\t\t\t);\n\t\t} else {\n\t\t\tparts.push(serializeBlock(block, ctx));\n\t\t\ti++;\n\t\t}\n\t}\n\treturn parts.filter((p) => p.length > 0).join('\\n\\n');\n}\n\n/** Serializes a single (non-list-item) block. */\nexport function serializeBlock(block: BlockNode, ctx: SerContext): string {\n\tif (ctx.opts.htmlFallback && hasHTMLIdInTree(block)) {\n\t\treturn serializeHTMLFallback([block], ctx);\n\t}\n\tconst type: string = block.type;\n\n\tif (type === 'paragraph') return serializeParagraph(block, ctx);\n\tif (type === 'heading') return serializeHeading(block, ctx);\n\tif (type === 'code_block') return serializeCodeBlock(block, ctx);\n\tif (type === 'horizontal_rule') return ctx.inListItem ? '***' : '---';\n\tif (type === 'image') return serializeImage(block, ctx);\n\tif (type === 'blockquote') return serializeBlockquote(block, ctx);\n\tif (type === 'table') return serializeTable(block, ctx);\n\tif (type === 'title') return serializeTitleLike(block, ctx, 1);\n\tif (type === 'subtitle') return serializeTitleLike(block, ctx, 2);\n\n\treturn serializeUnknownBlock(block, ctx);\n}\n\n/** Whether a block subtree carries HTML-only identity that Markdown cannot express. */\nfunction hasHTMLIdInTree(block: BlockNode): boolean {\n\tif (normalizeHTMLId(block.htmlId)) return true;\n\treturn getBlockChildren(block).some(hasHTMLIdInTree);\n}\n\n/** Emits a complete block run as raw HTML without leaking internal block IDs. */\nfunction serializeHTMLFallback(blocks: readonly BlockNode[], ctx: SerContext): string {\n\treturn serializeDocumentToHTML({ children: blocks }, resolveMarkdownHTMLRegistry(ctx.registry), {\n\t\tincludeBlockIds: false,\n\t});\n}\n\n/** Paragraph: inline content with leading block markers escaped per line. */\nfunction serializeParagraph(block: BlockNode, ctx: SerContext): string {\n\tconst content: string = serializeInlineContent(getInlineChildren(block), ctx);\n\tif (content.trim() === '') return '';\n\treturn content.split('\\n').map(escapeLineStart).join('\\n');\n}\n\n/** Heading: ATX (`## h`) by default, setext for levels 1-2 when requested. */\nfunction serializeHeading(block: BlockNode, ctx: SerContext): string {\n\tconst level: number = clampLevel((block.attrs?.level as number | undefined) ?? 1);\n\tconst content: string = serializeInlineContent(getInlineChildren(block), ctx).replace(/\\n/g, ' ');\n\n\tif (ctx.opts.headingStyle === 'setext' && level <= 2 && content !== '') {\n\t\tconst underline: string = level === 1 ? '=' : '-';\n\t\treturn `${content}\\n${underline.repeat(Math.max(3, content.length))}`;\n\t}\n\tconst hashes: string = '#'.repeat(level);\n\treturn content ? `${hashes} ${content}` : hashes;\n}\n\nfunction clampLevel(level: number): number {\n\tif (level < 1) return 1;\n\tif (level > 6) return 6;\n\treturn Math.floor(level);\n}\n\n/** Fenced code block; the fence is grown to exceed any fence run inside the code. */\nfunction serializeCodeBlock(block: BlockNode, ctx: SerContext): string {\n\tconst lang: string = String(block.attrs?.language ?? '');\n\tconst code: string = getBlockText(block);\n\tconst fenceChar: string = ctx.opts.codeFence[0] ?? '`';\n\tconst fence: string = fenceChar.repeat(Math.max(3, longestRun(code, fenceChar) + 1));\n\treturn `${fence}${lang}\\n${code}\\n${fence}`;\n}\n\n/** Length of the longest consecutive run of `ch` in `text`. */\nfunction longestRun(text: string, ch: string): number {\n\tlet longest = 0;\n\tlet current = 0;\n\tfor (const c of text) {\n\t\tif (c === ch) {\n\t\t\tcurrent++;\n\t\t\tlongest = Math.max(longest, current);\n\t\t} else {\n\t\t\tcurrent = 0;\n\t\t}\n\t}\n\treturn longest;\n}\n\n/** Standalone image on its own line; styling-bearing images use HTML fallback (D3). */\nfunction serializeImage(block: BlockNode, ctx: SerContext): string {\n\tconst src: string = String(block.attrs?.src ?? '');\n\tconst alt: string = String(block.attrs?.alt ?? '');\n\tconst title: string = String(block.attrs?.title ?? '');\n\tconst width = block.attrs?.width as number | undefined;\n\tconst height = block.attrs?.height as number | undefined;\n\tconst align = block.attrs?.align as string | undefined;\n\tconst hasStyling: boolean =\n\t\twidth !== undefined || height !== undefined || (align !== undefined && align !== 'center');\n\n\tif (hasStyling && ctx.opts.htmlFallback) {\n\t\tconst html: string | undefined = ctx.registry?.getNodeSpec('image')?.toHTML?.(block, '');\n\t\tif (html) return html;\n\t}\n\n\tconst titlePart: string = title ? ` \"${escapeLinkTitle(title)}\"` : '';\n\treturn `![${escapeInline(alt, ctx.opts.gfm)}](${escapeLinkDestination(src)}${titlePart})`;\n}\n\n/** Blockquote container: serialize children, then prefix every line with `> `. */\nfunction serializeBlockquote(block: BlockNode, ctx: SerContext): string {\n\tconst inner: string = serializeBlocks(getBlockChildren(block), ctx);\n\treturn inner\n\t\t.split('\\n')\n\t\t.map((line) => (line === '' ? '>' : `> ${line}`))\n\t\t.join('\\n');\n}\n\n/** title/subtitle: HTML fallback (`<h1 class>`) by default; degrade to `#`/`##` otherwise (D5). */\nfunction serializeTitleLike(block: BlockNode, ctx: SerContext, level: number): string {\n\tif (ctx.opts.htmlFallback) {\n\t\tconst content: string = serializeInlineContent(getInlineChildren(block), ctx);\n\t\tconst html: string | undefined = ctx.registry\n\t\t\t?.getNodeSpec(block.type)\n\t\t\t?.toHTML?.(block, content);\n\t\tif (html) return html;\n\t}\n\tconst content: string = serializeInlineContent(getInlineChildren(block), ctx).replace(/\\n/g, ' ');\n\tconst hashes: string = '#'.repeat(level);\n\treturn content ? `${hashes} ${content}` : hashes;\n}\n\n/** Unknown / superset block: per-spec `toMarkdown` hook, then raw-HTML fallback, then degrade. */\nfunction serializeUnknownBlock(block: BlockNode, ctx: SerContext): string {\n\tconst spec = ctx.registry?.getNodeSpec(block.type);\n\tconst content: string = isLeafBlock(block)\n\t\t? serializeInlineContent(getInlineChildren(block), ctx)\n\t\t: serializeBlocks(getBlockChildren(block), ctx);\n\n\tconst md: string | null | undefined = spec?.toMarkdown?.(block, content, exportContext(ctx.opts));\n\tif (md != null) return md;\n\n\tif (ctx.opts.htmlFallback && spec?.toHTML) return spec.toHTML(block, content);\n\n\t// htmlFallback off: keep textual content, drop the unrepresentable wrapper.\n\treturn content;\n}\n\n/**\n * Serializes a run of consecutive list items into Markdown list lines.\n *\n * Indent maps to CommonMark content columns (#194): each level's items are\n * padded to the content column of the last item one level up, so the parser\n * reads them back as nested (a `1. ` parent needs three columns, `- ` two).\n * Container items emit their block children indented to their own content\n * column, separated by the blank lines `serializeBlocks` produces.\n *\n * A nesting level is valid only when the level above it has a preceding item to\n * anchor the content column. An item whose stored indent skips a level (an\n * orphan, e.g. a first item the user tabbed in) is clamped to one deeper than\n * the previous item's effective level. This keeps every marker at a content\n * column an actual parent established, so the emitted pad never lands at four or\n * more columns — which the parser would read as indented code, merging the item\n * into its predecessor or dropping its marker (grammar disagreement). The stored\n * indent is preserved in the model; only its Markdown rendering normalizes.\n */\nfunction serializeListGroup(items: readonly BlockNode[], ctx: SerContext): string {\n\tconst lines: string[] = [];\n\tconst counters: number[] = [];\n\tconst contentColumns: number[] = [];\n\tlet previousIndent = -1;\n\n\tfor (const item of items) {\n\t\tconst listType: string = String(item.attrs?.listType ?? 'bullet');\n\t\tconst storedIndent: number = Math.max(0, (item.attrs?.indent as number | undefined) ?? 0);\n\t\t// Clamp to at most one level deeper than the previous item so a parent\n\t\t// content column always exists (no orphan levels, no >=4-column pad).\n\t\tconst indent: number = Math.min(storedIndent, previousIndent + 1);\n\t\tpreviousIndent = indent;\n\t\tconst padWidth: number = indent === 0 ? 0 : (contentColumns[indent - 1] ?? 0);\n\t\tconst pad: string = ' '.repeat(padWidth);\n\n\t\t// Reset deeper counters/columns when we step back out.\n\t\tcounters.length = indent + 1;\n\t\tcontentColumns.length = indent + 1;\n\n\t\tlet marker: string;\n\t\tif (listType === 'ordered') {\n\t\t\tcounters[indent] = (counters[indent] ?? 0) + 1;\n\t\t\tmarker = `${counters[indent]}.`;\n\t\t} else if (listType === 'checklist') {\n\t\t\tconst checked: boolean = item.attrs?.checked === true;\n\t\t\tmarker = `${ctx.opts.bullet} [${checked ? 'x' : ' '}]`;\n\t\t} else {\n\t\t\tmarker = ctx.opts.bullet;\n\t\t}\n\n\t\t// The task marker belongs to the first content line, not the geometry:\n\t\t// continuation lines of `- [x] foo` align to the bullet's content column.\n\t\tconst markerWidth: number =\n\t\t\tlistType === 'checklist' ? ctx.opts.bullet.length + 1 : marker.length + 1;\n\t\tcontentColumns[indent] = padWidth + markerWidth;\n\n\t\tif (isLeafBlock(item)) {\n\t\t\t// The item content is now block-tokenized on re-import, so a leaf whose\n\t\t\t// text begins with a block marker (`# `, `- `, `> `, `1. `) must be\n\t\t\t// line-start escaped or it reimports as a heading/nested-item child.\n\t\t\tconst content: string = escapeLineStart(\n\t\t\t\tserializeInlineContent(getInlineChildren(item), ctx).replace(/\\n/g, ' '),\n\t\t\t);\n\t\t\tlines.push(content ? `${pad}${marker} ${content}` : `${pad}${marker}`);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Container item (#194): serialize the block children, put the first line\n\t\t// on the marker line, and indent the rest to the item's content column.\n\t\tconst inner: string = serializeBlocks(getBlockChildren(item), { ...ctx, inListItem: true });\n\t\tif (inner === '') {\n\t\t\tlines.push(`${pad}${marker}`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst contentPad: string = ' '.repeat(contentColumns[indent] ?? padWidth + markerWidth);\n\t\tconst innerLines: string[] = inner.split('\\n');\n\t\tlines.push(`${pad}${marker} ${innerLines[0] ?? ''}`);\n\t\tfor (let li = 1; li < innerLines.length; li++) {\n\t\t\tconst innerLine: string = innerLines[li] ?? '';\n\t\t\tlines.push(innerLine === '' ? '' : `${contentPad}${innerLine}`);\n\t\t}\n\t}\n\n\treturn lines.join('\\n');\n}\n\n/** GFM table; tables with colspan/rowspan fall back to raw HTML (D3, no GFM equivalent). */\nfunction serializeTable(block: BlockNode, ctx: SerContext): string {\n\tconst rows: readonly BlockNode[] = getBlockChildren(block);\n\tif (rows.length === 0) return '';\n\n\t// CommonMark has no table syntax. Keep the semantic hierarchy through the\n\t// same raw-HTML seam used for spans and HTML IDs.\n\tif (!ctx.opts.gfm && ctx.opts.htmlFallback) {\n\t\treturn serializeHTMLFallback([block], ctx);\n\t}\n\n\t// GFM has no syntax for either logical column widths or row minimum\n\t// heights. Preserve them through the existing semantic HTML seam when it\n\t// is available. With `htmlFallback: false`, the documented behavior is a\n\t// plain pipe table whose dimensions reset to automatic on re-import.\n\tif (ctx.opts.htmlFallback && (hasSpannedCells(rows) || hasExplicitTableDimensions(block, rows))) {\n\t\treturn serializeHTMLFallback([block], ctx);\n\t}\n\n\tconst matrix: string[][] = rows.map((row) =>\n\t\tgetBlockChildren(row).map((cell) => serializeCell(cell, ctx)),\n\t);\n\tconst columns: number = matrix.reduce((max, row) => Math.max(max, row.length), 0);\n\tif (columns === 0) return '';\n\n\tconst renderRow = (cells: string[]): string => {\n\t\tconst padded: string[] = [...cells];\n\t\twhile (padded.length < columns) padded.push('');\n\t\treturn `| ${padded.join(' | ')} |`;\n\t};\n\n\tconst headerRow: BlockNode | undefined = rows[0];\n\tconst delimiters: string[] = Array.from({ length: columns }, (_v, col) =>\n\t\talignMarker(columnAlign(headerRow, col)),\n\t);\n\n\tconst out: string[] = [];\n\tout.push(renderRow(matrix[0] ?? []));\n\tout.push(`| ${delimiters.join(' | ')} |`);\n\tfor (let i = 1; i < matrix.length; i++) {\n\t\tout.push(renderRow(matrix[i] ?? []));\n\t}\n\treturn out.join('\\n');\n}\n\n/** Reads the column alignment from a header cell's paragraph `align` attribute. */\nfunction columnAlign(headerRow: BlockNode | undefined, col: number): string | undefined {\n\tif (!headerRow) return undefined;\n\tconst cell: BlockNode | undefined = getBlockChildren(headerRow)[col];\n\tif (!cell) return undefined;\n\tconst paragraph: BlockNode | undefined = getBlockChildren(cell)[0];\n\treturn paragraph?.attrs?.align as string | undefined;\n}\n\n/** Maps a logical alignment to its GFM delimiter marker. */\nfunction alignMarker(align: string | undefined): string {\n\tif (align === 'start') return ':---';\n\tif (align === 'center') return ':---:';\n\tif (align === 'end') return '---:';\n\treturn '---';\n}\n\n/** Whether any cell in the rows carries a colspan/rowspan > 1. */\nfunction hasSpannedCells(rows: readonly BlockNode[]): boolean {\n\tfor (const row of rows) {\n\t\tfor (const cell of getBlockChildren(row)) {\n\t\t\tconst colspan = cell.attrs?.colspan as number | undefined;\n\t\t\tconst rowspan = cell.attrs?.rowspan as number | undefined;\n\t\t\tif ((colspan ?? 1) > 1 || (rowspan ?? 1) > 1) return true;\n\t\t}\n\t}\n\treturn false;\n}\n\n/** Whether the table carries any safe dimension that GFM cannot represent. */\nfunction hasExplicitTableDimensions(table: BlockNode, rows: readonly BlockNode[]): boolean {\n\tif (hasExplicitTableColumnWidth(table.attrs?.columnWidthsPx)) return true;\n\treturn rows.some(\n\t\t(row: BlockNode): boolean =>\n\t\t\tnormalizeSerializedTableDimensionPx(row.attrs?.minHeightPx) !== undefined,\n\t);\n}\n\n/** Serializes a table cell to single-line inline Markdown, escaping pipes. */\nfunction serializeCell(cell: BlockNode, ctx: SerContext): string {\n\tconst blocks: readonly BlockNode[] = getBlockChildren(cell);\n\tconst inline: string = blocks\n\t\t.map((b) => serializeInlineContent(getInlineChildren(b), ctx))\n\t\t.join(' ')\n\t\t.replace(/\\n/g, ' ');\n\treturn inline.replace(/\\|/g, '\\\\|').trim();\n}\n","/**\n * MarkdownSerializer: converts an immutable Document into a Markdown string.\n *\n * Mirrors `DocumentSerializer.ts` (HTML) but is reached **only** via dynamic\n * `import()` from the async web-component method and the paste branch, so the\n * bundler genuinely code-splits the engine out of the core chunk (D13). Pure\n * functions — operate on Document/SchemaRegistry, no class state.\n */\n\nimport type { Document } from '../model/Document.js';\nimport type { SchemaRegistry } from '../model/SchemaRegistry.js';\nimport { buildMarkOrder } from './MarkSerializer.js';\nimport type { MarkdownSerializeOptions } from './MarkdownTypes.js';\nimport { serializeBlocks } from './markdown/BlockSerializers.js';\nimport { type SerContext, resolveSerializeOptions } from './markdown/MarkdownContext.js';\n\n/**\n * Serializes a document to a Markdown string.\n *\n * Standard CommonMark/GFM constructs are emitted by the engine's built-in\n * by-type mappings; unrepresentable nodes/marks emit raw HTML (valid Markdown)\n * when `htmlFallback` is on (default), or degrade gracefully when off (D3).\n */\nexport function serializeDocumentToMarkdown(\n\tdoc: Document,\n\tregistry?: SchemaRegistry,\n\toptions?: MarkdownSerializeOptions,\n): string {\n\tconst ctx: SerContext = {\n\t\tregistry,\n\t\topts: resolveSerializeOptions(options),\n\t\tmarkOrder: registry ? buildMarkOrder(registry) : undefined,\n\t};\n\tconst body: string = serializeBlocks(doc.children, ctx);\n\treturn finalizeDocument(body);\n}\n\n/**\n * Closes the assembled document with a single trailing newline, dropping any\n * leading/trailing blank lines. It intentionally does NOT touch the interior:\n * each block serializer is responsible for emitting clean lines, and\n * `serializeBlocks` already joins blocks with exactly one blank line. Trimming\n * only the document boundaries is provably code-safe, since a document never\n * begins or ends inside a code body (blocks open and close on their own\n * delimiters), so significant blank lines and trailing spaces inside a\n * `code_block` survive verbatim at any nesting depth.\n */\nfunction finalizeDocument(markdown: string): string {\n\tconst trimmed: string = markdown.trim();\n\treturn trimmed.length > 0 ? `${trimmed}\\n` : '';\n}\n"],"mappings":"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"}