collabmd 0.1.54 → 0.1.55

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 (447) hide show
  1. package/bin/collabmd.js +19 -38
  2. package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-cMeDxAEL.js +1 -0
  3. package/dist/client/assets/{abnfDiagram-VCTEODGH-DxNxad6-.js → abnfDiagram-VCTEODGH-D2UdmYvj.js} +1 -1
  4. package/dist/client/assets/{abnfDiagram-O67JEVCF-Dwt6a0Ds.js → abnfDiagram-YUKMZFIV-DbmU4Q-X.js} +1 -1
  5. package/dist/client/assets/api-client-utils-C5ESDKMG.js +1 -0
  6. package/dist/client/assets/architecture-7GRP2DOG-BBwRXFv3.js +1 -1
  7. package/dist/client/assets/architecture-WOLXFQ4H-C0NxYiG7.js +1 -0
  8. package/dist/client/assets/{architectureDiagram-NJMV4G6O-D5CGiX3G.js → architectureDiagram-47P4ROYG-C7OjXK9S.js} +3 -3
  9. package/dist/client/assets/{architectureDiagram-5GKGNRK7-C1uvg5id.js → architectureDiagram-5GKGNRK7-CSiUzzeN.js} +1 -1
  10. package/dist/client/assets/base-CaIEJUF9.css +1 -0
  11. package/dist/client/assets/{blockDiagram-BEXU5L5S-BgTM0var.js → blockDiagram-E7TT5TSB-DMG-YlZw.js} +3 -3
  12. package/dist/client/assets/{blockDiagram-I7D4REHJ-B2YonsoG.js → blockDiagram-I7D4REHJ-sXfAgK2w.js} +1 -1
  13. package/dist/client/assets/{browser-BKLM0ThC-BCLQGPD6-K2seJgRL.js → browser-BKLM0ThC-BCLQGPD6-CcMAHZXi.js} +1 -1
  14. package/dist/client/assets/{c4Diagram-7LVT6UL2-r4IwomZm.js → c4Diagram-7LVT6UL2-C88V_K-8.js} +1 -1
  15. package/dist/client/assets/{c4Diagram-YGBWAQC7-_xZPrNkB.js → c4Diagram-CRA5TL53-D3F9ElJv.js} +2 -2
  16. package/dist/client/assets/canvasEditor-BJkwGzO1.css +1 -0
  17. package/dist/client/assets/canvasEditor-sBK7KfrD.js +1 -0
  18. package/dist/client/assets/{chunk-6AZGARVD--pTGpDnx.js → chunk-24IY7LWP-flnn6SWX.js} +1 -1
  19. package/dist/client/assets/chunk-2BW5OAIV-CNFO1U_e.js +10 -0
  20. package/dist/client/assets/{chunk-2E4U76K2-CIQUuV9n.js → chunk-2E4U76K2-DEnS5IbF.js} +1 -1
  21. package/dist/client/assets/{chunk-5V3GS4D5-B5uC2oxu.js → chunk-3M4EKCLJ-D-sZGCtO.js} +1 -1
  22. package/dist/client/assets/chunk-3YJQHVM4-Ctp__8EK.js +2 -0
  23. package/dist/client/assets/{chunk-7PRAP22T-9uTvtc_-.js → chunk-4EA7E6EY-bU4wRJot.js} +1 -1
  24. package/dist/client/assets/{chunk-4HAMMTFA-q0ldNVvr.js → chunk-4HAMMTFA-CQy6Skzw.js} +1 -1
  25. package/dist/client/assets/{chunk-6K3QC6MW-JnuvEGV4.js → chunk-4S7OKTRW-BpUW13a3.js} +1 -1
  26. package/dist/client/assets/{chunk-ICYGCRZG-odvlDZyA.js → chunk-53FOQ5SW-5lPdGYP4.js} +1 -1
  27. package/dist/client/assets/{chunk-75Z2AOVW-DitkSoSG.js → chunk-75Z2AOVW-BRdhvVTZ.js} +1 -1
  28. package/dist/client/assets/{chunk-GWA4HPMP-CGmv2yIq.js → chunk-7TKQ45FW-rA2u-WUl.js} +1 -1
  29. package/dist/client/assets/{chunk-GTNCS2PH-ChgkzEIi.js → chunk-AW2ZBBNX-DL0KGAdi.js} +3 -3
  30. package/dist/client/assets/{chunk-747NJXEK-BjqqAsS9.js → chunk-BP2KR52E-DAQ1pzDV.js} +1 -1
  31. package/dist/client/assets/{chunk-CLGD4ZFX-BfYJtJm1.js → chunk-CLGD4ZFX-DJiSE0gD.js} +1 -1
  32. package/dist/client/assets/{chunk-5DYCD2WN-BKWCKnK-.js → chunk-DBDB3WZW-CXleNlok.js} +1 -1
  33. package/dist/client/assets/{chunk-DU6HZSFF-CWlP1Dk_.js → chunk-DU6HZSFF-C-18UZkS.js} +1 -1
  34. package/dist/client/assets/{chunk-MBY4JIJT-DTJ4UcAm.js → chunk-E2ZNV5FY-D_07zfWd.js} +3 -3
  35. package/dist/client/assets/chunk-EU5HNXII-CETVNUXF.js +213 -0
  36. package/dist/client/assets/{chunk-F27PBJKO-DPcsPcEs.js → chunk-F27PBJKO-_beIJos4.js} +1 -1
  37. package/dist/client/assets/{chunk-2ZTRR5NV-DcPRfelM.js → chunk-F6S3BTY2-DVWKCAHp.js} +1 -1
  38. package/dist/client/assets/{chunk-ISPTBLVO-BMsDq9Ha.js → chunk-FLFP27SU-CydzbSsY.js} +2 -2
  39. package/dist/client/assets/chunk-FVRAUYC3-C7b9SJ81.js +1 -0
  40. package/dist/client/assets/{chunk-GMAD6QVW-Bgk8qnty.js → chunk-GMAD6QVW-DnZH7DxV.js} +1 -1
  41. package/dist/client/assets/{chunk-GVQU2GXP-CQ8cl-Uu.js → chunk-GVQU2GXP-B0Vm415C.js} +1 -1
  42. package/dist/client/assets/chunk-H5A3YXKD-ChP7mNJq.js +41 -0
  43. package/dist/client/assets/{chunk-742MDFTN-D1nh6vNv.js → chunk-HJ2JQQFS-DQX7RePR.js} +1 -1
  44. package/dist/client/assets/{chunk-NETBCI7D-CmUwDWUZ.js → chunk-HTAEGDNF-C0PA_N-c.js} +1 -1
  45. package/dist/client/assets/{chunk-IMKFNOWR-CBqxfpcP.js → chunk-IMKFNOWR-DoO8IHzF.js} +1 -1
  46. package/dist/client/assets/{chunk-IH6LHLGP-BNevEHZK.js → chunk-KPI5JJXK-B2ld5-w4.js} +1 -1
  47. package/dist/client/assets/{chunk-WEXAMYUT-DDlVNp8J.js → chunk-KQW6MTUR-OQ4MyMr_.js} +1 -1
  48. package/dist/client/assets/{chunk-L3NEJ4N5-BflzkdTI.js → chunk-L3NEJ4N5-CvHossEU.js} +1 -1
  49. package/dist/client/assets/chunk-NGNAAXSQ-DqoPQk1a.js +136 -0
  50. package/dist/client/assets/{chunk-UA2S7LBM-DicYDjDM.js → chunk-NTY3LDVX-CVWLK_fh.js} +1 -1
  51. package/dist/client/assets/{chunk-UY3FDG6J-QT-rkt0y.js → chunk-OD3NTWWA-Dz9nCUGX.js} +1 -1
  52. package/dist/client/assets/{chunk-OSK3NFVY-DqeKV_pg.js → chunk-OSK3NFVY-C3JOcBao.js} +1 -1
  53. package/dist/client/assets/{chunk-P2QGCYS3-BA--DhpW.js → chunk-P2QGCYS3-Bfo8qS8r.js} +1 -1
  54. package/dist/client/assets/{chunk-POPQ4Y6H-V_NEc45n.js → chunk-POPQ4Y6H-sv6rCftH.js} +1 -1
  55. package/dist/client/assets/{chunk-PWAF6VOD-D_kLse-N.js → chunk-PWAF6VOD-B-AT-L2H.js} +1 -1
  56. package/dist/client/assets/{chunk-3Z5EZCMW-BAnA6eQ7.js → chunk-QNH66VMT-Cb9xxTwQ.js} +1 -1
  57. package/dist/client/assets/{chunk-SHT3W25Y-YM3S-A_M.js → chunk-SHT3W25Y-C1lu518T.js} +1 -1
  58. package/dist/client/assets/{chunk-GNY47TPC-CTrH5O5R.js → chunk-SVEVUXB4-BnM-LXop.js} +1 -1
  59. package/dist/client/assets/{chunk-SVP7TREG-DdNhDOmW.js → chunk-SVP7TREG-CKqt0syj.js} +1 -1
  60. package/dist/client/assets/{chunk-TICWLB2K-BGGgCr4x.js → chunk-TICWLB2K-D2ZnWAfF.js} +1 -1
  61. package/dist/client/assets/{chunk-TLUHSLCS-DCZhIDYA.js → chunk-TLUHSLCS-BMIhqv1X.js} +1 -1
  62. package/dist/client/assets/{chunk-6EIED4P4-DBVWq7Tz.js → chunk-TPMEZKFX-DIPHIqGb.js} +1 -1
  63. package/dist/client/assets/{chunk-6TQVIW2G-BSj0l_pu.js → chunk-VPELOWWC-DXayM28-.js} +1 -1
  64. package/dist/client/assets/chunk-VPRB5NB3-BqaJfj_v.js +127 -0
  65. package/dist/client/assets/{chunk-I5DQTOEV-aBZooNp1.js → chunk-VTWWFHGB-SZnJiyWY.js} +1 -1
  66. package/dist/client/assets/{chunk-KI3K4JFJ-FTtDwx3-.js → chunk-VZTHESGH-eHyXmK8W.js} +1 -1
  67. package/dist/client/assets/{chunk-7INBJB4K-CDmiHbaX.js → chunk-XC4XBNZT-D9oehSn8.js} +20 -20
  68. package/dist/client/assets/{chunk-XHIXRSVI-DN_fEwws.js → chunk-YK26KJH5-DVy3MGMd.js} +1 -1
  69. package/dist/client/assets/{chunk-6AEJRKK7-DTVZj5bY.js → chunk-Z6ETV63D-DOcrnz-P.js} +1 -1
  70. package/dist/client/assets/{chunk-OUJLGHUK-75UXlPjl.js → chunk-ZO67DCNQ-BAOMIkLF.js} +1 -1
  71. package/dist/client/assets/classDiagram-ZZMXUADV-BmETdFmC.js +1 -0
  72. package/dist/client/assets/{classDiagram-v2-NBCMYWYE-3TQORq33.js → classDiagram-v2-K4WV4PDN-eaadfJDB.js} +3 -3
  73. package/dist/client/assets/classDiagram-v2-VYDZK3BY-BmETdFmC.js +1 -0
  74. package/dist/client/assets/{comment-markdown-renderer-Bxi_JRSR.js → comment-markdown-renderer-CpBKaj7H.js} +1 -1
  75. package/dist/client/assets/comment-thread-store-DUQsWtnu.js +1 -0
  76. package/dist/client/assets/comment-threads-DnfkLVJA.js +4 -0
  77. package/dist/client/assets/comment-ui-shared-D_pgPUti.js +7 -0
  78. package/dist/client/assets/cynefin-EF2NZ3EQ-DVkJeZ8i.js +1 -0
  79. package/dist/client/assets/cynefin-OW5HDTMX-CF3N9j1_.js +1 -1
  80. package/dist/client/assets/{cynefinDiagram-VND7K2PF-DwfMZ3vk.js → cynefinDiagram-3GCD6N5R-DjpAsBHC.js} +1 -1
  81. package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-DTnLZaO7.js → cynefinDiagram-5FMLGOSQ-D2rFQG67.js} +1 -1
  82. package/dist/client/assets/dagre-C-rnJpZF.js +1 -0
  83. package/dist/client/assets/{dagre-GXQ25YYZ-Vtyx08Qh.js → dagre-GXQ25YYZ-Cku9eia9.js} +2 -2
  84. package/dist/client/assets/{dagre-6A5THRUB-DewyAGK6.js → dagre-W4DXFKR2-DOMOIsPd.js} +2 -2
  85. package/dist/client/assets/deferred-collab-C9aa9cvT.css +1 -0
  86. package/dist/client/assets/deferred-git-BPQ-UgrN.css +1 -0
  87. package/dist/client/assets/deferred-preview-B-RebLry.css +1 -0
  88. package/dist/client/assets/{diagram-22UHCM2B-DbZirFfl.js → diagram-2UJZ2QOL-D8WvnEyx.js} +6 -6
  89. package/dist/client/assets/{diagram-3UASUU5V-DmhdYv6_.js → diagram-OVF4WLC6-D8_escYE.js} +2 -2
  90. package/dist/client/assets/{diagram-CDSNMT55-D_qyS11R.js → diagram-PFPMY2P6-B1izZfrN.js} +3 -3
  91. package/dist/client/assets/{diagram-S7CK7UJ4-CGTzfo2f.js → diagram-S7CK7UJ4-BzicH2t-.js} +1 -1
  92. package/dist/client/assets/{diagram-MLGK6HIB-DIBG6Ivu.js → diagram-UMYRVEAY-Djf7WDjZ.js} +1 -1
  93. package/dist/client/assets/{diagram-UQ7AKVKN-CWZS8QtB.js → diagram-UQ7AKVKN-DqX4zTtr.js} +1 -1
  94. package/dist/client/assets/{diagram-VSXAHHWV-DaO1nOZF.js → diagram-VSXAHHWV-DnVbfI4Y.js} +1 -1
  95. package/dist/client/assets/{diagram-VX7I27RA-B54P6Cyf.js → diagram-VX7I27RA-D-Dj0TQC.js} +1 -1
  96. package/dist/client/assets/{diagram-MPIPVDR6-D9XsALDV.js → diagram-YEKJPTXX-B40bP3Yr.js} +2 -2
  97. package/dist/client/assets/{diagram-Z3DM3KII-Cl2EXiXp.js → diagram-Z3DM3KII-_iT7Uz5p.js} +1 -1
  98. package/dist/client/assets/diagram-ZIFT7M5P-BUUK0oNw.js +3 -0
  99. package/dist/client/assets/{direct-engine-DVLMOJWp-C-YL5NFb.js → direct-engine-DVLMOJWp-DWtWIifK.js} +1 -1
  100. package/dist/client/assets/dist-26Ce-5t4.js +1 -0
  101. package/dist/client/assets/dist-8MLNn-I6.js +1 -0
  102. package/dist/client/assets/dist-Amm5Pr1C.js +1 -0
  103. package/dist/client/assets/dist-BXXPaoUV.js +1 -0
  104. package/dist/client/assets/{dist-CoXN2D3R.js → dist-Bkb-_VdB.js} +1 -1
  105. package/dist/client/assets/dist-Bl4yuUS9.js +1 -0
  106. package/dist/client/assets/{dist-lw5TGjI6.js → dist-C2CGvCPd.js} +1 -1
  107. package/dist/client/assets/dist-C2niyEh0.js +1 -0
  108. package/dist/client/assets/{dist-DOHWxIty.js → dist-CFCSUmJk.js} +1 -1
  109. package/dist/client/assets/dist-CHUI56fT.js +6 -0
  110. package/dist/client/assets/dist-CJh3Qrid.js +13 -0
  111. package/dist/client/assets/{dist-Ch6Sr9KF.js → dist-CKxETpSC.js} +3 -3
  112. package/dist/client/assets/dist-CSHJthAI.js +2 -0
  113. package/dist/client/assets/dist-CbKnZGN4.js +1 -0
  114. package/dist/client/assets/{dist-KrdpB_GB.js → dist-Cik4RJXj.js} +1 -1
  115. package/dist/client/assets/{dist-uk11ih8u.js → dist-CqkAY6Ot.js} +2 -2
  116. package/dist/client/assets/dist-D2ql2LCd.js +1 -0
  117. package/dist/client/assets/{dist-BpAUe9sL.js → dist-D47MOYFN.js} +1 -1
  118. package/dist/client/assets/dist-DBhUaexM.js +1 -0
  119. package/dist/client/assets/dist-DJux6Vc5.js +1 -0
  120. package/dist/client/assets/{dist-9Eodxf4G.js → dist-DLNdMWPH.js} +1 -1
  121. package/dist/client/assets/dist-DPJj-Y3l.js +1 -0
  122. package/dist/client/assets/{dist-BSAZ-Hek.js → dist-DRYFMufe.js} +6 -6
  123. package/dist/client/assets/{dist-BrKhPlc9.js → dist-DTGcVSU8.js} +1 -1
  124. package/dist/client/assets/dist-DlOxjzWi.js +9 -0
  125. package/dist/client/assets/{dist-BT9gJXCb.js → dist-DogjjM_B.js} +1 -1
  126. package/dist/client/assets/dist-Dyv_RvyB.js +23 -0
  127. package/dist/client/assets/dist-FUFeH5Cx.js +1 -0
  128. package/dist/client/assets/dist-It70ktCU.js +1 -0
  129. package/dist/client/assets/dist-QMvcnJHf.js +1 -0
  130. package/dist/client/assets/dist-QN1K2czv.js +11 -0
  131. package/dist/client/assets/dist-W8ilOKl3.js +1 -0
  132. package/dist/client/assets/dist-_17-t9qP.js +1 -0
  133. package/dist/client/assets/{dist-DeCV9FU4.js → dist-uE774WWs.js} +1 -1
  134. package/dist/client/assets/document-formatter-DtXmKZcy.js +1 -0
  135. package/dist/client/assets/drawioEditor-DO6IOaJ1.js +9 -0
  136. package/dist/client/assets/{ebnfDiagram-PWID7BFC-PfC84FyI.js → ebnfDiagram-PWID7BFC-IemGPf9X.js} +1 -1
  137. package/dist/client/assets/{ebnfDiagram-ZINNZB2B-DYvm_QtE.js → ebnfDiagram-VR2GEFS7-9fXqy1DI.js} +1 -1
  138. package/dist/client/assets/editor-session-CPsqXY_A.js +13 -0
  139. package/dist/client/assets/elk-IJKZMXRS-DsbrbBYg.js +27 -0
  140. package/dist/client/assets/embedded-editor-base-C44ZcCZv.css +1 -0
  141. package/dist/client/assets/{embedpdf-TkbBYowM.js → embedpdf-BfUI-3pv.js} +1 -1
  142. package/dist/client/assets/{embedpdf-cl9qiF45-itpgqvGY.js → embedpdf-cl9qiF45-CLMxJTMP.js} +2 -2
  143. package/dist/client/assets/en-7ZVUCEYH-C_VXKxxb.js +1 -0
  144. package/dist/client/assets/{erDiagram-OPXOYQCR-o8GRv8A_.js → erDiagram-O2IAPWRE-Cdadm-HN.js} +2 -2
  145. package/dist/client/assets/{erDiagram-RLTQ6QDP-C9cJl5NB.js → erDiagram-RLTQ6QDP-CGGmjm8t.js} +1 -1
  146. package/dist/client/assets/eventmodeling-K75KTNOO-BWBlZ5cR.js +1 -0
  147. package/dist/client/assets/eventmodeling-NTZA5JFV-CDy1bN6j.js +1 -1
  148. package/dist/client/assets/excalidraw-element-link-NQnskRkm.js +1 -0
  149. package/dist/client/assets/excalidraw-scene-DLlw4jyc.js +1 -0
  150. package/dist/client/assets/excalidrawEditor-DiKOIudt.css +1 -0
  151. package/dist/client/assets/excalidrawEditor-W2lZ5Mej.js +9 -0
  152. package/dist/client/assets/export-page-Bomh9oEr.js +46 -0
  153. package/dist/client/assets/exportDocument-BFIOECJ3.js +2 -0
  154. package/dist/client/assets/exportDocument-D0mONgQ4.css +1 -0
  155. package/dist/client/assets/file-kind-BGxTVHan.js +1 -0
  156. package/dist/client/assets/{file-search-BA8o_gs0.js → file-search-Dk2O14Vw.js} +1 -1
  157. package/dist/client/assets/flowDiagram-HODETNUW-DcVVYJUZ.js +1 -0
  158. package/dist/client/assets/flowDiagram-OXPTDLAJ-Dy6y46oF.js +1 -0
  159. package/dist/client/assets/{ganttDiagram-EL5Y4UJY-x40PW0Ah.js → ganttDiagram-EL5Y4UJY-Duu4KnsU.js} +1 -1
  160. package/dist/client/assets/ganttDiagram-R7TSEDQI-BWy52pjn.js +292 -0
  161. package/dist/client/assets/gitGraph-4MIJSDKK-B-rpDYbz.js +1 -1
  162. package/dist/client/assets/gitGraph-VSP46ZUC-1499lQAI.js +1 -0
  163. package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-ahsNaZsp.js → gitGraphDiagram-WWUBYQGX-CaJ0vC1a.js} +1 -1
  164. package/dist/client/assets/gitGraphDiagram-XJZIOB7I-DJwp9ilx.js +106 -0
  165. package/dist/client/assets/graphlib-DS17s2tU.js +1 -0
  166. package/dist/client/assets/image-6XY3GD3F-DCWbu6d4.js +1 -0
  167. package/dist/client/assets/image-lightbox-controller-DAcXEXxT.js +184 -0
  168. package/dist/client/assets/index-CglpXOg7.css +1 -0
  169. package/dist/client/assets/index-D3WGkxfI.js +960 -0
  170. package/dist/client/assets/info-A6RAGUB7-BlutK7BT.js +1 -1
  171. package/dist/client/assets/info-OHQRW6UA-BDFQOo4H.js +1 -0
  172. package/dist/client/assets/{infoDiagram-27XIBGKW-MrZyptIy.js → infoDiagram-27XIBGKW-DBJh7QOu.js} +1 -1
  173. package/dist/client/assets/{infoDiagram-VRGFBTTK-KkUjDRAQ.js → infoDiagram-5W2HQ5XZ-DmWsqJ0w.js} +1 -1
  174. package/dist/client/assets/{ishikawaDiagram-5VMMS53U-Bnt9yM0O.js → ishikawaDiagram-5VMMS53U-CeEbSJem.js} +1 -1
  175. package/dist/client/assets/{ishikawaDiagram-OU5B5YK6-Di9BcpOY.js → ishikawaDiagram-K3B6WC7H-DH1NI35G.js} +2 -2
  176. package/dist/client/assets/{journeyDiagram-3NMN7TZE-Bl0abK1r.js → journeyDiagram-3NMN7TZE-BoIEEr6U.js} +1 -1
  177. package/dist/client/assets/{journeyDiagram-ZHPQQLJL-J-sGrs9e.js → journeyDiagram-COXZFDF6-CnHV2f9V.js} +3 -3
  178. package/dist/client/assets/{kanban-definition-PNTS6WVX-5ZDV_yIa.js → kanban-definition-P3RFRI5V-Cxvn5ZAG.js} +4 -4
  179. package/dist/client/assets/{kanban-definition-UXKFOSKX-DMgUfNt0.js → kanban-definition-UXKFOSKX-BY16Tgbr.js} +1 -1
  180. package/dist/client/assets/keyboard-shortcuts-BWNCBJqw.js +1 -0
  181. package/dist/client/assets/lobby-presence-DNNXcuwR.js +1 -0
  182. package/dist/client/assets/{markdown-CZ1tYEW8.js → markdown-DU84620G.js} +1 -1
  183. package/dist/client/assets/markdown-headings-zYEUahfW.js +41 -0
  184. package/dist/client/assets/{markdown-math-CyyBVuDO.js → markdown-math-B96cnrz1.js} +11 -11
  185. package/dist/client/assets/{mermaid-parser.core-Bpogunsh.js → mermaid-parser.core-R-uwU5kf.js} +3 -3
  186. package/dist/client/assets/{mermaid-parser.core-DBy--Jc0.js → mermaid-parser.core-mE6t1qEO.js} +1 -1
  187. package/dist/client/assets/mermaid.core-D8Z6LN7O.js +10 -0
  188. package/dist/client/assets/{mindmap-definition-NLK3R4M7-ByVb-0vj.js → mindmap-definition-LZFPQGKD-DVfFenfJ.js} +3 -3
  189. package/dist/client/assets/{mindmap-definition-YA3MSWOX-DBZN5_GH.js → mindmap-definition-YA3MSWOX-DtiE80UJ.js} +1 -1
  190. package/dist/client/assets/packet-AYTQ26CC-DvbY8dI6.js +1 -1
  191. package/dist/client/assets/packet-JDAUHWVQ-DJ9K2MA4.js +1 -0
  192. package/dist/client/assets/{pegDiagram-GJSIUBJH-aost1sSO.js → pegDiagram-BGZESJAR-DxfvEcwv.js} +1 -1
  193. package/dist/client/assets/{pegDiagram-XKGWAZYB-DRo8CZu3.js → pegDiagram-XKGWAZYB-CyozY-Kt.js} +1 -1
  194. package/dist/client/assets/pie-WAS4IAKB-DWSm9SSD.js +1 -1
  195. package/dist/client/assets/pie-XZMESJXO-CQIQasY-.js +1 -0
  196. package/dist/client/assets/{pieDiagram-5QR66LMP-BICdpEuz.js → pieDiagram-CAPJLFHJ-CRlMcrv3.js} +2 -2
  197. package/dist/client/assets/{pieDiagram-E7YTZNPT-CZThaHsc.js → pieDiagram-E7YTZNPT-BRdmTkDq.js} +1 -1
  198. package/dist/client/assets/preload-helper-CYtfOYgs.js +1 -0
  199. package/dist/client/assets/preview-render-compiler-D_aJv7Ew.js +3 -0
  200. package/dist/client/assets/{preview-render-worker-BA4VK_GY.js → preview-render-worker-dFNyrVyB.js} +46 -42
  201. package/dist/client/assets/prod-ItolaHmf.js +145 -0
  202. package/dist/client/assets/prod-rdly4JJQ.js +1 -0
  203. package/dist/client/assets/{quadrantDiagram-AXDQQJYC-C5iowkl_.js → quadrantDiagram-AXDQQJYC-7QyPIXkF.js} +1 -1
  204. package/dist/client/assets/{quadrantDiagram-O4NWA36T-Bgx5bF97.js → quadrantDiagram-GDMTTRAM-DE30uqTl.js} +3 -3
  205. package/dist/client/assets/quick-switcher-controller-DsK70I7K.js +1 -0
  206. package/dist/client/assets/radar-ABXABTNO-ByfpCXh9.js +1 -0
  207. package/dist/client/assets/radar-RG4KPBEZ-BfNQUEQy.js +1 -1
  208. package/dist/client/assets/railroad-74A4TZTK-BaQ6U6eJ.js +1 -1
  209. package/dist/client/assets/railroad-I3PHUGI6-CTUn9HhI.js +1 -0
  210. package/dist/client/assets/railroad-abnf-HS5TGJTU-BJ3KZw7J.js +1 -1
  211. package/dist/client/assets/railroad-abnf-LNEFI6M7-Ct-b-y0F.js +1 -0
  212. package/dist/client/assets/railroad-ebnf-DWYD2UWJ-BZMYMWOe.js +1 -0
  213. package/dist/client/assets/railroad-ebnf-LZEXJU2U-DA0sEq7w.js +1 -1
  214. package/dist/client/assets/railroad-peg-JR7BVNR7-Dj23PxYc.js +1 -0
  215. package/dist/client/assets/railroad-peg-WCYAUIDC-DCmlICzO.js +1 -1
  216. package/dist/client/assets/{railroadDiagram-O6MQD6OU-BTt_rKjT.js → railroadDiagram-O6MQD6OU-BPk3RS2D.js} +1 -1
  217. package/dist/client/assets/{railroadDiagram-XR7U4H2S-DbVoNgSz.js → railroadDiagram-SM67HX2B-CZRXJ647.js} +1 -1
  218. package/dist/client/assets/{requirementDiagram-BXWQKSXE-BkvazG7r.js → requirementDiagram-BXWQKSXE-BRwfym6z.js} +1 -1
  219. package/dist/client/assets/{requirementDiagram-PLB6GJNP-BT0j9C40.js → requirementDiagram-X7JNWC4A-BofCuLJA.js} +4 -4
  220. package/dist/client/assets/{sankeyDiagram-P5KCCOFB-C_IemB9h.js → sankeyDiagram-P5KCCOFB-D4LcrKpW.js} +1 -1
  221. package/dist/client/assets/{sankeyDiagram-IPEJSGJF-X1BCUIrf.js → sankeyDiagram-UM26HJRW-CLKMDbej.js} +3 -3
  222. package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-CxFBgLGd.js → sequenceDiagram-WJ2MYXX4-DQjtv-Bs.js} +1 -1
  223. package/dist/client/assets/sequenceDiagram-ZO4K6R2Y-CDP_m6ma.js +169 -0
  224. package/dist/client/assets/sizeCapture-INFHLROL-3uHXrFqA.js +1 -0
  225. package/dist/client/assets/sizeCapture-INFHLROL-BMR1ovSU.js +1 -0
  226. package/dist/client/assets/src-D5mvpivG.js +2 -0
  227. package/dist/client/assets/{standalone-DbyFjvTU.js → standalone-D_lg5NC9.js} +1 -1
  228. package/dist/client/assets/{stateDiagram-D77RDMKH-BaSQ6Owj.js → stateDiagram-D77RDMKH-DSMvV-kF.js} +1 -1
  229. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-ClmOOUsT.js +1 -0
  230. package/dist/client/assets/{stateDiagram-v2-GCMORJYK-CsVcfwVp.js → stateDiagram-v2-TBUQTH76-Dc5-FKzd.js} +2 -2
  231. package/dist/client/assets/{swimlanes-42K2YHIH-CALFEmiS.js → swimlanes-42K2YHIH-BUz31lO3.js} +1 -1
  232. package/dist/client/assets/{swimlanes-2SLR337P-CnYTVqRX.js → swimlanes-N4OXWK64-Dd3dFdPD.js} +1 -1
  233. package/dist/client/assets/swimlanesDiagram-K3J5GTZL-Bz9gFdls.js +8 -0
  234. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-DoDs3zod.js +8 -0
  235. package/dist/client/assets/{timeline-definition-24CTP7MA-zse-5Dbm.js → timeline-definition-24CTP7MA-BvqCvSjy.js} +1 -1
  236. package/dist/client/assets/{timeline-definition-EJHVYXUP-BhqPlKkN.js → timeline-definition-YOQAKGHF-D2XWPSLs.js} +3 -3
  237. package/dist/client/assets/treeView-D4JQ5SDB-DcX7Bx0H.js +1 -0
  238. package/dist/client/assets/treeView-Q6P3EWNA-BvHOzbu9.js +1 -1
  239. package/dist/client/assets/treemap-SAJKECNS-BcCHmcAX.js +1 -0
  240. package/dist/client/assets/treemap-WGGIJYW6-oety7paS.js +1 -1
  241. package/dist/client/assets/usecaseDiagram-VIAY4XPW-CDe-IMjS.js +328 -0
  242. package/dist/client/assets/vault-api-client-DrRW0QwO.js +7 -0
  243. package/dist/client/assets/{vennDiagram-4TSXK5OY-DgHr6cJD.js → vennDiagram-4TSXK5OY-BW6Qp12d.js} +1 -1
  244. package/dist/client/assets/{vennDiagram-UO4OBE2U-BRwLn2Q1.js → vennDiagram-BLWOH2XV-KxIPKpHi.js} +3 -3
  245. package/dist/client/assets/wardley-7MLQ67FV-DOahSwbZ.js +1 -0
  246. package/dist/client/assets/wardley-WFR3VGLG-BdwDpX_I.js +1 -1
  247. package/dist/client/assets/{wardleyDiagram-VM6X3IG4-9A60XZis.js → wardleyDiagram-VM6X3IG4-BoCETVsK.js} +1 -1
  248. package/dist/client/assets/{wardleyDiagram-VNRHLVJA-B_tMcVFG.js → wardleyDiagram-YMQ3BMBF-BNYqEy7M.js} +4 -4
  249. package/dist/client/assets/{wiki-link-resolver-Dch88erO.js → wiki-link-resolver-BCdGUpdu.js} +1 -1
  250. package/dist/client/assets/{worker-engine-BCCrxWYm-CX0qJ_cG.js → worker-engine-BCCrxWYm-1fphds7O.js} +1 -1
  251. package/dist/client/assets/workspace-sync-client-C_P9wtjf.js +1 -0
  252. package/dist/client/assets/{xychartDiagram-S5SC5T6Z-D00iy-wB.js → xychartDiagram-S5SC5T6Z-eB5Fu9P7.js} +1 -1
  253. package/dist/client/assets/xychartDiagram-TAQBALBS-Sv6aaptV.js +7 -0
  254. package/dist/client/assets/yjs-Jd9fna_Y.js +4 -0
  255. package/dist/client/assets/yjs-provider-reset-guard-Cqu0Z6xH.js +1 -0
  256. package/dist/client/canvas-editor.html +16 -0
  257. package/dist/client/drawio-editor.html +7 -6
  258. package/dist/client/excalidraw-editor.html +31 -30
  259. package/dist/client/export-document.html +4 -3
  260. package/dist/client/index.html +2 -2
  261. package/package.json +27 -29
  262. package/scripts/local-compose.mjs +101 -0
  263. package/src/client/app/canvas-editor.html +13 -0
  264. package/src/client/application/app-shell/git-feature.js +3 -2
  265. package/src/client/application/app-shell/ui-feature-identity.js +1 -0
  266. package/src/client/application/app-shell/ui-feature-shell.js +2 -0
  267. package/src/client/application/app-shell/ui-feature-tab-activity.js +4 -0
  268. package/src/client/application/app-shell/workspace-feature.js +8 -34
  269. package/src/client/application/diagram-chrome.js +8 -11
  270. package/src/client/application/diagram-preview-hydrator.js +5 -5
  271. package/src/client/application/mermaid-preview-hydrator.js +3 -2
  272. package/src/client/application/plantuml-preview-hydrator.js +6 -0
  273. package/src/client/application/preview-render-compiler.js +34 -98
  274. package/src/client/application/preview-render-executor.js +3 -0
  275. package/src/client/application/preview-render-worker.js +2 -0
  276. package/src/client/application/preview-renderer.js +9 -5
  277. package/src/client/application/workspace-coordinator.js +18 -10
  278. package/src/client/application/workspace-preview-controller.js +105 -158
  279. package/src/client/application/workspace-route-controller.js +29 -54
  280. package/src/client/bootstrap/canvas-markdown-preview.js +87 -0
  281. package/src/client/bootstrap/collabmd-app-shell.js +28 -13
  282. package/src/client/canvas-editor.js +143 -0
  283. package/src/client/domain/canvas-view.js +50 -0
  284. package/src/client/domain/excalidraw-scene.js +4 -49
  285. package/src/client/domain/highlight-runtime.js +0 -4
  286. package/src/client/domain/markdown-formatting.js +12 -94
  287. package/src/client/domain/markdown-headings.js +98 -0
  288. package/src/client/domain/wiki-link-completions.js +42 -10
  289. package/src/client/infrastructure/browser-preferences-port.js +27 -33
  290. package/src/client/infrastructure/canvas-room-client.js +210 -0
  291. package/src/client/infrastructure/canvas-text-editor.js +36 -0
  292. package/src/client/infrastructure/comment-thread-store.js +19 -77
  293. package/src/client/infrastructure/editor-view-adapter.js +0 -30
  294. package/src/client/infrastructure/excalidraw-room-client.js +22 -10
  295. package/src/client/infrastructure/hosted-api-client.js +4 -2
  296. package/src/client/infrastructure/vault-api-client.js +4 -4
  297. package/src/client/presentation/canvas-editor-view.js +1028 -0
  298. package/src/client/presentation/canvas-embed-controller.js +116 -0
  299. package/src/client/presentation/canvas-picker.js +111 -0
  300. package/src/client/presentation/drawio-embed-controller.js +1 -3
  301. package/src/client/presentation/excalidraw-embed-controller.js +10 -3
  302. package/src/client/presentation/file-action-controller.js +37 -0
  303. package/src/client/presentation/file-explorer-controller.js +1 -2
  304. package/src/client/presentation/file-explorer-view.js +7 -1
  305. package/src/client/presentation/file-icon-svg.js +1 -1
  306. package/src/client/presentation/file-tree-state.js +4 -1
  307. package/src/client/presentation/image-lightbox-controller.js +1 -5
  308. package/src/client/presentation/team-settings-controller.js +44 -10
  309. package/src/client/styles/components/actions.css +4 -16
  310. package/src/client/styles/components/surfaces.css +0 -7
  311. package/src/client/styles/features/comment-card.css +1 -2
  312. package/src/client/styles/features/comment-markdown.css +0 -18
  313. package/src/client/styles/features/diagram-preview.css +0 -18
  314. package/src/client/styles/features/git-branch.css +0 -4
  315. package/src/client/styles/foundation/themes.css +6 -0
  316. package/src/client/styles/foundation/utilities.css +1 -2
  317. package/src/client/styles/layout/editor-page.css +0 -13
  318. package/src/client/styles/layout/responsive.css +2 -7
  319. package/src/client/styles/layout/shell.css +13 -1
  320. package/src/client/styles/layout/view-modes.css +1 -0
  321. package/src/client/styles/surfaces/canvas-editor.css +239 -0
  322. package/src/domain/canvas-room-codec.js +359 -0
  323. package/src/domain/collabmd-content-capabilities.js +10 -1
  324. package/src/domain/comment-threads.js +49 -5
  325. package/src/domain/excalidraw-room-codec.js +23 -73
  326. package/src/domain/excalidraw-scene.js +48 -0
  327. package/src/domain/file-kind.js +13 -1
  328. package/src/server/application/workspace-reconciliation.js +0 -14
  329. package/src/server/domain/backlink-index.js +1 -36
  330. package/src/server/domain/bases/base-index-snapshot-store.js +41 -24
  331. package/src/server/domain/bases/base-query-service.js +1 -47
  332. package/src/server/domain/collaboration/collaboration-room.js +149 -15
  333. package/src/server/domain/collaboration/room-registry.js +7 -7
  334. package/src/server/domain/hosted-workspace.js +29 -2
  335. package/src/server/domain/plantuml-encoder.js +7 -43
  336. package/src/server/infrastructure/git/diff-service.js +1 -5
  337. package/src/server/infrastructure/git/history-service.js +18 -2
  338. package/src/server/infrastructure/git/untracked-files.js +1 -1
  339. package/src/server/infrastructure/http/create-git-api-command-handler.js +60 -149
  340. package/src/server/infrastructure/http/create-hosted-api-handler.js +5 -2
  341. package/src/server/infrastructure/http/create-vault-api-query-handler.js +2 -2
  342. package/src/server/infrastructure/http/http-response.js +2 -36
  343. package/src/server/infrastructure/http/request-body.js +14 -49
  344. package/src/server/infrastructure/persistence/hosted-metadata-store.js +12 -3
  345. package/src/server/infrastructure/persistence/path-utils.js +8 -2
  346. package/src/server/infrastructure/persistence/vault-file-store.js +26 -60
  347. package/src/server/{infrastructure/git → shared}/image-mime.js +2 -2
  348. package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-kJfwukbn.js +0 -1
  349. package/dist/client/assets/_basePickBy-QJXUw_pr.js +0 -1
  350. package/dist/client/assets/_baseUniq-DR4vVjyC.js +0 -1
  351. package/dist/client/assets/architecture-7GRP2DOG-DJVtYNt-.js +0 -1
  352. package/dist/client/assets/browser-utils-S4QYY31r.js +0 -1
  353. package/dist/client/assets/chunk-3FUC2YCW-8tZlhTGX.js +0 -1
  354. package/dist/client/assets/chunk-7M6MHVWA-BDakkknV.js +0 -213
  355. package/dist/client/assets/chunk-FOHPRMQF-Dmmo5Kak.js +0 -161
  356. package/dist/client/assets/chunk-O7XYJQB3-D0_ZY2za.js +0 -126
  357. package/dist/client/assets/chunk-T5WUORNS-DD7KlyY6.js +0 -40
  358. package/dist/client/assets/chunk-Z7XXMR3K-P4Vaq8hD.js +0 -10
  359. package/dist/client/assets/chunk-ZIGJFQKS-b8OUHKK5.js +0 -2
  360. package/dist/client/assets/classDiagram-ZZMXUADV-QLbh_Nkf.js +0 -1
  361. package/dist/client/assets/classDiagram-v2-VYDZK3BY-QLbh_Nkf.js +0 -1
  362. package/dist/client/assets/comment-thread-store-CHvy8GF8.js +0 -1
  363. package/dist/client/assets/comment-threads-nJhK1yfc.js +0 -4
  364. package/dist/client/assets/cynefin-OW5HDTMX-e-Quc9Yl.js +0 -1
  365. package/dist/client/assets/dagre-D7FiCLLP.js +0 -1
  366. package/dist/client/assets/deferred-collab-D4cxEdad.css +0 -1
  367. package/dist/client/assets/deferred-git-BHKtkFYi.css +0 -1
  368. package/dist/client/assets/deferred-preview-BAXYgf4T.css +0 -1
  369. package/dist/client/assets/diagram-ATOU4E4O-B5uX-jVO.js +0 -3
  370. package/dist/client/assets/dist-B2ZNQifU.js +0 -1
  371. package/dist/client/assets/dist-B6QCMNze.js +0 -1
  372. package/dist/client/assets/dist-BIAv19LO.js +0 -1
  373. package/dist/client/assets/dist-BKYp1-dl.js +0 -13
  374. package/dist/client/assets/dist-BSTbcioM.js +0 -11
  375. package/dist/client/assets/dist-BTVg1m-V.js +0 -1
  376. package/dist/client/assets/dist-Bi9ZIYXq.js +0 -9
  377. package/dist/client/assets/dist-Bqo-XRVG.js +0 -1
  378. package/dist/client/assets/dist-CBsvKPcT.js +0 -1
  379. package/dist/client/assets/dist-CJBYh9Wy.js +0 -23
  380. package/dist/client/assets/dist-CRwfjtwz.js +0 -2
  381. package/dist/client/assets/dist-CX7Kc61C.js +0 -1
  382. package/dist/client/assets/dist-CYfPeupF.js +0 -1
  383. package/dist/client/assets/dist-CucpLxUY.js +0 -1
  384. package/dist/client/assets/dist-DHBMeCxC.js +0 -6
  385. package/dist/client/assets/dist-DLEg9d4u.js +0 -1
  386. package/dist/client/assets/dist-DYFBD-wW.js +0 -1
  387. package/dist/client/assets/dist-DugWGOjQ.js +0 -1
  388. package/dist/client/assets/dist-NNrRnB-f.js +0 -1
  389. package/dist/client/assets/dist-PUxZqhFe.js +0 -1
  390. package/dist/client/assets/dist-cYiJMWHJ.js +0 -1
  391. package/dist/client/assets/dist-iKC7go4m.js +0 -1
  392. package/dist/client/assets/document-formatter-6I63vstk.js +0 -1
  393. package/dist/client/assets/drawioEditor-DNTjsjzJ.js +0 -9
  394. package/dist/client/assets/editor-session-D8GGkJak.js +0 -14
  395. package/dist/client/assets/elk-276RUBZZ-B8LB3Pac.js +0 -27
  396. package/dist/client/assets/embedded-editor-base-elU0Avik.css +0 -1
  397. package/dist/client/assets/en-JTHJ2SIP-DBz9bRq4.js +0 -1
  398. package/dist/client/assets/eventmodeling-NTZA5JFV-Dxtv5D-P.js +0 -1
  399. package/dist/client/assets/excalidraw-element-link-BRZOTIeI.js +0 -7
  400. package/dist/client/assets/excalidraw-scene-6uROebca.js +0 -1
  401. package/dist/client/assets/excalidrawEditor-BCTFp_CV.css +0 -1
  402. package/dist/client/assets/excalidrawEditor-D0orhhku.js +0 -9
  403. package/dist/client/assets/export-page-CVJNMERq.js +0 -46
  404. package/dist/client/assets/exportDocument-Ba-n1X4U.css +0 -1
  405. package/dist/client/assets/exportDocument-DSshnmnZ.js +0 -2
  406. package/dist/client/assets/file-kind-BwMIcZbi.js +0 -1
  407. package/dist/client/assets/flowDiagram-HODETNUW-Bq4470NR.js +0 -1
  408. package/dist/client/assets/flowDiagram-KWPJA3E3-DQG9qGiU.js +0 -1
  409. package/dist/client/assets/ganttDiagram-FUAMR5RP-BQpsI7gQ.js +0 -292
  410. package/dist/client/assets/gitGraph-4MIJSDKK-ZaBIE4Lb.js +0 -1
  411. package/dist/client/assets/gitGraphDiagram-X574FWY7-wbs_2m9f.js +0 -106
  412. package/dist/client/assets/graphlib-C9Tl7QrK.js +0 -1
  413. package/dist/client/assets/image-I42VHMUI-B2-c_ifV.js +0 -1
  414. package/dist/client/assets/index-BCgNcVNs.css +0 -1
  415. package/dist/client/assets/index-BpmR5Qqk.js +0 -1140
  416. package/dist/client/assets/info-A6RAGUB7-BcGxhjED.js +0 -1
  417. package/dist/client/assets/lobby-presence-KJrYhMdN.js +0 -1
  418. package/dist/client/assets/mermaid.core-BeOUPE3Q.js +0 -10
  419. package/dist/client/assets/packet-AYTQ26CC-CqpSjTWl.js +0 -1
  420. package/dist/client/assets/pie-WAS4IAKB-Bg2eCNl5.js +0 -1
  421. package/dist/client/assets/preload-helper-BAlEavIC.js +0 -1
  422. package/dist/client/assets/preview-render-compiler-BmWQStaL.js +0 -43
  423. package/dist/client/assets/prod-CA0ie9yD.js +0 -145
  424. package/dist/client/assets/prod-yKJZ3E4s.js +0 -1
  425. package/dist/client/assets/quick-switcher-controller-B5vT9Vj5.js +0 -1
  426. package/dist/client/assets/radar-RG4KPBEZ-DxExotg6.js +0 -1
  427. package/dist/client/assets/railroad-74A4TZTK-FfHmeIQk.js +0 -1
  428. package/dist/client/assets/railroad-abnf-HS5TGJTU-CLkdDRsJ.js +0 -1
  429. package/dist/client/assets/railroad-ebnf-LZEXJU2U-B162zvcG.js +0 -1
  430. package/dist/client/assets/railroad-peg-WCYAUIDC-CGs5GeJ5.js +0 -1
  431. package/dist/client/assets/sequenceDiagram-PO4LG4MO-B-2QfXhV.js +0 -169
  432. package/dist/client/assets/sizeCapture-INFHLROL-B0uUizjq.js +0 -1
  433. package/dist/client/assets/sizeCapture-INFHLROL-DrzwYt5z.js +0 -1
  434. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-CLlwrdvU.js +0 -1
  435. package/dist/client/assets/swimlanesDiagram-TC7HE7FX-Bh4tmz27.js +0 -8
  436. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-xhehUG9e.js +0 -8
  437. package/dist/client/assets/treeView-Q6P3EWNA-Cccy0ngL.js +0 -1
  438. package/dist/client/assets/treemap-WGGIJYW6-sMRCjCtX.js +0 -1
  439. package/dist/client/assets/usecaseDiagram-POWQR4AR-DR2LHQYs.js +0 -328
  440. package/dist/client/assets/vault-api-client-NS_EVHJ3.js +0 -7
  441. package/dist/client/assets/wardley-WFR3VGLG-Y7xty_3m.js +0 -1
  442. package/dist/client/assets/workspace-sync-client-BrMtf6zN.js +0 -1
  443. package/dist/client/assets/xychartDiagram-PMCCYNJV-fRpZ1MA5.js +0 -7
  444. package/dist/client/assets/yjs-B41tM6Sz.js +0 -4
  445. package/dist/client/assets/yjs-provider-reset-guard-DpntzUDR.js +0 -1
  446. package/scripts/local-plantuml-compose.mjs +0 -92
  447. package/scripts/local-structurizr-compose.mjs +0 -101
