@plebeiantech/lat.md 0.12.3-fork.13 → 0.12.3-fork.14

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 (274) hide show
  1. package/README.md +24 -0
  2. package/dist/src/cli/check-context.d.ts +56 -0
  3. package/dist/src/cli/check-context.js +215 -0
  4. package/dist/src/cli/check-coverage.js +9 -5
  5. package/dist/src/cli/check-frontmatter.js +1 -1
  6. package/dist/src/cli/check-mode.js +1 -1
  7. package/dist/src/cli/check-status.js +1 -1
  8. package/dist/src/cli/check.d.ts +19 -12
  9. package/dist/src/cli/check.js +259 -206
  10. package/dist/src/cli/context.js +1 -1
  11. package/dist/src/cli/expand.d.ts +1 -2
  12. package/dist/src/cli/expand.js +52 -5
  13. package/dist/src/cli/external.d.ts +11 -0
  14. package/dist/src/cli/external.js +185 -0
  15. package/dist/src/cli/fork-instructions.d.ts +1 -0
  16. package/dist/src/cli/fork-instructions.js +3 -2
  17. package/dist/src/cli/hook.d.ts +26 -0
  18. package/dist/src/cli/hook.js +112 -40
  19. package/dist/src/cli/index.js +55 -3
  20. package/dist/src/cli/init.d.ts +1 -0
  21. package/dist/src/cli/init.js +40 -2
  22. package/dist/src/cli/locate.js +4 -3
  23. package/dist/src/cli/refs.d.ts +2 -1
  24. package/dist/src/cli/refs.js +88 -43
  25. package/dist/src/cli/reindex.js +2 -1
  26. package/dist/src/cli/search.d.ts +12 -3
  27. package/dist/src/cli/search.js +45 -49
  28. package/dist/src/cli/section.d.ts +3 -1
  29. package/dist/src/cli/section.js +114 -38
  30. package/dist/src/code-refs.d.ts +17 -5
  31. package/dist/src/code-refs.js +246 -65
  32. package/dist/src/context.d.ts +3 -0
  33. package/dist/src/document-formats.d.ts +7 -0
  34. package/dist/src/document-formats.js +39 -0
  35. package/dist/src/extensions/alert-marker.d.ts +25 -0
  36. package/dist/src/extensions/alert-marker.js +55 -0
  37. package/dist/src/external-documents.d.ts +56 -0
  38. package/dist/src/external-documents.js +404 -0
  39. package/dist/src/external-sources.d.ts +136 -0
  40. package/dist/src/external-sources.js +1098 -0
  41. package/dist/src/fork/antigravity-hook.d.ts +47 -0
  42. package/dist/src/fork/antigravity-hook.js +424 -0
  43. package/dist/src/fork/antigravity-init.d.ts +17 -0
  44. package/dist/src/fork/antigravity-init.js +124 -0
  45. package/dist/src/fork/frontmatter-fields.d.ts +36 -0
  46. package/dist/src/fork/frontmatter-fields.js +23 -0
  47. package/dist/src/format.d.ts +5 -2
  48. package/dist/src/format.js +8 -3
  49. package/dist/src/graph-export.js +1 -1
  50. package/dist/src/lattice-model.d.ts +77 -0
  51. package/dist/src/lattice-model.js +464 -0
  52. package/dist/src/lattice.d.ts +9 -104
  53. package/dist/src/lattice.js +69 -516
  54. package/dist/src/markdown-analysis-cache.d.ts +20 -0
  55. package/dist/src/markdown-analysis-cache.js +139 -0
  56. package/dist/src/markdown-analysis-worker.d.ts +16 -0
  57. package/dist/src/markdown-analysis-worker.js +33 -0
  58. package/dist/src/markdown-analysis.d.ts +50 -0
  59. package/dist/src/markdown-analysis.js +139 -0
  60. package/dist/src/markdown-analyzer-loader.d.ts +4 -0
  61. package/dist/src/markdown-analyzer-loader.js +13 -0
  62. package/dist/src/markdown-validation.d.ts +25 -0
  63. package/dist/src/markdown-validation.js +104 -0
  64. package/dist/src/mcp/server.js +27 -11
  65. package/dist/src/parser-cache.d.ts +17 -0
  66. package/dist/src/parser-cache.js +65 -0
  67. package/dist/src/parser-import.d.ts +8 -0
  68. package/dist/src/parser-import.js +1 -0
  69. package/dist/src/parser.js +80 -5
  70. package/dist/src/path.d.ts +2 -0
  71. package/dist/src/path.js +4 -0
  72. package/dist/src/profiler.d.ts +16 -0
  73. package/dist/src/profiler.js +81 -0
  74. package/dist/src/project-analysis.d.ts +59 -0
  75. package/dist/src/project-analysis.js +233 -0
  76. package/dist/src/project-discovery.d.ts +6 -0
  77. package/dist/src/project-discovery.js +30 -0
  78. package/dist/src/repository-path.d.ts +11 -0
  79. package/dist/src/repository-path.js +52 -0
  80. package/dist/src/search/db.d.ts +1 -1
  81. package/dist/src/search/db.js +2 -2
  82. package/dist/src/search/embedder.d.ts +2 -1
  83. package/dist/src/search/embedder.js +6 -5
  84. package/dist/src/search/index.d.ts +2 -1
  85. package/dist/src/search/index.js +10 -8
  86. package/dist/src/search/query.d.ts +20 -0
  87. package/dist/src/search/query.js +67 -0
  88. package/dist/src/search/search.d.ts +3 -1
  89. package/dist/src/search/search.js +5 -2
  90. package/dist/src/source-formats.d.ts +7 -0
  91. package/dist/src/source-formats.js +26 -0
  92. package/dist/src/source-parser.d.ts +44 -4
  93. package/dist/src/source-parser.js +494 -57
  94. package/dist/src/view/client/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  95. package/dist/src/view/client/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  96. package/dist/src/view/client/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  97. package/dist/src/view/client/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  98. package/dist/src/view/client/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  99. package/dist/src/view/client/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  100. package/dist/src/view/client/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  101. package/dist/src/view/client/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  102. package/dist/src/view/client/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  103. package/dist/src/view/client/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  104. package/dist/src/view/client/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  105. package/dist/src/view/client/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  106. package/dist/src/view/client/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  107. package/dist/src/view/client/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  108. package/dist/src/view/client/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  109. package/dist/src/view/client/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  110. package/dist/src/view/client/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  111. package/dist/src/view/client/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  112. package/dist/src/view/client/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  113. package/dist/src/view/client/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  114. package/dist/src/view/client/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  115. package/dist/src/view/client/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  116. package/dist/src/view/client/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  117. package/dist/src/view/client/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  118. package/dist/src/view/client/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  119. package/dist/src/view/client/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  120. package/dist/src/view/client/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  121. package/dist/src/view/client/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  122. package/dist/src/view/client/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  123. package/dist/src/view/client/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  124. package/dist/src/view/client/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  125. package/dist/src/view/client/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  126. package/dist/src/view/client/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  127. package/dist/src/view/client/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  128. package/dist/src/view/client/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  129. package/dist/src/view/client/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  130. package/dist/src/view/client/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  131. package/dist/src/view/client/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  132. package/dist/src/view/client/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  133. package/dist/src/view/client/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  134. package/dist/src/view/client/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  135. package/dist/src/view/client/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  136. package/dist/src/view/client/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  137. package/dist/src/view/client/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  138. package/dist/src/view/client/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  139. package/dist/src/view/client/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  140. package/dist/src/view/client/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  141. package/dist/src/view/client/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  142. package/dist/src/view/client/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  143. package/dist/src/view/client/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  144. package/dist/src/view/client/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  145. package/dist/src/view/client/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  146. package/dist/src/view/client/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  147. package/dist/src/view/client/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  148. package/dist/src/view/client/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  149. package/dist/src/view/client/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  150. package/dist/src/view/client/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  151. package/dist/src/view/client/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  152. package/dist/src/view/client/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  153. package/dist/src/view/client/assets/MarkdownEditor-B7quqPb8.js +28 -0
  154. package/dist/src/view/client/assets/OrbitControls-DwcpQNja.js +1 -0
  155. package/dist/src/view/client/assets/STLLoader-CLWTKt5i.js +1 -0
  156. package/dist/src/view/client/assets/abnfDiagram-VCTEODGH-V7-T6qsl.js +1 -0
  157. package/dist/src/view/client/assets/arc-BnwR8Bu7.js +1 -0
  158. package/dist/src/view/client/assets/architectureDiagram-5GKGNRK7-u97vDna9.js +36 -0
  159. package/dist/src/view/client/assets/blockDiagram-I7D4REHJ-DETl8e_H.js +129 -0
  160. package/dist/src/view/client/assets/c4Diagram-7LVT6UL2-DJRAT1Ve.js +38 -0
  161. package/dist/src/view/client/assets/channel-BwQbnWCN.js +1 -0
  162. package/dist/src/view/client/assets/chunk-2Q5K7J3B-C0TmOC1Q.js +1 -0
  163. package/dist/src/view/client/assets/chunk-5VM5RSS4-dfBOrYE6.js +15 -0
  164. package/dist/src/view/client/assets/chunk-F27PBJKO-DAnks99K.js +1 -0
  165. package/dist/src/view/client/assets/chunk-IMKFNOWR-CPjB07if.js +231 -0
  166. package/dist/src/view/client/assets/chunk-JWPE2WC7-VvU_gZI6.js +1 -0
  167. package/dist/src/view/client/assets/chunk-POPQ4Y6H-DDUbVF55.js +1 -0
  168. package/dist/src/view/client/assets/chunk-SVP7TREG-BHROkr6D.js +88 -0
  169. package/dist/src/view/client/assets/chunk-TICWLB2K-95PzGIOg.js +206 -0
  170. package/dist/src/view/client/assets/chunk-XXDRQBXY-MdmuLhIs.js +1 -0
  171. package/dist/src/view/client/assets/classDiagram-ZZMXUADV-HvQKkIS-.js +1 -0
  172. package/dist/src/view/client/assets/classDiagram-v2-VYDZK3BY-HvQKkIS-.js +1 -0
  173. package/dist/src/view/client/assets/cose-bilkent-JH36ORCC-CauUf_rN.js +1 -0
  174. package/dist/src/view/client/assets/cynefin-OW5HDTMX-CeA8IKWo.js +166 -0
  175. package/dist/src/view/client/assets/cynefinDiagram-5FMLGOSQ-L1rtcT8l.js +62 -0
  176. package/dist/src/view/client/assets/cytoscape.esm-DzSz-X2X.js +321 -0
  177. package/dist/src/view/client/assets/dagre-GXQ25YYZ-DLQwTa3H.js +4 -0
  178. package/dist/src/view/client/assets/defaultLocale-DX6XiGOO.js +1 -0
  179. package/dist/src/view/client/assets/diagram-S7CK7UJ4-kbKdIyXG.js +30 -0
  180. package/dist/src/view/client/assets/diagram-UQ7AKVKN-kmzp92RC.js +41 -0
  181. package/dist/src/view/client/assets/diagram-VSXAHHWV-EXJTU8qq.js +3 -0
  182. package/dist/src/view/client/assets/diagram-VX7I27RA-DAiIyMCG.js +24 -0
  183. package/dist/src/view/client/assets/diagram-Z3DM3KII-G9wz50ZV.js +24 -0
  184. package/dist/src/view/client/assets/ebnfDiagram-PWID7BFC-D2tVRCNA.js +1 -0
  185. package/dist/src/view/client/assets/erDiagram-RLTQ6QDP-C925J5A3.js +99 -0
  186. package/dist/src/view/client/assets/flowDiagram-HODETNUW-DzoCa-Nq.js +168 -0
  187. package/dist/src/view/client/assets/ganttDiagram-EL5Y4UJY-D2ebbg4p.js +292 -0
  188. package/dist/src/view/client/assets/gitGraphDiagram-WWUBYQGX-B4QratYy.js +106 -0
  189. package/dist/src/view/client/assets/index-BnENo9bV.js +1 -0
  190. package/dist/src/view/client/assets/index-D0ajr_Ja.css +1 -0
  191. package/dist/src/view/client/assets/index-KZcnpXJH.js +321 -0
  192. package/dist/src/view/client/assets/infoDiagram-27XIBGKW-DL4mtHkt.js +2 -0
  193. package/dist/src/view/client/assets/init-Gi6I4Gst.js +1 -0
  194. package/dist/src/view/client/assets/ishikawaDiagram-5VMMS53U-CW4mto2d.js +70 -0
  195. package/dist/src/view/client/assets/journeyDiagram-3NMN7TZE-8R4eacFW.js +139 -0
  196. package/dist/src/view/client/assets/kanban-definition-UXKFOSKX-Cy9ioXEJ.js +89 -0
  197. package/dist/src/view/client/assets/katex-HP8lGamR.js +257 -0
  198. package/dist/src/view/client/assets/layout-C0MFuhth.js +1 -0
  199. package/dist/src/view/client/assets/linear-Dv3N4dQR.js +1 -0
  200. package/dist/src/view/client/assets/logo-small-RR_KBOAT.svg +149 -0
  201. package/dist/src/view/client/assets/maplibre-gl-DnqZgfUS.js +800 -0
  202. package/dist/src/view/client/assets/mermaid.core-bds9A7e2.js +310 -0
  203. package/dist/src/view/client/assets/mindmap-definition-YA3MSWOX-DjmGW355.js +96 -0
  204. package/dist/src/view/client/assets/ordinal-Cboi1Yqb.js +1 -0
  205. package/dist/src/view/client/assets/pegDiagram-XKGWAZYB-BWsZp0ab.js +1 -0
  206. package/dist/src/view/client/assets/pieDiagram-E7YTZNPT-CCH2gGR-.js +39 -0
  207. package/dist/src/view/client/assets/quadrantDiagram-AXDQQJYC-CjocPJFz.js +7 -0
  208. package/dist/src/view/client/assets/railroadDiagram-O6MQD6OU-BjLeb2KF.js +1 -0
  209. package/dist/src/view/client/assets/requirementDiagram-BXWQKSXE-Ct6AoXRr.js +84 -0
  210. package/dist/src/view/client/assets/sankeyDiagram-P5KCCOFB-CIpgGN_w.js +40 -0
  211. package/dist/src/view/client/assets/sequenceDiagram-WJ2MYXX4-DrmLFj6w.js +162 -0
  212. package/dist/src/view/client/assets/sizeCapture-INFHLROL-BdFMe2Lr.js +1 -0
  213. package/dist/src/view/client/assets/stateDiagram-D77RDMKH-Zd9F1goW.js +1 -0
  214. package/dist/src/view/client/assets/stateDiagram-v2-MP3YSRHH-ByIKCftl.js +1 -0
  215. package/dist/src/view/client/assets/swimlanes-42K2YHIH-a7VFwi00.js +1 -0
  216. package/dist/src/view/client/assets/swimlanesDiagram-VR7AAH4N-CzxaUHB-.js +8 -0
  217. package/dist/src/view/client/assets/three.module-PDSP0dbZ.js +4108 -0
  218. package/dist/src/view/client/assets/timeline-definition-24CTP7MA-BExPu6X5.js +120 -0
  219. package/dist/src/view/client/assets/vennDiagram-4TSXK5OY-PC1MU3si.js +34 -0
  220. package/dist/src/view/client/assets/wardleyDiagram-VM6X3IG4-DNWqU3fa.js +78 -0
  221. package/dist/src/view/client/assets/xychartDiagram-S5SC5T6Z-E1uA28_D.js +7 -0
  222. package/dist/src/view/client/index.html +2 -2
  223. package/dist/src/view/client-shell.d.ts +2 -0
  224. package/dist/src/view/client-shell.js +5 -0
  225. package/dist/src/view/diagnostics.d.ts +3 -2
  226. package/dist/src/view/diagnostics.js +49 -58
  227. package/dist/src/view/document-edit.d.ts +8 -0
  228. package/dist/src/view/document-edit.js +25 -0
  229. package/dist/src/view/document-route.d.ts +12 -0
  230. package/dist/src/view/document-route.js +93 -0
  231. package/dist/src/view/document-tree.d.ts +18 -0
  232. package/dist/src/view/document-tree.js +139 -0
  233. package/dist/src/view/external-document-tree.d.ts +3 -0
  234. package/dist/src/view/external-document-tree.js +674 -0
  235. package/dist/src/view/git-diff.js +187 -0
  236. package/dist/src/view/git.js +1 -1
  237. package/dist/src/view/graph.d.ts +3 -2
  238. package/dist/src/view/graph.js +94 -7
  239. package/dist/src/view/highlight.d.ts +10 -2
  240. package/dist/src/view/highlight.js +4540 -1360
  241. package/dist/src/view/markdown.d.ts +3 -2
  242. package/dist/src/view/markdown.js +214 -53
  243. package/dist/src/view/protocol.d.ts +59 -6
  244. package/dist/src/view/references.d.ts +10 -25
  245. package/dist/src/view/references.js +117 -107
  246. package/dist/src/view/repository.d.ts +13 -3
  247. package/dist/src/view/repository.js +234 -15
  248. package/dist/src/view/search.d.ts +1 -1
  249. package/dist/src/view/search.js +3 -7
  250. package/dist/src/view/server.d.ts +11 -2
  251. package/dist/src/view/server.js +212 -70
  252. package/dist/src/view/source-target.js +5 -8
  253. package/dist/src/view/static-build.d.ts +1 -0
  254. package/dist/src/view/static-build.js +245 -42
  255. package/dist/src/view/static-protocol.d.ts +19 -2
  256. package/dist/src/view/store.d.ts +16 -3
  257. package/dist/src/view/store.js +228 -36
  258. package/dist/src/view/table-of-contents.d.ts +2 -2
  259. package/dist/src/view/table-of-contents.js +2 -22
  260. package/dist/src/walk.d.ts +5 -3
  261. package/dist/src/walk.js +102 -8
  262. package/package.json +46 -8
  263. package/plugins/lat-md/README.md +61 -0
  264. package/plugins/lat-md/hooks.json +38 -0
  265. package/plugins/lat-md/plugin.json +9 -0
  266. package/plugins/lat-md/rules/AGENTS.md +118 -0
  267. package/plugins/lat-md/skills/lat-md/SKILL.md +178 -0
  268. package/plugins/lat-md/skills/lat-md-conventions/SKILL.md +182 -0
  269. package/templates/AGENTS.md +15 -3
  270. package/templates/cursor-rules.md +12 -3
  271. package/templates/skill/SKILL.md +22 -1
  272. package/dist/src/view/client/assets/index-C3iaZyYT.css +0 -1
  273. package/dist/src/view/client/assets/index-KWi67IMz.js +0 -334
  274. package/dist/src/view/client/assets/logo-CNF8zs47.svg +0 -182