@@ -102,6 +102,24 @@ function publicAuditEvent(record = null) {
102
102
  };
103
103
  }
104
104
 
105
+ function parseAuditCursor(cursor) {
106
+ if (!cursor) return null;
107
+ try {
108
+ if (typeof cursor !== 'string' || cursor.length > 256 || !/^[A-Za-z0-9_-]+$/u.test(cursor)) {
109
+ throw new Error('Invalid cursor');
110
+ }
111
+ const value = JSON.parse(Buffer.from(cursor, 'base64url').toString('utf8'));
112
+ if (!Array.isArray(value) || value.length !== 2
113
+ || !Number.isSafeInteger(value[0]) || value[0] < 0
114
+ || typeof value[1] !== 'string' || !value[1] || value[1].length > 128) {
115
+ throw new Error('Invalid cursor');
116
+ }
117
+ return { createdAt: value[0], id: value[1] };
118
+ } catch {
119
+ throw createHostedError(400, 'Invalid access history cursor.', 'HOSTED_AUDIT_CURSOR_INVALID');
120
+ }
121
+ }
122
+
105
123
  function publicVaultSource(record = null) {
106
124
  if (!record) {
107
125
  return null;
@@ -734,8 +752,17 @@ export class HostedWorkspaceService {
734
752
  }));
735
753
  }
736
754
 
737
- async listAuditEvents(user) {
755
+ async listAuditEvents(user, { cursor = '', limit = 50 } = {}) {
738
756
  await this.requireAdmin(user);
739
- return (await this.store.listAuditEvents()).map(publicAuditEvent);
757
+ const pageSize = Math.min(100, Math.max(1, Number.parseInt(limit, 10) || 50));
758
+ const rows = await this.store.listAuditEvents({ before: parseAuditCursor(cursor), limit: pageSize + 1 });
759
+ const events = rows.slice(0, pageSize).map(publicAuditEvent);
760
+ const last = events.at(-1);
761
+ return {
762
+ events,
763
+ nextCursor: rows.length > pageSize
764
+ ? Buffer.from(JSON.stringify([last.createdAt, last.id])).toString('base64url')
765
+ : null,
766
+ };
740
767
  }
741
768
  }
@@ -1,49 +1,13 @@
1
1
  import { deflateRawSync } from 'node:zlib';
2
2
 
3
- function encode6bit(value) {
4
- if (value < 10) {
5
- return String.fromCharCode(48 + value);
6
- }
7
-
8
- if (value < 36) {
9
- return String.fromCharCode(55 + value);
10
- }
11
-
12
- if (value < 62) {
13
- return String.fromCharCode(61 + value);
14
- }
15
-
16
- if (value === 62) {
17
- return '-';
18
- }
19
-
20
- if (value === 63) {
21
- return '_';
22
- }
23
-
24
- return '?';
25
- }
26
-
27
- function append3bytes(byte1, byte2, byte3) {
28
- const c1 = byte1 >> 2;
29
- const c2 = ((byte1 & 0x03) << 4) | (byte2 >> 4);
30
- const c3 = ((byte2 & 0x0f) << 2) | (byte3 >> 6);
31
- const c4 = byte3 & 0x3f;
32
-
33
- return `${encode6bit(c1 & 0x3f)}${encode6bit(c2 & 0x3f)}${encode6bit(c3 & 0x3f)}${encode6bit(c4 & 0x3f)}`;
34
- }
3
+ const BASE64URL_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
4
+ const PLANTUML_ALPHABET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_';
35
5
 