@@ -0,0 +1,674 @@
1
+ import { asciidocCompatibleContent } from '../external-documents.js';
2
+ import { decorateExternalSiteLinks, toViewDocumentTree, } from './document-tree.js';
3
+ import { highlightCode } from './highlight.js';
4
+ function text(value) {
5
+ return { type: 'text', value };
6
+ }
7
+ function element(tagName, children = [], properties = {}) {
8
+ return { type: 'element', tagName, properties, children };
9
+ }
10
+ function safeUrl(value) {
11
+ if (typeof value !== 'string')
12
+ return null;
13
+ const url = value.trim();
14
+ if (!url || /^\s*(?:data|javascript|vbscript):/i.test(url))
15
+ return null;
16
+ return url;
17
+ }
18
+ function codeBlock(source, language) {
19
+ const normalizedLanguage = language?.trim().toLowerCase() || null;
20
+ const highlighted = normalizedLanguage
21
+ ? highlightCode(normalizedLanguage, source)
22
+ : null;
23
+ const children = highlighted
24
+ ? toViewDocumentTree(highlighted).children
25
+ : [text(source ? `${source}\n` : '')];
26
+ const className = [
27
+ ...(normalizedLanguage ? [`language-${normalizedLanguage}`] : []),
28
+ ...(highlighted ? ['hljs'] : []),
29
+ ];
30
+ return element('pre', [
31
+ element('code', highlighted ? [...children, text('\n')] : children, className.length > 0 ? { className } : {}),
32
+ ]);
33
+ }
34
+ function rstData(node) {
35
+ const value = node.toObject().data;
36
+ return value && typeof value === 'object' ? value : {};
37
+ }
38
+ function rstInlineChildren(nodes, render) {
39
+ return nodes.flatMap(render);
40
+ }
41
+ function normalizeRstName(value) {
42
+ return value
43
+ .normalize('NFD')
44
+ .replaceAll(/[\u0300-\u036f]/g, '')
45
+ .toLowerCase()
46
+ .replaceAll(/[^a-z0-9\-_.:+<>]/g, '-')
47
+ .replaceAll(/-{2,}/g, '-')
48
+ .replace(/^[-]*/, '')
49
+ .replace(/[-]*$/, '');
50
+ }
51
+ async function restructuredTextTree(content) {
52
+ const { RstToHtmlCompiler } = await import('rst-compiler');
53
+ const parsed = new RstToHtmlCompiler().parse(content, {
54
+ disableErrors: true,
55
+ disableWarnings: true,
56
+ });
57
+ const properties = (node) => {
58
+ const id = parsed.htmlAttrResolver.getNodeHtmlId(node);
59
+ const className = parsed.htmlAttrResolver.getNodeHtmlClasses(node);
60
+ return {
61
+ ...(id ? { id } : {}),
62
+ ...(className.length > 0 ? { className } : {}),
63
+ };
64
+ };
65
+ const linkableNodes = new Map(parsed.simpleNameResolver.nodesLinkableFromOutside);
66
+ for (const node of parsed.root.findAllChildren('HyperlinkTarget')) {
67
+ const label = node.label;
68
+ if (label)
69
+ linkableNodes.set(normalizeRstName(label), node);
70
+ }
71
+ const linkedNodeUrl = (node, visited = new Set()) => {
72
+ if (visited.has(node))
73
+ return null;
74
+ visited.add(node);
75
+ if (node.nodeType === 'HyperlinkTarget') {
76
+ const target = node.target ?? '';
77
+ const alias = node.isAlias;
78
+ if (alias) {
79
+ const linked = linkableNodes.get(normalizeRstName(target.replace(/_$/, '')));
80
+ return linked ? linkedNodeUrl(linked, visited) : null;
81
+ }
82
+ if (target)
83
+ return safeUrl(target);
84
+ }
85
+ const id = parsed.htmlAttrResolver.getNodeHtmlId(node);
86
+ return id ? `#${id}` : null;
87
+ };
88
+ const hyperlinkUrl = (node) => {
89
+ const link = node;
90
+ if (link.isAnonymous && !link.isEmbeded) {
91
+ const target = parsed.simpleNameResolver.anonymousHyperlinkRefToTarget.get(node);
92
+ return target ? linkedNodeUrl(target) : null;
93
+ }
94
+ const rawTarget = link.target ?? '';
95
+ const targetName = link.isAlias ? rawTarget.replace(/_$/, '') : rawTarget;
96
+ const linked = linkableNodes.get(normalizeRstName(targetName));
97
+ return linked ? linkedNodeUrl(linked) : safeUrl(rawTarget);
98
+ };
99
+ const render = (node) => {
100
+ const data = rstData(node);
101
+ const children = () => rstInlineChildren(node.children, render);
102
+ switch (node.nodeType) {
103
+ case 'Document':
104
+ return children();
105
+ case 'Section': {
106
+ const level = Number(data.level ?? 1);
107
+ return [
108
+ element(`h${Math.max(1, Math.min(6, level))}`, children(), properties(node)),
109
+ ];
110
+ }
111
+ case 'Paragraph':
112
+ return [element('p', children(), properties(node))];
113
+ case 'Text':
114
+ return [text(node.textContent)];
115
+ case 'Emphasis':
116
+ return [element('em', [text(node.textContent)], properties(node))];
117
+ case 'StrongEmphasis':
118
+ return [element('strong', [text(node.textContent)], properties(node))];
119
+ case 'InlineLiteral':
120
+ case 'InterpretedText':
121
+ return [element('code', [text(node.textContent)], properties(node))];
122
+ case 'HyperlinkRef': {
123
+ const href = hyperlinkUrl(node);
124
+ if (!href)
125
+ return [text(node.textContent)];
126
+ return [
127
+ element('a', [text(node.textContent)], {
128
+ ...properties(node),
129
+ href,
130
+ }),
131
+ ];
132
+ }
133
+ case 'InlineInternalTarget':
134
+ return [element('span', [text(node.textContent)], properties(node))];
135
+ case 'LiteralBlock':
136
+ case 'DoctestBlock':
137
+ return [codeBlock(node.rawTextContent || node.textContent)];
138
+ case 'Blockquote':
139
+ return [element('blockquote', children(), properties(node))];
140
+ case 'BlockquoteAttribution':
141
+ return [element('footer', children(), properties(node))];
142
+ case 'Transition':
143
+ return [element('hr', [], properties(node))];
144
+ case 'LineBlock':
145
+ return [element('p', children(), properties(node))];
146
+ case 'LineBlockLine':
147
+ return [...children(), element('br')];
148
+ case 'BulletList':
149
+ return [element('ul', children(), properties(node))];
150
+ case 'EnumeratedList':
151
+ return [element('ol', children(), properties(node))];
152
+ case 'BulletListItem':
153
+ return [element('li', children(), properties(node))];
154
+ case 'DefinitionList':
155
+ case 'FieldList':
156
+ case 'OptionList':
157
+ return [element('dl', children(), properties(node))];
158
+ case 'DefinitionListItem': {
159
+ const item = node;
160
+ const term = item.term.flatMap(render);
161
+ const classifiers = item.classifiers.map((classifier) => classifier.flatMap(render));
162
+ const definition = item.definition.flatMap(render);
163
+ return [
164
+ element('dt', [
165
+ ...term,
166
+ ...classifiers.flatMap((classifier) => [
167
+ text(' : '),
168
+ ...classifier,
169
+ ]),
170
+ ]),
171
+ element('dd', definition),
172
+ ];
173
+ }
174
+ case 'FieldListItem': {
175
+ const item = node;
176
+ return [
177
+ element('dt', item.name.flatMap(render)),
178
+ element('dd', item.body.flatMap(render)),
179
+ ];
180
+ }
181
+ case 'OptionListItem': {
182
+ const options = node.options;
183
+ return [
184
+ element('dt', [
185
+ text(options
186
+ .map((option) => `${option.name}${option.delimiter ?? ''}${option.rawArgName ?? ''}`)
187
+ .join(', ')),
188
+ ]),
189
+ element('dd', children()),
190
+ ];
191
+ }
192
+ case 'Table': {
193
+ const headRows = node
194
+ .headRows;
195
+ const bodyRows = node
196
+ .bodyRows;
197
+ return [
198
+ element('table', [
199
+ ...(headRows?.length
200
+ ? [element('thead', headRows.flatMap(render))]
201
+ : []),
202
+ element('tbody', (bodyRows ?? node.children).flatMap(render)),
203
+ ]),
204
+ ];
205
+ }
206
+ case 'TableRow':
207
+ return [element('tr', children())];
208
+ case 'TableCell': {
209
+ const cell = node;
210
+ const parent = node.parent;
211
+ const tagName = parent?.nodeType === 'TableRow' &&
212
+ parent.isHeadRow
213
+ ? 'th'
214
+ : 'td';
215
+ return [
216
+ element(tagName, children(), {
217
+ ...(cell.colSpan && cell.colSpan > 1
218
+ ? { colSpan: cell.colSpan }
219
+ : {}),
220
+ ...(cell.rowSpan && cell.rowSpan > 1
221
+ ? { rowSpan: cell.rowSpan }
222
+ : {}),
223
+ }),
224
+ ];
225
+ }
226
+ case 'Directive': {
227
+ const directive = String(data.directive ?? '').toLowerCase();
228
+ const rawBody = typeof data.rawBodyText === 'string' ? data.rawBodyText : '';
229
+ if (['code', 'code-block', 'sourcecode'].includes(directive)) {
230
+ const language = node.initContentText
231
+ ?.trim()
232
+ .split(/\s+/, 1)[0];
233
+ return [codeBlock(rawBody || node.textContent, language)];
234
+ }
235
+ if (directive === 'image' || directive === 'figure') {
236
+ const src = safeUrl(node.initContentText);
237
+ return src
238
+ ? [element('img', [], { src, alt: String(data.alt ?? '') })]
239
+ : [];
240
+ }
241
+ if ([
242
+ 'attention',
243
+ 'caution',
244
+ 'danger',
245
+ 'error',
246
+ 'hint',
247
+ 'important',
248
+ 'note',
249
+ 'tip',
250
+ 'warning',
251
+ ].includes(directive)) {
252
+ return [
253
+ element('div', [
254
+ element('p', [text(directive[0].toUpperCase() + directive.slice(1))], {
255
+ className: ['markdown-alert-title'],
256
+ }),
257
+ ...children(),
258
+ ], {
259
+ className: [
260
+ 'markdown-alert',
261
+ `markdown-alert-${directive === 'hint' ? 'tip' : directive}`,
262
+ ],
263
+ }),
264
+ ];
265
+ }
266
+ if (directive === 'raw') {
267
+ return rawBody ? [codeBlock(rawBody)] : [];
268
+ }
269
+ return children();
270
+ }
271
+ case 'FootnoteRef':
272
+ case 'CitationRef':
273
+ return [element('sup', [text(node.textContent)], properties(node))];
274
+ case 'FootnoteDef':
275
+ case 'CitationDef':
276
+ return [element('div', children(), properties(node))];
277
+ case 'Comment':
278
+ case 'HyperlinkTarget':
279
+ case 'SubstitutionDef':
280
+ return [];
281
+ default:
282
+ return node.children.length > 0 ? children() : [text(node.textContent)];
283
+ }
284
+ };
285
+ return { version: 1, type: 'root', children: render(parsed.root) };
286
+ }
287
+ const ASCIIDOC_NORMAL_SUBSTITUTIONS = [
288
+ 'specialcharacters',
289
+ 'quotes',
290
+ 'attributes',
291
+ 'replacements',
292
+ 'macros',
293
+ 'post_replacements',
294
+ ];
295
+ function decodeAsciiEntities(value) {
296
+ return value.replace(/&(?:#(\d+)|#x([\da-f]+)|(amp|apos|gt|lt|quot));/gi, (match, decimal, hex, named) => {
297
+ if (decimal)
298
+ return String.fromCodePoint(Number(decimal));
299
+ if (hex)
300
+ return String.fromCodePoint(Number.parseInt(hex, 16));
301
+ return ({
302
+ amp: '&',
303
+ apos: "'",
304
+ gt: '>',
305
+ lt: '<',
306
+ quot: '"',
307
+ }[named.toLowerCase()] ?? match);
308
+ });
309
+ }
310
+ /** Convert Asciidoctor's native inline nodes into document-tree tokens. */
311
+ class AsciiInlineProjector {
312
+ tokens = [];
313
+ token(nodes) {
314
+ const index = this.tokens.push(Array.isArray(nodes) ? nodes : [nodes]) - 1;
315
+ return `\u{e000}${index}\u{e001}`;
316
+ }
317
+ properties(node) {
318
+ const id = node.getId();
319
+ const className = node.getRoles();
320
+ return {
321
+ ...(id ? { id } : {}),
322
+ ...(className.length > 0 ? { className } : {}),
323
+ };
324
+ }
325
+ decode(value) {
326
+ const nodes = [];
327
+ let cursor = 0;
328
+ for (const match of value.matchAll(/\u{e000}(\d+)\u{e001}/gu)) {
329
+ const index = match.index ?? 0;
330
+ if (index > cursor) {
331
+ nodes.push(text(decodeAsciiEntities(value.slice(cursor, index))));
332
+ }
333
+ nodes.push(...(this.tokens[Number(match[1])] ?? []));
334
+ cursor = index + match[0].length;
335
+ }
336
+ if (cursor < value.length) {
337
+ nodes.push(text(decodeAsciiEntities(value.slice(cursor))));
338
+ }
339
+ return nodes;
340
+ }
341
+ async project(owner, value) {
342
+ const substitutions = owner.subs && owner.subs.length > 0
343
+ ? owner.subs
344
+ : ASCIIDOC_NORMAL_SUBSTITUTIONS;
345
+ const converted = await owner.applySubs(value, substitutions);
346
+ return this.decode(Array.isArray(converted) ? converted.join('\n') : converted);
347
+ }
348
+ convert(node) {
349
+ const content = this.decode(node.getText() ?? '');
350
+ const properties = this.properties(node);
351
+ switch (node.getContext()) {
352
+ case 'quoted': {
353
+ const tagName = {
354
+ emphasis: 'em',
355
+ mark: 'mark',
356
+ monospaced: 'code',
357
+ strong: 'strong',
358
+ subscript: 'sub',
359
+ superscript: 'sup',
360
+ unquoted: 'span',
361
+ }[node.getType() ?? ''] ?? 'span';
362
+ if (node.getType() === 'double') {
363
+ return this.token([text('“'), ...content, text('”')]);
364
+ }
365
+ if (node.getType() === 'single') {
366
+ return this.token([text('‘'), ...content, text('’')]);
367
+ }
368
+ return this.token(element(tagName, content, properties));
369
+ }
370
+ case 'anchor': {
371
+ if (node.getType() === 'ref' || node.getType() === 'bibref') {
372
+ return this.token(element('span', content, {
373
+ ...properties,
374
+ ...(node.getId() ? { id: node.getId() } : {}),
375
+ }));
376
+ }
377
+ const href = safeUrl(node.getTarget());
378
+ return this.token(href
379
+ ? element('a', content.length > 0 ? content : [text(href)], {
380
+ ...properties,
381
+ href,
382
+ })
383
+ : content);
384
+ }
385
+ case 'image': {
386
+ const src = safeUrl(node.getTarget());
387
+ return this.token(src
388
+ ? element('img', [], {
389
+ ...properties,
390
+ src,
391
+ alt: node.getAlt(),
392
+ })
393
+ : content);
394
+ }
395
+ case 'break':
396
+ return this.token([...content, element('br')]);
397
+ case 'button':
398
+ return this.token(element('b', content, { className: ['button'] }));
399
+ case 'callout':
400
+ return this.token(element('b', [text(`(${node.getText() ?? ''})`)], {
401
+ className: ['conum'],
402
+ }));
403
+ case 'footnote':
404
+ return this.token(element('sup', [text(String(node.getAttribute('index') ?? node.getText() ?? ''))], { className: ['footnote'] }));
405
+ case 'indexterm':
406
+ return node.getType() === 'visible' ? this.token(content) : '';
407
+ case 'kbd': {
408
+ const keys = node.getAttribute('keys');
409
+ const values = Array.isArray(keys) ? keys.map(String) : [];
410
+ return this.token(values.flatMap((key, index) => [
411
+ ...(index > 0 ? [text('+')] : []),
412
+ element('kbd', [text(key)]),
413
+ ]));
414
+ }
415
+ case 'menu': {
416
+ const values = [
417
+ node.getAttribute('menu'),
418
+ ...(Array.isArray(node.getAttribute('submenus'))
419
+ ? node.getAttribute('submenus')
420
+ : []),
421
+ node.getAttribute('menuitem'),
422
+ ].filter((value) => value != null && value !== '');
423
+ return this.token(element('span', [text(values.map(String).join(' › '))], {
424
+ className: ['menuseq'],
425
+ }));
426
+ }
427
+ default:
428
+ return this.token(content);
429
+ }
430
+ }
431
+ }
432
+ function asciiSource(node) {
433
+ return node.getSource?.() ?? '';
434
+ }
435
+ function asciiNodeProperties(node) {
436
+ const id = node.getId();
437
+ const className = node.getRoles();
438
+ return {
439
+ ...(id ? { id } : {}),
440
+ ...(className.length > 0 ? { className } : {}),
441
+ };
442
+ }
443
+ function asciiRawText(value) {
444
+ return value && typeof value === 'object' && '_text' in value
445
+ ? String(value._text ?? '')
446
+ : '';
447
+ }
448
+ async function asciiTable(node, projector) {
449
+ const rows = node.rows?.toObject() ?? { head: [], body: [], foot: [] };
450
+ const renderRows = async (source, header) => {
451
+ const result = [];
452
+ for (const row of source) {
453
+ const cells = [];
454
+ for (const rawCell of row) {
455
+ const cell = rawCell;
456
+ cells.push(element(header ? 'th' : 'td', await projector.project(cell, asciiRawText(cell)), {
457
+ ...(cell.colspan && cell.colspan > 1
458
+ ? { colSpan: cell.colspan }
459
+ : {}),
460
+ ...(cell.rowspan && cell.rowspan > 1
461
+ ? { rowSpan: cell.rowspan }
462
+ : {}),
463
+ }));
464
+ }
465
+ result.push(element('tr', cells));
466
+ }
467
+ return result;
468
+ };
469
+ return element('table', [
470
+ ...(rows.head.length
471
+ ? [element('thead', await renderRows(rows.head, true))]
472
+ : []),
473
+ element('tbody', await renderRows(rows.body, false)),
474
+ ...(rows.foot.length
475
+ ? [element('tfoot', await renderRows(rows.foot, false))]
476
+ : []),
477
+ ]);
478
+ }
479
+ async function asciidocTree(content) {
480
+ const { load } = await import('@asciidoctor/core');
481
+ const document = await load(asciidocCompatibleContent(content), {
482
+ safe: 'secure',
483
+ sourcemap: true,
484
+ attributes: { showtitle: true },
485
+ });
486
+ const lines = content.split('\n');
487
+ const documentTitle = document.getAttribute('doctitle');
488
+ const rawDocumentTitle = typeof documentTitle === 'string' ? documentTitle : null;
489
+ const projector = new AsciiInlineProjector();
490
+ const originalConverter = document.getConverter();
491
+ document.setConverter(projector);
492
+ const sectionOffset = rawDocumentTitle ? 1 : 0;
493
+ const sectionTitle = (node) => {
494
+ const line = node.getLineNumber();
495
+ const raw = line ? lines[line - 1] : undefined;
496
+ const match = raw ? /^={1,6}\s+(.+)$/.exec(raw) : null;
497
+ return match?.[1] ?? String(node.getTitle() ?? '');
498
+ };
499
+ let render;
500
+ const renderMany = async (sourceNodes) => {
501
+ const result = [];
502
+ for (const sourceNode of sourceNodes)
503
+ result.push(...(await render(sourceNode)));
504
+ return result;
505
+ };
506
+ const renderListItem = async (raw) => {
507
+ const item = raw;
508
+ return element('li', [
509
+ ...(await projector.project(item, asciiRawText(item))),
510
+ ...(await renderMany(item.getBlocks())),
511
+ ]);
512
+ };
513
+ render = async (sourceNode) => {
514
+ const node = sourceNode;
515
+ const context = node.getContext();
516
+ const childNodes = () => renderMany(node.getBlocks());
517
+ switch (context) {
518
+ case 'preamble':
519
+ case 'document':
520
+ return await childNodes();
521
+ case 'section': {
522
+ const level = Math.max(1, Math.min(6, (node.getLevel() ?? node.level ?? 1) + sectionOffset));
523
+ return [
524
+ element(`h${level}`, await projector.project(node, sectionTitle(node)), asciiNodeProperties(node)),
525
+ ...(await childNodes()),
526
+ ];
527
+ }
528
+ case 'paragraph':
529
+ return [
530
+ element('p', await projector.project(node, asciiSource(node)), asciiNodeProperties(node)),
531
+ ];
532
+ case 'ulist':
533
+ case 'olist':
534
+ case 'colist': {
535
+ const tagName = context === 'ulist' ? 'ul' : 'ol';
536
+ return [
537
+ element(tagName, await Promise.all((node.getItems?.() ?? []).map(renderListItem)), asciiNodeProperties(node)),
538
+ ];
539
+ }
540
+ case 'dlist': {
541
+ const entries = node.getItems?.() ?? [];
542
+ const descriptionNodes = [];
543
+ for (const entry of entries) {
544
+ if (!Array.isArray(entry))
545
+ continue;
546
+ const terms = Array.isArray(entry[0]) ? entry[0] : [];
547
+ const description = entry[1];
548
+ for (const term of terms) {
549
+ descriptionNodes.push(element('dt', await projector.project(term, asciiRawText(term))));
550
+ }
551
+ descriptionNodes.push(element('dd', [
552
+ ...(description
553
+ ? await projector.project(description, asciiRawText(description))
554
+ : []),
555
+ ...(description ? await renderMany(description.getBlocks()) : []),
556
+ ]));
557
+ }
558
+ return [element('dl', descriptionNodes, asciiNodeProperties(node))];
559
+ }
560
+ case 'listing':
561
+ case 'literal': {
562
+ const language = context === 'listing' && node.getStyle() === 'source'
563
+ ? String(node.getAttribute('language') ?? '')
564
+ : null;
565
+ return [codeBlock(asciiSource(node), language)];
566
+ }
567
+ case 'stem':
568
+ return [codeBlock(asciiSource(node), 'text')];
569
+ case 'quote':
570
+ case 'verse': {
571
+ const contents = await childNodes();
572
+ return [
573
+ element('blockquote', contents.length > 0
574
+ ? contents
575
+ : [
576
+ element('p', await projector.project(node, asciiSource(node))),
577
+ ], asciiNodeProperties(node)),
578
+ ];
579
+ }
580
+ case 'admonition': {
581
+ const kind = String(node.getStyle() ?? 'note').toLowerCase();
582
+ const body = await childNodes();
583
+ return [
584
+ element('div', [
585
+ element('p', [text(kind[0].toUpperCase() + kind.slice(1))], {
586
+ className: ['markdown-alert-title'],
587
+ }),
588
+ ...(body.length > 0
589
+ ? body
590
+ : [
591
+ element('p', await projector.project(node, asciiSource(node))),
592
+ ]),
593
+ ], {
594
+ ...asciiNodeProperties(node),
595
+ className: [
596
+ 'markdown-alert',
597
+ `markdown-alert-${kind === 'hint' ? 'tip' : kind}`,
598
+ ],
599
+ }),
600
+ ];
601
+ }
602
+ case 'image': {
603
+ const src = safeUrl(node.getAttribute('target'));
604
+ return src
605
+ ? [
606
+ element('img', [], {
607
+ ...asciiNodeProperties(node),
608
+ src,
609
+ alt: String(node.getAttribute('alt') ?? ''),
610
+ }),
611
+ ]
612
+ : [];
613
+ }
614
+ case 'table':
615
+ return [await asciiTable(node, projector)];
616
+ case 'thematic_break':
617
+ case 'page_break':
618
+ return [element('hr', [], asciiNodeProperties(node))];
619
+ case 'floating_title':
620
+ case 'discrete_heading': {
621
+ const level = Math.max(1, Math.min(6, (node.getLevel() ?? node.level ?? 1) + 1));
622
+ return [
623
+ element(`h${level}`, await projector.project(node, sectionTitle(node)), asciiNodeProperties(node)),
624
+ ];
625
+ }
626
+ case 'pass':
627
+ return asciiSource(node) ? [codeBlock(asciiSource(node))] : [];
628
+ case 'open':
629
+ case 'example':
630
+ case 'sidebar': {
631
+ const contents = await childNodes();
632
+ return [
633
+ element('div', contents.length > 0
634
+ ? contents
635
+ : [
636
+ element('p', await projector.project(node, asciiSource(node))),
637
+ ], {
638
+ ...asciiNodeProperties(node),
639
+ className: [`asciidoc-${context}`, ...node.getRoles()],
640
+ }),
641
+ ];
642
+ }
643
+ default: {
644
+ const contents = await childNodes();
645
+ if (contents.length > 0)
646
+ return contents;
647
+ const source = asciiSource(node);
648
+ return source
649
+ ? [
650
+ element('p', await projector.project(node, source)),
651
+ ]
652
+ : [];
653
+ }
654
+ }
655
+ };
656
+ try {
657
+ const children = [];
658
+ if (rawDocumentTitle) {
659
+ children.push(element('h1', await projector.project(document, rawDocumentTitle), document.getId() ? { id: document.getId() } : {}));
660
+ }
661
+ children.push(...(await renderMany(document.getBlocks())));
662
+ return { version: 1, type: 'root', children };
663
+ }
664
+ finally {
665
+ document.setConverter(originalConverter);
666
+ }
667
+ }
668
+ /** Reflect a native non-Markdown parser AST into the browser document tree. */
669
+ export async function renderExternalDocumentTree(format, content) {
670
+ const tree = format === 'restructuredtext'
671
+ ? await restructuredTextTree(content)
672
+ : await asciidocTree(content);
673
+ return decorateExternalSiteLinks(tree);
674
+ }