36
6
  export function encodePlantUmlText(source = '') {
37
7
  const compressed = deflateRawSync(Buffer.from(String(source), 'utf-8'));
38
- let encoded = '';
39
-
40
- for (let index = 0; index < compressed.length; index += 3) {
41
- encoded += append3bytes(
42
- compressed[index] ?? 0,
43
- compressed[index + 1] ?? 0,
44
- compressed[index + 2] ?? 0,
45
- );
46
- }
47
-
48
- return encoded;
8
+ const padded = Buffer.alloc(Math.ceil(compressed.length / 3) * 3);
9
+ compressed.copy(padded);
10
+ return padded.toString('base64url').replace(/./gu, (character) => (
11
+ PLANTUML_ALPHABET[BASE64URL_ALPHABET.indexOf(character)]
12
+ ));
49
13
  }
@@ -107,7 +107,6 @@ export class GitDiffService {
107
107
  }
108
108
 
109
109
  getScopedFiles(status, scope = 'working-tree', path = null) {
110
- const orderedFiles = [];
111
110
  const fileMap = new Map();
112
111
  const sectionMap = createSectionMap(status.sections);
113
112
  const candidateSections = scope === 'staged'
@@ -126,13 +125,10 @@ export class GitDiffService {
126
125
  const existing = fileMap.get(file.path) ?? null;
127
126
  const merged = mergeScopedFile(existing, file, scope);
128
127
  fileMap.set(file.path, merged);
129
- if (!existing) {
130
- orderedFiles.push(merged);
131
- }
132
128
  }
133
129
  }
134
130
 
135
- return orderedFiles;
131
+ return Array.from(fileMap.values());
136
132
  }
137
133
 
138
134
  async getScopeSummary({
@@ -1,7 +1,7 @@
1
1
  import { createRequestError as createGitRequestError } from '../http/http-errors.js';
2
2
  import { getVaultFileKind, isImageAttachmentFilePath } from '../../../domain/file-kind.js';
3
3
  import { normalizeRelativeGitPath } from './path-utils.js';
4
- import { getImageMimeType } from './image-mime.js';
4
+ import { getImageMimeType } from '../../shared/image-mime.js';
5
5
  import {
6
6
  countPatchLines,
7
7
  parseGitLogHeader,
@@ -16,6 +16,8 @@ import {
16
16
  const EMPTY_TREE_HASH = '4b825dc642cb6eb9a060e54bf8d69288fbee4904';
17
17
  const DEFAULT_HISTORY_LIMIT = 30;
18
18
  const HISTORY_LIMIT_CAP = 50;
19
+ const RESPONSE_CACHE_LIMIT = 50;
20
+ const MAX_CACHED_RESPONSE_BYTES = 256 * 1024;
19
21
 
20
22
  function clampHistoryLimit(limit) {
21
23
  const parsedLimit = Number.parseInt(String(limit ?? DEFAULT_HISTORY_LIMIT), 10);
@@ -77,8 +79,22 @@ function getCachedValue(cache, key) {
77
79
  }
78
80
 
79
81
  function setCachedValue(cache, key, value, ttlMs) {
82
+ const now = Date.now();
83
+ for (const [cachedKey, cached] of cache) {
84
+ if (now >= cached.expiresAt) cache.delete(cachedKey);
85
+ }
86
+ cache.delete(key);
87
+ const payloadBytes = Buffer.isBuffer(value.content)
88
+ ? value.content.byteLength
89
+ : Buffer.byteLength(JSON.stringify(value));
90
+ if (ttlMs <= 0 || payloadBytes + Buffer.byteLength(key) > MAX_CACHED_RESPONSE_BYTES) {
91
+ return value;
92
+ }
93
+ while (cache.size >= RESPONSE_CACHE_LIMIT) {
94
+ cache.delete(cache.keys().next().value);
95
+ }
80
96
  cache.set(key, {
81
- expiresAt: Date.now() + ttlMs,
97
+ expiresAt: now + ttlMs,
82
98
  value,
83
99
  });
84
100
  return value;
@@ -7,7 +7,7 @@ import { getVaultFileKind, isImageAttachmentFilePath } from '../../../domain/fil
7
7
  import { mapWithConcurrency } from '../../shared/async-utils.js';
8
8
  import { createEmptyStats } from './responses.js';
9
9
  import { splitContentLines } from './parsers.js';
10
- import { getImageMimeType } from './image-mime.js';
10
+ import { getImageMimeType } from '../../shared/image-mime.js';
11
11
 
12
12
  async function countFileLines(filePath) {
13
13
  if (isImageAttachmentFilePath(filePath)) {
@@ -41,160 +41,71 @@ export function createGitApiCommandHandler({
41
41
  gitService,
42
42
  workspaceMutationCoordinator = null,
43
43
  }) {
44
- return async function handleGitApiCommand(req, res, requestUrl) {
45
- if (requestUrl.pathname === '/api/git/stage' && req.method === 'POST') {
46
- try {
47
- const body = await parseRequiredBody(req, res, 'path');
48
- if (!body) {
49
- return true;
50
- }
51
-
52
- jsonResponse(req, res, 200, await applyWorkspaceMutationEffects({
53
- action: 'stage',
54
- req,
55
- responsePayload: await workspaceMutationCoordinator.runManagedWorkspaceMutation(
56
- () => gitService.stageFile(body.path),
57
- ),
58
- workspaceMutationCoordinator,
59
- }));
60
- } catch (error) {
61
- handleApiError(req, res, error, '[api] Failed to stage git file:', 'Failed to stage git file');
62
- }
63
- return true;
64
- }
65
-
66
- if (requestUrl.pathname === '/api/git/unstage' && req.method === 'POST') {
67
- try {
68
- const body = await parseRequiredBody(req, res, 'path');
69
- if (!body) {
70
- return true;
71
- }
72
-
73
- jsonResponse(req, res, 200, await applyWorkspaceMutationEffects({
74
- action: 'unstage',
75
- req,
76
- responsePayload: await workspaceMutationCoordinator.runManagedWorkspaceMutation(
77
- () => gitService.unstageFile(body.path),
78
- ),
79
- workspaceMutationCoordinator,
80
- }));
81
- } catch (error) {
82
- handleApiError(req, res, error, '[api] Failed to unstage git file:', 'Failed to unstage git file');
83
- }
84
- return true;
85
- }
86
-
87
- if (requestUrl.pathname === '/api/git/stage-all' && req.method === 'POST') {
88
- try {
89
- jsonResponse(req, res, 200, await applyWorkspaceMutationEffects({
90
- action: 'stage-all',
91
- req,
92
- responsePayload: await workspaceMutationCoordinator.runManagedWorkspaceMutation(
93
- () => gitService.stageAll(),
94
- ),
95
- workspaceMutationCoordinator,
96
- }));
97
- } catch (error) {
98
- handleApiError(req, res, error, '[api] Failed to stage all git changes:', 'Failed to stage all git changes');
99
- }
100
- return true;
101
- }
102
-
103
- if (requestUrl.pathname === '/api/git/unstage-all' && req.method === 'POST') {
104
- try {
105
- jsonResponse(req, res, 200, await applyWorkspaceMutationEffects({
106
- action: 'unstage-all',
107
- req,
108
- responsePayload: await workspaceMutationCoordinator.runManagedWorkspaceMutation(
109
- () => gitService.unstageAll(),
110
- ),
111
- workspaceMutationCoordinator,
112
- }));
113
- } catch (error) {
114
- handleApiError(req, res, error, '[api] Failed to unstage all git changes:', 'Failed to unstage all git changes');
115
- }
116
- return true;
117
- }
118
-
119
- if (requestUrl.pathname === '/api/git/commit' && req.method === 'POST') {
120
- try {
121
- const body = await parseRequiredBody(req, res, 'message');
122
- if (!body) {
123
- return true;
124
- }
125
-
126
- jsonResponse(req, res, 200, await applyWorkspaceMutationEffects({
127
- action: 'commit',
128
- req,
129
- responsePayload: await workspaceMutationCoordinator.runManagedWorkspaceMutation(
130
- () => gitService.commitStaged({
131
- author: authService?.getAuthenticatedUser?.(req) ?? null,
132
- message: body.message,
133
- }),
134
- ),
135
- workspaceMutationCoordinator,
136
- }));
137
- } catch (error) {
138
- handleApiError(req, res, error, '[api] Failed to commit staged changes:', 'Failed to commit staged changes');
139
- }
140
- return true;
141
- }
44
+ const routes = [
45
+ {
46
+ action: 'stage', bodyField: 'path', errorMessage: 'Failed to stage git file',
47
+ run: (body) => gitService.stageFile(body.path),
48
+ },
49
+ {
50
+ action: 'unstage', bodyField: 'path', errorMessage: 'Failed to unstage git file',
51
+ run: (body) => gitService.unstageFile(body.path),
52
+ },
53
+ {
54
+ action: 'stage-all', errorMessage: 'Failed to stage all git changes',
55
+ run: () => gitService.stageAll(),
56
+ },
57
+ {
58
+ action: 'unstage-all', errorMessage: 'Failed to unstage all git changes',
59
+ run: () => gitService.unstageAll(),
60
+ },
61
+ {
62
+ action: 'commit', bodyField: 'message', errorMessage: 'Failed to commit staged changes',
63
+ run: (body, req) => gitService.commitStaged({
64
+ author: authService?.getAuthenticatedUser?.(req) ?? null,
65
+ message: body.message,
66
+ }),
67
+ },
68
+ {
69
+ action: 'push', errorMessage: 'Failed to push git branch',
70
+ run: () => gitService.pushBranch(),
71
+ },
72
+ {
73
+ action: 'pull', errorMessage: 'Failed to pull git branch',
74
+ run: (_body, req) => gitService.pullBranch({
75
+ author: authService?.getAuthenticatedUser?.(req) ?? null,
76
+ }),
77
+ },
78
+ {
79
+ action: 'reset-file', bodyField: 'path', errorMessage: 'Failed to reset git file',
80
+ run: (body) => gitService.resetFileToHead(body.path),
81
+ },
82
+ ];
142
83
 
143
- if (requestUrl.pathname === '/api/git/push' && req.method === 'POST') {
144
- try {
145
- jsonResponse(req, res, 200, await applyWorkspaceMutationEffects({
146
- action: 'push',
147
- req,
148
- responsePayload: await workspaceMutationCoordinator.runManagedWorkspaceMutation(
149
- () => gitService.pushBranch(),
150
- ),
151
- workspaceMutationCoordinator,
152
- }));
153
- } catch (error) {
154
- handleApiError(req, res, error, '[api] Failed to push git branch:', 'Failed to push git branch');
155
- }
156
- return true;
84
+ return async function handleGitApiCommand(req, res, requestUrl) {
85
+ const route = req.method === 'POST'
86
+ ? routes.find(({ action }) => requestUrl.pathname === `/api/git/${action}`)
87
+ : null;
88
+ if (!route) {
89
+ return false;
157
90
  }
158
91
 
159
- if (requestUrl.pathname === '/api/git/pull' && req.method === 'POST') {
160
- try {
161
- jsonResponse(req, res, 200, await applyWorkspaceMutationEffects({
162
- action: 'pull',
163
- req,
164
- responsePayload: await workspaceMutationCoordinator.runManagedWorkspaceMutation(
165
- () => gitService.pullBranch({
166
- author: authService?.getAuthenticatedUser?.(req) ?? null,
167
- }),
168
- ),
169
- workspaceMutationCoordinator,
170
- }));
171
- } catch (error) {
172
- handleApiError(req, res, error, '[api] Failed to pull git branch:', 'Failed to pull git branch');
92
+ try {
93
+ const body = route.bodyField ? await parseRequiredBody(req, res, route.bodyField) : {};
94
+ if (!body) {
95
+ return true;
173
96
  }
174
- return true;
175
- }
176
97
 
177
- if (requestUrl.pathname === '/api/git/reset-file' && req.method === 'POST') {
178
- try {
179
- const body = await parseRequiredBody(req, res, 'path');
180
- if (!body) {
181
- return true;
182
- }
183
-
184
- jsonResponse(req, res, 200, await applyWorkspaceMutationEffects({
185
- action: 'reset-file',
186
- req,
187
- responsePayload: await workspaceMutationCoordinator.runManagedWorkspaceMutation(
188
- () => gitService.resetFileToHead(body.path),
189
- ),
190
- workspaceMutationCoordinator,
191
- }));
192
- } catch (error) {
193
- handleApiError(req, res, error, '[api] Failed to reset git file:', 'Failed to reset git file');
194
- }
195
- return true;
98
+ jsonResponse(req, res, 200, await applyWorkspaceMutationEffects({
99
+ action: route.action,
100
+ req,
101
+ responsePayload: await workspaceMutationCoordinator.runManagedWorkspaceMutation(
102
+ () => route.run(body, req),
103
+ ),
104
+ workspaceMutationCoordinator,
105
+ }));
106
+ } catch (error) {
107
+ handleApiError(req, res, error, `[api] ${route.errorMessage}:`, route.errorMessage);
196
108
  }
197
-
198
- return false;
109
+ return true;
199
110
  };
200
111
  }
@@ -107,8 +107,11 @@ export function createHostedApiHandler({
107
107
  membership: await hostedWorkspaceService.acceptInvitation(user),
108
108
  });
109
109
  }],
110
- ['GET /api/hosted/audit', async ({ req, res, user }) => {
111
- jsonResponse(req, res, 200, { events: await hostedWorkspaceService.listAuditEvents(user) });
110
+ ['GET /api/hosted/audit', async ({ req, requestUrl, res, user }) => {
111
+ jsonResponse(req, res, 200, await hostedWorkspaceService.listAuditEvents(user, {
112
+ cursor: requestUrl.searchParams.get('cursor') || '',
113
+ limit: requestUrl.searchParams.get('limit') || 50,
114
+ }));
112
115
  }],
113
116
  ]);
114
117
 
@@ -225,9 +225,9 @@ async function handleBaseExport(req, res, _requestUrl, { baseQueryService }) {
225
225
  }
226
226
  }
227
227
 
228
- async function handleFileTree(req, res, _requestUrl, { vaultFileStore, workspaceMutationCoordinator }) {
228
+ async function handleFileTree(req, res, _requestUrl, { workspaceMutationCoordinator }) {
229
229
  try {
230
- const tree = workspaceMutationCoordinator?.getWorkspaceTree?.() ?? await vaultFileStore.tree();
230
+ const tree = workspaceMutationCoordinator.getWorkspaceTree();
231
231
  jsonResponse(req, res, 200, { tree });
232
232
  } catch (error) {
233
233
  console.error('[api] Failed to read file tree:', error.message);
@@ -3,6 +3,7 @@ import {
3
3
  constants as zlibConstants,
4
4
  gzip,
5
5
  } from 'node:zlib';
6
+ import { pipeline } from 'node:stream/promises';
6
7
 
7
8
  const COMPRESSIBLE_CONTENT_TYPE_PATTERN = /^(?:text\/|application\/(?:javascript|json|xml)|image\/svg\+xml)/i;
8
9
  const MIN_COMPRESSIBLE_BYTES = 1024;
@@ -212,42 +213,7 @@ export function sendStreamResponse(req, res, {
212
213
  return Promise.resolve();
213
214
  }
214
215
 
215
- return new Promise((resolve, reject) => {
216
- let settled = false;
217
-
218
- const finish = (error = null) => {
219
- if (settled) {
220
- return;
221
- }
222
-
223
- settled = true;
224
- res.off('finish', handleFinish);
225
- res.off('error', handleError);
226
- res.off('close', handleClose);
227
- stream.off('error', handleError);
228
-
229
- if (error) {
230
- reject(error);
231
- return;
232
- }
233
-
234
- resolve();
235
- };
236
-
237
- const handleFinish = () => finish();
238
- const handleError = (error) => finish(error);
239
- const handleClose = () => {
240
- if (!res.writableEnded) {
241
- finish(new Error('Response stream closed before completion'));
242
- }
243
- };
244
-
245
- res.on('finish', handleFinish);
246
- res.on('error', handleError);
247
- res.on('close', handleClose);
248
- stream.on('error', handleError);
249
- stream.pipe(res);
250
- });
216
+ return pipeline(stream, res);
251
217
  }
252
218
 
253
219
  export function jsonResponse(req, res, statusCode, data) {
@@ -3,56 +3,21 @@ import { createRequestError } from './http-errors.js';
3
3
  export const REQUEST_BODY_LIMIT_BYTES = 8_388_608;
4
4
 
5
5
  async function readRequestBuffer(req, maxBytes = REQUEST_BODY_LIMIT_BYTES) {
6
- return new Promise((resolve, reject) => {
7
- const chunks = [];
8
- let size = 0;
9
- let done = false;
10
- let limitError = null;
11
-
12
- const finish = (callback, value) => {
13
- if (done) {
14
- return;
15
- }
16
-
17
- done = true;
18
- req.off('data', onData);
19
- req.off('end', onEnd);
20
- req.off('error', onError);
21
- callback(value);
22
- };
23
-
24
- const onData = (chunk) => {
25
- if (limitError) {
26
- return;
27
- }
28
-
29
- size += chunk.length;
30
- if (size > maxBytes) {
31
- chunks.length = 0;
32
- limitError = createRequestError(413, 'Request body too large');
33
- return;
34
- }
35
-
6
+ const chunks = [];
7
+ let size = 0;
8
+ let tooLarge = false;
9
+ for await (const chunk of req) {
10
+ if (tooLarge) continue;
11
+ size += chunk.length;
12
+ if (size > maxBytes) {
13
+ chunks.length = 0;
14
+ tooLarge = true;
15
+ } else {
36
16
  chunks.push(chunk);
37
- };
38
-
39
- const onEnd = () => {
40
- if (limitError) {
41
- finish(reject, limitError);
42
- return;
43
- }
44
-
45
- finish(resolve, Buffer.concat(chunks));
46
- };
47
-
48
- const onError = (error) => {
49
- finish(reject, error);
50
- };
51
-
52
- req.on('data', onData);
53
- req.on('end', onEnd);
54
- req.on('error', onError);
55
- });
17
+ }
18
+ }
19
+ if (tooLarge) throw createRequestError(413, 'Request body too large');
20
+ return Buffer.concat(chunks);
56
21
  }
57
22
 
58
23
  export async function readRequestBody(req, maxBytes = REQUEST_BODY_LIMIT_BYTES) {
@@ -174,6 +174,8 @@ export class HostedMetadataStore {
174
174
  metadata_json TEXT NOT NULL,
175
175
  created_at INTEGER NOT NULL
176
176
  );
177
+ CREATE INDEX IF NOT EXISTS audit_events_created_id_idx
178
+ ON audit_events(created_at DESC, id DESC);
177
179
 
178
180
  CREATE TABLE IF NOT EXISTS operational_security_events (
179
181
  id TEXT PRIMARY KEY,
@@ -514,11 +516,18 @@ export class HostedMetadataStore {
514
516
  );
515
517
  }
516
518
 
517
- async listAuditEvents() {
519
+ async listAuditEvents({ before = null, limit = 51 } = {}) {
520
+ if (before) {
521
+ return this.prepare(
522
+ 'listAuditEventsBefore',
523
+ `SELECT * FROM audit_events WHERE (created_at, id) < (?, ?)
524
+ ORDER BY created_at DESC, id DESC LIMIT ?`,
525
+ ).all(before.createdAt, before.id, limit).map(rowToAuditEvent);
526
+ }
518
527
  return this.prepare(
519
528
  'listAuditEvents',
520
- 'SELECT * FROM audit_events ORDER BY created_at DESC',
521
- ).all().map(rowToAuditEvent);
529
+ 'SELECT * FROM audit_events ORDER BY created_at DESC, id DESC LIMIT ?',
530
+ ).all(limit).map(rowToAuditEvent);
522
531
  }
523
532
 
524
533
  async createOperationalSecurityEvent(event) {
@@ -1,10 +1,10 @@
1
1
  import { lstatSync } from 'node:fs';
2
2
  import { isAbsolute, join, normalize, relative, resolve } from 'path';
3
3
 
4
- import { isVaultFilePath } from '../../../domain/file-kind.js';
4
+ import { getVaultFileKind, isVaultFilePath } from '../../../domain/file-kind.js';
5
5
 
6
6
  export const IGNORED_DIRECTORIES = new Set(['.git', '.obsidian', '.trash', 'node_modules', '.DS_Store']);
7
- export const VAULT_FILE_PATH_REQUIREMENT = '.md, .markdown, .mdx, .html, .htm, .base, .excalidraw, .drawio, .mmd, .mermaid, .puml, .plantuml, .dsl, .pdf, .png, .jpg, .jpeg, .webp, .gif, or .svg';
7
+ export const VAULT_FILE_PATH_REQUIREMENT = '.md, .markdown, .mdx, .html, .htm, .base, .canvas, .excalidraw, .drawio, .mmd, .mermaid, .puml, .plantuml, .dsl, .pdf, .png, .jpg, .jpeg, .webp, .gif, or .svg';
8
8
  export const INVALID_VAULT_FILE_PATH_ERROR = `Invalid file path — must end in ${VAULT_FILE_PATH_REQUIREMENT}`;
9
9
  export const INVALID_DIRECTORY_PATH_ERROR = 'Invalid directory path';
10
10
 
@@ -119,6 +119,12 @@ export function resolveVaultRenamePaths(vaultDir, oldPath, newPath) {
119
119
  };
120
120
  }
121
121
 
122
+ const oldKind = getVaultFileKind(absoluteOld);
123
+ const newKind = getVaultFileKind(absoluteNew);
124
+ if (oldKind !== newKind && [oldKind, newKind].includes('canvas')) {
125
+ return { absoluteNew: null, absoluteOld: null, error: 'Canvas files must keep the .canvas extension' };
126
+ }
127
+
122
128
  return { absoluteNew, absoluteOld, error: null };
123
129
  }
124
130