collabmd 0.1.52 → 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.
- package/bin/collabmd.js +22 -40
- package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-cMeDxAEL.js +1 -0
- package/dist/client/assets/{abnfDiagram-VCTEODGH-DxNxad6-.js → abnfDiagram-VCTEODGH-D2UdmYvj.js} +1 -1
- package/dist/client/assets/{abnfDiagram-O67JEVCF-Dwt6a0Ds.js → abnfDiagram-YUKMZFIV-DbmU4Q-X.js} +1 -1
- package/dist/client/assets/api-client-utils-C5ESDKMG.js +1 -0
- package/dist/client/assets/architecture-7GRP2DOG-BBwRXFv3.js +1 -1
- package/dist/client/assets/architecture-WOLXFQ4H-C0NxYiG7.js +1 -0
- package/dist/client/assets/{architectureDiagram-NJMV4G6O-D5CGiX3G.js → architectureDiagram-47P4ROYG-C7OjXK9S.js} +3 -3
- package/dist/client/assets/{architectureDiagram-5GKGNRK7-C1uvg5id.js → architectureDiagram-5GKGNRK7-CSiUzzeN.js} +1 -1
- package/dist/client/assets/base-CaIEJUF9.css +1 -0
- package/dist/client/assets/{blockDiagram-BEXU5L5S-BgTM0var.js → blockDiagram-E7TT5TSB-DMG-YlZw.js} +3 -3
- package/dist/client/assets/{blockDiagram-I7D4REHJ-B2YonsoG.js → blockDiagram-I7D4REHJ-sXfAgK2w.js} +1 -1
- package/dist/client/assets/{browser-BKLM0ThC-IxjwuOIz-C0mP17s1.js → browser-BKLM0ThC-BCLQGPD6-CcMAHZXi.js} +1 -1
- package/dist/client/assets/{c4Diagram-7LVT6UL2-r4IwomZm.js → c4Diagram-7LVT6UL2-C88V_K-8.js} +1 -1
- package/dist/client/assets/{c4Diagram-YGBWAQC7-_xZPrNkB.js → c4Diagram-CRA5TL53-D3F9ElJv.js} +2 -2
- package/dist/client/assets/canvasEditor-BJkwGzO1.css +1 -0
- package/dist/client/assets/canvasEditor-sBK7KfrD.js +1 -0
- package/dist/client/assets/{chunk-6AZGARVD--pTGpDnx.js → chunk-24IY7LWP-flnn6SWX.js} +1 -1
- package/dist/client/assets/chunk-2BW5OAIV-CNFO1U_e.js +10 -0
- package/dist/client/assets/{chunk-2E4U76K2-CIQUuV9n.js → chunk-2E4U76K2-DEnS5IbF.js} +1 -1
- package/dist/client/assets/{chunk-5V3GS4D5-B5uC2oxu.js → chunk-3M4EKCLJ-D-sZGCtO.js} +1 -1
- package/dist/client/assets/chunk-3YJQHVM4-Ctp__8EK.js +2 -0
- package/dist/client/assets/{chunk-7PRAP22T-9uTvtc_-.js → chunk-4EA7E6EY-bU4wRJot.js} +1 -1
- package/dist/client/assets/{chunk-4HAMMTFA-q0ldNVvr.js → chunk-4HAMMTFA-CQy6Skzw.js} +1 -1
- package/dist/client/assets/{chunk-6K3QC6MW-JnuvEGV4.js → chunk-4S7OKTRW-BpUW13a3.js} +1 -1
- package/dist/client/assets/{chunk-ICYGCRZG-odvlDZyA.js → chunk-53FOQ5SW-5lPdGYP4.js} +1 -1
- package/dist/client/assets/{chunk-75Z2AOVW-DitkSoSG.js → chunk-75Z2AOVW-BRdhvVTZ.js} +1 -1
- package/dist/client/assets/{chunk-GWA4HPMP-CGmv2yIq.js → chunk-7TKQ45FW-rA2u-WUl.js} +1 -1
- package/dist/client/assets/{chunk-GTNCS2PH-ChgkzEIi.js → chunk-AW2ZBBNX-DL0KGAdi.js} +3 -3
- package/dist/client/assets/{chunk-747NJXEK-BjqqAsS9.js → chunk-BP2KR52E-DAQ1pzDV.js} +1 -1
- package/dist/client/assets/{chunk-CLGD4ZFX-BfYJtJm1.js → chunk-CLGD4ZFX-DJiSE0gD.js} +1 -1
- package/dist/client/assets/{chunk-5DYCD2WN-BKWCKnK-.js → chunk-DBDB3WZW-CXleNlok.js} +1 -1
- package/dist/client/assets/{chunk-DU6HZSFF-CWlP1Dk_.js → chunk-DU6HZSFF-C-18UZkS.js} +1 -1
- package/dist/client/assets/{chunk-MBY4JIJT-DTJ4UcAm.js → chunk-E2ZNV5FY-D_07zfWd.js} +3 -3
- package/dist/client/assets/chunk-EU5HNXII-CETVNUXF.js +213 -0
- package/dist/client/assets/{chunk-F27PBJKO-DPcsPcEs.js → chunk-F27PBJKO-_beIJos4.js} +1 -1
- package/dist/client/assets/{chunk-2ZTRR5NV-DcPRfelM.js → chunk-F6S3BTY2-DVWKCAHp.js} +1 -1
- package/dist/client/assets/{chunk-RUX4WMZV-BGnd3s_C.js → chunk-FLFP27SU-CydzbSsY.js} +2 -2
- package/dist/client/assets/chunk-FVRAUYC3-C7b9SJ81.js +1 -0
- package/dist/client/assets/{chunk-GMAD6QVW-Bgk8qnty.js → chunk-GMAD6QVW-DnZH7DxV.js} +1 -1
- package/dist/client/assets/{chunk-GVQU2GXP-CQ8cl-Uu.js → chunk-GVQU2GXP-B0Vm415C.js} +1 -1
- package/dist/client/assets/chunk-H5A3YXKD-ChP7mNJq.js +41 -0
- package/dist/client/assets/{chunk-742MDFTN-D1nh6vNv.js → chunk-HJ2JQQFS-DQX7RePR.js} +1 -1
- package/dist/client/assets/{chunk-NETBCI7D-CmUwDWUZ.js → chunk-HTAEGDNF-C0PA_N-c.js} +1 -1
- package/dist/client/assets/{chunk-IMKFNOWR-CBqxfpcP.js → chunk-IMKFNOWR-DoO8IHzF.js} +1 -1
- package/dist/client/assets/{chunk-IH6LHLGP-BNevEHZK.js → chunk-KPI5JJXK-B2ld5-w4.js} +1 -1
- package/dist/client/assets/{chunk-WEXAMYUT-DDlVNp8J.js → chunk-KQW6MTUR-OQ4MyMr_.js} +1 -1
- package/dist/client/assets/{chunk-L3NEJ4N5-BflzkdTI.js → chunk-L3NEJ4N5-CvHossEU.js} +1 -1
- package/dist/client/assets/chunk-NGNAAXSQ-DqoPQk1a.js +136 -0
- package/dist/client/assets/{chunk-UA2S7LBM-DicYDjDM.js → chunk-NTY3LDVX-CVWLK_fh.js} +1 -1
- package/dist/client/assets/{chunk-UY3FDG6J-QT-rkt0y.js → chunk-OD3NTWWA-Dz9nCUGX.js} +1 -1
- package/dist/client/assets/{chunk-OSK3NFVY-DqeKV_pg.js → chunk-OSK3NFVY-C3JOcBao.js} +1 -1
- package/dist/client/assets/{chunk-P2QGCYS3-BA--DhpW.js → chunk-P2QGCYS3-Bfo8qS8r.js} +1 -1
- package/dist/client/assets/{chunk-POPQ4Y6H-V_NEc45n.js → chunk-POPQ4Y6H-sv6rCftH.js} +1 -1
- package/dist/client/assets/{chunk-PWAF6VOD-D_kLse-N.js → chunk-PWAF6VOD-B-AT-L2H.js} +1 -1
- package/dist/client/assets/{chunk-3Z5EZCMW-BAnA6eQ7.js → chunk-QNH66VMT-Cb9xxTwQ.js} +1 -1
- package/dist/client/assets/{chunk-SHT3W25Y-YM3S-A_M.js → chunk-SHT3W25Y-C1lu518T.js} +1 -1
- package/dist/client/assets/{chunk-GNY47TPC-CTrH5O5R.js → chunk-SVEVUXB4-BnM-LXop.js} +1 -1
- package/dist/client/assets/{chunk-SVP7TREG-DdNhDOmW.js → chunk-SVP7TREG-CKqt0syj.js} +1 -1
- package/dist/client/assets/{chunk-TICWLB2K-BGGgCr4x.js → chunk-TICWLB2K-D2ZnWAfF.js} +1 -1
- package/dist/client/assets/{chunk-TLUHSLCS-DCZhIDYA.js → chunk-TLUHSLCS-BMIhqv1X.js} +1 -1
- package/dist/client/assets/{chunk-6EIED4P4-DBVWq7Tz.js → chunk-TPMEZKFX-DIPHIqGb.js} +1 -1
- package/dist/client/assets/{chunk-6TQVIW2G-BSj0l_pu.js → chunk-VPELOWWC-DXayM28-.js} +1 -1
- package/dist/client/assets/chunk-VPRB5NB3-BqaJfj_v.js +127 -0
- package/dist/client/assets/{chunk-I5DQTOEV-aBZooNp1.js → chunk-VTWWFHGB-SZnJiyWY.js} +1 -1
- package/dist/client/assets/{chunk-KI3K4JFJ-FTtDwx3-.js → chunk-VZTHESGH-eHyXmK8W.js} +1 -1
- package/dist/client/assets/{chunk-7INBJB4K-CDmiHbaX.js → chunk-XC4XBNZT-D9oehSn8.js} +20 -20
- package/dist/client/assets/{chunk-XHIXRSVI-DN_fEwws.js → chunk-YK26KJH5-DVy3MGMd.js} +1 -1
- package/dist/client/assets/{chunk-6AEJRKK7-DTVZj5bY.js → chunk-Z6ETV63D-DOcrnz-P.js} +1 -1
- package/dist/client/assets/{chunk-OUJLGHUK-75UXlPjl.js → chunk-ZO67DCNQ-BAOMIkLF.js} +1 -1
- package/dist/client/assets/classDiagram-ZZMXUADV-BmETdFmC.js +1 -0
- package/dist/client/assets/{classDiagram-v2-NBCMYWYE-3TQORq33.js → classDiagram-v2-K4WV4PDN-eaadfJDB.js} +3 -3
- package/dist/client/assets/classDiagram-v2-VYDZK3BY-BmETdFmC.js +1 -0
- package/dist/client/assets/{comment-markdown-renderer-Bxi_JRSR.js → comment-markdown-renderer-CpBKaj7H.js} +1 -1
- package/dist/client/assets/comment-thread-store-DUQsWtnu.js +1 -0
- package/dist/client/assets/comment-threads-DnfkLVJA.js +4 -0
- package/dist/client/assets/comment-ui-shared-D_pgPUti.js +7 -0
- package/dist/client/assets/cynefin-EF2NZ3EQ-DVkJeZ8i.js +1 -0
- package/dist/client/assets/cynefin-OW5HDTMX-CF3N9j1_.js +1 -1
- package/dist/client/assets/{cynefinDiagram-VND7K2PF-DwfMZ3vk.js → cynefinDiagram-3GCD6N5R-DjpAsBHC.js} +1 -1
- package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-DTnLZaO7.js → cynefinDiagram-5FMLGOSQ-D2rFQG67.js} +1 -1
- package/dist/client/assets/dagre-C-rnJpZF.js +1 -0
- package/dist/client/assets/{dagre-GXQ25YYZ-Vtyx08Qh.js → dagre-GXQ25YYZ-Cku9eia9.js} +2 -2
- package/dist/client/assets/{dagre-6A5THRUB-DewyAGK6.js → dagre-W4DXFKR2-DOMOIsPd.js} +2 -2
- package/dist/client/assets/deferred-collab-C9aa9cvT.css +1 -0
- package/dist/client/assets/deferred-git-BPQ-UgrN.css +1 -0
- package/dist/client/assets/deferred-preview-B-RebLry.css +1 -0
- package/dist/client/assets/{diagram-22UHCM2B-DbZirFfl.js → diagram-2UJZ2QOL-D8WvnEyx.js} +6 -6
- package/dist/client/assets/{diagram-3UASUU5V-DmhdYv6_.js → diagram-OVF4WLC6-D8_escYE.js} +2 -2
- package/dist/client/assets/{diagram-CDSNMT55-D_qyS11R.js → diagram-PFPMY2P6-B1izZfrN.js} +3 -3
- package/dist/client/assets/{diagram-S7CK7UJ4-CGTzfo2f.js → diagram-S7CK7UJ4-BzicH2t-.js} +1 -1
- package/dist/client/assets/{diagram-MLGK6HIB-DIBG6Ivu.js → diagram-UMYRVEAY-Djf7WDjZ.js} +1 -1
- package/dist/client/assets/{diagram-UQ7AKVKN-CWZS8QtB.js → diagram-UQ7AKVKN-DqX4zTtr.js} +1 -1
- package/dist/client/assets/{diagram-VSXAHHWV-DaO1nOZF.js → diagram-VSXAHHWV-DnVbfI4Y.js} +1 -1
- package/dist/client/assets/{diagram-VX7I27RA-B54P6Cyf.js → diagram-VX7I27RA-D-Dj0TQC.js} +1 -1
- package/dist/client/assets/{diagram-MPIPVDR6-D9XsALDV.js → diagram-YEKJPTXX-B40bP3Yr.js} +2 -2
- package/dist/client/assets/{diagram-Z3DM3KII-Cl2EXiXp.js → diagram-Z3DM3KII-_iT7Uz5p.js} +1 -1
- package/dist/client/assets/diagram-ZIFT7M5P-BUUK0oNw.js +3 -0
- package/dist/client/assets/{direct-engine-DdrQKpgq-4QysbH_V.js → direct-engine-DVLMOJWp-DWtWIifK.js} +1 -1
- package/dist/client/assets/dist-26Ce-5t4.js +1 -0
- package/dist/client/assets/dist-8MLNn-I6.js +1 -0
- package/dist/client/assets/dist-Amm5Pr1C.js +1 -0
- package/dist/client/assets/dist-BXXPaoUV.js +1 -0
- package/dist/client/assets/{dist-zHDLm1oE.js → dist-Bkb-_VdB.js} +1 -1
- package/dist/client/assets/dist-Bl4yuUS9.js +1 -0
- package/dist/client/assets/{dist-CKf7LlAo.js → dist-C2CGvCPd.js} +1 -1
- package/dist/client/assets/dist-C2niyEh0.js +1 -0
- package/dist/client/assets/{dist-Y6zYRI-A.js → dist-CFCSUmJk.js} +1 -1
- package/dist/client/assets/dist-CHUI56fT.js +6 -0
- package/dist/client/assets/dist-CJh3Qrid.js +13 -0
- package/dist/client/assets/{dist-Ch6Sr9KF.js → dist-CKxETpSC.js} +3 -3
- package/dist/client/assets/dist-CSHJthAI.js +2 -0
- package/dist/client/assets/dist-CbKnZGN4.js +1 -0
- package/dist/client/assets/{dist-BVCNc-Es.js → dist-Cik4RJXj.js} +1 -1
- package/dist/client/assets/{dist-DGa-2MNX.js → dist-CqkAY6Ot.js} +2 -2
- package/dist/client/assets/dist-D2ql2LCd.js +1 -0
- package/dist/client/assets/{dist-CvVoyTRF.js → dist-D47MOYFN.js} +1 -1
- package/dist/client/assets/dist-DBhUaexM.js +1 -0
- package/dist/client/assets/dist-DJux6Vc5.js +1 -0
- package/dist/client/assets/{dist-CXOUa90Q.js → dist-DLNdMWPH.js} +1 -1
- package/dist/client/assets/dist-DPJj-Y3l.js +1 -0
- package/dist/client/assets/{dist-DI6c02Da.js → dist-DRYFMufe.js} +6 -6
- package/dist/client/assets/{dist-CUsXdnU4.js → dist-DTGcVSU8.js} +1 -1
- package/dist/client/assets/dist-DlOxjzWi.js +9 -0
- package/dist/client/assets/{dist-BfpAc922.js → dist-DogjjM_B.js} +1 -1
- package/dist/client/assets/dist-Dyv_RvyB.js +23 -0
- package/dist/client/assets/dist-FUFeH5Cx.js +1 -0
- package/dist/client/assets/dist-It70ktCU.js +1 -0
- package/dist/client/assets/dist-QMvcnJHf.js +1 -0
- package/dist/client/assets/dist-QN1K2czv.js +11 -0
- package/dist/client/assets/dist-W8ilOKl3.js +1 -0
- package/dist/client/assets/dist-_17-t9qP.js +1 -0
- package/dist/client/assets/{dist-CsQTfQFi.js → dist-uE774WWs.js} +1 -1
- package/dist/client/assets/document-formatter-DtXmKZcy.js +1 -0
- package/dist/client/assets/drawioEditor-DO6IOaJ1.js +9 -0
- package/dist/client/assets/{ebnfDiagram-PWID7BFC-PfC84FyI.js → ebnfDiagram-PWID7BFC-IemGPf9X.js} +1 -1
- package/dist/client/assets/{ebnfDiagram-ZINNZB2B-DYvm_QtE.js → ebnfDiagram-VR2GEFS7-9fXqy1DI.js} +1 -1
- package/dist/client/assets/editor-session-CPsqXY_A.js +13 -0
- package/dist/client/assets/elk-IJKZMXRS-DsbrbBYg.js +27 -0
- package/dist/client/assets/embedded-editor-base-C44ZcCZv.css +1 -0
- package/dist/client/assets/{embedpdf-DyOonRvx.js → embedpdf-BfUI-3pv.js} +1 -1
- package/dist/client/assets/{embedpdf-DA4bA119-DsoNiPlQ.js → embedpdf-cl9qiF45-CLMxJTMP.js} +3 -3
- package/dist/client/assets/en-7ZVUCEYH-C_VXKxxb.js +1 -0
- package/dist/client/assets/{erDiagram-OPXOYQCR-o8GRv8A_.js → erDiagram-O2IAPWRE-Cdadm-HN.js} +2 -2
- package/dist/client/assets/{erDiagram-RLTQ6QDP-C9cJl5NB.js → erDiagram-RLTQ6QDP-CGGmjm8t.js} +1 -1
- package/dist/client/assets/{estree-DCT3Jm65.js → estree-DGmLqopC.js} +17 -17
- package/dist/client/assets/eventmodeling-K75KTNOO-BWBlZ5cR.js +1 -0
- package/dist/client/assets/eventmodeling-NTZA5JFV-CDy1bN6j.js +1 -1
- package/dist/client/assets/excalidraw-element-link-NQnskRkm.js +1 -0
- package/dist/client/assets/excalidraw-scene-DLlw4jyc.js +1 -0
- package/dist/client/assets/excalidrawEditor-DiKOIudt.css +1 -0
- package/dist/client/assets/excalidrawEditor-W2lZ5Mej.js +9 -0
- package/dist/client/assets/export-page-Bomh9oEr.js +46 -0
- package/dist/client/assets/exportDocument-BFIOECJ3.js +2 -0
- package/dist/client/assets/exportDocument-D0mONgQ4.css +1 -0
- package/dist/client/assets/file-kind-BGxTVHan.js +1 -0
- package/dist/client/assets/{file-search-3hYF4cYa.js → file-search-Dk2O14Vw.js} +1 -1
- package/dist/client/assets/flowDiagram-HODETNUW-DcVVYJUZ.js +1 -0
- package/dist/client/assets/flowDiagram-OXPTDLAJ-Dy6y46oF.js +1 -0
- package/dist/client/assets/{ganttDiagram-EL5Y4UJY-x40PW0Ah.js → ganttDiagram-EL5Y4UJY-Duu4KnsU.js} +1 -1
- package/dist/client/assets/ganttDiagram-R7TSEDQI-BWy52pjn.js +292 -0
- package/dist/client/assets/gitGraph-4MIJSDKK-B-rpDYbz.js +1 -1
- package/dist/client/assets/gitGraph-VSP46ZUC-1499lQAI.js +1 -0
- package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-ahsNaZsp.js → gitGraphDiagram-WWUBYQGX-CaJ0vC1a.js} +1 -1
- package/dist/client/assets/gitGraphDiagram-XJZIOB7I-DJwp9ilx.js +106 -0
- package/dist/client/assets/graphlib-DS17s2tU.js +1 -0
- package/dist/client/assets/{html-CBXMuS97.js → html-BryNQ_yx.js} +6 -6
- package/dist/client/assets/image-6XY3GD3F-DCWbu6d4.js +1 -0
- package/dist/client/assets/image-lightbox-controller-DAcXEXxT.js +184 -0
- package/dist/client/assets/index-CglpXOg7.css +1 -0
- package/dist/client/assets/index-D3WGkxfI.js +960 -0
- package/dist/client/assets/info-A6RAGUB7-BlutK7BT.js +1 -1
- package/dist/client/assets/info-OHQRW6UA-BDFQOo4H.js +1 -0
- package/dist/client/assets/{infoDiagram-27XIBGKW-MrZyptIy.js → infoDiagram-27XIBGKW-DBJh7QOu.js} +1 -1
- package/dist/client/assets/{infoDiagram-VRGFBTTK-KkUjDRAQ.js → infoDiagram-5W2HQ5XZ-DmWsqJ0w.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-5VMMS53U-Bnt9yM0O.js → ishikawaDiagram-5VMMS53U-CeEbSJem.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-OU5B5YK6-Di9BcpOY.js → ishikawaDiagram-K3B6WC7H-DH1NI35G.js} +2 -2
- package/dist/client/assets/{journeyDiagram-3NMN7TZE-Bl0abK1r.js → journeyDiagram-3NMN7TZE-BoIEEr6U.js} +1 -1
- package/dist/client/assets/{journeyDiagram-ZHPQQLJL-J-sGrs9e.js → journeyDiagram-COXZFDF6-CnHV2f9V.js} +3 -3
- package/dist/client/assets/{kanban-definition-PNTS6WVX-5ZDV_yIa.js → kanban-definition-P3RFRI5V-Cxvn5ZAG.js} +4 -4
- package/dist/client/assets/{kanban-definition-UXKFOSKX-DMgUfNt0.js → kanban-definition-UXKFOSKX-BY16Tgbr.js} +1 -1
- package/dist/client/assets/keyboard-shortcuts-BWNCBJqw.js +1 -0
- package/dist/client/assets/lobby-presence-DNNXcuwR.js +1 -0
- package/dist/client/assets/{markdown-Bo71X2X2.js → markdown-DU84620G.js} +17 -17
- package/dist/client/assets/markdown-headings-zYEUahfW.js +41 -0
- package/dist/client/assets/{markdown-math-CyyBVuDO.js → markdown-math-B96cnrz1.js} +11 -11
- package/dist/client/assets/{mermaid-parser.core-Bpogunsh.js → mermaid-parser.core-R-uwU5kf.js} +3 -3
- package/dist/client/assets/{mermaid-parser.core-DBy--Jc0.js → mermaid-parser.core-mE6t1qEO.js} +1 -1
- package/dist/client/assets/mermaid.core-D8Z6LN7O.js +10 -0
- package/dist/client/assets/{mindmap-definition-NLK3R4M7-ByVb-0vj.js → mindmap-definition-LZFPQGKD-DVfFenfJ.js} +3 -3
- package/dist/client/assets/{mindmap-definition-YA3MSWOX-DBZN5_GH.js → mindmap-definition-YA3MSWOX-DtiE80UJ.js} +1 -1
- package/dist/client/assets/packet-AYTQ26CC-DvbY8dI6.js +1 -1
- package/dist/client/assets/packet-JDAUHWVQ-DJ9K2MA4.js +1 -0
- package/dist/client/assets/{pdfium-RAgkpwfK.wasm → pdfium-BJ2Yip8Q.wasm} +0 -0
- package/dist/client/assets/{pegDiagram-GJSIUBJH-aost1sSO.js → pegDiagram-BGZESJAR-DxfvEcwv.js} +1 -1
- package/dist/client/assets/{pegDiagram-XKGWAZYB-DRo8CZu3.js → pegDiagram-XKGWAZYB-CyozY-Kt.js} +1 -1
- package/dist/client/assets/pie-WAS4IAKB-DWSm9SSD.js +1 -1
- package/dist/client/assets/pie-XZMESJXO-CQIQasY-.js +1 -0
- package/dist/client/assets/{pieDiagram-5QR66LMP-BICdpEuz.js → pieDiagram-CAPJLFHJ-CRlMcrv3.js} +2 -2
- package/dist/client/assets/{pieDiagram-E7YTZNPT-CZThaHsc.js → pieDiagram-E7YTZNPT-BRdmTkDq.js} +1 -1
- package/dist/client/assets/preload-helper-CYtfOYgs.js +1 -0
- package/dist/client/assets/preview-render-compiler-D_aJv7Ew.js +3 -0
- package/dist/client/assets/{preview-render-worker-BI2bFVqM.js → preview-render-worker-dFNyrVyB.js} +47 -43
- package/dist/client/assets/prod-ItolaHmf.js +145 -0
- package/dist/client/assets/prod-rdly4JJQ.js +1 -0
- package/dist/client/assets/{quadrantDiagram-AXDQQJYC-C5iowkl_.js → quadrantDiagram-AXDQQJYC-7QyPIXkF.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-O4NWA36T-Bgx5bF97.js → quadrantDiagram-GDMTTRAM-DE30uqTl.js} +3 -3
- package/dist/client/assets/quick-switcher-controller-DsK70I7K.js +1 -0
- package/dist/client/assets/radar-ABXABTNO-ByfpCXh9.js +1 -0
- package/dist/client/assets/radar-RG4KPBEZ-BfNQUEQy.js +1 -1
- package/dist/client/assets/railroad-74A4TZTK-BaQ6U6eJ.js +1 -1
- package/dist/client/assets/railroad-I3PHUGI6-CTUn9HhI.js +1 -0
- package/dist/client/assets/railroad-abnf-HS5TGJTU-BJ3KZw7J.js +1 -1
- package/dist/client/assets/railroad-abnf-LNEFI6M7-Ct-b-y0F.js +1 -0
- package/dist/client/assets/railroad-ebnf-DWYD2UWJ-BZMYMWOe.js +1 -0
- package/dist/client/assets/railroad-ebnf-LZEXJU2U-DA0sEq7w.js +1 -1
- package/dist/client/assets/railroad-peg-JR7BVNR7-Dj23PxYc.js +1 -0
- package/dist/client/assets/railroad-peg-WCYAUIDC-DCmlICzO.js +1 -1
- package/dist/client/assets/{railroadDiagram-O6MQD6OU-BTt_rKjT.js → railroadDiagram-O6MQD6OU-BPk3RS2D.js} +1 -1
- package/dist/client/assets/{railroadDiagram-XR7U4H2S-DbVoNgSz.js → railroadDiagram-SM67HX2B-CZRXJ647.js} +1 -1
- package/dist/client/assets/{requirementDiagram-BXWQKSXE-BkvazG7r.js → requirementDiagram-BXWQKSXE-BRwfym6z.js} +1 -1
- package/dist/client/assets/{requirementDiagram-PLB6GJNP-BT0j9C40.js → requirementDiagram-X7JNWC4A-BofCuLJA.js} +4 -4
- package/dist/client/assets/runtime-config-CvrkHb0n.js +1 -0
- package/dist/client/assets/runtime-paths-qQGhzNx4.js +1 -0
- package/dist/client/assets/{sankeyDiagram-P5KCCOFB-C_IemB9h.js → sankeyDiagram-P5KCCOFB-D4LcrKpW.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-IPEJSGJF-X1BCUIrf.js → sankeyDiagram-UM26HJRW-CLKMDbej.js} +3 -3
- package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-CxFBgLGd.js → sequenceDiagram-WJ2MYXX4-DQjtv-Bs.js} +1 -1
- package/dist/client/assets/sequenceDiagram-ZO4K6R2Y-CDP_m6ma.js +169 -0
- package/dist/client/assets/sizeCapture-INFHLROL-3uHXrFqA.js +1 -0
- package/dist/client/assets/sizeCapture-INFHLROL-BMR1ovSU.js +1 -0
- package/dist/client/assets/src-D5mvpivG.js +2 -0
- package/dist/client/assets/{standalone-6z5x8CWe.js → standalone-D_lg5NC9.js} +1 -1
- package/dist/client/assets/{stateDiagram-D77RDMKH-BaSQ6Owj.js → stateDiagram-D77RDMKH-DSMvV-kF.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-MP3YSRHH-ClmOOUsT.js +1 -0
- package/dist/client/assets/{stateDiagram-v2-GCMORJYK-CsVcfwVp.js → stateDiagram-v2-TBUQTH76-Dc5-FKzd.js} +2 -2
- package/dist/client/assets/{swimlanes-42K2YHIH-CALFEmiS.js → swimlanes-42K2YHIH-BUz31lO3.js} +1 -1
- package/dist/client/assets/{swimlanes-2SLR337P-CnYTVqRX.js → swimlanes-N4OXWK64-Dd3dFdPD.js} +1 -1
- package/dist/client/assets/swimlanesDiagram-K3J5GTZL-Bz9gFdls.js +8 -0
- package/dist/client/assets/swimlanesDiagram-VR7AAH4N-DoDs3zod.js +8 -0
- package/dist/client/assets/{timeline-definition-24CTP7MA-zse-5Dbm.js → timeline-definition-24CTP7MA-BvqCvSjy.js} +1 -1
- package/dist/client/assets/{timeline-definition-EJHVYXUP-BhqPlKkN.js → timeline-definition-YOQAKGHF-D2XWPSLs.js} +3 -3
- package/dist/client/assets/treeView-D4JQ5SDB-DcX7Bx0H.js +1 -0
- package/dist/client/assets/treeView-Q6P3EWNA-BvHOzbu9.js +1 -1
- package/dist/client/assets/treemap-SAJKECNS-BcCHmcAX.js +1 -0
- package/dist/client/assets/treemap-WGGIJYW6-oety7paS.js +1 -1
- package/dist/client/assets/usecaseDiagram-VIAY4XPW-CDe-IMjS.js +328 -0
- package/dist/client/assets/vault-api-client-DrRW0QwO.js +7 -0
- package/dist/client/assets/{vennDiagram-4TSXK5OY-DgHr6cJD.js → vennDiagram-4TSXK5OY-BW6Qp12d.js} +1 -1
- package/dist/client/assets/{vennDiagram-UO4OBE2U-BRwLn2Q1.js → vennDiagram-BLWOH2XV-KxIPKpHi.js} +3 -3
- package/dist/client/assets/wardley-7MLQ67FV-DOahSwbZ.js +1 -0
- package/dist/client/assets/wardley-WFR3VGLG-BdwDpX_I.js +1 -1
- package/dist/client/assets/{wardleyDiagram-VM6X3IG4-9A60XZis.js → wardleyDiagram-VM6X3IG4-BoCETVsK.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-VNRHLVJA-B_tMcVFG.js → wardleyDiagram-YMQ3BMBF-BNYqEy7M.js} +4 -4
- package/dist/client/assets/{wiki-link-resolver-Dch88erO.js → wiki-link-resolver-BCdGUpdu.js} +1 -1
- package/dist/client/assets/{worker-engine-m0rlHn8R-5h66k403.js → worker-engine-BCCrxWYm-1fphds7O.js} +1 -1
- package/dist/client/assets/workspace-sync-client-C_P9wtjf.js +1 -0
- package/dist/client/assets/{xychartDiagram-S5SC5T6Z-D00iy-wB.js → xychartDiagram-S5SC5T6Z-eB5Fu9P7.js} +1 -1
- package/dist/client/assets/xychartDiagram-TAQBALBS-Sv6aaptV.js +7 -0
- package/dist/client/assets/yjs-Jd9fna_Y.js +4 -0
- package/dist/client/assets/yjs-provider-reset-guard-Cqu0Z6xH.js +1 -0
- package/dist/client/canvas-editor.html +16 -0
- package/dist/client/drawio-editor.html +9 -8
- package/dist/client/excalidraw-editor.html +33 -32
- package/dist/client/export-document.html +4 -3
- package/dist/client/index.html +13 -2
- package/package.json +31 -33
- package/scripts/local-compose.mjs +101 -0
- package/src/client/app/canvas-editor.html +13 -0
- package/src/client/app/index.html +11 -0
- package/src/client/app/main-entry.js +30 -4
- package/src/client/application/app-shell/git-feature.js +3 -2
- package/src/client/application/app-shell/ui-feature-identity.js +1 -0
- package/src/client/application/app-shell/ui-feature-shell.js +2 -0
- package/src/client/application/app-shell/ui-feature-tab-activity.js +4 -0
- package/src/client/application/app-shell/workspace-feature.js +8 -34
- package/src/client/application/diagram-chrome.js +8 -11
- package/src/client/application/diagram-preview-hydrator.js +5 -5
- package/src/client/application/mermaid-preview-hydrator.js +3 -2
- package/src/client/application/plantuml-preview-hydrator.js +6 -0
- package/src/client/application/preview-render-compiler.js +34 -98
- package/src/client/application/preview-render-executor.js +3 -0
- package/src/client/application/preview-render-worker.js +2 -0
- package/src/client/application/preview-renderer.js +9 -5
- package/src/client/application/workspace-coordinator.js +18 -10
- package/src/client/application/workspace-preview-controller.js +105 -158
- package/src/client/application/workspace-route-controller.js +29 -54
- package/src/client/bootstrap/canvas-markdown-preview.js +87 -0
- package/src/client/bootstrap/collabmd-app-shell.js +31 -14
- package/src/client/browser-utils.js +21 -0
- package/src/client/canvas-editor.js +143 -0
- package/src/client/domain/canvas-view.js +50 -0
- package/src/client/domain/excalidraw-scene.js +4 -49
- package/src/client/domain/file-search.js +1 -1
- package/src/client/domain/highlight-runtime.js +0 -4
- package/src/client/domain/markdown-formatting.js +12 -94
- package/src/client/domain/markdown-headings.js +98 -0
- package/src/client/domain/runtime-paths.js +4 -0
- package/src/client/domain/wiki-link-completions.js +42 -10
- package/src/client/infrastructure/browser-preferences-port.js +27 -33
- package/src/client/infrastructure/canvas-room-client.js +210 -0
- package/src/client/infrastructure/canvas-text-editor.js +36 -0
- package/src/client/infrastructure/comment-thread-store.js +19 -77
- package/src/client/infrastructure/editor-view-adapter.js +0 -30
- package/src/client/infrastructure/excalidraw-room-client.js +22 -10
- package/src/client/infrastructure/hosted-api-client.js +4 -2
- package/src/client/infrastructure/runtime-config.js +14 -0
- package/src/client/infrastructure/vault-api-client.js +4 -4
- package/src/client/presentation/canvas-editor-view.js +1028 -0
- package/src/client/presentation/canvas-embed-controller.js +116 -0
- package/src/client/presentation/canvas-picker.js +111 -0
- package/src/client/presentation/drawio-embed-controller.js +4 -4
- package/src/client/presentation/excalidraw-embed-controller.js +13 -4
- package/src/client/presentation/file-action-controller.js +58 -1
- package/src/client/presentation/file-explorer-controller.js +1 -2
- package/src/client/presentation/file-explorer-view.js +31 -7
- package/src/client/presentation/file-icon-svg.js +1 -1
- package/src/client/presentation/file-tree-state.js +4 -1
- package/src/client/presentation/image-lightbox-controller.js +1 -5
- package/src/client/presentation/team-settings-controller.js +44 -10
- package/src/client/presentation/vault-dashboard.js +63 -0
- package/src/client/styles/components/actions.css +4 -16
- package/src/client/styles/components/surfaces.css +0 -7
- package/src/client/styles/features/comment-card.css +1 -2
- package/src/client/styles/features/comment-markdown.css +0 -18
- package/src/client/styles/features/diagram-preview.css +0 -18
- package/src/client/styles/features/git-branch.css +0 -4
- package/src/client/styles/foundation/themes.css +6 -0
- package/src/client/styles/foundation/utilities.css +3 -2
- package/src/client/styles/layout/editor-page.css +0 -13
- package/src/client/styles/layout/overlays.css +5 -0
- package/src/client/styles/layout/responsive.css +2 -7
- package/src/client/styles/layout/shell.css +165 -1
- package/src/client/styles/layout/view-modes.css +1 -0
- package/src/client/styles/surfaces/canvas-editor.css +239 -0
- package/src/domain/canvas-room-codec.js +359 -0
- package/src/domain/collabmd-content-capabilities.js +10 -1
- package/src/domain/comment-threads.js +49 -5
- package/src/domain/excalidraw-room-codec.js +23 -73
- package/src/domain/excalidraw-scene.js +48 -0
- package/src/domain/file-kind.js +13 -1
- package/src/server/application/workspace-reconciliation.js +0 -14
- package/src/server/config/env.js +39 -6
- package/src/server/domain/backlink-index.js +1 -36
- package/src/server/domain/bases/base-index-snapshot-store.js +41 -24
- package/src/server/domain/bases/base-query-service.js +1 -47
- package/src/server/domain/collaboration/collaboration-room.js +149 -15
- package/src/server/domain/collaboration/room-registry.js +7 -7
- package/src/server/domain/hosted-workspace.js +29 -2
- package/src/server/domain/plantuml-encoder.js +7 -43
- package/src/server/infrastructure/git/diff-service.js +1 -5
- package/src/server/infrastructure/git/history-service.js +18 -2
- package/src/server/infrastructure/git/untracked-files.js +1 -1
- package/src/server/infrastructure/http/create-git-api-command-handler.js +60 -149
- package/src/server/infrastructure/http/create-hosted-api-handler.js +5 -2
- package/src/server/infrastructure/http/create-static-handler.js +3 -1
- package/src/server/infrastructure/http/create-vault-api-query-handler.js +3 -3
- package/src/server/infrastructure/http/http-response.js +2 -36
- package/src/server/infrastructure/http/request-body.js +14 -49
- package/src/server/infrastructure/persistence/hosted-metadata-store.js +12 -3
- package/src/server/infrastructure/persistence/path-utils.js +8 -2
- package/src/server/infrastructure/persistence/vault-file-store.js +26 -60
- package/src/server/{infrastructure/git → shared}/image-mime.js +2 -2
- package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-BEz2BKN1.js +0 -1
- package/dist/client/assets/_basePickBy-QJXUw_pr.js +0 -1
- package/dist/client/assets/_baseUniq-DR4vVjyC.js +0 -1
- package/dist/client/assets/architecture-7GRP2DOG-DJVtYNt-.js +0 -1
- package/dist/client/assets/browser-utils-vlHL9goC.js +0 -1
- package/dist/client/assets/chunk-3FUC2YCW-8tZlhTGX.js +0 -1
- package/dist/client/assets/chunk-4SOEAONT-C3fufoVl.js +0 -40
- package/dist/client/assets/chunk-7M6MHVWA-BDakkknV.js +0 -213
- package/dist/client/assets/chunk-FOHPRMQF-Dmmo5Kak.js +0 -161
- package/dist/client/assets/chunk-O7XYJQB3-D0_ZY2za.js +0 -126
- package/dist/client/assets/chunk-Z7XXMR3K-P4Vaq8hD.js +0 -10
- package/dist/client/assets/chunk-ZIGJFQKS-b8OUHKK5.js +0 -2
- package/dist/client/assets/classDiagram-ZZMXUADV-QLbh_Nkf.js +0 -1
- package/dist/client/assets/classDiagram-v2-VYDZK3BY-QLbh_Nkf.js +0 -1
- package/dist/client/assets/comment-thread-store-CHvy8GF8.js +0 -1
- package/dist/client/assets/comment-threads-nJhK1yfc.js +0 -4
- package/dist/client/assets/cynefin-OW5HDTMX-e-Quc9Yl.js +0 -1
- package/dist/client/assets/dagre-D7FiCLLP.js +0 -1
- package/dist/client/assets/deferred-collab-D4cxEdad.css +0 -1
- package/dist/client/assets/deferred-git-BHKtkFYi.css +0 -1
- package/dist/client/assets/deferred-preview-BAXYgf4T.css +0 -1
- package/dist/client/assets/diagram-ATOU4E4O-B5uX-jVO.js +0 -3
- package/dist/client/assets/dist-B7fBbwrO.js +0 -1
- package/dist/client/assets/dist-BYBF4LtZ.js +0 -1
- package/dist/client/assets/dist-B_1hMrc6.js +0 -1
- package/dist/client/assets/dist-BnVaoRgZ.js +0 -1
- package/dist/client/assets/dist-Bog8M5U3.js +0 -13
- package/dist/client/assets/dist-CAG5sIOj.js +0 -1
- package/dist/client/assets/dist-CYMCikZo.js +0 -1
- package/dist/client/assets/dist-CYfPeupF.js +0 -1
- package/dist/client/assets/dist-Ck-B8onw.js +0 -2
- package/dist/client/assets/dist-CrkYYcOU.js +0 -1
- package/dist/client/assets/dist-Cu5Ze2cs.js +0 -6
- package/dist/client/assets/dist-D4kDR0g8.js +0 -1
- package/dist/client/assets/dist-D8LnhZzy.js +0 -1
- package/dist/client/assets/dist-DNONgI1P.js +0 -11
- package/dist/client/assets/dist-DVBYH83t.js +0 -1
- package/dist/client/assets/dist-DX6qtdxv.js +0 -1
- package/dist/client/assets/dist-Da-jLrCf.js +0 -1
- package/dist/client/assets/dist-DofvCYzJ.js +0 -1
- package/dist/client/assets/dist-Dx37MHWs.js +0 -1
- package/dist/client/assets/dist-GTGhtpyW.js +0 -9
- package/dist/client/assets/dist-W0FoeIxk.js +0 -23
- package/dist/client/assets/dist-jVKfryIL.js +0 -1
- package/dist/client/assets/document-formatter-gO8qM2qY.js +0 -1
- package/dist/client/assets/drawioEditor-DCkWweiy.js +0 -9
- package/dist/client/assets/editor-session-DxRyr4EM.js +0 -14
- package/dist/client/assets/elk-276RUBZZ-B8LB3Pac.js +0 -27
- package/dist/client/assets/embedded-editor-base-elU0Avik.css +0 -1
- package/dist/client/assets/en-GNC3RJIS-CEy_oGTd.js +0 -1
- package/dist/client/assets/eventmodeling-NTZA5JFV-Dxtv5D-P.js +0 -1
- package/dist/client/assets/excalidraw-element-link-CGZ5934B.js +0 -7
- package/dist/client/assets/excalidraw-scene-6uROebca.js +0 -1
- package/dist/client/assets/excalidrawEditor-BCTFp_CV.css +0 -1
- package/dist/client/assets/excalidrawEditor-BVfSxjSO.js +0 -9
- package/dist/client/assets/export-page-BCo_e15t.js +0 -46
- package/dist/client/assets/exportDocument-Ba-n1X4U.css +0 -1
- package/dist/client/assets/exportDocument-DP6oE_or.js +0 -2
- package/dist/client/assets/file-kind-BwMIcZbi.js +0 -1
- package/dist/client/assets/flowDiagram-HODETNUW-Bq4470NR.js +0 -1
- package/dist/client/assets/flowDiagram-KWPJA3E3-DQG9qGiU.js +0 -1
- package/dist/client/assets/ganttDiagram-FUAMR5RP-BQpsI7gQ.js +0 -292
- package/dist/client/assets/gitGraph-4MIJSDKK-ZaBIE4Lb.js +0 -1
- package/dist/client/assets/gitGraphDiagram-X574FWY7-wbs_2m9f.js +0 -106
- package/dist/client/assets/graphlib-C9Tl7QrK.js +0 -1
- package/dist/client/assets/image-EJJKRVD3-BQfi5nWJ.js +0 -1
- package/dist/client/assets/index-BxAuGDoN.css +0 -1
- package/dist/client/assets/index-uw9O0z1c.js +0 -1112
- package/dist/client/assets/info-A6RAGUB7-BcGxhjED.js +0 -1
- package/dist/client/assets/lobby-presence-Cz5jGOPg.js +0 -1
- package/dist/client/assets/mermaid.core-BeOUPE3Q.js +0 -10
- package/dist/client/assets/packet-AYTQ26CC-CqpSjTWl.js +0 -1
- package/dist/client/assets/pie-WAS4IAKB-Bg2eCNl5.js +0 -1
- package/dist/client/assets/preload-helper-BAlEavIC.js +0 -1
- package/dist/client/assets/preview-render-compiler-ktU0SXxY.js +0 -43
- package/dist/client/assets/prod-DU-0VfI7.js +0 -145
- package/dist/client/assets/prod-cXUNdmYV.js +0 -1
- package/dist/client/assets/quick-switcher-controller-DSlOwOsU.js +0 -1
- package/dist/client/assets/radar-RG4KPBEZ-DxExotg6.js +0 -1
- package/dist/client/assets/railroad-74A4TZTK-FfHmeIQk.js +0 -1
- package/dist/client/assets/railroad-abnf-HS5TGJTU-CLkdDRsJ.js +0 -1
- package/dist/client/assets/railroad-ebnf-LZEXJU2U-B162zvcG.js +0 -1
- package/dist/client/assets/railroad-peg-WCYAUIDC-CGs5GeJ5.js +0 -1
- package/dist/client/assets/runtime-config-BFVdhnJu.js +0 -1
- package/dist/client/assets/runtime-paths-Cn0snt_9.js +0 -1
- package/dist/client/assets/sequenceDiagram-PO4LG4MO-B-2QfXhV.js +0 -169
- package/dist/client/assets/sizeCapture-INFHLROL-B0uUizjq.js +0 -1
- package/dist/client/assets/sizeCapture-INFHLROL-DrzwYt5z.js +0 -1
- package/dist/client/assets/stateDiagram-v2-MP3YSRHH-CLlwrdvU.js +0 -1
- package/dist/client/assets/swimlanesDiagram-TC7HE7FX-Bh4tmz27.js +0 -8
- package/dist/client/assets/swimlanesDiagram-VR7AAH4N-xhehUG9e.js +0 -8
- package/dist/client/assets/treeView-Q6P3EWNA-Cccy0ngL.js +0 -1
- package/dist/client/assets/treemap-WGGIJYW6-sMRCjCtX.js +0 -1
- package/dist/client/assets/usecaseDiagram-POWQR4AR-DR2LHQYs.js +0 -328
- package/dist/client/assets/vault-api-client-BQxLVPeF.js +0 -7
- package/dist/client/assets/wardley-WFR3VGLG-Y7xty_3m.js +0 -1
- package/dist/client/assets/workspace-sync-client-C2pdaQUN.js +0 -1
- package/dist/client/assets/xychartDiagram-PMCCYNJV-fRpZ1MA5.js +0 -7
- package/dist/client/assets/yjs-B41tM6Sz.js +0 -4
- package/dist/client/assets/yjs-provider-reset-guard-DpntzUDR.js +0 -1
- package/scripts/local-plantuml-compose.mjs +0 -92
- package/scripts/local-structurizr-compose.mjs +0 -101
|
@@ -0,0 +1,960 @@
|
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./deferred-collab-C9aa9cvT.css","./deferred-git-BPQ-UgrN.css","./quick-switcher-De4PjZFC.css"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{i as e,r as t,t as n}from"./room-DX7lIfnu.js";import{_ as r,a as i,b as a,c as o,d as s,f as c,g as l,h as u,i as d,l as f,m as p,n as m,o as h,p as g,r as _,s as v,t as y,u as b,v as x,y as S}from"./file-kind-BGxTVHan.js";import{n as ee}from"./wiki-link-resolver-BCdGUpdu.js";import{a as te,c as ne,d as C,f as w,i as re,l as ie,n as ae,o as oe,p as T,r as E,s as se,t as ce,u as D}from"./vault-api-client-DrRW0QwO.js";import{c as le,i as ue,l as de,n as O,r as fe,t as pe}from"./api-client-utils-C5ESDKMG.js";import{a as me,c as he,d as k,f as ge,g as _e,h as ve,i as ye,l as be,m as xe,n as Se,o as Ce,p as we,s as Te,t as Ee,u as De}from"./image-lightbox-controller-DAcXEXxT.js";import{t as A}from"./preload-helper-CYtfOYgs.js";import{n as Oe,r as j,t as M}from"./vault-utils-Bct69Xw2.js";import{r as ke,t as Ae}from"./preview-render-profile-D652PAjA.js";import{a as je,c as Me,i as Ne,r as N,s as Pe,t as P}from"./runtime-paths-qQGhzNx4.js";import{a as Fe,c as Ie,f as Le,i as Re,l as ze,n as Be,o as Ve,p as He,r as Ue,s as We,t as Ge,u as Ke}from"./runtime-config-CvrkHb0n.js";import{r as qe}from"./file-search-Dk2O14Vw.js";import{t as Je}from"./keyboard-shortcuts-BWNCBJqw.js";import{n as Ye}from"./excalidraw-scene-DLlw4jyc.js";import{t as Xe}from"./comment-threads-DnfkLVJA.js";import{C as Ze,S as Qe,T as $e,_ as et,a as tt,b as nt,c as rt,d as it,f as at,g as ot,h as st,i as ct,l as lt,n as ut,o as dt,p as ft,r as pt,s as mt,t as ht,u as gt,v as _t,w as vt,x as yt,y as bt}from"./comment-ui-shared-D_pgPUti.js";import{t as xt}from"./document-formatter-DtXmKZcy.js";import{t as St}from"./workspace-change-CVA9dVmy.js";var Ct=Object.freeze([`annotation`,`document-capture`,`document-close`,`document-open`,`document-print`,`document-protect`,`form`,`history`,`insert`,`panel-comment`,`redaction`,`rotate`]),wt=class{constructor({getTheme:e=()=>`dark`,loadEmbedPdf:t}={}){this.getTheme=e,this.loadEmbedPdf=t??(()=>A(()=>import(`./embedpdf-BfUI-3pv.js`),[],import.meta.url)),this.renderToken=0,this.viewer=null}async render({filePath:e,renderHost:t}){this.cancel();let n=this.renderToken,r=document.createElement(`div`);r.className=`pdf-file-preview-viewer`,r.setAttribute(`aria-label`,`${String(e).split(`/`).pop()||e} PDF preview`),t.replaceChildren(r);try{let{default:t,LockModeType:i,ZoomMode:a}=await this.loadEmbedPdf();if(n!==this.renderToken||!r.isConnected)return;let o=t.init({type:`container`,target:r,src:N(`/download/file?path=${encodeURIComponent(e)}`),annotations:{locked:{type:i.All}},disabledCategories:Ct,fontFallback:null,fonts:{signature:null,ui:null},stamp:{defaultLibrary:!1,manifests:[]},tabBar:`never`,theme:{preference:this.getTheme()},wasmUrl:new URL(new URL(`pdfium-BJ2Yip8Q.wasm`,import.meta.url).href,``+import.meta.url).toString(),zoom:{defaultZoomLevel:a.FitWidth,maxZoom:2,minZoom:.5,zoomStep:.25}});this.viewer=o}catch{if(n!==this.renderToken)return;r.classList.add(`pdf-file-preview-error`),r.textContent=`This PDF could not be rendered in the browser.`}}setTheme(e){this.viewer?.setTheme?.(e)}cancel(){this.renderToken+=1,this.viewer?.remove(),this.viewer=null}},Tt=/^\s*(`{3,})(mermaid|plantuml|puml)\s*$/iu;function Et(e=``,t=``,{contentStartLine:n=1}={}){let r=_(t),i=String(e).split(`
|
|
3
|
+
`);if(r===`mermaid`||r===`plantuml`)return[{endLine:n+Math.max(i.length-1,0),kind:r,source:String(e),startLine:n}];if(r!==`markdown`)return[];let a=[];for(let e=0;e<i.length;e+=1){let t=i[e].match(Tt);if(!t)continue;let r=t[1],o=t[2].toLowerCase()===`mermaid`?`mermaid`:`plantuml`,s=e+1,c=s;for(;c<i.length&&i[c].trim()!==r;)c+=1;c>=i.length||(a.push({endLine:n+c,kind:o,source:i.slice(s,c).join(`
|
|
4
|
+
`),startLine:n+e}),e=c)}return a}function Dt(e=``,t=``,n={}){let r=Et(e,t,n),i=Number.parseInt(n.startLine,10);return Number.isInteger(i)?r.find(({startLine:e})=>e===i)??null:r.length===1?r[0]:null}async function Ot(e={},{callTool:t,getMermaid:n,signal:r}={}){let i=Number.parseInt(e.startLine,10),a=await t(`read_document`,{lineCount:500,path:e.path,startLine:Number.isInteger(i)?i:1},{signal:r}),o=Dt(a.content,e.path,{contentStartLine:a.startLine,startLine:e.startLine});if(!o||o.kind!==`mermaid`)return t(`render_diagram`,e,{signal:r});if(a.kind===`mermaid`&&a.truncated)throw Error(`Mermaid source exceeds the WebMCP read limit`);let s=await _e(await n(),o.source),c=e.format??`png`,l=c===`svg`?`image/svg+xml`:`image/png`,u=c===`svg`?new TextEncoder().encode(s):new Uint8Array(await(await ve(s)).arrayBuffer());return{endLine:o.endLine,format:c,image:{data:u.toBase64(),encoding:`base64`,mimeType:l},kind:o.kind,mimeType:l,path:a.path,renderer:`mermaid-browser`,revision:a.revision,startLine:o.startLine,warnings:[]}}async function kt(e){if(e.quickSwitcher)return e.quickSwitcher;e.quickSwitcherModulePromise||=e.loadQuickSwitcherController();let t;try{t=await e.quickSwitcherModulePromise}catch(t){throw e.quickSwitcherModulePromise=null,console.error(`[quick-switcher] Failed to load file search.`,t),e.toastController?.show?.(`Failed to load file search. Try again.`,{dismissible:!0}),t}return e.quickSwitcher||=new t({getFileList:()=>e.fileExplorer.flatFiles,getFileMetadata:()=>e.fileExplorer.fileEntries,getRecentFiles:()=>e.preferences?.getRecentFiles?.()??[],getSearchConfig:()=>e.runtimeConfig.search??{},onFileSelect:t=>e.workspaceRouteController.handleFileSelection(t,{closeSidebarOnMobile:!0,revealInTree:!e.isMobileViewport()}),onTextMatchSelect:t=>{t?.file&&e.navigation.navigateToFile(t.file,{column:t.column,drawioMode:t.kind===`drawio`?`text`:null,line:t.line,matchLength:t.matchLength})},searchText:t=>e.vaultApiClient.searchText(t)}),e.quickSwitcher}async function At(e){try{(await kt(e)).toggle()}catch{}}var jt=class{constructor({backlinksPanel:e,canvasEmbed:t=null,clearInitialFileBootstrap:n,clearStaticPreviewDocument:r=null,closeSidebarOnMobile:i,drawioEmbed:a,elements:o,excalidrawEmbed:s,fileHistoryView:c=null,fileExplorer:l,getIsTabActive:u,getSessionLoadToken:d,gitDiffView:f,gitPanel:p,imageLightbox:m=null,lobby:h,navigation:g,previewRenderer:_,renderAvatars:v,renderPresence:y,requestPreviewRouteAnchor:b=null,resetPreviewMode:x,scrollSyncController:S,setSession:ee,setSessionLoadToken:te,setSidebarTab:ne,setSidebarVisibility:C,setCurrentFilePath:w,showGitCommit:re,showGitDiff:ie,showGitFileHistory:ae,showGitFilePreview:oe,showGitHistory:T,syncMainChrome:E,videoEmbed:se,workspaceCoordinator:ce,layoutController:D}){this.backlinksPanel=e,this.canvasEmbed=t,this.clearInitialFileBootstrap=n,this.clearStaticPreviewDocument=r,this.closeSidebarOnMobile=i,this.drawioEmbed=a??{setHydrationPaused(){}},this.elements=o,this.excalidrawEmbed=s,this.fileHistoryView=c,this.fileExplorer=l,this.getIsTabActive=u,this.getSessionLoadToken=d,this.gitDiffView=f,this.gitPanel=p,this.imageLightbox=m,this.lobby=h,this.navigation=g,this.previewRenderer=_,this.renderAvatars=v,this.renderPresence=y,this.requestPreviewRouteAnchor=b,this.resetPreviewMode=x,this.scrollSyncController=S,this.setSession=ee,this.setSessionLoadToken=te,this.setSidebarTab=ne,this.setSidebarVisibility=C??(()=>{}),this.setCurrentFilePath=w,this.showGitCommit=re,this.showGitDiff=ie,this.showGitFileHistory=ae,this.showGitFilePreview=oe,this.showGitHistory=T,this.syncMainChrome=E,this.videoEmbed=se,this.workspaceCoordinator=ce,this.layoutController=D,this.pendingTreeRevealPath=null,this.preserveSidebarTabRoutePath=null}async handleHashChange(){if(!this.getIsTabActive())return;let e=this.navigation.getHashRoute();if(e.type===`file`||await this.prepareActiveEmbedDisconnect()){if(e.type===`empty`){this.requestPreviewRouteAnchor?.(null),this.gitPanel.setSelection(),this.showEmptyState(),this.syncMainChrome({mode:`empty`,title:`CollabMD`});return}if(e.type===`git-diff`){this.requestPreviewRouteAnchor?.(null),this.setSidebarTab(`git`),await this.showGitDiff(e);return}if(e.type===`git-file-history`){this.requestPreviewRouteAnchor?.(null),this.setSidebarTab(`files`),await this.showGitFileHistory(e);return}if(e.type===`git-file-preview`){this.requestPreviewRouteAnchor?.(null),this.setSidebarTab(`files`),await this.showGitFilePreview(e);return}if(e.type===`git-history`){this.requestPreviewRouteAnchor?.(null),this.setSidebarTab(`git`),await this.showGitHistory();return}if(e.type===`git-commit`){this.requestPreviewRouteAnchor?.(null),this.setSidebarTab(`git`),await this.showGitCommit(e);return}this.preserveSidebarTabRoutePath===e.filePath?this.preserveSidebarTabRoutePath=null:(this.preserveSidebarTabRoutePath=null,this.setSidebarTab(`files`)),await this.openFile(e.filePath,{drawioMode:e.drawioMode||null})&&(this.revealEditorMatch(e),e.elementId&&this.excalidrawEmbed?.openElement(e.filePath,e.elementId,e.elementType),this.requestPreviewRouteAnchor?.(e.anchor??null,e.filePath))}}showEmptyState(){this.gitDiffView.hide(),this.fileHistoryView?.hide?.(),this.workspaceCoordinator.cleanupSession(),this.clearStaticPreviewDocument?.(),this.setSession(null),this.setSessionLoadToken(this.getSessionLoadToken()+1),this.clearInitialFileBootstrap(),this.resetPreviewMode(),this.elements.outlineToggle?.classList.remove(`hidden`),this.elements.markdownToolbar?.classList.add(`hidden`),this.setCurrentFilePath(null),this.lobby.setCurrentFile(null),this.fileExplorer.setActiveFile(null),this.elements.emptyState?.classList.remove(`hidden`),this.elements.editorPage?.classList.add(`hidden`),this.elements.diffPage?.classList.add(`hidden`),this.resetPreviewSurface(),this.renderAvatars(),this.renderPresence(),this.backlinksPanel.clear(),this.elements.activeFileName&&(this.elements.activeFileName.textContent=`CollabMD`)}prepareGitView(e=null){this.setSessionLoadToken(this.getSessionLoadToken()+1),this.clearInitialFileBootstrap(),this.clearStaticPreviewDocument?.(),this.workspaceCoordinator.cleanupSession(),this.setSession(null),this.resetPreviewMode(),this.layoutController.reset(),this.setCurrentFilePath(e),this.lobby.setCurrentFile(null),this.fileExplorer.setActiveFile(e)}showDiffState(){this.fileHistoryView?.hide?.(),this.prepareGitView(),this.elements.emptyState?.classList.add(`hidden`),this.elements.editorPage?.classList.add(`hidden`),this.elements.diffPage?.classList.remove(`hidden`),this.resetPreviewSurface(),this.elements.outlineToggle?.classList.add(`hidden`),this.elements.markdownToolbar?.classList.add(`hidden`),this.renderAvatars(),this.renderPresence(),this.backlinksPanel.clear()}showFileHistoryState(e){this.gitDiffView.hide(),this.prepareGitView(e),this.elements.emptyState?.classList.add(`hidden`),this.elements.editorPage?.classList.add(`hidden`),this.elements.diffPage?.classList.remove(`hidden`),this.resetPreviewSurface(),this.elements.outlineToggle?.classList.add(`hidden`),this.elements.markdownToolbar?.classList.add(`hidden`),this.renderAvatars(),this.renderPresence(),this.backlinksPanel.clear()}showPreviewOnlyState(e){this.gitDiffView.hide(),this.fileHistoryView?.hide?.(),this.prepareGitView(e),this.elements.emptyState?.classList.add(`hidden`),this.elements.editorPage?.classList.remove(`hidden`),this.elements.diffPage?.classList.add(`hidden`),this.resetPreviewSurface(),this.elements.markdownToolbar?.classList.add(`hidden`),this.renderAvatars(),this.renderPresence(),this.backlinksPanel.clear()}async openFile(e,t={}){if(!await this.prepareActiveEmbedDisconnect(e))return!1;let n=this.pendingTreeRevealPath===e;n&&(this.pendingTreeRevealPath=null),this.imageLightbox?.close?.(),this.gitPanel.setSelection(),this.gitDiffView.hide(),this.fileHistoryView?.hide?.(),this.clearStaticPreviewDocument?.(),this.syncMainChrome({mode:`editor`});let r=await this.workspaceCoordinator.openFile(e,t);return this.setSession(this.workspaceCoordinator.getSession()),r!==!1&&(n&&this.revealFileInTree(e,{clearSearch:!0}),!0)}async prepareActiveEmbedDisconnect(e=null){let t=this.workspaceCoordinator.stateStore?.currentFilePath??this.workspaceCoordinator.stateStore?.get?.(`currentFilePath`)??null;if(!t||t===e)return!0;let n=this.workspaceCoordinator.isCanvasFile?.(t)?this.canvasEmbed:this.workspaceCoordinator.isExcalidrawFile?.(t)?this.excalidrawEmbed:null;return n&&!await n.prepareFileDisconnect(t,{timeoutMs:1e4})?(this.navigation.navigateToFile(t),!1):!0}preserveSidebarTabForNextFileRoute(e){this.preserveSidebarTabRoutePath=e||null}cleanupSession(){this.workspaceCoordinator.cleanupSession(),this.setSession(this.workspaceCoordinator.getSession())}handleFileSelection(e,{closeSidebarOnMobile:t=!1,revealInTree:n=!1}={}){let r=this.navigation.getHashRoute?.()??null,i=r?.type===`file`&&r.filePath===e&&!r.drawioMode;if(n&&(this.pendingTreeRevealPath=e,i)){this.pendingTreeRevealPath=null,this.revealFileInTree(e,{clearSearch:!0});return}t&&!n&&this.closeSidebarOnMobile(),this.navigation.navigateToFile(e)}revealFileInTree(e,{clearSearch:t=!1}={}){this.setSidebarTab(`files`),this.setSidebarVisibility(!0),this.fileExplorer.revealFile?.(e,{clearSearch:t})}revealEditorMatch(e={}){if(!Number.isFinite(e.line))return!1;let t=this.workspaceCoordinator.getSession?.();return t?.revealSearchMatch?.({column:e.column,length:e.matchLength,line:e.line})??t?.scrollToLine?.(e.line,.2)??!1}resetPreviewSurface(){this.elements.previewContent&&(this.elements.previewContent.innerHTML=``,this.elements.previewContent.dataset.renderPhase=`ready`),this.videoEmbed?.reconcileEmbeds(this.elements.previewContent),this.imageLightbox?.close?.(),this.previewRenderer.setHydrationPaused(!1),this.drawioEmbed.setHydrationPaused(!1),this.excalidrawEmbed.setHydrationPaused(!1),this.videoEmbed?.detachForCommit(),this.scrollSyncController.setLargeDocumentMode(!1),this.scrollSyncController.invalidatePreviewBlocks()}},Mt=class{constructor({getFileList:e,navigation:t,refreshExplorer:n,toastController:r,vaultApiClient:i,wikiLinkAutoCreate:a=!0}){this.getFileList=e,this.navigation=t,this.refreshExplorer=n,this.toastController=r,this.vaultApiClient=i,this.wikiLinkAutoCreate=a}handleWikiLinkClick(e){let t=ee(e,this.getFileList());if(t){this.navigation.navigateToFile(t);return}if(!this.wikiLinkAutoCreate){this.toastController.show(`Wiki-link target does not exist`);return}let n=this.normalizeNewWikiFilePath(e);if(!n){this.toastController.show(`Cannot create an empty wiki-link target`);return}this.createAndOpenFile(n,e)}normalizeNewWikiFilePath(e){let t=T(e);return t?t.endsWith(`.md`)?t:`${t}.md`:null}async createAndOpenFile(e,t){try{await this.vaultApiClient.createFile({content:oe(t||e),path:e}),await this.refreshExplorer(),this.navigation.navigateToFile(e)}catch(e){this.toastController.show(`Failed to create file: ${e.message}`)}}},Nt=`default-src 'none'; base-uri about:; form-action 'none'; object-src 'none'; frame-src 'none'; worker-src 'none'; connect-src 'none'; style-src 'unsafe-inline'; img-src data: blob:; font-src data:; media-src data: blob:`;function Pt(e,t=!1){return`<meta http-equiv="Content-Security-Policy" content="${Nt}; script-src ${t?`'unsafe-inline'`:`'none'`};"><base href="about:srcdoc">${String(e??``)}`}function Ft(e){let t=new DOMParser().parseFromString(e,`text/html`);return t.scripts.length>0||[...t.querySelectorAll(`*`)].some(e=>[...e.attributes].some(({name:t,value:n})=>t.startsWith(`on`)&&t in e||(t===`href`||t===`xlink:href`)&&/^\s*javascript:/iu.test(n)))}function It(e,t,n){if(!e)return;let r=n?`Indent PlantUML document`:`Format document`;e.classList.toggle(`hidden`,!xt(t)),e.setAttribute(`aria-label`,r),e.setAttribute(`title`,r);let i=e.querySelector(`.ui-action-label`);i&&(i.textContent=n?`Indent`:`Format`)}var Lt=class{constructor({backlinksPanel:e,basesPreview:t=null,canvasEmbed:n=null,drawioEmbed:r,elements:a,excalidrawEmbed:o,getDisplayName:s,getSession:c,isDrawioFile:l,isExcalidrawFile:u,isBaseFile:d,isImageFile:f,isPdfFile:p,isMermaidFile:m,isPlantUmlFile:h,layoutController:g,outlineController:_,previewRenderer:v,pdfPreview:y=null,scrollSyncController:b,structurizrPreview:x=null,videoEmbed:S}){this.backlinksPanel=e,this.basesPreview=t??{reconcileEmbeds(){},renderStandalone(){}},this.canvasEmbed=n,this.drawioEmbed=r??{detachForCommit(){},hydrateVisibleEmbeds(){},reconcileEmbeds(){},setHydrationPaused(){},syncLayout(){},updateLocalUser(){},updateTheme(){}},this.elements=a,this.htmlPreviewShell=null,this.elements.htmlPreviewMaximizeButton&&(this.elements.htmlPreviewMaximizeButton.addEventListener(`click`,()=>{let e=this.htmlPreviewShell?.classList.contains(`is-maximized`);this.setHtmlPreviewMaximized(!e)}),xe(this.elements.htmlPreviewMaximizeButton,`maximize`)),this.excalidrawEmbed=o,this.getDisplayName=s,this.getSession=c,this.isDrawioFile=l??(()=>!1),this.isExcalidrawFile=u??(()=>!1),this.isBaseFile=d??i,this.isImageFile=f??(()=>!1),this.isPdfFile=p??(()=>!1),this.isMermaidFile=m??(()=>!1),this.isPlantUmlFile=h??(()=>!1),this.layoutController=g,this.outlineController=_,this.previewRenderer=v,this.pdfPreview=y??{cancel(){},render(){}},this.previewHydrationPaused=!1,this.pendingPreviewLayoutSync=!1,this.previewLayoutSyncTimer=null,this.scrollSyncController=b,this.structurizrPreview=x??{queueSync(){},render:async()=>!1,reset(){}},this.videoEmbed=S}createDiagramPreviewDocument(e,t=``){let n=String(t??``),r=Math.max(...n.match(/`+/g)?.map(e=>e.length)??[0]),i="`".repeat(Math.max(3,r+1));return`${i}${e}\n${n}\n${i}`}getPreviewSource(e,{drawioMode:t=null}={}){let n=this.getSession()?.getText()??``;return this.isMermaidFile(e)?this.createDiagramPreviewDocument(`mermaid`,n):this.isPlantUmlFile(e)?this.createDiagramPreviewDocument(`plantuml`,n):this.isDrawioFile(e)&&t===`text`?this.createDiagramPreviewDocument(`xml`,n):n}setHtmlPreviewMaximized(e){let t=!!(e&&this.htmlPreviewShell);this.htmlPreviewShell?.classList.toggle(`is-maximized`,t),globalThis.document?.body?.classList.toggle(`html-preview-maximized-open`,t);let n=this.elements.htmlPreviewMaximizeButton;n&&(xe(n,t?`restore`:`maximize`),n.title=t?`Restore HTML preview`:`Maximize HTML preview`,n.setAttribute(`aria-label`,n.title))}resetPreviewMode(){this.canvasEmbed?.unmount(),this.setHtmlPreviewMaximized(!1),this.htmlPreviewShell=null,this.pdfPreview.cancel(),this.elements.previewContent?.classList.remove(`is-drawio-file-preview`),this.elements.previewContent?.classList.remove(`is-excalidraw-file-preview`),this.elements.previewContent?.classList.remove(`is-canvas-file-preview`),this.elements.previewContent?.classList.remove(`is-base-file-preview`),this.elements.previewContent?.classList.remove(`is-image-file-preview`),this.elements.previewContent?.classList.remove(`is-pdf-file-preview`),this.elements.previewContent?.classList.remove(`is-html-file-preview`),this.elements.previewContent?.classList.remove(`is-mermaid-file-preview`),this.elements.previewContent?.classList.remove(`is-plantuml-file-preview`),this.elements.previewContent?.classList.remove(`is-structurizr-file-preview`),this.structurizrPreview.reset()}syncFileChrome(e,{drawioMode:t=null,preferPreviewForBase:n=!1}={}){let r=this.isDrawioFile(e),i=this.isExcalidrawFile(e),a=h(e),o=this.isBaseFile(e),s=this.isImageFile(e),u=this.isPdfFile(e),d=b(e),f=c(e),p=this.isMermaidFile(e),m=this.isPlantUmlFile(e),g=l(e),_=v(e),y=i||a||r&&t!==`text`;if(this.backlinksPanel.setDisplayMode?.(y?`header`:`dock`),this.elements.editorFindButton?.classList.toggle(`hidden`,!f),this.elements.toolbarViewToggle?.classList.toggle(`hidden`,a),this.elements.mobileViewToggle?.classList.toggle(`hidden`,a),this.elements.toggleWrapButton?.classList.toggle(`hidden`,a),It(this.elements.editorFormatButton,e,m),this.elements.markdownToolbar?.classList.toggle(`hidden`,!f),this.elements.exportMenuGroup?.classList.toggle(`hidden`,!f),this.elements.htmlPreviewMaximizeButton?.classList.toggle(`hidden`,!d),this.elements.outlineToggle?.classList.toggle(`hidden`,_||s||u||d||o),this.elements.previewContent?.classList.toggle(`is-mermaid-file-preview`,p),this.elements.previewContent?.classList.toggle(`is-plantuml-file-preview`,m),this.elements.previewContent?.classList.toggle(`is-structurizr-file-preview`,g),g&&(this.outlineController.close(),this.backlinksPanel.clear()),r&&t!==`text`||i||a||d||s||u||o&&n){this.layoutController.setView(`preview`,{persist:!1}),this.outlineController.close(),this.backlinksPanel.clear();return}(p||m)&&(this.outlineController.close(),this.backlinksPanel.clear())}prepareFilePreview(e){let t=this.elements.previewContent;if(!t)return null;this.videoEmbed?.detachForCommit(),this.drawioEmbed.detachForCommit(),this.excalidrawEmbed.detachForCommit(),this.resetPreviewMode(),e&&t.classList.add(e);let n=this.previewRenderer.ensureRenderHost();return this.previewRenderer.normalizePreviewChildren(n),{previewElement:t,renderHost:n}}commitFilePreview(e,t){e&&(e.replaceChildren(t),e.style.minHeight=``)}renderCanvasFilePreview(e){let t=this.prepareFilePreview(`is-canvas-file-preview`);if(!t)return;let{previewElement:n,renderHost:r}=t;r&&(r.style.minHeight=``),this.canvasEmbed?.mount(e,r),n.dataset.renderPhase=`ready`,this.outlineController.close(),this.scrollSyncController.setLargeDocumentMode(!1),this.scrollSyncController.invalidatePreviewBlocks(),this.videoEmbed?.reconcileEmbeds(n),this.drawioEmbed.reconcileEmbeds(n),this.excalidrawEmbed.reconcileEmbeds(n,{isLargeDocument:!1})}renderExcalidrawFilePreview(e){let t=this.prepareFilePreview(`is-excalidraw-file-preview`);if(!t)return;let{previewElement:n,renderHost:r}=t,i=document.createElement(`div`);i.className=`excalidraw-embed-placeholder`,i.dataset.embedKey=`${e}#file-preview`,i.dataset.embedLabel=this.getDisplayName(e),i.dataset.embedTarget=e;let a=document.createElement(`div`);a.className=`preview-shell`,a.textContent=`Loading Excalidraw preview…`,i.appendChild(a),this.commitFilePreview(r,i),n.dataset.renderPhase=`ready`,this.outlineController.refresh(),this.scrollSyncController.setLargeDocumentMode(!1),this.scrollSyncController.invalidatePreviewBlocks(),this.videoEmbed?.reconcileEmbeds(n),this.drawioEmbed.reconcileEmbeds(n),this.excalidrawEmbed.reconcileEmbeds(n,{isLargeDocument:!1}),this.drawioEmbed.hydrateVisibleEmbeds(),this.excalidrawEmbed.hydrateVisibleEmbeds(),this.schedulePreviewLayoutSync({delayMs:0})}renderDrawioFilePreview(e){let t=this.prepareFilePreview(`is-drawio-file-preview`);if(!t)return;let{previewElement:n,renderHost:r}=t,i=document.createElement(`div`);i.className=`drawio-embed-placeholder`,i.dataset.drawioKey=`${e}#file-preview`,i.dataset.drawioLabel=this.getDisplayName(e),i.dataset.drawioMode=`edit`,i.dataset.drawioTarget=e;let a=document.createElement(`div`);a.className=`preview-shell`,a.textContent=`Loading draw.io preview…`,i.appendChild(a),this.commitFilePreview(r,i),n.dataset.renderPhase=`ready`,this.outlineController.refresh(),this.scrollSyncController.setLargeDocumentMode(!1),this.scrollSyncController.invalidatePreviewBlocks(),this.videoEmbed?.reconcileEmbeds(n),this.drawioEmbed.reconcileEmbeds(n),this.drawioEmbed.hydrateVisibleEmbeds(),this.schedulePreviewLayoutSync({delayMs:0})}renderImageFilePreview(e){let t=this.prepareFilePreview(`is-image-file-preview`);if(!t)return;let{previewElement:n,renderHost:r}=t,i=document.createElement(`figure`);i.className=`image-file-preview-shell`;let a=document.createElement(`img`);a.className=`image-file-preview-image`,a.alt=this.getDisplayName(e),a.src=N(`/attachment?path=${encodeURIComponent(e)}`),i.appendChild(a),this.commitFilePreview(r,i),n.dataset.renderPhase=`ready`,this.outlineController.refresh(),this.scrollSyncController.setLargeDocumentMode(!1),this.scrollSyncController.invalidatePreviewBlocks(),this.videoEmbed?.reconcileEmbeds(n),this.schedulePreviewLayoutSync({delayMs:0})}renderPdfFilePreview(e){let t=this.prepareFilePreview(`is-pdf-file-preview`);if(!t)return;let{previewElement:n,renderHost:r}=t;r&&(this.pdfPreview.render({filePath:e,renderHost:r}),r.style.minHeight=``),n.dataset.renderPhase=`ready`,this.outlineController.close(),this.backlinksPanel.clear(),this.scrollSyncController.setLargeDocumentMode(!1),this.scrollSyncController.invalidatePreviewBlocks(),this.videoEmbed?.reconcileEmbeds(n),this.schedulePreviewLayoutSync({delayMs:0})}renderHtmlFilePreview({content:e=``}={}){let t=this.htmlPreviewShell?.classList.contains(`is-maximized`)??!1,n=this.prepareFilePreview(`is-html-file-preview`);if(!n)return;let{previewElement:r,renderHost:i}=n,a=String(e??``),o=document.createElement(`iframe`);o.className=`html-file-preview-frame`,o.title=`HTML preview`,o.referrerPolicy=`no-referrer`,o.setAttribute(`allow`,`camera 'none'; microphone 'none'; geolocation 'none'; clipboard-read 'none'; clipboard-write 'none'`),o.setAttribute(`sandbox`,``),o.srcdoc=Pt(a);let s=document.createElement(`div`);if(s.className=`html-file-preview-shell`,Ft(a)){let e=document.createElement(`div`);e.className=`html-file-preview-script-gate`,e.textContent=`Scripts are disabled by default. Run them only if you trust this HTML file.`;let t=document.createElement(`button`);t.type=`button`,t.className=`ui-button ui-button--secondary ui-button--compact`,t.textContent=`Run scripts`,t.addEventListener(`click`,()=>{o.setAttribute(`sandbox`,`allow-scripts`),o.srcdoc=Pt(a,!0),e.remove()}),e.append(t),s.append(e)}s.append(o),this.htmlPreviewShell=s,this.setHtmlPreviewMaximized(t),this.commitFilePreview(i,s),r.dataset.renderPhase=`ready`,this.outlineController.close(),this.backlinksPanel.clear(),this.scrollSyncController.setLargeDocumentMode(!1),this.scrollSyncController.invalidatePreviewBlocks(),this.schedulePreviewLayoutSync({delayMs:0})}async renderBaseFilePreview(e,{source:t=null}={}){let n=this.prepareFilePreview(`is-base-file-preview`);if(!n)return;let{previewElement:r,renderHost:i}=n;i&&(i.style.minHeight=``),await this.basesPreview.renderStandalone({filePath:e,renderHost:i,source:typeof t==`string`?t:this.getSession()?.getText?.()??null}),r.dataset.renderPhase=`ready`,this.outlineController.close(),this.scrollSyncController.setLargeDocumentMode(!1),this.scrollSyncController.invalidatePreviewBlocks(),this.videoEmbed?.reconcileEmbeds(r),this.schedulePreviewLayoutSync({delayMs:0})}async renderStructurizrFilePreview(e,{source:t=null}={}){let n=this.prepareFilePreview(`is-structurizr-file-preview`);if(!n)return;let{previewElement:r,renderHost:i}=n;i&&(i.style.minHeight=``),await this.structurizrPreview.render({filePath:e,renderHost:i,source:typeof t==`string`?t:this.getSession()?.getText?.()??``}),r.dataset.renderPhase=`ready`,this.outlineController.close(),this.backlinksPanel.clear(),this.scrollSyncController.setLargeDocumentMode(!1),this.scrollSyncController.invalidatePreviewBlocks(),this.videoEmbed?.reconcileEmbeds(r),this.schedulePreviewLayoutSync({delayMs:0})}renderTextFilePreview({content:e=``}={}){let t=this.prepareFilePreview();if(!t)return;let{previewElement:n,renderHost:r}=t,i=document.createElement(`div`);i.className=`preview-shell`;let a=document.createElement(`pre`),o=document.createElement(`code`);o.textContent=String(e??``),a.appendChild(o),i.appendChild(a),this.commitFilePreview(r,i),n.dataset.renderPhase=`ready`,this.outlineController.close(),this.backlinksPanel.clear(),this.scrollSyncController.setLargeDocumentMode(!1),this.scrollSyncController.invalidatePreviewBlocks(),this.videoEmbed?.reconcileEmbeds(n),this.schedulePreviewLayoutSync({delayMs:0})}createResizeHandler(e){let t=null;return()=>{clearTimeout(t),t=setTimeout(()=>{e?.(),this.schedulePreviewLayoutSync({delayMs:0})},100)}}initializePreviewLayoutObserver(e=()=>{}){if(typeof ResizeObserver!=`function`||!this.elements.previewContent)return null;let t=new ResizeObserver(()=>{e()});return t.observe(this.elements.previewContent),t}resetPreviewLayoutSync(){clearTimeout(this.previewLayoutSyncTimer),this.previewLayoutSyncTimer=null,this.pendingPreviewLayoutSync=!1,this.previewHydrationPaused=!1}schedulePreviewLayoutSync({delayMs:e=120}={}){if(this.previewHydrationPaused){this.pendingPreviewLayoutSync=!0;return}clearTimeout(this.previewLayoutSyncTimer),this.previewLayoutSyncTimer=setTimeout(()=>{this.previewLayoutSyncTimer=null;let e=!!this.getSession(),t=this.elements.previewContent?.classList?.contains?.(`is-drawio-file-preview`)??!1,n=this.elements.previewContent?.classList?.contains?.(`is-excalidraw-file-preview`)??!1;if((e||t||n)&&this.elements.previewContent&&this.elements.previewContent.dataset.renderPhase!==`shell`){if(this.previewHydrationPaused){this.pendingPreviewLayoutSync=!0;return}this.videoEmbed?.syncLayout(),this.drawioEmbed.syncLayout(),this.excalidrawEmbed.syncLayout(),(!t&&!n||e)&&(this.scrollSyncController.invalidatePreviewBlocks(),this.scrollSyncController.warmPreviewBlocks({onReady:()=>{this.getSession()&&(this.scrollSyncController.realignAfterLayoutChange(),this.outlineController.scheduleActiveHeadingUpdate())}}))}},e)}handleEditorScrollActivityChange(e){let t=!!e;if(this.previewHydrationPaused=t,this.previewRenderer.setHydrationPaused(t),this.drawioEmbed.setHydrationPaused(t),this.excalidrawEmbed.setHydrationPaused(t),t){clearTimeout(this.previewLayoutSyncTimer),this.previewLayoutSyncTimer=null,this.pendingPreviewLayoutSync=!0;return}this.pendingPreviewLayoutSync&&(this.pendingPreviewLayoutSync=!1,this.schedulePreviewLayoutSync({delayMs:0}))}},Rt=300,zt=20,Bt=50;function Vt(e=``){let t=String(e??``).replace(/^#/,``);if(!t)return``;try{return decodeURIComponent(t)}catch{return t}}function Ht(e){try{let t=e?.contentDocument,n=t?.querySelector(`.joint-layers`),r=t?.querySelector(`#diagram-viewport`),i=n?new DOMMatrixReadOnly(getComputedStyle(n).transform).a:0;return{scrollLeft:r?.scrollLeft??0,scrollTop:r?.scrollTop??0,zoom:Number.isFinite(i)&&i>0?i:null}}catch{return null}}var Ut=class{constructor({enabled:e=!1,syncWorkspace:t}){this.enabled=!!e,this.syncWorkspace=t,this.iframe=null,this.shell=null,this.status=null,this.maximizeButton=null,this.filePath=null,this.viewKey=``,this.lastVersion=null,this.syncTimer=null,this.syncToken=0,this.frameFitTimer=null,this.frameHost=null,this.pendingIframe=null,this.pendingVersion=null,this.handleFrameLoad=e=>{let t=e?.currentTarget||this.iframe;if(t)try{t===this.iframe&&(this.viewKey=Vt(t.contentWindow?.location?.hash||``)||this.viewKey,t.contentWindow?.addEventListener(`hashchange`,this.handleFrameHashChange)),this.prepareFrame(t)}catch{t===this.pendingIframe&&this.commitPendingIframe(t)}},this.handleFrameHashChange=()=>{try{this.viewKey=Vt(this.iframe?.contentWindow?.location?.hash||``)||this.viewKey}catch{}}}setStatus(e=``,{error:t=!1}={}){this.status&&(this.status.textContent=e,this.status.hidden=!e,this.status.classList.toggle(`is-error`,t))}prepareFrame(e=this.iframe){if(!e?.contentDocument?.head){e===this.pendingIframe&&this.commitPendingIframe(e);return}e.contentWindow?.dispatchEvent(new Event(`resize`)),this.scheduleFrameFit(e,e===this.pendingIframe?()=>this.commitPendingIframe(e):null)}fitFrameToCanvas(e=this.iframe){let t=e?.contentDocument,n=t?.querySelector(`#diagram-canvas`);if(!n||e===this.pendingIframe&&!t.querySelector(`.joint-layers`))return!1;try{let t=e?.contentWindow?.structurizr?.diagram;t?.setEmbedded?.(!0),t?.resize?.(),t?.zoomToWidthOrHeight?.()}catch{}let{width:r,height:i}=n.getBoundingClientRect();return!(!r||!i)}disposeFrame(e){if(e){try{e.contentWindow?.removeEventListener?.(`hashchange`,this.handleFrameHashChange)}catch{}e.removeEventListener(`load`,this.handleFrameLoad),e.remove()}}discardPendingIframe(){this.pendingIframe&&(clearTimeout(this.frameFitTimer),this.frameFitTimer=null,this.disposeFrame(this.pendingIframe),this.pendingIframe=null,this.pendingVersion=null)}commitPendingIframe(e){if(e!==this.pendingIframe||!this.shell?.isConnected)return;let t=this.iframe,n=this.pendingVersion,r=Ht(t);if(this.pendingIframe=null,this.pendingVersion=null,r?.zoom)try{e.contentWindow?.structurizr?.diagram?.zoomTo?.(r.zoom)}catch{}try{let t=e.contentDocument?.querySelector(`#diagram-viewport`);t&&r&&(t.scrollLeft=r.scrollLeft,t.scrollTop=r.scrollTop)}catch{}this.disposeFrame(t),e.style.visibility=``,e.style.pointerEvents=``,e.removeAttribute(`aria-hidden`),this.iframe=e,this.lastVersion=n;try{this.viewKey=Vt(e.contentWindow?.location?.hash||``)||this.viewKey,e.contentWindow?.addEventListener(`hashchange`,this.handleFrameHashChange)}catch{}this.setStatus(``)}createIframe(){let e=document.createElement(`iframe`);return e.className=`structurizr-preview-iframe`,e.title=`Structurizr architecture diagram`,e.loading=`eager`,e.referrerPolicy=`same-origin`,e.addEventListener(`load`,this.handleFrameLoad),e}syncMaximizeButtonState(){if(!this.maximizeButton||!this.shell)return;let e=this.shell.classList.contains(`is-maximized`);xe(this.maximizeButton,e?`restore`:`maximize`);let t=e?`Restore diagram size`:`Maximize diagram`;this.maximizeButton.title=t,this.maximizeButton.setAttribute(`aria-label`,t)}setMaximized(e){let t=!!e;this.shell?.classList.toggle(`is-maximized`,t),document.body?.classList.toggle(`structurizr-maximized-open`,t),this.syncMaximizeButtonState(),this.iframe?.contentWindow?.dispatchEvent(new Event(`resize`))}scheduleFrameFit(e=this.iframe,t=null){if(!e)return;clearTimeout(this.frameFitTimer);let n=0,r=()=>{if(this.frameFitTimer=null,this.fitFrameToCanvas(e)||n>=zt){t?.();return}n+=1,this.frameFitTimer=setTimeout(r,Bt)};r()}mount(e,t){if(this.filePath&&this.filePath!==t&&(this.setMaximized(!1),this.discardPendingIframe(),this.disposeFrame(this.iframe),this.iframe=null,this.lastVersion=null,this.viewKey=``),this.filePath=t,this.shell?.isConnected&&this.shell.parentElement===e)return;clearTimeout(this.frameFitTimer),this.frameFitTimer=null,this.shell=document.createElement(`section`),this.shell.className=`structurizr-preview-shell diagram-preview-shell`,this.shell.dataset.structurizrPreview=`true`;let n=document.createElement(`div`);n.className=`structurizr-preview-header diagram-preview-toolbar`;let r=document.createElement(`span`);r.className=`structurizr-preview-label`,r.textContent=String(t).split(`/`).pop()?.replace(/\.dsl$/i,``)||`Structurizr`,this.maximizeButton=document.createElement(`button`),this.maximizeButton.type=`button`,this.maximizeButton.className=`structurizr-preview-btn ui-preview-action ui-preview-action--icon-only`,this.maximizeButton.dataset.action=`toggle-maximize`,this.maximizeButton.addEventListener(`click`,e=>{e.preventDefault(),this.setMaximized(!this.shell?.classList.contains(`is-maximized`))}),n.append(r,this.maximizeButton),this.syncMaximizeButtonState(),this.status=document.createElement(`div`),this.status.className=`structurizr-preview-status`,this.status.setAttribute(`aria-live`,`polite`),this.status.setAttribute(`role`,`status`),this.status.hidden=!0,this.frameHost=document.createElement(`div`),this.frameHost.className=`structurizr-preview-stage`,this.shell.append(n,this.status,this.frameHost),e?.replaceChildren(this.shell),this.iframe=null,this.pendingIframe=null,this.pendingVersion=null,this.lastVersion=null}async render({filePath:e,renderHost:t,source:n=``}){return this.mount(t,e),this.syncNow({filePath:e,source:String(n??``)})}queueSync({filePath:e,source:t=``}={}){clearTimeout(this.syncTimer),this.syncTimer=setTimeout(()=>{this.syncTimer=null,this.syncNow({filePath:e,source:String(t??``)})},Rt)}async syncNow({filePath:e,source:t=``}={}){if(e!==this.filePath)return!1;let n=++this.syncToken;if(!this.enabled)return this.setStatus(`Structurizr preview is not configured. Start CollabMD with --local-structurizr.`,{error:!0}),!1;this.iframe||this.setStatus(`Validating Structurizr workspace…`);try{let r=await this.syncWorkspace({path:e,source:t});if(n!==this.syncToken||e!==this.filePath)return!1;let i=r?.version||null,a=Ne(`/workspace/1/diagrams`),o=this.viewKey?`#${encodeURIComponent(this.viewKey)}`:``;if(!this.iframe){let e=this.createIframe();this.iframe=e,this.frameHost?.appendChild(e),e.src=`${a}${o}`,this.lastVersion=i}else if(i!==this.lastVersion){this.discardPendingIframe();let e=this.createIframe();e.style.visibility=`hidden`,e.style.pointerEvents=`none`,e.setAttribute(`aria-hidden`,`true`),this.pendingIframe=e,this.pendingVersion=i,this.frameHost?.appendChild(e),e.src=`${a}${o}`}return this.setStatus(``),!0}catch(t){return n!==this.syncToken||e!==this.filePath||this.setStatus(t?.message||`Failed to load Structurizr workspace.`,{error:!0}),!1}}reset(){this.setMaximized(!1),clearTimeout(this.syncTimer),this.syncTimer=null,clearTimeout(this.frameFitTimer),this.frameFitTimer=null,this.syncToken+=1,this.discardPendingIframe(),this.disposeFrame(this.iframe),this.iframe=null,this.frameHost=null,this.shell=null,this.status=null,this.maximizeButton=null,this.filePath=null,this.lastVersion=null,this.viewKey=``}},Wt=150;function Gt(e){return new Promise(t=>{setTimeout(t,e)})}var Kt=class{constructor({attachEditorScroller:e,beginDocumentLoad:t,cleanupAfterSessionDestroy:n,createEditorSession:r,getDisplayName:i,getFileList:a,getVaultFileList:o=a,getLineWrappingEnabled:s,getVimModeEnabled:c,getLocalUser:l,getStoredUserName:u,getTheme:d,isBaseFile:f,isCanvasFile:p,isDrawioFile:m,isExcalidrawFile:h,isImageFile:g,isPdfFile:_,isMermaidFile:v,isPlantUmlFile:y,isStructurizrWorkspaceFile:b,isTabActive:x,loadBootstrapContent:S=null,loadEditorSessionClass:ee,loadBacklinks:te,onBeforeFileOpen:ne,onConnectionChange:C,onContentChange:w,onCommentsChange:re,onFileAwarenessChange:ie,onFileOpenError:ae,onFileOpenReady:oe,onImagePaste:T,onSelectionChange:E,onSessionAssigned:se=null,onFileOpenMetric:ce=null,onRenderBasePreview:D,onRenderCanvasPreview:le,onRenderExcalidrawPreview:ue,onRenderDrawioPreview:de,onRenderHtmlPreview:O,onRenderImagePreview:fe,onRenderPdfPreview:pe,onRenderStructurizrPreview:me,onSyncWrapToggle:he,onUpdateActiveFile:k,onUpdateCurrentFile:ge,onUpdateLobbyCurrentFile:_e,onUpdateVisibleChrome:ve,onViewModeReset:ye,renderPresence:be,scrollContainerForSession:xe,shouldUseDrawioPreview:Se=null,showEditorLoading:Ce,stateStore:we}){this.attachEditorScroller=e,this.beginDocumentLoad=t,this.cleanupAfterSessionDestroy=n,this.createEditorSession=r,this.getDisplayName=i,this.getFileList=a,this.getVaultFileList=o,this.getLineWrappingEnabled=s,this.getVimModeEnabled=c??(()=>!1),this.getLocalUser=l,this.getStoredUserName=u,this.getTheme=d,this.isBaseFile=f??(()=>!1),this.isCanvasFile=p??(()=>!1),this.isDrawioFile=m??(()=>!1),this.isExcalidrawFile=h??(()=>!1),this.isImageFile=g??(()=>!1),this.isPdfFile=_??(()=>!1),this.isMermaidFile=v??(()=>!1),this.isPlantUmlFile=y??(()=>!1),this.isStructurizrWorkspaceFile=b??(()=>!1),this.isTabActive=x,this.loadBootstrapContent=S,this.loadEditorSessionClassPort=ee,this.loadBacklinks=te,this.onBeforeFileOpen=ne,this.onConnectionChange=C,this.onContentChange=w,this.onCommentsChange=re,this.onFileAwarenessChange=ie,this.onFileOpenError=ae,this.onFileOpenReady=oe,this.onImagePaste=T,this.onSelectionChange=E,this.onSessionAssigned=se,this.onFileOpenMetric=ce,this.onRenderBasePreview=D,this.onRenderCanvasPreview=le,this.onRenderDrawioPreview=de,this.onRenderExcalidrawPreview=ue,this.onRenderHtmlPreview=O,this.onRenderImagePreview=fe,this.onRenderPdfPreview=pe,this.onRenderStructurizrPreview=me,this.onSyncWrapToggle=he,this.onUpdateActiveFile=k,this.onUpdateCurrentFile=ge,this.onUpdateLobbyCurrentFile=_e,this.onUpdateVisibleChrome=ve,this.onViewModeReset=ye,this.renderPresence=be,this.scrollContainerForSession=xe,this.shouldUseDrawioPreview=Se??(()=>!0),this.showEditorLoading=Ce,this.stateStore=we,this.session=null}getSession(){return this.session}loadEditorSessionClass(){return this.loadEditorSessionClassPort()}waitForNextPaint(){return new Promise(e=>{requestAnimationFrame(()=>{requestAnimationFrame(e)})})}reportFileOpenMetric(e,t,n={}){this.onFileOpenMetric?.(e,{filePath:this.stateStore.currentFilePath,loadToken:t,...n})}cleanupSession(){this.session?.destroy(),this.session=null,this.attachEditorScroller(null),this.cleanupAfterSessionDestroy()}prepareForFileOpen(e,{drawioMode:t=null,resetConnectionState:n=!0}={}){return this.onViewModeReset(),this.onBeforeFileOpen(),this.stateStore.connectionHelpShown=!1,n&&(this.stateStore.connectionState={status:`connecting`,unreachable:!1}),this.stateStore.currentDrawioMode=t??null,this.stateStore.currentFilePath=e,this.onUpdateCurrentFile(e),this.onUpdateLobbyCurrentFile(e),this.onUpdateActiveFile(e),this.onUpdateVisibleChrome(e,{displayName:this.getDisplayName(e),drawioMode:t,isMarkdown:c(e)}),this.showEditorLoading(),this.beginDocumentLoad(),this.renderPresence(),{supportsBacklinks:S(e)}}finalizeFileOpen({isBase:e=!1,isCanvas:t=!1,isDrawio:n=!1,filePath:r,isExcalidraw:a=!1,isHtml:o=!1,isImage:s=!1,isPdf:c=!1,supportsBacklinks:l}){t&&this.onRenderCanvasPreview(r),a&&this.onRenderExcalidrawPreview(r),(e||i(r))&&this.onRenderBasePreview(r),n&&this.onRenderDrawioPreview(r),o&&this.onRenderHtmlPreview({content:this.session?.getText?.()??``}),s&&this.onRenderImagePreview(r),c&&this.onRenderPdfPreview(r),this.isStructurizrWorkspaceFile(r)&&this.onRenderStructurizrPreview(r,{source:this.session?.getText?.()??``}),this.onSyncWrapToggle(),l&&this.loadBacklinks(r)}async openFile(e,{drawioMode:t=null}={}){if(!this.isTabActive())return!1;if(!e||!this.getVaultFileList().includes(e))return this.cleanupSession(),this.stateStore.sessionLoadToken+=1,this.onFileOpenError({code:`not-found`,filePath:e}),!1;let n=t??null,r=this.stateStore.currentDrawioMode??null,i=this.isDrawioFile(e)&&t!==`text`&&this.shouldUseDrawioPreview(e),a=this.isExcalidrawFile(e),o=this.isCanvasFile(e),s=this.isBaseFile(e),c=this.isImageFile(e),l=this.isPdfFile(e),u=b(e),d=this.isMermaidFile(e),f=this.isPlantUmlFile(e),p=this.isStructurizrWorkspaceFile(e);if(e===this.stateStore.currentFilePath&&n===r&&(this.session||i||a||o||c||l))return this.onUpdateActiveFile(e),this.onUpdateLobbyCurrentFile(e),!0;let m=++this.stateStore.sessionLoadToken,h=performance.now();this.cleanupSession();let g=this.prepareForFileOpen(e,{drawioMode:n,resetConnectionState:!i&&!a&&!c&&!l});if(this.reportFileOpenMetric(`open_started`,m,{filePath:e}),i||a||o||c||l)return this.onSessionAssigned?.(null),m===this.stateStore.sessionLoadToken?(this.onFileOpenReady(null),this.finalizeFileOpen({filePath:e,isBase:s,isCanvas:o,isDrawio:i,isExcalidraw:a,isImage:c,isPdf:l,session:null,supportsBacklinks:g.supportsBacklinks}),!0):void 0;let _=!1,v=!1,y=this.loadBootstrapContent?(async()=>{this.reportFileOpenMetric(`bootstrap_fetch_started`,m);try{let t=await this.loadBootstrapContent(e);return this.reportFileOpenMetric(`bootstrap_fetch_completed`,m,{found:t!==null}),t}catch(e){return this.reportFileOpenMetric(`bootstrap_fetch_completed`,m,{error:e.message,found:!1}),null}})():Promise.resolve(null),x=await this.loadEditorSessionClass();if(m!==this.stateStore.sessionLoadToken)return!1;let S=this.createEditorSession(x,{filePath:e,getFileList:this.getFileList,lineWrappingEnabled:this.getLineWrappingEnabled(),localUser:this.getLocalUser(),vimModeEnabled:this.getVimModeEnabled(),onAwarenessChange:e=>this.onFileAwarenessChange(e),onConnectionChange:e=>this.onConnectionChange(e),onCommentsChange:e=>this.onCommentsChange?.(e),onContentChange:()=>{a||this.onContentChange({isBase:s,isHtml:u,isMermaid:d,isPlantUml:f,isStructurizrWorkspace:p})},onImagePaste:e=>this.onImagePaste?.(e),preferredUserName:this.getStoredUserName(),onSelectionChange:e=>this.onSelectionChange?.(e),theme:this.getTheme()});this.session=S,this.onSessionAssigned?.(S);try{let t=!1,n=async n=>{_||m!==this.stateStore.sessionLoadToken||(_=!0,this.attachEditorScroller(this.scrollContainerForSession(S)),S.applyTheme(this.getTheme()),this.onFileOpenReady(S),this.reportFileOpenMetric(`editor_ready`,m,{reason:n}),S.requestMeasure(),await this.waitForNextPaint(),!(t||m!==this.stateStore.sessionLoadToken)&&(t=!0,this.finalizeFileOpen({filePath:e,isBase:s,isExcalidraw:a,isHtml:u,session:S,supportsBacklinks:g.supportsBacklinks})))},r=S.initialize(e),i=(async()=>(await r,m!==this.stateStore.sessionLoadToken||(await S.waitForInitialSync(null),m!==this.stateStore.sessionLoadToken)?!1:(v=!0,S.activateCollaborativeView?.(),this.attachEditorScroller(this.scrollContainerForSession(S)),S.applyTheme(this.getTheme()),this.reportFileOpenMetric(`initial_sync_complete`,m),S.ensureInitialContent?.(),_?S.requestMeasure():await n(`live-sync`),!0)))(),o=(async()=>{let t=await y;if(t===null||v||_||m!==this.stateStore.sessionLoadToken)return!1;let r=performance.now()-h,a=Math.max(0,Wt-r);return a>0&&await Promise.race([i.then(e=>e?`live-sync`:`stale`),Gt(a).then(()=>`timeout`)])===`live-sync`||v||_||m!==this.stateStore.sessionLoadToken||!S.showBootstrapContent({content:t,filePath:e})&&!S.hasBootstrapContent?.()?!1:(this.reportFileOpenMetric(`bootstrap_shown`,m),await n(`bootstrap`),!0)})();return await r,m!==this.stateStore.sessionLoadToken||(await Promise.all([i,o]),m!==this.stateStore.sessionLoadToken)?!1:(_||(S.ensureInitialContent?.(),await n(`post-initialize`)),!0)}catch(t){return m===this.stateStore.sessionLoadToken&&(console.error(`[app] Failed to initialize editor:`,t),S.destroy(),this.attachEditorScroller(null),this.session===S&&(this.session=null),this.onFileOpenError({code:`load-failed`,filePath:e}),!1)}}};function qt(e=document){return{agentConnectionContent:e.getElementById(`agentConnectionContent`),agentConnectionDialog:e.getElementById(`agentConnectionDialog`),connectAgentButton:e.getElementById(`connectAgentBtn`),appShell:e.getElementById(`appShell`),hostedGate:e.getElementById(`hostedGate`),teamSettingsButton:e.getElementById(`teamSettingsBtn`),teamSettingsContent:e.getElementById(`teamSettingsContent`),teamSettingsDialog:e.getElementById(`teamSettingsDialog`),currentUserName:e.getElementById(`currentUserName`),chatContainer:e.getElementById(`chatContainer`),chatEmptyState:e.getElementById(`chatEmptyState`),chatForm:e.getElementById(`chatForm`),chatInput:e.getElementById(`chatInput`),chatMessages:e.getElementById(`chatMessages`),chatPanel:e.getElementById(`chatPanel`),chatCloseButton:e.getElementById(`chatCloseBtn`),chatStatus:e.getElementById(`chatStatus`),chatToastContainer:e.getElementById(`chatToastContainer`),chatNotificationButton:e.getElementById(`chatNotificationBtn`),chatNotificationMuteButton:e.getElementById(`chatNotificationMuteBtn`),chatNotificationStatus:e.getElementById(`chatNotificationStatus`),chatToggleBadge:e.getElementById(`chatToggleBadge`),chatToggleButton:e.getElementById(`chatToggleBtn`),gitCommitCancel:e.getElementById(`gitCommitCancel`),gitCommitCopy:e.getElementById(`gitCommitCopy`),gitCommitDialog:e.getElementById(`gitCommitDialog`),gitCommitForm:e.getElementById(`gitCommitForm`),gitCommitInput:e.getElementById(`gitCommitInput`),gitCommitSubmit:e.getElementById(`gitCommitSubmit`),gitCommitTitle:e.getElementById(`gitCommitTitle`),gitResetCancel:e.getElementById(`gitResetCancel`),gitResetCopy:e.getElementById(`gitResetCopy`),gitResetDialog:e.getElementById(`gitResetDialog`),gitResetFileName:e.getElementById(`gitResetFileName`),gitResetSubmit:e.getElementById(`gitResetSubmit`),gitResetTitle:e.getElementById(`gitResetTitle`),displayNameCancel:e.getElementById(`displayNameCancel`),displayNameCopy:e.getElementById(`displayNameCopy`),displayNameDialog:e.getElementById(`displayNameDialog`),displayNameForm:e.getElementById(`displayNameForm`),displayNameInput:e.getElementById(`displayNameInput`),displayNameSubmit:e.getElementById(`displayNameSubmit`),displayNameTitle:e.getElementById(`displayNameTitle`),fileActionDialog:e.getElementById(`fileActionDialog`),editNameButton:e.getElementById(`editNameBtn`),editorFindButton:e.getElementById(`editorFindBtn`),editorFormatButton:e.getElementById(`editorFormatBtn`),editorContainer:e.getElementById(`editorContainer`),exportDocxButton:e.getElementById(`exportDocxBtn`),exportHtmlButton:e.getElementById(`exportHtmlBtn`),exportMenuGroup:e.getElementById(`exportMenuGroup`),exportPdfButton:e.getElementById(`exportPdfBtn`),markdownToolbar:e.getElementById(`markdownToolbar`),editorPage:e.getElementById(`editor-page`),diffPage:e.getElementById(`diff-page`),fileSearch:e.getElementById(`fileSearch`),fileHistoryButton:e.getElementById(`fileHistoryBtn`),fileHistoryButtonLabel:e.getElementById(`fileHistoryBtnLabel`),filesSidebarTab:e.getElementById(`filesSidebarTab`),gitSearch:e.getElementById(`gitSearch`),gitSearchInput:e.getElementById(`gitSearchInput`),gitSidebarTab:e.getElementById(`gitSidebarTab`),gitOperationStatus:e.getElementById(`gitOperationStatus`),lineInfo:e.getElementById(`lineInfo`),mobileViewToggle:e.getElementById(`mobileViewToggle`),htmlPreviewMaximizeButton:e.getElementById(`htmlPreviewMaximize`),previewContent:e.getElementById(`previewContent`),previewContainer:e.getElementById(`previewContainer`),reviewFileChangesButton:e.getElementById(`reviewFileChangesBtn`),presencePanel:e.getElementById(`presencePanel`),presencePanelList:e.getElementById(`presencePanelList`),presencePanelStatus:e.getElementById(`presencePanelStatus`),searchFilesButton:e.getElementById(`searchFilesBtn`),skipToEditor:e.getElementById(`skipToEditor`),toolbarSearchButton:e.getElementById(`toolbarSearchBtn`),shareButton:e.getElementById(`shareBtn`),toastContainer:e.getElementById(`toastContainer`),toggleWrapButton:e.getElementById(`toggleWrapBtn`),toggleVimModeButton:e.getElementById(`toggleVimModeBtn`),userAvatars:e.getElementById(`userAvatars`),userCount:e.getElementById(`userCount`),cursorNamesToggleLabel:e.getElementById(`cursorNamesToggleLabel`),toggleCursorNamesButton:e.getElementById(`toggleCursorNamesBtn`),wrapToggleLabel:e.getElementById(`wrapToggleLabel`),vimModeToggleLabel:e.getElementById(`vimModeToggleLabel`),activeFileName:e.getElementById(`activeFileName`),sidebarToggle:e.getElementById(`sidebarToggle`),sidebarClose:e.getElementById(`sidebarClose`),sidebarBackdrop:e.getElementById(`sidebarBackdrop`),sidebar:e.getElementById(`sidebar`),sidebarResizer:e.getElementById(`sidebarResizer`),emptyState:e.getElementById(`emptyState`),emptyStateNewFileBtn:e.getElementById(`emptyStateNewFileBtn`),emptyStateSearchBtn:e.getElementById(`emptyStateSearchBtn`),backlinksPanel:e.getElementById(`backlinksPanel`),backlinksHeaderPanel:e.getElementById(`backlinksHeaderPanel`),backlinksInlinePanel:e.getElementById(`backlinksInlinePanel`),commentSelectionButton:e.getElementById(`commentSelectionBtn`),commentsDrawer:e.getElementById(`commentsDrawer`),commentsDrawerEmpty:e.getElementById(`commentsDrawerEmpty`),commentsDrawerList:e.getElementById(`commentsDrawerList`),commentsSidebarTab:e.getElementById(`commentsSidebarTab`),commentsToggleButton:e.getElementById(`commentsToggle`),commentOverviewPanel:e.getElementById(`commentOverviewPanel`),outlineToggle:e.getElementById(`outlineToggle`),tabLockCopy:e.getElementById(`tabLockCopy`),tabLockOverlay:e.getElementById(`tabLockOverlay`),tabLockTakeoverButton:e.getElementById(`tabLockTakeoverBtn`),tabLockTitle:e.getElementById(`tabLockTitle`),toolbarCenter:e.getElementById(`toolbarCenter`),toolbarDiffBadge:e.getElementById(`toolbarDiffBadge`),toolbarOverflowMenu:e.getElementById(`toolbarOverflowMenu`),toolbarOverflowToggle:e.getElementById(`toolbarOverflowToggle`),toolbarViewToggle:e.getElementById(`toolbarViewToggle`),sidebarTabs:e.getElementById(`sidebarTabs`)}}var F=`collabmd-chat-alerts-muted-until`,Jt=36e5;function Yt(e){return e.lobby?.getConnectionState?.()??{status:`connected`,unreachable:!1}}function Xt(e){return e.scrollHeight-e.scrollTop-e.clientHeight<=24}function Zt(){try{let e=Number(globalThis.localStorage?.getItem(F));return!Number.isFinite(e)||e<=Date.now()?(globalThis.localStorage?.removeItem(F),0):e}catch{return 0}}function Qt(e){try{e>0?globalThis.localStorage?.setItem(F,String(e)):globalThis.localStorage?.removeItem(F)}catch{}}var $t={updateChatMessages(e,{initial:t=!1}={}){let n=new Set(this.chatMessageIds),r=this.lobby.getLocalUser()?.peerId??null;if(this.chatMessages=e,this.chatMessageIds=new Set(e.map(e=>e.id)),!this.chatInitialSyncComplete){t&&(this.chatInitialSyncComplete=!0),this.renderChat();return}let i=e.filter(e=>!n.has(e.id)&&e.peerId&&e.peerId!==r);this.chatIsOpen?this.chatUnreadCount=0:i.length>0&&(this.chatUnreadCount+=i.length);for(let e of i)this.maybeNotifyChatMessage(e);this.renderChat()},openChatPanel(){this.chatIsOpen=!0,this.chatUnreadCount=0,this.elements.chatPanel?.matches(`:popover-open`)||this.elements.chatPanel?.showPopover(),this.renderChat({stickToBottom:!0}),requestAnimationFrame(()=>this.elements.chatInput?.focus())},closeChatPanel(){this.elements.chatPanel?.matches(`:popover-open`)&&this.elements.chatPanel.hidePopover(),this.chatIsOpen=!1,this.renderChat({messagesChanged:!1})},handleChatSubmit(){let e=Yt(this);if(this.isTabActive===!1||e.status!==`connected`)return;let t=this.elements.chatInput;if(t){if(!this.lobby.sendChatMessage(t.value)){t.focus();return}if(t.value=``,!this.chatIsOpen){this.openChatPanel();return}this.renderChat({stickToBottom:!0})}},renderChat({messagesChanged:e=!0,stickToBottom:t=!1}={}){this.syncChatToggleButton(),this.syncChatNotificationButton();let n=this.elements.chatMessages,r=this.elements.chatEmptyState,i=Yt(this),a=i.status===`connected`,o=a&&this.chatInitialSyncComplete&&this.isTabActive!==!1;this.elements.chatStatus&&(this.elements.chatStatus.textContent=this.chatInitialSyncComplete?a?`${this.globalUsers.length} online`:i.unreachable?`Server unreachable`:`Reconnecting...`:`Syncing...`);let s=this.elements.chatForm?.querySelector?.(`button[type="submit"]`);if(s&&(s.disabled=!o,s.title=o?`Send message`:`Chat is unavailable while disconnected`),!n||!this.chatIsOpen||!e)return;if(this.chatMessages.length===0){n.replaceChildren(),r?.classList.remove(`hidden`),n.classList.add(`hidden`);return}r?.classList.add(`hidden`),n.classList.remove(`hidden`);let c=t||Xt(n),l=document.createDocumentFragment();this.chatMessages.forEach(e=>{l.appendChild(this.createChatMessageElement(e))}),n.replaceChildren(l),c&&this.scrollChatToBottom()},createChatMessageElement(e){let n=document.createElement(`article`),r=e.peerId===this.lobby.getLocalUser()?.peerId;n.className=`chat-message`,n.classList.toggle(`is-local`,r);let i=document.createElement(`div`);i.className=`chat-message-avatar`;let a=e.userColor||`var(--color-primary-active)`;i.style.backgroundColor=a,i.style.color=t(e.userColor),i.textContent=(e.userName||`?`).charAt(0).toUpperCase(),i.setAttribute(`aria-hidden`,`true`);let o=document.createElement(`div`);o.className=`chat-message-body`;let s=document.createElement(`div`);s.className=`chat-message-meta`;let c=document.createElement(`span`);c.className=`chat-message-author`,c.textContent=r?`${e.userName} (you)`:e.userName;let l=document.createElement(`span`);l.className=`chat-message-time`,l.textContent=this.formatChatTimestamp(e.createdAt),s.append(c,l);let u=this.getChatMessageFileLabel(e.filePath);if(u){let e=document.createElement(`span`);e.className=`ui-pill chat-message-file`,e.textContent=u,s.append(e)}let d=document.createElement(`p`);return d.className=`chat-message-text`,d.textContent=e.text,o.append(s,d),n.append(i,o),n},scrollChatToBottom(){let e=this.elements.chatMessages;e&&requestAnimationFrame(()=>{e.scrollTop=e.scrollHeight})},formatChatTimestamp(e){if(!Number.isFinite(e))return``;try{return this.chatTimeFormatter.format(new Date(e))}catch{return``}},getChatMessageFileLabel(e){return e?this.getDisplayName(e):``},formatChatToastMessage(e){let t=e?.userName||`Someone`,n=String(e?.text??``).replace(/\s+/g,` `).trim();return`${t}: ${n.length>88?`${n.slice(0,85).trimEnd()}...`:n}`},syncChatNotificationButton(){let e=this.elements.chatNotificationButton,t=this.elements.chatNotificationMuteButton,n=this.elements.chatNotificationStatus;if(!e&&!t&&!n)return;let r=this.notifications?.getPermission?.()??`unsupported`,i=r===`granted`,a=i&&Zt()>0,o=r===`denied`,s=i?{text:a?`Alerts muted`:`Alerts on`,label:a?`Desktop alerts muted`:`Desktop alerts enabled`}:o?{text:`Alerts blocked`,label:`Desktop alerts blocked in browser settings`}:null;if(e&&(e.classList.toggle(`hidden`,r!=="default"),e.disabled=!1,e.removeAttribute(`aria-pressed`),e.textContent=`Enable desktop alerts`,e.title=`Allow desktop alerts for new chat messages`),t){t.classList.toggle(`hidden`,!i),t.disabled=!1,t.setAttribute(`aria-pressed`,String(a));let e=a?`Unmute desktop alerts`:`Mute desktop alerts for one hour`;t.setAttribute(`aria-label`,e),t.title=e}n&&(n.classList.toggle(`hidden`,!s),n.textContent=s?.text??``,s?(n.setAttribute(`aria-label`,s.label),n.title=s.label):(n.removeAttribute(`aria-label`),n.removeAttribute(`title`)),n.classList.toggle(`ui-status-badge--accent`,i&&!a),n.classList.toggle(`ui-status-badge--muted`,o||a))},async handleChatNotificationToggle(){let e=await this.notifications?.requestPermission?.();if(this.syncChatNotificationButton(),e!==`granted`){if(e===`denied`){(this.chatToastController??this.toastController)?.show(`Desktop alerts are blocked. Allow them in browser site settings.`,{duration:5e3,tone:`warning`});return}e===`unsupported`&&(this.chatToastController??this.toastController)?.show(`This browser does not support desktop alerts.`,{duration:5e3,tone:`warning`})}},toggleChatNotificationMute(){Qt(Zt()>0?0:Date.now()+Jt),this.renderChat({messagesChanged:!1})},syncChatToggleButton(){let e=this.elements.chatToggleButton,t=this.elements.chatToggleBadge;if(!e)return;let n=this.chatUnreadCount>0,r=n&&!this.chatIsOpen;e.classList.toggle(`is-active`,this.chatIsOpen),e.classList.toggle(`is-unread`,r),e.setAttribute(`aria-label`,n?`Open team chat, ${this.chatUnreadCount} unread`:`Open team chat`),e.title=this.chatUnreadCount>0?`Team chat (${this.chatUnreadCount} unread)`:`Team chat`,t&&(t.classList.toggle(`hidden`,!n),t.textContent=this.chatUnreadCount>9?`9+`:String(this.chatUnreadCount))},maybeNotifyChatMessage(e){if(!this.chatInitialSyncComplete||this.isTabActive===!1||this.chatIsOpen||Zt()>0)return;let t=!!(globalThis.document?.hidden||globalThis.document?.visibilityState===`hidden`),n=typeof globalThis.document?.hasFocus==`function`?globalThis.document.hasFocus():!t,r=null;(t||!n)&&(r=this.notifications?.show?.({body:String(e?.text??``).replace(/\s+/g,` `).trim(),onClick:()=>{window.focus?.(),r?.close?.(),this.openChatPanel()},tag:`collabmd-chat-${e?.id??`message`}`,title:`New message from ${e?.userName||`Someone`}`})),!r&&(this.chatToastController??this.toastController).show(this.formatChatToastMessage(e),4e3)}},en={createCommentThread(e){let t=this.session?.createCommentThread(e);return t&&this.scheduleCommentOverviewRefresh(),t},replyToCommentThread(e,t){let n=this.session?.replyToCommentThread(e,t);return n&&this.scheduleCommentOverviewRefresh(),n},resolveCommentThread(e){let t=this.session?.deleteCommentThread(e);return t&&this.scheduleCommentOverviewRefresh(),t},getCommentFileKind(e=this.currentFilePath){return _(e)||`markdown`},syncCommentChrome(e=this.currentFilePath){let t=a(e)&&!this.isExcalidrawFile(e);t&&globalThis.document&&(this._deferredCollabStylesPromise??=A(()=>Promise.resolve({}),__vite__mapDeps([0]),import.meta.url)),this.commentUi.setCurrentFile(e,{fileKind:this.getCommentFileKind(e),supported:t}),this.handleCommentThreadsChange(this.session?.getCommentThreads?.()??[]),this.handleCommentSelectionChange(this.session?.getCurrentSelectionCommentAnchor?.()??null)},handleCommentSelectionChange(e){this.commentUi.setSelectionAnchor(e)},handleCommentThreadsChange(e=[]){this.commentUi.setThreads(e),this.focusPendingCommentOverviewThread()},handleCommentEditorContentChange(){this.commentUi.handleEditorContentChange()},refreshCommentUiLayout(){this.commentUi.refreshLayout()},scheduleCommentOverviewRefresh({delayMs:e=900}={}){clearTimeout(this._commentOverviewRefreshTimer),this._commentOverviewRefreshTimer=setTimeout(()=>{this._commentOverviewRefreshTimer=null,this._commentOverviewStale=!1,this.commentsOverview?.refresh?.()},e)},handleCommentOverviewWorkspaceTreeChange(){this._commentOverviewStale=!0,this.activeSidebarTab===`comments`&&this.scheduleCommentOverviewRefresh({delayMs:0})},refreshCommentOverviewForSidebarOpen(){this._commentOverviewStale=!1,globalThis.document&&(this._deferredCollabStylesPromise??=A(()=>Promise.resolve({}),__vite__mapDeps([0]),import.meta.url)),this.commentsOverview?.refresh?.()},async openCommentOverviewThread({anchor:e=null,filePath:t,threadId:n}={}){if(!t||!n)return;let r=_(t)===`excalidraw`,i=Number.isFinite(e?.startLine)?e.startLine:null;if(r||(this._pendingCommentOverviewFocus={attempts:0,filePath:t,line:i,threadId:n}),this.setSidebarTab(`comments`),this.setSidebarVisibility(!0),this.workspaceRouteController?.preserveSidebarTabForNextFileRoute?.(t),this.navigation.navigateToFile(t,r?void 0:{line:i}),(this.currentFilePath!==t||!this.session)&&await this.workspaceRouteController.openFile(t),this.setSidebarTab(`comments`),this.setSidebarVisibility(!0),r){this.excalidrawEmbed?.openCommentThread?.(t,n),this.closeSidebarOnMobile?.();return}this.focusPendingCommentOverviewThread(),this.closeSidebarOnMobile?.()},focusPendingCommentOverviewThread(){let e=this._pendingCommentOverviewFocus;return!e||e.filePath!==this.currentFilePath?!1:(Number.isFinite(e.line)&&this.session?.scrollToLine?.(e.line,.2),this.commentUi.openThreadFromOverview?.(e.threadId)?(this._pendingCommentOverviewFocus=null,this.setSidebarTab(`comments`),!0):e.attempts>=8?(this._pendingCommentOverviewFocus=null,!1):(e.attempts+=1,clearTimeout(this._commentOverviewFocusTimer),this._commentOverviewFocusTimer=setTimeout(()=>{this._commentOverviewFocusTimer=null,this.focusPendingCommentOverviewThread()},120),!1))}},tn=`collabmd-export-page`,nn=`collabmd-export-host`,rn=500,an=3e5,I=new Map,on=null;function sn(){return`export-${globalThis.crypto?.randomUUID?.()??`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}`}function cn(e){return[`html`,`pdf`].includes(e)?e:`docx`}function ln({currentFilePath:e=``,currentMarkdownText:t=``,directoryPath:n=``,fileList:r=[],filePath:i,format:a,jobId:o,markdownText:s=``,title:c=``}){return{action:cn(a),currentFilePath:String(e??``),currentMarkdownText:String(t??``),directoryPath:String(n??``),fileList:Array.isArray(r)?r.slice():[],filePath:String(i??``),jobId:o,markdownText:String(s??``),source:nn,theme:`light`,title:String(c??``),type:`bootstrap`}}function un(e){e&&(e.closePollId&&window.clearInterval(e.closePollId),e.timeoutId&&window.clearTimeout(e.timeoutId))}function L(e,{notifyError:t=!1,message:n=``}={}){let r=I.get(e);r&&(un(r),I.delete(e),t&&n&&on?.(n))}function dn({onError:e=null}={}){on=typeof e==`function`?e:null,!window.__collabmdExportBridgeInitialized&&(window.addEventListener(`message`,e=>{if(e.origin!==window.location.origin)return;let t=e.data;if(!t||t.source!==tn)return;let n=String(t.jobId??``).trim();if(!n)return;let r=I.get(n);if(r){if(t.type===`ready`){if(r.window?.closed){L(n,{message:`Export window was closed before the export completed`,notifyError:!0});return}try{r.window?.postMessage(r.payload,window.location.origin)}catch(e){L(n,{message:e instanceof Error?e.message:`Failed to send export data`,notifyError:!0})}return}(t.type===`complete`||t.type===`error`)&&L(n,{message:t.type===`error`&&t.message?String(t.message):``,notifyError:t.type===`error`&&!!t.message})}}),window.__collabmdExportBridgeInitialized=!0)}async function fn(e){let t=sn(),n=globalThis.open(``,t);if(!n)throw Error(`Export popup was blocked`);return I.set(t,{closePollId:window.setInterval(()=>{n.closed&&L(t,{message:`Export window was closed before the export completed`,notifyError:!0})},rn),payload:ln({...e,jobId:t}),timeoutId:window.setTimeout(()=>{L(t,{message:`Export timed out before it completed`,notifyError:!0})},an),window:n}),n.location.replace(je(`/export-document.html`)),n.focus?.(),t}async function pn({currentFilePath:e=``,currentMarkdownText:t=``,directoryPath:n,fileList:r=[],format:i}={}){let a=String(n??``).replace(/\\/gu,`/`).replace(/^\/+|\/+$/gu,``).trim();if(!a)throw Error(`No folder was selected`);return fn({currentFilePath:e,currentMarkdownText:t,directoryPath:a,fileList:r,format:i})}async function mn({fileList:e=[],filePath:t,format:n,markdownText:r=``,title:i=``}={}){let a=String(t??``).trim();if(!a)throw Error(`No markdown note is open`);return fn({fileList:e,filePath:a,format:n,markdownText:r,title:i})}var hn={initializeExportBridge(){this._exportBridgeInitialized||=(dn({onError:e=>{this.toastController?.show(e)}}),!0)},async handleDirectoryExportRequest(e,t){try{return await pn({currentFilePath:this.currentFilePath,currentMarkdownText:this.session?.getText?.()??``,directoryPath:e,fileList:this.fileExplorer?.flatDocumentFiles??[],format:t}),!0}catch(e){return this.toastController?.show(e instanceof Error?e.message:`Failed to start folder export`),!1}},async handleExportRequest(e){let t=String(this.currentFilePath??``).trim();if(!c(t))return this.toastController?.show(`Export is available for markdown notes only`),!1;try{return await mn({fileList:this.fileExplorer?.flatDocumentFiles??[],filePath:t,format:e,markdownText:this.session?.getText?.()??``,title:this.getDisplayName(t)}),!0}catch(e){return this.toastController?.show(e instanceof Error?e.message:`Failed to start export`),!1}}};function gn(e){return e>0?`Commit ${e} file${e===1?``:`s`}`:`Commit included files`}var _n={formatPullBackupToast(e=null){let t=Number(e?.fileCount||0);return t===1?`Pulled latest changes. 1 overlapping local file was backed up.`:t>1?`Pulled latest changes. ${t} overlapping local files were backed up.`:`Pulled latest changes. Overlapping local changes were recorded in a pull backup.`},setGitOperationStatus(e=``){let t=this.elements.gitOperationStatus;if(!t)return;let n=String(e??``).trim();t.textContent=n,t.classList.toggle(`hidden`,!n)},async runGitActionWithStatus(e,t){this.setGitOperationStatus(e);try{return await t()}finally{this.setGitOperationStatus(``)}},handleGitDiffSelection(e,{closeSidebarOnMobile:t=!1,scope:n=`working-tree`}={}){t&&this.closeSidebarOnMobile(),this.navigation.navigateToGitDiff({filePath:e,scope:n})},handleGitCommitSelection(e,{closeSidebarOnMobile:t=!1,historyFilePath:n=null,path:r=null}={}){t&&this.closeSidebarOnMobile(),this.navigation.navigateToGitCommit({hash:e,historyFilePath:n,path:r})},handleGitHistorySelection({closeSidebarOnMobile:e=!1}={}){e&&this.closeSidebarOnMobile(),this.navigation.navigateToGitHistory()},handleGitFileHistorySelection(e=this.currentFilePath,{closeSidebarOnMobile:t=!1}={}){t&&this.closeSidebarOnMobile(),e&&this.navigation.navigateToGitFileHistory({filePath:e})},handleGitFilePreviewSelection({hash:e,path:t,currentFilePath:n=null,closeSidebarOnMobile:r=!1}={}){r&&this.closeSidebarOnMobile(),e&&t&&this.navigation.navigateToGitFilePreview({hash:e,path:t,currentFilePath:n})},handleGitRepoChange(e,t=null){this.gitRepoAvailable=!!e,this.elements.sidebarTabs?.classList.remove(`hidden`),this.elements.gitSidebarTab?.classList.toggle(`hidden`,!this.gitRepoAvailable);let n=e&&t?.summary?.changedFiles>0;if(this.elements.gitSidebarTab?.classList.toggle(`has-changes`,n),this.gitDiffView.setRepoStatus(this.gitRepoAvailable?t:null),this.syncReviewFileChangesButton(),!this.gitRepoAvailable&&this.activeSidebarTab===`git`){this.syncFileHistoryButton({mode:this.navigation.getHashRoute().type===`git-file-preview`?`history-preview`:`editor`}),this.setSidebarTab(`files`);return}let r=this.navigation.getHashRoute().type;this.gitRepoAvailable&&(r===`git-diff`||r===`git-commit`||r===`git-history`)&&this.activeSidebarTab!==`git`&&this.setSidebarTab(`git`),this.syncFileHistoryButton({filePath:this.currentFilePath,mode:r===`git-file-preview`?`history-preview`:r===`file`?`editor`:`empty`})},syncFileHistoryButton({filePath:e=this.currentFilePath,mode:t=`editor`}={}){let n=this.elements.fileHistoryButton,r=this.elements.fileHistoryButtonLabel;if(n&&r){if(!(this.gitRepoAvailable&&this.supportsFileHistory?.(e))){n.classList.add(`hidden`);return}if(n.classList.remove(`hidden`),t===`history-preview`){r.textContent=`Back to history`,n.setAttribute(`aria-label`,`Back to file history`),n.title=`Back to file history`;return}if(t!==`editor`){n.classList.add(`hidden`);return}r.textContent=`History`,n.setAttribute(`aria-label`,`Open file history`),n.title=`View file history`}},syncReviewFileChangesButton({filePath:e=this.currentFilePath,mode:t=`editor`}={}){let n=this.elements.reviewFileChangesButton;n&&n.classList.toggle(`hidden`,!this.gitRepoAvailable||t!==`editor`||!e)},syncMainChrome({badgeLabel:e=``,mode:t,title:n=null}={}){let r=t===`diff`||t===`history`||t===`history-preview`,i=r||t===`editor`&&this.isCanvasFile?.(this.currentFilePath);this.elements.toolbarViewToggle?.classList.toggle(`hidden`,!!i),this.elements.mobileViewToggle?.classList.toggle(`hidden`,!!i),this.elements.userCount?.classList.toggle(`hidden`,r),this.elements.toolbarDiffBadge?.classList.toggle(`hidden`,!e),this.elements.toolbarDiffBadge&&(this.elements.toolbarDiffBadge.textContent=e),n&&this.elements.activeFileName&&(this.elements.activeFileName.textContent=n),this.syncFileHistoryButton({filePath:this.currentFilePath,mode:t}),this.syncReviewFileChangesButton({filePath:this.currentFilePath,mode:t})},async showGitDiff({filePath:e=null,scope:t=`all`}={}){this.clearStaticPreviewDocument?.(),this.gitPanel.setSelection(e?{path:e,scope:t,source:`workspace`}:{}),this.gitPanel.setMode(`changes`),this.showDiffState(),this.syncMainChrome({badgeLabel:`Diff`,mode:`diff`,title:this.gitDiffView.getToolbarTitle({filePath:e,scope:t})}),this.syncFileHistoryButton({filePath:e,mode:`diff`}),await this.gitDiffView.openWorkspaceDiff({filePath:e,scope:t})},async showGitCommit({hash:e,path:t=null,historyFilePath:n=null}={}){this.clearStaticPreviewDocument?.(),this.gitPanel.setMode(`history`),this.gitPanel.setSelection(e?{commitHash:e,path:t,source:`commit`}:{source:`commit`}),this.showDiffState(),this.syncMainChrome({badgeLabel:`Diff`,mode:`diff`,title:this.gitDiffView.getToolbarTitle({commitHash:e,path:t,source:`commit`})}),this.syncFileHistoryButton({filePath:t,mode:`diff`}),await this.gitDiffView.openCommitDiff({hash:e,historyFilePath:n,path:t})},async showGitHistory(){this.clearStaticPreviewDocument?.(),this.gitPanel.setMode(`history`),this.gitPanel.setSelection({source:`commit`}),this.workspaceRouteController?.showEmptyState?.(),this.syncMainChrome({mode:`empty`,title:`Git History`}),this.syncFileHistoryButton({mode:`empty`})},async showGitFileHistory({filePath:e=null}={}){if(!e){this.workspaceRouteController?.showEmptyState?.();return}this.clearStaticPreviewDocument?.(),this.commentUi?.attachSession?.(null),this.commentUi?.setCurrentFile?.(e,{fileKind:this.getCommentFileKind(e),supported:!1}),this.handleCommentThreadsChange?.([]),this.handleCommentSelectionChange?.(null),this.workspaceRouteController?.showFileHistoryState?.(e),this.syncMainChrome({badgeLabel:`History`,mode:`history`,title:this.getDisplayName(e)}),this.syncFileHistoryButton({filePath:e,mode:`history`}),await this.fileHistoryView.openFileHistory({filePath:e})},async _loadGitFileSnapshot({hash:e,filePath:t,resolvedCurrentFilePath:n}){let r=await this.gitApiClient.readFileSnapshot({hash:e,path:t});if(this.setStaticPreviewDocument?.({...r,currentFilePath:n}),this.workspacePreviewController.resetPreviewMode(),this.elements.markdownToolbar?.classList.add(`hidden`),this.elements.outlineToggle?.classList.toggle(`hidden`,r.fileKind!==`markdown`),r.fileKind===`markdown`||r.fileKind===`mermaid`||r.fileKind===`plantuml`){r.fileKind===`mermaid`?this.elements.previewContent?.classList.add(`is-mermaid-file-preview`):r.fileKind===`plantuml`&&this.elements.previewContent?.classList.add(`is-plantuml-file-preview`),this.previewRenderer.beginDocumentLoad(),this.previewRenderer.queueRender();return}this.elements.outlineToggle?.classList.add(`hidden`),this.workspacePreviewController.renderTextFilePreview({content:r.content,filePath:n})},_handleGitFilePreviewError(e,t){console.error(`[git-preview] Failed to load file snapshot:`,e),this.clearStaticPreviewDocument?.(),this.toastController.show(`Failed to load historical file preview`),this.workspacePreviewController.renderTextFilePreview({content:`Failed to load historical file preview.`,filePath:t}),this.elements.outlineToggle?.classList.add(`hidden`)},async showGitFilePreview({hash:e,filePath:t=null,currentFilePath:n=null}={}){let r=String(n??``).trim()||t;if(!e||!t||!r){this.workspaceRouteController?.showEmptyState?.();return}this.commentUi?.attachSession?.(null),this.commentUi?.setCurrentFile?.(r,{fileKind:this.getCommentFileKind(r),supported:!1}),this.handleCommentThreadsChange?.([]),this.handleCommentSelectionChange?.(null),this.workspaceRouteController?.showPreviewOnlyState?.(r),this.layoutController.setView(`preview`,{persist:!1}),this.syncMainChrome({badgeLabel:`History Preview`,mode:`history-preview`,title:this.getDisplayName(r)}),this.syncFileHistoryButton({filePath:r,mode:`history-preview`});try{await this._loadGitFileSnapshot({hash:e,filePath:t,resolvedCurrentFilePath:r})}catch(e){this._handleGitFilePreviewError(e,r)}},async postGitAction(e,t){let n=crypto.randomUUID();this.pendingWorkspaceRequestIds?.add(n);try{switch(e){case`stage`:return await this.gitApiClient.stageFile({path:t.path,requestId:n});case`unstage`:return await this.gitApiClient.unstageFile({path:t.path,requestId:n});case`stage-all`:return await this.gitApiClient.stageAll({requestId:n});case`unstage-all`:return await this.gitApiClient.unstageAll({requestId:n});case`push`:return await this.gitApiClient.pushBranch({requestId:n});case`pull`:return await this.gitApiClient.pullBranch({requestId:n});case`reset-file`:return await this.gitApiClient.resetFile({path:t.path,requestId:n});case`commit`:return await this.gitApiClient.commit({message:t.message,requestId:n});default:throw Error(`Unsupported git action: ${e}`)}}catch(e){throw this.pendingWorkspaceRequestIds?.delete(n),e}},async refreshWorkspaceAfterGitAction({filePath:e=null,preferredScope:t=null}={}){await this.fileExplorer.refresh(),await this.refreshGitAfterAction({filePath:e,preferredScope:t})},async refreshGitAfterAction({filePath:e=null,preferredScope:t=null}={}){await this.gitPanel.refresh({force:!0});let n=this.navigation.getHashRoute();if(n.type===`git-history`){await this.showGitHistory();return}if(n.type===`git-file-history`){await this.showGitFileHistory({filePath:n.filePath});return}if(n.type===`git-file-preview`){await this.showGitFilePreview({hash:n.hash,filePath:n.filePath,currentFilePath:n.currentFilePath});return}if(n.type===`git-commit`){await this.showGitCommit({hash:n.hash,path:n.path,historyFilePath:n.historyFilePath});return}if(n.type!==`git-diff`)return;let r=e??n.filePath,i=t??n.scope;if(i!==n.scope||r!==n.filePath){this.navigation.navigateToGitDiff({filePath:r,scope:i});return}await this.showGitDiff({filePath:n.filePath,scope:n.scope})},async finalizeGitAction({action:e,filePath:t=null,preferredScope:n=null,result:r={},showLocalFileToast:i=!1}={}){let a=St(r.workspaceChange);return await this.refreshWorkspaceAfterGitAction({filePath:t,preferredScope:n}),this.handleWorkspaceChangeForCurrentFile(a,{action:e,local:!0,showToast:i}),a},handleWorkspaceChangeForCurrentFile(e,{action:t=`git`,local:n=!1,showToast:r=!0}={}){let i=this.currentFilePath;if(!i)return!1;let a=e.deletedPaths.includes(i),o=e.renamedPaths.find(e=>e.oldPath===i);if(!a&&!o)return!1;if(!r)return o?this.navigation.navigateToFile(o.newPath):this.navigation.navigateToFile(null),!0;let s=this.getDisplayName(i);return o?(this.navigation.navigateToFile(o.newPath),this.toastController.show(n?`${s} moved to ${this.getDisplayName(o.newPath)}`:`${s} moved on disk`),!0):(this.navigation.navigateToFile(null),this.toastController.show(n?`${s} was removed by ${t}`:`${s} was removed after a ${t} operation`),!0)},async handleIncomingWorkspaceEvent(e){if(!this.isTabActive||!e)return;if(e.requestId&&this.pendingWorkspaceRequestIds?.has(e.requestId)){this.pendingWorkspaceRequestIds.delete(e.requestId);return}let t=St(e.workspaceChange);e.origin===`git`&&await this.refreshGitAfterAction(),this.handleWorkspaceChangeForCurrentFile(t,{action:e.action||e.origin||`workspace`,local:!1,showToast:!0});let n=[...t.changedPaths,...t.deletedPaths,...t.renamedPaths.flatMap(e=>[e.oldPath,e.newPath])].some(e=>/(?:\.dsl$|(?:^|\/)workspace\.json$)/iu.test(e));if(this.currentFilePath&&this.isStructurizrWorkspaceFile?.(this.currentFilePath)&&n&&this.structurizrPreview?.queueSync({filePath:this.currentFilePath,source:this.session?.getText?.()??``}),e.origin===`filesystem`&&this.currentFilePath&&t.changedPaths.includes(this.currentFilePath)){let n=t.changedPaths.length===1&&Array.isArray(e.highlightRanges)?e.highlightRanges.find(e=>e.path===this.currentFilePath):null;n&&this.session?.flashExternalUpdate?.(n)||this.toastController.show(`${this.getDisplayName(this.currentFilePath)} updated from disk`)}this.currentFilePath&&Array.isArray(e.reloadRequiredPaths)&&e.reloadRequiredPaths.includes(this.currentFilePath)&&this.toastController.show(`${this.getDisplayName(this.currentFilePath)} needs a manual reload`)},async stageGitFile(e,{scope:t=`working-tree`}={}){e&&await this.runGitActionWithStatus(`Staging changes...`,async()=>{let n=await this.postGitAction(`stage`,{path:e});await this.finalizeGitAction({action:`stage`,filePath:e,preferredScope:t===`all`?`all`:`staged`,result:n})})},async unstageGitFile(e,{scope:t=`staged`}={}){e&&await this.runGitActionWithStatus(`Unstaging changes...`,async()=>{let n=await this.postGitAction(`unstage`,{path:e});await this.finalizeGitAction({action:`unstage`,filePath:e,preferredScope:t===`all`?`all`:`working-tree`,result:n})})},async stageAllGitFiles(){await this.runGitActionWithStatus(`Staging all changes...`,async()=>{let e=await this.postGitAction(`stage-all`,{});await this.finalizeGitAction({action:`stage-all`,preferredScope:`staged`,result:e})})},async unstageAllGitFiles(){await this.runGitActionWithStatus(`Unstaging all changes...`,async()=>{let e=await this.postGitAction(`unstage-all`,{});await this.finalizeGitAction({action:`unstage-all`,preferredScope:`working-tree`,result:e})})},async pushGitBranch(){await this.runGitActionWithStatus(`Pushing branch...`,async()=>{try{let e=await this.postGitAction(`push`,{});await this.finalizeGitAction({action:`push`,result:e})}catch(e){this.toastController.show(e.message||`Failed to push branch`)}})},async pullGitBranch(){await this.runGitActionWithStatus(`Pulling branch...`,async()=>{try{let e=await this.postGitAction(`pull`,{});await this.finalizeGitAction({action:`pull`,result:e,showLocalFileToast:!0}),e.pullBackup&&this.toastController.show(this.formatPullBackupToast(e.pullBackup),5e3)}catch(e){if(e?.code===`pull_conflicted_commits`){this.toastController.show(`Cannot pull automatically because local and remote commits conflict.`,5e3);return}if(e?.code===`pull_conflicted_after_autostash`){this.toastController.show(`Pull updated the branch, but reapplying local changes caused conflicts. Review the conflicted files and the pull backup summary.`,6e3);return}this.toastController.show(e.message||`Failed to pull branch`)}})},openGitResetDialog(e){if(!this.isTabActive||!e)return;let t=this.elements.gitResetDialog;t&&this.elements.gitResetFileName&&(this.pendingGitResetPath=e,this.elements.gitResetTitle&&(this.elements.gitResetTitle.textContent=`Reset file to current branch`),this.elements.gitResetCopy&&(this.elements.gitResetCopy.textContent=`Restore this file from the current checked-out branch. If this branch does not contain the file, the file will be deleted locally.`),this.elements.gitResetFileName.value=e,this.elements.gitResetSubmit&&(this.elements.gitResetSubmit.textContent=`Reset file`),this.elements.gitResetSubmit?.toggleAttribute(`disabled`,!1),!t.open&&(typeof t.showModal==`function`?t.showModal():t.setAttribute(`open`,`true`)))},async handleGitResetSubmit(){let e=this.pendingGitResetPath,t=this.elements.gitResetDialog,n=this.elements.gitResetSubmit;if(e&&t){n?.toggleAttribute(`disabled`,!0),n&&(n.textContent=`Resetting…`);try{await this.runGitActionWithStatus(`Resetting file…`,async()=>{let t=await this.postGitAction(`reset-file`,{path:e});await this.finalizeGitAction({action:`reset`,filePath:e,result:t,showLocalFileToast:!0})}),t.close()}catch(e){this.toastController.show(e.message||`Failed to reset file`)}finally{n&&(n.textContent=`Reset file`),n?.toggleAttribute(`disabled`,!1)}}},openGitCommitDialog(){if(!this.isTabActive)return;let e=this.elements.gitCommitDialog,t=this.elements.gitCommitInput;if(!e||!t)return;let n=Number(this.gitPanel.status?.summary?.staged||0),r=gn(n);this.elements.gitCommitTitle&&(this.elements.gitCommitTitle.textContent=r),this.elements.gitCommitCopy&&(this.elements.gitCommitCopy.textContent=n>0?`This commit will include ${n} file${n===1?``:`s`}.`:`All included changes will be committed.`),this.elements.gitCommitSubmit&&(this.elements.gitCommitSubmit.textContent=r),t.value=``,!e.open&&(typeof e.showModal==`function`?e.showModal():e.setAttribute(`open`,`true`),requestAnimationFrame(()=>{t.focus(),t.select()}))},async handleGitCommitSubmit(){let e=this.elements.gitCommitDialog,t=this.elements.gitCommitInput,n=this.elements.gitCommitSubmit,r=String(t?.value??``).trim();if(e&&t){if(!r){t.focus(),this.toastController.show(`Describe what changed before committing`);return}n?.toggleAttribute(`disabled`,!0),n&&(n.textContent=`Committing...`);try{await this.runGitActionWithStatus(`Committing changes...`,async()=>{let e=await this.postGitAction(`commit`,{message:r});await this.finalizeGitAction({action:`commit`,result:e})}),e.close()}catch(e){this.toastController.show(e.message||`Failed to commit included changes`)}finally{n&&(n.textContent=`Commit included files`),n?.toggleAttribute(`disabled`,!1)}}}},vn=5;function yn(e,t){return String(e?.name??``).localeCompare(String(t?.name??``),void 0,{sensitivity:`base`})}function bn(e){let t=!!e.session,n=!!(e.currentFilePath&&e.isDrawioFile?.(e.currentFilePath)),r=!!(e.currentFilePath&&e.isExcalidrawFile?.(e.currentFilePath)),i=!!(e.currentFilePath&&e.isImageFile?.(e.currentFilePath)),a=!!(e.currentFilePath&&e.isPdfFile?.(e.currentFilePath));return!t&&(!e.currentFilePath||n||r||i||a)?e.lobby?.getConnectionState?.()??e.connectionState:e.connectionState}function xn(e,t){let n=[...e],r=n.findIndex(e=>e.isLocal);if(r>0){let[e]=n.splice(r,1);n.unshift(e)}let i=n.findIndex(e=>!e.isLocal&&e.clientId===t),a=+!!n[0]?.isLocal;if(i>a){let[e]=n.splice(i,1);n.splice(a,0,e)}return n}function Sn(e,t){let n=e.filter(e=>e.isLocal).sort(yn),r=e.filter(e=>!e.isLocal),i=r.filter(e=>e.clientId===t).sort(yn),a=r.filter(e=>e.clientId!==t).sort(yn);return[...n,...i,...a]}function Cn(e,t){return t.currentFile&&t.currentFile===e.currentFilePath?`Here`:t.currentFile?e.getDisplayName(t.currentFile):`No file`}var wn={updateGlobalUsers(e){this.globalUsers=e,this.syncFollowedUser(),this.renderAvatars(),this.renderChat({messagesChanged:!1}),this.renderPresence(),this.syncCurrentUserName()},updateFileAwareness(e){this.syncFollowedUser()},renderPresence(){let e=this.elements.userCount;if(!e)return;let t=bn(this),n=this.globalUsers.length>0;if(t.status!==`connected`&&this.closePresencePanel(),e.type=`button`,e.classList.toggle(`is-active`,this.presencePanelOpen),t.status===`connected`){e.textContent=`${this.globalUsers.length} online`,e.style.opacity=`1`,e.disabled=!n,e.setAttribute(`aria-label`,`Show ${this.globalUsers.length} online users`),this.renderPresencePanel();return}if(t.status===`connecting`){e.textContent=t.unreachable?`Unreachable`:`Connecting...`,e.style.opacity=`0.6`,e.disabled=!0,e.setAttribute(`aria-label`,e.textContent),this.renderPresencePanel();return}e.textContent=`Offline`,e.style.opacity=`0.6`,e.disabled=!0,e.setAttribute(`aria-label`,`Offline`),this.renderPresencePanel()},renderAvatars(){let e=this.elements.userAvatars;if(!e)return;e.replaceChildren();let n=xn(this.globalUsers,this.followedUserClientId);if(n.slice(0,vn).forEach(n=>{let r=document.createElement(n.isLocal?`div`:`button`);r.className=`user-avatar`,r.classList.toggle(`is-local`,n.isLocal),r.style.backgroundColor=n.color,r.style.color=t(n.color),r.classList.toggle(`is-following`,n.clientId===this.followedUserClientId);let i=document.createElement(`span`);i.className=`user-avatar-initial`,i.textContent=n.name.charAt(0).toUpperCase(),r.appendChild(i);let a=n.currentFile&&n.currentFile===this.currentFilePath,o=n.currentFile?this.getDisplayName(n.currentFile):`No file`;if(n.isLocal){let e=document.createElement(`span`);e.className=`user-avatar-self-label`,e.textContent=`You`,r.appendChild(e),r.title=`${n.name} (you) — ${o}`,r.setAttribute(`role`,`img`),r.setAttribute(`aria-label`,`${n.name} (you) — ${o}`)}else{r.type=`button`,r.classList.add(`user-avatar-button`),a||r.classList.add(`different-file`);let e=n.clientId===this.followedUserClientId?`Stop following ${n.name}`:a?`Follow ${n.name}`:`Follow ${n.name} — ${o}`;r.title=e,r.setAttribute(`aria-label`,e),r.addEventListener(`click`,()=>this.toggleFollowUser(n.clientId))}e.appendChild(r)}),n.length>vn){let t=document.createElement(`button`);t.type=`button`,t.className=`user-avatar user-avatar-button user-avatar-overflow-trigger`,t.style.backgroundColor=`var(--color-surface-dynamic)`,t.style.color=`var(--color-text-muted)`,t.setAttribute(`popovertarget`,`presencePanel`),t.setAttribute(`aria-label`,`Show ${n.length} online users`),t.title=`Show ${n.length} online users`;let r=document.createElement(`span`);r.className=`user-avatar-initial`,r.textContent=`+${n.length-vn}`,t.appendChild(r),e.appendChild(t)}},openPresencePanel(){bn(this).status===`connected`&&this.globalUsers.length!==0&&(this.presencePanelOpen=!0,this.elements.presencePanel?.matches(`:popover-open`)||this.elements.presencePanel?.showPopover(),this.renderAvatars(),this.renderPresence())},closePresencePanel(){this.elements.presencePanel?.matches(`:popover-open`)&&this.elements.presencePanel.hidePopover(),this.presencePanelOpen=!1,this.renderAvatars?.()},renderPresencePanel(){let e=this.elements.presencePanel,n=this.elements.presencePanelList,r=this.elements.presencePanelStatus;if(!e||!n||!this.presencePanelOpen)return;let i=Sn(this.globalUsers,this.followedUserClientId),a=bn(this);if(r){if(a.status===`connected`){let e=this.globalUsers.filter(e=>!e.isLocal).length;r.textContent=e===0?`You’re the only person here right now.`:`${e} ${e===1?`teammate`:`teammates`} online. Select someone to follow.`}else r.textContent=a.status===`connecting`?a.unreachable?`Server unreachable.`:`Connecting presence...`:`Presence is offline.`}if(n.replaceChildren(),i.length===0){let e=document.createElement(`div`);e.className=`presence-panel-empty-state`,e.textContent=a.status===`connected`?`Nobody else is here yet.`:`Presence will appear here when the connection is active.`,n.appendChild(e);return}let o=document.createDocumentFragment();i.forEach(e=>{let n=document.createElement(`article`);n.className=`presence-panel-user`,n.classList.toggle(`is-local`,e.isLocal),n.classList.toggle(`is-following`,e.clientId===this.followedUserClientId);let r=document.createElement(e.isLocal?`div`:`button`);r.className=`presence-panel-user-button`;let i=document.createElement(`span`);i.className=`presence-panel-user-avatar`,i.style.backgroundColor=e.color,i.style.color=t(e.color),i.textContent=e.name.charAt(0).toUpperCase(),i.setAttribute(`aria-hidden`,`true`);let a=document.createElement(`span`);a.className=`presence-panel-user-body`;let s=document.createElement(`span`);s.className=`presence-panel-user-topline`;let c=document.createElement(`span`);if(c.className=`presence-panel-user-name`,c.textContent=e.name,s.appendChild(c),e.isLocal){let e=document.createElement(`span`);e.className=`presence-panel-user-badge`,e.textContent=`You`,s.appendChild(e)}else if(e.clientId===this.followedUserClientId){let e=document.createElement(`span`);e.className=`presence-panel-user-badge`,e.textContent=`Following`,s.appendChild(e)}let l=document.createElement(`span`);if(l.className=`presence-panel-user-file`,l.textContent=Cn(this,e),a.append(s,l),r.append(i,a),e.isLocal)r.setAttribute(`role`,`group`),r.setAttribute(`aria-label`,`${e.name} (you) — ${l.textContent}`);else{let t=e.clientId===this.followedUserClientId;r.type=`button`,r.setAttribute(`aria-label`,t?`Keep following ${e.name}`:`Follow ${e.name} — ${l.textContent}`),r.addEventListener(`click`,()=>{this.startFollowingUser(e.clientId,{closePanel:!0})})}if(n.appendChild(r),!e.isLocal&&e.clientId===this.followedUserClientId){let t=document.createElement(`button`);t.type=`button`,t.className=`presence-panel-user-stop`,t.textContent=`Stop`,t.setAttribute(`aria-label`,`Stop following ${e.name}`),t.addEventListener(`click`,e=>{e.stopPropagation(),this.stopFollowingUser({closePanel:!0})}),n.appendChild(t)}o.appendChild(n)}),n.appendChild(o)},startFollowingUser(e,{closePanel:t=!1}={}){if(!e)return;let n=this.globalUsers.find(t=>t.clientId===e&&!t.isLocal);if(n){if(this.followedUserClientId=e,this.followedCursorSignature=``,t&&this.presencePanelOpen?this.closePresencePanel():(this.renderAvatars(),this.renderPresencePanel()),n.currentFile&&n.currentFile!==this.currentFilePath){this.navigation.navigateToFile(n.currentFile,{preserveFollow:!0});return}requestAnimationFrame(()=>{this.followedUserClientId===e&&this.followUserCursor(n,{force:!0})})}},toggleFollowUser(e){if(e){if(this.followedUserClientId===e){this.stopFollowingUser();return}this.startFollowingUser(e)}},stopFollowingUser({closePanel:e=!1}={}){this.followedUserClientId&&(this.currentFilePath&&this.isExcalidrawFile?.(this.currentFilePath)&&this.excalidrawEmbed?.setFollowedUser(this.currentFilePath,null),this.followedUserClientId=null,this.followedCursorSignature=``,e&&this.presencePanelOpen?this.closePresencePanel():(this.renderAvatars(),this.renderPresencePanel()))},syncFollowedUser(){if(!this.followedUserClientId)return;let e=this.globalUsers.find(e=>e.clientId===this.followedUserClientId);if(!e||e.isLocal){this.stopFollowingUser();return}if(e.currentFile&&e.currentFile!==this.currentFilePath){this.navigation.navigateToFile(e.currentFile,{preserveFollow:!0});return}this.followUserCursor(e)},followUserCursor(e,{force:t=!1}={}){if(this.currentFilePath&&this.isExcalidrawFile?.(this.currentFilePath)){this.followExcalidrawUser(e,{force:t});return}let n=this.resolveFileClientId(e.peerId),r=n==null?null:this.session?.getUserViewport(n),i=n==null?null:this.session?.getUserCursor(n),a=i?.cursorHead??null,o=i?.cursorLine??null,s=i?.cursorAnchor??null,c=r?.topLine??null,l=r?.viewportRatio??.35;if(!e||c==null&&(a==null||o==null)){this.followedCursorSignature=``;return}let u=`${e.clientId}:${c??`no-viewport`}:${s??`no-anchor`}:${a??`no-head`}`;(t||u!==this.followedCursorSignature)&&(n!=null&&this.session?.scrollToUserViewport(n)||n!=null&&this.session?.scrollToUserCursor(n,`center`)||a!=null&&this.session?.scrollToPosition(a,`center`)||o!=null&&this.session?.scrollToLine(o,l))&&(this.followedCursorSignature=u)},followExcalidrawUser(e,{force:t=!1}={}){if(!e?.peerId||!this.currentFilePath){this.followedCursorSignature=``;return}let n=`excalidraw:${this.currentFilePath}:${e.peerId}`;(t||n!==this.followedCursorSignature)&&Promise.resolve(this.excalidrawEmbed?.setFollowedUser(this.currentFilePath,e.peerId)).then(t=>{t!==!1&&this.followedUserClientId===e.clientId&&(this.followedCursorSignature=n)}).catch(()=>{})},resolveFileClientId(e){if(!e||!this.session?.awareness)return null;for(let[t,n]of this.session.awareness.getStates())if(n.user?.peerId===e)return t;return null}};function Tn(){return this.runtimeConfig?.auth?.strategy===`oidc`&&this.runtimeConfig?.auth?.provider===`google`}function En({mode:e=`edit`}={}){if(this.isIdentityManagedByAuth()||!this.isTabActive)return;let t=this.elements.displayNameDialog,n=this.elements.displayNameInput,r=this.elements.displayNameTitle,i=this.elements.displayNameCopy,a=this.elements.displayNameCancel,o=this.elements.displayNameSubmit;if(!t||!n)return;let s=e===`onboarding`;this._displayNameDialogMode=e,r&&(r.textContent=s?`Choose your display name`:`Update display name`),i&&(i.textContent=s?`Pick a name collaborators will see. You can skip for now and continue as a guest.`:`Your name will be visible to everyone editing this vault.`),a&&(a.textContent=s?`Skip for now`:`Cancel`),o&&(o.textContent=s?`Continue`:`Save name`),n.value=s?``:this.getCurrentUserName(),!t.open&&(typeof t.showModal==`function`?t.showModal():t.setAttribute(`open`,`true`),requestAnimationFrame(()=>{n.focus(),n.select()}))}function Dn(){!this.isTabActive||this._hasPromptedForDisplayName||this.getStoredUserName()||this.isIdentityManagedByAuth()||(this._hasPromptedForDisplayName=!0,requestAnimationFrame(()=>{this.openDisplayNameDialog({mode:`onboarding`})}))}function On(){if(this._displayNameDialogMode===`onboarding`&&!this.getStoredUserName()){let e=this.getCurrentUserName();e&&this.preferences.setUserName(e)}this.elements.displayNameDialog?.close()}function kn(){if(this.isIdentityManagedByAuth())return;let t=this.elements.displayNameInput,n=this.elements.displayNameDialog;if(!t||!n)return;let r=this.session?this.session.setUserName(t.value):e(t.value);if(!r){t.focus(),this.toastController.show(`Name must be 1-24 characters`);return}this.preferences.setUserName(r),this.lobby.setUserName(r);let i=this.lobby.getLocalUser();this.drawioEmbed?.updateLocalUser(i),this.excalidrawEmbed?.updateLocalUser(i),this.canvasEmbed?.updateLocalUser(i),this.syncCurrentUserName(),this.renderChat(),n.close()}function An(){return this.globalUsers.find(e=>e.isLocal)??this.session?.getLocalUser()??this.lobby?.getLocalUser()??null}function jn(){return this.getCurrentUser()?.name??this.getStoredUserName()??``}function Mn(){return this.preferences.getUserName()}function Nn(){let e=this.elements.currentUserName;if(!e)return;let t=this.getCurrentUserName();e.textContent=t||`Set name`,e.classList.toggle(`has-name`,!!t),this.isIdentityManagedByAuth()||this.elements.editNameButton?.setAttribute(`aria-label`,`${t||`Set name`}. Change display name`)}function Pn(){let e=this.isIdentityManagedByAuth();this.elements.editNameButton?.classList.toggle(`hidden`,e),this.elements.editNameButton?.toggleAttribute(`disabled`,e),e&&this.elements.displayNameDialog?.open&&this.elements.displayNameDialog.close()}var Fn={getCurrentUser:An,getCurrentUserName:jn,getStoredUserName:Mn,handleDisplayNameCancel:On,handleDisplayNameSubmit:kn,isIdentityManagedByAuth:Tn,openDisplayNameDialog:En,promptForDisplayNameIfNeeded:Dn,syncCurrentUserName:Nn,syncIdentityManagementUi:Pn},In=0,Ln=2e3,Rn=8,zn=`
|
|
5
|
+
<svg viewBox="0 0 24 24" width="14" height="14" aria-hidden="true" focusable="false">
|
|
6
|
+
<rect x="8" y="8" width="11" height="11" rx="2" fill="none" stroke="currentColor" stroke-width="2"/>
|
|
7
|
+
<path d="M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
|
8
|
+
</svg>
|
|
9
|
+
`,Bn=`
|
|
10
|
+
<svg viewBox="0 0 24 24" width="15" height="15" aria-hidden="true" focusable="false">
|
|
11
|
+
<path d="M10 13.5 14 9.5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
|
12
|
+
<path d="M9.35 7.55 10.6 6.3a4.2 4.2 0 0 1 5.95 5.95l-1.25 1.25" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
|
13
|
+
<path d="m14.65 16.45-1.25 1.25a4.2 4.2 0 0 1-5.95-5.95L8.7 10.5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
|
14
|
+
</svg>
|
|
15
|
+
`;async function Vn(){await this.hostedGateController?.initialize(),this.initializeExportBridge?.(),this.renderMarkdownToolbar?.(),this.initializeVisualViewportBinding?.(),this.themeController.initialize(),this.previewRenderer.applyTheme(this.themeController.getTheme()),this.outlineController.initialize(),this.layoutController.initialize(),this.scrollSyncController.initialize(),this.fileExplorer.initialize(),this.gitPanel.initialize(),this.gitDiffView.initialize(),this.fileHistoryView.initialize(),this.commentsOverview?.initialize?.(),this.initializePreviewLayoutObserver(),this.syncIdentityManagementUi(),this.syncCurrentUserName(),this.syncCursorNamesToggle(),this.syncWrapToggle(),this.syncVimModeToggle(),this.syncToolbarOverflowVisibility?.(),this.syncFileHistoryButton({mode:`empty`}),this.renderChat(),this.elements.chatInput?.setAttribute(`maxlength`,String(this.lobbyChatMessageMaxLength)),this.bindEvents(),this.initializeSidebarResizer?.(),this.restoreSidebarState(),this.initializeVersionMonitoring(),this.tabActivityLock.initialize(),this.tabActivityLock.tryActivate(),window.addEventListener(`hashchange`,()=>this.workspaceRouteController.handleHashChange());let e=this.createResizeHandler();window.addEventListener(`resize`,()=>{e(),this.syncToolbarOverflowVisibility?.()}),this.runtimeConfig?.gitEnabled!==!1&&(this.gitRepoAvailable=!0,this.elements.gitSidebarTab?.classList.remove(`hidden`),this.elements.sidebarTabs?.classList.remove(`hidden`)),this.fileExplorerReadyPromise=this.fileExplorer.refresh().then(()=>{if(this.fileExplorerReady=!0,this.commentsOverview?.refresh?.(),He(this.navigation.getHashRoute().type)&&this.gitPanel.refresh({force:!1}),this.isTabActive)return this.workspaceRouteController.handleHashChange()})}function Hn(){this.versionMonitor?.start()}function Un(){let e=document.documentElement,t=window.visualViewport;if(e){if(!t){e.style.setProperty(`--app-viewport-height`,`100dvh`),e.style.setProperty(`--app-viewport-offset-top`,`0px`);return}e.style.setProperty(`--app-viewport-height`,`${Math.round(t.height)}px`),e.style.setProperty(`--app-viewport-offset-top`,`${Math.round(t.offsetTop)}px`)}}function Wn(){this.syncVisualViewportBounds?.();let e=window.visualViewport;if(!e)return;let t=()=>this.syncVisualViewportBounds?.();e.addEventListener(`resize`,t,{passive:!0}),e.addEventListener(`scroll`,t,{passive:!0}),window.addEventListener(`orientationchange`,t)}function Gn(e=null){if(this._reloadPromptShown)return;this._reloadPromptShown=!0;let t=String(e?.build?.packageVersion??this.runtimeConfig?.build?.packageVersion??``).trim(),n=t?`Version ${t} is available. Reload to update.`:`A new version is available. Reload to update.`;this.toastController.show(n,{actionLabel:`Reload`,dismissible:!0,duration:In,onAction:()=>window.location.reload()})}function Kn(){let e=()=>{this.toggleQuickSwitcher(),this.closeToolbarOverflowMenu?.()};this.elements.shareButton?.addEventListener(`click`,()=>{this.copyCurrentLink(),this.closeToolbarOverflowMenu?.()}),this.elements.toolbarSearchButton?.addEventListener(`click`,e),this.elements.searchFilesButton?.addEventListener(`click`,e),this.elements.exportHtmlButton?.addEventListener(`click`,()=>{this.handleExportRequest?.(`html`),this.closeToolbarOverflowMenu?.()}),this.elements.exportDocxButton?.addEventListener(`click`,()=>{this.handleExportRequest?.(`docx`),this.closeToolbarOverflowMenu?.()}),this.elements.exportPdfButton?.addEventListener(`click`,()=>{this.handleExportRequest?.(`pdf`),this.closeToolbarOverflowMenu?.()}),this.elements.reviewFileChangesButton?.addEventListener(`click`,()=>{this.handleGitDiffSelection(this.currentFilePath,{closeSidebarOnMobile:!0,scope:`all`})}),this.elements.fileHistoryButton?.addEventListener(`click`,()=>{let e=this.navigation.getHashRoute();if(e.type===`git-file-preview`){this.handleGitFileHistorySelection(e.currentFilePath??e.filePath,{closeSidebarOnMobile:!0}),this.closeToolbarOverflowMenu?.();return}this.handleGitFileHistorySelection(this.currentFilePath,{closeSidebarOnMobile:!0}),this.closeToolbarOverflowMenu?.()}),this.elements.editNameButton?.addEventListener(`click`,()=>{this.openDisplayNameDialog(),this.closeToolbarOverflowMenu?.()})}function qn(){this.elements.displayNameCancel?.addEventListener(`click`,()=>{this.handleDisplayNameCancel()}),this.elements.gitCommitCancel?.addEventListener(`click`,()=>{this.elements.gitCommitDialog?.close()}),this.elements.gitResetCancel?.addEventListener(`click`,()=>{this.elements.gitResetDialog?.close()}),this.elements.gitResetSubmit?.addEventListener(`click`,()=>{this.handleGitResetSubmit()}),this.elements.gitCommitDialog?.addEventListener(`close`,()=>{this.elements.gitCommitInput&&(this.elements.gitCommitInput.value=``),this.elements.gitCommitSubmit&&(this.elements.gitCommitSubmit.textContent=`Commit included files`)}),this.elements.gitResetDialog?.addEventListener(`close`,()=>{this.pendingGitResetPath=null,this.elements.gitResetFileName&&(this.elements.gitResetFileName.value=``),this.elements.gitResetSubmit&&(this.elements.gitResetSubmit.textContent=`Reset file`)}),this.elements.displayNameForm?.addEventListener(`submit`,e=>{e.preventDefault(),this.handleDisplayNameSubmit()}),this.elements.gitCommitForm?.addEventListener(`submit`,e=>{e.preventDefault(),this.handleGitCommitSubmit()})}function Jn(e){e?.preventDefault?.();let t=this.elements.editorContainer;if(!t)return;let n=t.querySelector(`.cm-content, iframe, [contenteditable="true"]`)??t;n===t&&!t.hasAttribute(`tabindex`)&&t.setAttribute(`tabindex`,`-1`),n.focus()}function Yn(){let e=()=>this.stopFollowingUser?.();this.elements.editorContainer?.addEventListener(`pointerdown`,e),this.elements.editorContainer?.addEventListener(`keydown`,e),this.elements.editorContainer?.addEventListener(`wheel`,e,{passive:!0}),this.elements.previewContainer?.addEventListener(`pointerdown`,e),this.elements.previewContainer?.addEventListener(`wheel`,e,{passive:!0}),this.elements.skipToEditor?.addEventListener(`click`,e=>this.focusEditor(e)),this.elements.emptyStateNewFileBtn?.addEventListener(`click`,()=>{this.fileExplorer.actionController.openRootCreateMenu({anchor:this.elements.emptyStateNewFileBtn})}),this.elements.emptyStateSearchBtn?.addEventListener(`click`,()=>{this.toggleQuickSwitcher()}),this.elements.presencePanel?.addEventListener(`toggle`,e=>{this.presencePanelOpen=e.newState===`open`,this.renderAvatars?.(),this.renderPresence?.()}),this.elements.chatPanel?.addEventListener(`toggle`,e=>{this.chatIsOpen=e.newState===`open`,this.chatIsOpen&&(this.chatUnreadCount=0),this.renderChat?.({messagesChanged:this.chatIsOpen,stickToBottom:this.chatIsOpen}),this.chatIsOpen&&requestAnimationFrame(()=>this.elements.chatInput?.focus())}),this.elements.chatNotificationButton?.addEventListener(`click`,()=>{this.handleChatNotificationToggle()}),this.elements.chatNotificationMuteButton?.addEventListener(`click`,()=>{this.toggleChatNotificationMute()}),this.elements.chatForm?.addEventListener(`submit`,e=>{e.preventDefault(),this.handleChatSubmit()}),Kn.call(this),qn.call(this),this.elements.markdownToolbar?.addEventListener(`click`,e=>{this.handleMarkdownToolbarClick?.(e)}),this.elements.markdownToolbar?.addEventListener(`keydown`,e=>{this.handleMarkdownToolbarKeydown?.(e)}),this.elements.tabLockTakeoverButton?.addEventListener(`click`,()=>{this.handleTabTakeover()}),this.elements.toggleWrapButton?.addEventListener(`click`,()=>{this.toggleLineWrapping()}),this.elements.toggleCursorNamesButton?.addEventListener(`click`,()=>{let e=this.elements.editorContainer.classList.contains(`hide-cursor-names`);this.preferences.setCursorNamesVisible(e),this.syncCursorNamesToggle(e)}),this.elements.toggleVimModeButton?.addEventListener(`click`,()=>{this.toggleVimMode()}),this.elements.editorFindButton?.addEventListener(`click`,()=>{this.runEditorCommand?.(`openSearch`)}),this.elements.editorFormatButton?.addEventListener(`click`,()=>{this.formatCurrentDocument()}),this.elements.toolbarOverflowMenu?.addEventListener(`click`,e=>{let t=e.target instanceof Element?e.target.closest(`button`):null;t&&t!==this.elements.toggleVimModeButton&&t!==this.elements.toggleCursorNamesButton&&this.closeToolbarOverflowMenu()}),this.elements.toolbarOverflowMenu?.addEventListener(`toggle`,e=>{e.newState===`closed`&&this.elements.toolbarOverflowMenu.querySelectorAll(`details[open]`).forEach(e=>{e.removeAttribute(`open`)})}),this.elements.previewContent?.addEventListener(`click`,e=>{this.handlePreviewContentClick?.(e)}),this.elements.previewContent?.addEventListener(`pointerover`,e=>{this.handlePreviewContentPointerOver?.(e)}),this.elements.previewContent?.addEventListener(`focusin`,e=>{this.handlePreviewContentPointerOver?.(e)}),this.elements.sidebarToggle?.addEventListener(`click`,()=>{this.closeToolbarOverflowMenu(),this.toggleSidebar()}),this.elements.sidebarClose?.addEventListener(`click`,()=>{this.closeSidebarOnMobile()}),this.elements.sidebarBackdrop?.addEventListener(`click`,()=>{this.closeSidebarOnMobile()}),this.elements.filesSidebarTab?.addEventListener(`click`,()=>{this.setSidebarTab(`files`)}),this.elements.gitSidebarTab?.addEventListener(`click`,()=>{this.gitRepoAvailable&&this.setSidebarTab(`git`)}),this.elements.commentsSidebarTab?.addEventListener(`click`,()=>{this.setSidebarTab(`comments`)}),this.elements.sidebarTabs?.addEventListener(`keydown`,e=>{this.handleSidebarTabsKeydown(e)}),document.addEventListener(`keydown`,e=>{this.handleDocumentKeydown(e)},{capture:!0})}function Xn(e){e.key===`Escape`&&this.stopFollowingUser?.(),Je(e)&&(e.preventDefault(),e.stopPropagation(),this.toggleQuickSwitcher())}function Zn(e,t){let n=e.closest(`ul, ol`);return n instanceof Element&&n.parentElement===t}function Qn(e){return!e.closest(`input[data-task-checkbox="true"]`)&&!!e.closest(`a, button, input, select, textarea, summary, [contenteditable="true"], [role="button"], [role="link"]`)}function $n(e){let t=window.getSelection();return!!(!t?.isCollapsed&&e.contains(t.anchorNode)&&e.contains(t.focusNode))}function er(e=``){let t=String(e??``).trim();if(!t)return``;try{return decodeURIComponent(t)}catch{return t}}function tr(e,t,{behavior:n=`smooth`}={}){if(!e||!t)return;let r=e.getBoundingClientRect(),i=t.getBoundingClientRect(),a=e.scrollTop+(i.top-r.top);e.scrollTo({behavior:n,top:Math.max(a,0)})}async function nr(e){await navigator.clipboard.writeText(e)}function rr(e){if(!(e instanceof HTMLElement))return``;let t=e.cloneNode(!0);return t instanceof HTMLElement?(t.querySelectorAll(`.preview-heading-fold-button, .preview-heading-link-button`).forEach(e=>e.remove()),t.textContent.replace(/\s+/g,` `).trim()):e.textContent.trim()}function ir(){return globalThis.performance?.now?.()??Date.now()}function ar(e,t,{behavior:n=`auto`}={}){if(!(e instanceof HTMLElement)||!t)return!1;if(this.outlineController?.navigateToHeading?.(e,t,{behavior:n}))return!0;let r=this.elements.previewContainer??document.getElementById(`previewContainer`);if(!r)return!1;this.scrollSyncController?.suspendSync?.(250),tr(r,e,{behavior:n}),this.attachPreviewHeadingControls?.(e);let i=Number.parseInt(e.getAttribute(`data-source-line`)||``,10);return Number.isFinite(i)&&this.session?.scrollToLine?.(i,0),!0}function or(e){if(!this.currentFilePath||!e)return``;let t=new URL(window.location.href);return t.hash=Ke(this.currentFilePath,{anchor:e,drawioMode:this.currentDrawioMode??null}),t.toString()}async function sr(e){let t=this.createPreviewHeadingLinkUrl(e);if(!t){this.toastController.show(`Failed to copy section link`);return}try{await nr(t),this.toastController.show(`Section link copied`)}catch{this.toastController.show(`Failed to copy section link`)}}async function cr(e){let t=e?.closest(`pre`)?.querySelector(`:scope > code`);if(t instanceof HTMLElement)try{await nr(t.textContent),this.toastController.show(`Code copied`)}catch{this.toastController.show(`Failed to copy code`)}}function lr(e,t){if(!(e instanceof HTMLElement)||!(t instanceof HTMLButtonElement))return;let n=rr(e),r=e.dataset.previewHeadingCollapsed===`true`;e.setAttribute(`aria-expanded`,String(!r)),t.setAttribute(`aria-expanded`,String(!r)),t.setAttribute(`aria-label`,`${r?`Expand`:`Collapse`} ${n}`),t.setAttribute(`title`,`${r?`Expand`:`Collapse`} section`)}function ur(e){if(!(e instanceof HTMLElement)||!/^H[1-6]$/.test(e.tagName))return;if(!this._previewHeadingFoldButton){let e=document.createElement(`button`);e.type=`button`,e.className=`ui-icon-button preview-heading-fold-button`,this._previewHeadingFoldButton=e}if(!this._previewHeadingLinkButton){let e=document.createElement(`button`);e.type=`button`,e.className=`ui-icon-button preview-heading-link-button`,e.innerHTML=Bn,this._previewHeadingLinkButton=e}let t=this._previewHeadingFoldButton,n=this._previewHeadingLinkButton;if(t.parentElement!==e&&e.prepend(t),lr(e,t),!e.id){n.remove();return}let r=rr(e);n.dataset.previewHeadingAnchor=e.id,n.setAttribute(`aria-label`,`Copy link to ${r}`),n.setAttribute(`title`,`Copy link to this section`),n.parentElement!==e&&e.append(n)}function dr(e){if(!(e instanceof HTMLElement)||e.tagName!==`PRE`||!e.querySelector(`:scope > code`))return;if(!this._previewCodeCopyButton){let e=document.createElement(`button`);e.type=`button`,e.className=`ui-button ui-button--secondary ui-button--compact preview-code-copy-button`,e.setAttribute(`aria-label`,`Copy code`),e.title=`Copy code`,e.innerHTML=`${zn}<span data-preview-code-copy-label>Copy</span>`,this._previewCodeCopyButton=e}let t=this._previewCodeCopyButton;t.parentElement!==e&&e.append(t)}function fr(e){if(!(e.target instanceof Element)||!this.elements.previewContent)return;let t=e.target.closest(`h1, h2, h3, h4, h5, h6`);t instanceof HTMLElement&&this.elements.previewContent.contains(t)&&this.attachPreviewHeadingControls(t);let n=e.target.closest(`pre`);n instanceof HTMLElement&&this.elements.previewContent.contains(n)&&this.attachPreviewCodeCopyButton(n)}function pr(e){new Set(Array.from(e?.querySelectorAll?.(`h1, h2, h3, h4, h5, h6`)??[]).map(e=>e.parentElement).filter(Boolean)).forEach(e=>{let t=[];Array.from(e.children).forEach(e=>{let n=/^H([1-6])$/.exec(e.tagName)?.[1];if(n){let r=Number(n);for(;t.at(-1)>=r;)t.pop();e.hidden=t.length>0,e.dataset.previewHeadingCollapsed===`true`&&t.push(r)}else e.hidden=t.length>0})})}function mr(e){if(!(e instanceof HTMLElement)||!/^H[1-6]$/.test(e.tagName))return!1;let t=[],n=Number(e.tagName[1])+1;for(let r=e;r;r=r.previousElementSibling){let e=Number(/^H([1-6])$/.exec(r.tagName)?.[1]);!e||e>=n||(n=e,r.dataset.previewHeadingCollapsed===`true`&&t.push(r))}return t.length!==0&&(t.forEach(e=>delete e.dataset.previewHeadingCollapsed),this.syncPreviewHeadingFoldButtons(),this.scrollSyncController?.invalidatePreviewBlocks?.(),this.schedulePreviewLayoutSync?.({delayMs:0}),this.refreshCommentUiLayout?.(),!0)}function hr(){let e=this.elements.previewContent?.querySelectorAll?.(`h1, h2, h3, h4, h5, h6`)??[];Array.from(e).forEach(e=>{if(!(e instanceof HTMLElement))return;let t=e.dataset.previewHeadingCollapsed===`true`;e.setAttribute(`aria-expanded`,String(!t));let n=e.querySelector(`:scope > .preview-heading-fold-button`);n instanceof HTMLButtonElement&&lr(e,n)}),pr(this.elements.previewContent)}function gr(){let e=this._previewHeadingLinkButton,t=e?.parentElement;if(!(t instanceof HTMLElement)||!t.id)return;let n=rr(t);e.dataset.previewHeadingAnchor=t.id,e.setAttribute(`aria-label`,`Copy link to ${n}`),e.setAttribute(`title`,`Copy link to this section`)}function _r(e,t=this.currentFilePath){let n=String(e??``).trim();return this._pendingPreviewRouteAnchor=n?{applied:!1,appliedCount:0,anchorId:n,filePath:t??this.currentFilePath??null,stabilizeUntil:ir()+Ln}:null,this._pendingPreviewRouteAnchor?this.applyPendingPreviewRouteAnchor({behavior:`auto`,clearMissing:!1}):!1}function vr({allowExpired:e=!1,behavior:t=`auto`,clearMissing:n=!1}={}){let r=this._pendingPreviewRouteAnchor;if(!r)return!1;if(!e&&r.applied&&r.stabilizeUntil<=ir())return this._pendingPreviewRouteAnchor=null,!1;if(r.filePath&&this.currentFilePath&&r.filePath!==this.currentFilePath)return!1;let i=document.getElementById(r.anchorId);return!(i instanceof HTMLElement)||!this.elements.previewContent?.contains(i)?(!r.applied&&n&&r.filePath&&r.filePath===this.currentFilePath&&(this._pendingPreviewRouteAnchor=null),!1):this.navigatePreviewHeading(i,r.anchorId,{behavior:t})?(r.applied=!0,r.appliedCount=(r.appliedCount??0)+1,r.stabilizeUntil=ir()+Ln,r.appliedCount>=Rn&&(this._pendingPreviewRouteAnchor=null),!0):!1}function yr(e){if(!(e.target instanceof Element))return;let t=e.target.closest(`button.preview-heading-fold-button`),n=t?.closest(`h1, h2, h3, h4, h5, h6`);if(t instanceof HTMLButtonElement&&n instanceof HTMLElement){e.preventDefault(),n.dataset.previewHeadingCollapsed=String(n.dataset.previewHeadingCollapsed!==`true`),this.syncPreviewHeadingFoldButtons(),this.scrollSyncController?.invalidatePreviewBlocks?.(),this.schedulePreviewLayoutSync?.({delayMs:0}),this.refreshCommentUiLayout?.();return}let r=e.target.closest(`button.preview-code-copy-button`);if(r instanceof HTMLButtonElement){e.preventDefault(),this.copyPreviewCodeBlock(r);return}let i=e.target.closest(`button.preview-heading-link-button[data-preview-heading-anchor]`);if(i instanceof HTMLButtonElement){e.preventDefault(),this.copyPreviewHeadingLink(i.dataset.previewHeadingAnchor||``);return}let a=e.target.closest(`a.wiki-link[data-wiki-target]`);if(a){e.preventDefault(),this.wikiLinkFileController.handleWikiLinkClick(a.dataset.wikiTarget);return}let o=e.target.closest(`a[href]`),s=o?.getAttribute(`href`)?.trim()||``;if(o&&s.startsWith(`#`)&&!Le(s)){if(e.preventDefault(),s===`#`||s.toLowerCase()===`#top`){this.scrollSyncController?.suspendSync?.(250),(this.elements.previewContainer??document.getElementById(`previewContainer`))?.scrollTo({top:0,behavior:`smooth`});return}let t=er(s.slice(1));if(!t)return;let n=document.getElementById(t);if(!n||!this.elements.previewContent?.contains(n))return;this.navigatePreviewHeading(n,t,{behavior:`smooth`});return}let c=e.target.closest(`.task-list-item[data-source-line]`);if(!c||Zn(e.target,c)||Qn(e.target)||$n(c))return;e.preventDefault();let l=Number.parseInt(c.getAttribute(`data-source-line`)||``,10);Number.isFinite(l)&&this.session?.toggleTaskListItem?.(l)}function br(){let e=this.elements.toolbarOverflowToggle;e&&(e.classList.remove(`hidden`),e.hidden=!1,e.setAttribute(`aria-hidden`,`false`))}function xr(){this.elements.toolbarOverflowMenu?.matches(`:popover-open`)&&this.elements.toolbarOverflowMenu.hidePopover()}function Sr(e){this.previewRenderer.applyTheme(e),this.currentFilePath&&!this.isExcalidrawFile(this.currentFilePath)&&!this.isCanvasFile?.(this.currentFilePath)&&!this.isImageFile?.(this.currentFilePath)&&!this.isPdfFile?.(this.currentFilePath)&&!this.isStructurizrWorkspaceFile?.(this.currentFilePath)&&this.previewRenderer.queueRender(),this.session?.applyTheme(e),this.excalidrawEmbed.updateTheme(e),this.canvasEmbed?.updateTheme(e),this.drawioEmbed.updateTheme(e),this.pdfPreview?.setTheme(e)}function Cr(e){this.connectionState=e,e?.firstConnection&&this.recordFileOpenMetric?.(`ws_connected`,{status:e.status}),this.renderPresence(),this.renderChat({messagesChanged:!1}),e.unreachable&&!this.connectionHelpShown&&(this.connectionHelpShown=!0,this.toastController.show(`Cannot reach server at ${e.wsBaseUrl}`,6e3))}function wr(){let e=!(this.session?.isLineWrappingEnabled()??this.getStoredLineWrapping());this.session?.setLineWrapping(e),this.preferences.setLineWrappingEnabled(e),this.syncWrapToggle(e),this.session?.requestMeasure(),this.scrollSyncController.syncPreviewToEditor()}function Tr(){return this.preferences.getLineWrappingEnabled()}async function Er(){let e=this.elements.editorFormatButton;e?.setAttribute(`disabled`,``);try{let e=await this.session?.formatDocument?.(this.currentFilePath),t={changed:`Document changed while formatting. Try again.`,formatted:_(this.currentFilePath)===`plantuml`?`PlantUML indentation applied`:`Document formatted`,unchanged:`Document is already formatted`,unsupported:`Formatting is unavailable for this file type`};this.toastController.show(t[e]??t.unsupported)}catch(e){this.toastController.show(`Formatting failed: ${e?.message||`Unknown error`}`,5e3)}finally{e?.removeAttribute(`disabled`)}}function Dr(){let e=!(this.session?.isVimModeEnabled?.()??this.getStoredVimMode());this.session?.setVimMode?.(e),this.preferences.setVimModeEnabled(e),this.syncVimModeToggle(e)}function Or(){return this.preferences.getVimModeEnabled()}function kr(e){let t=e??this.session?.isVimModeEnabled?.()??this.getStoredVimMode(),n=this.elements.vimModeToggleLabel,r=this.elements.toggleVimModeButton;n&&(n.textContent=t?`On`:`Off`),r&&(r.setAttribute(`aria-label`,`${t?`Disable`:`Enable`} Vim keybindings`),r.setAttribute(`title`,`${t?`Disable`:`Enable`} Vim keybindings`),r.setAttribute(`aria-pressed`,String(t)))}function Ar(e=this.preferences.getCursorNamesVisible()){this.elements.editorContainer?.classList.toggle(`hide-cursor-names`,!e);let t=this.elements.cursorNamesToggleLabel;t&&(t.textContent=e?`On`:`Off`);let n=this.elements.toggleCursorNamesButton;n?.setAttribute(`aria-pressed`,String(e)),n?.setAttribute(`aria-label`,`${e?`Hide`:`Show`} cursor names`),n?.setAttribute(`title`,`${e?`Hide`:`Show`} cursor names`)}function jr(e){let t=e??this.session?.isLineWrappingEnabled()??this.getStoredLineWrapping(),n=this.elements.wrapToggleLabel,r=this.elements.toggleWrapButton,i=t?`Wrap on`:`Wrap off`;n&&(n.textContent=i),r&&r.setAttribute(`aria-label`,`${i}. ${t?`Disable line wrap`:`Enable line wrap`}`)}function Mr(){clearTimeout(this._backlinkRefreshTimer),this._backlinkRefreshTimer=setTimeout(()=>{S(this.currentFilePath)&&this.backlinksPanel.load(this.currentFilePath)},2e3)}function Nr(){this.elements.editorContainer&&(this.elements.editorContainer.classList.add(`is-loading-editor`),this.elements.editorContainer.innerHTML=`
|
|
16
|
+
<div class="editor-loading" id="editorLoading" role="status" aria-live="polite" aria-label="Loading file…">
|
|
17
|
+
<div class="skeleton-line skeleton-line--title skeleton-line--break"></div>
|
|
18
|
+
<div class="skeleton-line skeleton-line--full"></div>
|
|
19
|
+
<div class="skeleton-line skeleton-line--ninety"></div>
|
|
20
|
+
<div class="skeleton-line skeleton-line--ninety-five"></div>
|
|
21
|
+
<div class="skeleton-line skeleton-line--eighty"></div>
|
|
22
|
+
</div>`)}function Pr(){this.elements.editorContainer&&(this.elements.editorContainer.classList.remove(`is-loading-editor`),this.elements.editorContainer.querySelector(`#editorLoading`)?.remove())}function Fr(e=`Failed to load file`){if(!this.elements.editorContainer)return;let t=document.createElement(`div`),n=document.createElement(`span`);t.className=`editor-loading`,t.id=`editorLoading`,n.className=`loading-text`,n.textContent=e,t.appendChild(n),this.elements.editorContainer.classList.remove(`is-loading-editor`),this.elements.editorContainer.replaceChildren(t)}function Ir(){document.documentElement.removeAttribute(`data-initial-file-requested`)}var Lr={applyPendingPreviewRouteAnchor:vr,attachPreviewCodeCopyButton:dr,attachPreviewHeadingControls:ur,bindEvents:Yn,clearInitialFileBootstrap:Ir,closeToolbarOverflowMenu:xr,copyPreviewCodeBlock:cr,copyPreviewHeadingLink:sr,createPreviewHeadingLinkUrl:or,focusEditor:Jn,formatCurrentDocument:Er,getStoredLineWrapping:Tr,getStoredVimMode:Or,handleConnectionChange:Cr,handleDocumentKeydown:Xn,handlePreviewContentClick:yr,handlePreviewContentPointerOver:fr,handleThemeChange:Sr,hideEditorLoading:Pr,initialize:Vn,initializeVisualViewportBinding:Wn,initializeVersionMonitoring:Hn,isPlainQuickSwitcherShortcut:Je,navigatePreviewHeading:ar,promptForVersionReload:Gn,requestPreviewRouteAnchor:_r,scheduleBacklinkRefresh:Mr,showEditorLoadError:Fr,showEditorLoading:Nr,syncPreviewHeadingFoldButtons:hr,syncPreviewHeadingLinkButtons:gr,syncVisualViewportBounds:Un,syncToolbarOverflowVisibility:br,syncVimModeToggle:kr,syncCursorNamesToggle:Ar,syncWrapToggle:jr,toggleLineWrapping:wr,unfoldPreviewHeading:mr,toggleVimMode:Dr},Rr=260,zr=220,Br=420,Vr=16;function Hr(){let e=this.elements.sidebar,t=this.elements.sidebarResizer;if(!e||!t)return;let n=Rr,r=null,i=0,a=Rr,o=e=>Math.round(Math.max(zr,Math.min(Br,e))),s=r=>{n=o(r),e.style.setProperty(`--sidebar-width`,`${n}px`),t.setAttribute(`aria-valuenow`,String(n))},c=t=>{(t?.pointerId==null||t.pointerId===r)&&r!==null&&(r=null,e.classList.remove(`is-resizing`),document.body.style.cursor=``,document.body.style.userSelect=``)};s(Rr),t.addEventListener(`pointerdown`,o=>{this.isMobileViewport()||e.classList.contains(`collapsed`)||(r=o.pointerId,i=o.clientX,a=e.getBoundingClientRect().width||n,e.classList.add(`is-resizing`),document.body.style.cursor=`col-resize`,document.body.style.userSelect=`none`,t.setPointerCapture?.(o.pointerId),o.preventDefault())}),t.addEventListener(`pointermove`,e=>{e.pointerId===r&&s(a+e.clientX-i)}),t.addEventListener(`pointerup`,c),t.addEventListener(`pointercancel`,c),t.addEventListener(`lostpointercapture`,c),t.addEventListener(`keydown`,t=>{if(!(this.isMobileViewport()||e.classList.contains(`collapsed`))){if(t.key===`ArrowLeft`||t.key===`ArrowRight`){t.preventDefault(),s(n+(t.key===`ArrowRight`?Vr:-16));return}(t.key===`Home`||t.key===`End`)&&(t.preventDefault(),s(t.key===`Home`?zr:Br))}})}function Ur(){return this.mobileBreakpointQuery.matches}function Wr(){let e=this.elements.sidebar;e&&this.isMobileViewport()&&(e.classList.contains(`collapsed`)||this.setSidebarVisibility(!1))}function Gr(){let e=this.elements.sidebar;if(!e)return;let t=e.classList.contains(`collapsed`);this.setSidebarVisibility(t)}function Kr(){if(!this.elements.sidebar)return;let e=this.isMobileViewport(),t=this.preferences.getSidebarVisible(),n=!0;t===`true`?n=!0:(t===`false`||e)&&(n=!1),this.applySidebarVisibility(n)}function qr(e){this.applySidebarVisibility(e),this.preferences.setSidebarVisible(e)}function Jr(e){let t=this.elements.sidebar;if(!t)return;let n=this.isMobileViewport(),r=!e,i=r&&n,a=e&&n;t.classList.toggle(`collapsed`,r),t.toggleAttribute(`hidden`,i),t.setAttribute(`aria-hidden`,r?`true`:`false`),t.inert=r;let o=this.elements.sidebarBackdrop;o?.toggleAttribute(`hidden`,!a),o?.setAttribute(`aria-hidden`,a?`false`:`true`),o&&(o.inert=!a)}function Yr(e){if(![`ArrowLeft`,`ArrowRight`,`Home`,`End`].includes(e.key))return;let t=[this.elements.filesSidebarTab,this.elements.commentsSidebarTab,this.elements.gitSidebarTab].filter(e=>e&&!e.classList.contains(`hidden`)),n=Math.max(0,t.indexOf(e.target)),r=e.key===`Home`?0:e.key===`End`?t.length-1:(n+(e.key===`ArrowRight`?1:-1)+t.length)%t.length;e.preventDefault(),t[r]?.click(),t[r]?.focus()}function Xr(e){let t=e===`git`&&this.gitRepoAvailable?`git`:e===`comments`?`comments`:`files`;this.activeSidebarTab=t,[[this.elements.filesSidebarTab,`files`],[this.elements.commentsSidebarTab,`comments`],[this.elements.gitSidebarTab,`git`]].forEach(([e,n])=>{let r=t===n;e?.classList.toggle(`active`,r),e?.setAttribute(`aria-selected`,String(r)),e?.setAttribute(`tabindex`,r?`0`:`-1`)});let n=document.getElementById(`fileTree`),r=this.elements.commentOverviewPanel,i=document.getElementById(`gitPanel`);[[n,t===`files`],[r,t===`comments`],[i,t===`git`]].forEach(([e,t])=>{e?.classList.toggle(`hidden`,!t),e?.setAttribute(`aria-hidden`,String(!t))}),this.elements.fileSearch?.classList.toggle(`hidden`,t!==`files`),this.elements.gitSearch?.classList.toggle(`hidden`,t!==`git`),i?.classList.toggle(`active`,t===`git`),this.gitPanel.setActive(t===`git`),t===`comments`&&this.refreshCommentOverviewForSidebarOpen?.()}var Zr={applySidebarVisibility:Jr,closeSidebarOnMobile:Wr,handleSidebarTabsKeydown:Yr,initializeSidebarResizer:Hr,isMobileViewport:Ur,restoreSidebarState:Kr,setSidebarTab:Xr,setSidebarVisibility:qr,toggleSidebar:Gr};function Qr(){this.tabActivityLock.tryActivate({takeover:!0})}function $r({takeover:e=!1}={}){let t=!this.isTabActive;this.isTabActive=!0,this.hideTabLockOverlay(),this.webMcpTools?.refresh(),this.lobby.provider||this.lobby.connect(),this.connectWorkspaceSync(),t&&(this.fileExplorerReady&&this.workspaceRouteController.handleHashChange(),this.promptForDisplayNameIfNeeded()),e&&this.toastController.show(`This tab is now active`)}function ei(){this.workspaceSync.provider||this.workspaceSync.connect()}async function ti({reason:e}={}){let t=this.isTabActive,n=this.currentFilePath,r=!!(n&&this.isExcalidrawFile?.(n));this.isTabActive=!1,this.webMcpTools?.refresh(),this.lobby.disconnect(),this.workspaceSync.disconnect(),this.globalUsers=[],this.chatMessages=[],this.chatMessageIds.clear(),this.chatUnreadCount=0,this.chatInitialSyncComplete=!1,this.presencePanelOpen=!1,this.followedUserClientId=null,this.followedCursorSignature=``,this.connectionState={status:`disconnected`,unreachable:!1},this.showTabLockOverlay({reason:e}),r&&await this.excalidrawEmbed.prepareFileDisconnect(n),!(n&&this.isCanvasFile?.(n)&&!await this.canvasEmbed.prepareFileDisconnect(n))&&(this.showEmptyState(),this.renderChat(),t&&e===`taken-over`&&this.toastController.show(`Another tab took over this session`))}function ni({reason:e}={}){let t=this.elements.tabLockOverlay,n=this.elements.tabLockTitle,r=this.elements.tabLockCopy;t&&(document.dispatchEvent(new Event(`collabmd:close-custom-modals`)),document.querySelectorAll(`dialog[open]`).forEach(e=>{e!==t&&e.close()}),n&&(n.textContent=e===`taken-over`?`This tab is no longer active`:`This vault is active in another tab`),r&&(r.textContent=e===`taken-over`?`Another tab took over the live session. This tab is now disconnected until you explicitly take over here again.`:`To avoid duplicate presence and chat, only one tab can stay connected at a time. Use the other tab, or take over the session here.`),t.open||(this.tabLockPreviouslyFocusedElement=document.activeElement instanceof HTMLElement?document.activeElement:null,t.showModal()),this.elements.tabLockTakeoverButton?.focus())}function ri(){this.elements.tabLockOverlay?.open&&this.elements.tabLockOverlay.close(),this.tabLockPreviouslyFocusedElement?.focus?.(),this.tabLockPreviouslyFocusedElement=null}var ii={connectWorkspaceSync:ei,handleTabActivated:$r,handleTabBlocked:ti,handleTabTakeover:Qr,hideTabLockOverlay:ri,showTabLockOverlay:ni},R=Object.freeze({bold:`
|
|
23
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
24
|
+
<path d="M7 5h6a4 4 0 0 1 0 8H7z"/>
|
|
25
|
+
<path d="M7 13h7a4 4 0 0 1 0 8H7z"/>
|
|
26
|
+
</svg>
|
|
27
|
+
`,italic:`
|
|
28
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
29
|
+
<path d="M14 4h6"/>
|
|
30
|
+
<path d="M4 20h6"/>
|
|
31
|
+
<path d="M14 4 10 20"/>
|
|
32
|
+
</svg>
|
|
33
|
+
`,strikethrough:`
|
|
34
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.1" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
35
|
+
<path d="M6 6.5c1.4-1.2 3.2-1.9 5.4-1.9 3.1 0 5.6 1.4 5.6 3.9 0 2.1-1.7 3-4.3 3.5l-2.4.5c-2.7.5-4.3 1.6-4.3 3.6 0 2.7 2.7 4.2 6 4.2 2.1 0 4.2-.6 5.7-1.8"/>
|
|
36
|
+
<path d="M3 12h18"/>
|
|
37
|
+
</svg>
|
|
38
|
+
`,link:`
|
|
39
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
40
|
+
<path d="M10 13a5 5 0 0 0 7.54.54l2.92-2.92a5 5 0 0 0-7.07-7.07L11.5 5.4"/>
|
|
41
|
+
<path d="M14 11a5 5 0 0 0-7.54-.54L3.54 13.38a5 5 0 1 0 7.07 7.07L12.5 18.6"/>
|
|
42
|
+
</svg>
|
|
43
|
+
`,image:`
|
|
44
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
45
|
+
<rect x="3" y="5" width="18" height="14" rx="2"/>
|
|
46
|
+
<circle cx="9" cy="10" r="1.5"/>
|
|
47
|
+
<path d="m21 16-5.5-5.5L7 19"/>
|
|
48
|
+
</svg>
|
|
49
|
+
`,video:`
|
|
50
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
51
|
+
<rect x="3" y="5" width="18" height="14" rx="2"/>
|
|
52
|
+
<path d="m10 9 5 3-5 3z" fill="currentColor" stroke="none"/>
|
|
53
|
+
</svg>
|
|
54
|
+
`,table:`
|
|
55
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
56
|
+
<rect x="3" y="5" width="18" height="14" rx="1"/>
|
|
57
|
+
<path d="M3 10h18"/>
|
|
58
|
+
<path d="M9 5v14"/>
|
|
59
|
+
<path d="M15 5v14"/>
|
|
60
|
+
</svg>
|
|
61
|
+
`,code:`
|
|
62
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.1" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
63
|
+
<path d="m8 9-4 3 4 3"/>
|
|
64
|
+
<path d="m16 9 4 3-4 3"/>
|
|
65
|
+
<path d="m13 6-2 12"/>
|
|
66
|
+
</svg>
|
|
67
|
+
`,horizontalRule:`
|
|
68
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
69
|
+
<path d="M4 12h16"/>
|
|
70
|
+
<path d="M9 8h6"/>
|
|
71
|
+
<path d="M9 16h6"/>
|
|
72
|
+
</svg>
|
|
73
|
+
`,indent:`
|
|
74
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.1" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
75
|
+
<path d="M4 6h16"/>
|
|
76
|
+
<path d="M10 12h10"/>
|
|
77
|
+
<path d="M10 18h10"/>
|
|
78
|
+
<path d="m4 9 4 3-4 3"/>
|
|
79
|
+
</svg>
|
|
80
|
+
`,outdent:`
|
|
81
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.1" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
82
|
+
<path d="M4 6h16"/>
|
|
83
|
+
<path d="M10 12h10"/>
|
|
84
|
+
<path d="M10 18h10"/>
|
|
85
|
+
<path d="m8 9-4 3 4 3"/>
|
|
86
|
+
</svg>
|
|
87
|
+
`,redo:`
|
|
88
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.1" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
89
|
+
<path d="M21 7v6h-6"/>
|
|
90
|
+
<path d="M20 13a8 8 0 0 0-14-3"/>
|
|
91
|
+
</svg>
|
|
92
|
+
`,undo:`
|
|
93
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.1" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
94
|
+
<path d="M3 7v6h6"/>
|
|
95
|
+
<path d="M4 13a8 8 0 0 1 14-3"/>
|
|
96
|
+
</svg>
|
|
97
|
+
`,chevronDown:`
|
|
98
|
+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
99
|
+
<path d="m6 9 6 6 6-6"/>
|
|
100
|
+
</svg>
|
|
101
|
+
`}),ai=Object.freeze([{action:`paragraph`,label:`Paragraph`,shortLabel:`P`,title:`Paragraph`},{action:`heading-1`,label:`Heading 1`,shortLabel:`H1`,title:`Heading 1`},{action:`heading-2`,label:`Heading 2`,shortLabel:`H2`,title:`Heading 2`},{action:`heading-3`,label:`Heading 3`,shortLabel:`H3`,title:`Heading 3`},{action:`heading-4`,label:`Heading 4`,shortLabel:`H4`,title:`Heading 4`},{action:`heading-5`,label:`Heading 5`,shortLabel:`H5`,title:`Heading 5`},{action:`heading-6`,label:`Heading 6`,shortLabel:`H6`,title:`Heading 6`},{action:`quote`,label:`Quote`,shortLabel:`Quote`,title:`Block quote`},{action:`bullet-list`,label:`Bullet list`,shortLabel:`List`,title:`Bullet list`},{action:`numbered-list`,label:`Numbered list`,shortLabel:`1.`,title:`Numbered list`},{action:`task-list`,label:`Task list`,shortLabel:`Task`,title:`Task list`},{action:`code-block`,label:`Code block`,shortLabel:`Code`,title:`Code block`}]),oi=Object.freeze([{action:`bold`,label:`Bold`,title:`Bold`,icon:R.bold},{action:`italic`,label:`Italic`,title:`Italic`,icon:R.italic},{action:`strikethrough`,label:`Strikethrough`,title:`Strikethrough`,icon:R.strikethrough},{action:`code`,label:`Inline code`,title:`Inline code`,icon:R.code}]),si=Object.freeze([{commandId:`undo`,label:`Undo`,title:`Undo`,icon:R.undo},{commandId:`redo`,label:`Redo`,title:`Redo`,icon:R.redo},{commandId:`indentMore`,label:`Indent`,title:`Indent`,icon:R.indent},{commandId:`indentLess`,label:`Outdent`,title:`Outdent`,icon:R.outdent}]),ci=Object.freeze([{action:`link`,label:`Insert link`,title:`Insert link`,icon:R.link},{action:`image`,label:`Insert image`,title:`Insert image`,icon:R.image},{action:`video`,label:`Insert video`,title:`Insert video`,icon:R.video}]),li=Object.freeze([{action:`table`,label:`Insert table`,title:`Insert table`,icon:R.table},{action:`horizontal-rule`,label:`Insert horizontal rule`,title:`Insert horizontal rule`,icon:R.horizontalRule}]),ui=Object.freeze([{kind:`buttons`,groupLabel:`Edit`,actions:si,mobileOnly:!0},{kind:`block-menu`,actions:ai},{kind:`buttons`,groupLabel:`Inline formatting`,actions:oi},{kind:`buttons`,groupLabel:`Media and links`,actions:ci},{kind:`buttons`,groupLabel:`Insert`,actions:li}]),di=[...ai,...oi,...ci,...li],fi=new Map(di.map(e=>[e.action,e]));function pi(e){return fi.get(e)??null}function mi(){return ai}function hi(e){return ai.some(t=>t.action===e)}function gi(e){return pi(e)?.shortLabel??`P`}function _i(){return R}var vi=`image/png,image/jpeg,image/webp,image/gif,image/svg+xml`,yi=`paragraph`;function bi(e){return e===`heading`?`heading-2`:String(e??``).trim()}function xi(e){return e.map(e=>`<button type="button" class="ui-icon-button ui-icon-button--toolbar ui-toolbar-action" ${e.commandId?`data-editor-command="${j(e.commandId)}"`:`data-markdown-action="${j(e.action)}"`} aria-label="${j(e.label)}" title="${j(e.title)}">${e.icon}</button>`).join(``)}function Si(e){return`
|
|
102
|
+
<div class="markdown-toolbar-block-menu-shell">
|
|
103
|
+
<button
|
|
104
|
+
type="button"
|
|
105
|
+
class="ui-button ui-button--ghost markdown-toolbar-block-trigger"
|
|
106
|
+
data-markdown-block-menu-toggle
|
|
107
|
+
popovertarget="markdownBlockMenuPopover"
|
|
108
|
+
title="Block formatting"
|
|
109
|
+
>
|
|
110
|
+
<span class="markdown-toolbar-block-trigger-label" data-markdown-block-trigger-label>${j(gi(e))}</span>
|
|
111
|
+
<span class="markdown-toolbar-block-trigger-icon" aria-hidden="true">${_i().chevronDown}</span>
|
|
112
|
+
</button>
|
|
113
|
+
<div id="markdownBlockMenuPopover" class="markdown-toolbar-popover" popover="auto">
|
|
114
|
+
<div class="markdown-toolbar-menu" data-markdown-block-menu role="menu" aria-label="Block formatting">
|
|
115
|
+
${Ci(e)}
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
`}function Ci(e){return mi().map(t=>{let n=t.action===e;return`
|
|
120
|
+
<button
|
|
121
|
+
type="button"
|
|
122
|
+
class="markdown-toolbar-menu-item${n?` is-active`:``}"
|
|
123
|
+
data-markdown-block-action="${j(t.action)}"
|
|
124
|
+
role="menuitemradio"
|
|
125
|
+
aria-checked="${n?`true`:`false`}"
|
|
126
|
+
title="${j(t.title)}"
|
|
127
|
+
>
|
|
128
|
+
<span class="markdown-toolbar-menu-item-label">${j(t.label)}</span>
|
|
129
|
+
<span class="markdown-toolbar-menu-item-shortcut">${j(t.shortLabel)}</span>
|
|
130
|
+
</button>
|
|
131
|
+
`}).join(``)}function wi(e){return ui.map(t=>t.kind===`block-menu`?Si(e):`
|
|
132
|
+
<div class="markdown-toolbar-group${t.mobileOnly?` markdown-toolbar-group--mobile-only`:``}" role="group" aria-label="${j(t.groupLabel)}">
|
|
133
|
+
${xi(t.actions)}
|
|
134
|
+
</div>
|
|
135
|
+
`).join(``)}function Ti(){let e=bi(this._activeMarkdownBlockAction||yi);return hi(e)?e:yi}function Ei(){let e=this.elements?.markdownToolbar;e&&(e.innerHTML=wi(this.getActiveMarkdownBlockAction()),this.syncMarkdownToolbarBlockUi())}function Di(){return document.getElementById(`markdownBlockMenuPopover`)}function Oi(){let e=this.elements?.markdownToolbar;if(!e)return;let t=this.getActiveMarkdownBlockAction(),n=pi(t),r=e.querySelector(`[data-markdown-block-trigger-label]`);r&&(r.textContent=gi(t));let i=e.querySelector(`[data-markdown-block-menu-toggle]`);i&&n&&(i.setAttribute(`aria-label`,`${n.label}. Block formatting`),i.setAttribute(`title`,`${n.label}. Block formatting`)),e.querySelectorAll(`[data-markdown-block-action]`).forEach(e=>{let n=e.getAttribute(`data-markdown-block-action`)===t;e.classList.toggle(`is-active`,n),e.setAttribute(`aria-checked`,n?`true`:`false`)})}function ki(e){let t=bi(e);hi(t)&&(this._activeMarkdownBlockAction=t,this.syncMarkdownToolbarBlockUi())}function Ai(){return!!this.getMarkdownBlockMenuPopover()?.matches(`:popover-open`)}function ji(){let e=this.getMarkdownBlockMenuPopover();e&&!e.matches(`:popover-open`)&&e.showPopover()}function Mi(){let e=this.getMarkdownBlockMenuPopover();e?.matches(`:popover-open`)&&e.hidePopover()}function Ni(e){let t=e.target instanceof Element?e.target:null;if(!t)return;let n=t.closest(`[data-editor-command]`)?.getAttribute(`data-editor-command`);if(n){e.preventDefault(),this.runEditorCommand(n);return}let r=t.closest(`[data-markdown-block-action]`);if(r){e.preventDefault();let t=r.getAttribute(`data-markdown-block-action`);this.closeMarkdownBlockMenu(),t&&this.applyMarkdownToolbarAction(t);return}let i=t.closest(`[data-markdown-action]`)?.getAttribute(`data-markdown-action`);i&&this.applyMarkdownToolbarAction(i)}function Pi(e){if(!this.isMarkdownBlockMenuOpen()){e.target instanceof Element&&e.target.closest(`[data-markdown-block-menu-toggle]`)&&e.key===`ArrowDown`&&(e.preventDefault(),this.openMarkdownBlockMenu(),this.getMarkdownBlockMenuPopover()?.querySelector(`[data-markdown-block-action]`)?.focus());return}let t=Array.from(this.getMarkdownBlockMenuPopover()?.querySelectorAll(`[data-markdown-block-action]`)??[]),n=t.findIndex(t=>t===e.target);n<0||(e.key===`ArrowDown`?(e.preventDefault(),t[(n+1)%t.length]?.focus()):e.key===`ArrowUp`&&(e.preventDefault(),t[(n-1+t.length)%t.length]?.focus()))}function Fi(e){if(!this.session||!c(this.currentFilePath))return;if(e===`image`){this.handleToolbarImageInsert();return}let t=bi(e);if(!this.session.applyMarkdownToolbarAction(t)){this.toastController.show(`Formatting action is unavailable`);return}hi(t)&&this.setActiveMarkdownBlockAction(t)}function Ii(e){return this.session?.runEditorCommand?.(e)?!0:(this.toastController.show(`Editor action is unavailable`),!1)}async function Li(){let[e]=await le({accept:vi});e&&await this.handleEditorImageInsert(e)}async function Ri(e){if(!this.session||!c(this.currentFilePath))return console.warn(`[ui] Ignoring image insert because there is no active markdown session.`,{currentFilePath:this.currentFilePath,hasSession:!!this.session}),!1;let t=this.currentFilePath,n=this.session;try{console.debug(`[ui] Uploading image attachment.`,{fileName:e?.name||``,size:e?.size??null,sourcePath:t,type:e?.type||``});let r=await this.vaultApiClient.uploadImageAttachment({file:e,fileName:e?.name||``,sourcePath:t});return await this.fileExplorer.refresh(),this.currentFilePath===t&&this.session&&this.session===n&&typeof r?.markdown==`string`&&(console.debug(`[ui] Inserting uploaded image markdown into the editor.`,{sourcePath:t,storedPath:r.path??``}),this.session.insertText(r.markdown)),!0}catch(e){return console.error(`[ui] Failed to insert image attachment:`,e),this.toastController.show(e.message||`Failed to upload image`),!1}}async function zi(){try{await navigator.clipboard.writeText(window.location.href),this.toastController.show(`Link copied`)}catch{this.toastController.show(`Failed to copy link`)}}var Bi={applyMarkdownToolbarAction:Fi,copyCurrentLink:zi,closeMarkdownBlockMenu:Mi,getActiveMarkdownBlockAction:Ti,getMarkdownBlockMenuPopover:Di,handleEditorImageInsert:Ri,handleMarkdownToolbarClick:Ni,handleMarkdownToolbarKeydown:Pi,handleToolbarImageInsert:Li,isMarkdownBlockMenuOpen:Ai,openMarkdownBlockMenu:ji,renderMarkdownToolbar:Ei,runEditorCommand:Ii,setActiveMarkdownBlockAction:ki,syncMarkdownToolbarBlockUi:Oi},Vi={isBaseFile:i,isCanvasFile:h,isDrawioFile:o,isExcalidrawFile:f,isImageFile:s,isPdfFile:p,isMermaidFile:g,isPlantUmlFile:u,isStructurizrWorkspaceFile:l,getPreviewSource(){let e=this.getStaticPreviewDocument?.(),t=e?.currentFilePath??e?.filePath??null;return e&&t&&t===this.currentFilePath?this.isMermaidFile(this.currentFilePath)?this.workspacePreviewController.createDiagramPreviewDocument(`mermaid`,e.content):this.isPlantUmlFile(this.currentFilePath)?this.workspacePreviewController.createDiagramPreviewDocument(`plantuml`,e.content):String(e.content??``):this.workspacePreviewController.getPreviewSource(this.currentFilePath,{drawioMode:this.currentDrawioMode??null})},getStaticPreviewDocument(){return this._staticPreviewDocument??null},setStaticPreviewDocument(e){let t=e?.filePath??e?.path??null,n=e?.currentFilePath??t;this._staticPreviewDocument=e?{content:String(e.content??``),currentFilePath:n,fileKind:e.fileKind??_(t),filePath:t,hash:e.hash??null}:null},clearStaticPreviewDocument(){this._staticPreviewDocument=null},supportsFileHistory(e){let t=_(e);return t!==null&&t!==`image`&&t!==`pdf`},getDisplayName(e){return x(String(e??``).split(`/`).pop())},handleLayoutViewRequest(e){return this.isCanvasFile?.(this.currentFilePath)?e===`preview`:!this.currentFilePath||!this.isDrawioFile(this.currentFilePath)?!0:this.currentDrawioMode===`text`?e!==`preview`||(this.layoutController.isMobileViewport?.()&&this.layoutController.primeView(e),this.navigation.navigateToFile(this.currentFilePath),!1):e===`preview`||(this.layoutController.primeView(e),this.navigation.navigateToFile(this.currentFilePath,{drawioMode:`text`}),!1)},renderBaseFilePreview(e,t){return clearTimeout(this._basePreviewRenderTimer),this._basePreviewRenderTimer=null,this.workspacePreviewController.renderBaseFilePreview(e,t)},scheduleBaseFilePreview(e,t){let n=this.sessionLoadToken;clearTimeout(this._basePreviewRenderTimer),this._basePreviewRenderTimer=setTimeout(()=>{this._basePreviewRenderTimer=null,e===this.currentFilePath&&n===this.sessionLoadToken&&this.renderBaseFilePreview(e,t)},180)},createResizeHandler(){return this.workspacePreviewController.createResizeHandler(()=>this.restoreSidebarState())},initializePreviewLayoutObserver(){this._previewLayoutResizeObserver?.disconnect(),this._previewLayoutResizeObserver=this.workspacePreviewController.initializePreviewLayoutObserver(()=>this.schedulePreviewLayoutSync())},schedulePreviewLayoutSync(e){this.workspacePreviewController.schedulePreviewLayoutSync(e)},handleEditorScrollActivityChange(e){this.workspacePreviewController.handleEditorScrollActivityChange(e)},showEmptyState(){this.workspacePreviewController.resetPreviewLayoutSync(),this.workspaceRouteController.showEmptyState()},showDiffState(){this.workspacePreviewController.resetPreviewLayoutSync(),this.workspaceRouteController.showDiffState()}},Hi={listConnections(){return fetch(N(`/agent/connections`)).then(e=>O(e,`Failed to load Agent Connections`))},createConnection(e){return fetch(N(`/agent/connections`),{body:JSON.stringify(e),headers:{"Content-Type":`application/json`},method:`POST`}).then(e=>O(e,`Failed to create Agent Connection`))},revokeConnection(e){return fetch(N(`/agent/connections/${encodeURIComponent(e)}`),{method:`DELETE`}).then(e=>O(e,`Failed to revoke Agent Connection`))}};function z(e,t,n){try{return e.getItem(t)??n}catch{return n}}function B(e,t,n){try{e.setItem(t,n)}catch{}}var Ui=20,V={fileTreeShowExtensions:`collabmd-file-tree-show-extensions`,lineWrapping:`collabmd-editor-line-wrap`,recentFiles:`collabmd-recent-files`,vimMode:`collabmd-editor-vim-mode`,viewMode:`collabmd-editor-view-mode`,sidebarVisible:`collabmd-sidebar-visible`,userName:`collabmd-user-name`,cursorNames:`collabmd-editor-cursor-names`},Wi=class{constructor({storage:e=globalThis.localStorage}={}){this.storage=e}getUserName(){return z(this.storage,V.userName,``)||``}setUserName(e){B(this.storage,V.userName,e)}getFileTreeShowExtensions(){return z(this.storage,V.fileTreeShowExtensions,null)===`true`}setFileTreeShowExtensions(e){B(this.storage,V.fileTreeShowExtensions,e?`true`:`false`)}getLineWrappingEnabled(){return z(this.storage,V.lineWrapping,null)!==`false`}setLineWrappingEnabled(e){B(this.storage,V.lineWrapping,String(e))}getCursorNamesVisible(){return z(this.storage,V.cursorNames,null)!==`false`}setCursorNamesVisible(e){B(this.storage,V.cursorNames,String(e))}getVimModeEnabled(){return z(this.storage,V.vimMode,null)===`true`}setVimModeEnabled(e){B(this.storage,V.vimMode,String(e))}getViewMode(){let e=z(this.storage,V.viewMode,null);return e===`editor`||e===`preview`||e===`split`?e:null}setViewMode(e){(e===`editor`||e===`preview`||e===`split`)&&B(this.storage,V.viewMode,e)}getRecentFiles(){let e=z(this.storage,V.recentFiles,`[]`);try{let t=JSON.parse(e);return Array.isArray(t)?[...new Set(t.filter(e=>typeof e==`string`&&e))]:[]}catch{return[]}}recordRecentFile(e){if(!e)return;let t=[e,...this.getRecentFiles().filter(t=>t!==e)];B(this.storage,V.recentFiles,JSON.stringify(t.slice(0,Ui)))}getSidebarVisible(){return z(this.storage,V.sidebarVisible,null)}setSidebarVisible(e){B(this.storage,V.sidebarVisible,e?`true`:`false`)}};function H(e,{body:t=null,fallback:n=`Request failed`,method:r=`GET`}={}){return fetch(N(e),{...t===null?{}:{body:JSON.stringify(t)},headers:{"Content-Type":`application/json`},method:r}).then(e=>O(e,n))}var Gi={acceptInvitation(){return H(`/hosted/invitations/accept`,{fallback:`Failed to accept invitation`,method:`POST`})},claimWorkspace({teamName:e,token:t}){return H(`/hosted/claim`,{body:{teamName:e,token:t},fallback:`Failed to claim workspace`,method:`POST`})},completeSetup(){return H(`/hosted/setup/complete`,{fallback:`Failed to complete setup`,method:`POST`})},createInvitation({email:e,role:t}){return H(`/hosted/invitations`,{body:{email:e,role:t},fallback:`Failed to create invitation`,method:`POST`})},getStatus(){return H(`/hosted/status`,{fallback:`Failed to load workspace status`})},listAuditEvents({cursor:e=``,limit:t=50}={}){let n=new URLSearchParams({limit:String(t)});return e&&n.set(`cursor`,e),H(`/hosted/audit?${n}`,{fallback:`Failed to load access history`})},listInvitations(){return H(`/hosted/invitations`,{fallback:`Failed to load invitations`})},listMemberships(){return H(`/hosted/memberships`,{fallback:`Failed to load collaborators`})},removeMembership(e){return H(`/hosted/memberships/${encodeURIComponent(e)}`,{fallback:`Failed to remove collaborator`,method:`DELETE`})},revokeInvitation(e){return H(`/hosted/invitations/${encodeURIComponent(e)}`,{fallback:`Failed to revoke invitation`,method:`DELETE`})},updateInvitationRole(e,t){return H(`/hosted/invitations/${encodeURIComponent(e)}`,{body:{role:t},fallback:`Failed to update invitation`,method:`PATCH`})},updateMembershipRole(e,t){return H(`/hosted/memberships/${encodeURIComponent(e)}`,{body:{role:t},fallback:`Failed to update role`,method:`PATCH`})}},Ki=class{getApi(){return typeof globalThis.Notification==`function`?globalThis.Notification:null}getPermission(){return this.getApi()?.permission??`unsupported`}async requestPermission(){let e=this.getApi();if(!e||typeof e.requestPermission!=`function`)return`unsupported`;if(e.permission!=="default")return e.permission;try{return await e.requestPermission()}catch{return e.permission??`default`}}show({body:e,onClick:t,tag:n,title:r}={}){let i=this.getApi();if(!i||i.permission!==`granted`||!e)return null;try{let a=new i(r,{body:e,renotify:!0,tag:n});return t&&(a.onclick=t),a}catch{return null}}},qi=6e4;function Ji(e){return String(e?.build?.id??e?.buildId??``).trim()}var Yi=class{constructor({currentBuildId:e=``,documentRef:t=globalThis.document??null,fetchImpl:n=globalThis.fetch?.bind(globalThis),intervalMs:r=qi,onUpdateAvailable:i=null,runtimeConfig:a={basePath:``},versionUrl:o=null,windowRef:s=globalThis.window??globalThis}={}){this.currentBuildId=String(e??``).trim(),this.documentRef=t,this.fetchImpl=n,this.intervalHandle=null,this.intervalMs=Math.max(5e3,Number(r)||qi),this.isChecking=!1,this.onUpdateAvailable=typeof i==`function`?i:null,this.runtimeConfig=a,this.updateDetected=!1,this.versionUrl=o||Ne(`/version.json`,a),this.windowRef=s,this.handleFocus=()=>{this.checkNow({force:!0})},this.handleVisibilityChange=()=>{this.documentRef?.hidden||this.checkNow({force:!0})}}start(){this.fetchImpl&&!this.intervalHandle&&(this.documentRef?.addEventListener?.(`visibilitychange`,this.handleVisibilityChange),this.windowRef?.addEventListener?.(`focus`,this.handleFocus),this.intervalHandle=this.windowRef?.setInterval?.(()=>{this.checkNow()},this.intervalMs)??null,this.checkNow({force:!0}))}stop(){this.intervalHandle&&=(this.windowRef?.clearInterval?.(this.intervalHandle),null),this.documentRef?.removeEventListener?.(`visibilitychange`,this.handleVisibilityChange),this.windowRef?.removeEventListener?.(`focus`,this.handleFocus)}async checkNow({force:e=!1}={}){if(!this.fetchImpl||this.isChecking||this.updateDetected||!e&&this.documentRef?.hidden)return!1;this.isChecking=!0;try{let e=await this.fetchImpl(this.versionUrl,{cache:`no-store`,headers:{Accept:`application/json`}});if(!e?.ok)return!1;let t=await e.json().catch(()=>null),n=Ji(t);return n?this.currentBuildId?n!==this.currentBuildId&&(this.updateDetected=!0,this.onUpdateAvailable?.(t),!0):(this.currentBuildId=n,!1):!1}catch{return!1}finally{this.isChecking=!1}}};function U(e={}){let t=new URLSearchParams;return Object.entries(e).forEach(([e,n])=>{n!=null&&n!==``&&t.set(e,String(n))}),t}async function W(e,t,{fallbackError:n,requestId:r=null}={}){let i=await fetch(N(e),{body:JSON.stringify(t),headers:pe(r,{"Content-Type":`application/json`}),method:`POST`});return O(i,n)}var Xi={async readStatus({force:e=!1}={}){let t=await fetch(N(`/git/status${e?`?force=true`:``}`));return O(t,`Failed to load git status`)},getPullBackupSummaryUrl(e){let t=U({id:e});return N(`/git/pull-backup-summary?${t.toString()}`)},async readPullBackups(){let e=await fetch(N(`/git/pull-backups`));return O(e,`Failed to load pull backups`)},async readHistory({limit:e,offset:t}={}){let n=U({limit:e,offset:t}),r=await fetch(N(`/git/history?${n.toString()}`));return O(r,`Failed to load git history`)},async readFileHistory({path:e,limit:t,offset:n}={}){let r=U({limit:t,offset:n,path:e}),i=await fetch(N(`/git/file-history?${r.toString()}`));return O(i,`Failed to load file history`)},async readDiff({allowLargePatch:e=!1,metaOnly:t=!1,path:n=null,scope:r=`all`}={}){let i=U({allowLargePatch:e?`true`:null,metaOnly:t?`true`:null,path:n,scope:r}),a=await fetch(N(`/git/diff?${i.toString()}`));return O(a,`Failed to load git diff`)},async readCommit({allowLargePatch:e=!1,hash:t,metaOnly:n=!1,path:r=null}={}){let i=U({allowLargePatch:e?`true`:null,hash:t,metaOnly:n?`true`:null,path:r}),a=await fetch(N(`/git/commit?${i.toString()}`));return O(a,`Failed to load git commit`)},async readFileSnapshot({hash:e,path:t}={}){let n=U({hash:e,path:t}),r=await fetch(N(`/git/file-snapshot?${n.toString()}`));return O(r,`Failed to load historical file preview`)},getFileAttachmentUrl({hash:e,path:t}={}){let n=U({hash:e,path:t});return N(`/git/file-attachment?${n.toString()}`)},async stageFile({path:e,requestId:t=null}={}){return W(`/git/stage`,{path:e},{requestId:t,fallbackError:`Failed to stage file`})},async unstageFile({path:e,requestId:t=null}={}){return W(`/git/unstage`,{path:e},{requestId:t,fallbackError:`Failed to unstage file`})},async stageAll({requestId:e=null}={}){return W(`/git/stage-all`,{},{requestId:e,fallbackError:`Failed to stage all changes`})},async unstageAll({requestId:e=null}={}){return W(`/git/unstage-all`,{},{requestId:e,fallbackError:`Failed to unstage all changes`})},async pushBranch({requestId:e=null}={}){return W(`/git/push`,{},{requestId:e,fallbackError:`Failed to push branch`})},async pullBranch({requestId:e=null}={}){return W(`/git/pull`,{},{requestId:e,fallbackError:`Failed to pull branch`})},async resetFile({path:e,requestId:t=null}={}){return W(`/git/reset-file`,{path:e},{requestId:t,fallbackError:`Failed to reset file`})},async commit({message:e,requestId:t=null}={}){return W(`/git/commit`,{message:e},{requestId:t,fallbackError:`Failed to commit staged changes`})}},Zi=`collabmd-active-tab-lock`,Qi=`collabmd-tab-id`,$i=`collabmd-tab-lock`,ea=4e3;function ta(){return Date.now()}function na(){return globalThis.crypto?.randomUUID?.()??`tab-${ta()}-${Math.random().toString(36).slice(2,10)}`}function ra(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}var ia=class{constructor({heartbeatIntervalMs:e=ea,onBlocked:t,onActivated:n,onStolen:r}={}){this.heartbeatIntervalMs=e,this.staleAfterMs=e*3,this.onBlocked=t,this.onActivated=n,this.onStolen=r,this.tabId=this.getOrCreateTabId(),this.channel=null,this.heartbeatTimer=null,this.isOwner=!1,this.listenerController=null,this.handleStorageEvent=this.handleStorageEvent.bind(this),this.handlePageHide=this.handlePageHide.bind(this)}initialize(){this.listenerController?.abort(),this.listenerController=new AbortController;let{signal:e}=this.listenerController;window.addEventListener(`storage`,this.handleStorageEvent,{signal:e}),window.addEventListener(`pagehide`,this.handlePageHide,{signal:e}),`BroadcastChannel`in globalThis&&(this.channel=new BroadcastChannel($i),this.channel.addEventListener(`message`,e=>{this.handleChannelMessage(e.data)}))}destroy(){this.release(),this.listenerController?.abort(),this.listenerController=null,this.channel?.close(),this.channel=null}tryActivate({takeover:e=!1}={}){let t=this.readLock();return this.isFreshLock(t)&&t.tabId!==this.tabId&&!e?(this.isOwner=!1,this.stopHeartbeat(),this.onBlocked?.({reason:`active-elsewhere`,ownerTabId:t.tabId}),!1):(this.writeLock(),this.startHeartbeat(),this.isOwner=!0,this.channel?.postMessage({type:`claimed`,takeover:e,tabId:this.tabId}),this.onActivated?.({takeover:e}),!0)}release(){this.readLock()?.tabId===this.tabId&&(localStorage.removeItem(Zi),this.channel?.postMessage({type:`released`,tabId:this.tabId})),this.isOwner=!1,this.stopHeartbeat()}getOrCreateTabId(){try{let e=window.sessionStorage.getItem(Qi);if(e)return e;let t=na();return window.sessionStorage.setItem(Qi,t),t}catch{return na()}}readLock(){try{return ra(window.localStorage.getItem(Zi))}catch{return null}}isFreshLock(e){return!!(e&&typeof e.tabId==`string`&&Number.isFinite(e.updatedAt)&&ta()-e.updatedAt<this.staleAfterMs)}writeLock(){try{window.localStorage.setItem(Zi,JSON.stringify({tabId:this.tabId,updatedAt:ta()}))}catch{}}startHeartbeat(){this.stopHeartbeat(),this.writeLock(),this.heartbeatTimer=window.setInterval(()=>{if(!this.isOwner){this.stopHeartbeat();return}this.writeLock()},this.heartbeatIntervalMs)}stopHeartbeat(){this.heartbeatTimer&&=(window.clearInterval(this.heartbeatTimer),null)}handleStorageEvent(e){if(e.key!==Zi)return;let t=ra(e.newValue);this.handleExternalLockChange(t)}handleChannelMessage(e){e&&typeof e==`object`&&e.tabId!==this.tabId&&e.type===`claimed`&&this.handleExternalLockChange(this.readLock())}handleExternalLockChange(e){this.isOwner&&this.isFreshLock(e)&&e.tabId!==this.tabId&&(this.isOwner=!1,this.stopHeartbeat(),this.onStolen?.({ownerTabId:e.tabId}))}handlePageHide(){this.release()}};function G(e={},t=Object.keys(e)){return{additionalProperties:!1,properties:e,required:t,type:`object`}}var K={description:`Lowercase SHA-256 revision returned by read_document.`,pattern:`^[a-f0-9]{64}$`,type:`string`},aa=G({agentEditable:{type:`boolean`},embeddable:{type:`boolean`},kind:{type:[`string`,`null`]},mtimeMs:{minimum:0,type:`number`},nodeType:{enum:[`directory`,`file`],type:`string`},path:{type:`string`},readable:{type:`boolean`},size:{minimum:0,type:`number`}}),oa=G({exists:{type:`boolean`},kind:{type:[`string`,`null`]},line:{minimum:1,type:`integer`},rawTarget:{type:`string`},resolvedPath:{type:[`string`,`null`]},targetPath:{type:`string`}}),sa=G({kind:{type:[`string`,`null`]},line:{minimum:1,type:`integer`},mimeType:{type:[`string`,`null`]},source:{type:`string`},supported:{type:`boolean`},url:{type:[`string`,`null`]}}),ca=G({contexts:{items:{type:`string`},type:`array`},file:{type:`string`}}),la=G({code:{type:`string`},line:{minimum:1,type:`integer`},message:{type:`string`},target:{type:`string`}}),ua=G({issues:{items:la,type:`array`},valid:{type:`boolean`}}),da={description:`Return reference validation for the exact saved revision. Markdown only; validation issues do not roll back the save.`,type:`boolean`},fa={endLine:{minimum:1,type:`integer`},format:{enum:[`png`,`svg`],type:`string`},kind:{enum:[`mermaid`,`plantuml`],type:`string`},mimeType:{enum:[`image/png`,`image/svg+xml`],type:`string`},path:{type:`string`},renderer:{type:`string`},revision:K,startLine:{minimum:1,type:`integer`},warnings:{items:{type:`string`},type:`array`}},pa=G({file:{type:`string`},kind:{type:`string`},matchCount:{minimum:0,type:`integer`},snippets:{items:G({column:{minimum:1,type:`integer`},line:{minimum:1,type:`integer`},matchEnd:{minimum:0,type:`integer`},matchStart:{minimum:0,type:`integer`},text:{type:`string`}}),type:`array`},truncated:{type:`boolean`}}),ma=G({examples:{items:{type:`string`},type:`array`},extensions:{items:{type:`string`},type:`array`},guide:{type:`string`},kind:{type:`string`}}),ha=G({agentCreatable:{type:`boolean`},agentEditable:{type:`boolean`},commentsSupported:{type:`boolean`},editable:{type:`boolean`},examples:{items:{type:`string`},type:`array`},extensions:{items:{type:`string`},type:`array`},guide:{type:`string`},kind:{type:`string`},readable:{type:`boolean`},searchable:{type:`boolean`}}),ga={additionalProperties:!1,properties:{autoResize:{type:`boolean`},afterElementId:{description:`Place this new element immediately after an existing or concurrently created element.`,maxLength:128,minLength:1,type:`string`},backgroundColor:{type:`string`},endArrowhead:{type:[`string`,`null`]},beforeElementId:{description:`Place this new element immediately before an existing or concurrently created element.`,maxLength:128,minLength:1,type:`string`},containerId:{maxLength:128,minLength:1,type:[`string`,`null`]},endElementId:{maxLength:128,minLength:1,type:`string`},fillStyle:{enum:[`cross-hatch`,`hachure`,`solid`,`zigzag`],type:`string`},fontFamily:{minimum:1,type:`integer`},fontSize:{exclusiveMinimum:0,type:`number`},lineHeight:{exclusiveMinimum:0,type:`number`},groupIds:{items:{maxLength:128,minLength:1,type:`string`},maxItems:20,type:`array`,uniqueItems:!0},height:{minimum:0,type:`number`},id:{maxLength:128,minLength:1,type:`string`},opacity:{maximum:100,minimum:0,type:`number`},points:{items:{items:{type:`number`},maxItems:2,minItems:2,type:`array`},maxItems:1e3,minItems:2,type:`array`},roughness:{maximum:2,minimum:0,type:`number`},startArrowhead:{type:[`string`,`null`]},startElementId:{maxLength:128,minLength:1,type:`string`},strokeColor:{type:`string`},strokeStyle:{enum:[`dashed`,`dotted`,`solid`],type:`string`},strokeWidth:{exclusiveMinimum:0,type:`number`},text:{maxLength:2e4,type:`string`},type:{enum:[`arrow`,`diamond`,`ellipse`,`freedraw`,`line`,`rectangle`,`text`],type:`string`},width:{minimum:0,type:`number`},x:{type:`number`},y:{type:`number`}},required:[`id`,`type`,`x`,`y`],type:`object`},_a=G({id:{maxLength:128,minLength:1,type:`string`},set:{additionalProperties:!0,description:`Excalidraw element fields to shallow-merge. id, type, and version cannot change.`,type:`object`}}),va=G({element:{...ga,required:[`type`,`x`,`y`]},id:{maxLength:128,minLength:1,type:`string`}},[`element`,`id`]),ya=G({action:{enum:[`bringToFront`,`sendToBack`],type:`string`},afterElementId:{maxLength:128,minLength:1,type:`string`},beforeElementId:{maxLength:128,minLength:1,type:`string`},id:{maxLength:128,minLength:1,type:`string`}},[`id`]),ba=G({dx:{type:`number`},dy:{type:`number`},ids:{description:`Requested targets. Bound text, its container, and all members of referenced groups move atomically.`,items:{maxLength:128,minLength:1,type:`string`},maxItems:200,minItems:1,type:`array`,uniqueItems:!0}}),xa=G({height:{minimum:0,type:`number`},width:{minimum:0,type:`number`},x:{type:`number`},y:{type:`number`}}),Sa={additionalProperties:!1,properties:{behind:{description:`ID of the immediately higher element that paints in front of this element.`,type:`string`},endElementId:{type:`string`},containerId:{type:`string`},fontFamily:{description:`Excalidraw font-family identifier. Standard Excalifont is 5; legacy Virgil is 1.`,minimum:1,type:`integer`},fontName:{type:`string`},fontSize:{exclusiveMinimum:0,type:`number`},height:{minimum:0,type:`number`},id:{type:`string`},inFrontOf:{description:`ID of the immediately lower element that this element paints in front of.`,type:`string`},paintOrder:{description:`Zero-based back-to-front paint position.`,minimum:0,type:`integer`},lineHeight:{exclusiveMinimum:0,type:`number`},startElementId:{type:`string`},text:{type:`string`},textAlign:{type:`string`},type:{type:`string`},verticalAlign:{type:`string`},width:{minimum:0,type:`number`},x:{type:`number`},y:{type:`number`}},required:[`height`,`id`,`paintOrder`,`type`,`width`,`x`,`y`],type:`object`},Ca=G({code:{type:`string`},elementIds:{items:{type:`string`},type:`array`},message:{type:`string`}}),wa={bounds:xa,elementCount:{minimum:0,type:`integer`},elements:{items:Sa,type:`array`},layout:G({boundText:G({misaligned:{minimum:0,type:`integer`},outsideContainer:{minimum:0,type:`integer`},staleHeight:{minimum:0,type:`integer`},total:{minimum:0,type:`integer`}})}),truncated:{type:`boolean`},valid:{type:`boolean`},warnings:{items:Ca,type:`array`}},Ta=G(wa),Ea=G({...wa,path:{type:`string`},revision:K}),Da={elementCount:{minimum:0,type:`integer`},format:{enum:[`png`,`svg`],type:`string`},height:{minimum:1,type:`integer`},mimeType:{enum:[`image/png`,`image/svg+xml`],type:`string`},renderer:{type:`string`},rendererVersion:{type:`string`},scale:{exclusiveMinimum:0,type:`number`},warnings:{items:{type:`string`},type:`array`},width:{minimum:1,type:`integer`}},Oa={format:{description:`Image format. PNG is most widely supported by MCP clients.`,enum:[`png`,`svg`],type:`string`},padding:{description:`Scene padding in diagram units.`,maximum:100,minimum:0,type:`number`},path:{description:`Vault-relative .excalidraw path.`,maxLength:1024,minLength:1,type:`string`},render:{description:`Return an image render. Set false for a compact structural and layout verification response.`,type:`boolean`},scale:{description:`Requested output scale; automatically reduced when needed to stay within 4096 pixels.`,maximum:4,minimum:.25,type:`number`}},ka=G({format:Oa.format,inspectOcclusion:{description:`Inspect fully occluded elements. Defaults to true.`,type:`boolean`},padding:Oa.padding,render:{description:`Also return an image rendered from the exact created or edited revision.`,type:`boolean`},scale:Oa.scale},[]),Aa=G({inspection:Ta,...Da},[`inspection`]),ja={elementCount:{minimum:0,type:`integer`},format:{enum:[`png`,`svg`],type:`string`},inspection:Ta,layout:wa.layout,path:{type:`string`},revision:K,valid:{type:`boolean`}},Ma={oneOf:[G(ja),G({...ja,...Da})]},Na=Object.freeze([{annotations:{idempotentHint:!0,readOnlyHint:!0},description:`List current Vault files and directories, including binary metadata and agent capability flags.`,inputSchema:G({cursor:{description:`Path from the previous nextCursor; omit for the first page.`,type:`string`},kinds:{description:`Optional CollabMD content kinds to include.`,items:{type:`string`},type:`array`,uniqueItems:!0},limit:{description:`Maximum entries to return.`,maximum:200,minimum:1,type:`integer`},prefix:{description:`Optional Vault directory or path prefix.`,type:`string`},pathQuery:{description:`Optional case-insensitive substring to match anywhere in an entry path.`,maxLength:500,minLength:1,type:`string`}},[]),method:`listWorkspaceEntries`,name:`list_workspace_entries`,outputSchema:G({entries:{items:aa,type:`array`},nextCursor:{type:[`string`,`null`]},truncated:{type:`boolean`}}),scope:`vault:read`,untrustedContentHint:!0,webMcp:!0},{annotations:{idempotentHint:!0,readOnlyHint:!0},description:`Search current Vault text with one literal case-insensitive phrase, not a natural-language question. Defaults to 10 files and 2 snippets each. Read relevant ranges before answering and cite path:line evidence. Narrow prefix or query when truncated; no matches do not prove a topic is absent.`,inputSchema:G({limit:{default:10,description:`Maximum matching documents to return (default 10).`,maximum:50,minimum:1,type:`integer`},maxSnippetsPerFile:{default:2,description:`Maximum matching snippets returned per document (default 2).`,maximum:10,minimum:1,type:`integer`},kinds:{description:`Optional CollabMD content kinds to include.`,items:{type:`string`},type:`array`,uniqueItems:!0},prefix:{description:`Optional Vault directory or path prefix.`,type:`string`},query:{description:`Literal case-insensitive text to find; regular expressions are not supported.`,maxLength:500,minLength:2,type:`string`},wholeWord:{description:`Match only when the literal query is bounded by non-word characters.`,type:`boolean`}},[`query`]),method:`searchVault`,name:`search_vault`,outputSchema:G({backend:{type:`string`},files:{items:pa,type:`array`},matchCount:{minimum:0,type:`integer`},ok:{type:`boolean`},query:{type:`string`},search:{additionalProperties:!1,properties:{available:{type:`boolean`},backend:{type:`string`},minQueryLength:{minimum:1,type:`integer`},unavailableReason:{type:`string`},version:{type:`string`}},required:[`available`,`backend`,`minQueryLength`,`unavailableReason`,`version`],type:`object`},truncated:{description:`True when documents or snippets were omitted, or the search was incomplete. Counts cover observed matches, not necessarily all Vault matches.`,type:`boolean`}}),scope:`vault:read`,untrustedContentHint:!0,webMcp:!0},{annotations:{idempotentHint:!0,readOnlyHint:!0},description:`Read current text (default 80 lines) or a compact Markdown outline with full-document revision. Follow nextStartLine for more. Read content immediately before exact edits; on revision conflict reread and recompute. Maximum source size is 1000000 characters; a single content line over 100000 characters fails explicitly.`,inputSchema:G({lineCount:{default:80,description:`Maximum content lines or outline headings to return (default 80).`,maximum:500,minimum:1,type:`integer`},mode:{default:`content`,description:`Outline returns top-level ATX and single-line Setext headings, excluding fenced code and frontmatter. Heading text is capped at 200 characters.`,enum:[`content`,`outline`],type:`string`},path:{description:`Vault-relative document path.`,maxLength:1024,minLength:1,type:`string`},startLine:{description:`One-based first line to return.`,minimum:1,type:`integer`}},[`path`]),method:`readDocument`,name:`read_document`,outputSchema:G({content:{type:`string`},endLine:{minimum:1,type:`integer`},headings:{items:G({level:{minimum:1,maximum:6,type:`integer`},line:{minimum:1,type:`integer`},text:{type:`string`},truncated:{type:`boolean`}}),type:`array`},nextStartLine:{type:[`integer`,`null`],minimum:1},kind:{type:`string`},path:{type:`string`},revision:K,startLine:{minimum:1,type:`integer`},totalLines:{minimum:1,type:`integer`},truncated:{type:`boolean`}},[`content`,`endLine`,`kind`,`nextStartLine`,`path`,`revision`,`startLine`,`totalLines`,`truncated`]),scope:`vault:read`,untrustedContentHint:!0,webMcp:!0},{annotations:{idempotentHint:!0,readOnlyHint:!0},description:`Inspect resolved and missing wiki-links, embeds, public video embeds, and backlinks for one Markdown document.`,inputSchema:G({path:{description:`Vault-relative Markdown path.`,maxLength:1024,minLength:1,type:`string`}},[`path`]),method:`inspectDocumentReferences`,name:`inspect_document_references`,outputSchema:G({backlinks:{items:ca,type:`array`},embeds:{items:oa,type:`array`},path:{type:`string`},revision:K,videos:{items:sa,type:`array`},wikiLinks:{items:oa,type:`array`}}),scope:`vault:read`,untrustedContentHint:!0,webMcp:!0},{annotations:{idempotentHint:!0,readOnlyHint:!0},description:`Validate one Markdown document for missing wiki-link/embed targets and unsupported public video embeds.`,inputSchema:G({path:{description:`Vault-relative Markdown path.`,maxLength:1024,minLength:1,type:`string`}},[`path`]),method:`validateDocument`,name:`validate_document`,outputSchema:G({issues:{items:la,type:`array`},path:{type:`string`},revision:K,valid:{type:`boolean`}}),scope:`vault:read`,untrustedContentHint:!0,webMcp:!0},{annotations:{idempotentHint:!0,readOnlyHint:!0},description:`Run a Base query and return filtered rows so you can verify filters and expected output.`,inputSchema:G({limit:{description:`Maximum rows to return.`,maximum:200,minimum:1,type:`integer`},path:{description:`Vault-relative .base path.`,maxLength:1024,minLength:1,type:`string`},search:{description:`Optional case-insensitive row search across visible columns.`,maxLength:500,type:`string`},view:{description:`Optional Base view name.`,maxLength:200,type:`string`}},[`path`]),method:`queryBase`,name:`query_base`,outputSchema:G({columns:{items:G({id:{type:`string`},label:{type:`string`}}),type:`array`},path:{type:`string`},rows:{items:G({cells:{additionalProperties:{type:`string`},type:`object`},path:{type:`string`}}),type:`array`},totalRows:{minimum:0,type:`integer`},truncated:{type:`boolean`},view:G({name:{type:`string`},type:{type:`string`}})}),scope:`vault:read`,untrustedContentHint:!0,webMcp:!0},{annotations:{idempotentHint:!0,readOnlyHint:!0},description:`Render one standalone or fenced Mermaid/PlantUML diagram. Markdown with multiple diagrams requires the opening fence startLine. Mermaid rendering requires WebMCP.`,inputSchema:G({format:{description:`Image format. PNG is most widely supported by MCP clients.`,enum:[`png`,`svg`],type:`string`},path:{description:`Vault-relative Markdown, Mermaid, or PlantUML path.`,maxLength:1024,minLength:1,type:`string`},startLine:{description:`Opening fence line for a diagram embedded in Markdown.`,minimum:1,type:`integer`}},[`path`]),method:`renderDiagram`,name:`render_diagram`,outputSchema:G(fa),resultKind:`image`,scope:`vault:read`,untrustedContentHint:!0,webMcp:!0},{annotations:{idempotentHint:!0,readOnlyHint:!0},description:`Inspect an Excalidraw scene structurally. Returns paint order, geometry, text style, bindings, bounds, layout diagnostics, occlusion, clipping, and validity warnings.`,inputSchema:G({path:{description:`Vault-relative .excalidraw path.`,maxLength:1024,minLength:1,type:`string`}},[`path`]),method:`inspectExcalidraw`,name:`inspect_excalidraw`,outputSchema:Ea,scope:`vault:read`,untrustedContentHint:!0,webMcp:!0},{annotations:{idempotentHint:!0,readOnlyHint:!0},description:`Verify one Excalidraw revision with compact structural and layout diagnostics; render is optional.`,inputSchema:G({...Oa,inspectOcclusion:{description:`Inspect fully occluded elements. Defaults to true.`,type:`boolean`}},[`path`]),method:`verifyExcalidraw`,name:`verify_excalidraw`,outputSchema:Ma,resultKind:`optional-image`,scope:`vault:read`,untrustedContentHint:!0,webMcp:!0},{annotations:{idempotentHint:!0,readOnlyHint:!0},description:`Describe CollabMD-supported content kinds, extensions, syntax, and agent write support.`,inputSchema:G({kind:{description:`Optional content kind. Omit to list all capabilities.`,type:`string`}},[]),method:`getSyntax`,name:`get_collabmd_syntax`,outputSchema:{oneOf:[G({capabilities:{items:ha,type:`array`}}),ma]},scope:`vault:read`,webMcp:!0},{annotations:{destructiveHint:!1,idempotentHint:!0,readOnlyHint:!1},description:`Create an editable .excalidraw scene. Before the first diagram in a task, call get_collabmd_syntax with kind="excalidraw" for design guidance and valid examples. Request inline inspection/rendering and examine the image before finishing.`,inputSchema:G({elements:{description:`One to 200 basic Excalidraw elements in back-to-front order. Text may bind to a container with containerId; groupIds define atomic movement groups. Arrows may bind with startElementId and endElementId. beforeElementId or afterElementId sets explicit placement.`,items:ga,maxItems:200,minItems:1,type:`array`},path:{description:`New Vault-relative path ending in .excalidraw.`,maxLength:1024,minLength:1,type:`string`},verify:ka},[`path`,`elements`]),method:`createExcalidraw`,name:`create_excalidraw`,outputSchema:G({elementCount:{minimum:1,type:`integer`},path:{type:`string`},revision:K,verification:Aa},[`elementCount`,`path`,`revision`]),resultKind:`optional-image`,scope:`vault:edit`,webMcp:!0},{annotations:{destructiveHint:!1,idempotentHint:!1,readOnlyHint:!1},description:`Edit an existing .excalidraw scene only when its revision matches. Before the first diagram edit in a task, consult get_collabmd_syntax with kind="excalidraw". Inspect first, preserve existing style and unrelated elements, then verify the result. Supports create, update, replace, translate, reorder, and delete; bound-text metric edits reflow automatically.`,inputSchema:G({create:{items:ga,maxItems:200,type:`array`},delete:{description:`Element IDs to tombstone.`,items:{maxLength:128,minLength:1,type:`string`},maxItems:200,type:`array`,uniqueItems:!0},normalizeTextPlacement:{description:`Normalize every bound text label to its container center and current line-height metrics. This can be the only edit operation.`,enum:[!0],type:`boolean`},path:{description:`Vault-relative .excalidraw path returned by read_document.`,maxLength:1024,minLength:1,type:`string`},revision:K,reorder:{description:`Layer changes applied in array order. Each entry uses exactly one action, beforeElementId, or afterElementId directive.`,items:ya,maxItems:200,type:`array`},replace:{description:`Atomic same-ID element replacement. Layer position is preserved by default.`,items:va,maxItems:200,type:`array`},update:{items:_a,maxItems:200,type:`array`},translate:ba,verify:ka},[`path`,`revision`]),method:`editExcalidraw`,name:`edit_excalidraw`,outputSchema:G({created:{minimum:0,type:`integer`},deleted:{minimum:0,type:`integer`},elementCount:{minimum:0,type:`integer`},path:{type:`string`},reordered:{minimum:0,type:`integer`},reflowed:{description:`Number of bound text labels whose position or height was normalized.`,minimum:0,type:`integer`},replaced:{minimum:0,type:`integer`},revision:K,translated:{description:`Number of explicitly requested translation targets; related bound or grouped elements may also move.`,minimum:0,type:`integer`},updated:{minimum:0,type:`integer`},verification:Aa},[`created`,`deleted`,`elementCount`,`path`,`reordered`,`reflowed`,`replaced`,`revision`,`translated`,`updated`]),resultKind:`optional-image`,scope:`vault:edit`,webMcp:!0},{annotations:{destructiveHint:!1,idempotentHint:!1,readOnlyHint:!1},description:`Apply up to 20 unique, non-overlapping exact replacements against the revision from a fresh content read. Combined old/new text is limited to 50000 characters. On conflict reread; on ambiguous matches include more surrounding text. Optional Markdown validation checks the saved revision.`,inputSchema:G({path:{description:`Vault-relative path returned by read_document.`,maxLength:1024,minLength:1,type:`string`},replacements:{description:`One to 20 exact text replacements; each oldText must resolve unambiguously.`,items:{additionalProperties:!1,properties:{newText:{description:`Replacement text, normalized to LF line endings.`,type:`string`},oldText:{description:`Exact current text to replace.`,minLength:1,type:`string`}},required:[`oldText`,`newText`],type:`object`},maxItems:20,minItems:1,type:`array`},revision:K,validate:da},[`path`,`revision`,`replacements`]),method:`applyTextEdits`,name:`apply_text_edits`,outputSchema:G({path:{type:`string`},replacementCount:{minimum:1,type:`integer`},revision:K,validation:ua},[`path`,`replacementCount`,`revision`]),scope:`vault:edit`,webMcp:!0},{annotations:{destructiveHint:!1,idempotentHint:!0,readOnlyHint:!1},description:`Create a new supported text document (up to 200000 characters). Inspect nearby naming/style and consult get_collabmd_syntax for unfamiliar kinds. Identical retries succeed; different content at an existing path fails. Optional Markdown validation checks the saved revision.`,inputSchema:G({content:{description:`Initial document text, normalized to LF line endings.`,maxLength:2e5,type:`string`},path:{description:`New Vault-relative path with a supported text extension.`,maxLength:1024,minLength:1,type:`string`},validate:da},[`path`,`content`]),method:`createDocument`,name:`create_document`,outputSchema:G({kind:{type:`string`},path:{type:`string`},revision:K,validation:ua},[`kind`,`path`,`revision`]),scope:`vault:edit`,webMcp:!0}]);new Map(Na.map(e=>[e.name,e]));function Pa(){return Na.filter(({webMcp:e})=>e)}function Fa(e){return`collabmd_${e}`}var Ia=4096,La=`collabmd_get_active_context`,Ra=`Call collabmd_get_active_context first. Use create_excalidraw only for a new path; for an existing diagram, inspect_excalidraw then edit_excalidraw with its exact revision and inline verification.`;async function za(e,{format:t=`png`,padding:n=32,scale:r=1}={}){let{exportToBlob:i,exportToSvg:a}=await A(async()=>{let{exportToBlob:e,exportToSvg:t}=await import(`./prod-rdly4JJQ.js`);return{exportToBlob:e,exportToSvg:t}},[],import.meta.url),o=Ye(e,{padding:n,scale:r}),s,c,l,u;if(t===`svg`){let e=await a(o),t=e.outerHTML;s=new TextEncoder().encode(t).toBase64(),c=Math.max(1,Math.ceil(Number.parseFloat(e.getAttribute(`height`))||1)),l=`image/svg+xml`,u=Math.max(1,Math.ceil(Number.parseFloat(e.getAttribute(`width`))||1))}else{let e=await i({...o,maxWidthOrHeight:Ia,mimeType:`image/png`}),t=await createImageBitmap(e);s=new Uint8Array(await e.arrayBuffer()).toBase64(),c=t.height,l=`image/png`,u=t.width,t.close()}return{format:t,height:c,image:{data:s,encoding:`base64`,mimeType:l},mimeType:l,renderer:`excalidraw-official-browser`,rendererVersion:`bundled`,scale:r,warnings:[],width:u}}function Ba(e){if(!e||typeof e!=`object`)return e;let t={...e};if(delete t.scene,!t.verification?.scene)return t;let n={...t.verification};return delete n.scene,{...t,verification:n}}function Va(e){if(e?.aborted)throw e.reason??new DOMException(`Tool execution was cancelled`,`AbortError`)}async function Ha(e,t,n={}){let r=e?.verification?.scene??e?.scene;if(!r)return e;let i={...e.verification?.scene?n.verify:n,...e.verification?.scene?e.verification:e};try{let n=await t(r,i),a=Ba(e);if(e.verification?.scene){let{image:e,...t}=n;return{...a,image:e,verification:{...a.verification,...t}}}return{...a,...n}}catch(t){console.error(`[webmcp] Exact Excalidraw rendering failed:`,t.message);let n=Ba(e);return e?.verification?.scene?{...n,verification:{...n.verification,warnings:[...n.verification?.warnings??[],`exact-render-unavailable`]}}:{...n,warnings:[...n.warnings??[],`exact-render-unavailable`]}}}function Ua(e,t){return!t||Object.keys(t).length===0||!e||typeof e!=`object`?e:{...e,webMcp:t}}function Wa(e={}){let t=e.activeDiagramPath||null,n=e.activePath||null;return{activeDiagramPath:t,activePath:n,kind:_(n),localRevision:e.localRevision??null,selection:e.selection??null,preferredDiagramPath:t,workflow:t?`Current diagram is ${t}. Inspect it, edit with the returned exact revision, request inline verification, then use the returned canvas paint acknowledgement.`:n?`Read the active document before editing. Selection offsets are UTF-16 and refer to localRevision; compare it with the fresh server revision and reconsider the selection if they differ. Batch unique exact replacements; reread on conflict. Request Markdown validation when changing references.`:`No diagram is active. Use create_excalidraw with a new .excalidraw path and request inline verification. Inspect then revision-edit any existing path; do not retry stale edits without rereading.`}}function Ga(e){return e.name.includes(`excalidraw`)?`${e.description} ${Ra}`:e.description}function Ka(e,t){return typeof e==`function`?e(t):null}async function qa(e,t){try{return await Ka(e,t)}catch(e){return console.error(`[webmcp] Failed to acknowledge an applied mutation:`,e.message),{status:`unavailable`}}}function Ja(e){return{annotations:{readOnlyHint:!0,untrustedContentHint:!0},description:`Return the active file kind, bounded primary editor selection (up to 2000 characters), local snapshot revision, and diagram context. Call for edits referring to this document or selection. Local revision does not confirm server synchronization; read_document supplies the edit revision.`,execute:async()=>Wa(await e?.()),inputSchema:{additionalProperties:!1,properties:{},required:[],type:`object`},name:La}}var Ya=class{constructor({acknowledgeToolCall:e=null,callTool:t,getActiveContext:n=null,getIsTabActive:r,modelContext:i=globalThis.document?.modelContext??null,onDidMutate:a=null,prepareToolCall:o=null,renderExcalidrawScene:s=za}){this.acknowledgeToolCall=e,this.callTool=t,this.getActiveContext=n,this.getIsTabActive=r,this.modelContext=i,this.onDidMutate=a,this.prepareToolCall=o,this.renderExcalidrawScene=s,this.registration=null}async refresh(){if(typeof this.modelContext?.registerTool!=`function`||typeof this.callTool!=`function`||!this.getIsTabActive())return this.unregister(),!1;if(this.registration)return!0;let e=new AbortController,t={controller:e};this.registration=t;try{let t=Pa().map(e=>({annotations:{consequentialHint:!e.annotations.readOnlyHint,readOnlyHint:!!e.annotations.readOnlyHint,untrustedContentHint:!!e.untrustedContentHint},description:Ga(e),execute:async(t={},{signal:n}={})=>{Va(n);let r=null;typeof this.prepareToolCall==`function`&&(r=await this.prepareToolCall({input:t,name:e.name,signal:n}),Va(n));let i;try{i=await this.callTool(e.name,t,{signal:n})}catch(e){Va(n);let t=e?.body;if(typeof t?.code==`string`&&t.code.startsWith(`AGENT_`)&&t.code!==`AGENT_REQUEST_FAILED`)return{...t,isError:!0};throw e}let a=await Ha(i,this.renderExcalidrawScene,t);Va(n);let o=r?{preparation:r}:{};if(e.annotations.readOnlyHint)a=Ua(a,o);else{let i=await qa(this.acknowledgeToolCall,{input:t,name:e.name,preparation:r,result:a,signal:n});i&&(o.acknowledgement=i),a=Ua(a,o);try{this.onDidMutate?.({name:e.name,result:a})}catch(e){console.error(`[webmcp] Failed to report an applied mutation:`,e.message)}}return a},inputSchema:e.inputSchema,name:Fa(e.name)}));return t.push(Ja(this.getActiveContext)),await Promise.all(t.map(t=>this.modelContext.registerTool(t,{signal:e.signal}))),!0}catch(n){return e.signal.aborted||(e.abort(),console.error(`[webmcp] Failed to register tools:`,n.message)),this.registration===t&&(this.registration=null),!1}}unregister(){this.registration?.controller.abort(),this.registration=null}};function Xa(e){let t=null,n=null;function r(){return n??=Promise.resolve().then(e).then(e=>(t=e,e)),n}return{ensure:r,getImpl:()=>t,get provider(){return t?.provider??null},connect(){r().then(e=>{e.connect()})},disconnect(){t?.disconnect()},destroy(){t?.destroy()}}}function Za(e={}){let t=null,r=n(e.preferredUserName),i=Xa(async()=>{let{LobbyPresence:n}=await A(async()=>{let{LobbyPresence:e}=await import(`./lobby-presence-DNNXcuwR.js`);return{LobbyPresence:e}},[],import.meta.url),i=new n({...e,preferredUserName:r.name});return i.localUser=r,t&&i.setCurrentFile(t),i});return{get provider(){return i.provider},connect:()=>i.connect(),disconnect:()=>i.disconnect(),destroy:()=>i.destroy(),getConnectionState(){return i.getImpl()?.getConnectionState?.()??{status:`connecting`,unreachable:!1}},setCurrentFile(e){t=e,i.getImpl()?.setCurrentFile(e)},setUserName(e){e&&(r={...r,name:e},i.getImpl()?.setUserName(e))},getLocalUser(){return i.getImpl()?.getLocalUser()??r},sendChatMessage(e){return i.getImpl()?.sendChatMessage(e)??null},sendWorkspaceEvent(e){return i.getImpl()?.sendWorkspaceEvent(e)}}}function Qa(e={}){return Xa(async()=>{let{WorkspaceSyncClient:t}=await A(async()=>{let{WorkspaceSyncClient:e}=await import(`./workspace-sync-client-C_P9wtjf.js`);return{WorkspaceSyncClient:e}},[],import.meta.url);return new t(e)})}function $a({authRequired:e,endpoint:t}){return[`MCP endpoint: ${t}`,`Transport: Streamable HTTP`,`Authorization: ${e?`Bearer $COLLABMD_ACCESS_TOKEN`:`None`}`].join(`
|
|
136
|
+
`)}function eo(e){return`export COLLABMD_ACCESS_TOKEN='${String(e).replaceAll(`'`,`'\\''`)}'`}function to(e){return e?new Date(e).toLocaleString():`Never`}var no=class{constructor({apiClient:e,closeToolbarMenu:t,content:n,dialog:r,runtimeConfig:i,toastController:a,trigger:o}){this.apiClient=e,this.closeToolbarMenu=t,this.content=n,this.dialog=r,this.runtimeConfig=i,this.toastController=a,this.trigger=o,this.secretToken=``,this.config={authRequired:i.auth?.strategy!==`none`,endpoint:i.agentAccess?.endpoint||``,managed:!!i.agentAccess?.managed},this.endpoint=new URL(this.config.endpoint,window.location.origin).toString(),this.trigger?.classList.toggle(`hidden`,!i.agentAccess?.enabled),this.trigger?.addEventListener(`click`,()=>void this.open()),this.dialog?.addEventListener(`close`,()=>{this.secretToken=``,this.content?.replaceChildren(),this.trigger?.focus?.()}),this.dialog?.addEventListener(`click`,e=>void this.handleClick(e)),this.dialog?.addEventListener(`submit`,e=>void this.handleSubmit(e))}async open(){this.closeToolbarMenu?.(),this.dialog?.showModal?.(),this.renderStatus(`Loading Agent Access…`);try{let e=this.config.managed?(await this.apiClient.listConnections()).connections:[];this.renderOverview(e)}catch(e){this.renderStatus(e.message||`Failed to load Agent Access`,{error:!0})}}renderStatus(e,{error:t=!1}={}){this.content&&(this.content.innerHTML=`<p class="agent-connection-status${t?` is-error`:``}" role="status">${j(e)}</p>`)}renderOverview(e=[]){let t=e.length>0?e.map(e=>`
|
|
137
|
+
<article class="agent-connection-card">
|
|
138
|
+
<div>
|
|
139
|
+
<strong>${j(e.label)}</strong>
|
|
140
|
+
<span>${j(e.scopes.join(`, `))}</span>
|
|
141
|
+
<small>Expires ${j(to(e.expiresAt))}</small>
|
|
142
|
+
</div>
|
|
143
|
+
<button class="ui-button ui-button--secondary ui-button--compact" type="button" data-agent-revoke="${j(e.id)}">Revoke</button>
|
|
144
|
+
</article>
|
|
145
|
+
`).join(``):`
|
|
146
|
+
<div class="agent-connection-empty">
|
|
147
|
+
<strong>Connect your first agent</strong>
|
|
148
|
+
<p>Choose its access, create a secure token, then copy the setup into your agent.</p>
|
|
149
|
+
</div>
|
|
150
|
+
`,n=this.config.managed?`<button class="ui-button ui-button--primary" type="button" data-agent-create>${e.length>0?`New connection`:`Start setup`}</button>`:`
|
|
151
|
+
<section class="agent-connection-empty">
|
|
152
|
+
<strong>No authentication required</strong>
|
|
153
|
+
<ol class="agent-connection-steps">
|
|
154
|
+
<li>Copy the connection details below into your agent.</li>
|
|
155
|
+
<li>Add this CollabMD MCP endpoint and restart the agent.</li>
|
|
156
|
+
<li>Anyone who can reach this no-auth workspace can use its read and edit tools.</li>
|
|
157
|
+
</ol>
|
|
158
|
+
</section>
|
|
159
|
+
`,r=this.config.managed?`
|
|
160
|
+
<section class="agent-connection-section">
|
|
161
|
+
<h3>Connections</h3>
|
|
162
|
+
<div class="agent-connection-list">${t}</div>
|
|
163
|
+
</section>
|
|
164
|
+
`:``;this.content.innerHTML=`
|
|
165
|
+
${r}
|
|
166
|
+
${this.config.managed?``:n}
|
|
167
|
+
<details class="agent-connection-details">
|
|
168
|
+
<summary>Connection details</summary>
|
|
169
|
+
<code>${j(this.endpoint)}</code>
|
|
170
|
+
<p>Streamable HTTP · ${this.config.authRequired?`Bearer token`:`No authentication`} · Read and edit tools</p>
|
|
171
|
+
</details>
|
|
172
|
+
<div class="agent-connection-actions">
|
|
173
|
+
${this.config.managed?n:`<button class="ui-button ui-button--primary" type="button" data-agent-copy-setup>Copy connection details</button>`}
|
|
174
|
+
<button class="ui-button ui-button--ghost" type="button" data-agent-close>Close</button>
|
|
175
|
+
</div>
|
|
176
|
+
<p class="agent-connection-live" role="status" aria-live="polite"></p>
|
|
177
|
+
`}renderCreate(){this.content.innerHTML=`
|
|
178
|
+
<form class="agent-connection-form" data-agent-create-form>
|
|
179
|
+
<header class="agent-connection-step-header">
|
|
180
|
+
<span>Step 1 of 2</span>
|
|
181
|
+
<h3>Choose access</h3>
|
|
182
|
+
<p>You can revoke this connection at any time.</p>
|
|
183
|
+
</header>
|
|
184
|
+
<label class="app-dialog-field">
|
|
185
|
+
<span class="app-dialog-label">Connection name</span>
|
|
186
|
+
<input class="ui-input" name="label" maxlength="80" value="My Agent" required>
|
|
187
|
+
</label>
|
|
188
|
+
<fieldset class="agent-connection-scopes">
|
|
189
|
+
<legend>Access</legend>
|
|
190
|
+
<label><input type="checkbox" checked disabled> Read Vault Content</label>
|
|
191
|
+
<label><input type="checkbox" name="edit" checked> Edit and create supported text files</label>
|
|
192
|
+
</fieldset>
|
|
193
|
+
<p class="agent-connection-note">Token expires after 30 days and can be revoked here. Delete, rename, Git, and publish are not exposed.</p>
|
|
194
|
+
<div class="agent-connection-actions">
|
|
195
|
+
<button class="ui-button ui-button--secondary" type="button" data-agent-back>Back</button>
|
|
196
|
+
<button class="ui-button ui-button--primary" type="submit">Create secure token</button>
|
|
197
|
+
</div>
|
|
198
|
+
<p class="agent-connection-live" role="status" aria-live="polite"></p>
|
|
199
|
+
</form>
|
|
200
|
+
`}renderToken({token:e}){this.secretToken=e;let t=$a({authRequired:this.config.authRequired,endpoint:this.endpoint});this.content.innerHTML=`
|
|
201
|
+
<header class="agent-connection-step-header">
|
|
202
|
+
<span>Step 2 of 2</span>
|
|
203
|
+
<h3>Finish setup in your MCP client</h3>
|
|
204
|
+
<p class="agent-connection-warning">The token is shown once. Finish these steps before closing.</p>
|
|
205
|
+
</header>
|
|
206
|
+
<ol class="agent-connection-steps agent-connection-steps--setup">
|
|
207
|
+
<li>
|
|
208
|
+
<div><strong>Save the access token</strong><span>Run the copied command in the terminal that starts your MCP client.</span></div>
|
|
209
|
+
<button class="ui-button ui-button--primary" type="button" data-agent-copy-token>Copy token command</button>
|
|
210
|
+
</li>
|
|
211
|
+
<li>
|
|
212
|
+
<div><strong>Add this workspace</strong><span>Paste the setup into your MCP client.</span></div>
|
|
213
|
+
<button class="ui-button ui-button--secondary" type="button" data-agent-copy-setup>Copy MCP setup</button>
|
|
214
|
+
</li>
|
|
215
|
+
</ol>
|
|
216
|
+
<details class="agent-connection-details">
|
|
217
|
+
<summary>View manual setup</summary>
|
|
218
|
+
<input class="ui-input agent-connection-token" value="${j(e)}" readonly aria-label="Agent Connection token">
|
|
219
|
+
<pre><code>${j(t)}</code></pre>
|
|
220
|
+
</details>
|
|
221
|
+
<div class="agent-connection-actions">
|
|
222
|
+
<button class="ui-button ui-button--primary" type="button" data-agent-close>Done</button>
|
|
223
|
+
</div>
|
|
224
|
+
<p class="agent-connection-live" role="status" aria-live="polite"></p>
|
|
225
|
+
`}async refresh(){let e=this.config.managed?(await this.apiClient.listConnections()).connections:[];this.renderOverview(e)}setLiveMessage(e){let t=this.content?.querySelector(`.agent-connection-live`);t&&(t.textContent=e)}async copy(e,t){await navigator.clipboard.writeText(e),this.setLiveMessage(t)}async handleClick(e){let t=e.target.closest(`button`);if(t){if(t.dataset.agentClose!=null){this.dialog.close();return}if(t.dataset.agentCreate!=null){this.renderCreate();return}if(t.dataset.agentBack!=null){await this.refresh();return}if(t.dataset.agentCopyToken!=null){await this.copy(eo(this.secretToken),`Token command copied — run it in the agent terminal.`);return}if(t.dataset.agentCopySetup!=null){await this.copy($a({authRequired:this.config.authRequired,endpoint:this.endpoint}),`Setup copied — add it to your MCP client.`);return}if(t.dataset.agentRevoke){if(!window.confirm(`Revoke this Agent Connection?`))return;try{await this.apiClient.revokeConnection(t.dataset.agentRevoke),await this.refresh(),this.setLiveMessage(`Agent Connection revoked`)}catch(e){this.toastController?.show(e.message||`Failed to revoke Agent Connection`)}}}}async handleSubmit(e){let t=e.target.closest(`[data-agent-create-form]`);if(!t)return;e.preventDefault();let n=new FormData(t),r=t.querySelector(`[type="submit"]`);r.disabled=!0;try{let e=await this.apiClient.createConnection({clientKind:`generic`,label:n.get(`label`),scopes:n.get(`edit`)===`on`?[`vault:read`,`vault:edit`]:[`vault:read`]});this.renderToken(e)}catch(e){this.setLiveMessage(e.message||`Failed to create Agent Connection`),r.disabled=!1}}},ro=class{constructor({documentRef:e=document,headerPanelElement:t=null,inlinePanelElement:n=null,loadBacklinks:r=null,onBeforeToggle:i=null,onFileSelect:a,panelElement:o}){this.documentRef=e,this.headerPanel=t,this.panelRoot=o,this.inlinePanel=n,this.loadBacklinks=r,this.onBeforeToggle=i,this.onFileSelect=a,this._expanded=!1,this._currentFile=null,this._displayMode=`dock`,this._fetchController=null,this._backlinks=[],this._pendingOutsidePointer=null;let s=this.panelRoot?.querySelector(`[data-backlinks-variant="dock"]`)??this.panelRoot;this.panels=[this._createPanelRef(s,this.panelRoot),this._createPanelRef(this.headerPanel,this.headerPanel),this._createPanelRef(this.inlinePanel,this.inlinePanel)].filter(Boolean),this.handleDocumentPointerDown=e=>{if(!this._expanded)return;let t=e?.target;if(t&&this.panels.some(({panel:e})=>e?.contains?.(t))){this._pendingOutsidePointer=null;return}(e?.pointerType!==`mouse`||e?.button===0)&&(this._pendingOutsidePointer={pointerId:e?.pointerId??`mouse`,startX:Number(e?.clientX??0),startY:Number(e?.clientY??0)})},this.handleDocumentPointerMove=e=>{if(!this._pendingOutsidePointer)return;let t=Math.abs(Number(e?.clientX??0)-this._pendingOutsidePointer.startX),n=Math.abs(Number(e?.clientY??0)-this._pendingOutsidePointer.startY);(t>10||n>10)&&(this._pendingOutsidePointer=null)},this.handleDocumentPointerEnd=e=>{if(!this._expanded||!this._pendingOutsidePointer)return;let t=e?.target;if(t&&this.panels.some(({panel:e})=>e?.contains?.(t))){this._pendingOutsidePointer=null;return}this._pendingOutsidePointer=null,this.close()},this.handleDocumentKeyDown=e=>{this._expanded&&e?.key===`Escape`&&(e.preventDefault?.(),this.close())},this.bindEvents()}bindEvents(){this.panels.forEach(e=>{e.header?.addEventListener(`click`,()=>{this._backlinks.length!==0&&(this.onBeforeToggle?.(),this._expanded=!this._expanded,this._pendingOutsidePointer=null,this._applyExpandState())})}),this.documentRef?.addEventListener?.(`pointerdown`,this.handleDocumentPointerDown),this.documentRef?.addEventListener?.(`pointermove`,this.handleDocumentPointerMove,{passive:!0}),this.documentRef?.addEventListener?.(`pointerup`,this.handleDocumentPointerEnd),this.documentRef?.addEventListener?.(`pointercancel`,this.handleDocumentPointerEnd),this.documentRef?.addEventListener?.(`keydown`,this.handleDocumentKeyDown)}async load(e){let t=e!==this._currentFile;if(this._currentFile=e,t&&(this._expanded=!1),!e){this._backlinks=[],this._render();return}this._fetchController?.abort(),this._fetchController=new AbortController;try{let t=await this.loadBacklinks(e,{signal:this._fetchController.signal});if(this._currentFile!==e)return;this._backlinks=t}catch(e){if(e.name===`AbortError`)return;console.warn(`[backlinks] Failed to load:`,e.message),this._backlinks=[]}this._render()}setDisplayMode(e=`dock`){let t=e===`header`?`header`:`dock`;this._displayMode!==t&&(this._displayMode=t,this._expanded=!1,this._pendingOutsidePointer=null,this._render())}clear(){this._currentFile=null,this._backlinks=[],this._expanded=!1,this._render()}close(){this._expanded&&(this._expanded=!1,this._pendingOutsidePointer=null,this._applyExpandState())}_createPanelRef(e,t=e){return e?{panel:e,header:e.querySelector(`.backlinks-header`),toggle:e.querySelector(`.backlinks-toggle`),countBadge:e.querySelector(`.backlinks-count`),body:e.querySelector(`.backlinks-body`),list:e.querySelector(`.backlinks-list`),root:t}:null}_render(){let e=this._backlinks.length,t=e===1?`Linked Mention`:`Linked Mentions`,n=!!this._currentFile&&e>0;n||(this._expanded=!1),this.panels.forEach(r=>{let i=n&&this._shouldShowPanel(r);r.root?.classList?.toggle?.(`hidden`,!i),r.countBadge.textContent=n?String(e):``,r.toggle.textContent=t,r.header?.classList.toggle(`backlinks-header-empty`,!i),i?this._renderList(r.list):r.list.innerHTML=``}),this._applyExpandState()}_shouldShowPanel(e){let t=e.panel?.getAttribute?.(`data-backlinks-variant`)??``;return t===`header`?this._displayMode===`header`:t!==`dock`||this._displayMode===`dock`}_renderList(e){if(!e)return;e.innerHTML=``;let t=this.documentRef?.createDocumentFragment?.(),n=t??e;this._backlinks.forEach(e=>{n.appendChild(this._createBacklinkItem(e))}),t&&e.appendChild(t)}_createBacklinkItem(e){let t=x(e.file.split(`/`).pop()),n=e.file.includes(`/`)?e.file.substring(0,e.file.lastIndexOf(`/`)):``,r=this.documentRef.createElement(`button`);r.type=`button`,r.className=`backlink-item`,r.addEventListener(`click`,()=>{this.close(),this.onFileSelect?.(e.file)});let i=this.documentRef.createElement(`div`);if(i.className=`backlink-file-name`,i.innerHTML=`
|
|
226
|
+
<svg class="backlink-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
227
|
+
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
|
|
228
|
+
<polyline points="14 2 14 8 20 8"/>
|
|
229
|
+
</svg>
|
|
230
|
+
<span>${j(t)}</span>
|
|
231
|
+
${n?`<span class="backlink-dir">${j(n)}</span>`:``}
|
|
232
|
+
`,r.appendChild(i),e.contexts.slice(0,3).forEach(e=>{let t=this.documentRef.createElement(`div`);t.className=`backlink-context`,t.textContent=e,r.appendChild(t)}),e.contexts.length>3){let t=this.documentRef.createElement(`div`);t.className=`backlink-context backlink-more`,t.textContent=`+${e.contexts.length-3} more`,r.appendChild(t)}return r}_applyExpandState(){this.panels.forEach(e=>{let t=this._expanded&&this._backlinks.length>0&&this._shouldShowPanel(e);e.panel.classList.toggle(`expanded`,t),e.header?.setAttribute(`aria-expanded`,String(t)),e.header?.setAttribute(`aria-disabled`,String(this._backlinks.length===0)),e.body?.setAttribute(`aria-hidden`,String(!t)),e.body?.toggleAttribute(`inert`,!t)})}},io=class{constructor({apiClient:e,appRoot:t=null,gate:n,runtimeConfig:r,teamSettingsController:i}){this.apiClient=e,this.appRoot=t,this.gate=n,this.content=n?.querySelector(`[data-hosted-gate-content]`)??null,this.teamSettingsController=i,this.enabled=r.hosted?.enabled===!0,this.accessGrantedPromise=new Promise(e=>{this.resolveAccessGranted=e}),this.gate?.addEventListener(`click`,e=>void this.handleClick(e)),this.gate?.addEventListener(`submit`,e=>void this.handleSubmit(e))}async initialize(){if(!this.enabled){this.hide();return}await this.refresh(),await this.accessGrantedPromise}async refresh(){this.show(`Loading workspace…`);let e;try{e=await this.apiClient.getStatus()}catch(e){e.status===401||e.code===`HOSTED_AUTH_REQUIRED`?this.show(`Sign in to access this workspace.`,{title:`Sign-in required`}):this.show(e.message||`Failed to load workspace status.`,{error:!0,title:`Workspace unavailable`}),this.teamSettingsController?.setTriggerVisible(!1);return}this.applyStatus(e)}applyStatus(e){let t=e.membership??null,n=t?.role===`admin`;if(this.teamSettingsController?.setTriggerVisible(!!(n&&e.setupComplete)),!e.claimed){this.renderClaim();return}if(!e.setupComplete){n?this.renderSetup(e):this.show(`Workspace setup is incomplete. Ask a Team Admin to finish setup.`,{title:e.team?.name||`Workspace setup`});return}if(!t){this.renderAccept(e);return}this.hide(),this.resolveAccessGranted()}hide(){this.gate?.classList.add(`hidden`),this.content?.replaceChildren(),this.appRoot&&(this.appRoot.inert=!1)}reveal(){this.gate&&(this.gate.classList.remove(`hidden`),this.appRoot&&(this.appRoot.inert=!0),this.content?.querySelector(`button, input, select`)?.focus?.())}render(e){this.gate&&this.content&&(this.content.replaceChildren(Oe(e)),this.reveal())}show(e,{error:t=!1,title:n=`Workspace`}={}){this.render(`
|
|
233
|
+
<h2 class="hosted-gate-title" id="hostedGateTitle">${j(n)}</h2>
|
|
234
|
+
<p class="hosted-gate-status${t?` is-error`:``}" role="status">${j(e)}</p>
|
|
235
|
+
`)}renderClaim(){this.render(`
|
|
236
|
+
<h2 class="hosted-gate-title" id="hostedGateTitle">Claim this workspace</h2>
|
|
237
|
+
<p class="hosted-gate-copy">Enter the team name and the one-time claim token from provisioning to become the first Team Admin.</p>
|
|
238
|
+
<form class="hosted-gate-form" data-claim-form>
|
|
239
|
+
<label class="app-dialog-field">
|
|
240
|
+
<span class="app-dialog-label">Team name</span>
|
|
241
|
+
<input class="ui-input" name="teamName" maxlength="80" autocomplete="off" spellcheck="false" required>
|
|
242
|
+
</label>
|
|
243
|
+
<label class="app-dialog-field">
|
|
244
|
+
<span class="app-dialog-label">Claim token</span>
|
|
245
|
+
<input class="ui-input" name="token" type="password" autocomplete="off" spellcheck="false" required>
|
|
246
|
+
</label>
|
|
247
|
+
<button class="ui-button ui-button--primary" type="submit">Claim workspace</button>
|
|
248
|
+
</form>
|
|
249
|
+
<p class="hosted-gate-live" role="status" aria-live="polite"></p>
|
|
250
|
+
`)}renderSetup(e){this.render(`
|
|
251
|
+
<h2 class="hosted-gate-title" id="hostedGateTitle">${j(e.team?.name||`Workspace setup`)}</h2>
|
|
252
|
+
<p class="hosted-gate-copy">Workspace setup is not complete. The editor and invitations stay unavailable until setup is done. Connecting a GitHub vault source comes later; for now, completing setup unlocks team management.</p>
|
|
253
|
+
<button class="ui-button ui-button--primary" type="button" data-complete-setup>Complete setup</button>
|
|
254
|
+
<p class="hosted-gate-live" role="status" aria-live="polite"></p>
|
|
255
|
+
`)}renderAccept(e){this.render(`
|
|
256
|
+
<h2 class="hosted-gate-title" id="hostedGateTitle">${j(e.team?.name||`Workspace`)}</h2>
|
|
257
|
+
<p class="hosted-gate-copy">You are signed in but not a team member yet. If a Team Admin invited your Google email, accept below to join.</p>
|
|
258
|
+
<button class="ui-button ui-button--primary" type="button" data-accept-invitation>Accept invitation</button>
|
|
259
|
+
<p class="hosted-gate-live" role="status" aria-live="polite"></p>
|
|
260
|
+
`)}setLiveMessage(e){let t=this.content?.querySelector(`.hosted-gate-live`);t&&(t.textContent=e)}async handleClick(e){let t=e.target.closest(`button`);if(t){if(t.dataset.completeSetup!=null){t.disabled=!0;try{await this.apiClient.completeSetup(),await this.refresh()}catch(e){this.setLiveMessage(e.message||`Failed to complete setup`),t.disabled=!1}return}if(t.dataset.acceptInvitation!=null){t.disabled=!0;try{await this.apiClient.acceptInvitation(),await this.refresh()}catch(e){this.setLiveMessage(e.message||`No pending invitation was found for your account.`),t.disabled=!1}}}}async handleSubmit(e){let t=e.target.closest(`[data-claim-form]`);if(!t)return;e.preventDefault();let n=new FormData(t),r=t.querySelector(`[type="submit"]`);r.disabled=!0;try{await this.apiClient.claimWorkspace({teamName:String(n.get(`teamName`)??``).trim(),token:String(n.get(`token`)??``)}),await this.refresh()}catch(e){this.setLiveMessage(e.message||`Failed to claim workspace`),r.disabled=!1}}};function ao(e){return e?new Date(e).toLocaleString():`—`}function oo(e){return[`collaborator`,`admin`].map(t=>`<option value="${t}"${t===e?` selected`:``}>${t===`admin`?`Admin`:`Collaborator`}</option>`).join(``)}function so(e){return e.map(e=>`
|
|
261
|
+
<li class="team-settings-row team-settings-row--audit">
|
|
262
|
+
<div class="team-settings-row-main">
|
|
263
|
+
<strong>${j(e.type)}</strong>
|
|
264
|
+
<span>${j(e.targetEmail||``)}${e.targetRole?` · ${j(e.targetRole)}`:``}</span>
|
|
265
|
+
<small>By ${j(e.actorName||e.actorEmail)} · ${ao(e.createdAt)}</small>
|
|
266
|
+
</div>
|
|
267
|
+
</li>`).join(``)}var co=class{constructor({apiClient:e,closeToolbarMenu:t,content:n,dialog:r,toastController:i,trigger:a}){this.apiClient=e,this.closeToolbarMenu=t,this.content=n,this.dialog=r,this.toastController=i,this.trigger=a,this.trigger?.classList.add(`hidden`),this.trigger?.addEventListener(`click`,()=>void this.open()),this.dialog?.addEventListener(`close`,()=>{this.content?.replaceChildren(),this.trigger?.focus?.()}),this.dialog?.addEventListener(`click`,e=>void this.handleClick(e)),this.dialog?.addEventListener(`submit`,e=>void this.handleSubmit(e)),this.dialog?.addEventListener(`change`,e=>void this.handleChange(e))}setTriggerVisible(e){this.trigger?.classList.toggle(`hidden`,!e)}async open(){this.closeToolbarMenu?.(),this.dialog?.showModal?.(),this.renderStatus(`Loading team settings…`),await this.refresh()}async loadOverview(){let[e,t,n]=await Promise.all([this.apiClient.listMemberships(),this.apiClient.listInvitations(),this.apiClient.listAuditEvents()]);this.renderOverview({auditEvents:n.events??[],invitations:t.invitations??[],memberships:e.memberships??[],nextAuditCursor:n.nextCursor??null})}renderStatus(e,{error:t=!1}={}){this.content&&this.content.replaceChildren(Oe(`<p class="team-settings-status${t?` is-error`:``}" role="status">${j(e)}</p>`))}renderOverview({auditEvents:e=[],invitations:t=[],memberships:n=[],nextAuditCursor:r=null}){if(!this.content)return;let i=n.length>0?n.map(e=>`
|
|
268
|
+
<li class="team-settings-row">
|
|
269
|
+
<div class="team-settings-row-main">
|
|
270
|
+
<strong>${j(e.name||e.email)}</strong>
|
|
271
|
+
<span>${j(e.email)}</span>
|
|
272
|
+
<small>Joined ${ao(e.joinedAt)}</small>
|
|
273
|
+
</div>
|
|
274
|
+
<label class="team-settings-row-role">Role
|
|
275
|
+
<select class="ui-input ui-input--compact" data-membership-role="${j(e.id)}">
|
|
276
|
+
${oo(e.role)}
|
|
277
|
+
</select>
|
|
278
|
+
</label>
|
|
279
|
+
<button class="ui-button ui-button--secondary ui-button--compact" type="button" data-membership-remove="${j(e.id)}" data-membership-email="${j(e.email)}">Remove</button>
|
|
280
|
+
</li>`).join(``):`<p class="team-settings-empty">No collaborators yet.</p>`,a=t.length>0?t.map(e=>`
|
|
281
|
+
<li class="team-settings-row">
|
|
282
|
+
<div class="team-settings-row-main">
|
|
283
|
+
<strong>${j(e.email)}</strong>
|
|
284
|
+
<span>Invited by ${j(e.invitedByName||e.invitedByEmail)}</span>
|
|
285
|
+
<small>Expires ${ao(e.expiresAt)}</small>
|
|
286
|
+
</div>
|
|
287
|
+
<label class="team-settings-row-role">Role
|
|
288
|
+
<select class="ui-input ui-input--compact" data-invitation-role="${j(e.id)}">
|
|
289
|
+
${oo(e.role)}
|
|
290
|
+
</select>
|
|
291
|
+
</label>
|
|
292
|
+
<button class="ui-button ui-button--secondary ui-button--compact" type="button" data-invitation-revoke="${j(e.id)}" data-invitation-email="${j(e.email)}">Revoke</button>
|
|
293
|
+
</li>`).join(``):`<p class="team-settings-empty">No pending invitations.</p>`,o=e.length>0?so(e):`<p class="team-settings-empty">No access history yet.</p>`;this.content.replaceChildren(Oe(`
|
|
294
|
+
<section class="team-settings-section">
|
|
295
|
+
<h3>Collaborators</h3>
|
|
296
|
+
<ul class="team-settings-list">${i}</ul>
|
|
297
|
+
</section>
|
|
298
|
+
<section class="team-settings-section">
|
|
299
|
+
<h3>Pending invitations</h3>
|
|
300
|
+
<ul class="team-settings-list">${a}</ul>
|
|
301
|
+
<form class="team-settings-invite-form" data-invite-form>
|
|
302
|
+
<label class="app-dialog-field">
|
|
303
|
+
<span class="app-dialog-label">Email</span>
|
|
304
|
+
<input class="ui-input" name="email" type="email" maxlength="254" autocomplete="off" spellcheck="false" required placeholder="teammate@example.com">
|
|
305
|
+
</label>
|
|
306
|
+
<label class="app-dialog-field">
|
|
307
|
+
<span class="app-dialog-label">Role</span>
|
|
308
|
+
<select class="ui-input" name="role">
|
|
309
|
+
<option value="collaborator">Collaborator</option>
|
|
310
|
+
<option value="admin">Admin</option>
|
|
311
|
+
</select>
|
|
312
|
+
</label>
|
|
313
|
+
<button class="ui-button ui-button--primary" type="submit">Invite</button>
|
|
314
|
+
</form>
|
|
315
|
+
<p class="team-settings-note">Share this workspace URL with the invited person. They sign in with the matching Google email, then accept the invitation. Email delivery is not set up yet.</p>
|
|
316
|
+
</section>
|
|
317
|
+
<section class="team-settings-section">
|
|
318
|
+
<h3>Access history</h3>
|
|
319
|
+
<ul class="team-settings-list team-settings-list--audit" tabindex="-1" aria-label="Access history">${o}</ul>
|
|
320
|
+
${r?`<button class="ui-button ui-button--secondary ui-button--compact" type="button" data-audit-more="${j(r)}">Load more history</button>`:``}
|
|
321
|
+
</section>
|
|
322
|
+
<div class="team-settings-actions">
|
|
323
|
+
<button class="ui-button ui-button--ghost" type="button" data-team-close>Close</button>
|
|
324
|
+
</div>
|
|
325
|
+
<p class="team-settings-live" role="status" aria-live="polite"></p>
|
|
326
|
+
`))}setLiveMessage(e){let t=this.content?.querySelector(`.team-settings-live`);t&&(t.textContent=e)}async refresh(){try{await this.loadOverview()}catch(e){this.renderStatus(e.message||`Failed to load team settings`,{error:!0})}}async loadMoreAuditEvents(e){if(!e.disabled){e.disabled=!0;try{let t=await this.apiClient.listAuditEvents({cursor:e.dataset.auditMore});if(!this.content?.contains(e))return;let n=this.content.querySelector(`.team-settings-list--audit`);n.append(Oe(so(t.events??[]))),t.nextCursor?e.dataset.auditMore=t.nextCursor:(document.activeElement===e&&n.focus(),e.remove()),this.setLiveMessage(`More access history loaded`)}catch(t){this.content?.contains(e)&&this.setLiveMessage(t.message||`Failed to load access history`)}finally{e.disabled=!1}}}async handleClick(e){let t=e.target.closest(`button`);if(t){if(t.dataset.teamClose!=null){this.dialog.close();return}if(t.dataset.auditMore!=null){await this.loadMoreAuditEvents(t);return}if(t.dataset.membershipRemove){if(!window.confirm(`Remove ${t.dataset.membershipEmail} from the team? They lose workspace access immediately.`))return;try{await this.apiClient.removeMembership(t.dataset.membershipRemove),await this.refresh(),this.setLiveMessage(`Collaborator removed`)}catch(e){this.toastController?.show(e.message||`Failed to remove collaborator`)}return}if(t.dataset.invitationRevoke){if(!window.confirm(`Revoke the invitation for ${t.dataset.invitationEmail}?`))return;try{await this.apiClient.revokeInvitation(t.dataset.invitationRevoke),await this.refresh(),this.setLiveMessage(`Invitation revoked`)}catch(e){this.toastController?.show(e.message||`Failed to revoke invitation`)}}}}async handleChange(e){let t=e.target.closest(`[data-membership-role]`);if(t){try{await this.apiClient.updateMembershipRole(t.dataset.membershipRole,t.value),await this.refresh(),this.setLiveMessage(`Role updated`)}catch(e){this.toastController?.show(e.message||`Failed to update role`),await this.refresh()}return}let n=e.target.closest(`[data-invitation-role]`);if(n)try{await this.apiClient.updateInvitationRole(n.dataset.invitationRole,n.value),await this.refresh(),this.setLiveMessage(`Invitation role updated`)}catch(e){this.toastController?.show(e.message||`Failed to update invitation`),await this.refresh()}}async handleSubmit(e){let t=e.target.closest(`[data-invite-form]`);if(!t)return;e.preventDefault();let n=new FormData(t),r=t.querySelector(`[type="submit"]`);r.disabled=!0;try{await this.apiClient.createInvitation({email:String(n.get(`email`)??``).trim(),role:n.get(`role`)}),await this.refresh(),this.setLiveMessage(`Invitation created — share the workspace URL with the invited person.`)}catch(e){this.setLiveMessage(e.message||`Failed to create invitation`),r.disabled=!1}}};function q(e){return Array.isArray(e)?e:[]}function lo({copy:e,title:t,tone:n=``}){let r=document.createElement(`div`);r.className=`comment-overview-empty ui-empty-state ui-empty-state--compact`,n&&(r.dataset.tone=n);let i=document.createElement(`p`);i.className=`ui-empty-state-title`,i.textContent=t;let a=document.createElement(`p`);return a.className=`ui-empty-state-copy`,a.textContent=e,r.append(i,a),r}var uo=class{constructor({panelElement:e,toastController:t=null,vaultApiClient:n,onOverviewChange:r=null,onThreadSelect:i=null}){this.panel=e,this.toastController=t,this.vaultApiClient=n,this.onOverviewChange=r,this.onThreadSelect=i,this.overview={files:[],generatedAt:0,totalThreadCount:0},this.loading=!1,this.errorMessage=``,this.refreshPromise=null,this.timeFormatter=new Intl.DateTimeFormat(void 0,{day:`numeric`,hour:`numeric`,minute:`2-digit`,month:`short`})}initialize(){this.render()}getThreadCounts(){return new Map(q(this.overview.files).map(e=>[e.filePath,Number(e.threadCount||0)]))}async refresh(){return this.refreshPromise?this.refreshPromise:(this.loading=!0,this.render(),this.refreshPromise=(async()=>{try{let e=await this.vaultApiClient.readCommentOverview();this.errorMessage=``,this.setOverview(e?.overview??e??{},{render:!1})}catch(e){console.error(`[comments] Failed to load comment overview:`,e.message),this.errorMessage=`Unable to load open comments.`,this.toastController?.show?.(`Failed to load comments`)}finally{this.loading=!1,this.refreshPromise=null,this.render()}})(),this.refreshPromise)}setOverview(e={},{render:t=!0}={}){this.errorMessage=``,this.overview={files:q(e.files),generatedAt:Number(e.generatedAt||0),totalThreadCount:Number(e.totalThreadCount||0)},this.onOverviewChange?.(this.overview,{threadCounts:this.getThreadCounts()}),t&&this.render()}render(){if(!this.panel||this.panel.classList.contains(`hidden`))return;if(this.panel.replaceChildren(),this.errorMessage){let e=lo({copy:this.errorMessage,title:`Comments unavailable`,tone:`error`});e.setAttribute(`role`,`alert`),this.panel.appendChild(e);return}if(this.loading&&q(this.overview.files).length===0){let e=lo({copy:`Checking the vault for active threads…`,title:`Loading comments`});e.setAttribute(`role`,`status`),this.panel.appendChild(e);return}let e=q(this.overview.files);if(e.length===0){let e=lo({copy:`Open comments from any document will appear here.`,title:`You’re all caught up`});this.panel.appendChild(e);return}let t=document.createDocumentFragment();e.forEach(e=>{t.appendChild(this.createFileGroup(e))}),this.panel.appendChild(t)}createFileGroup(e){let t=document.createElement(`section`);t.className=`comment-overview-file`;let n=document.createElement(`div`);n.className=`comment-overview-file-header`;let r=document.createElement(`div`);r.className=`comment-overview-file-title-wrap`;let i=document.createElement(`h3`);i.className=`comment-overview-file-title`,i.textContent=x(C(e.filePath));let a=document.createElement(`span`);a.className=`comment-overview-file-path`,a.textContent=w(e.filePath)||e.filePath;let o=document.createElement(`span`);return o.className=`comment-overview-file-count`,o.textContent=String(e.threadCount||q(e.threads).length),r.append(i,a),n.append(r,o),t.appendChild(n),q(e.threads).forEach(n=>{t.appendChild(this.createThreadButton(e.filePath,n))}),t}createThreadButton(e,t){let n=Number(t.messageCount||0),r=tt({authorName:t.latestMessage?.userName||t.createdByName||`Anonymous`,lineLabel:gt(t.anchor),messageCount:n,previewBody:t.latestMessage?.bodyPreview||``,quote:t.anchor?.quote||`Source anchored comment`,timestamp:this.formatTimestamp(t.latestActivityAt)});return r.addEventListener(`click`,()=>{this.onThreadSelect?.({anchor:t.anchor,filePath:e,threadId:t.id})}),r}formatTimestamp(e){if(!Number.isFinite(e))return``;try{return this.timeFormatter.format(new Date(e))}catch{return``}}};function fo(){if(this.cardRoot?.isConnected&&this.cardRoot.parentElement===document.body)return this.cardRoot;let e=document.createElement(`div`);return e.className=`comment-card-root hidden`,document.body.appendChild(e),this.cardRoot=e,e}function po(e=`editor`,t=null,n=null){let r=n?.anchor??this.session?.getCurrentSelectionCommentAnchor?.();if(!r)return;this.selectionAnchor=r,this.reactionPicker=null;let i=e===`editor`&&t?`editor-chip`:e,a=t??(e===`toolbar`?this.commentSelectionButton?.getBoundingClientRect?.():this.session?.getCommentAnchorClientRect?.(r));this.activeCard={anchor:r,composerDraft:null,mode:`create`,origin:i,previewRange:n?.range??null,replyThreadId:null,sourceRect:a??null},this.render()}function mo(e,{anchor:t,origin:n,sourceRect:r}){this.reactionPicker=null,this.activeCard={anchor:t,groupKey:e.key,groupThreadIds:e.threads.map(e=>e.id),mode:`group`,origin:n,replyDrafts:{},replyThreadId:null,sourceRect:r},this.renderDrawer(),this.renderCard()}function ho(){let e=this.activeCard?.mode===`create`&&this.activeCard.origin===`preview`;this.activeCard=null,this.pendingCardFocusElement=null,this.reactionPicker=null,this.renderCard(),e&&this.clearPreviewSelection(),this.scheduleLayoutRefresh()}function go(){return this.activeCard?this.activeCard.origin===`editor`?this.session?.getCommentAnchorClientRect?.(this.activeCard.anchor)??this.activeCard.sourceRect:this.activeCard.origin===`editor-chip`?this.activeCard.sourceRect:this.activeCard.origin===`preview`?mt(Array.from(this.activeCard.previewRange?.getClientRects?.()??[]))||(this.resolvePreviewTarget(this.activeCard.anchor)?.bubbleRect??this.activeCard.sourceRect):this.activeCard.origin===`toolbar`?this.commentSelectionButton?.getBoundingClientRect?.()??this.activeCard.sourceRect:this.activeCard.sourceRect:null}function _o(e){return e instanceof HTMLTextAreaElement?{selectionDirection:e.selectionDirection??`none`,selectionEnd:e.selectionEnd,selectionStart:e.selectionStart,value:e.value}:null}function vo(){if(!this.activeCard)return;let e=this.cardRoot?.querySelector(`.comment-card-input`),t=_o(e);if(t){if(this.activeCard.mode===`create`){this.activeCard.composerDraft=t;return}this.activeCard.mode===`group`&&this.activeCard.replyThreadId&&(this.activeCard.replyDrafts={...this.activeCard.replyDrafts??{},[this.activeCard.replyThreadId]:t})}}function yo(e,t=null){return{element:e,selectionDirection:t?.selectionDirection??`none`,selectionEnd:Number.isInteger(t?.selectionEnd)?t.selectionEnd:null,selectionStart:Number.isInteger(t?.selectionStart)?t.selectionStart:null}}function bo(){let e=this.ensureCardRoot();if(this.captureActiveCardDraft(),e.replaceChildren(),e.classList.toggle(`hidden`,!this.activeCard),!this.activeCard){this.pendingCardFocusElement=null,e.style.visibility=``;return}this.pendingCardFocusElement=null;let t=document.createElement(`section`);t.className=`comment-card`,t.addEventListener(`click`,e=>{this.reactionPicker&&!e.target?.closest?.(`.comment-reaction-picker-wrap`)&&(this.reactionPicker=null,requestAnimationFrame(()=>{this.activeCard&&this.renderCard()}))});let n=document.createElement(`div`);n.className=`ui-record-header comment-card-header`;let r=document.createElement(`div`);r.className=`comment-card-title-wrap`;let i=document.createElement(`h3`);i.className=`comment-card-title`,i.textContent=this.activeCard.mode===`create`?`New comment`:`Comment threads`;let a=document.createElement(`p`);a.className=`comment-card-meta`,a.textContent=gt(this.activeCard.anchor),r.append(i,a);let o=document.createElement(`button`);o.type=`button`,o.className=k({variant:`ghost`,size:`compact`,pill:!0,extra:[`ui-action-pill`,`comment-card-close`]}),o.setAttribute(`aria-label`,`Close comments`),o.textContent=`Close`,o.addEventListener(`click`,()=>this.closeCard()),n.append(r,o),t.appendChild(n);let s=document.createElement(`div`);if(s.className=`comment-card-scroll`,this.activeCard.mode===`create`&&this.activeCard.anchor?.fallbackToLines){let e=document.createElement(`p`);e.className=`comment-card-anchor-note`,e.textContent=`Exact preview mapping was unavailable. This comment will be anchored to ${gt(this.activeCard.anchor).toLowerCase()}.`,s.appendChild(e)}if(this.activeCard.anchor?.quote){let e=document.createElement(`p`);e.className=`comment-card-quote`,e.textContent=this.activeCard.anchor.quote,s.appendChild(e)}if(this.activeCard.mode===`create`)s.appendChild(this.createComposer());else{let e=this.getThreadGroups().find(e=>e.key===this.activeCard.groupKey);if(!e){this.closeCard();return}e.threads.forEach(e=>{s.appendChild(this.createThreadElement(e))})}e.style.visibility=`hidden`,t.appendChild(s),e.appendChild(t),this.updateReactionPickerPosition(t),this.positionCard(t),e.style.visibility=``,this.flushPendingCardFocus(),this.scheduleLayoutRefresh()}function xo(e){let t=st(e);if(!t)return;let{picker:n,scroll:r,wrap:i}=t;n.classList.remove(`is-upward`),n.style.maxHeight=``;let a=i.getBoundingClientRect(),o=r.getBoundingClientRect(),s=n.getBoundingClientRect(),c=window.innerHeight-12,l=Math.min(o.bottom,c),u=Math.max(o.top,12),d=Math.max(l-a.bottom-8,0),f=Math.max(a.top-u-8,0),p=s.height>d&&f>d,m=Math.max(p?f:d,120);n.classList.toggle(`is-upward`,p),n.style.maxHeight=`${m}px`}function So(){let e=this.cardRoot?.firstElementChild;if(!e||!this.activeCard){this.cardRoot&&(this.cardRoot.style.visibility=``);return}this.positionCard(e),this.cardRoot.style.visibility=``,this.flushPendingCardFocus()}function Co(){let e=document.createElement(`form`);e.className=`comment-card-form`;let t=document.createElement(`textarea`);t.className=ge({extra:`comment-card-input`}),t.rows=4,t.maxLength=Xe,t.setAttribute(`aria-label`,`Add comment`),t.placeholder=`Add context, feedback, or a question…`,t.value=this.activeCard?.composerDraft?.value??``;let n=document.createElement(`div`);n.className=`ui-record-actions comment-card-actions`;let r=document.createElement(`button`);r.type=`button`,r.className=k({variant:`secondary`}),r.textContent=`Cancel`,r.addEventListener(`click`,()=>this.closeCard());let i=document.createElement(`button`);return i.type=`submit`,i.className=k({variant:`primary`}),i.textContent=`Post comment`,n.append(r,i),e.append(t,n),e.addEventListener(`submit`,async e=>{if(e.preventDefault(),!await this.onCreateThread?.({anchor:this.activeCard?.anchor,body:t.value})){t.focus();return}this.closeCard()}),this.pendingCardFocusElement=yo(t,this.activeCard?.composerDraft),e}function wo(e){let t=document.createElement(`article`);t.className=`comment-thread-card`;let n=document.createElement(`div`);n.className=`ui-record-actions comment-thread-card-actions`;let r=document.createElement(`button`);r.type=`button`,r.className=k({variant:`ghost`,size:`compact`,pill:!0,extra:[`ui-action-pill`,`comment-thread-card-action`]});let i=this.activeCard?.replyThreadId===e.id;r.classList.toggle(`is-active`,i),r.textContent=`Reply`,r.setAttribute(`aria-pressed`,String(i)),r.setAttribute(`aria-label`,i?`Cancel reply`:`Reply to thread`),r.title=i?`Cancel reply`:`Reply to thread`,r.addEventListener(`click`,()=>{i&&this.activeCard?.replyDrafts?.[e.id]&&delete this.activeCard.replyDrafts[e.id],this.activeCard={...this.activeCard,replyThreadId:i?null:e.id},this.renderCard()});let a=document.createElement(`button`);return a.type=`button`,a.className=k({variant:`ghost`,size:`compact`,pill:!0,extra:[`ui-action-pill`,`comment-thread-card-action`,`is-danger`]}),a.textContent=`Resolve`,a.addEventListener(`click`,async()=>{await this.onResolveThread?.(e.id)}),n.append(r,a),e.messages.forEach((r,i)=>{t.appendChild(this.createMessageElement(e,r,{actions:i===0?n:null,isThreadStart:i===0}))}),this.activeCard?.replyThreadId===e.id&&t.appendChild(this.createReplyComposer(e)),t}function To(e,t,{actions:n=null,isThreadStart:r=!1}={}){let i=document.createElement(`div`);i.className=`comment-message-card`,i.classList.toggle(`is-thread-start`,r);let a=document.createElement(`div`);a.className=`ui-record-meta comment-message-card-meta`;let o=document.createElement(`span`);o.className=`comment-message-card-author`,o.textContent=t.userName;let s=document.createElement(`span`);s.className=`comment-message-card-time`,s.textContent=this.formatTimestamp(t.createdAt);let c=rt(t.body,`comment-message-card-body comment-markdown`);return a.append(o,s),n&&a.appendChild(n),i.append(a,c),i.appendChild(this.createReactionBar(e,t)),i}function Eo(e,t){let n=this.session?.getLocalUser?.()?.userId??``,r=document.createElement(`div`);r.className=`comment-reaction-bar`;let i=new Set((t.reactions??[]).map(e=>e.emoji)),a=document.createElement(`div`);a.className=`comment-reaction-chips`,(t.reactions??[]).forEach(r=>{let i=document.createElement(`button`);i.type=`button`,i.className=`ui-chip-button ui-chip-button--comment comment-reaction-chip`,i.classList.toggle(`is-active`,ot(r,n)),i.setAttribute(`aria-pressed`,String(ot(r,n))),i.title=r.users?.map(e=>e.userName).join(`, `)||r.emoji;let o=document.createElement(`span`);o.className=`comment-reaction-chip-emoji`,o.textContent=r.emoji;let s=document.createElement(`span`);s.className=`comment-reaction-chip-count`,s.textContent=it(r),i.append(o,s),i.addEventListener(`click`,async()=>{await this.onToggleReaction?.(e.id,t.id,r.emoji)}),a.appendChild(i)});let o=document.createElement(`div`);o.className=`comment-reaction-actions`,ut.filter(e=>!i.has(e)).forEach(n=>{o.appendChild(this.createQuickReactionButton(e,t,n))});let s=document.createElement(`div`);s.className=`comment-reaction-picker-wrap`;let c=document.createElement(`button`);return c.type=`button`,c.className=`ui-chip-button ui-chip-button--comment comment-reaction-more-trigger`,c.dataset.reactionPickerToggle=`true`,c.setAttribute(`aria-expanded`,String(_t(this.reactionPicker,e.id,t.id))),c.textContent=`More`,c.addEventListener(`click`,()=>{let n=_t(this.reactionPicker,e.id,t.id);this.reactionPicker=n?null:{messageId:t.id,threadId:e.id},this.renderCard()}),s.appendChild(c),_t(this.reactionPicker,e.id,t.id)&&s.appendChild(this.createReactionPicker(e,t)),o.appendChild(s),r.append(a,o),r}function Do(e,t,n){let r=document.createElement(`button`);return r.type=`button`,r.className=`ui-icon-chip ui-icon-chip--comment comment-reaction-quick-add`,r.textContent=n,r.title=`React with ${n}`,r.addEventListener(`click`,async()=>{await this.onToggleReaction?.(e.id,t.id,n)}),r}function Oo(e,t){let n=document.createElement(`div`);n.className=`comment-reaction-picker`;let r=document.createElement(`div`);return r.className=`comment-reaction-picker-grid`,ht.forEach(n=>{r.appendChild(this.createReactionPickerButton(e,t,n))}),n.appendChild(r),n}function ko(e,t,n){let r=document.createElement(`button`);return r.type=`button`,r.className=`ui-icon-chip ui-icon-chip--comment comment-reaction-picker-btn`,r.textContent=n,r.title=`React with ${n}`,r.addEventListener(`click`,async()=>{await this.onToggleReaction?.(e.id,t.id,n)&&(this.reactionPicker=null,this.renderCard())}),r}function Ao(e){let t=document.createElement(`form`);t.className=`comment-reply-form`;let n=this.activeCard?.replyDrafts?.[e.id]??null,r=document.createElement(`textarea`);r.className=ge({extra:`comment-card-input`}),r.rows=3,r.maxLength=Xe,r.setAttribute(`aria-label`,`Reply to thread`),r.placeholder=`Reply to thread…`,r.value=n?.value??``;let i=document.createElement(`div`);i.className=`ui-record-actions comment-card-actions`;let a=document.createElement(`button`);a.type=`button`,a.className=k({variant:`secondary`}),a.textContent=`Cancel`,a.addEventListener(`click`,()=>{this.activeCard?.replyDrafts?.[e.id]&&delete this.activeCard.replyDrafts[e.id],this.activeCard={...this.activeCard,replyThreadId:null},this.renderCard()});let o=document.createElement(`button`);return o.type=`submit`,o.className=k({variant:`primary`}),o.textContent=`Reply`,i.append(a,o),t.append(r,i),this.pendingCardFocusElement=yo(r,n),t.addEventListener(`submit`,async t=>{if(t.preventDefault(),!await this.onReplyToThread?.(e.id,r.value)){r.focus();return}this.activeCard?.replyDrafts?.[e.id]&&delete this.activeCard.replyDrafts[e.id],this.activeCard={...this.activeCard,replyThreadId:null},this.renderCard()}),t}function jo(e){let t=this.updateCardSourceRect(),n=window.innerWidth,r=window.innerHeight,i=e.getBoundingClientRect(),a=M((n-i.width)/2,16,n-i.width-16),o=M((r-i.height)/4,16,r-i.height-16),s=a,c=o;t&&(s=M(t.left,16,n-Math.min(i.width,520)-16),c=t.bottom+14,c+i.height>r-16&&(c=Math.max(t.top-i.height-14,16))),this.cardRoot.style.left=`${s}px`,this.cardRoot.style.top=`${c}px`,this.cardRoot.style.width=`${Math.min(Math.max(i.width,520),n-32)}px`}function Mo(){let e=this.pendingCardFocusElement,t=e instanceof HTMLElement?e:e?.element;if(!(t instanceof HTMLElement)||!t.isConnected){this.pendingCardFocusElement=null;return}this.pendingCardFocusElement=null;let n=()=>{if(!t.isConnected)return;let n=document.activeElement;n instanceof HTMLElement&&this.editorContainer?.contains(n)&&n.blur(),t.focus({preventScroll:!0}),t instanceof HTMLTextAreaElement&&Number.isInteger(e?.selectionStart)&&Number.isInteger(e?.selectionEnd)&&t.setSelectionRange(e.selectionStart,e.selectionEnd,e.selectionDirection??`none`)};n(),document.activeElement!==t&&requestAnimationFrame(()=>{n(),document.activeElement!==t&&setTimeout(()=>{n()},50)})}var No={captureActiveCardDraft:vo,closeCard:ho,createComposer:Co,createPendingFocusTarget:yo,createMessageElement:To,createQuickReactionButton:Do,createReactionBar:Eo,createReactionPicker:Oo,createReactionPickerButton:ko,createReplyComposer:Ao,createTextareaDraft:_o,createThreadElement:wo,ensureCardRoot:fo,flushPendingCardFocus:Mo,openComposerForSelection:po,openThreadGroup:mo,positionCard:jo,renderCard:bo,repositionActiveCard:So,updateCardSourceRect:go,updateReactionPickerPosition:xo};function Po(e,t,n){e.classList.toggle(`is-active`,t),e.classList.toggle(`is-hovered`,n),e.classList.toggle(`is-passive`,!t&&!n)}function Fo(){let e=this.getThreadGroups();this.renderEditorLayer(e),this.renderPreviewLayer(e),this.repositionActiveCard()}function Io(){this.layoutFrame||=requestAnimationFrame(()=>{this.layoutFrame=0,this.refreshLayout()})}function Lo(){if(this.editorLayer?.isConnected&&this.editorLayer.parentElement===this.editorContainer)return this.editorLayer;let e=document.createElement(`div`);return e.className=`comment-editor-layer`,this.editorContainer?.appendChild(e),this.editorLayer=e,e}function Ro(e=this.getThreadGroups()){let t=this.ensureEditorLayer();if(!this.supported||!this.session){t.childElementCount>0&&t.replaceChildren();return}let n=this.editorContainer?.getBoundingClientRect?.();if(!n){t.childElementCount>0&&t.replaceChildren();return}let r=new Map(Array.from(t.querySelectorAll(`.comment-editor-badge`)).map(e=>[e.dataset.commentEditorGroupKey,e])),i=new Set,a=[];e.forEach(e=>{let o=this.session.getCommentAnchorClientRect?.(e.anchor);if(!o)return;let s=$e(o,n);if(s.bottom<0||s.top>n.height)return;let c=r.get(e.key);c||(c=document.createElement(`button`),c.type=`button`,c.className=`ui-state-marker ui-state-marker--comment comment-editor-badge`,c.dataset.commentEditorGroupKey=e.key,c.addEventListener(`pointerdown`,e=>{e.preventDefault()}),c.addEventListener(`pointerenter`,()=>{this.updateHoveredEditorGroups([c.dataset.commentEditorGroupKey])}),c.addEventListener(`pointerleave`,()=>{this.updateHoveredEditorGroups([])}),c.addEventListener(`focusin`,()=>{this.updateHoveredEditorGroups([c.dataset.commentEditorGroupKey])}),c.addEventListener(`focusout`,()=>{this.updateHoveredEditorGroups([])}),c.addEventListener(`click`,()=>{let e=c.commentGroup;e&&this.openThreadGroup(e,{anchor:e.anchor,origin:`editor`,sourceRect:c.commentSourceRect})}),t.appendChild(c)),c.commentGroup=e,c.commentSourceRect=o,c.dataset.count!==String(e.threads.length)&&(c.dataset.count=String(e.threads.length),c.replaceChildren(ct(e.threads.length)));let l=this.activeCard?.groupKey===e.key,u=this.hoveredEditorGroupKeys.includes(e.key);Po(c,l,u),c.setAttribute(`aria-label`,`${e.threads.length} comment thread${e.threads.length===1?``:`s`}`);let d=Math.max(s.top,8);c.style.top=`${d}px`,c.style.left=`${Math.max(n.width-36,8)}px`,c.title=`${e.threads.length} comment${e.threads.length===1?``:`s`}`,i.add(e.key),a.push(d)}),r.forEach((e,t)=>{i.has(t)||e.remove()});let o=t.querySelector(`.comment-selection-chip`);if(!this.committedSelectionAnchor||this.activeCard?.mode===`create`){o?.remove();return}let s=this.session.getCommentAnchorClientRect?.(this.committedSelectionAnchor),c=this.session.getSelectionChipClientRect?.(this.committedSelectionAnchor)??s;if(!c){o?.remove();return}let l=$e(c,n);if(l.bottom<0||l.top>n.height){o?.remove();return}let u=M(l.top,8,Math.max(n.height-36,8));for(;a.some(e=>Math.abs(e-u)<32);)u=M(u+36,8,Math.max(n.height-36,8));o||(o=document.createElement(`button`),o.type=`button`,o.className=`ui-selection-pill ui-selection-pill--comment comment-selection-chip`,o.textContent=`Comment`,o.addEventListener(`pointerdown`,e=>{e.preventDefault(),e.stopPropagation(),this.openComposerForSelection(`editor`,o.getBoundingClientRect())}),t.appendChild(o)),o.style.top=`${u}px`,o.style.right=`12px`}function zo(){if(this.previewLayer?.isConnected&&this.previewLayer.parentElement===this.previewElement)return this.previewLayer;let e=document.createElement(`div`);e.className=`comment-preview-highlights`;let t=document.createElement(`div`);return t.className=`comment-preview-layer`,this.previewElement?.append(e,t),this.previewHighlightLayer=e,this.previewLayer=t,t}function Bo(e){let t=this.previewLayer?.querySelector(`.comment-preview-selection-chip`),n=this.activeCard?.mode===`create`?null:this.previewSelection;if(!n){t?.remove();return}let r=mt(Array.from(n.range?.getClientRects?.()??[]))||n.rect;if(!r){t?.remove();return}t||(t=document.createElement(`button`),t.type=`button`,t.className=`ui-chip-button ui-chip-button--comment comment-preview-selection-chip`,t.textContent=`Comment`,t.setAttribute(`aria-label`,`Comment on selected preview text`),t.addEventListener(`pointerdown`,e=>{e.preventDefault(),e.stopPropagation()}),t.addEventListener(`click`,()=>{this.openComposerForSelection(`preview`,t.getBoundingClientRect(),t.previewSelection)}),this.previewLayer?.appendChild(t)),t.previewSelection=n,t.style.left=`${M(r.left-e.left,8,Math.max(this.previewElement.clientWidth-88,8))}px`,t.style.top=`${M(r.bottom-e.top+8,8,Math.max(this.previewElement.clientHeight-36,8))}px`}function Vo(e=this.getThreadGroups()){if(this.ensurePreviewLayer(),!this.supported||!this.previewElement){this.previewLayer?.childElementCount>0&&this.previewLayer.replaceChildren(),this.previewHighlightLayer?.childElementCount>0&&this.previewHighlightLayer.replaceChildren(),this.previewHoverRegions=[];return}let t=this.previewElement.getBoundingClientRect(),n={diagramShells:Array.from(this.previewElement.querySelectorAll(`.mermaid-shell, .plantuml-shell`)),sourceBlocks:Array.from(this.previewElement.querySelectorAll(`[data-source-line]`)).filter(e=>et(e))},r=new Map(Array.from(this.previewHighlightLayer?.querySelectorAll(`[data-comment-preview-highlight-key]`)??[]).map(e=>[e.dataset.commentPreviewHighlightKey,e])),i=new Set,a=({groupKey:e=``,isActive:n,isHovered:a,key:o,rect:s})=>{let c=r.get(o);c||(c=document.createElement(`div`),c.className=`comment-preview-highlight`,c.dataset.commentPreviewHighlightKey=o,this.previewHighlightLayer?.appendChild(c)),e?(c.dataset.commentPreviewGroupKey=e,c.dataset.commentPreviewGroupKeys=e):(delete c.dataset.commentPreviewGroupKey,delete c.dataset.commentPreviewGroupKeys),Po(c,n,a),c.style.left=`${s.left-t.left}px`,c.style.top=`${s.top-t.top}px`,c.style.width=`${s.width}px`,c.style.height=`${s.height}px`,i.add(o)};if(this.activeCard?.mode===`create`&&this.activeCard.origin===`preview`){let e=Array.from(this.activeCard.previewRange?.getClientRects?.()??[]);(e.length>0?e:[this.resolvePreviewTarget(this.activeCard.anchor,n)?.bubbleRect].filter(Boolean)).forEach((e,t)=>{a({isActive:!0,isHovered:!1,key:`selection:${t}`,rect:e})})}let o=[];e.forEach(e=>{let t=this.resolvePreviewTarget(e.anchor,n);if(!t?.bubbleRect)return;o.push({key:e.key,rects:t.hoverRects?.length>0?t.hoverRects:[t.bubbleRect]});let r=this.activeCard?.groupKey===e.key,i=this.hoveredPreviewGroupKeys.includes(e.key);t.highlightRects?.forEach((t,n)=>{a({groupKey:e.key,isActive:r,isHovered:i,key:`${e.key}:highlight:${n}`,rect:t})})}),Bo.call(this,t),r.forEach((e,t)=>{i.has(t)||e.remove()}),this.previewHoverRegions=o,this.lastPreviewPointerPosition&&this.updateHoveredPreviewGroups(this.getPreviewGroupKeysAtPoint(this.lastPreviewPointerPosition.x,this.lastPreviewPointerPosition.y))}function Ho(){this.previewSelection=null,window.getSelection()?.removeAllRanges(),this.scheduleLayoutRefresh()}function Uo(e,{diagramShells:t=null,sourceBlocks:n=null}={}){if(!this.previewElement||!e)return null;let r=(t??Array.from(this.previewElement.querySelectorAll(`.mermaid-shell, .plantuml-shell`))).find(t=>yt(t,e));if(r){let e=r.getBoundingClientRect();return{bubbleRect:e,highlightRects:[],hoverRects:[e]}}let i=(n??Array.from(this.previewElement.querySelectorAll(`[data-source-line]`)).filter(e=>et(e))).filter(t=>yt(t,e));if(e.kind===`text`&&e.quote){let t=i.map(t=>({element:t,range:lt(t,e.quote)})).filter(e=>e.range);if(t.length===1){let e=Array.from(t[0].range.getClientRects());return{bubbleRect:mt(e)||t[0].element.getBoundingClientRect(),highlightRects:e,hoverRects:e}}}let a=i[0];if(!a)return null;let o=a.getBoundingClientRect();return{bubbleRect:o,highlightRects:[],hoverRects:[o]}}function Wo(e){if(!(e instanceof Node))return[];let t=e.closest?.(`[data-comment-preview-group-keys]`);return t?.dataset?.commentPreviewGroupKey?[t.dataset.commentPreviewGroupKey]:Ze(String(t?.dataset?.commentPreviewGroupKeys??``).split(/\s+/).filter(Boolean)).split(` `).filter(Boolean)}function Go(e,t){if(!Number.isFinite(e)||!Number.isFinite(t))return[];let n=document.elementFromPoint(e,t),r=this.getPreviewGroupKeysForTarget(n);if(r.length>0)return r;let i=this.previewHoverRegions.filter(n=>n.rects.some(n=>Qe(e,t,n))).map(e=>e.key);return nt(i)}function Ko(e=[]){let t=nt(e),n=t.join(` `);n!==this.hoveredPreviewGroupKeysSignature&&(this.hoveredPreviewGroupKeys=t,this.hoveredPreviewGroupKeysSignature=n,this.syncHoveredCommentClasses())}function qo(e=[]){let t=nt(e),n=t.join(` `);n!==this.hoveredEditorGroupKeysSignature&&(this.hoveredEditorGroupKeys=t,this.hoveredEditorGroupKeysSignature=n,this.syncHoveredCommentClasses())}function Jo(){this.editorLayer?.querySelectorAll(`.comment-editor-badge`).forEach(e=>{let t=e.dataset.commentEditorGroupKey;Po(e,this.activeCard?.groupKey===t,this.hoveredEditorGroupKeys.includes(t))}),[...Array.from(this.previewLayer?.querySelectorAll(`[data-comment-preview-group-key]`)??[]),...Array.from(this.previewHighlightLayer?.querySelectorAll(`[data-comment-preview-group-key]`)??[])].forEach(e=>{let t=e.dataset.commentPreviewGroupKey;Po(e,this.activeCard?.groupKey===t,this.hoveredPreviewGroupKeys.includes(t))})}function Yo(e){this.updateHoveredPreviewGroups(this.getPreviewGroupKeysForTarget(e))}var Xo={clearPreviewSelection:Ho,ensureEditorLayer:Lo,ensurePreviewLayer:zo,getPreviewGroupKeysAtPoint:Go,getPreviewGroupKeysForTarget:Wo,refreshLayout:Fo,renderEditorLayer:Ro,renderPreviewLayer:Vo,resolvePreviewTarget:Uo,scheduleLayoutRefresh:Io,syncHoveredCommentClasses:Jo,syncHoveredPreviewGroupsFromTarget:Yo,updateHoveredEditorGroups:qo,updateHoveredPreviewGroups:Ko};function Zo(){this.renderToolbar(),this.renderDrawer(),this.renderCard(),this.scheduleLayoutRefresh()}function Qo(){let e=this.threads.length,t=this.supported&&!!this.session;if(this.commentSelectionButton?.classList.toggle(`hidden`,!t),this.commentsToggleButton?.classList.toggle(`hidden`,!this.supported),this.commentSelectionButton&&(this.commentSelectionButton.disabled=!this.selectionAnchor),this.commentsToggleButton){this.commentsToggleButton.classList.toggle(`active`,this.drawerOpen),this.commentsToggleButton.setAttribute(`aria-expanded`,String(this.drawerOpen));let t=e>0?`Comments ${e}`:`Comments`,n=this.commentsToggleButton.querySelector(`.ui-action-label`);n?n.textContent=t:this.commentsToggleButton.textContent=t}}function $o(){if(!this.commentsDrawer||!this.commentsDrawerList||(this.commentsDrawer.classList.toggle(`hidden`,!this.supported||!this.drawerOpen),!this.supported||!this.drawerOpen))return;this.commentsDrawerList.replaceChildren();let e=this.getThreadGroups();if(this.commentsDrawerEmpty?.classList.toggle(`hidden`,e.length>0),e.length===0)return;let t=document.createDocumentFragment();e.forEach(e=>{let n=ft(e),r=e.threads.reduce((e,t)=>e+(Array.isArray(t.messages)?t.messages.length:0),0),i=tt({authorName:n?.userName||e.threads[0]?.createdByName||`Anonymous`,buttonClassName:`comment-overview-thread comments-drawer-item`,footerClassName:`comment-overview-thread-footer comments-drawer-item-footer`,headerClassName:`comment-overview-thread-header comments-drawer-item-header`,lineClassName:`comment-overview-thread-line comments-drawer-item-title`,lineLabel:gt(e.anchor),messageCount:r,previewBody:n?.body||``,previewClassName:`comment-markdown comment-overview-thread-preview comments-drawer-item-preview`,quote:e.anchor?.quote||e.anchor?.excerpt||`Source anchored comment`,quoteClassName:`comment-overview-thread-quote comments-drawer-item-quote`,timestamp:n?this.formatTimestamp(n.createdAt):``});i.classList.toggle(`is-active`,this.activeCard?.groupKey===e.key),i.addEventListener(`pointerdown`,e=>{e.preventDefault()}),i.addEventListener(`click`,()=>{this.onNavigateToLine?.(e.anchor?.startLine??1),this.mobileBreakpointQuery?.matches&&this.setDrawerOpen(!1),this.openThreadGroup(e,{anchor:e.anchor,origin:`editor`,sourceRect:this.session?.getCommentAnchorClientRect?.(e.anchor)??i.getBoundingClientRect()})}),t.appendChild(i)}),this.commentsDrawerList.appendChild(t)}function es(e){if(!Number.isFinite(e))return``;try{return this.timeFormatter.format(new Date(e))}catch{return``}}var ts={formatTimestamp:es,render:Zo,renderDrawer:$o,renderToolbar:Qo};function ns(e){this.session?.getScrollContainer?.()?.removeEventListener(`scroll`,this.handleEditorScroll),this.session=e,this.selectionAnchor=e?.getCurrentSelectionCommentAnchor?.()??null,this.pendingSelectionAnchor=null,this.committedSelectionAnchor=null,this.previewSelection=null,this.reactionPicker=null,this.clearSelectionRevealTimer(),this.pointerSelecting=!1,e?.getScrollContainer?.()?.addEventListener(`scroll`,this.handleEditorScroll,{passive:!0}),this.render()}function rs(e,{fileKind:t=`markdown`,supported:n=!1}={}){let r=this.currentFile!==e;this.currentFile=e,this.fileKind=t,this.supported=!!(e&&n),r&&(this.drawerOpen=!1,this.threads=[],this.selectionAnchor=null,this.pendingSelectionAnchor=null,this.committedSelectionAnchor=null,this.clearSelectionRevealTimer(),this.pointerSelecting=!1,this.activeCard=null,this.updateHoveredEditorGroups([]),this.updateHoveredPreviewGroups([]),this.previewHoverRegions=[],this.lastPreviewPointerPosition=null,this.previewSelection=null,this.reactionPicker=null),this.supported||(this.drawerOpen=!1,this.activeCard=null,this.threads=[],this.selectionAnchor=null,this.pendingSelectionAnchor=null,this.committedSelectionAnchor=null,this.clearSelectionRevealTimer(),this.pointerSelecting=!1,this.updateHoveredEditorGroups([]),this.updateHoveredPreviewGroups([]),this.previewHoverRegions=[],this.lastPreviewPointerPosition=null,this.previewSelection=null,this.reactionPicker=null),this.render()}function is(e){if(this.selectionAnchor=this.supported?e:null,!this.supported||!this.selectionAnchor){this.pendingSelectionAnchor=null,this.committedSelectionAnchor=null,this.clearSelectionRevealTimer(),this.renderToolbar(),this.scheduleLayoutRefresh();return}if(!bt(this.selectionAnchor)){this.pendingSelectionAnchor=null,this.committedSelectionAnchor=null,this.clearSelectionRevealTimer(),this.renderToolbar(),this.scheduleLayoutRefresh();return}if(this.pendingSelectionAnchor=this.selectionAnchor,this.activeCard?.mode===`create`){this.clearSelectionRevealTimer(),this.renderToolbar(),this.scheduleLayoutRefresh();return}if(this.pointerSelecting){this.clearSelectionRevealTimer(),this.committedSelectionAnchor=null,this.renderToolbar(),this.scheduleLayoutRefresh();return}if(pt(this.committedSelectionAnchor,this.selectionAnchor)){this.renderToolbar(),this.scheduleLayoutRefresh();return}this.scheduleSelectionReveal(this.selectionAnchor),this.renderToolbar(),this.scheduleLayoutRefresh()}function as(){this.activeCard?.mode!==`create`&&(this.clearSelectionRevealTimer(),this.pendingSelectionAnchor=null,this.committedSelectionAnchor=null,this.scheduleLayoutRefresh())}function os(e=[]){this.threads=vt(e);let t=this.getThreadGroups();if(this.activeCard?.mode===`group`){let e=Array.isArray(this.activeCard.groupThreadIds)?this.activeCard.groupThreadIds:[],n=t.find(e=>e.key===this.activeCard.groupKey)??t.find(t=>t.threads.length===e.length&&t.threads.every(t=>e.includes(t.id)));n?(this.activeCard={...this.activeCard,anchor:n.anchor,groupKey:n.key,groupThreadIds:n.threads.map(e=>e.id)},this.activeCard.replyThreadId&&!n.threads.some(e=>e.id===this.activeCard.replyThreadId)&&(this.activeCard.replyThreadId=null)):this.activeCard=null}this.reactionPicker&&!this.threads.some(e=>e.id===this.reactionPicker.threadId&&e.messages?.some(e=>e.id===this.reactionPicker.messageId))&&(this.reactionPicker=null),this.render()}function ss(e){let t=!!e;t!==this.drawerOpen&&(t&&this.onWillOpenDrawer?.(),this.drawerOpen=t,this.render())}function cs(){this.setDrawerOpen(!1)}function ls(e){if(!e||!this.supported)return!1;let t=this.getThreadGroups().find(t=>t.threads.some(t=>t.id===e));return t?(this.onNavigateToLine?.(t.anchor?.startLine??1),this.openThreadGroup(t,{anchor:t.anchor,origin:`editor`,sourceRect:this.session?.getCommentAnchorClientRect?.(t.anchor)??null}),!0):!1}function us(){let e=new Map;return this.threads.forEach(t=>{let n=at(t.anchor),r=e.get(n);if(r){r.threads.push(t);return}e.set(n,{anchor:t.anchor,key:n,threads:[t]})}),Array.from(e.values()).sort((e,t)=>(e.anchor?.startLine??0)-(t.anchor?.startLine??0))}function ds(){this.selectionRevealTimer&&=(clearTimeout(this.selectionRevealTimer),0)}function fs(e){this.clearSelectionRevealTimer(),this.selectionRevealTimer=window.setTimeout(()=>{this.selectionRevealTimer=0,!this.pointerSelecting&&this.activeCard?.mode!==`create`&&pt(this.pendingSelectionAnchor,e)&&(this.committedSelectionAnchor=e,this.scheduleLayoutRefresh())},150)}var ps={attachSession:ns,clearSelectionRevealTimer:ds,closeDrawer:cs,getThreadGroups:us,handleEditorContentChange:as,openThreadFromOverview:ls,scheduleSelectionReveal:fs,setCurrentFile:rs,setDrawerOpen:ss,setSelectionAnchor:is,setThreads:os},ms=class{constructor({commentSelectionButton:e,commentsDrawer:t,commentsDrawerEmpty:n,commentsDrawerList:r,commentsToggleButton:i,editorContainer:a,mobileBreakpointQuery:o=window.matchMedia(`(max-width: 768px)`),onWillOpenDrawer:s,onCreateThread:c,onNavigateToLine:l,onReplyToThread:u,onToggleReaction:d,onResolveThread:f,previewContainer:p,previewElement:m}){this.commentSelectionButton=e,this.commentsDrawer=t,this.commentsDrawerEmpty=n,this.commentsDrawerList=r,this.commentsToggleButton=i,this.editorContainer=a,this.mobileBreakpointQuery=o,this.onWillOpenDrawer=s,this.onCreateThread=c,this.onNavigateToLine=l,this.onReplyToThread=u,this.onToggleReaction=d,this.onResolveThread=f,this.previewContainer=p,this.previewElement=m,this.currentFile=null,this.fileKind=`markdown`,this.supported=!1,this.drawerOpen=!1,this.threads=[],this.selectionAnchor=null,this.pendingSelectionAnchor=null,this.committedSelectionAnchor=null,this.selectionRevealTimer=0,this.pointerSelecting=!1,this.session=null,this.activeCard=null,this.hoveredEditorGroupKeys=[],this.hoveredEditorGroupKeysSignature=``,this.hoveredPreviewGroupKeys=[],this.hoveredPreviewGroupKeysSignature=``,this.previewHoverRegions=[],this.lastPreviewPointerPosition=null,this.previewSelection=null,this.editorLayer=null,this.previewLayer=null,this.previewHighlightLayer=null,this.cardRoot=null,this.pendingCardFocusElement=null,this.reactionPicker=null,this.listenerController=null,this.layoutFrame=0,this.timeFormatter=new Intl.DateTimeFormat(void 0,{day:`numeric`,hour:`numeric`,minute:`2-digit`,month:`short`}),this.handleEditorScroll=()=>this.scheduleLayoutRefresh(),this.handlePreviewScroll=()=>this.scheduleLayoutRefresh(),this.handleWindowResize=()=>this.scheduleLayoutRefresh(),this.handlePreviewPointerMove=e=>{this.lastPreviewPointerPosition={x:e.clientX,y:e.clientY},this.updateHoveredPreviewGroups(this.getPreviewGroupKeysAtPoint(e.clientX,e.clientY))},this.handlePreviewPointerLeave=()=>{this.lastPreviewPointerPosition=null,this.updateHoveredPreviewGroups([])},this.handlePreviewFocusIn=e=>{this.updateHoveredPreviewGroups(this.getPreviewGroupKeysForTarget(e.target))},this.handlePreviewFocusOut=e=>{this.updateHoveredPreviewGroups(this.getPreviewGroupKeysForTarget(e.relatedTarget))},this.handleDocumentSelectionChange=()=>{if(this.activeCard?.mode===`create`&&this.activeCard.origin===`preview`)return;let e=this.supported&&this.fileKind===`markdown`?dt(window.getSelection(),this.previewElement,this.session?.getText?.()??``):null;(e||this.previewSelection)&&(this.previewSelection=e,this.scheduleLayoutRefresh())},this.handleCommentSelectionButtonPointerDown=e=>{e.preventDefault()},this.handleEditorPointerDown=e=>{e.button===0&&this.supported&&this.session&&e.target?.closest?.(`.cm-editor`)&&!e.target?.closest?.(`.comment-editor-layer`)&&(this.pointerSelecting=!0,this.clearSelectionRevealTimer(),this.committedSelectionAnchor&&(this.committedSelectionAnchor=null,this.scheduleLayoutRefresh()))},this.handleDocumentPointerUp=()=>{this.pointerSelecting&&requestAnimationFrame(()=>{let e=this.supported?this.session?.getCurrentSelectionCommentAnchor?.()??null:null;this.pointerSelecting=!1,this.selectionAnchor=e,this.renderToolbar(),this.pendingSelectionAnchor=bt(e)?e:null,this.clearSelectionRevealTimer(),this.committedSelectionAnchor=bt(e)&&this.activeCard?.mode!==`create`?e:null,this.scheduleLayoutRefresh()})},this.handleEditorFocusOut=e=>{let t=e.relatedTarget;t instanceof Node&&(this.editorContainer?.contains(t)||this.cardRoot?.contains(t)||this.commentSelectionButton?.contains(t))||(this.clearSelectionRevealTimer(),this.pendingSelectionAnchor=null,this.committedSelectionAnchor=null,this.scheduleLayoutRefresh())},this.handleDocumentPointerDown=e=>{let t=e.target;if(this.activeCard&&this.cardRoot){if(this.cardRoot.contains(t))return;this.closeCard()}this.drawerOpen&&(t instanceof Node&&(this.commentsDrawer?.contains(t)||this.commentsToggleButton?.contains(t))||this.closeDrawer())},this.handleDocumentKeyDown=e=>{if(e.key===`Escape`&&this.reactionPicker){this.reactionPicker=null,this.renderCard();return}e.key===`Escape`&&this.activeCard&&this.closeCard(),e.key===`Escape`&&this.previewSelection&&this.clearPreviewSelection(),e.key===`Escape`&&this.committedSelectionAnchor&&(this.clearSelectionRevealTimer(),this.pendingSelectionAnchor=null,this.committedSelectionAnchor=null,this.scheduleLayoutRefresh())},this.listenerController=new AbortController;let{signal:h}=this.listenerController;this.commentSelectionButton?.addEventListener(`pointerdown`,this.handleCommentSelectionButtonPointerDown,{signal:h}),this.commentSelectionButton?.addEventListener(`click`,()=>{this.openComposerForSelection(`toolbar`)},{signal:h}),this.commentsToggleButton?.addEventListener(`click`,()=>{this.setDrawerOpen(!this.drawerOpen)},{signal:h}),this.previewContainer?.addEventListener(`scroll`,this.handlePreviewScroll,{passive:!0,signal:h}),this.previewElement?.addEventListener(`pointermove`,this.handlePreviewPointerMove,{passive:!0,signal:h}),this.previewElement?.addEventListener(`pointerleave`,this.handlePreviewPointerLeave,{signal:h}),this.previewElement?.addEventListener(`focusin`,this.handlePreviewFocusIn,{signal:h}),this.previewElement?.addEventListener(`focusout`,this.handlePreviewFocusOut,{signal:h}),this.editorContainer?.addEventListener(`pointerdown`,this.handleEditorPointerDown,{signal:h}),this.editorContainer?.addEventListener(`focusout`,this.handleEditorFocusOut,{signal:h}),window.addEventListener(`resize`,this.handleWindowResize,{signal:h}),document.addEventListener(`pointerup`,this.handleDocumentPointerUp,{signal:h}),document.addEventListener(`pointercancel`,this.handleDocumentPointerUp,{signal:h}),document.addEventListener(`pointerdown`,this.handleDocumentPointerDown,{signal:h}),document.addEventListener(`keydown`,this.handleDocumentKeyDown,{signal:h}),document.addEventListener(`selectionchange`,this.handleDocumentSelectionChange,{signal:h})}destroy(){this.layoutFrame&&=(cancelAnimationFrame(this.layoutFrame),0),this.attachSession(null),this.listenerController?.abort(),this.listenerController=null,this.previewHoverRegions=[],this.previewSelection=null,this.cardRoot?.remove(),this.editorLayer?.remove(),this.previewLayer?.remove(),this.pendingCardFocusElement=null}};Object.assign(ms.prototype,ps,ts,Xo,No);function hs(){return typeof window>`u`||typeof window.matchMedia!=`function`?{matches:!1}:window.matchMedia(`(max-width: 768px)`)}function gs(e){return typeof HTMLElement>`u`||!(e instanceof HTMLElement)?[]:Array.from(e.querySelectorAll(`.create-menu-item, .file-action-sheet-item:not(:disabled)`))}var _s=class{constructor({mobileBreakpointQuery:e=hs()}={}){this.mobileBreakpointQuery=e,this.activeAnchor=null,this.desktopMenu=null,this.windowResizeHandler=null,this.blockingModalHandler=()=>this.close(),this.boundClose=()=>this.close()}isMobileViewport(){return!!this.mobileBreakpointQuery?.matches}isOpen(){return!!(this.desktopMenu||this.mobileSheet)}toggle(e={}){if(this.isOpen()){this.close();return}this.open(e)}open({anchor:e=null,items:t=[],title:n=`Create`}={}){if(this.close({restoreFocus:!1}),Array.isArray(t)&&t.length!==0){if(this.activeAnchor=typeof HTMLElement<`u`&&e instanceof HTMLElement?e:null,this.activeAnchor?.setAttribute(`aria-expanded`,`true`),this.isMobileViewport()){this.openMobileSheet({items:t,title:n});return}this.openDesktopMenu({anchor:this.activeAnchor,items:t,title:n})}}close({restoreFocus:e=!0}={}){if(this.desktopMenu){let e=this.desktopMenu;this.desktopMenu=null,e.remove()}this.mobileSheet&&=(this.mobileSheet.open&&this.mobileSheet.close(),this.mobileSheet.remove(),null),document.removeEventListener(`collabmd:close-custom-modals`,this.blockingModalHandler),this.windowResizeHandler&&typeof window<`u`&&window.removeEventListener(`resize`,this.windowResizeHandler),this.windowResizeHandler=null;let t=this.activeAnchor;this.activeAnchor?.setAttribute(`aria-expanded`,`false`),this.activeAnchor=null,e&&t?.focus?.()}openDesktopMenu({anchor:e,items:t,title:n}){let r=document.createElement(`div`);r.className=`create-menu`,r.setAttribute(`role`,`menu`),r.setAttribute(`aria-label`,n),r.setAttribute(`popover`,`auto`),this.renderMenuItems(r,t),document.body.appendChild(r),r.showPopover?.(),this.positionDesktopMenu(r,e),r.addEventListener(`keydown`,e=>{this.handleDesktopMenuKeyDown(e,r)}),r.addEventListener(`toggle`,e=>{e.newState===`closed`&&r.isConnected&&this.desktopMenu===r&&this.close()}),this.windowResizeHandler=this.boundClose,typeof window<`u`&&window.addEventListener(`resize`,this.windowResizeHandler),this.desktopMenu=r,gs(r)[0]?.focus()}openMobileSheet({items:e,title:t}){let n=document.createElement(`dialog`);n.className=`file-action-sheet create-action-sheet`,n.setAttribute(`aria-label`,t),n.setAttribute(`closedby`,`any`);let r=document.createElement(`div`);r.className=`create-action-sheet-header`,r.textContent=t,n.appendChild(r),this.renderMenuItems(n,e,{mobile:!0});let i=document.createElement(`button`);i.type=`button`,i.className=k({variant:`ghost`,extra:[`file-action-sheet-item`,`create-action-sheet-cancel`]}),i.textContent=`Cancel`,i.addEventListener(`click`,()=>{this.close()}),n.appendChild(i),n.addEventListener(`cancel`,e=>{e.preventDefault(),this.close()}),n.addEventListener(`close`,()=>{n.isConnected&&this.mobileSheet===n&&this.close()}),n.addEventListener(`click`,e=>{let t=n.getBoundingClientRect();(e.clientX<t.left||e.clientX>t.right||e.clientY<t.top||e.clientY>t.bottom)&&this.close()}),document.body.append(n),document.addEventListener(`collabmd:close-custom-modals`,this.blockingModalHandler),this.mobileSheet=n,n.showModal(),gs(n)[0]?.focus()}renderMenuItems(e,t,{mobile:n=!1}={}){let r=null;t.forEach(t=>{if(t.group&&t.group!==r){let i=document.createElement(`div`);i.className=n?`create-action-sheet-group`:`create-menu-group`,i.textContent=t.group,e.appendChild(i),r=t.group}let i=document.createElement(`button`);i.type=`button`,i.className=n?k({variant:`ghost`,extra:[`file-action-sheet-item`,`create-action-sheet-item`,`create-action-sheet-option`]}):`create-menu-item`,i.setAttribute(`role`,n?`button`:`menuitem`),i.dataset.actionId=t.id;let a=document.createElement(`span`);a.className=`create-menu-item-icon`,a.setAttribute(`aria-hidden`,`true`),a.innerHTML=t.icon||``,i.appendChild(a);let o=document.createElement(`span`);o.className=`create-menu-item-copy`;let s=document.createElement(`span`);s.className=`create-menu-item-label`,s.textContent=t.label,o.appendChild(s);let c=t.meta||t.hint;if(c){let e=document.createElement(`span`);e.className=`create-menu-item-meta`,e.textContent=c,o.appendChild(e)}i.appendChild(o),i.addEventListener(`click`,()=>{this.close({restoreFocus:!1}),t.onSelect?.()}),e.appendChild(i)})}positionDesktopMenu(e,t){let n=e.getBoundingClientRect(),r=t?.getBoundingClientRect?.(),i=r?.left??8,a=Math.max(8,window.innerWidth-n.width-8),o=Math.max(8,Math.min(i,a)),s=(r?.bottom??8)+8,c=window.innerHeight-n.height-8;s>c&&r&&(s=Math.max(8,r.top-n.height-8)),e.style.left=`${o}px`,e.style.top=`${Math.max(8,s)}px`}handleDesktopMenuKeyDown(e,t){let n=gs(t);if(n.length===0)return;let r=Math.max(0,n.indexOf(document.activeElement));switch(e.key){case`ArrowDown`:e.preventDefault(),n[(r+1)%n.length]?.focus();break;case`ArrowUp`:e.preventDefault(),n[(r-1+n.length)%n.length]?.focus();break;case`Home`:e.preventDefault(),n[0]?.focus();break;case`End`:e.preventDefault(),n[n.length-1]?.focus();break;case`Escape`:e.preventDefault(),this.close();break;case`Tab`:this.close({restoreFocus:!1})}}};function vs(e,t,n){return e===t?n:`${n}${e.slice(t.length)}`}function ys(e,t,n){return`${e} ${e===1?t:n}`}var bs=y.join(`,`);function xs(){return JSON.stringify({type:`excalidraw`,version:2,source:`collabmd`,elements:[],appState:{viewBackgroundColor:`#ffffff`,gridSize:null},files:{}})}function J(e,t){return t?{...e,requestId:t}:e}var Ss=class{constructor({mobileBreakpointQuery:e=typeof window<`u`&&typeof window.matchMedia==`function`?window.matchMedia(`(max-width: 768px)`):{matches:!1},onDirectoryExport:t,onFileDelete:n,onFileSelect:r,onShowFileExtensionsChange:i,pendingWorkspaceRequestIds:a=null,showFileExtensions:o=!1,state:s,toastController:c,vaultClient:l,view:u,refresh:d}){this.onDirectoryExport=t,this.onFileDelete=n,this.onFileSelect=r,this.onShowFileExtensionsChange=i,this.pendingWorkspaceRequestIds=a,this.showFileExtensions=!!o,this.state=s,this.toastController=c,this.vaultClient=l,this.view=u,this.refresh=d,this.createButton=document.getElementById(`sidebarCreateBtn`),this.fileExplorerOptionsButton=document.getElementById(`fileExplorerOptionsBtn`),this.actionDialog=document.getElementById(`fileActionDialog`),this.actionForm=document.getElementById(`fileActionForm`),this.actionTitle=document.getElementById(`fileActionTitle`),this.actionCopy=document.getElementById(`fileActionCopy`),this.actionField=document.getElementById(`fileActionField`),this.actionLabel=document.getElementById(`fileActionLabel`),this.actionInput=document.getElementById(`fileActionInput`),this.actionHint=document.getElementById(`fileActionHint`),this.actionNote=document.getElementById(`fileActionNote`),this.actionCancelButton=document.getElementById(`fileActionCancel`),this.actionSubmitButton=document.getElementById(`fileActionSubmit`),this.createMenu=new _s({mobileBreakpointQuery:e}),this.fileExplorerOptionsMenu=new _s({mobileBreakpointQuery:e}),this.pendingAction=null,this.actionBusy=!1}initialize(){this.createButton?.addEventListener(`click`,()=>{this.openRootCreateMenu({anchor:this.createButton})}),this.fileExplorerOptionsButton?.addEventListener(`click`,()=>{this.openFileExplorerOptionsMenu({anchor:this.fileExplorerOptionsButton})}),this.actionCancelButton?.addEventListener(`click`,()=>this.closeActionDialog()),this.actionForm?.addEventListener(`submit`,e=>{e.preventDefault(),this.handleActionSubmit()}),this.actionDialog?.addEventListener(`close`,()=>this.resetActionDialog())}getCreateActions({parentDir:e=``}={}){return[{contextLabel:`Upload files`,group:`File`,hint:`Supported vault files`,icon:this.getCreateActionIcon(`upload`),id:`upload`,label:`Upload files`,meta:`Multiple`,onSelect:()=>{this.handleUploadFiles({parentDir:e})}},{contextLabel:`New markdown file`,group:`Note`,hint:`Markdown`,icon:this.getCreateActionIcon(`markdown`),id:`markdown`,label:`Markdown note`,meta:`.md`,onSelect:()=>this.handleNewFile({parentDir:e})},{contextLabel:`New base file`,group:`Note`,hint:`Base`,icon:this.getCreateActionIcon(`base`),id:`base`,label:`Base file`,meta:`.base`,onSelect:()=>this.handleNewBase({parentDir:e})},{contextLabel:`New canvas`,group:`Diagram`,hint:`JSON Canvas`,icon:this.getCreateActionIcon(`canvas`),id:`canvas`,label:`Canvas`,meta:`.canvas`,onSelect:()=>this.handleNewCanvas({parentDir:e})},{contextLabel:`New Excalidraw drawing`,group:`Diagram`,hint:`Excalidraw`,icon:this.getCreateActionIcon(`excalidraw`),id:`excalidraw`,label:`Excalidraw drawing`,meta:`.excalidraw`,onSelect:()=>this.handleNewDrawing({parentDir:e})},{contextLabel:`New draw.io diagram`,group:`Diagram`,hint:`draw.io`,icon:this.getCreateActionIcon(`drawio`),id:`drawio`,label:`draw.io diagram`,meta:`.drawio`,onSelect:()=>this.handleNewDrawio({parentDir:e})},{contextLabel:`New Mermaid diagram`,group:`Diagram`,hint:`Mermaid`,icon:this.getCreateActionIcon(`mermaid`),id:`mermaid`,label:`Mermaid diagram`,meta:`.mmd`,onSelect:()=>this.handleNewMermaid({parentDir:e})},{contextLabel:`New PlantUML diagram`,group:`Diagram`,hint:`PlantUML`,icon:this.getCreateActionIcon(`plantuml`),id:`plantuml`,label:`PlantUML diagram`,meta:`.puml`,onSelect:()=>this.handleNewPlantUml({parentDir:e})},{contextLabel:`New Structurizr workspace`,group:`Diagram`,hint:`Structurizr DSL`,icon:this.getCreateActionIcon(`structurizr`),id:`structurizr`,label:`Structurizr workspace`,meta:`.dsl`,onSelect:()=>this.handleNewStructurizr({parentDir:e})},{contextLabel:`New folder`,group:`Structure`,hint:`Folder`,icon:this.getCreateActionIcon(`folder`),id:`folder`,label:`Folder`,meta:`folder`,onSelect:()=>this.handleNewFolder({parentDir:e})}]}createContextMenuItems(e=``){return this.getCreateActions({parentDir:e}).map(e=>({label:e.contextLabel,onSelect:e.onSelect}))}getDirectoryContextMenuItems(e){return[{label:`New…`,onSelect:({anchor:t}={})=>this.openCreateMenu({anchor:t,parentDir:e})},{label:`Rename / move`,onSelect:()=>this.handleRenameDirectory(e)},{label:`Download source ZIP`,onSelect:()=>this.handleDownloadDirectory(e)},{label:`Export HTML`,onSelect:()=>this.onDirectoryExport?.(e,`html`)},{label:`Print / save PDF`,onSelect:()=>this.onDirectoryExport?.(e,`pdf`)},{label:`Delete`,danger:!0,onSelect:()=>this.handleDeleteDirectory(e)}]}getFileContextMenuItems(e){return[{label:`Copy as URL`,onSelect:()=>this.copyFileUrl(e)},{label:`Rename / move`,onSelect:()=>this.handleRenameFile(e)},{label:`Download`,onSelect:()=>this.handleDownloadFile(e)},{label:`Delete`,danger:!0,onSelect:()=>this.handleDelete(e)}]}async copyFileUrl(e){let t=new URL(window.location.href);t.search=``;let n=P();n&&t.searchParams.set(`vault`,n),t.hash=Ke(e);try{await ue(t.toString()),this.showToast(`Link copied`)}catch{this.showToast(`Failed to copy link`)}}showToast(e){e&&this.toastController?.show(String(e))}getCreateActionIcon(e){switch(e){case`upload`:return`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 16V4"/><path d="m7 9 5-5 5 5"/><path d="M5 20h14"/></svg>`;case`base`:return`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 4h7l5 5v11a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z"/><path d="M14 4v5h5"/><path d="M8 13h8"/><path d="M8 17h6"/><path d="M8 9h3"/></svg>`;case`canvas`:case`drawio`:case`plantuml`:case`structurizr`:return`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="7" height="6" rx="1"/><rect x="14" y="4" width="7" height="6" rx="1"/><rect x="8.5" y="14" width="7" height="6" rx="1"/><path d="M10 7h4"/><path d="M17.5 10v2.5"/><path d="M6.5 10v2.5"/><path d="M6.5 12.5h11"/></svg>`;case`excalidraw`:return`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19l7-7 3 3-7 7-3-3z"/><path d="M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z"/><path d="M2 2l7.586 7.586"/><circle cx="11" cy="11" r="2"/></svg>`;case`folder`:return`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>`;case`mermaid`:return`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 7.5c0-1.38 1.12-2.5 2.5-2.5 1.04 0 1.93.64 2.3 1.56A2.5 2.5 0 0 1 14 8.5v1"/><path d="M19 16.5c0 1.38-1.12 2.5-2.5 2.5-1.04 0-1.93-.64-2.3-1.56A2.5 2.5 0 0 1 10 15.5v-1"/><path d="M8 10.5h8"/><path d="M8 13.5h8"/><path d="M10 8.5v7"/><path d="M14 8.5v7"/></svg>`;default:return`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>`}}showError(e,t){this.showToast(t?.message?`${e}: ${t.message}`:e)}createPendingWorkspaceRequestId(){if(!this.pendingWorkspaceRequestIds)return null;let e=crypto.randomUUID();return this.pendingWorkspaceRequestIds.add(e),e}clearPendingWorkspaceRequestId(e){e&&this.pendingWorkspaceRequestIds?.delete(e)}async runWorkspaceMutation(e){let t=this.createPendingWorkspaceRequestId();try{return await e(t)}catch(e){throw this.clearPendingWorkspaceRequestId(t),e}}openActionDialog({title:e,copy:t,label:n=`Path`,hint:r=``,note:i=``,placeholder:a=``,value:o=``,submitLabel:s=`Save`,destructive:c=!1,requiresInput:l=!0,emptyMessage:u=`A value is required`,onSubmit:d}){this.actionDialog&&this.actionTitle&&this.actionCopy&&this.actionSubmitButton&&this.actionCancelButton&&(!l||this.actionInput)&&(this.actionDialog.open&&(typeof this.actionDialog.close==`function`?this.actionDialog.close():(this.actionDialog.removeAttribute(`open`),this.resetActionDialog())),this.pendingAction={requiresInput:l,emptyMessage:u,onSubmit:d},this.createMenu.close({restoreFocus:!1}),this.fileExplorerOptionsMenu.close({restoreFocus:!1}),this.view?.removeContextMenu?.(),this.actionTitle.textContent=e,this.actionCopy.textContent=t,this.actionField&&(this.actionField.hidden=!l),this.actionLabel&&(this.actionLabel.textContent=n),this.actionInput&&(this.actionInput.value=o,this.actionInput.placeholder=a,this.actionInput.required=l,this.actionInput.disabled=!1),this.actionHint&&(this.actionHint.textContent=r,this.actionHint.hidden=!l||!r),this.actionNote&&(this.actionNote.textContent=i,this.actionNote.hidden=!i,this.actionNote.classList.toggle(`is-danger`,c)),this.actionSubmitButton.textContent=s,this.actionSubmitButton.disabled=!1,this.actionSubmitButton.classList.toggle(`ui-button--primary`,!c),this.actionSubmitButton.classList.toggle(`ui-button--danger`,c),this.actionCancelButton.disabled=!1,typeof this.actionDialog.showModal==`function`?this.actionDialog.showModal():this.actionDialog.setAttribute(`open`,`true`),requestAnimationFrame(()=>{if(!l||!this.actionInput){this.actionSubmitButton.focus();return}this.actionInput.focus(),o&&this.actionInput.select()}))}resetActionDialog(){this.pendingAction=null,this.actionBusy=!1,this.actionField&&(this.actionField.hidden=!1),this.actionLabel&&(this.actionLabel.textContent=`Path`),this.actionInput&&(this.actionInput.value=``,this.actionInput.placeholder=``,this.actionInput.required=!0,this.actionInput.disabled=!1),this.actionHint&&(this.actionHint.textContent=``,this.actionHint.hidden=!0),this.actionNote&&(this.actionNote.textContent=``,this.actionNote.hidden=!0,this.actionNote.classList.remove(`is-danger`)),this.actionSubmitButton&&(this.actionSubmitButton.textContent=`Save`,this.actionSubmitButton.disabled=!1,this.actionSubmitButton.className=k({variant:`primary`})),this.actionCancelButton&&(this.actionCancelButton.disabled=!1)}closeActionDialog(){if(this.actionDialog){if(this.actionDialog.open&&typeof this.actionDialog.close==`function`){this.actionDialog.close();return}this.actionDialog.removeAttribute(`open`),this.resetActionDialog()}}setActionDialogBusy(e){this.actionBusy=e,this.actionInput&&(this.actionInput.disabled=e||!(this.pendingAction?.requiresInput??!0)),this.actionCancelButton&&(this.actionCancelButton.disabled=e),this.actionSubmitButton&&(this.actionSubmitButton.disabled=e)}async handleActionSubmit(){if(!this.pendingAction?.onSubmit||this.actionBusy)return;let e=this.pendingAction.requiresInput,t=e?this.actionInput?.value.trim()??``:void 0;if(e&&!t){this.showToast(this.pendingAction.emptyMessage),this.actionInput?.focus();return}this.setActionDialogBusy(!0);let n;try{n=await this.pendingAction.onSubmit(t)}catch(e){this.showError(`Failed to complete action`,e)}if(this.setActionDialogBusy(!1),n!==!1){this.closeActionDialog();return}e&&this.actionInput&&(this.actionInput.focus(),this.actionInput.select())}async uploadVaultFiles(e=[],{parentDir:t=``}={}){let n=T(t),i=!1;for(let t of Array.from(e??[])){let e=C(t?.name),a=E(n,e);if(!e||!r(a)){this.showToast(`Unsupported file type: ${e||`unnamed file`}`);continue}try{await this.runWorkspaceMutation(e=>this.vaultClient.uploadFile({file:t,path:a,requestId:e})),i=!0,this.state.expandDirectoryPath(a,{includeLeaf:!1})}catch(t){this.showToast(`${e}: ${t?.message||`Failed to upload file`}`)}}return i&&await this.refresh(),i}async handleUploadFiles({parentDir:e=``}={}){let t=await le({accept:bs,multiple:!0});return t.length!==0&&this.uploadVaultFiles(t,{parentDir:e})}async createVaultFile(e,t,{openAfterCreate:n=!1,errorMessage:r=`Failed to create file`}={}){try{return await this.runWorkspaceMutation(n=>this.vaultClient.createFile(J({content:t,path:e},n))),this.state.expandDirectoryPath(e,{includeLeaf:!1}),await this.refresh(),n&&this.onFileSelect?.(e),!0}catch(e){return this.showToast(e?.message||r),!1}}async createDirectory(e){let t=T(e);if(!t)return this.showToast(`Folder path is required`),!1;try{return await this.runWorkspaceMutation(e=>this.vaultClient.createDirectory(t,J({},e))),this.state.expandDirectoryPath(t),await this.refresh(),!0}catch(e){return this.showToast(e?.message||`Failed to create folder`),!1}}async renameVaultFile(e,t,n){let r=T(t);if(!r)return this.showToast(`File path is required`),!1;let i=m(r);if(i&&i.toLowerCase()!==String(n??``).toLowerCase())return this.showToast(`File type changes are not supported during rename. Keep the ${n} extension.`),!1;let a=i?r:`${r}${n}`;if(!C(a))return this.showToast(`File path is required`),!1;if(a===e)return!0;try{return await this.runWorkspaceMutation(t=>this.vaultClient.renameFile(J({newPath:a,oldPath:e},t))),this.state.expandDirectoryPath(a,{includeLeaf:!1}),await this.refresh(),this.state.activeFilePath===e&&(this.state.activeFilePath=a,this.onFileSelect?.(a)),!0}catch(e){return this.showToast(e?.message||`Failed to rename`),!1}}async renameDirectory(e,t){let n=T(t);if(!n)return this.showToast(`Folder path is required`),!1;if(n===e)return!0;try{if(await this.runWorkspaceMutation(t=>this.vaultClient.renameDirectory(J({newPath:n,oldPath:e},t))),this.state.replaceExpandedDirectoryPrefix(e,n),this.state.expandDirectoryPath(n),await this.refresh(),this.state.activeFilePath&&this.state.activeFilePath.startsWith(`${e}/`)){let t=vs(this.state.activeFilePath,e,n);this.state.activeFilePath=t,this.onFileSelect?.(t)}return!0}catch(e){return this.showToast(e?.message||`Failed to rename folder`),!1}}async deleteVaultFile(e){try{return await this.runWorkspaceMutation(t=>this.vaultClient.deleteFile(e,J({},t))),await this.refresh(),this.state.activeFilePath===e&&(this.state.activeFilePath=null,this.onFileDelete?.(e)),!0}catch(e){return this.showToast(e?.message||`Failed to delete`),!1}}async deleteDirectory(e,{recursive:t=!1}={}){try{await this.runWorkspaceMutation(n=>this.vaultClient.deleteDirectory(e,J({recursive:t},n)));let n=this.state.activeFilePath;return await this.refresh(),this.state.removeExpandedDirectoryPrefix(e),n&&n.startsWith(`${e}/`)&&(this.state.activeFilePath=null,this.onFileDelete?.(n)),!0}catch(e){return this.showToast(e?.message||`Failed to delete folder`),!1}}planMoveEntryByDrop({destinationDirectory:e=``,sourcePath:t=``,sourceType:n=`file`}={}){let r=T(t),i=T(e),a=w(r),o=C(r);return!r||!o?{ok:!1,reason:`Invalid item to move`}:a===i?{ok:!1,reason:`Item is already in that folder`}:n===`directory`?i===r?{ok:!1,reason:`A folder cannot be moved into itself`}:i.startsWith(`${r}/`)?{ok:!1,reason:`A folder cannot be moved into one of its descendants`}:{nextPath:E(i,o),ok:!0}:{extension:m(r)||`.md`,nextPath:E(i,o),ok:!0}}canMoveEntryByDrop(e={}){return this.planMoveEntryByDrop(e).ok}async moveEntryByDrop(e={}){let t=this.planMoveEntryByDrop(e);return t.ok?e.sourceType===`directory`?this.renameDirectory(e.sourcePath,t.nextPath):this.renameVaultFile(e.sourcePath,t.nextPath,t.extension):(this.showToast(t.reason),!1)}async downloadFileEntry(e){try{return await this.vaultClient.downloadFile(e),!0}catch(e){return this.showToast(e?.message||`Failed to download file`),!1}}async downloadDirectoryEntry(e){try{return await this.vaultClient.downloadDirectory(e),!0}catch(e){return this.showToast(e?.message||`Failed to download folder`),!1}}getCreateContext(e=``){let t=T(e);return{hintPrefix:t?`Use "/" to create nested items under this folder.`:`Use "/" to place it inside a folder.`,inputLabelSuffix:t?`name or path`:`path`,note:t?`Parent folder: ${t}`:``,normalizedParentDir:t}}openRootCreateMenu({anchor:e=this.createButton}={}){this.openCreateMenu({anchor:e,parentDir:``})}openCreateMenu({anchor:e=this.createButton,parentDir:t=``}={}){this.view?.removeContextMenu?.(),this.fileExplorerOptionsMenu.close({restoreFocus:!1}),this.createMenu.toggle({anchor:e,items:this.getCreateActions({parentDir:t}),title:`Create`})}openFileExplorerOptionsMenu({anchor:e=this.fileExplorerOptionsButton}={}){this.view?.removeContextMenu?.(),this.createMenu.close({restoreFocus:!1}),this.fileExplorerOptionsMenu.toggle({anchor:e,items:[{icon:`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6S2 12 2 12Z"></path><circle cx="12" cy="12" r="2.5"></circle></svg>`,id:`show-file-extensions`,label:`Show file extensions`,meta:this.showFileExtensions?`On`:`Off`,onSelect:()=>{this.showFileExtensions=!this.showFileExtensions,this.onShowFileExtensionsChange?.(this.showFileExtensions)}}],title:`File explorer options`})}handleNewFile({parentDir:e=``}={}){let t=this.getCreateContext(e);this.openActionDialog({title:`Create markdown file`,copy:t.normalizedParentDir?`Add a new note inside the selected folder. It opens immediately after creation.`:`Add a new note to the vault. It opens immediately after creation.`,label:`File ${t.inputLabelSuffix}`,hint:`${t.hintPrefix} ".md" is added automatically.`,note:t.note,placeholder:t.normalizedParentDir?`my-note`:`notes/my-note`,submitLabel:`Create file`,emptyMessage:`File path is required`,onSubmit:e=>{let n=T(e);if(!n)return this.showToast(`File path is required`),!1;let r=D(E(t.normalizedParentDir,n),`.md`);return this.createVaultFile(r,oe(r),{errorMessage:`Failed to create file`,openAfterCreate:!0})}})}handleNewBase({parentDir:e=``}={}){let t=this.getCreateContext(e);this.openActionDialog({title:`Create base file`,copy:t.normalizedParentDir?"Add a new `.base` file inside the selected folder. It opens immediately after creation.":"Add a new `.base` file to the vault. It opens immediately after creation.",label:`Base ${t.inputLabelSuffix}`,hint:`${t.hintPrefix} ".base" is added automatically.`,note:t.note,placeholder:t.normalizedParentDir?`table-view`:`views/table-view`,submitLabel:`Create base`,emptyMessage:`Base path is required`,onSubmit:e=>{let n=T(e);if(!n)return this.showToast(`Base path is required`),!1;let r=re(E(t.normalizedParentDir,n));return this.createVaultFile(r.path,r.content,{errorMessage:`Failed to create base file`,openAfterCreate:!0})}})}handleNewFolder({parentDir:e=``}={}){let t=this.getCreateContext(e);this.openActionDialog({title:`Create folder`,copy:t.normalizedParentDir?`Add a new folder inside the selected folder.`:`Add a new folder to organize notes and diagrams.`,label:`Folder ${t.inputLabelSuffix}`,hint:t.hintPrefix,note:t.note,placeholder:t.normalizedParentDir?`archive`:`notes/archive`,submitLabel:`Create folder`,emptyMessage:`Folder path is required`,onSubmit:e=>this.createDirectory(E(t.normalizedParentDir,e))})}handleNewCanvas({parentDir:e=``}={}){let t=this.getCreateContext(e);this.openActionDialog({title:`Create canvas`,copy:`Create a canvas for connected notes, files, links, and groups.`,label:`Canvas ${t.inputLabelSuffix}`,hint:`${t.hintPrefix} ".canvas" is added automatically.`,note:t.note,placeholder:t.normalizedParentDir?`ideas`:`diagrams/ideas`,submitLabel:`Create canvas`,emptyMessage:`Canvas path is required`,onSubmit:e=>{let n=T(e);if(!n)return this.showToast(`Canvas path is required`),!1;let r=D(E(t.normalizedParentDir,n),`.canvas`);return this.createVaultFile(r,`{"nodes":[],"edges":[]}
|
|
327
|
+
`,{errorMessage:`Failed to create canvas`,openAfterCreate:!0})}})}handleNewDrawing({parentDir:e=``}={}){let t=this.getCreateContext(e);this.openActionDialog({title:`Create Excalidraw drawing`,copy:t.normalizedParentDir?`Start a new drawing inside the selected folder.`:`Start a new drawing file in the vault.`,label:`Drawing ${t.inputLabelSuffix}`,hint:`${t.hintPrefix} ".excalidraw" is added automatically.`,note:t.note,placeholder:t.normalizedParentDir?`architecture`:`diagrams/architecture`,submitLabel:`Create drawing`,emptyMessage:`Drawing path is required`,onSubmit:e=>{let n=T(e);if(!n)return this.showToast(`Drawing path is required`),!1;let r=D(E(t.normalizedParentDir,n),`.excalidraw`);return this.createVaultFile(r,xs(),{errorMessage:`Failed to create drawing`,openAfterCreate:!0})}})}handleNewMermaid({parentDir:e=``}={}){let t=this.getCreateContext(e);this.openActionDialog({title:`Create Mermaid diagram`,copy:t.normalizedParentDir?"Create a new `.mmd` or `.mermaid` file inside the selected folder.":"Create a new `.mmd` or `.mermaid` file with starter diagram content.",label:`Diagram ${t.inputLabelSuffix}`,hint:`${t.hintPrefix} ".mmd" is added automatically unless you enter ".mermaid".`,note:t.note,placeholder:t.normalizedParentDir?`flow`:`diagrams/flow`,submitLabel:`Create diagram`,emptyMessage:`Diagram path is required`,onSubmit:e=>{let n=T(e);if(!n)return this.showToast(`Diagram path is required`),!1;let r=se(E(t.normalizedParentDir,n));return this.createVaultFile(r.path,r.content,{errorMessage:`Failed to create Mermaid diagram`,openAfterCreate:!0})}})}handleNewDrawio({parentDir:e=``}={}){let t=this.getCreateContext(e);this.openActionDialog({title:`Create draw.io diagram`,copy:t.normalizedParentDir?"Create a new `.drawio` diagram inside the selected folder.":"Create a new `.drawio` diagram with a native starter document.",label:`Diagram ${t.inputLabelSuffix}`,hint:`${t.hintPrefix} ".drawio" is added automatically.`,note:t.note,placeholder:t.normalizedParentDir?`architecture`:`diagrams/architecture`,submitLabel:`Create diagram`,emptyMessage:`Diagram path is required`,onSubmit:e=>{let n=T(e);if(!n)return this.showToast(`Diagram path is required`),!1;let r=te(E(t.normalizedParentDir,n));return this.createVaultFile(r.path,r.content,{errorMessage:`Failed to create draw.io diagram`,openAfterCreate:!0})}})}handleNewPlantUml({parentDir:e=``}={}){let t=this.getCreateContext(e);this.openActionDialog({title:`Create PlantUML diagram`,copy:t.normalizedParentDir?"Create a new `.puml` or `.plantuml` file inside the selected folder.":"Create a new `.puml` or `.plantuml` file with starter diagram content.",label:`Diagram ${t.inputLabelSuffix}`,hint:`${t.hintPrefix} ".puml" is added automatically unless you enter ".plantuml".`,note:t.note,placeholder:t.normalizedParentDir?`sequence-flow`:`diagrams/sequence-flow`,submitLabel:`Create diagram`,emptyMessage:`Diagram path is required`,onSubmit:e=>{let n=T(e);if(!n)return this.showToast(`Diagram path is required`),!1;let r=ne(E(t.normalizedParentDir,n));return this.createVaultFile(r.path,r.content,{errorMessage:`Failed to create PlantUML diagram`,openAfterCreate:!0})}})}handleNewStructurizr({parentDir:e=``}={}){let t=this.getCreateContext(e);this.openActionDialog({title:`Create Structurizr workspace`,copy:t.normalizedParentDir?`Create a collaborative C4 workspace inside the selected folder.`:`Create a collaborative C4 workspace in the vault.`,label:`Workspace ${t.inputLabelSuffix}`,hint:`${t.hintPrefix} ".dsl" is added automatically. workspace.dsl is conventional; any workspace .dsl file can render.`,note:t.note,placeholder:`workspace`,submitLabel:`Create workspace`,emptyMessage:`Workspace path is required`,onSubmit:e=>{let n=T(e);if(!n)return this.showToast(`Workspace path is required`),!1;let r=ie(E(t.normalizedParentDir,n));return this.createVaultFile(r.path,r.content,{errorMessage:`Failed to create Structurizr workspace`,openAfterCreate:!0})}})}handleRenameFile(e){let t=m(e)||`.md`;this.openActionDialog({title:`Rename or move file`,copy:`Update the relative path without changing the file type.`,label:`Path`,hint:`Use "/" to move the file into another folder. ${t} is kept automatically.`,value:e,submitLabel:`Save file path`,emptyMessage:`File path is required`,onSubmit:n=>this.renameVaultFile(e,n,t)})}handleRenameDirectory(e){this.openActionDialog({title:`Rename or move folder`,copy:`Update the relative path for this folder and everything inside it.`,label:`Path`,hint:`Use "/" to move the folder into another location in the vault.`,value:e,submitLabel:`Save folder path`,emptyMessage:`Folder path is required`,onSubmit:t=>this.renameDirectory(e,t)})}handleDelete(e){this.openActionDialog({title:`Delete file`,copy:`This permanently removes the file from the vault.`,note:e,submitLabel:`Delete file`,destructive:!0,requiresInput:!1,onSubmit:()=>this.deleteVaultFile(e)})}handleDeleteDirectory(e){let{directoryCount:t,fileCount:n}=this.state.getDirectoryDescendantSummary(e),r=t>0||n>0,i=r?`This will permanently remove ${ys(n,`file`,`files`)} and ${ys(t,`nested folder`,`nested folders`)} inside this folder.`:`This permanently removes the empty folder from the vault.`;this.openActionDialog({title:r?`Delete folder and contents`:`Delete folder`,copy:i,note:e,submitLabel:r?`Delete folder and contents`:`Delete folder`,destructive:!0,requiresInput:!1,onSubmit:()=>this.deleteDirectory(e,{recursive:r})})}handleDownloadFile(e){this.downloadFileEntry(e)}handleDownloadDirectory(e){this.downloadDirectoryEntry(e)}};function Cs(e=[],t=``){for(let n of e){if(n.path===t)return n;if(n.type===`directory`&&Array.isArray(n.children)){let e=Cs(n.children,t);if(e)return e}}return null}var ws=420,Ts=10,Es=700,Ds=80;function Os({container:e,itemSelector:t,placeholder:n,skipLabels:r=[]}){let i=document.createElement(`input`);return i.type=`search`,i.className=`file-context-search`,i.setAttribute(`aria-label`,n),i.placeholder=n,i.addEventListener(`input`,()=>{let n=i.value.trim().toLowerCase();e.querySelectorAll(t).forEach(e=>{if(r.includes(e.textContent))return;let t=(e.dataset.searchText??e.textContent??``).toLowerCase();e.hidden=n.length>0&&!t.includes(n)&&!qe(t,n)})}),i.addEventListener(`keydown`,n=>{n.key===`Enter`&&(n.preventDefault(),Array.from(e.querySelectorAll(t)).find(e=>!e.hidden&&!r.includes(e.textContent))?.click())}),e.appendChild(i),i}var ks=class{constructor({mobileBreakpointQuery:e=window.matchMedia(`(max-width: 768px)`),onEntryDrop:t,onDirectoryToggle:n,onFileContextMenu:r,onFileSelect:i,onSearchChange:a,onTreeContextMenu:o,onValidateDrop:s,onVaultSelect:c}){this.onVaultSelect=c,this.onEntryDrop=t,this.onDirectoryToggle=n,this.onFileContextMenu=r,this.onFileSelect=i,this.onSearchChange=a,this.onTreeContextMenu=o,this.onValidateDrop=s,this.mobileBreakpointQuery=e,this.treeContainer=document.getElementById(`fileTree`),this.searchInput=document.getElementById(`fileSearchInput`),this.searchStatus=document.getElementById(`fileSearchStatus`),this.renderedDirectoryWrappers=new Map,this.renderedChildContainers=new Map,this.renderedFileItems=new Map,this.lastRenderMode=`tree`,this.longPressTimer=0,this.longPressContext=null,this.suppressedActivationTarget=null,this.contextMenuCloseHandler=null,this.contextMenuCloseTimer=null,this.contextMenuAnchor=null,this.actionSheetCloseHandler=null,this.blockingModalHandler=()=>this.removeContextMenu(),this.dragSource=null,this.currentSearchQuery=``,this.activeDropTarget=null,this.invalidDropAttempt=null,this.autoExpandTimer=0,this.autoExpandTargetPath=``,this.rootDropZone=null,this.threadCounts=new Map,this.showFileExtensions=!1,this.searchDebounceTimer=null,this.pendingSearchValue=null}renderVaultSwitcher(e){let{activeVaultId:t,onVaultSelect:n,vaults:r}=e??{};if(!Array.isArray(r)||r.length<2||document.getElementById(`vaultSwitcher`))return;let i=document.createElement(`div`);i.className=`sidebar-search vault-switcher`,i.id=`vaultSwitcherWrap`;let a=r.filter(e=>e?.id);if(a.length===0)return;let o=a.find(e=>e.id===t)??a[0],s=document.createElement(`button`);s.type=`button`,s.className=`vault-switcher-button`,s.id=`vaultSwitcher`,s.setAttribute(`aria-haspopup`,`menu`),s.setAttribute(`aria-label`,`Switch vault (current: ${o.name||o.id})`),s.title=`Switch vault`,s.innerHTML=`<span class="vault-switcher-icon" aria-hidden="true"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path></svg></span><span class="vault-switcher-name">${j(o.name||o.id)}</span><span class="vault-switcher-chevron" aria-hidden="true"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"></path></svg></span>`,s.addEventListener(`click`,e=>{this.showContextMenu(e,a.map(e=>({label:e.name||e.id,searchText:`${e.name||e.id} ${e.id}`,onSelect:()=>(n??this.onVaultSelect)?.(e.id)})),{alignToAnchor:!0,searchPlaceholder:`Filter vaults…`})}),i.appendChild(s);let c=document.getElementById(`fileSearch`);c?.parentNode?c.parentNode.insertBefore(i,c):this.treeContainer?.parentNode?.prepend(i)}initialize(){this.searchInput?.addEventListener(`input`,e=>{this.handleSearchInput(e.target.value)}),this.treeContainer?.addEventListener(`click`,e=>{this.handleTreeClick(e)}),this.treeContainer?.addEventListener(`contextmenu`,e=>{this.handleTreeContextMenu(e)}),this.treeContainer?.addEventListener(`pointerdown`,e=>{this.handleTreePointerDown(e)}),this.treeContainer?.addEventListener(`pointermove`,e=>{this.handleLongPressPointerMove(e)},{passive:!0}),this.treeContainer?.addEventListener(`pointerup`,()=>{this.cancelLongPress()}),this.treeContainer?.addEventListener(`pointercancel`,()=>{this.cancelLongPress()}),this.treeContainer?.addEventListener(`scroll`,()=>{this.cancelLongPress()},{passive:!0}),this.treeContainer?.addEventListener(`dragstart`,e=>{this.handleTreeDragStart(e)}),this.treeContainer?.addEventListener(`dragend`,e=>{this.handleTreeDragEnd(e)}),this.treeContainer?.addEventListener(`dragenter`,e=>{this.handleTreeDragEnter(e)}),this.treeContainer?.addEventListener(`dragover`,e=>{this.handleTreeDragOver(e)}),this.treeContainer?.addEventListener(`drop`,e=>{this.handleTreeDrop(e)}),this.treeContainer?.addEventListener(`dragleave`,e=>{this.handleTreeDragLeave(e)})}handleSearchInput(e){this.pendingSearchValue=String(e??``),clearTimeout(this.searchDebounceTimer),this.searchDebounceTimer=setTimeout(()=>{this.searchDebounceTimer=null,this.pendingSearchValue=null,this.onSearchChange?.(e)},150)}cancelPendingSearch(){clearTimeout(this.searchDebounceTimer),this.searchDebounceTimer=null,this.pendingSearchValue=null}getTreeItem(e){let t=e.target instanceof Element?e.target.closest(`.file-tree-item`):null;return!t||!this.treeContainer?.contains(t)?null:t}handleTreeClick(e){let t=this.getTreeItem(e);if(t&&!this.consumeSuppressedActivation(t,e)){if(t.classList.contains(`file-tree-dir`)){this.onDirectoryToggle?.(t.dataset.path);return}this.onFileSelect?.(t.dataset.path)}}handleTreeContextMenu(e){let t=this.getTreeItem(e);if(t){if(e.preventDefault(),t.classList.contains(`file-tree-dir`)){this.onFileContextMenu?.(e,{directoryPath:t.dataset.path,type:`directory`});return}this.onFileContextMenu?.(e,{filePath:t.dataset.path,type:`file`});return}e.preventDefault(),this.onTreeContextMenu?.(e)}handleTreePointerDown(e){let t=this.getTreeItem(e);if(t){this.startLongPress(e,()=>{if(t.classList.contains(`file-tree-dir`)){this.onFileContextMenu?.(this.createLongPressEvent(t),{directoryPath:t.dataset.path,type:`directory`});return}this.onFileContextMenu?.(this.createLongPressEvent(t),{filePath:t.dataset.path,type:`file`})},t);return}this.startLongPress(e,()=>{this.onTreeContextMenu?.({clientX:Number(e.clientX||0),clientY:Number(e.clientY||0),preventDefault(){},target:this.treeContainer})},this.treeContainer)}handleTreeDragStart(e){let t=this.getTreeItem(e);t&&this.isDragAndDropEnabled()&&(this.dragSource={path:t.dataset.path,type:t.dataset.entryType},document.body?.classList.add(`is-file-tree-dragging`),this.treeContainer&&(this.treeContainer.dataset.dragActive=`true`),t.classList.add(`is-dragging`),e.dataTransfer&&(e.dataTransfer.effectAllowed=this.dragSource.type===`file`?`copyMove`:`move`,e.dataTransfer.setData(`text/plain`,t.dataset.path),this.dragSource.type===`file`&&e.dataTransfer.setData(`application/x-collabmd-vault-file`,JSON.stringify({path:t.dataset.path,vaultId:P()||``}))))}handleTreeDragEnd(e){(this.getTreeItem(e)??this.treeContainer?.querySelector(`.file-tree-item.is-dragging`))?.classList.remove(`is-dragging`);let t=this.dragSource;this.invalidDropAttempt&&t&&this.onEntryDrop?.(this.invalidDropAttempt),this.dragSource=null,this.invalidDropAttempt=null,this.clearDragFeedback()}handleTreeDragEnter(e){let t=e.target instanceof Element?e.target.closest(`.file-tree-dir`):null;if(t&&this.treeContainer?.contains(t)){this.handleDirectoryDragEnter(e,t,t.dataset.path);return}e.target instanceof Element&&e.target.closest(`.file-tree-root-drop-zone`)&&this.handleRootZoneDragEnter(e)}updateSearchStatus(e,t=null){if(!this.searchStatus)return;let n=String(e??``).trim()&&Number.isInteger(t)?`${t} match${t===1?``:`es`}`:``;this.searchStatus.textContent=n,this.searchStatus.classList.toggle(`hidden`,!n)}revealFile(e){this.renderedFileItems.get(e)?.scrollIntoView({block:`nearest`})}setActiveFile(e){if(this.treeContainer?.querySelector(`.file-tree-file.active`)?.classList.remove(`active`),!e)return!0;let t=this.renderedFileItems.get(e);return t?.classList.add(`active`),!!t}setThreadCounts(e){this.threadCounts=e instanceof Map?e:new Map,this.renderedFileItems.forEach((e,t)=>{let n=Number(this.threadCounts.get(t)??0)||0,r=e.querySelector(`.file-tree-comment-count`);if(e.classList.toggle(`has-comments`,n>0),e.setAttribute(`aria-label`,`${t}${n>0?`, ${n} open comment thread${n===1?``:`s`}`:``}`),n<=0){delete e.dataset.threadCount,r?.remove();return}e.dataset.threadCount=String(n),r||(r=document.createElement(`span`),r.className=`file-tree-comment-count`,e.appendChild(r)),r.textContent=String(n),r.setAttribute(`aria-hidden`,`true`)})}render({activeFilePath:e,changedPaths:t=null,expandedDirs:n,reset:r=!1,searchMatches:i,searchQuery:a,showFileExtensions:o=!1,threadCounts:s=new Map,tree:c}){if(!this.treeContainer)return;if(this.threadCounts=s instanceof Map?s:new Map,this.showFileExtensions=!!o,this.currentSearchQuery=String(a??``).trim(),this.currentSearchQuery&&this.clearDragFeedback(),this.searchInput&&this.pendingSearchValue===null&&this.searchInput.value!==a&&(this.searchInput.value=a),this.updateSearchStatus(a,this.currentSearchQuery?i.length:null),this.currentSearchQuery){this.lastRenderMode=`search`,this.renderSearchResults(i,e);return}if(r||this.lastRenderMode!==`tree`||!Array.isArray(t)||t.length===0){this.renderFullTree(c,{activeFilePath:e,expandedDirs:n}),this.lastRenderMode=`tree`;return}let l=Array.from(new Set(t.map(e=>w(e)))).sort((e,t)=>e.split(`/`).length-t.split(`/`).length).filter((e,t,n)=>!n.slice(0,t).some(t=>t&&e.startsWith(`${t}/`)));if(l.includes(``)){this.renderFullTree(c,{activeFilePath:e,expandedDirs:n}),this.lastRenderMode=`tree`;return}for(let t of l)if(!this.rerenderDirectoryBranch(t,c,{activeFilePath:e,expandedDirs:n})){this.renderFullTree(c,{activeFilePath:e,expandedDirs:n}),this.lastRenderMode=`tree`;return}this.lastRenderMode=`tree`}renderSearchResults(e,t){if(!this.treeContainer)return;if(this.resetTreeIndexes(),this.treeContainer.innerHTML=``,this.rootDropZone=null,e.length===0){this.treeContainer.innerHTML=`<div class="file-tree-empty">No matches</div>`;return}let n=document.createDocumentFragment(),r=e.slice(0,Ds);for(let e of r)n.appendChild(this.createFileItem({activeFilePath:t,depth:0,filePath:e.path,fileType:e.type||(d(e.path)??`file`),name:e.name||C(e.path),searchResult:!0}));if(e.length>Ds){let t=document.createElement(`div`);t.className=`file-tree-empty`,t.textContent=`${e.length-Ds} more matches. Refine the search.`,n.appendChild(t)}this.treeContainer.appendChild(n)}renderFullTree(e,{activeFilePath:t,expandedDirs:n}){if(this.resetTreeIndexes(),this.treeContainer.innerHTML=``,this.rootDropZone=null,e.length===0){this.treeContainer.innerHTML=`<div class="file-tree-empty">No vault files found</div>`;return}let r=document.createDocumentFragment();r.appendChild(this.createRootDropZone()),this.renderNodes(e,r,{activeFilePath:t,depth:0,expandedDirs:n}),this.treeContainer.appendChild(r)}resetTreeIndexes(){this.renderedDirectoryWrappers.clear(),this.renderedChildContainers.clear(),this.renderedFileItems.clear()}renderNodes(e,t,{activeFilePath:n,depth:r,expandedDirs:i}){for(let a of e){if(a.type===`directory`){t.appendChild(this.createDirectoryItem(a,{activeFilePath:n,depth:r,expandedDirs:i}));continue}t.appendChild(this.createFileItem({activeFilePath:n,depth:r,filePath:a.path,fileType:a.type,name:a.name}))}}createDirectoryItem(e,{activeFilePath:t,depth:n,expandedDirs:r}){let i=document.createElement(`div`);i.className=`file-tree-group`;let a=document.createElement(`button`);a.className=`file-tree-item file-tree-dir`,a.title=e.path,a.setAttribute(`aria-label`,e.path),a.style.setProperty(`--depth`,n),a.dataset.depth=n;let o=r.has(e.path);if(a.setAttribute(`aria-expanded`,String(o)),a.dataset.path=e.path,a.dataset.entryType=`directory`,a.innerHTML=`
|
|
328
|
+
<span class="file-tree-chevron${o?` expanded`:``}" aria-hidden="true"></span>
|
|
329
|
+
<span class="file-tree-icon" aria-hidden="true"></span>
|
|
330
|
+
<span class="file-tree-name">${j(e.name)}</span>
|
|
331
|
+
`,this.configureDragSource(a),i.appendChild(a),this.renderedDirectoryWrappers.set(e.path,i),o&&Array.isArray(e.children)){let a=document.createElement(`div`);a.className=`file-tree-children`,this.renderedChildContainers.set(e.path,a),this.renderNodes(e.children,a,{activeFilePath:t,depth:n+1,expandedDirs:r}),i.appendChild(a)}else this.renderedChildContainers.delete(e.path);return i}rerenderDirectoryBranch(e,t,{activeFilePath:n,expandedDirs:r}){let i=this.renderedDirectoryWrappers.get(e),a=Cs(t,e);if(!i||a?.type!==`directory`)return!1;let o=i.querySelector(`.file-tree-dir`),s=r.has(e);o?.setAttribute(`aria-expanded`,String(s)),o?.querySelector(`.file-tree-chevron`)?.classList.toggle(`expanded`,s);let c=Number(o?.dataset.depth??0),l=this.renderedChildContainers.get(e)??i.querySelector(`.file-tree-children`);return this.clearRenderedDescendants(e),s?(l?l.innerHTML=``:(l=document.createElement(`div`),l.className=`file-tree-children`,i.appendChild(l)),this.renderedChildContainers.set(e,l),this.renderNodes(a.children??[],l,{activeFilePath:n,depth:c+1,expandedDirs:r}),!0):(l?.remove(),this.renderedChildContainers.delete(e),!0)}clearRenderedDescendants(e){let t=`${e}/`;Array.from(this.renderedDirectoryWrappers.keys()).forEach(e=>{e.startsWith(t)&&this.renderedDirectoryWrappers.delete(e)}),Array.from(this.renderedChildContainers.keys()).forEach(e=>{e.startsWith(t)&&this.renderedChildContainers.delete(e)}),Array.from(this.renderedFileItems.keys()).forEach(e=>{e.startsWith(t)&&this.renderedFileItems.delete(e)})}createFileItem({activeFilePath:e,depth:t,filePath:n,fileType:r=`file`,name:i,searchResult:a=!1}){let o=document.createElement(`button`),s=w(n);o.className=`file-tree-item file-tree-file${a?` file-tree-search-result`:``}`,o.title=n;let c=Number(this.threadCounts.get(n)??0);o.setAttribute(`aria-label`,`${n}${c>0?`, ${c} open comment thread${c===1?``:`s`}`:``}`),n===e&&o.classList.add(`active`),c>0&&o.classList.add(`has-comments`),o.style.setProperty(`--depth`,t),o.dataset.depth=t,o.dataset.path=n,o.dataset.entryType=`file`,o.dataset.kind=_(n)??r??`file`,c>0&&(o.dataset.threadCount=String(c));let l=this.showFileExtensions||a?String(i??``):x(i);return o.innerHTML=`
|
|
332
|
+
<span class="file-tree-icon" aria-hidden="true"></span>
|
|
333
|
+
${a?`<span class="file-tree-search-copy">
|
|
334
|
+
<span class="file-tree-name">${j(l)}</span>
|
|
335
|
+
${s?`<span class="file-tree-search-path">${j(s)}</span>`:``}
|
|
336
|
+
</span>`:`<span class="file-tree-name">${j(l)}</span>`}
|
|
337
|
+
${c>0?`<span class="file-tree-comment-count" aria-hidden="true">${c}</span>`:``}
|
|
338
|
+
`,this.configureDragSource(o),this.renderedFileItems.set(n,o),o}isMobileViewport(){return!!this.mobileBreakpointQuery?.matches}isDragAndDropEnabled(){return!this.isMobileViewport()&&!this.currentSearchQuery}configureDragSource(e){e instanceof HTMLElement&&(e.draggable=this.isDragAndDropEnabled())}createRootDropZone(){let e=document.createElement(`div`);return e.className=`file-tree-root-drop-zone`,e.textContent=`Drop here to move to vault root`,e.addEventListener(`dragenter`,e=>{this.handleRootZoneDragEnter(e)}),e.addEventListener(`dragover`,e=>{this.handleRootZoneDragOver(e)}),e.addEventListener(`drop`,e=>{this.handleRootZoneDrop(e)}),this.rootDropZone=e,e}validateDrop(e){return!this.dragSource||this.currentSearchQuery?!1:this.onValidateDrop?.({destinationDirectory:e,sourcePath:this.dragSource.path,sourceType:this.dragSource.type})===!0}setDropTarget(e){if(this.activeDropTarget?.element&&this.activeDropTarget.element!==e?.element&&this.activeDropTarget.element.classList.remove(`is-drop-target`,`is-drop-invalid`),this.activeDropTarget?.root&&!e?.root&&this.treeContainer?.classList.remove(`is-drop-target-root`,`is-drop-invalid`),this.activeDropTarget?.rootZone&&!e?.rootZone&&this.rootDropZone?.classList.remove(`is-drop-target`,`is-drop-invalid`),this.activeDropTarget=e,!e||e.isValid?this.invalidDropAttempt=null:this.dragSource&&(this.invalidDropAttempt={destinationDirectory:e.destinationDirectory||``,sourcePath:this.dragSource.path,sourceType:this.dragSource.type}),e){if(e.root){this.treeContainer?.classList.toggle(`is-drop-target-root`,e.isValid),this.treeContainer?.classList.toggle(`is-drop-invalid`,!e.isValid);return}if(e.rootZone){this.rootDropZone?.classList.toggle(`is-drop-target`,e.isValid),this.rootDropZone?.classList.toggle(`is-drop-invalid`,!e.isValid);return}e.element.classList.toggle(`is-drop-target`,e.isValid),e.element.classList.toggle(`is-drop-invalid`,!e.isValid)}}scheduleAutoExpand(e,t){e.getAttribute(`aria-expanded`)!==`true`&&this.autoExpandTargetPath!==t&&(this.cancelAutoExpand(),this.autoExpandTargetPath=t,this.autoExpandTimer=window.setTimeout(()=>{this.autoExpandTimer=0,this.autoExpandTargetPath=``,e.isConnected&&e.getAttribute(`aria-expanded`)!==`true`&&this.onDirectoryToggle?.(t)},Es))}cancelAutoExpand(){this.autoExpandTimer&&=(window.clearTimeout(this.autoExpandTimer),0),this.autoExpandTargetPath=``}clearDragFeedback(){this.cancelAutoExpand(),this.setDropTarget(null),document.body?.classList.remove(`is-file-tree-dragging`),this.treeContainer&&delete this.treeContainer.dataset.dragActive}handleDirectoryDragEnter(e,t,n){if(!this.dragSource)return;e.preventDefault(),e.stopPropagation();let r=this.validateDrop(n);this.setDropTarget({destinationDirectory:n,element:t,isValid:r,root:!1}),r?this.scheduleAutoExpand(t,n):this.cancelAutoExpand()}handleDirectoryDragOver(e,t,n){if(!this.dragSource)return;e.preventDefault(),e.stopPropagation();let r=this.validateDrop(n);e.dataTransfer&&(e.dataTransfer.dropEffect=r?`move`:`none`),this.setDropTarget({destinationDirectory:n,element:t,isValid:r,root:!1}),r?this.scheduleAutoExpand(t,n):this.cancelAutoExpand()}handleDirectoryDrop(e,t){if(!this.dragSource)return;e.preventDefault(),e.stopPropagation();let n={destinationDirectory:t,sourcePath:this.dragSource.path,sourceType:this.dragSource.type};this.clearDragFeedback(),this.onEntryDrop?.(n)}handleTreeDragOver(e){if(!this.dragSource||!this.treeContainer)return;let t=e.target instanceof Element?e.target.closest(`.file-tree-dir`):null;if(t&&this.treeContainer.contains(t)){this.handleDirectoryDragOver(e,t,t.dataset.path);return}let n=e.target instanceof Element?e.target.closest(`.file-tree-file`):null;if(n&&this.treeContainer.contains(n)){this.handleNonDropTargetDragOver(e);return}if(e.target instanceof Element&&e.target.closest(`.file-tree-root-drop-zone`)){this.handleRootZoneDragOver(e);return}e.preventDefault(),this.cancelAutoExpand();let r=this.validateDrop(``);e.dataTransfer&&(e.dataTransfer.dropEffect=r?`move`:`none`),this.setDropTarget({destinationDirectory:``,element:this.treeContainer,isValid:r,root:!0})}handleTreeDrop(e){if(!this.dragSource||!this.treeContainer)return;let t=e.target instanceof Element?e.target.closest(`.file-tree-dir`):null;if(t&&this.treeContainer.contains(t)){this.handleDirectoryDrop(e,t.dataset.path);return}if(e.target instanceof Element&&e.target.closest(`.file-tree-root-drop-zone`)){this.handleRootZoneDrop(e);return}if(e.target instanceof Element&&e.target.closest(`.file-tree-file`))return;e.preventDefault();let n={destinationDirectory:``,sourcePath:this.dragSource.path,sourceType:this.dragSource.type};this.clearDragFeedback(),this.onEntryDrop?.(n)}handleTreeDragLeave(e){if(!this.dragSource||!this.treeContainer)return;let t=e.relatedTarget;t&&this.treeContainer.contains(t)||this.clearDragFeedback()}handleRootZoneDragEnter(e){if(!this.dragSource)return;e.preventDefault(),e.stopPropagation();let t=this.validateDrop(``);this.cancelAutoExpand(),this.setDropTarget({destinationDirectory:``,element:this.rootDropZone,isValid:t,rootZone:!0})}handleRootZoneDragOver(e){if(!this.dragSource)return;e.preventDefault(),e.stopPropagation();let t=this.validateDrop(``);e.dataTransfer&&(e.dataTransfer.dropEffect=t?`move`:`none`),this.cancelAutoExpand(),this.setDropTarget({destinationDirectory:``,element:this.rootDropZone,isValid:t,rootZone:!0})}handleRootZoneDrop(e){if(!this.dragSource)return;e.preventDefault(),e.stopPropagation();let t={destinationDirectory:``,sourcePath:this.dragSource.path,sourceType:this.dragSource.type};this.clearDragFeedback(),this.onEntryDrop?.(t)}handleNonDropTargetDragOver(e){this.dragSource&&(e.preventDefault(),e.stopPropagation(),e.dataTransfer&&(e.dataTransfer.dropEffect=`none`),this.clearDragFeedback())}startLongPress(e,t,n=null){this.isMobileViewport()&&[`touch`,`pen`].includes(String(e.pointerType||``))&&Number(e.button??0)===0&&(this.cancelLongPress(),this.longPressContext={callback:t,pointerId:e.pointerId,startX:Number(e.clientX||0),startY:Number(e.clientY||0),target:n??e.currentTarget??e.target??null},this.longPressTimer=window.setTimeout(()=>{let e=this.longPressContext;this.longPressTimer=0,e&&(this.suppressedActivationTarget=e.target,e.callback(),this.longPressContext=null)},ws))}handleLongPressPointerMove(e){if(!this.longPressContext||e.pointerId!==this.longPressContext.pointerId)return;let t=Math.abs(Number(e.clientX||0)-this.longPressContext.startX),n=Math.abs(Number(e.clientY||0)-this.longPressContext.startY);(t>Ts||n>Ts)&&this.cancelLongPress()}cancelLongPress(){this.longPressTimer&&=(window.clearTimeout(this.longPressTimer),0),this.longPressContext=null}createLongPressEvent(e){return{clientX:this.longPressContext?.startX??0,clientY:this.longPressContext?.startY??0,preventDefault(){},stopPropagation(){},target:e}}consumeSuppressedActivation(e,t){return this.suppressedActivationTarget===e&&(this.suppressedActivationTarget=null,t?.preventDefault?.(),t?.stopPropagation?.(),!0)}showContextMenu(e,t,n){let{alignToAnchor:r=!1,searchPlaceholder:i=``}=n??{};if(this.removeContextMenu(),!Array.isArray(t)||t.length===0)return;let a=e.currentTarget instanceof Element?e.currentTarget:e.target;if(this.contextMenuAnchor=a instanceof HTMLElement?a:null,this.isMobileViewport()){this.showActionSheet(t,{searchPlaceholder:i});return}let o=document.createElement(`div`);o.className=`file-context-menu`,o.setAttribute(`role`,`menu`),o.setAttribute(`aria-label`,`File actions`);let s=i?Os({container:o,itemSelector:`[role="menuitem"]`,placeholder:i}):null;for(let e of t){let t=document.createElement(`button`);t.type=`button`,t.className=`file-context-item${e.danger?` file-context-danger`:``}`,t.setAttribute(`role`,`menuitem`),t.textContent=e.label,e.searchText&&(t.dataset.searchText=e.searchText),t.addEventListener(`click`,()=>{this.removeContextMenu(),e.onSelect?.({anchor:a})}),o.appendChild(t)}document.body.appendChild(o);let c=o.getBoundingClientRect(),l=Math.max(8,window.innerWidth-c.width-8),u=Math.max(8,window.innerHeight-c.height-8),d=r?this.contextMenuAnchor?.getBoundingClientRect?.():null;if(d){o.style.minWidth=`${d.width}px`,o.style.left=`${Math.max(8,Math.min(d.left,l))}px`;let e=d.bottom+4;o.style.top=e+c.height>window.innerHeight-8?`${Math.max(8,d.top-c.height-4)}px`:`${e}px`}else o.style.left=`${Math.max(8,Math.min(e.clientX,l))}px`,o.style.top=`${Math.max(8,Math.min(e.clientY,u))}px`;let f=e=>{o.contains(e.target)||this.removeContextMenu()};this.contextMenuCloseHandler=f,o.addEventListener(`keydown`,e=>{let t=Array.from(o.querySelectorAll(`[role="menuitem"]`)).filter(e=>!e.hidden),n=document.activeElement===s?-1:Math.max(0,t.indexOf(document.activeElement));if(e.key===`Escape`){e.preventDefault(),this.removeContextMenu();return}if(e.key===`Tab`){this.removeContextMenu({restoreFocus:!1});return}let r=e.key===`Home`?0:e.key===`End`?t.length-1:e.key===`ArrowDown`?(n+1)%t.length:e.key===`ArrowUp`?(n-1+t.length)%t.length:-1;r>=0&&(e.preventDefault(),t[r]?.focus())}),document.addEventListener(`collabmd:close-custom-modals`,this.blockingModalHandler),this.contextMenuCloseTimer=setTimeout(()=>{this.contextMenuCloseTimer=null,o.isConnected&&this.contextMenuCloseHandler===f&&document.addEventListener(`click`,f)},0),(s??o.querySelector(`[role="menuitem"]`))?.focus()}showActionSheet(e,t){let{searchPlaceholder:n=``}=t??{},r=document.createElement(`dialog`);r.className=`file-action-sheet`,r.setAttribute(`aria-label`,`File actions`),r.setAttribute(`closedby`,`any`),n&&Os({container:r,itemSelector:`.file-action-sheet-item`,placeholder:n,skipLabels:[`Cancel`]}),e.forEach(e=>{let t=document.createElement(`button`);t.type=`button`,t.className=k({variant:`secondary`,extra:[`file-action-sheet-item`,e.danger?`file-context-danger`:``]}),t.textContent=e.label,e.searchText&&(t.dataset.searchText=e.searchText),t.addEventListener(`click`,()=>{this.removeContextMenu(),e.onSelect?.()}),r.appendChild(t)});let i=document.createElement(`button`);i.type=`button`,i.className=k({variant:`ghost`,extra:`file-action-sheet-item`}),i.textContent=`Cancel`,i.addEventListener(`click`,()=>{this.removeContextMenu()}),r.appendChild(i),r.addEventListener(`keydown`,e=>{e.key===`Escape`&&(e.preventDefault(),this.removeContextMenu())}),r.addEventListener(`cancel`,e=>{e.preventDefault(),this.removeContextMenu()}),r.addEventListener(`close`,()=>{r.isConnected&&this.removeContextMenu()}),r.addEventListener(`click`,e=>{let t=r.getBoundingClientRect();(e.clientX<t.left||e.clientX>t.right||e.clientY<t.top||e.clientY>t.bottom)&&this.removeContextMenu()}),document.body.append(r),document.addEventListener(`collabmd:close-custom-modals`,this.blockingModalHandler),this.actionSheetCloseHandler=()=>{r.open&&r.close(),r.remove(),this.actionSheetCloseHandler=null},r.showModal(),(r.querySelector(`.file-context-search`)??r.querySelector(`button:not(:disabled)`))?.focus()}removeContextMenu({restoreFocus:e=!0}={}){this.cancelLongPress(),this.clearDragFeedback(),document.querySelectorAll(`.file-context-menu`).forEach(e=>e.remove()),this.contextMenuCloseTimer!==null&&(clearTimeout(this.contextMenuCloseTimer),this.contextMenuCloseTimer=null),this.contextMenuCloseHandler&&=(document.removeEventListener(`click`,this.contextMenuCloseHandler),null),document.removeEventListener(`collabmd:close-custom-modals`,this.blockingModalHandler),this.actionSheetCloseHandler?.(),e&&this.contextMenuAnchor?.focus?.(),this.contextMenuAnchor=null}},As=class{constructor({mobileBreakpointQuery:e=window.matchMedia(`(max-width: 768px)`),onFileSelect:t,onFileDelete:n,onDirectoryExport:r,pendingWorkspaceRequestIds:i=null,onShowFileExtensionsChange:a,showFileExtensions:o=!1,toastController:s,vaultClient:c,vaultSwitcher:l=null}){this.onFileSelect=t,this.onFileDelete=n,this.onDirectoryExport=r,this.onShowFileExtensionsChange=a,this.toastController=s,this.vaultClient=c,this.vaultSwitcher=l,this.state=new Se,this.showFileExtensions=!!o,this.threadCounts=new Map,this.view=new ks({mobileBreakpointQuery:e,onDirectoryToggle:e=>{this.state.toggleDirectory(e),this.view.rerenderDirectoryBranch(e,this.state.tree,{activeFilePath:this.state.activeFilePath,expandedDirs:this.state.expandedDirs})||this.renderTree()},onEntryDrop:e=>this.actionController.moveEntryByDrop(e),onFileContextMenu:(e,t)=>{if(t.type===`directory`){this.view.showContextMenu(e,this.actionController.getDirectoryContextMenuItems(t.directoryPath));return}this.view.showContextMenu(e,this.actionController.getFileContextMenuItems(t.filePath))},onFileSelect:e=>{this.onFileSelect?.(e)},onValidateDrop:e=>this.actionController.canMoveEntryByDrop(e),onSearchChange:e=>{this.state.setSearchQuery(e),this.renderTree()},onTreeContextMenu:e=>{this.view.showContextMenu(e,this.actionController.createContextMenuItems())}}),this.actionController=new Ss({mobileBreakpointQuery:e,onDirectoryExport:this.onDirectoryExport,onFileDelete:this.onFileDelete,onFileSelect:this.onFileSelect,onShowFileExtensionsChange:e=>{this.showFileExtensions=!!e,this.onShowFileExtensionsChange?.(this.showFileExtensions),this.renderTree()},pendingWorkspaceRequestIds:i,showFileExtensions:this.showFileExtensions,refresh:()=>this.refresh(),state:this.state,toastController:this.toastController,vaultClient:this.vaultClient,view:this.view})}initialize(){this.view.initialize(),this.view.renderVaultSwitcher(this.vaultSwitcher),this.actionController.initialize()}async refresh(){try{let e=await this.vaultClient.readTree();this.setTree(e.tree||[])}catch(e){console.error(`[explorer] Failed to load file tree:`,e.message)}}setTree(e,{changedPaths:t=null,reset:n=!1}={}){this.state.setTree(e),this.renderTree({changedPaths:t,reset:n})}setActiveFile(e){let t=this.state.expandedDirs.size;if(this.state.setActiveFile(e),this.state.searchQuery){this.view.setActiveFile(e);return}(this.state.expandedDirs.size!==t||!this.view.setActiveFile(e))&&this.renderTree()}setThreadCounts(e=new Map){this.threadCounts=e instanceof Map?new Map(e):new Map(Object.entries(e??{})),this.view.setThreadCounts(this.threadCounts)}revealFile(e,{clearSearch:t=!1}={}){t&&(this.state.setSearchQuery(``),this.view.cancelPendingSearch()),this.state.setActiveFile(e),this.renderTree({reset:t}),this.view.revealFile(e)}get flatFiles(){return this.state.flatFiles}get fileEntries(){return this.state.flatFileEntries}get flatDocumentFiles(){return this.state.flatDocumentFiles}renderTree({changedPaths:e=null,reset:t=!1}={}){this.view.render({activeFilePath:this.state.activeFilePath,changedPaths:e,expandedDirs:this.state.expandedDirs,reset:t,searchMatches:this.state.getSearchMatches(),searchQuery:this.state.searchQuery,showFileExtensions:this.showFileExtensions,threadCounts:this.threadCounts,tree:this.state.tree})}},js=30;function Ms(e=``){let t=C(e),n=w(e);return n?`
|
|
339
|
+
<span class="file-history-path">${j(t)}</span>
|
|
340
|
+
<span class="file-history-dir">${j(n)}</span>
|
|
341
|
+
`:`<span class="file-history-path">${j(t)}</span>`}function Ns(e={}){let t=[String(e.authorName||`Unknown`),String(e.relativeDateLabel||``)];return e.status===`renamed`&&e.oldPath&&t.push(`Renamed from ${e.oldPath}`),t.filter(Boolean).map(e=>j(e)).join(` · `)}function Ps(e={}){return e.type===`local`?`local`:`commit:${String(e.hash||``).trim()}:${String(e.pathAtCommit||``).trim()}`}function Y(){return{commits:[],error:``,hasMore:!1,loaded:!1,loading:!1,loadingMore:!1,offset:0}}var Fs=class{constructor({diffRenderer:e=null,gitApiClient:t=null,onOpenCommitDiff:n=()=>{},onOpenFile:r=()=>{},onOpenPreview:i=()=>{},onOpenWorkspaceDiff:a=()=>{},toastController:o=null}={}){this.diffRenderer=e,this.gitApiClient=t,this.onOpenCommitDiff=n,this.onOpenFile=r,this.onOpenPreview=i,this.onOpenWorkspaceDiff=a,this.toastController=o,this.page=document.getElementById(`diff-page`),this.content=document.getElementById(`diffContent`),this.fileIndicator=document.getElementById(`diffFileIndicator`),this.openEditorButton=document.getElementById(`diffOpenEditorBtn`),this.primaryActionButton=document.getElementById(`diffPrimaryActionBtn`),this.commitButton=document.getElementById(`diffCommitBtn`),this.backToHistoryButton=document.getElementById(`diffBackToHistoryBtn`),this.gitActionsGroup=document.getElementById(`diffGitActionsGroup`),this.editorActionsGroup=document.getElementById(`diffEditorActionsGroup`),this.actionsDivider=document.getElementById(`diffToolbarDivider`),this.stats=document.getElementById(`diffStats`),this.prevButton=document.getElementById(`diffPrevBtn`),this.nextButton=document.getElementById(`diffNextBtn`),this.layoutToggle=document.getElementById(`diffLayoutToggle`),this.modeButtons=Array.from(document.querySelectorAll(`[data-diff-mode]`)),this.isActive=!1,this.currentFilePath=null,this.localChanges=null,this.history=Y(),this.diffMode=`unified`,this.selectedEntryKey=null,this.detailCache=new Map,this.detailErrors=new Map,this.historyListElement=null,this.historyListScrollTop=0,this.loadingEntryKey=null,this.selectionRequestToken=0}initialize(){this.openEditorButton?.addEventListener(`click`,()=>{this.isActive&&this.currentFilePath&&this.onOpenFile?.(this.currentFilePath)}),this.modeButtons.forEach(e=>{e.addEventListener(`click`,()=>{if(!this.isActive)return;let t=e.getAttribute(`data-diff-mode`);t&&t!==this.diffMode&&(this.diffMode=t,this.render())})}),this.content?.addEventListener(`click`,e=>{if(!this.isActive)return;let t=e.target instanceof Element?e.target.closest(`[data-file-history-select]`):null;if(t){let e=this.findEntryByKey(t.getAttribute(`data-file-history-select`));e&&this.selectEntry(e);return}if(e.target instanceof Element&&e.target.closest(`[data-file-history-open-selected-diff]`)){this.openSelectedDiff();return}if(e.target instanceof Element&&e.target.closest(`[data-file-history-open-selected-preview]`)){this.openSelectedPreview();return}e.target instanceof Element&&e.target.closest(`[data-file-history-load-more]`)&&this.loadMore()})}hide(){this.isActive=!1,this.page?.classList.add(`hidden`),this.content?.classList.remove(`diff-content--history`),this.content&&(this.content.innerHTML=``),this.currentFilePath=null,this.localChanges=null,this.history=Y(),this.selectedEntryKey=null,this.loadingEntryKey=null,this.detailCache.clear(),this.detailErrors.clear(),this.historyListElement=null,this.historyListScrollTop=0,this.selectionRequestToken=0}getEntries(){let e=[];this.localChanges&&e.push({...this.localChanges,key:`local`,label:`Local changes`,pathAtCommit:this.currentFilePath,type:`local`});for(let t of this.history.commits??[])e.push({...t,key:Ps({...t,type:`commit`}),type:`commit`});return e}findEntryByKey(e){return this.getEntries().find(t=>t.key===e)??null}getSelectedEntry(){return this.findEntryByKey(this.selectedEntryKey)}getDefaultEntry(){return this.getEntries()[0]??null}getSelectedDetailState(){let e=this.getSelectedEntry();return e?{detail:this.detailCache.get(e.key)??null,entry:e,error:this.detailErrors.get(e.key)??``,loading:this.loadingEntryKey===e.key}:null}ensureDeferredGitStyles(){return this._deferredGitStylesPromise??=A(()=>Promise.resolve({}),__vite__mapDeps([1]),import.meta.url).catch(()=>{}),this._deferredGitStylesPromise}async openFileHistory({filePath:e}){this.ensureDeferredGitStyles(),this.isActive=!0,this.currentFilePath=String(e??``).trim()||null,this.localChanges=null,this.history={...Y(),loading:!0},this.selectedEntryKey=null,this.loadingEntryKey=null,this.detailCache.clear(),this.detailErrors.clear(),this.historyListElement=null,this.historyListScrollTop=0,this.selectionRequestToken=0,this.renderLoading();try{let[e,t]=await Promise.all([this.loadLocalChanges().catch(()=>null),this.fetchHistoryPage({offset:0})]);this.localChanges=e,this.history=t;let n=this.getDefaultEntry();return n?(await this.selectEntry(n),{history:t,localChanges:e}):(this.render(),{history:t,localChanges:e})}catch(e){return console.error(`[file-history] Failed to load file history:`,e),this.toastController?.show(`Failed to load file history`),this.localChanges=null,this.history={...Y(),error:`Failed to load file history`,loaded:!0},this.render(),{history:this.history,localChanges:null}}}async loadLocalChanges(){if(!this.currentFilePath)return null;let e=await this.gitApiClient.readDiff({metaOnly:!0,path:this.currentFilePath,scope:`all`}),t=e.files?.[0];return t?{...t,summary:e.summary??{additions:Number(t.stats?.additions||0),deletions:Number(t.stats?.deletions||0),filesChanged:1}}:null}async fetchHistoryPage({offset:e=0}={}){if(!this.currentFilePath)return{...Y(),loaded:!0};let t=await this.gitApiClient.readFileHistory({limit:js,offset:e,path:this.currentFilePath}),n=Array.isArray(t.commits)?t.commits:[];return{commits:n,error:``,hasMore:!!t.hasMore,loaded:!0,loading:!1,loadingMore:!1,offset:e+n.length}}async loadSelectedDetail(e){if(!e)return null;if(e.type===`local`){let t=await this.gitApiClient.readDiff({path:this.currentFilePath||``,scope:`all`});return{detail:t.files?.[0]??null,summary:t.summary??e.summary??null}}let t=await this.gitApiClient.readCommit({hash:e.hash||``,path:e.pathAtCommit||``});return{commit:t.commit??null,detail:t.files?.[0]??null,summary:t.summary??null}}async selectEntry(e){if(!e)return null;let t=e.key||Ps(e);this.selectedEntryKey=t,this.detailErrors.delete(t);let n=this.detailCache.get(t);if(n)return this.loadingEntryKey=null,this.render(),n;this.loadingEntryKey=t,this.render();let r=++this.selectionRequestToken;try{let n=await this.loadSelectedDetail(e);return this.detailCache.set(t,n),this.detailErrors.delete(t),r===this.selectionRequestToken&&this.selectedEntryKey===t&&(this.loadingEntryKey=null,this.render()),n}catch(n){return console.error(`[file-history] Failed to load selected diff:`,n),this.toastController?.show(e.type===`local`?`Failed to load local diff`:`Failed to load commit diff`),this.detailErrors.set(t,e.type===`local`?`Failed to load local diff`:`Failed to load commit diff`),r===this.selectionRequestToken&&this.selectedEntryKey===t&&(this.loadingEntryKey=null,this.render()),null}}async loadMore(){if(this.currentFilePath&&!this.history.loading&&!this.history.loadingMore&&this.history.hasMore){this.history={...this.history,error:``,loadingMore:!0},this.render();try{let e=await this.fetchHistoryPage({offset:this.history.offset});this.history={commits:[...this.history.commits,...e.commits],error:``,hasMore:e.hasMore,loaded:!0,loading:!1,loadingMore:!1,offset:e.offset},this.render()}catch(e){console.error(`[file-history] Failed to load more history:`,e),this.toastController?.show(`Failed to load file history`),this.history={...this.history,error:`Failed to load file history`,loadingMore:!1},this.render()}}}openSelectedDiff(){let e=this.getSelectedEntry();if(e){if(e.type===`local`){this.onOpenWorkspaceDiff?.(this.currentFilePath);return}this.onOpenCommitDiff?.(e.hash,{historyFilePath:this.currentFilePath,path:e.pathAtCommit})}}openSelectedPreview(){let e=this.getSelectedEntry();e&&e.type===`commit`&&this.onOpenPreview?.({currentFilePath:this.currentFilePath,hash:e.hash,path:e.pathAtCommit})}renderDiffFileHeader(e={}){return typeof this.diffRenderer?.renderFileHeader==`function`?this.diffRenderer.renderFileHeader(e):`
|
|
342
|
+
<div class="diff-file-header">
|
|
343
|
+
<span class="diff-file-path">${j(e.path||this.currentFilePath||``)}</span>
|
|
344
|
+
</div>
|
|
345
|
+
`}renderDiffMarkup(e={}){if(typeof this.diffRenderer?.renderDiffDetail==`function`){let t=this.diffRenderer.mode;this.diffRenderer.mode=this.diffMode;let n=this.diffRenderer.renderDiffDetail(e,0,{includeHeader:!0});return this.diffRenderer.mode=t,n}return`
|
|
346
|
+
${this.renderDiffFileHeader(e)}
|
|
347
|
+
<div class="diff-empty-state">Diff renderer unavailable.</div>
|
|
348
|
+
`}syncToolbar(){let e=this.getSelectedDetailState(),t=e?.entry??null,n=e?.detail?.summary??t?.summary??(t?{additions:Number(t.additions||0),deletions:Number(t.deletions||0)}:null),r=!!t;this.syncToolbarIndicators(t,n,r),this.syncToolbarButtonStates(r)}syncToolbarIndicators(e,t,n){let r=Number(t?.additions||0),i=Number(t?.deletions||0);this.fileIndicator&&(this.fileIndicator.textContent=e?.type===`commit`?e.shortHash||`Commit`:e?.type===`local`?`Local changes`:`History`),this.stats&&(this.stats.innerHTML=`
|
|
349
|
+
<span class="ui-stat-token ui-stat-token--add diff-stats-add">+${r}</span>
|
|
350
|
+
<span class="ui-stat-token ui-stat-token--del diff-stats-del">-${i}</span>
|
|
351
|
+
`,this.stats.classList.toggle(`hidden`,!n))}syncToolbarButtonStates(e){this.backToHistoryButton?.classList.add(`hidden`),this.gitActionsGroup?.classList.add(`hidden`),this.layoutToggle?.classList.add(`hidden`),this.prevButton?.classList.add(`hidden`),this.nextButton?.classList.add(`hidden`),this.actionsDivider?.classList.add(`hidden`),this.editorActionsGroup?.classList.remove(`hidden`),this.modeButtons.forEach(t=>{let n=t.getAttribute(`data-diff-mode`)===this.diffMode;t.classList.toggle(`hidden`,!e),t.classList.toggle(`active`,n),t.setAttribute?.(`aria-pressed`,String(n))}),this.openEditorButton?.toggleAttribute(`disabled`,!this.currentFilePath),this.openEditorButton&&(this.openEditorButton.textContent=`Open file`),this.primaryActionButton?.toggleAttribute(`disabled`,!0),this.commitButton?.toggleAttribute(`disabled`,!0)}renderLoading(){this.isActive&&(this.page?.classList.remove(`hidden`),this.content&&(this.content.classList.add(`diff-content--history`),this.content.innerHTML=`<div class="git-panel-empty" role="status" aria-live="polite">Loading file history…</div>`),this.historyListElement=null,this.syncToolbar())}renderEmpty(e,{alert:t=!1}={}){this.isActive&&(this.page?.classList.remove(`hidden`),this.content&&(this.content.classList.add(`diff-content--history`),this.content.innerHTML=`<div class="git-panel-empty"${t?` role="alert"`:``}>${j(e)}</div>`),this.historyListElement=null,this.syncToolbar())}captureListScroll(){this.historyListElement&&(this.historyListScrollTop=Number(this.historyListElement.scrollTop||0))}restoreListScroll(){if(!this.content?.querySelector){this.historyListElement=null;return}let e=this.content.querySelector(`[data-file-history-list]`);this.historyListElement=e??null,e&&(e.scrollTop=this.historyListScrollTop,e.addEventListener(`scroll`,()=>{this.historyListScrollTop=Number(e.scrollTop||0)},{passive:!0}))}renderScopeLabels(e={}){let t=[];return e.hasStagedChanges&&t.push(`staged`),e.hasWorkingTreeChanges&&t.push(`working tree`),e.hasUntrackedChanges&&t.push(`untracked`),t.length>0?t.join(` · `):`working tree`}renderHistoryItem(e={}){let t=e.key===this.selectedEntryKey,n=Number(e.additions??e.summary?.additions??0),r=Number(e.deletions??e.summary?.deletions??0),i=e.type===`local`?`Live workspace`:Ns(e),a=e.type===`local`?`Local changes`:e.subject||e.shortHash||`Commit`,o=e.type===`local`?`<span class="ui-pill-badge ui-pill-badge--accent file-history-item-badge">Live</span>`:`<span class="ui-pill-badge ui-pill-badge--code file-history-item-badge">${j(e.shortHash||``)}</span>`;return`
|
|
352
|
+
<button
|
|
353
|
+
class="ui-record-surface file-history-item${t?` active`:``}${e.type===`local`?` file-history-item-local`:``}"
|
|
354
|
+
type="button"
|
|
355
|
+
data-file-history-select="${j(e.key)}"
|
|
356
|
+
aria-current="${t?`true`:`false`}"
|
|
357
|
+
>
|
|
358
|
+
<span class="file-history-item-top">
|
|
359
|
+
<span class="file-history-item-copy">
|
|
360
|
+
<span class="file-history-item-title">${j(a)}</span>
|
|
361
|
+
<span class="file-history-item-meta">${e.type===`local`?j(this.renderScopeLabels(e)):i}</span>
|
|
362
|
+
</span>
|
|
363
|
+
${o}
|
|
364
|
+
</span>
|
|
365
|
+
<span class="file-history-item-stats">
|
|
366
|
+
<span class="git-change-add">+${n}</span>
|
|
367
|
+
<span class="git-change-del">-${r}</span>
|
|
368
|
+
</span>
|
|
369
|
+
</button>
|
|
370
|
+
`}renderSelectedHeader(e){let t=e?.entry;return t?`
|
|
371
|
+
<div class="file-history-detail-header">
|
|
372
|
+
<div class="file-history-detail-copy">
|
|
373
|
+
<span class="file-history-detail-kicker">${t.type===`local`?`Live workspace`:`Commit ${j(t.shortHash||``)}`}</span>
|
|
374
|
+
<h2 class="file-history-detail-title">${t.type===`local`?`Local changes`:j(t.subject||t.shortHash||`Commit`)}</h2>
|
|
375
|
+
<p class="file-history-detail-meta">${t.type===`local`?j(this.renderScopeLabels(t)):Ns(t)}</p>
|
|
376
|
+
</div>
|
|
377
|
+
<div class="file-history-detail-actions">
|
|
378
|
+
<button
|
|
379
|
+
class="${k({variant:`secondary`,action:!0,surface:!0})}"
|
|
380
|
+
type="button"
|
|
381
|
+
data-file-history-open-selected-diff
|
|
382
|
+
>
|
|
383
|
+
Open standalone diff
|
|
384
|
+
</button>
|
|
385
|
+
${t.type===`commit`?`
|
|
386
|
+
<button
|
|
387
|
+
class="${k({variant:`primary`,action:!0})}"
|
|
388
|
+
type="button"
|
|
389
|
+
data-file-history-open-selected-preview
|
|
390
|
+
>
|
|
391
|
+
Preview file
|
|
392
|
+
</button>
|
|
393
|
+
`:``}
|
|
394
|
+
</div>
|
|
395
|
+
</div>
|
|
396
|
+
`:`
|
|
397
|
+
<div class="file-history-detail-header">
|
|
398
|
+
<div class="file-history-detail-copy">
|
|
399
|
+
<span class="file-history-detail-kicker">History</span>
|
|
400
|
+
<h2 class="file-history-detail-title">No selection</h2>
|
|
401
|
+
<p class="file-history-detail-meta">Choose a history item to inspect the file diff.</p>
|
|
402
|
+
</div>
|
|
403
|
+
</div>
|
|
404
|
+
`}renderSelectedBody(e){let t=e?.entry;return t?e.loading?`
|
|
405
|
+
<section class="diff-file-block file-history-diff-block">
|
|
406
|
+
<div class="diff-file-header">
|
|
407
|
+
<span class="diff-file-path">${j(t.pathAtCommit||this.currentFilePath||``)}</span>
|
|
408
|
+
</div>
|
|
409
|
+
<div class="diff-empty-state" role="status" aria-live="polite">Loading diff…</div>
|
|
410
|
+
</section>
|
|
411
|
+
`:e.error?`
|
|
412
|
+
<section class="diff-file-block file-history-diff-block">
|
|
413
|
+
${this.renderDiffFileHeader({path:t.pathAtCommit||this.currentFilePath||``})}
|
|
414
|
+
<div class="diff-empty-state" role="alert">${j(e.error)}</div>
|
|
415
|
+
</section>
|
|
416
|
+
`:e.detail?.detail?`
|
|
417
|
+
<section class="diff-file-block file-history-diff-block">
|
|
418
|
+
${this.renderDiffMarkup(e.detail.detail)}
|
|
419
|
+
</section>
|
|
420
|
+
`:`<div class="diff-empty-state">No diff available for this history item.</div>`:`<div class="diff-empty-state">Select a history entry to inspect this file.</div>`}render(){if(!this.isActive)return;if(this.page?.classList.remove(`hidden`),this.captureListScroll(),this.syncToolbar(),!this.currentFilePath){this.renderEmpty(`No file selected.`);return}if(this.history.loading&&!this.history.loaded){this.renderLoading();return}if(!(this.localChanges||(this.history.commits?.length??0)>0)){this.renderEmpty(this.history.error||`No history found for this file.`,{alert:!!this.history.error});return}if(!this.content)return;this.content.classList.add(`diff-content--history`);let e=this.getSelectedDetailState();this.content.innerHTML=`
|
|
421
|
+
<section class="file-history-shell">
|
|
422
|
+
<aside class="file-history-sidebar" aria-label="File history entries">
|
|
423
|
+
<header class="file-history-sidebar-header">
|
|
424
|
+
<span class="file-history-kicker">File history</span>
|
|
425
|
+
<div class="file-history-title">${Ms(this.currentFilePath)}</div>
|
|
426
|
+
<p class="file-history-sidebar-copy">Select an entry to inspect the exact changes for this file.</p>
|
|
427
|
+
</header>
|
|
428
|
+
<div class="file-history-list" data-file-history-list>
|
|
429
|
+
${this.getEntries().map(e=>this.renderHistoryItem(e)).join(``)}
|
|
430
|
+
</div>
|
|
431
|
+
${this.history.hasMore?`
|
|
432
|
+
<div class="git-history-footer file-history-footer">
|
|
433
|
+
<button
|
|
434
|
+
class="${k({variant:`secondary`,size:`compact`,action:!0,surface:!0,extra:`git-history-load-more`})}"
|
|
435
|
+
type="button"
|
|
436
|
+
data-file-history-load-more
|
|
437
|
+
${this.history.loadingMore?`disabled`:``}
|
|
438
|
+
>
|
|
439
|
+
${this.history.loadingMore?`Loading…`:`Load more`}
|
|
440
|
+
</button>
|
|
441
|
+
</div>
|
|
442
|
+
`:``}
|
|
443
|
+
</aside>
|
|
444
|
+
<section class="file-history-detail">
|
|
445
|
+
${this.renderSelectedHeader(e)}
|
|
446
|
+
<div class="file-history-detail-body">
|
|
447
|
+
${this.renderSelectedBody(e)}
|
|
448
|
+
</div>
|
|
449
|
+
</section>
|
|
450
|
+
</section>
|
|
451
|
+
`,this.restoreListScroll()}},Is=class{constructor({getLocalUser:e,getTheme:t,onAwarenessChange:n,onConnectionChange:r,onOpenFile:i,toastController:a}){this.getLocalUser=e,this.getTheme=t,this.onAwarenessChange=n,this.onConnectionChange=r,this.onOpenFile=i,this.toastController=a,this.iframe=null,this.filePath=null,this.ready=!1,this.pendingDisconnects=new Map,this.handleMessage=e=>this.onMessage(e)}mount(e,t){if(!t||this.filePath===e&&this.iframe?.isConnected)return;this.unmount();let n=new URL(je(`/canvas-editor.html`));n.searchParams.set(`file`,e),n.searchParams.set(`theme`,this.getTheme?.()??`dark`);let r=P();r&&n.searchParams.set(`vaultId`,r);let i=Pe();i&&n.searchParams.set(`server`,i);let a=this.getLocalUser?.();for(let[e,t]of Object.entries({userName:a?.name,userColor:a?.color,userColorLight:a?.colorLight,userPeerId:a?.peerId}))t&&n.searchParams.set(e,t);let o=document.createElement(`iframe`);o.className=`canvas-file-preview-frame`,o.title=`Canvas: ${e}`,o.src=n.toString(),this.filePath=e,this.iframe=o,window.addEventListener(`message`,this.handleMessage),t.replaceChildren(o),this.onConnectionChange?.({status:`connecting`,unreachable:!1})}unmount(){window.removeEventListener(`message`,this.handleMessage),this.pendingDisconnects.forEach(e=>e(!1)),this.iframe?.remove(),this.iframe=null,this.filePath=null,this.ready=!1}postMessage(e){this.iframe?.contentWindow?.postMessage(e,window.location.origin)}updateTheme(e){this.postMessage({type:`canvas-theme`,theme:e})}updateLocalUser(e=this.getLocalUser?.()){e&&this.postMessage({type:`canvas-user`,user:e})}prepareFileDisconnect(e,{timeoutMs:t=1e4}={}){if(e!==this.filePath||!this.iframe||!this.ready)return Promise.resolve(!0);let n=crypto.randomUUID();return new Promise(r=>{let i=setTimeout(()=>a(!1),t),a=e=>{clearTimeout(i),this.pendingDisconnects.delete(n),e||this.toastController?.show(`Waiting for the canvas to reconnect before leaving`),r(e)};this.pendingDisconnects.set(n,a),this.postMessage({type:`canvas-prepare-disconnect`,filePath:e,requestId:n})})}onMessage(e){if(e.origin!==window.location.origin||!this.iframe||e.source!==this.iframe.contentWindow)return;let t=e.data;if(t&&typeof t==`object`){if(t.type===`canvas-open-file`){if(typeof t.filePath==`string`&&t.filePath){let e=typeof t.subpath==`string`&&t.subpath.startsWith(`#`)?t.subpath.slice(1):null;this.onOpenFile?.(t.filePath,e?{anchor:e}:{})}return}t.filePath===this.filePath&&(t.type===`canvas-ready`?(this.ready=!0,this.updateTheme(this.getTheme?.()??`dark`),this.updateLocalUser()):t.type===`canvas-awareness`&&Array.isArray(t.users)?this.onAwarenessChange?.(t.users):t.type===`canvas-connection`&&[`connected`,`connecting`,`disconnected`].includes(t.state?.status)?this.onConnectionChange?.(t.state):(t.type===`canvas-disconnect-ready`||t.type===`canvas-disconnect-blocked`)&&this.pendingDisconnects.get(t.requestId)?.(t.type===`canvas-disconnect-ready`))}}},Ls=Object.freeze({".gif":`GIF`,".jpeg":`JPEG`,".jpg":`JPEG`,".png":`PNG`,".svg":`SVG`,".webp":`WebP`});function X(e=null){return e?.fileKind||_(e?.path)||null}function Rs(e=``){let t=String(e??``).toLowerCase(),n=t.lastIndexOf(`.`);return Ls[n>=0?t.slice(n):``]??`Image`}function Z(e=``){try{let t=JSON.parse(String(e??``));return!t||typeof t!=`object`||!Array.isArray(t.elements)?null:t}catch{return null}}function zs(e=[]){if(e.length===0)return null;let t=e.join(`
|
|
452
|
+
`);return Z(t)?t:e.find(e=>Z(e))??null}function Bs(e={}){let t=[],n=[];for(let r of e.hunks??[])for(let e of r.lines??[])e.type===`context`?(t.push(e.content),n.push(e.content)):e.type===`deletion`?t.push(e.content):e.type===`addition`&&n.push(e.content);let r=zs(t),i=zs(n),a=e.status===`added`||e.status===`untracked`,o=e.status===`deleted`;return{after:o?null:Z(i),before:a?null:Z(r),afterSource:o?``:i||``,beforeSource:a?``:r||``}}function Vs(e=null){return Array.isArray(e?.elements)?e.elements.filter(e=>e&&!e.isDeleted):[]}function Hs(e){if(!e||typeof e!=`object`)return``;let t={...e};return delete t.version,delete t.versionNonce,JSON.stringify(t)}function Us(e,t){if(!e&&!t)return null;let n=new Map(Vs(e).map(e=>[e.id,e])),r=new Map(Vs(t).map(e=>[e.id,e])),i=0,a=0,o=0;for(let[e,t]of r)n.has(e)?Hs(n.get(e))!==Hs(t)&&(o+=1):i+=1;for(let e of n.keys())r.has(e)||(a+=1);return{added:i,afterCount:r.size,beforeCount:n.size,removed:a,updated:o}}function Ws(e){let t=Number(e);return!Number.isFinite(t)||t<0?``:t<1024?`${t} B`:t<1048576?`${(t/1024).toFixed(+(t<10240))} KB`:`${(t/1048576).toFixed(1)} MB`}function Q(e){return/<(?:mxfile|mxGraphModel|diagram)\b/iu.test(String(e??``))}function Gs(e){return String(e??``).replace(/>\s*</gu,`>
|
|
453
|
+
<`).trim()}function Ks(e=[]){if(e.length===0)return``;let t=e.join(`
|
|
454
|
+
`);return Q(t)?t:e.find(e=>Q(e))??``}function qs(e={}){let t=[],n=[];for(let r of e.hunks??[])for(let e of r.lines??[])e.type===`context`?(t.push(e.content),n.push(e.content)):e.type===`deletion`?t.push(e.content):e.type===`addition`&&n.push(e.content);let r=typeof e.drawioBeforeSource==`string`?e.drawioBeforeSource:Ks(t),i=typeof e.drawioAfterSource==`string`?e.drawioAfterSource:Ks(n),a=e.status===`added`||e.status===`untracked`;return{after:e.status===`deleted`?``:i,before:a?``:r}}function Js(e){let t=new Map;if(typeof DOMParser>`u`||typeof XMLSerializer>`u`)return t;let n=new DOMParser().parseFromString(String(e??``),`application/xml`);if(n.querySelector(`parsererror`))return t;let r=new XMLSerializer;for(let e of n.getElementsByTagName(`mxCell`)){let n=e.getAttribute(`id`);n&&n!==`0`&&n!==`1`&&t.set(n,r.serializeToString(e).replace(/\s+/gu,` `).trim())}return t}function Ys(e){return/<mxGraphModel\b/iu.test(String(e??``))&&Js(e).size===0}function Xs(e,t){if(!e&&!t)return null;let n=Js(e),r=Js(t),i=n.size>0||r.size>0,a=0,o=0,s=0;if(i){for(let[e,t]of r)n.has(e)?n.get(e)!==t&&(s+=1):a+=1;for(let e of n.keys())r.has(e)||(o+=1);e!==t&&a===0&&o===0&&s===0&&(s=1)}else{let n=!!e,r=!!t;a=!n&&r?1:0,o=n&&!r?1:0,s=n&&r&&e!==t?1:0}return{added:a,afterCount:r.size,beforeCount:n.size,cellBased:i,removed:o,updated:s}}function Zs(e){return`diff-section-${encodeURIComponent(String(e??``)).replace(/%/g,`_`)}`}function Qs(e){switch(e){case`added`:case`untracked`:return`ui-status-badge--success`;case`deleted`:return`ui-status-badge--danger`;case`renamed`:return`ui-status-badge--accent`;default:return`ui-status-badge--warning`}}function $s(e=!1){return`<svg class="diff-section-chevron${e?` collapsed`:``}" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" aria-hidden="true"><polyline points="6 9 12 15 18 9"/></svg>`}function ec(e,t){let n=0;for(;n<e.length&&n<t.length&&e[n]===t[n];)n+=1;return n}function tc(e,t,n){let r=0,i=Math.min(e.length,t.length)-n;for(;r<i;){let n=e.length-1-r,i=t.length-1-r;if(e[n]!==t[i])break;r+=1}return r}function nc(e,t){let n=ec(e,t),r=tc(e,t,n),i=Math.max(n,e.length-r),a=Math.max(n,t.length-r);return{leftHtml:`${j(e.slice(0,n))}${i>n?`<span class="diff-highlight-del">${j(e.slice(n,i))}</span>`:``}${j(e.slice(i))}`,rightHtml:`${j(t.slice(0,n))}${a>n?`<span class="diff-highlight-add">${j(t.slice(n,a))}</span>`:``}${j(t.slice(a))}`}}function rc(e=[]){let t=[];for(let n=0;n<e.length;n+=1){let r=e[n];if(r.type===`context`||r.type===`note`){t.push({additions:[],context:[r],deletions:[]});continue}if(r.type!==`deletion`&&r.type!==`addition`)continue;let i=[],a=[];for(;n<e.length&&e[n].type===`deletion`;)i.push(e[n]),n+=1;for(;n<e.length&&e[n].type===`addition`;)a.push(e[n]),n+=1;--n,t.push({additions:a,context:[],deletions:i})}return t}function ic(e,t,n){let r=Number.isInteger(e.oldLine)?e.oldLine:``,i=Number.isInteger(e.newLine)?e.newLine:``,a=e.type===`note`?`note`:e.type,o=e.type===`context`||e.type===`note`?` `:t;return`
|
|
455
|
+
<div class="diff-line ${a}">
|
|
456
|
+
<div class="diff-line-numbers">
|
|
457
|
+
<span class="diff-line-num">${r}</span>
|
|
458
|
+
<span class="diff-line-num">${i}</span>
|
|
459
|
+
</div>
|
|
460
|
+
<div class="diff-line-prefix">${j(o)}</div>
|
|
461
|
+
<div class="diff-line-content">${n}</div>
|
|
462
|
+
</div>
|
|
463
|
+
`}function ac(e,t){let n=e?j(e.content):``,r=t?j(t.content):``;if(e&&t&&e.type===`deletion`&&t.type===`addition`){let i=nc(e.content,t.content);n=i.leftHtml,r=i.rightHtml}return`
|
|
464
|
+
<div class="diff-split-row">
|
|
465
|
+
<div class="diff-split-line ${e?.type||`empty`}">
|
|
466
|
+
<span class="diff-split-num">${Number.isInteger(e?.oldLine)?e.oldLine:``}</span>
|
|
467
|
+
<span class="diff-split-content">${n}</span>
|
|
468
|
+
</div>
|
|
469
|
+
<div class="diff-split-line ${t?.type||`empty`}">
|
|
470
|
+
<span class="diff-split-num">${Number.isInteger(t?.newLine)?t.newLine:``}</span>
|
|
471
|
+
<span class="diff-split-content">${r}</span>
|
|
472
|
+
</div>
|
|
473
|
+
</div>
|
|
474
|
+
`}var oc=class{constructor({getTheme:e=()=>`dark`,gitApiClient:t=null,onBackToHistory:n=null,onCommitStaged:r=null,onOpenFile:i=null,onStageFile:a=null,onUnstageFile:o=null,toastController:s=null,vaultApiClient:c=null}={}){this.getTheme=e,this.gitApiClient=t,this.onBackToHistory=n,this.onCommitStaged=r,this.onOpenFile=i,this.onStageFile=a,this.onUnstageFile=o,this.toastController=s,this.vaultApiClient=c,this.page=document.getElementById(`diff-page`),this.content=document.getElementById(`diffContent`),this.scrollContainer=document.getElementById(`diffScroll`),this.fileIndicator=document.getElementById(`diffFileIndicator`),this.openEditorButton=document.getElementById(`diffOpenEditorBtn`),this.primaryActionButton=document.getElementById(`diffPrimaryActionBtn`),this.commitButton=document.getElementById(`diffCommitBtn`),this.backToHistoryButton=document.getElementById(`diffBackToHistoryBtn`),this.gitActionsGroup=document.getElementById(`diffGitActionsGroup`),this.editorActionsGroup=document.getElementById(`diffEditorActionsGroup`),this.actionsDivider=document.getElementById(`diffToolbarDivider`),this.stats=document.getElementById(`diffStats`),this.prevButton=document.getElementById(`diffPrevBtn`),this.nextButton=document.getElementById(`diffNextBtn`),this.layoutToggle=document.getElementById(`diffLayoutToggle`),this.modeButtons=Array.from(document.querySelectorAll(`[data-diff-mode]`)),this.layoutButtons=Array.from(document.querySelectorAll(`[data-diff-layout]`)),this.isActive=!1,this.mode=`unified`,this.layoutMode=`focused`,this.source=`workspace`,this.data=null,this.currentIndex=0,this.activeFilePath=null,this.workspaceFilePath=null,this.fileCache=new Map,this.fileErrors=new Map,this.loadingFiles=new Set,this.collapsedFiles=new Set,this.fileLoadPromises=new Map,this.excalidrawPreviewPayloads=new Map,this.excalidrawPreviewCounter=0,this.drawioPreviewPayloads=new Map,this.drawioPreviewCounter=0,this.requestScope=`all`,this.commitHash=null,this.commitBaseRef=null,this.commitMeta=null,this.historyFilePath=null,this.pendingAction=null,this.repoStatus=null}initialize(){this.prevButton?.addEventListener(`click`,()=>{this.isActive&&this.navigateFile(-1)}),this.nextButton?.addEventListener(`click`,()=>{this.isActive&&this.navigateFile(1)}),this.backToHistoryButton?.addEventListener(`click`,()=>{this.isActive&&this.commitMeta?.hash&&this.onBackToHistory?.({hash:this.commitMeta.hash,historyFilePath:this.historyFilePath})}),this.openEditorButton?.addEventListener(`click`,()=>{if(!this.isActive||this.source!==`workspace`)return;let e=this.getCurrentFile()?.path??this.workspaceFilePath;e&&this.onOpenFile?.(e)}),this.primaryActionButton?.addEventListener(`click`,()=>{if(!this.isActive)return;let e=this.getPrimaryAction();e&&this.handleFileAction(e)}),this.commitButton?.addEventListener(`click`,()=>{this.isActive&&this.handleFileAction(`commit`)}),this.content?.addEventListener(`click`,e=>{if(!this.isActive)return;let t=e.target instanceof Element?e.target.closest(`[data-load-full-diff]`):null;if(t){let e=t.getAttribute(`data-diff-file-path`)||this.activeFilePath;e&&this.loadFileForPath(e,{forceFullPatch:!0});return}let n=e.target instanceof Element?e.target.closest(`[data-diff-section-toggle]`):null;if(n){let e=n.getAttribute(`data-diff-section-toggle`);e&&this.toggleFileSection(e);return}let r=e.target instanceof Element?e.target.closest(`[data-diff-index-path]`):null;if(r){let e=r.getAttribute(`data-diff-index-path`);e&&this.handleIndexSelection(e)}}),this.modeButtons.forEach(e=>{e.addEventListener(`click`,()=>{if(!this.isActive)return;let t=e.getAttribute(`data-diff-mode`);t&&t!==this.mode&&(this.mode=t,this.render())})}),this.layoutButtons.forEach(e=>{e.addEventListener(`click`,()=>{if(!this.isActive)return;let t=e.getAttribute(`data-diff-layout`);t&&t!==this.layoutMode&&this.setLayoutMode(t)})}),this.scrollContainer?.addEventListener(`scroll`,()=>{this.isActive&&this.handleScrollSelection()})}hide(){this.isActive=!1,this.page?.classList.add(`hidden`),this.content&&(this.content.innerHTML=``),this.data=null,this.source=`workspace`,this.layoutMode=`focused`,this.currentIndex=0,this.activeFilePath=null,this.workspaceFilePath=null,this.fileCache.clear(),this.fileErrors.clear(),this.loadingFiles.clear(),this.collapsedFiles.clear(),this.fileLoadPromises.clear(),this.excalidrawPreviewPayloads.clear(),this.drawioPreviewPayloads.clear(),this.requestScope=`all`,this.commitHash=null,this.commitBaseRef=null,this.commitMeta=null,this.historyFilePath=null,this.pendingAction=null}async openWorkspaceDiff({filePath:e=null,scope:t=`all`}={}){this.isActive=!0,this.source=`workspace`,this.layoutMode=`focused`,this.commitHash=null,this.commitBaseRef=null,this.commitMeta=null,this.historyFilePath=null,this.activeFilePath=e,this.workspaceFilePath=e,this.fileCache.clear(),this.fileErrors.clear(),this.loadingFiles.clear(),this.collapsedFiles.clear(),this.fileLoadPromises.clear(),this.excalidrawPreviewPayloads.clear(),this.drawioPreviewPayloads.clear(),this.requestScope=t,this.renderLoading(`Loading diff summary…`);try{let n=await this.gitApiClient.readDiff({metaOnly:!0,path:e,scope:t});this.data=n;let r=e?Math.max(0,n.files.findIndex(t=>t.path===e)):0;return this.currentIndex=r,this.activeFilePath=n.files?.[r]?.path??null,(n.files?.length??0)===0?(this.render(),n):(await this.loadCurrentFile(),n)}catch(e){return console.error(`[git-diff] Failed to load diff:`,e),this.toastController?.show(`Failed to load git diff`),this.data={files:[],metaOnly:!1,source:`workspace`,summary:{additions:0,deletions:0,filesChanged:0}},this.renderEmpty(`Failed to load git diff`,{alert:!0}),this.data}}async openCommitDiff({hash:e,path:t=null,historyFilePath:n=null}={}){this.isActive=!0,this.source=`commit`,this.layoutMode=`stacked`,this.commitHash=String(e??``).trim()||null,this.commitBaseRef=null,this.commitMeta=null,this.historyFilePath=String(n??``).trim()||null,this.activeFilePath=t||null,this.workspaceFilePath=null,this.fileCache.clear(),this.fileErrors.clear(),this.loadingFiles.clear(),this.collapsedFiles.clear(),this.fileLoadPromises.clear(),this.excalidrawPreviewPayloads.clear(),this.drawioPreviewPayloads.clear(),this.requestScope=`all`,this.renderLoading(`Loading commit summary…`);try{let e=await this.gitApiClient.readCommit({hash:this.commitHash||``,metaOnly:!0});this.data=e,this.commitMeta=e.commit??null,this.commitBaseRef=e.baseRef||null;let n=t?Math.max(0,e.files.findIndex(e=>e.path===t)):0;return this.currentIndex=n,this.activeFilePath=e.files?.[n]?.path??null,this.collapsedFiles=new Set((e.files??[]).map(e=>e.path).filter(e=>e&&e!==this.activeFilePath)),(e.files?.length??0)===0?(this.render(),e):(this.activeFilePath&&await this.loadFileForPath(this.activeFilePath,{render:!1}),this.render(),e)}catch(e){return console.error(`[git-diff] Failed to load commit:`,e),this.toastController?.show(`Failed to load git commit`),this.data={commit:null,files:[],metaOnly:!1,source:`commit`,summary:{additions:0,deletions:0,filesChanged:0}},this.commitMeta=null,this.renderEmpty(`Failed to load git commit`,{alert:!0}),this.data}}async open(e={}){return this.openWorkspaceDiff(e)}async setLayoutMode(e){let t=e===`stacked`?`stacked`:`focused`;if(this.source!==`commit`){this.layoutMode=`focused`,this.render();return}if(this.layoutMode=t,this.activeFilePath&&this.setActiveFilePath(this.activeFilePath),this.layoutMode===`focused`){await this.loadCurrentFile();return}this.activeFilePath&&(this.collapsedFiles.delete(this.activeFilePath),await this.loadFileForPath(this.activeFilePath,{render:!1})),this.render()}navigateFile(e){if(!this.data?.files?.length||this.source===`commit`&&this.layoutMode===`stacked`)return;let t=Math.max(0,Math.min(this.currentIndex+e,this.data.files.length-1));t!==this.currentIndex&&(this.currentIndex=t,this.activeFilePath=this.data.files[t]?.path??null,this.scrollContainer?.scrollTo({top:0,behavior:`auto`}),this.loadCurrentFile())}renderLoading(e=`Loading git diff…`){this.isActive&&(this.page?.classList.remove(`hidden`),this.content&&(this.content.innerHTML=`<div class="diff-empty-state" role="status" aria-live="polite">${j(e)}</div>`),this.data=null,this.syncToolbar())}renderEmpty(e,{alert:t=!1}={}){this.isActive&&(this.page?.classList.remove(`hidden`),this.content&&(this.content.innerHTML=`<div class="diff-empty-state"${t?` role="alert"`:``}>${j(e)}</div>`),this.syncToolbar())}renderUnifiedHunk(e){let t=[];for(let n of rc(e.lines)){if(n.context.length>0){for(let e of n.context)t.push(ic(e,` `,j(e.content)));continue}let e=Math.max(n.deletions.length,n.additions.length);for(let r=0;r<e;r+=1){let e=n.deletions[r]??null,i=n.additions[r]??null,a=e&&i?nc(e.content,i.content):null;e&&t.push(ic(e,`-`,a?.leftHtml??j(e.content))),i&&t.push(ic(i,`+`,a?.rightHtml??j(i.content)))}}return`
|
|
475
|
+
<div class="diff-hunk-header">${j(e.header)}</div>
|
|
476
|
+
${t.join(``)}
|
|
477
|
+
`}getGitImageUrl(e,t){return!e||!t?``:typeof this.gitApiClient?.getFileAttachmentUrl==`function`?this.gitApiClient.getFileAttachmentUrl({hash:e,path:t}):N(`/git/file-attachment?hash=${encodeURIComponent(e)}&path=${encodeURIComponent(t)}`)}getCurrentImageUrl(e){return e?N(`/attachment?path=${encodeURIComponent(e)}`):``}getImageDiffSources(e){let t=e.status===`added`||e.status===`untracked`,n=e.status===`deleted`,r=e.oldPath||e.path,i=e.path;return this.source===`commit`?{after:n?``:this.getGitImageUrl(this.commitHash,i),before:t?``:this.getGitImageUrl(this.commitBaseRef,r)}:{after:n?``:this.getCurrentImageUrl(i),before:t?``:this.getGitImageUrl(`HEAD`,r)}}renderImagePane({file:e,label:t,source:n,emptyLabel:r}){let i=n?`<img class="diff-media-image" src="${j(n)}" alt="${j(`${t} ${e.path}`)}" loading="lazy" decoding="async">`:`<div class="diff-media-empty"><span class="diff-media-empty-icon" aria-hidden="true">—</span><span>${j(r)}</span></div>`;return`
|
|
478
|
+
<div class="diff-media-pane">
|
|
479
|
+
<div class="diff-media-pane-header">
|
|
480
|
+
<span class="diff-media-pane-label">${j(t)}</span>
|
|
481
|
+
<span class="diff-media-pane-meta">${j(Rs(e.path))}</span>
|
|
482
|
+
</div>
|
|
483
|
+
<div class="diff-media-canvas">${i}</div>
|
|
484
|
+
</div>
|
|
485
|
+
`}renderImageDiff(e){let t=this.getImageDiffSources(e),n=Ws(e.byteLength);return`
|
|
486
|
+
<section class="diff-special diff-media-diff" aria-label="Image diff">
|
|
487
|
+
<div class="diff-special-header">
|
|
488
|
+
<div>
|
|
489
|
+
<span class="diff-special-eyebrow">Binary preview</span>
|
|
490
|
+
<h2 class="diff-special-title">Image comparison</h2>
|
|
491
|
+
</div>
|
|
492
|
+
<span class="diff-special-note">${j(Rs(e.path))}${n?` · ${j(n)}`:``}</span>
|
|
493
|
+
</div>
|
|
494
|
+
<div class="diff-media-grid">
|
|
495
|
+
${this.renderImagePane({emptyLabel:`No previous image`,file:e,label:`Before`,source:t.before})}
|
|
496
|
+
${this.renderImagePane({emptyLabel:`No image in this revision`,file:e,label:`After`,source:t.after})}
|
|
497
|
+
</div>
|
|
498
|
+
<p class="diff-special-footnote">Image bytes are shown as a visual comparison instead of a text patch.</p>
|
|
499
|
+
</section>
|
|
500
|
+
`}registerExcalidrawPreview(e){if(!e)return``;this.excalidrawPreviewCounter+=1;let t=`diff-excalidraw-preview-${this.excalidrawPreviewCounter.toString(36)}`;return this.excalidrawPreviewPayloads.set(t,e),t}renderExcalidrawPane({label:e,scene:t,source:n,emptyLabel:r}){let i=this.registerExcalidrawPreview(t),a=t?`
|
|
501
|
+
<div class="diff-excalidraw-preview" data-diff-excalidraw-preview="${j(i)}">
|
|
502
|
+
<span class="diff-excalidraw-preview-loading">Rendering diagram…</span>
|
|
503
|
+
</div>
|
|
504
|
+
`:`<div class="diff-excalidraw-preview diff-excalidraw-preview--empty"><span>${j(r)}</span></div>`,o=n?`
|
|
505
|
+
<details class="diff-excalidraw-source">
|
|
506
|
+
<summary>Structured scene</summary>
|
|
507
|
+
<pre>${j(n)}</pre>
|
|
508
|
+
</details>
|
|
509
|
+
`:``;return`
|
|
510
|
+
<div class="diff-excalidraw-pane">
|
|
511
|
+
<div class="diff-excalidraw-pane-header">
|
|
512
|
+
<span class="diff-media-pane-label">${j(e)}</span>
|
|
513
|
+
<span class="diff-media-pane-meta">${t?`${Vs(t).length} elements`:`—`}</span>
|
|
514
|
+
</div>
|
|
515
|
+
${a}
|
|
516
|
+
${o}
|
|
517
|
+
</div>
|
|
518
|
+
`}renderExcalidrawDiff(e){let t=Bs(e),n=Us(t.before,t.after)??{added:0,afterCount:0,beforeCount:0,removed:0,updated:0},r=!!(t.before||t.after),i=e.tooLarge&&e.canLoadFullPatch?`<button class="${k({variant:`secondary`,extra:`diff-load-full-btn`})}" type="button" data-load-full-diff data-diff-file-path="${j(e.path)}">Load full diff</button>`:``;return`
|
|
519
|
+
<section class="diff-special diff-excalidraw-diff" aria-label="Excalidraw diff">
|
|
520
|
+
<div class="diff-special-header">
|
|
521
|
+
<div>
|
|
522
|
+
<span class="diff-special-eyebrow">Diagram-aware preview</span>
|
|
523
|
+
<h2 class="diff-special-title">Excalidraw scene changes</h2>
|
|
524
|
+
</div>
|
|
525
|
+
<span class="diff-special-note">${r?`${n.afterCount} visible elements`:`Scene preview unavailable`}</span>
|
|
526
|
+
</div>
|
|
527
|
+
<div class="diff-scene-summary" aria-label="Scene change summary">
|
|
528
|
+
<span class="diff-scene-stat diff-scene-stat--add"><strong>+${n.added}</strong><span>added</span></span>
|
|
529
|
+
<span class="diff-scene-stat diff-scene-stat--update"><strong>~${n.updated}</strong><span>updated</span></span>
|
|
530
|
+
<span class="diff-scene-stat diff-scene-stat--remove"><strong>-${n.removed}</strong><span>removed</span></span>
|
|
531
|
+
</div>
|
|
532
|
+
<div class="diff-excalidraw-grid">
|
|
533
|
+
${this.renderExcalidrawPane({emptyLabel:`No previous scene`,label:`Before`,scene:t.before,source:t.beforeSource?JSON.stringify(t.before||Z(t.beforeSource),null,2):``})}
|
|
534
|
+
${this.renderExcalidrawPane({emptyLabel:e.tooLarge?`Load the full diff to preview this scene`:`No scene in this revision`,label:`After`,scene:t.after,source:t.afterSource?JSON.stringify(t.after||Z(t.afterSource),null,2):``})}
|
|
535
|
+
</div>
|
|
536
|
+
${i}
|
|
537
|
+
<p class="diff-special-footnote">The preview compares drawable elements by id; expand “Structured scene” when you need the underlying JSON.</p>
|
|
538
|
+
</section>
|
|
539
|
+
`}async readDrawioSource({hash:e=null,path:t=null,current:n=!1}={}){if(!t)return``;try{if(n){let e=await this.vaultApiClient?.readFile?.(t);return typeof e?.content==`string`?e.content:``}if(!e||typeof this.gitApiClient?.readFileSnapshot!=`function`)return``;let r=await this.gitApiClient.readFileSnapshot({hash:e,path:t});return typeof r?.content==`string`?r.content:``}catch{return``}}async enrichDrawioDetail(e){let t=qs(e),n=t.before,r=t.after,i=e.status===`added`||e.status===`untracked`,a=e.status===`deleted`,o=e.oldPath||e.path,s=e.path;return!i&&!Q(n)&&(n=await this.readDrawioSource({current:!1,hash:this.source===`commit`?this.commitBaseRef:`HEAD`,path:o})),!a&&!Q(r)&&(r=await this.readDrawioSource({current:this.source!==`commit`,hash:this.source===`commit`?this.commitHash:null,path:s})),{...e,drawioAfterSource:r,drawioBeforeSource:n}}registerDrawioPreview(e){if(!e)return``;this.drawioPreviewCounter+=1;let t=`diff-drawio-preview-${this.drawioPreviewCounter.toString(36)}`;return this.drawioPreviewPayloads.set(t,e),t}renderDrawioPane({emptyLabel:e,label:t,source:n}){let r=Ys(n),i=r?``:this.registerDrawioPreview(n),a=n&&!r?`
|
|
540
|
+
<div class="diff-drawio-preview" data-diff-drawio-preview="${j(i)}">
|
|
541
|
+
<span class="diff-drawio-preview-loading">Rendering draw.io preview…</span>
|
|
542
|
+
</div>
|
|
543
|
+
`:`<div class="diff-drawio-preview diff-drawio-preview--empty"><span>${j(r?`No drawable cells`:e)}</span></div>`,o=n?`
|
|
544
|
+
<details class="diff-drawio-source">
|
|
545
|
+
<summary>XML source</summary>
|
|
546
|
+
<pre>${j(Gs(n))}</pre>
|
|
547
|
+
</details>
|
|
548
|
+
`:``;return`
|
|
549
|
+
<div class="diff-drawio-pane">
|
|
550
|
+
<div class="diff-drawio-pane-header">
|
|
551
|
+
<span class="diff-media-pane-label">${j(t)}</span>
|
|
552
|
+
<span class="diff-media-pane-meta">draw.io</span>
|
|
553
|
+
</div>
|
|
554
|
+
${a}
|
|
555
|
+
${o}
|
|
556
|
+
</div>
|
|
557
|
+
`}renderDrawioDiff(e){let t=qs(e),n=Xs(t.before,t.after)??{added:0,afterCount:0,beforeCount:0,cellBased:!1,removed:0,updated:0},r=t.before||t.after?n.cellBased?`${n.afterCount} drawable cells`:`Source-level comparison`:`Preview unavailable`,i=e.tooLarge&&e.canLoadFullPatch?`<button class="${k({variant:`secondary`,extra:`diff-load-full-btn`})}" type="button" data-load-full-diff data-diff-file-path="${j(e.path)}">Load full diff</button>`:``;return`
|
|
558
|
+
<section class="diff-special diff-drawio-diff" aria-label="draw.io diff">
|
|
559
|
+
<div class="diff-special-header">
|
|
560
|
+
<div>
|
|
561
|
+
<span class="diff-special-eyebrow">Diagram-aware preview</span>
|
|
562
|
+
<h2 class="diff-special-title">draw.io diagram changes</h2>
|
|
563
|
+
</div>
|
|
564
|
+
<span class="diff-special-note">${j(r)}</span>
|
|
565
|
+
</div>
|
|
566
|
+
<div class="diff-scene-summary" aria-label="draw.io change summary">
|
|
567
|
+
<span class="diff-scene-stat diff-scene-stat--add"><strong>+${n.added}</strong><span>added</span></span>
|
|
568
|
+
<span class="diff-scene-stat diff-scene-stat--update"><strong>~${n.updated}</strong><span>updated</span></span>
|
|
569
|
+
<span class="diff-scene-stat diff-scene-stat--remove"><strong>-${n.removed}</strong><span>removed</span></span>
|
|
570
|
+
</div>
|
|
571
|
+
<div class="diff-drawio-grid">
|
|
572
|
+
${this.renderDrawioPane({emptyLabel:`No previous diagram`,label:`Before`,source:t.before})}
|
|
573
|
+
${this.renderDrawioPane({emptyLabel:e.tooLarge?`Load the full diff to preview this diagram`:`No diagram in this revision`,label:`After`,source:t.after})}
|
|
574
|
+
</div>
|
|
575
|
+
${i}
|
|
576
|
+
<p class="diff-special-footnote">Both revisions use the draw.io viewer; expand “XML source” when you need the underlying document.</p>
|
|
577
|
+
</section>
|
|
578
|
+
`}async hydrateExcalidrawPreviews(){if(this.excalidrawPreviewPayloads.size===0||!this.content)return;let e;try{({exportToSvg:e}=await A(()=>import(`./prod-rdly4JJQ.js`),[],import.meta.url))}catch(e){console.warn(`[git-diff] Excalidraw preview renderer unavailable:`,e);return}for(let[t,n]of this.excalidrawPreviewPayloads){let r=this.content.querySelector?.(`[data-diff-excalidraw-preview="${t}"]`);if(r)try{let t=await e(Ye(n));r.replaceChildren(t),r.classList.add(`is-ready`)}catch(e){console.warn(`[git-diff] Failed to render Excalidraw scene preview:`,e),r.textContent=`Visual preview unavailable`,r.classList.add(`is-error`)}}}async hydrateDrawioPreviews(){if(this.drawioPreviewPayloads.size!==0&&this.content)for(let[e,t]of this.drawioPreviewPayloads){let n=this.content.querySelector?.(`[data-diff-drawio-preview="${e}"]`);if(n)try{await Te(n,{ariaLabel:`draw.io diagram diff preview`,className:`mxgraph drawio-viewer-frame diff-drawio-viewer-frame`,source:t,theme:this.getTheme?.()===`light`?`light`:`dark`}),n.classList.add(`is-ready`)}catch(e){console.warn(`[git-diff] Failed to render draw.io diagram preview:`,e),n.textContent=`Visual preview unavailable`,n.classList.add(`is-error`)}}}renderFileHeader(e){let t=X(e)===`image`?`<span class="diff-file-header-kind">${j(Rs(e.path))} image</span>`:`<span class="diff-file-header-stats"><span class="ui-stat-token ui-stat-token--add diff-stats-add">+${e.stats?.additions??0}</span><span class="ui-stat-token ui-stat-token--del diff-stats-del">-${e.stats?.deletions??0}</span></span>`,n=e.hasStagedChanges?`<span class="ui-pill-badge ui-pill-badge--muted" aria-label="Included in next commit">✓ Included</span>`:``;return`
|
|
579
|
+
<div class="diff-file-header">
|
|
580
|
+
<span class="diff-file-path">${j(e.path)}</span>
|
|
581
|
+
<span class="ui-status-badge ${Qs(e.status)}">${j(e.status)}</span>
|
|
582
|
+
${n}
|
|
583
|
+
${t}
|
|
584
|
+
</div>
|
|
585
|
+
`}renderUnifiedFileBody(e){return`
|
|
586
|
+
${e.isBinary?`<div class="diff-binary-message">${j(e.binaryMessage||`Binary file changed`)}</div>`:``}
|
|
587
|
+
${e.hunks.map(e=>this.renderUnifiedHunk(e)).join(``)}
|
|
588
|
+
`}renderSplitFileBody(e){return`
|
|
589
|
+
<div class="diff-split">
|
|
590
|
+
<div class="diff-split-pane">
|
|
591
|
+
<div class="diff-split-pane-header">Before</div>
|
|
592
|
+
${e.hunks.map(e=>{let t=[];for(let n of rc(e.lines)){if(n.context.length>0){for(let e of n.context)t.push(ac(e,e));continue}let e=Math.max(n.deletions.length,n.additions.length);for(let r=0;r<e;r+=1)t.push(ac(n.deletions[r]??null,n.additions[r]??null))}return`
|
|
593
|
+
<div class="diff-split-hunk">${j(e.header)}</div>
|
|
594
|
+
${t.join(``)}
|
|
595
|
+
`}).join(``)}
|
|
596
|
+
</div>
|
|
597
|
+
</div>
|
|
598
|
+
`}renderDiffDetail(e,t,{includeHeader:n=!0}={}){if(!e)return`<div class="diff-empty-state">Select a file to load its diff.</div>`;let r=X(e);if(r===`image`)return`${n?this.renderFileHeader(e):``}${this.renderImageDiff(e)}`;if(r===`excalidraw`)return`${n?this.renderFileHeader(e):``}${this.renderExcalidrawDiff(e)}`;if(r===`drawio`)return`${n?this.renderFileHeader(e):``}${this.renderDrawioDiff(e)}`;if(e.tooLarge)return`
|
|
599
|
+
${n?this.renderFileHeader(e):``}
|
|
600
|
+
<div class="diff-limit-card">
|
|
601
|
+
<strong>Large diff withheld</strong>
|
|
602
|
+
<span>This file diff is large enough to impact rendering performance.</span>
|
|
603
|
+
<button class="${k({variant:`secondary`,extra:`diff-load-full-btn`})}" type="button" data-load-full-diff data-diff-file-path="${j(e.path)}">Load full diff</button>
|
|
604
|
+
</div>
|
|
605
|
+
`;let i=this.mode===`split`?this.renderSplitFileBody(e,t):this.renderUnifiedFileBody(e,t);return`${n?this.renderFileHeader(e):``}${i}`}renderFocusedFileBody(){let e=this.getCurrentFile();if(!e)return`<div class="diff-empty-state">No changes to display.</div>`;if(this.isFileLoading(e.path))return`
|
|
606
|
+
<section class="diff-file-block">
|
|
607
|
+
${this.renderFileHeader(e)}
|
|
608
|
+
<div class="diff-empty-state" role="status" aria-live="polite">Loading file diff…</div>
|
|
609
|
+
</section>
|
|
610
|
+
`;let t=this.fileErrors.get(e.path);return t?`
|
|
611
|
+
<section class="diff-file-block">
|
|
612
|
+
${this.renderFileHeader(e)}
|
|
613
|
+
<div class="diff-empty-state" role="alert">${j(t)}</div>
|
|
614
|
+
</section>
|
|
615
|
+
`:`
|
|
616
|
+
<section class="diff-file-block" data-diff-file-index="${this.currentIndex}">
|
|
617
|
+
${this.renderDiffDetail(this.getFileDetail(e.path)??e,this.currentIndex)}
|
|
618
|
+
</section>
|
|
619
|
+
`}renderCommitHeader(){return this.source!==`commit`||!this.commitMeta?``:`
|
|
620
|
+
<section class="diff-commit-header">
|
|
621
|
+
<div class="diff-commit-subject">${j(this.commitMeta.subject||this.commitMeta.shortHash||`Commit`)}</div>
|
|
622
|
+
<div class="diff-commit-meta">
|
|
623
|
+
<span>${j(this.commitMeta.shortHash||``)}</span>
|
|
624
|
+
<span>${j(this.commitMeta.authorName||`Unknown`)}</span>
|
|
625
|
+
<span title="${j(this.commitMeta.authoredAt||``)}">${j(this.commitMeta.relativeDateLabel||``)}</span>
|
|
626
|
+
${this.commitMeta.isMergeCommit?`<span>Merge commit</span>`:``}
|
|
627
|
+
</div>
|
|
628
|
+
<div class="diff-commit-meta diff-commit-meta-secondary">
|
|
629
|
+
<span>${j(this.commitMeta.hash||``)}</span>
|
|
630
|
+
<span>${Number(this.data?.summary?.filesChanged||0)} file${Number(this.data?.summary?.filesChanged||0)===1?``:`s`}</span>
|
|
631
|
+
</div>
|
|
632
|
+
</section>
|
|
633
|
+
`}renderCommitIndex(){return`
|
|
634
|
+
<aside class="diff-commit-index" aria-label="Changed files in commit">
|
|
635
|
+
<div class="diff-commit-index-header">Changed Files</div>
|
|
636
|
+
<div class="diff-commit-index-list">
|
|
637
|
+
${(this.data?.files??[]).map((e,t)=>{let n=this.activeFilePath===e.path,r=w(e.path);return`
|
|
638
|
+
<button
|
|
639
|
+
class="ui-record-surface diff-index-item${n?` active`:``}"
|
|
640
|
+
type="button"
|
|
641
|
+
data-diff-index-path="${j(e.path)}"
|
|
642
|
+
aria-current="${n?`true`:`false`}"
|
|
643
|
+
>
|
|
644
|
+
<span class="ui-record-header diff-index-item-top">
|
|
645
|
+
<span class="ui-record-title diff-index-item-name">${j(C(e.path))}</span>
|
|
646
|
+
<span class="ui-status-badge ${Qs(e.status)}">${j(e.status)}</span>
|
|
647
|
+
</span>
|
|
648
|
+
${r?`<span class="ui-record-subtitle diff-index-item-path">${j(r)}</span>`:``}
|
|
649
|
+
<span class="ui-record-meta diff-index-item-meta">
|
|
650
|
+
<span>${t+1}</span>
|
|
651
|
+
<span class="ui-stat-token ui-stat-token--add diff-stats-add">+${e.stats?.additions??0}</span>
|
|
652
|
+
<span class="ui-stat-token ui-stat-token--del diff-stats-del">-${e.stats?.deletions??0}</span>
|
|
653
|
+
</span>
|
|
654
|
+
</button>
|
|
655
|
+
`}).join(``)}
|
|
656
|
+
</div>
|
|
657
|
+
</aside>
|
|
658
|
+
`}renderStackedSection(e,t){let n=this.isFileCollapsed(e.path),r=this.activeFilePath===e.path,i=this.isFileLoading(e.path),a=this.fileErrors.get(e.path),o=this.getFileDetail(e.path)??e,s=n?``:i?`<div class="diff-empty-state" role="status" aria-live="polite">Loading file diff…</div>`:a?`<div class="diff-empty-state" role="alert">${j(a)}</div>`:this.renderDiffDetail(o,t,{includeHeader:!1});return`
|
|
659
|
+
<section
|
|
660
|
+
class="diff-commit-section${r?` active`:``}${n?` collapsed`:``}"
|
|
661
|
+
id="${Zs(e.path)}"
|
|
662
|
+
data-diff-section-path="${j(e.path)}"
|
|
663
|
+
>
|
|
664
|
+
<button
|
|
665
|
+
class="diff-commit-section-header"
|
|
666
|
+
type="button"
|
|
667
|
+
data-diff-section-toggle="${j(e.path)}"
|
|
668
|
+
>
|
|
669
|
+
<span class="diff-commit-section-main">
|
|
670
|
+
${$s(n)}
|
|
671
|
+
<span class="diff-commit-section-copy">
|
|
672
|
+
<span class="diff-commit-section-name">${j(C(e.path))}</span>
|
|
673
|
+
${w(e.path)?`<span class="diff-commit-section-path">${j(w(e.path))}</span>`:``}
|
|
674
|
+
</span>
|
|
675
|
+
</span>
|
|
676
|
+
<span class="diff-commit-section-meta">
|
|
677
|
+
<span class="ui-status-badge ${Qs(e.status)}">${j(e.status)}</span>
|
|
678
|
+
<span class="ui-stat-token ui-stat-token--add diff-stats-add">+${e.stats?.additions??0}</span>
|
|
679
|
+
<span class="ui-stat-token ui-stat-token--del diff-stats-del">-${e.stats?.deletions??0}</span>
|
|
680
|
+
</span>
|
|
681
|
+
</button>
|
|
682
|
+
<div class="diff-commit-section-body${n?` hidden`:``}">
|
|
683
|
+
${s}
|
|
684
|
+
</div>
|
|
685
|
+
</section>
|
|
686
|
+
`}renderCommitBody(){return this.layoutMode===`focused`?`
|
|
687
|
+
<div class="diff-commit-shell diff-commit-shell-focused">
|
|
688
|
+
${this.renderCommitIndex()}
|
|
689
|
+
<div class="diff-commit-main">
|
|
690
|
+
${this.renderFocusedFileBody()}
|
|
691
|
+
</div>
|
|
692
|
+
</div>
|
|
693
|
+
`:`
|
|
694
|
+
<div class="diff-commit-shell diff-commit-shell-stacked">
|
|
695
|
+
${this.renderCommitIndex()}
|
|
696
|
+
<div class="diff-commit-main">
|
|
697
|
+
<div class="diff-commit-sections">
|
|
698
|
+
${(this.data?.files??[]).map((e,t)=>this.renderStackedSection(e,t)).join(``)}
|
|
699
|
+
</div>
|
|
700
|
+
</div>
|
|
701
|
+
</div>
|
|
702
|
+
`}getCurrentFile(){let e=this.data?.files??[];return e.length===0?null:e[this.currentIndex]??e[0]??null}getFileByPath(e){return(this.data?.files??[]).find(t=>t.path===e)??null}setActiveFilePath(e,{syncIndex:t=!0}={}){if(this.activeFilePath=e,!t)return;let n=Math.max(0,(this.data?.files??[]).findIndex(t=>t.path===e));n>=0&&(this.currentIndex=n)}getCacheKeyForPath(e){return e?this.source===`commit`?`commit:${this.commitHash}:${e}`:`workspace:${this.requestScope}:${e}`:null}getCurrentCacheKey(){return this.getCacheKeyForPath(this.getCurrentFile()?.path??null)}getCurrentFileDetail(){let e=this.getCurrentCacheKey();return e?this.fileCache.get(e):null}getFileDetail(e){let t=this.getCacheKeyForPath(e);return t?this.fileCache.get(t):null}isFileCollapsed(e){return this.collapsedFiles.has(e)}isFileLoading(e){return this.loadingFiles.has(e)}getCurrentActionState(){if(this.source===`commit`)return{canCommit:!1,canStage:!1,canUnstage:!1};let e=this.getCurrentFile(),t=this.getCurrentFileDetail()??e,n=Number(this.repoStatus?.summary?.staged||0);return t?.path?{canCommit:n>0,canStage:!!(t.hasWorkingTreeChanges||t.hasUntrackedChanges),canUnstage:!!t.hasStagedChanges}:{canCommit:n>0,canStage:!1,canUnstage:!1}}getPrimaryAction(){if(this.source===`commit`)return null;let e=this.getCurrentActionState();return e.canStage&&!e.canUnstage?`stage`:e.canUnstage&&!e.canStage||this.requestScope===`staged`&&e.canUnstage?`unstage`:e.canStage?`stage`:e.canUnstage?`unstage`:null}async handleFileAction(e){if(this.source===`commit`)return;let t=this.getCurrentFile();if(t?.path&&!this.pendingAction){this.pendingAction=e,this.syncToolbar();try{e===`stage`?await this.onStageFile?.(t.path,{scope:this.requestScope}):e===`unstage`?await this.onUnstageFile?.(t.path,{scope:this.requestScope}):e===`commit`&&await this.onCommitStaged?.()}finally{this.pendingAction=null,this.syncToolbar()}}}setRepoStatus(e){this.repoStatus=e,this.syncToolbar()}async handleIndexSelection(e){if(this.getFileByPath(e)){if(this.setActiveFilePath(e),this.source===`commit`&&this.layoutMode===`stacked`){this.collapsedFiles.delete(e),await this.loadFileForPath(e,{render:!1}),this.render(),this.scrollToFileSection(e);return}await this.loadFileForPath(e)}}async toggleFileSection(e){if(this.source===`commit`&&this.layoutMode===`stacked`){if(this.setActiveFilePath(e),this.collapsedFiles.has(e)){this.collapsedFiles.delete(e),await this.loadFileForPath(e,{render:!1}),this.render(),this.scrollToFileSection(e);return}this.collapsedFiles.add(e),this.render()}}scrollToFileSection(e){if(!this.content)return;let t=Zs(e),n=()=>{let e=document.getElementById?.(t)??null;if(e){if(this.scrollContainer?.scrollTo&&this.scrollContainer.getBoundingClientRect&&e.getBoundingClientRect){let t=this.scrollContainer.getBoundingClientRect(),n=e.getBoundingClientRect(),r=Number(this.scrollContainer.scrollTop)||0,i=Math.max(0,r+(n.top-t.top)-8);this.scrollContainer.scrollTo({top:i,behavior:`smooth`});return}e.scrollIntoView?.({behavior:`smooth`,block:`start`})}};if(typeof requestAnimationFrame==`function`){requestAnimationFrame(n);return}setTimeout(n,0)}handleScrollSelection(){if(this.source!==`commit`||this.layoutMode!==`stacked`||!this.scrollContainer||!this.content)return;let e=Array.from(this.content.querySelectorAll?.(`[data-diff-section-path]`)??[]);if(e.length===0)return;let t=this.scrollContainer.getBoundingClientRect?.();if(!t)return;let n=t.top+120,r=null;for(let t of e){let e=t.getBoundingClientRect?.();if(!e)continue;let i=t.getAttribute?.(`data-diff-section-path`);if(i){if(e.top<=n)r=i;else if(r)break;else{r=i;break}}}r&&r!==this.activeFilePath&&(this.setActiveFilePath(r),this.render())}async loadCurrentFile({forceFullPatch:e=!1}={}){let t=this.getCurrentFile();return t?.path?this.loadFileForPath(t.path,{forceFullPatch:e}):(this.render(),null)}async loadFileForPath(e,{forceFullPatch:t=!1,render:n=!0}={}){let r=this.getFileByPath(e);if(!r?.path)return n&&this.render(),null;this.setActiveFilePath(e);let i=this.getCacheKeyForPath(e),a=i?this.fileCache.get(i):null;if(a&&(!a.tooLarge||!t))return n&&this.render(),a;let o=`${e}:${t?`full`:`partial`}`;if(this.fileLoadPromises.has(o))return this.fileLoadPromises.get(o);this.loadingFiles.add(e),this.fileErrors.delete(e),n&&this.render();let s=(async()=>{try{let n;if(this.source===`commit`){let i=await this.gitApiClient.readCommit({allowLargePatch:t,hash:this.commitHash||``,path:e});n={...r,...i.files?.[0]??{}}}else{let i=await this.gitApiClient.readDiff({allowLargePatch:t,path:e,scope:this.requestScope});n={...r,...i.files?.[0]??{}}}return X(n)===`drawio`&&(n=await this.enrichDrawioDetail(n)),i&&this.fileCache.set(i,n),this.fileErrors.delete(e),n}catch(t){console.error(`[git-diff] Failed to load file diff:`,t);let n=this.source===`commit`?`Failed to load commit file diff`:`Failed to load file diff`;return this.fileErrors.set(e,n),this.toastController?.show(n),null}finally{this.loadingFiles.delete(e),this.fileLoadPromises.delete(o),this.render()}})();return this.fileLoadPromises.set(o,s),s}syncToolbar(){let e=this.data?.files?.length??0,t=e===0?0:this.currentIndex+1,n=this.source===`commit`,r=n&&this.layoutMode===`stacked`;if(this.fileIndicator&&(r?this.fileIndicator.textContent=`${e} file${e===1?``:`s`}`:this.fileIndicator.textContent=e>0?`${t} of ${e}`:`0 files`),this.stats){let e=(this.data?.files??[]).filter(e=>X(e)===`image`).reduce((e,t)=>({additions:e.additions+Number(t.stats?.additions||0),deletions:e.deletions+Number(t.stats?.deletions||0)}),{additions:0,deletions:0}),t=this.data?.files??[],n=t.length>0&&t.every(e=>X(e)===`image`),r=Number(this.data?.summary?.additions??0),i=Number(this.data?.summary?.deletions??0),a=n?0:Math.max(0,r-e.additions),o=n?0:Math.max(0,i-e.deletions);this.stats.innerHTML=`
|
|
703
|
+
<span class="ui-stat-token ui-stat-token--add diff-stats-add">+${a}</span>
|
|
704
|
+
<span class="ui-stat-token ui-stat-token--del diff-stats-del">-${o}</span>
|
|
705
|
+
`}this.modeButtons.forEach(e=>{let t=e.getAttribute(`data-diff-mode`)===this.mode;e.classList.remove(`hidden`),e.classList.toggle(`active`,t),e.setAttribute?.(`aria-pressed`,String(t))}),this.layoutButtons.forEach(e=>{let t=e.getAttribute(`data-diff-layout`)===this.layoutMode;e.classList.toggle(`active`,t),e.setAttribute?.(`aria-pressed`,String(t))});let i=!!this.getCurrentFile()?.path,a=i||!!this.workspaceFilePath,o=this.getCurrentActionState(),s=this.getPrimaryAction(),c=Number(this.repoStatus?.summary?.staged||0);if(this.backToHistoryButton?.classList.toggle(`hidden`,!n),this.gitActionsGroup?.classList.toggle(`hidden`,n),this.editorActionsGroup?.classList.toggle(`hidden`,n),this.actionsDivider?.classList.toggle(`hidden`,n),this.layoutToggle?.classList.toggle(`hidden`,!n),this.stats?.classList.remove(`hidden`),this.openEditorButton&&(this.openEditorButton.textContent=`Open in editor`),this.openEditorButton?.toggleAttribute(`disabled`,!a||n),this.primaryActionButton){let e=s===`stage`&&!o.canUnstage;this.primaryActionButton.classList.toggle(`ui-button--primary`,e),this.primaryActionButton.classList.toggle(`ui-button--secondary`,!e),this.primaryActionButton.classList.toggle(`ui-button--surface`,!e),this.primaryActionButton.textContent=this.pendingAction&&this.pendingAction===s?`Working…`:s===`unstage`?`Remove`:`Include in commit`,this.primaryActionButton.toggleAttribute(`disabled`,n||!i||!s||!!this.pendingAction)}this.commitButton&&(this.commitButton.textContent=this.pendingAction===`commit`?`Working…`:gn(c)),this.commitButton?.classList.toggle(`hidden`,n||!i||!o.canUnstage),this.commitButton?.toggleAttribute(`disabled`,n||!o.canCommit||!!this.pendingAction),this.prevButton?.classList.remove(`hidden`),this.nextButton?.classList.remove(`hidden`),this.prevButton?.classList.toggle(`hidden`,r),this.nextButton?.classList.toggle(`hidden`,r),this.prevButton?.toggleAttribute(`disabled`,r||this.currentIndex<=0),this.nextButton?.toggleAttribute(`disabled`,r||e===0||this.currentIndex>=e-1)}render(){if(this.isActive){if(this.page?.classList.remove(`hidden`),(this.data?.files??[]).length===0){this.renderEmpty(this.source===`commit`?`No commit changes to display.`:`No changes to display.`);return}this.content&&(this.excalidrawPreviewPayloads.clear(),this.drawioPreviewPayloads.clear(),this.source===`commit`?this.content.innerHTML=`${this.renderCommitHeader()}${this.renderCommitBody()}`:this.content.innerHTML=this.renderFocusedFileBody(),this.syncToolbar(),this.hydrateExcalidrawPreviews(),this.hydrateDrawioPreviews())}}getToolbarTitle({commitHash:e=null,filePath:t=null,path:n=null,scope:r=`all`,source:i=`workspace`}={}){return i===`commit`||this.source===`commit`?this.layoutMode===`stacked`?this.commitMeta?.shortHash?`Commit ${this.commitMeta.shortHash}`:e?`Commit ${String(e).slice(0,7)}`:`Commit Diff`:n?C(n):this.activeFilePath?C(this.activeFilePath):this.commitMeta?.shortHash?`Commit ${this.commitMeta.shortHash}`:e?`Commit ${String(e).slice(0,7)}`:`Commit Diff`:t?C(t):r===`staged`?`Staged Changes`:r===`working-tree`?`Working Tree Changes`:`All Changes`}},sc=30,cc=1e4;function lc(){return`<svg class="git-file-icon" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>`}function uc(){return`<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="18" cy="18" r="3"/><circle cx="6" cy="6" r="3"/><path d="M13 6h3a2 2 0 0 1 2 2v7"/><path d="M6 9v12"/></svg>`}function dc(e){return`<svg class="git-section-chevron${e?` collapsed`:``}" width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" aria-hidden="true"><polyline points="6 9 12 15 18 9"/></svg>`}function fc(e){switch(e){case`commit`:return`<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg>`;case`pull`:return`<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5v14"/><path d="m18 13-6 6-6-6"/></svg>`;case`push`:return`<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 19V5"/><path d="m6 11 6-6 6 6"/></svg>`;case`unstage`:return`<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 12H8"/><path d="m12 16-4-4 4-4"/></svg>`;case`reset`:return`<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 12a9 9 0 1 0 3-6.7"/><path d="M3 4v5h5"/></svg>`;default:return`<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5v14"/><path d="M5 12h14"/></svg>`}}function pc(e){switch(e){case`added`:return`ui-status-badge--success`;case`deleted`:return`ui-status-badge--danger`;case`renamed`:return`ui-status-badge--accent`;case`untracked`:return`ui-status-badge--muted`;default:return`ui-status-badge--warning`}}function mc(e={},t={}){let n=Number(e.additions||0),r=Number(e.deletions||0);return Number(e.changedFiles||0)>0||n>0||r>0?`
|
|
706
|
+
<span class="git-change-stats" aria-label="Local diff summary">
|
|
707
|
+
<span class="git-change-add">+${n}</span>
|
|
708
|
+
<span class="git-change-del">-${r}</span>
|
|
709
|
+
</span>
|
|
710
|
+
`:t.upstream||Number(t.ahead||0)>0||Number(t.behind||0)>0?`
|
|
711
|
+
<span class="git-sync-info" aria-label="Remote sync status">
|
|
712
|
+
<span class="git-sync-metric git-sync-metric--ahead">↑${Number(t.ahead||0)}</span>
|
|
713
|
+
<span class="git-sync-metric git-sync-metric--behind">↓${Number(t.behind||0)}</span>
|
|
714
|
+
</span>
|
|
715
|
+
`:`<span class="git-sync-info git-sync-info-muted">Clean</span>`}function hc(e={}){let t=String(e.subject||``).trim()||e.shortHash||`Commit`;return j(t)}var gc=class{constructor({enabled:e=!0,gitApiClient:t=null,onCommitStaged:n=()=>{},onOpenPullBackup:r=()=>{},onPullBranch:i=()=>{},onPushBranch:a=()=>{},onRepoChange:o=()=>{},onResetFile:s=()=>{},onSelectCommit:c=()=>{},onSelectDiff:l=()=>{},onStageAll:u=()=>{},onStageFile:d=()=>{},onUnstageAll:f=()=>{},onUnstageFile:p=()=>{},onViewAllDiff:m=()=>{},searchInput:h=null,toastController:g=null}={}){this.enabled=e,this.gitApiClient=t,this.onCommitStaged=n,this.onOpenPullBackup=r,this.onPullBranch=i,this.onPushBranch=a,this.onRepoChange=o,this.onResetFile=s,this.onSelectCommit=c,this.onSelectDiff=l,this.onStageAll=u,this.onStageFile=d,this.onUnstageAll=f,this.onUnstageFile=p,this.onViewAllDiff=m,this.searchInput=h,this.toastController=g,this.panel=document.getElementById(`gitPanel`),this.pullBackups=[],this.status=null,this.statusError=``,this.active=!1,this.refreshTimer=null,this.searchQuery=``,this.panelMode=`changes`,this.collapsedSections=new Set,this.selection={commitHash:null,path:null,scope:null,source:`workspace`},this.pendingActionKey=null,this.history={commits:[],error:``,hasMore:!1,loaded:!1,loading:!1,loadingMore:!1,offset:0}}_handlePanelModeClick(e){let t=e.target instanceof Element?e.target.closest(`[data-git-panel-mode]`):null;if(t){let e=t.getAttribute(`data-git-panel-mode`);return(e===`changes`||e===`history`)&&this.setMode(e),!0}return!1}_handleSectionToggleClick(e){let t=e.target instanceof Element?e.target.closest(`[data-git-section-toggle]`):null;return t?(this.toggleSection(t.getAttribute(`data-git-section-toggle`)),!0):!1}_handleCommitHistoryClick(e){let t=e.target instanceof Element?e.target.closest(`[data-git-commit-hash]`):null;if(t&&!e.target.closest(`[data-git-history-load-more]`)){let e=t.getAttribute(`data-git-commit-hash`);return e&&this.onSelectCommit(e,{path:this.selection.commitHash===e?this.selection.path:null}),!0}return!1}_handleFileSelectionClick(e){let t=e.target instanceof Element?e.target.closest(`[data-git-path]`):null;if(t&&!e.target.closest(`[data-git-file-action]`)){let e=t.getAttribute(`data-git-path`);return e&&this.onSelectDiff(e,{scope:t.getAttribute(`data-git-scope`)||`working-tree`}),!0}return!1}_handleFileActionClick(e){let t=e.target instanceof Element?e.target.closest(`[data-git-file-action]`):null;if(t){let n=t.getAttribute(`data-git-file-action`),r=t.getAttribute(`data-git-path`);return n&&r&&(e.preventDefault(),e.stopPropagation(),this.handleFileAction(n,r,t.getAttribute(`data-git-scope`)||`working-tree`)),!0}return!1}_handlePanelClick(e){if(this._handlePanelModeClick(e)||this._handleSectionToggleClick(e)||this._handleCommitHistoryClick(e))return;if(e.target instanceof Element&&e.target.closest(`[data-git-history-load-more]`)){this.loadMoreHistory();return}if(this._handleFileSelectionClick(e))return;let t=e.target instanceof Element?e.target.closest(`[data-git-pull-backup-id]`):null;if(t){let e=t.getAttribute(`data-git-pull-backup-id`);e&&this.onOpenPullBackup(e);return}if(this._handleFileActionClick(e))return;let n=e.target instanceof Element?e.target.closest(`[data-git-bulk-action]`):null;if(n){let e=n.getAttribute(`data-git-bulk-action`);(e===`stage-all`||e===`unstage-all`)&&this.handleBulkAction(e);return}if(e.target instanceof Element&&e.target.closest(`[data-git-view-all]`)){this.onViewAllDiff();return}if(e.target instanceof Element&&e.target.closest(`[data-git-commit-staged]`)){this.handleCommitStaged();return}let r=e.target instanceof Element?e.target.closest(`[data-git-sync-action]`):null;if(r){let e=r.getAttribute(`data-git-sync-action`);(e===`pull`||e===`push`)&&this.handleSyncAction(e)}}initialize(){this.panel?.addEventListener(`click`,e=>{this._handlePanelClick(e)}),this.searchInput?.addEventListener(`input`,e=>{this.searchQuery=String(e.target?.value??``).trim().toLowerCase(),this.render()}),this.syncSearchUi()}setActive(e){let t=!!e;if(this.active!==t||t&&!this.refreshTimer&&this.panelMode!==`history`){if(this.active=t,!this.active){this.stopStatusPolling();return}this.syncSearchUi(),A(()=>Promise.resolve({}),__vite__mapDeps([1]),import.meta.url),this.refresh({force:!1,includeHistory:this.panelMode===`history`}),this.panelMode===`changes`?this.ensureStatusPolling():this.stopStatusPolling()}}async setMode(e,{forceHistoryRefresh:t=!1}={}){let n=e===`history`?`history`:`changes`,r=this.panelMode!==n;if(this.panelMode=n,this.syncSearchUi(),this.render(),this.active){if(this.panelMode===`changes`){this.ensureStatusPolling(),r&&await this.refresh({force:!1,includeHistory:!1});return}this.stopStatusPolling(),(t||r||!this.history.loaded)&&await this.refreshHistory({force:t||r})}}setSelection({commitHash:e=null,path:t=null,scope:n=null,source:r=`workspace`}={}){this.selection={commitHash:e,path:t,scope:n,source:r},(r===`commit`||e)&&(this.panelMode=`history`,this.syncSearchUi()),this.render()}toggleSection(e){e&&(this.collapsedSections.has(e)?this.collapsedSections.delete(e):this.collapsedSections.add(e),this.render())}ensureStatusPolling(){!this.refreshTimer&&this.active&&this.panelMode===`changes`&&(this.refreshTimer=setInterval(()=>{this.refresh({force:!1,includeHistory:!1})},cc))}stopStatusPolling(){clearInterval(this.refreshTimer),this.refreshTimer=null}syncSearchUi(){this.searchInput&&(this.searchInput.setAttribute(`placeholder`,this.panelMode===`history`?`Filter loaded commits...`:`Search changes...`),this.searchInput.setAttribute(`aria-label`,this.panelMode===`history`?`Filter loaded commits`:`Search changed files`))}async refresh({force:e=!1,includeHistory:t=this.panelMode===`history`}={}){let n=await this.refreshStatus({force:e});return t&&n?.isGitRepo&&await this.refreshHistory({force:e}),n}async refreshStatus({force:e=!1}={}){if(!this.enabled)return this.statusError=``,this.status={isGitRepo:!1,sections:[],summary:{changedFiles:0}},this.pullBackups=[],this.history={...this.history,commits:[],error:``,hasMore:!1,loaded:!1,loading:!1,loadingMore:!1,offset:0},this.onRepoChange(!1,this.status),this.render(),this.status;try{let t=await this.gitApiClient.readStatus({force:e});if(this.status=t,this.statusError=``,this.pullBackups=[],t.isGitRepo)try{let e=await this.gitApiClient.readPullBackups();this.pullBackups=Array.isArray(e.backups)?e.backups:[]}catch(e){console.error(`[git-panel] Failed to load pull backups:`,e)}else this.history={...this.history,commits:[],error:``,hasMore:!1,loaded:!1,loading:!1,loadingMore:!1,offset:0};return this.onRepoChange(!!t.isGitRepo,t),this.render(),t}catch(e){return console.error(`[git-panel] Failed to load git status:`,e),this.toastController?.show(`Failed to load git status`),this.statusError=`Failed to load Git status. Try again.`,this.render(),null}}async refreshHistory({force:e=!1}={}){if(!this.status?.isGitRepo)return this.history={...this.history,commits:[],error:``,hasMore:!1,loaded:!1,loading:!1,loadingMore:!1,offset:0},this.render(),this.history;if(this.history.loading&&!e)return this.history;this.history={...this.history,error:``,loading:!0,loadingMore:!1},e&&(this.history={...this.history,commits:[],hasMore:!1,loaded:!1,offset:0}),this.render();try{let e=await this.gitApiClient.readHistory({limit:sc,offset:0});return this.history={commits:Array.isArray(e.commits)?e.commits:[],error:``,hasMore:!!e.hasMore,loaded:!0,loading:!1,loadingMore:!1,offset:Array.isArray(e.commits)?e.commits.length:0},this.render(),this.history}catch(e){return console.error(`[git-panel] Failed to load git history:`,e),this.toastController?.show(`Failed to load git history`),this.history={...this.history,error:`Failed to load git history`,loading:!1,loadingMore:!1},this.render(),this.history}}async loadMoreHistory(){if(this.status?.isGitRepo&&!this.history.loading&&!this.history.loadingMore&&this.history.hasMore){this.history={...this.history,error:``,loadingMore:!0},this.render();try{let e=await this.gitApiClient.readHistory({limit:sc,offset:this.history.offset}),t=Array.isArray(e.commits)?e.commits:[];this.history={commits:[...this.history.commits,...t],error:``,hasMore:!!e.hasMore,loaded:!0,loading:!1,loadingMore:!1,offset:this.history.offset+t.length},this.render()}catch(e){console.error(`[git-panel] Failed to load more git history:`,e),this.toastController?.show(`Failed to load git history`),this.history={...this.history,error:`Failed to load git history`,loadingMore:!1},this.render()}}}filterFiles(e=[]){return this.searchQuery?e.filter(e=>e.path.toLowerCase().includes(this.searchQuery)||String(e.oldPath||``).toLowerCase().includes(this.searchQuery)):e}filterCommits(e=[]){return this.searchQuery?e.filter(e=>String(e.subject||``).toLowerCase().includes(this.searchQuery)||String(e.shortHash||``).toLowerCase().includes(this.searchQuery)||String(e.authorName||``).toLowerCase().includes(this.searchQuery)):e}async handleFileAction(e,t,n){let r=`${e}:${n}:${t}`;if(this.pendingActionKey!==r){this.pendingActionKey=r,this.render();try{e===`stage`?await this.onStageFile(t,{scope:n}):e===`unstage`?await this.onUnstageFile(t,{scope:n}):e===`reset`&&await this.onResetFile(t,{scope:n})}finally{this.pendingActionKey=null,this.render()}}}async handleBulkAction(e){if(!this.pendingActionKey){this.pendingActionKey=e,this.render();try{await(e===`stage-all`?this.onStageAll():this.onUnstageAll())}finally{this.pendingActionKey=null,this.render()}}}async handleCommitStaged(){let e=`commit-staged`;if(this.pendingActionKey!==e){this.pendingActionKey=e,this.render();try{await this.onCommitStaged()}finally{this.pendingActionKey=null,this.render()}}}async handleSyncAction(e){let t=`sync:${e}`;if(this.pendingActionKey!==t){this.pendingActionKey=t,this.render();try{e===`pull`?await this.onPullBranch():e===`push`&&await this.onPushBranch()}finally{this.pendingActionKey=null,this.render()}}}renderSection(e){let t=this.filterFiles(e.files);if(t.length===0)return``;let n=this.collapsedSections.has(e.key),r=e.key===`staged`?`Included in Next Commit`:e.label;return`
|
|
716
|
+
<section class="git-section">
|
|
717
|
+
<button class="git-section-header" type="button" data-git-section-toggle="${j(e.key)}">
|
|
718
|
+
${dc(n)}
|
|
719
|
+
${j(r)}
|
|
720
|
+
<span class="ui-pill-badge ui-pill-badge--count ui-pill-badge--muted git-section-count">${t.length}</span>
|
|
721
|
+
</button>
|
|
722
|
+
<div class="git-file-list${n?` hidden`:``}">
|
|
723
|
+
${t.map(e=>this.renderFile(e)).join(``)}
|
|
724
|
+
</div>
|
|
725
|
+
</section>
|
|
726
|
+
`}renderPullBackupsSection(){return!Array.isArray(this.pullBackups)||this.pullBackups.length===0?``:`
|
|
727
|
+
<section class="git-section">
|
|
728
|
+
<button class="git-section-header" type="button" data-git-section-toggle="pull-backups">
|
|
729
|
+
${dc(this.collapsedSections.has(`pull-backups`))}
|
|
730
|
+
Pull Backups
|
|
731
|
+
<span class="ui-pill-badge ui-pill-badge--count ui-pill-badge--muted git-section-count">${this.pullBackups.length}</span>
|
|
732
|
+
</button>
|
|
733
|
+
<div class="git-file-list${this.collapsedSections.has(`pull-backups`)?` hidden`:``}">
|
|
734
|
+
${this.pullBackups.map(e=>this.renderPullBackup(e)).join(``)}
|
|
735
|
+
</div>
|
|
736
|
+
</section>
|
|
737
|
+
`}renderPullBackup(e){let t=String(e?.createdAt||``).replace(`T`,` `).replace(/\.\d+Z?$/u,`Z`),n=Number(e?.fileCount||0);return`
|
|
738
|
+
<div class="ui-item-row git-file-row">
|
|
739
|
+
<button
|
|
740
|
+
class="ui-item-main git-file-item"
|
|
741
|
+
type="button"
|
|
742
|
+
title="Open read-only pull backup summary in a new tab"
|
|
743
|
+
data-git-pull-backup-id="${j(e.id||``)}"
|
|
744
|
+
>
|
|
745
|
+
${lc()}
|
|
746
|
+
<span class="ui-item-copy git-file-copy">
|
|
747
|
+
<span class="ui-item-title git-file-name">Pull backup ${j(e.id||``)}</span>
|
|
748
|
+
<span class="ui-item-subtitle git-file-path">${j(`${t} · ${e.branch||`HEAD`} · ${n} file${n===1?``:`s`}`)}</span>
|
|
749
|
+
</span>
|
|
750
|
+
<span class="ui-status-badge ui-status-badge--warning">BK</span>
|
|
751
|
+
</button>
|
|
752
|
+
</div>
|
|
753
|
+
`}renderFile(e){let t=this.selection.source===`workspace`&&this.selection.path===e.path&&this.selection.scope===e.scope,n=w(e.path),r=C(e.path),i=String(e.path||``),a=pc(e.status),o=e.scope===`staged`?{label:`Remove from commit`,value:`unstage`}:{label:`Include in commit`,value:`stage`},s=`${o.value}:${e.scope}:${e.path}`,c=this.pendingActionKey===s,l=`reset:${e.scope}:${e.path}`,u=this.pendingActionKey===l;return`
|
|
754
|
+
<div class="ui-item-row git-file-row${t?` active`:``}">
|
|
755
|
+
<button
|
|
756
|
+
class="ui-item-main git-file-item${t?` active`:``}"
|
|
757
|
+
type="button"
|
|
758
|
+
data-git-path="${j(e.path)}"
|
|
759
|
+
data-git-scope="${j(e.scope)}"
|
|
760
|
+
title="${j(i)}"
|
|
761
|
+
>
|
|
762
|
+
${lc()}
|
|
763
|
+
<span class="ui-item-copy git-file-copy">
|
|
764
|
+
<span class="ui-item-title git-file-name">${j(r)}</span>
|
|
765
|
+
${n?`<span class="ui-item-subtitle git-file-path">${j(n)}</span>`:``}
|
|
766
|
+
</span>
|
|
767
|
+
<span class="ui-status-badge ${a}">${j(e.code)}</span>
|
|
768
|
+
</button>
|
|
769
|
+
<div class="ui-item-actions git-file-actions">
|
|
770
|
+
<button
|
|
771
|
+
class="ui-icon-button ui-action-icon ui-action-icon--surface"
|
|
772
|
+
type="button"
|
|
773
|
+
data-git-file-action="reset"
|
|
774
|
+
data-git-path="${j(e.path)}"
|
|
775
|
+
data-git-scope="${j(e.scope)}"
|
|
776
|
+
aria-label="Reset ${j(r)}"
|
|
777
|
+
title="Reset to current branch"
|
|
778
|
+
${u?`disabled`:``}
|
|
779
|
+
>
|
|
780
|
+
${u?`...`:fc(`reset`)}
|
|
781
|
+
</button>
|
|
782
|
+
<button
|
|
783
|
+
class="ui-icon-button ui-action-icon ui-action-icon--surface"
|
|
784
|
+
type="button"
|
|
785
|
+
data-git-file-action="${o.value}"
|
|
786
|
+
data-git-path="${j(e.path)}"
|
|
787
|
+
data-git-scope="${j(e.scope)}"
|
|
788
|
+
aria-label="${j(o.label)} ${j(r)}"
|
|
789
|
+
title="${j(o.label)}"
|
|
790
|
+
${c?`disabled`:``}
|
|
791
|
+
>
|
|
792
|
+
${c?`...`:fc(o.value)}
|
|
793
|
+
</button>
|
|
794
|
+
</div>
|
|
795
|
+
</div>
|
|
796
|
+
`}renderPanelModes(){return`
|
|
797
|
+
<div class="${De({pill:!0,extra:`git-panel-mode-switch`})}" role="tablist" aria-label="Git panel modes">
|
|
798
|
+
<button
|
|
799
|
+
class="${be({active:this.panelMode===`changes`,extra:`git-panel-mode-btn`})}"
|
|
800
|
+
type="button"
|
|
801
|
+
data-git-panel-mode="changes"
|
|
802
|
+
aria-selected="${this.panelMode===`changes`}"
|
|
803
|
+
>
|
|
804
|
+
Changes
|
|
805
|
+
</button>
|
|
806
|
+
<button
|
|
807
|
+
class="${be({active:this.panelMode===`history`,extra:`git-panel-mode-btn`})}"
|
|
808
|
+
type="button"
|
|
809
|
+
data-git-panel-mode="history"
|
|
810
|
+
aria-selected="${this.panelMode===`history`}"
|
|
811
|
+
>
|
|
812
|
+
History
|
|
813
|
+
</button>
|
|
814
|
+
</div>
|
|
815
|
+
`}renderHistoryRow(e){let t=this.selection.source===`commit`&&this.selection.commitHash===e.hash,n=Number(e.filesChanged||0);return`
|
|
816
|
+
<button
|
|
817
|
+
class="ui-record-surface git-history-row${t?` active`:``}"
|
|
818
|
+
type="button"
|
|
819
|
+
data-git-commit-hash="${j(e.hash||``)}"
|
|
820
|
+
title="${j(e.authoredAt||``)}"
|
|
821
|
+
>
|
|
822
|
+
<span class="ui-record-header git-history-row-top">
|
|
823
|
+
<span class="ui-record-title git-history-subject">${hc(e)}</span>
|
|
824
|
+
<span class="ui-pill-badge ui-pill-badge--code git-history-hash">${j(e.shortHash||``)}</span>
|
|
825
|
+
</span>
|
|
826
|
+
<span class="ui-record-meta git-history-row-meta">
|
|
827
|
+
<span>${j(e.authorName||`Unknown`)}</span>
|
|
828
|
+
<span>${j(e.relativeDateLabel||``)}</span>
|
|
829
|
+
<span>${n} file${n===1?``:`s`}</span>
|
|
830
|
+
${e.isMergeCommit?`<span>Merge</span>`:``}
|
|
831
|
+
</span>
|
|
832
|
+
<span class="ui-record-meta git-history-row-stats">
|
|
833
|
+
<span class="git-change-add">+${Number(e.additions||0)}</span>
|
|
834
|
+
<span class="git-change-del">-${Number(e.deletions||0)}</span>
|
|
835
|
+
</span>
|
|
836
|
+
</button>
|
|
837
|
+
`}renderHistoryPanel(){let e=this.filterCommits(this.history.commits);return this.history.loading&&!this.history.loaded?`<div class="git-panel-empty" role="status" aria-live="polite">Loading git history…</div>`:this.history.error&&!this.history.loaded?`<div class="git-panel-empty" role="alert">${j(this.history.error)}</div>`:this.history.loaded&&e.length===0&&this.history.commits.length===0?`<div class="git-panel-empty">No commits yet on this branch.</div>`:this.history.loaded&&e.length===0?`<div class="git-panel-empty">No loaded commits match your filter.</div>`:`
|
|
838
|
+
<div class="git-history-list">
|
|
839
|
+
${e.map(e=>this.renderHistoryRow(e)).join(``)}
|
|
840
|
+
</div>
|
|
841
|
+
${this.history.hasMore?`
|
|
842
|
+
<div class="git-history-footer">
|
|
843
|
+
<button
|
|
844
|
+
class="${k({variant:`secondary`,size:`compact`,action:!0,surface:!0,extra:`git-history-load-more`})}"
|
|
845
|
+
type="button"
|
|
846
|
+
data-git-history-load-more
|
|
847
|
+
${this.history.loadingMore?`disabled`:``}
|
|
848
|
+
>
|
|
849
|
+
${this.history.loadingMore?`Loading…`:`Load more`}
|
|
850
|
+
</button>
|
|
851
|
+
</div>
|
|
852
|
+
`:``}
|
|
853
|
+
`}renderChangesPanel(){let e=this.renderPullBackupsSection(),t=(this.status.sections??[]).map(e=>this.renderSection(e)).filter(Boolean).join(``),n=!!this.status.summary?.changedFiles,r=Number(this.status.summary?.staged||0),i=Number(this.status.summary?.workingTree||0)+Number(this.status.summary?.untracked||0),a=this.pendingActionKey===`commit-staged`;return`
|
|
854
|
+
${e}
|
|
855
|
+
${t||`<div class="git-panel-empty">${this.searchQuery&&n?`No changes match your filter.`:`No local changes`}</div>`}
|
|
856
|
+
${n?`
|
|
857
|
+
<div class="git-panel-footer">
|
|
858
|
+
<div class="git-panel-footer-actions">
|
|
859
|
+
${i>0?`
|
|
860
|
+
<button
|
|
861
|
+
class="${k({variant:`secondary`,size:`compact`,action:!0,surface:!0})}"
|
|
862
|
+
type="button"
|
|
863
|
+
data-git-bulk-action="stage-all"
|
|
864
|
+
${this.pendingActionKey?`disabled`:``}
|
|
865
|
+
>
|
|
866
|
+
${this.pendingActionKey===`stage-all`?`Working...`:`Include all changes`}
|
|
867
|
+
</button>
|
|
868
|
+
`:``}
|
|
869
|
+
${r>0?`
|
|
870
|
+
<button
|
|
871
|
+
class="${k({variant:`secondary`,size:`compact`,action:!0,surface:!0})}"
|
|
872
|
+
type="button"
|
|
873
|
+
data-git-bulk-action="unstage-all"
|
|
874
|
+
${this.pendingActionKey?`disabled`:``}
|
|
875
|
+
>
|
|
876
|
+
${this.pendingActionKey===`unstage-all`?`Working...`:`Remove all from commit`}
|
|
877
|
+
</button>
|
|
878
|
+
`:``}
|
|
879
|
+
<button class="${k({variant:`secondary`,size:`compact`,action:!0,surface:!0})}" type="button" data-git-view-all>
|
|
880
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M2 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
|
|
881
|
+
View full diff
|
|
882
|
+
</button>
|
|
883
|
+
<button
|
|
884
|
+
class="${k({variant:`primary`,action:!0,wide:!0,extra:`git-footer-commit-btn`})}"
|
|
885
|
+
type="button"
|
|
886
|
+
data-git-commit-staged
|
|
887
|
+
${r===0||a?`disabled`:``}
|
|
888
|
+
>
|
|
889
|
+
${a?`Working…`:gn(r)}
|
|
890
|
+
</button>
|
|
891
|
+
</div>
|
|
892
|
+
</div>
|
|
893
|
+
`:``}
|
|
894
|
+
`}renderEmpty(e,{alert:t=!1,status:n=!1}={}){if(!this.panel)return;let r=t?` role="alert"`:n?` role="status" aria-live="polite"`:``;this.panel.innerHTML=`
|
|
895
|
+
<div class="git-panel-empty ui-empty-state ui-empty-state--compact"${r}>
|
|
896
|
+
<p class="ui-empty-state-copy">${j(e)}</p>
|
|
897
|
+
</div>
|
|
898
|
+
`}render(){if(!this.panel)return;if(this.statusError){this.renderEmpty(this.statusError,{alert:!0});return}if(!this.status){this.renderEmpty(`Loading git status…`,{status:!0});return}if(!this.status.isGitRepo){this.renderEmpty(`Git is unavailable for this vault.`);return}let e=this.status.branch??{},t=!!e.upstream,n=this.pendingActionKey===`sync:pull`,r=this.pendingActionKey===`sync:push`;this.panel.innerHTML=`
|
|
899
|
+
<div class="git-branch-bar">
|
|
900
|
+
<div class="git-branch-meta">
|
|
901
|
+
<span class="git-branch-name">
|
|
902
|
+
${uc()}
|
|
903
|
+
${j(e.name||`HEAD`)}
|
|
904
|
+
</span>
|
|
905
|
+
${mc(this.status.summary,e)}
|
|
906
|
+
</div>
|
|
907
|
+
<div class="git-branch-actions" role="group" aria-label="Remote sync actions">
|
|
908
|
+
<button
|
|
909
|
+
class="${k({variant:`secondary`,size:`compact`,pill:!0,surface:!0,extra:`ui-action-pill`})}"
|
|
910
|
+
type="button"
|
|
911
|
+
data-git-sync-action="pull"
|
|
912
|
+
title="${t?`Pull remote changes`:`No upstream branch configured`}"
|
|
913
|
+
aria-label="Pull branch"
|
|
914
|
+
${!t||n?`disabled`:``}
|
|
915
|
+
>
|
|
916
|
+
${n?`...`:`${fc(`pull`)}<span>Pull</span>`}
|
|
917
|
+
</button>
|
|
918
|
+
<button
|
|
919
|
+
class="${k({variant:`secondary`,size:`compact`,pill:!0,surface:!0,extra:`ui-action-pill`})}"
|
|
920
|
+
type="button"
|
|
921
|
+
data-git-sync-action="push"
|
|
922
|
+
title="${t?`Push local commits`:`No upstream branch configured`}"
|
|
923
|
+
aria-label="Push branch"
|
|
924
|
+
${!t||r?`disabled`:``}
|
|
925
|
+
>
|
|
926
|
+
${r?`...`:`${fc(`push`)}<span>Push</span>`}
|
|
927
|
+
</button>
|
|
928
|
+
</div>
|
|
929
|
+
${this.renderPanelModes()}
|
|
930
|
+
</div>
|
|
931
|
+
${this.panelMode===`history`?this.renderHistoryPanel():this.renderChangesPanel()}
|
|
932
|
+
`}},_c=class{constructor({mobileBreakpointQuery:e=window.matchMedia(`(max-width: 768px)`),onMeasureEditor:t,onPreferredViewChange:n=null,onViewChange:r=null,onViewRequest:i=null,preferredView:a=`split`}){this.mobileBreakpointQuery=e,this.onMeasureEditor=t,this.onPreferredViewChange=n,this.onViewChange=r,this.onViewRequest=i,this.preferredView=a===`editor`||a===`preview`||a===`split`?a:`split`,this.mobileShowsEditor=!this.isMobileViewport(),this.currentView=this.mobileShowsEditor?this.preferredView:`preview`,this.editorLayout=document.getElementById(`editorLayout`),this.editorPane=document.getElementById(`editorPane`),this.previewPane=document.getElementById(`previewPane`),this.mobileToggleButton=document.getElementById(`mobileViewToggle`),this.resizer=document.getElementById(`resizer`),this.viewButtons=Array.from(document.querySelectorAll(`#toolbarViewToggle [data-view]`))}isMobileViewport(){return this.mobileBreakpointQuery.matches}initialize(){this.viewButtons.forEach(e=>{e.addEventListener(`click`,()=>{this.onViewRequest?.(e.dataset.view)!==!1&&this.setView(e.dataset.view)})}),this.mobileToggleButton?.addEventListener(`click`,()=>this.toggleMobileView()),this.initializeResizer(),this.restorePreferredView()}primeView(e){if(e){if(this.isMobileViewport()){this.mobileShowsEditor=e!==`preview`;return}this.preferredView=e}}reset(){this.restorePreferredView(),this.editorPane&&(this.editorPane.style.flex=``),this.previewPane&&(this.previewPane.style.flex=``),this.updateResizerValue()}restorePreferredView(){let e=this.isMobileViewport()?this.mobileShowsEditor?`split`:`preview`:this.preferredView;this.applyView(e),this.updateMobileToggleButton(this.mobileShowsEditor?`Preview`:`Editor`)}applyView(e){this.currentView=e,this.editorLayout?.setAttribute(`data-view`,e),this.syncViewButtons(),this.onViewChange?.(e)}setView(e,{persist:t=!0}={}){e&&(t&&(this.preferredView=e,this.onPreferredViewChange?.(e)),this.applyView(e),(e===`split`||e===`editor`)&&this.scheduleEditorMeasure())}toggleMobileView(){let e=!this.mobileShowsEditor,t=e?`split`:`preview`;this.onViewRequest?.(t)!==!1&&(this.mobileShowsEditor=e,this.applyView(t),this.updateMobileToggleButton(this.mobileShowsEditor?`Preview`:`Editor`),this.mobileShowsEditor&&this.scheduleEditorMeasure())}scheduleEditorMeasure(){this.onMeasureEditor&&setTimeout(()=>this.onMeasureEditor(),50)}updateMobileToggleButton(e){this.mobileToggleButton&&(this.mobileToggleButton.innerHTML=`${e===`Editor`?`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"/><line x1="8" y1="8" x2="16" y2="8"/><line x1="8" y1="12" x2="14" y2="12"/><line x1="8" y1="16" x2="12" y2="16"/></svg>`:`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>`}<span class="ui-toolbar-button-label">${e}</span>`)}syncViewButtons(){this.viewButtons.forEach(e=>{let t=e.dataset.view===this.currentView;e.classList.toggle(`active`,t),e.setAttribute(`aria-pressed`,String(t))})}updateResizerValue(){if(!this.resizer||!this.editorLayout||!this.editorPane)return;let e=this.editorLayout.offsetWidth;if(!Number.isFinite(e)||e<=0)return;let t=Math.round(this.editorPane.offsetWidth/e*100);this.resizer.setAttribute(`aria-valuenow`,String(Math.max(20,Math.min(80,t))))}applyEditorPaneWidth(e){if(!this.editorLayout||!this.editorPane||!this.previewPane)return;let t=this.editorLayout.offsetWidth;if(!Number.isFinite(t)||t<=0)return;let n=Math.max(200,Math.min(t-200,e))/t*100;this.editorPane.style.flex=`0 0 ${n}%`,this.previewPane.style.flex=`1`,this.updateResizerValue()}initializeResizer(){if(!this.resizer||!this.editorLayout||!this.editorPane||!this.previewPane)return;let e=!1,t=0,n=0;this.resizer.addEventListener(`mousedown`,r=>{e=!0,t=r.clientX,n=this.editorPane.offsetWidth,this.resizer.classList.add(`dragging`),document.body.style.cursor=`col-resize`,document.body.style.userSelect=`none`,r.preventDefault()}),document.addEventListener(`mousemove`,r=>{if(!e)return;let i=r.clientX-t;this.applyEditorPaneWidth(n+i)}),document.addEventListener(`mouseup`,()=>{e&&(e=!1,this.resizer.classList.remove(`dragging`),document.body.style.cursor=``,document.body.style.userSelect=``,this.scheduleEditorMeasure())}),this.resizer.addEventListener(`keydown`,e=>{let t=this.editorLayout.offsetWidth;if(!Number.isFinite(t)||t<=0)return;let n=Math.max(24,Math.round(t*.05));if(e.key===`ArrowLeft`){e.preventDefault(),this.applyEditorPaneWidth(this.editorPane.offsetWidth-n),this.scheduleEditorMeasure();return}if(e.key===`ArrowRight`){e.preventDefault(),this.applyEditorPaneWidth(this.editorPane.offsetWidth+n),this.scheduleEditorMeasure();return}if(e.key===`Home`){e.preventDefault(),this.applyEditorPaneWidth(t*.2),this.scheduleEditorMeasure();return}e.key===`End`&&(e.preventDefault(),this.applyEditorPaneWidth(t*.8),this.scheduleEditorMeasure())}),this.updateResizerValue()}},vc=class{constructor({mobileBreakpointQuery:e=window.matchMedia(`(max-width: 768px)`),onNavigateToHeading:t,onWillOpen:n}={}){this.outlineOpen=!1,this.activeHeadingFrame=null,this.activeHeadingId=null,this.headings=[],this.pinnedHeadingId=null,this.onNavigateToHeading=t,this.onWillOpen=n,this.panel=document.getElementById(`outlinePanel`),this.closeButton=document.getElementById(`outlineClose`),this.navigation=document.getElementById(`outlineNav`),this.previewContainer=document.getElementById(`previewContainer`),this.toggleButton=document.getElementById(`outlineToggle`),this.mobileBreakpointQuery=e,this.handlePreviewScroll=()=>this.scheduleActiveHeadingUpdate(),this.handleDocumentPointerDown=e=>{if(!this.outlineOpen)return;let t=e.target;t instanceof Node&&(this.panel?.contains(t)||this.toggleButton?.contains(t))||this.close()}}initialize(){this.toggleButton?.addEventListener(`click`,()=>this.toggle()),this.closeButton?.addEventListener(`click`,()=>this.close()),document.addEventListener(`pointerdown`,this.handleDocumentPointerDown)}toggle(){this.setOpenState(!this.outlineOpen)}close(){this.setOpenState(!1)}setOpenState(e){if(e&&!this.outlineOpen&&this.onWillOpen?.(),this.outlineOpen=e,this.panel?.classList.toggle(`hidden`,!this.outlineOpen),this.toggleButton?.classList.toggle(`active`,this.outlineOpen),this.panel?.setAttribute(`aria-hidden`,String(!this.outlineOpen)),this.toggleButton?.setAttribute(`aria-expanded`,String(this.outlineOpen)),this.outlineOpen){this.refresh();return}this.cleanup()}refresh(){if(!this.navigation)return;if(!this.outlineOpen){this.cleanup();return}let e=document.getElementById(`previewContent`)?.querySelectorAll(`h1, h2, h3, h4, h5, h6`)??[];if(e.length===0){this.navigation.innerHTML=`<div class="outline-empty">No headings found</div>`,this.cleanup();return}let t=Array.from(e).map((e,t)=>(e.id||=`heading-${t}-${e.textContent.trim().toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-|-$/g,``).slice(0,40)}`,{id:e.id,level:Number.parseInt(e.tagName[1],10),sourceLine:Number.parseInt(e.getAttribute(`data-source-line`)||``,10),text:e.textContent.trim()}));this.navigation.innerHTML=t.map(e=>`<button class="outline-item" data-level="${e.level}" data-target="${e.id}"${Number.isFinite(e.sourceLine)?` data-source-line="${e.sourceLine}"`:``} title="${e.text.replace(/"/g,`"`)}">${e.text}</button>`).join(``),this.navigation.querySelectorAll(`.outline-item`).forEach(e=>{e.addEventListener(`click`,()=>{let t=document.getElementById(e.dataset.target);this.navigateToHeading(t,e.dataset.target,{behavior:`auto`}),this.mobileBreakpointQuery.matches&&this.close()})}),this.observeHeadings(Array.from(e))}cleanup({preservePinnedHeading:e=!1}={}){this.activeHeadingFrame&&=(cancelAnimationFrame(this.activeHeadingFrame),null),this.previewContainer?.removeEventListener(`scroll`,this.handlePreviewScroll),this.headings=[],e||(this.pinnedHeadingId=null)}setActiveItem(e,{scrollIntoView:t=!0,behavior:n=`smooth`}={}){this.activeHeadingId=e,this.navigation?.querySelectorAll(`.outline-item`).forEach(t=>{t.classList.toggle(`active`,t.dataset.target===e)}),t&&this.navigation?.querySelector(`.outline-item.active`)?.scrollIntoView({behavior:n,block:`nearest`})}observeHeadings(e){if(this.cleanup({preservePinnedHeading:!0}),!this.previewContainer||e.length===0)return;this.headings=e,this.previewContainer.addEventListener(`scroll`,this.handlePreviewScroll,{passive:!0});let t=this.getPinnedHeading();if(t){this.setActiveItem(t.id,{behavior:`auto`,scrollIntoView:!0});return}this.updateActiveHeading()}scheduleActiveHeadingUpdate(){this.activeHeadingFrame||=requestAnimationFrame(()=>{this.activeHeadingFrame=null,this.updateActiveHeading()})}updateActiveHeading(){if(!this.previewContainer||this.headings.length===0)return;let e=this.getPinnedHeading();if(e&&this.shouldKeepPinnedHeadingActive(e)){this.setActiveItem(e.id,{behavior:`auto`,scrollIntoView:!0});return}this.pinnedHeadingId=null;let t=this.previewContainer.scrollTop,n=this.headings[0];for(let e of this.headings){if(this.getHeadingScrollTop(e)>t)break;n=e}this.setActiveItem(n.id,{behavior:`auto`,scrollIntoView:!0})}getHeadingScrollTop(e){if(!this.previewContainer)return 0;let t=this.previewContainer.getBoundingClientRect(),n=e.getBoundingClientRect();return this.previewContainer.scrollTop+(n.top-t.top)}getPinnedHeading(){return this.pinnedHeadingId?this.headings.find(e=>e.id===this.pinnedHeadingId)??null:null}shouldKeepPinnedHeadingActive(e){if(!this.previewContainer||!e?.isConnected)return!1;let t=this.getHeadingScrollTop(e)-this.previewContainer.scrollTop,n=t+e.getBoundingClientRect().height,r=this.previewContainer.clientHeight*.45;return n>-48&&t<r}notifyHeadingNavigation(e,t){if(!e)return;let n=Number.parseInt(e.getAttribute(`data-source-line`)||``,10);this.onNavigateToHeading?.({headingId:t,sourceLine:Number.isFinite(n)?n:null})}navigateToHeading(e,t,{behavior:n=`auto`}={}){return!e||!t?!1:(this.pinnedHeadingId=t,this.notifyHeadingNavigation(e,t),this.scrollHeadingIntoView(e,{behavior:n}),this.setActiveItem(t,{behavior:n}),!0)}scrollHeadingIntoView(e,{behavior:t=`smooth`}={}){if(!e||!this.previewContainer)return;let n=this.previewContainer.getBoundingClientRect(),r=e.getBoundingClientRect(),i=this.previewContainer.scrollTop+(r.top-n.top);this.previewContainer.scrollTo({behavior:t,top:Math.max(i,0)})}},yc=.35,bc=120,xc=12,Sc=2,Cc=`[data-source-line]:not(svg, svg *)`,wc=[`wheel`,`touchstart`,`pointerdown`,`keydown`];function $(e){return Math.max(e.scrollHeight-e.clientHeight,0)}function Tc(e){return Math.max(e,0)}function Ec(e){return Math.max(e.clientHeight*yc,xc)}function Dc(e){return(e?.scrollTop??0)<=Sc}function Oc(e,t){let n=e.getBoundingClientRect();return t.getBoundingClientRect().top-n.top+e.scrollTop}function kc(e){return!e.querySelector(Cc)}var Ac=class{constructor({getEditorLineNumber:e,onEditorScrollActivityChange:t,previewContainer:n,previewElement:r,scrollEditorToLine:i}){this.getEditorLineNumber=e,this.onEditorScrollActivityChange=t,this.previewContainer=n,this.previewElement=r,this.scrollEditorToLine=i,this.editorScroller=null,this.editorScrollActive=!1,this.editorScrollIdleTimer=null,this.scrollUnlockFrames=new Map,this.pendingSync=null,this.frameId=null,this.previewBlocks=null,this.previewBlocksWarmId=null,this.previewBlocksReadyCallbacks=[],this.largeDocumentMode=!1,this.lastInteractionSource=`editor`,this.scrollInputSource=null,this.suspendedUntil=0,this.listenerController=null,this.editorListenerController=null,this.handleScrollInput=e=>{let t=e.currentTarget;this.scrollInputSource=t,this.lastInteractionSource=t===this.editorScroller?`editor`:`preview`,this.pendingSync=null,cancelAnimationFrame(this.scrollUnlockFrames.get(t)),this.scrollUnlockFrames.delete(t);let n=t===this.editorScroller?this.previewContainer:this.editorScroller;n&&this.lockScrollTarget(n),t===this.previewContainer&&(clearTimeout(this.editorScrollIdleTimer),this.editorScrollIdleTimer=null,this.setEditorScrollActive(!1))},this.handleEditorScroll=()=>{if(!(!this.editorScroller||this.scrollInputSource&&this.scrollInputSource!==this.editorScroller||this.scrollUnlockFrames.has(this.editorScroller)||this.isSuspended())){if(this.lastInteractionSource=`editor`,this.largeDocumentMode){this.setEditorScrollActive(!0),this.scheduleEditorScrollIdle(),this.scheduleSync(this.editorScroller,this.previewContainer,{preferApproximateMapping:!0});return}this.scheduleSync(this.editorScroller,this.previewContainer)}},this.handlePreviewScroll=()=>{!this.previewContainer||this.scrollInputSource&&this.scrollInputSource!==this.previewContainer||this.scrollUnlockFrames.has(this.previewContainer)||this.isSuspended()||(this.lastInteractionSource=`preview`,this.scheduleSync(this.previewContainer,this.editorScroller))}}initialize(){this.listenerController?.abort(),this.listenerController=new AbortController;let{signal:e}=this.listenerController;this.previewContainer?.addEventListener(`scroll`,this.handlePreviewScroll,{passive:!0,signal:e}),wc.forEach(t=>this.previewContainer?.addEventListener(t,this.handleScrollInput,{passive:!0,signal:e}))}attachEditorScroller(e){if(this.editorScroller===e)return;if(this.editorListenerController?.abort(),this.editorScroller=e,this.scrollInputSource=null,!this.editorScroller){this.editorListenerController=null;return}this.editorListenerController=new AbortController;let{signal:t}=this.editorListenerController;this.editorScroller.addEventListener(`scroll`,this.handleEditorScroll,{passive:!0,signal:t}),wc.forEach(e=>this.editorScroller.addEventListener(e,this.handleScrollInput,{passive:!0,signal:t}))}syncPreviewToEditor(){this.lastInteractionSource=`editor`,this.sync(this.editorScroller,this.previewContainer)}syncEditorToPreview(){this.lastInteractionSource=`preview`,this.sync(this.previewContainer,this.editorScroller)}destroy(){this.listenerController?.abort(),this.listenerController=null,this.editorListenerController?.abort(),this.editorListenerController=null,this.editorScroller=null,this.scrollInputSource=null,clearTimeout(this.editorScrollIdleTimer),this.editorScrollIdleTimer=null,this.pendingSync=null,this.previewBlocks=null,fe(this.previewBlocksWarmId),this.previewBlocksWarmId=null,this.previewBlocksReadyCallbacks=[],this.scrollUnlockFrames.forEach(e=>cancelAnimationFrame(e)),this.scrollUnlockFrames.clear(),this.editorScrollActive=!1,this.lastInteractionSource=`editor`,this.suspendedUntil=0,this.frameId&&=(cancelAnimationFrame(this.frameId),null)}scheduleSync(e,t,{preferApproximateMapping:n=!1}={}){e&&t&&!this.scrollUnlockFrames.has(e)&&!this.isSuspended()&&(this.pendingSync={preferApproximateMapping:n,source:e,target:t},!this.frameId&&(this.frameId=requestAnimationFrame(()=>{if(this.frameId=null,!this.pendingSync)return;let{preferApproximateMapping:e,source:t,target:n}=this.pendingSync;this.pendingSync=null,this.sync(t,n,{preferApproximateMapping:e})})))}invalidatePreviewBlocks(){this.previewBlocks=null,fe(this.previewBlocksWarmId),this.previewBlocksWarmId=null,this.previewBlocksReadyCallbacks=[]}setLargeDocumentMode(e){this.largeDocumentMode=!!e,this.largeDocumentMode||(clearTimeout(this.editorScrollIdleTimer),this.editorScrollIdleTimer=null,this.setEditorScrollActive(!1))}warmPreviewBlocks({onReady:e}={}){if(typeof e==`function`&&(this.previewBlocks?e(this.previewBlocks):this.previewBlocksReadyCallbacks.push(e)),!this.largeDocumentMode){this.previewBlocks||=this.buildPreviewBlocks(),this.flushPreviewBlocksReadyCallbacks();return}this.previewBlocks||this.previewBlocksWarmId!==null||(this.previewBlocksWarmId=de(()=>{this.previewBlocksWarmId=null,this.previewBlocks=this.buildPreviewBlocks(),this.flushPreviewBlocksReadyCallbacks()},500))}realignAfterLayoutChange(){let e=()=>{if(this.lastInteractionSource===`preview`){this.syncEditorToPreview();return}this.syncPreviewToEditor()};if(this.largeDocumentMode&&!this.previewBlocks){this.warmPreviewBlocks({onReady:()=>e()});return}e()}suspendSync(e=250){this.suspendedUntil=performance.now()+e}isSuspended(){return performance.now()<this.suspendedUntil}flushPreviewBlocksReadyCallbacks(){this.previewBlocksReadyCallbacks.length!==0&&this.previewBlocksReadyCallbacks.splice(0).forEach(e=>{try{e(this.previewBlocks??[])}catch(e){console.warn(`[scroll-sync] Preview block callback failed:`,e)}})}setEditorScrollActive(e){this.editorScrollActive!==e&&(this.editorScrollActive=e,this.onEditorScrollActivityChange?.(e))}scheduleEditorScrollIdle(){clearTimeout(this.editorScrollIdleTimer),this.editorScrollIdleTimer=setTimeout(()=>{this.editorScrollIdleTimer=null,this.setEditorScrollActive(!1),this.syncPreviewToEditor()},bc)}sync(e,t,{preferApproximateMapping:n=!1}={}){if(!e||!t||this.scrollUnlockFrames.has(e)||this.isSuspended())return;if(!n&&e===this.editorScroller&&t===this.previewContainer){let e=this.getPreviewScrollTopForEditorLine();if(e!==null){this.setScrollTop(t,e);return}}if(e===this.previewContainer&&t===this.editorScroller){let e=this.getEditorLineNumberForPreviewScroll();if(e!==null){this.lockScrollTarget(t),this.scrollEditorToLine?.(e,yc);return}}let r=$(e),i=$(t),a=r>0?e.scrollTop/r:0,o=i>0?i*a:0;this.setScrollTop(t,o)}setScrollTop(e,t){this.lockScrollTarget(e),e.scrollTop=Tc(t)}lockScrollTarget(e){cancelAnimationFrame(this.scrollUnlockFrames.get(e)),this.scrollUnlockFrames.set(e,requestAnimationFrame(()=>{this.scrollUnlockFrames.set(e,requestAnimationFrame(()=>{this.scrollUnlockFrames.delete(e)}))}))}getPreviewScrollTopForEditorLine(){if(Dc(this.editorScroller))return 0;let e=this.getEditorLineNumber?.();if(!Number.isFinite(e))return null;let t=this.getPreviewBlocks();if(t.length===0||!this.previewContainer)return null;let{block:n,index:r}=this.findBlockForLine(t,e),i=this.getPreviewSpan(t,r),a=Math.max(n.end-n.start,1),o=M((e-n.start)/a,0,1),s=$(this.previewContainer),c=Ec(this.previewContainer);return M(n.top+i*o-c,0,s)}getEditorLineNumberForPreviewScroll(){if(!this.previewContainer)return null;let e=this.getPreviewBlocks();if(e.length===0)return null;let t=this.previewContainer.scrollTop+Ec(this.previewContainer),{block:n,index:r}=this.findBlockForScrollTop(e,t),i=this.getPreviewSpan(e,r),a=Math.max(n.end-n.start,1),o=i>0?M((t-n.top)/i,0,1):0;return Math.round(n.start+a*o)}getPreviewBlocks(){return this.previewBlocks?this.previewBlocks:!this.previewContainer||!this.previewElement||this.largeDocumentMode?[]:(this.previewBlocks=this.buildPreviewBlocks(),this.previewBlocks)}buildPreviewBlocks(){let e=Array.from(this.previewElement.querySelectorAll(Cc)).map(e=>{let t=Number.parseInt(e.getAttribute(`data-source-line`)||``,10),n=Number.parseInt(e.getAttribute(`data-source-line-end`)||``,10);return Number.isFinite(t)?{element:e,end:Number.isFinite(n)?Math.max(n,t+1):t+1,start:t,top:Oc(this.previewContainer,e)}:null}).filter(Boolean).sort((e,t)=>e.top-t.top||e.start-t.start||e.end-t.end),t=e.filter(e=>kc(e.element)),n=t.length>0?t:e;return n.filter((e,t)=>{let r=n[t-1];return!r||Math.abs(r.top-e.top)>1||r.start!==e.start||r.end!==e.end})}findBlockForLine(e,t){let n=null,r=-1;for(let i=0;i<e.length;i+=1){let a=e[i];if(t>=a.start&&t<a.end){if(!n){n=a,r=i;continue}let e=n.end-n.start,t=a.end-a.start;(t<e||t===e&&a.start>=n.start)&&(n=a,r=i)}}if(n)return{block:n,index:r};let i=0;for(let n=0;n<e.length&&!(e[n].start>t);n+=1)i=n;return{block:e[i],index:i}}findBlockForScrollTop(e,t){for(let n=0;n<e.length;n+=1)if(t<this.getPreviewSpan(e,n)+e[n].top)return{block:e[n],index:n};let n=e.length-1;return{block:e[n],index:n}}getPreviewSpan(e,t){if(!this.previewContainer)return 1;let n=e[t],r=e[t+1],i=n.element.getBoundingClientRect().height;if(!r){let e=$(this.previewContainer);return Math.max(e-n.top+this.previewContainer.clientHeight,i,1)}return Math.max(r.top-n.top,i,1)}},jc=`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="5"/><path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/></svg>`,Mc=`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>`,Nc=class{constructor({storageKey:e=`collabmd-theme`,onChange:t}){this.storageKey=e,this.onChange=t,this.currentTheme=`dark`}initialize(){this.currentTheme=this.readPreferredTheme(),this.applyTheme(),document.querySelectorAll(`[data-theme-toggle]`).forEach(e=>{e.addEventListener(`click`,()=>this.toggle())})}getTheme(){return this.currentTheme}toggle(){this.currentTheme=this.currentTheme===`dark`?`light`:`dark`,this.persistTheme(),this.applyTheme()}readPreferredTheme(){try{let e=window.localStorage.getItem(this.storageKey);if(e===`light`||e===`dark`)return e}catch{}return window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`}persistTheme(){try{window.localStorage.setItem(this.storageKey,this.currentTheme)}catch{}}applyTheme(){document.documentElement.setAttribute(`data-theme`,this.currentTheme),this.updateToggleIcons(),this.onChange?.(this.currentTheme)}updateToggleIcons(){let e=this.currentTheme===`dark`?`Dark`:`Light`,t=this.currentTheme===`dark`?`light`:`dark`,n=this.currentTheme===`dark`?Mc:jc;document.querySelectorAll(`[data-theme-toggle]`).forEach(r=>{let i=r.querySelector(`[data-theme-toggle-icon]`),a=r.querySelector(`[data-theme-toggle-state]`);i?i.innerHTML=n:r.innerHTML=n,a&&(a.textContent=e,a.dataset.theme=this.currentTheme),r.setAttribute(`aria-label`,`Theme: ${e}. Switch to ${t} mode`),r.setAttribute(`title`,`Theme: ${e}. Switch to ${t} mode`)})}},Pc=class{constructor(e){this.container=e}show(e,t=3e3){if(!this.container)return null;let n=typeof t==`number`?{duration:t}:{...t??{}},r=Number(n.duration)>0?Number(n.duration):0,i=document.createElement(`div`);i.className=`toast`,typeof n.tone==`string`&&n.tone&&(i.dataset.tone=n.tone);let a=document.createElement(`span`);a.className=`toast__message`,a.textContent=e,i.appendChild(a);let o=()=>{i.isConnected&&!i.classList.contains(`leaving`)&&(i.classList.add(`leaving`),i.addEventListener(`animationend`,()=>i.remove(),{once:!0}))};if(n.actionLabel&&typeof n.onAction==`function`){let e=document.createElement(`button`);e.className=`toast__action`,e.type=`button`,e.textContent=n.actionLabel,e.addEventListener(`click`,()=>{n.onAction(),n.closeOnAction!==!1&&o()}),i.appendChild(e)}if(n.dismissible){let e=document.createElement(`button`);e.className=`toast__dismiss`,e.type=`button`,e.setAttribute(`aria-label`,`Dismiss notification`),e.textContent=`Close`,e.addEventListener(`click`,o),i.appendChild(e)}return this.container.appendChild(i),r>0&&setTimeout(o,r),i}},Fc=[$t,en,hn,_n,wn,{...Lr,...Zr,...Fn,...Bi,...ii},Vi],Ic=class{constructor(){for(let e of Fc)for(let[t,n]of Object.entries(e))t in this||(this[t]=n);this.elements=qt(document),this.runtimeConfig=Be(),this.activeSidebarTab=`files`,this.chatInitialSyncComplete=!1,this.chatIsOpen=!1,this.chatMessageIds=new Set,this.chatMessages=[],this.chatUnreadCount=0,this.connectionHelpShown=!1,this.connectionState={status:`disconnected`,unreachable:!1},this.currentDrawioMode=null,this.currentFilePath=null,this.fileExplorerReady=!1,this.followedCursorSignature=``,this.followedUserClientId=null,this.gitRepoAvailable=!1,this.globalUsers=[],this.isTabActive=!1,this.presencePanelOpen=!1,this.sessionLoadToken=0,this.navigation={getHashRoute:Ge,navigateToFile:(e,t={})=>{let{preserveFollow:n=!1,...r}=t;!n&&e!==this.currentFilePath&&this.stopFollowingUser(),Re(e,r)},navigateToGitCommit:Fe,navigateToGitDiff:Ve,navigateToGitFileHistory:We,navigateToGitFilePreview:Ie,navigateToGitHistory:ze},this.preferences=new Wi,this.notifications=new Ki,this.gitApiClient=Xi,this.vaultApiClient=ce,this._session=null,this._hasPromptedForDisplayName=!1,this._basePreviewRenderTimer=null,this._backlinkRefreshTimer=null,this._previewLayoutResizeObserver=null,this._reloadPromptShown=!1,this._staticPreviewDocument=null,this.pendingGitResetPath=null,this.chatTimeFormatter=new Intl.DateTimeFormat(void 0,{hour:`numeric`,minute:`2-digit`}),this.lobbyChatMessageMaxLength=280,this.quickSwitcher=null,this.quickSwitcherModulePromise=null,this.fileExplorerReadyPromise=Promise.resolve(),this.mobileBreakpointQuery=window.matchMedia(`(max-width: 768px)`),this.pendingWorkspaceRequestIds=new Set,this._fileOpenPerf=null,this.versionMonitor=new Yi({currentBuildId:this.runtimeConfig.build?.id,onUpdateAvailable:e=>this.promptForVersionReload(e),runtimeConfig:this.runtimeConfig}),this.lobby=Za({preferredUserName:this.getStoredUserName(),onChange:e=>this.updateGlobalUsers(e),onChatChange:(e,t)=>this.updateChatMessages(e,t)}),this.workspaceSync=Qa({onTreeChange:(e,t={})=>{this.fileExplorer.setTree(e,t),this.handleCommentOverviewWorkspaceTreeChange?.(),this.fileExplorerReady=!0},onWorkspaceEvent:e=>{this.handleIncomingWorkspaceEvent(e)}}),this.toastController=new Pc(this.elements.toastContainer),this.chatToastController=new Pc(this.elements.chatToastContainer),this.agentConnectionController=new no({apiClient:Hi,closeToolbarMenu:()=>this.closeToolbarOverflowMenu(),content:this.elements.agentConnectionContent,dialog:this.elements.agentConnectionDialog,runtimeConfig:this.runtimeConfig,toastController:this.toastController,trigger:this.elements.connectAgentButton}),this.teamSettingsController=new co({apiClient:Gi,closeToolbarMenu:()=>this.closeToolbarOverflowMenu(),content:this.elements.teamSettingsContent,dialog:this.elements.teamSettingsDialog,toastController:this.toastController,trigger:this.elements.teamSettingsButton}),this.hostedGateController=new io({apiClient:Gi,appRoot:this.elements.appShell,gate:this.elements.hostedGate,runtimeConfig:this.runtimeConfig,teamSettingsController:this.teamSettingsController});let e=(...e)=>this.vaultApiClient.callAgentTool(...e);this.webMcpTools=new Ya({acknowledgeToolCall:({input:e,name:t,preparation:n,result:r,signal:i})=>t!==`edit_excalidraw`||e.path!==this.currentFilePath?null:this.excalidrawEmbed?.waitForAgentPaint(e.path,r.revision,{afterRevision:n?.revision,signal:i}),callTool:(t,n,r)=>t===`render_diagram`?Ot(n,{callTool:e,getMermaid:()=>this.previewRenderer.mermaidHydrator.ensureMermaid(),signal:r?.signal}):e(t,n,r),getActiveContext:async()=>{let e=this.currentFilePath,t=this.session,n=t?.activeFilePath===e?await t.getAgentContext():null;if(e!==this.currentFilePath||t!==this.session)throw Error(`Active document changed; request active context again`);return{...n,activeDiagramPath:this.isExcalidrawFile(e)?e:null,activePath:e}},getIsTabActive:()=>this.isTabActive,onDidMutate:()=>{this.toastController.show(`Agent-assisted Vault change applied. Review it before committing.`)},prepareToolCall:async({input:e,name:t,signal:n})=>{if(![`edit_excalidraw`,`inspect_excalidraw`,`read_document`,`verify_excalidraw`].includes(t)||e.path!==this.currentFilePath)return null;let r=await this.excalidrawEmbed?.flushPendingAgentWrites(e.path,{signal:n});if([`timeout`,`unavailable`].includes(r?.status))throw Error(`The active Excalidraw editor did not confirm its latest collaboration update`);return r}}),this.fileExplorer=new As({mobileBreakpointQuery:this.mobileBreakpointQuery,onDirectoryExport:(e,t)=>this.handleDirectoryExportRequest(e,t),onFileDelete:()=>this.navigation.navigateToFile(null),onFileSelect:e=>this.workspaceRouteController.handleFileSelection(e,{closeSidebarOnMobile:!0}),onShowFileExtensionsChange:e=>{this.preferences.setFileTreeShowExtensions(e)},pendingWorkspaceRequestIds:this.pendingWorkspaceRequestIds,showFileExtensions:this.preferences.getFileTreeShowExtensions(),toastController:this.toastController,vaultClient:this.vaultApiClient,vaultSwitcher:{activeVaultId:P(this.runtimeConfig),vaults:this.runtimeConfig.vaults??[],onVaultSelect:async e=>{if(!e||e===P(this.runtimeConfig)||!await this.workspaceRouteController.prepareActiveEmbedDisconnect())return;Me(e);let t=new URL(window.location.href);t.searchParams.set(`vault`,e),window.location.assign(t.toString())}}}),this.commentsOverview=new uo({onOverviewChange:(e,{threadCounts:t})=>{this.fileExplorer.setThreadCounts(t)},onThreadSelect:e=>this.openCommentOverviewThread(e),panelElement:this.elements.commentOverviewPanel,toastController:this.toastController,vaultApiClient:this.vaultApiClient}),this.gitPanel=new gc({enabled:this.runtimeConfig.gitEnabled!==!1,gitApiClient:this.gitApiClient,onCommitStaged:()=>this.openGitCommitDialog(),onOpenPullBackup:e=>e&&window.open(Xi.getPullBackupSummaryUrl(e),`_blank`,`noopener,noreferrer`),onPullBranch:()=>this.pullGitBranch(),onPushBranch:()=>this.pushGitBranch(),onRepoChange:(e,t)=>this.handleGitRepoChange(e,t),onResetFile:(e,{scope:t})=>this.openGitResetDialog(e,{scope:t}),onSelectCommit:(e,{path:t})=>this.handleGitCommitSelection(e,{closeSidebarOnMobile:!0,path:t}),onSelectDiff:(e,{scope:t})=>this.handleGitDiffSelection(e,{closeSidebarOnMobile:!0,scope:t}),onStageAll:()=>this.stageAllGitFiles(),onStageFile:(e,{scope:t})=>this.stageGitFile(e,{scope:t}),onUnstageAll:()=>this.unstageAllGitFiles(),onUnstageFile:(e,{scope:t})=>this.unstageGitFile(e,{scope:t}),onViewAllDiff:()=>this.handleGitDiffSelection(null,{closeSidebarOnMobile:!0,scope:`all`}),searchInput:this.elements.gitSearchInput,toastController:this.toastController}),this.outlineController=new vc({mobileBreakpointQuery:this.mobileBreakpointQuery,onNavigateToHeading:({headingId:e,sourceLine:t})=>{let n=document.getElementById(e);this.elements.previewContent?.contains(n)&&this.unfoldPreviewHeading(n),Number.isFinite(t)&&(this.scrollSyncController.suspendSync(250),this.session?.scrollToLine(t,0))},onWillOpen:()=>this.commentUi?.closeDrawer()}),this.videoEmbed=new ye({previewElement:this.elements.previewContent}),this.basesPreview=new he({getActiveFilePath:()=>this.currentFilePath,getSession:()=>this.session,onOpenFile:e=>e&&this.navigation.navigateToFile(e),previewElement:this.elements.previewContent,replaceBaseSource:({path:e,source:t})=>{e&&e===this.currentFilePath&&this.session?.replaceText?.(t)},toastController:this.toastController,vaultApiClient:this.vaultApiClient}),this.imageLightbox=new Ee({previewElement:this.elements.previewContent}),this.previewRenderer=new we({getContent:()=>this.getPreviewSource(),getFileList:()=>this.fileExplorer.flatDocumentFiles,getPreviewVisible:()=>!!this._staticPreviewDocument||this.layoutController?.currentView!==`editor`,getTheme:()=>this.themeController?.getTheme?.()??`dark`,getWikiLinkAutoCreate:()=>this.runtimeConfig.wikiLinkAutoCreate!==!1,loadFileSource:async e=>{let t=await this.vaultApiClient.readFile(e);return String(t?.content??``)},getSourceFilePath:()=>this.currentFilePath,onAfterRenderCommit:(e,t)=>{this.recordFileOpenMetric(`preview_committed`,{chars:t?.chars??0,renderVersion:t?.renderVersion??0}),this.videoEmbed.reconcileEmbeds(this.elements.previewContent),this.basesPreview.reconcileEmbeds(this.elements.previewContent),this.drawioEmbed.reconcileEmbeds(this.elements.previewContent),this.excalidrawEmbed.reconcileEmbeds(this.elements.previewContent,{isLargeDocument:t.isLargeDocument}),this.scrollSyncController.setLargeDocumentMode(t.isLargeDocument),this.syncPreviewHeadingFoldButtons(),this.syncPreviewHeadingLinkButtons(),this.applyPendingPreviewRouteAnchor({behavior:`auto`,clearMissing:!0}),this.schedulePreviewLayoutSync({delayMs:0}),this.refreshCommentUiLayout()},onBeforeRenderCommit:()=>{this.videoEmbed.detachForCommit(),this.drawioEmbed.detachForCommit(),this.excalidrawEmbed.detachForCommit()},onPreviewLayoutChange:()=>{this.scrollSyncController.invalidatePreviewBlocks(),this.applyPendingPreviewRouteAnchor({behavior:`auto`,clearMissing:!1}),this.schedulePreviewLayoutSync({delayMs:0}),this.refreshCommentUiLayout()},outlineController:this.outlineController,plantUmlRenderClient:this.vaultApiClient,previewContainer:this.elements.previewContainer,previewElement:this.elements.previewContent,toastController:this.toastController}),this.themeController=new Nc({onChange:e=>this.handleThemeChange(e)}),this.layoutController=new _c({preferredView:this.preferences.getViewMode()||`split`,mobileBreakpointQuery:this.mobileBreakpointQuery,onMeasureEditor:()=>this.session?.requestMeasure(),onPreferredViewChange:e=>this.preferences.setViewMode(e),onViewChange:()=>{(this.currentFilePath||this._staticPreviewDocument)&&this.previewRenderer.queueRender()},onViewRequest:e=>this.handleLayoutViewRequest(e)}),this.scrollSyncController=new Ac({getEditorLineNumber:()=>this.session?.getTopVisibleLineNumber(.35)??1,onEditorScrollActivityChange:e=>this.handleEditorScrollActivityChange(e),previewContainer:this.elements.previewContainer,previewElement:this.elements.previewContent,scrollEditorToLine:(e,t)=>this.session?.scrollToLine(e,t)}),this.pdfPreview=new wt({getTheme:()=>this.themeController.getTheme()}),this.backlinksPanel=new ro({headerPanelElement:this.elements.backlinksHeaderPanel,inlinePanelElement:this.elements.backlinksInlinePanel,loadBacklinks:(e,t={})=>this.vaultApiClient.readBacklinks(e,t),onBeforeToggle:()=>this.scrollSyncController.suspendSync(250),onFileSelect:e=>this.workspaceRouteController.handleFileSelection(e,{closeSidebarOnMobile:!0}),panelElement:this.elements.backlinksPanel}),this.canvasEmbed=new Is({getLocalUser:()=>this.lobby.getLocalUser(),getTheme:()=>this.themeController.getTheme(),onAwarenessChange:e=>this.updateFileAwareness(e),onConnectionChange:e=>this.handleConnectionChange(e),onOpenFile:(e,t)=>{this.fileExplorer.flatFiles.includes(e)&&this.navigation.navigateToFile(e,t)},toastController:this.toastController}),this.excalidrawEmbed=new me({getLocalUser:()=>this.lobby.getLocalUser(),getTheme:()=>this.themeController.getTheme(),onOpenElement:({elementId:e,elementType:t,filePath:n}={})=>{n&&e&&this.navigation.navigateToFile(n,{elementId:e,elementType:t})},onOpenFile:e=>e&&this.navigation.navigateToFile(e),onStopFollowing:()=>this.stopFollowingUser(),onToggleQuickSwitcher:()=>{this.toggleQuickSwitcher()},previewContainer:this.elements.previewContainer,previewElement:this.elements.previewContent,toastController:this.toastController}),this.drawioEmbed=new Ce({getLocalUser:()=>this.lobby.getLocalUser(),getTheme:()=>this.themeController.getTheme(),onOpenFile:e=>e&&this.navigation.navigateToFile(e),onOpenTextFile:e=>e&&this.navigation.navigateToFile(e,{drawioMode:`text`}),onToggleQuickSwitcher:()=>{this.toggleQuickSwitcher()},previewContainer:this.elements.previewContainer,previewElement:this.elements.previewContent,toastController:this.toastController,vaultApiClient:this.vaultApiClient}),this.commentUi=new ms({commentSelectionButton:this.elements.commentSelectionButton,commentsDrawer:this.elements.commentsDrawer,commentsDrawerEmpty:this.elements.commentsDrawerEmpty,commentsDrawerList:this.elements.commentsDrawerList,commentsToggleButton:this.elements.commentsToggleButton,editorContainer:this.elements.editorContainer,onWillOpenDrawer:()=>{this._deferredCollabStylesPromise??=A(()=>Promise.resolve({}),__vite__mapDeps([0]),import.meta.url),this.outlineController.close()},previewContainer:this.elements.previewContainer,previewElement:this.elements.previewContent,onCreateThread:({anchor:e,body:t})=>this.createCommentThread({anchor:e,body:t}),onNavigateToLine:e=>{let t=this.session;this.scrollSyncController.suspendSync(250),t?.scrollToLine(e,.2)&&requestAnimationFrame(()=>{this.session===t&&(this.scrollSyncController.suspendSync(0),this.scrollSyncController.syncPreviewToEditor())})},onReplyToThread:(e,t)=>this.replyToCommentThread(e,t),onToggleReaction:(e,t,n)=>this.session?.toggleCommentReaction(e,t,n),onResolveThread:e=>this.resolveCommentThread(e)}),this.structurizrPreview=new Ut({enabled:this.runtimeConfig.structurizrEnabled===!0,syncWorkspace:e=>this.vaultApiClient.syncStructurizrWorkspace(e)}),this.workspacePreviewController=new Lt({backlinksPanel:this.backlinksPanel,basesPreview:this.basesPreview,canvasEmbed:this.canvasEmbed,drawioEmbed:this.drawioEmbed,elements:this.elements,excalidrawEmbed:this.excalidrawEmbed,getDisplayName:e=>this.getDisplayName(e),getSession:()=>this.session,isBaseFile:e=>this.isBaseFile(e),isDrawioFile:e=>this.isDrawioFile(e),isExcalidrawFile:e=>this.isExcalidrawFile(e),isImageFile:e=>this.isImageFile(e),isPdfFile:e=>this.isPdfFile(e),isMermaidFile:e=>this.isMermaidFile(e),isPlantUmlFile:e=>this.isPlantUmlFile(e),layoutController:this.layoutController,structurizrPreview:this.structurizrPreview,outlineController:this.outlineController,pdfPreview:this.pdfPreview,previewRenderer:this.previewRenderer,scrollSyncController:this.scrollSyncController,videoEmbed:this.videoEmbed}),this.wikiLinkFileController=new Mt({getFileList:()=>this.fileExplorer.flatDocumentFiles,navigation:this.navigation,refreshExplorer:()=>this.fileExplorer.refresh(),toastController:this.toastController,vaultApiClient:this.vaultApiClient,wikiLinkAutoCreate:this.runtimeConfig.wikiLinkAutoCreate!==!1}),this.gitDiffView=new oc({getTheme:()=>this.themeController.getTheme(),gitApiClient:this.gitApiClient,onBackToHistory:({historyFilePath:e}={})=>{if(e){this.navigation.navigateToGitFileHistory({filePath:e});return}this.navigation.navigateToGitHistory()},onCommitStaged:()=>this.openGitCommitDialog(),onOpenFile:e=>e&&this.navigation.navigateToFile(e),onStageFile:(e,{scope:t})=>this.stageGitFile(e,{scope:t}),onUnstageFile:(e,{scope:t})=>this.unstageGitFile(e,{scope:t}),toastController:this.toastController,vaultApiClient:this.vaultApiClient}),this.fileHistoryView=new Fs({diffRenderer:this.gitDiffView,gitApiClient:this.gitApiClient,onOpenCommitDiff:(e,{historyFilePath:t,path:n})=>this.handleGitCommitSelection(e,{closeSidebarOnMobile:!1,historyFilePath:t,path:n}),onOpenFile:e=>e&&this.navigation.navigateToFile(e),onOpenPreview:({hash:e,path:t,currentFilePath:n})=>this.handleGitFilePreviewSelection({hash:e,path:t,currentFilePath:n}),onOpenWorkspaceDiff:e=>this.handleGitDiffSelection(e,{closeSidebarOnMobile:!1,scope:`all`}),toastController:this.toastController}),this.tabActivityLock=new ia({onActivated:({takeover:e})=>this.handleTabActivated({takeover:e}),onBlocked:()=>this.handleTabBlocked({reason:`active-elsewhere`}),onStolen:()=>this.handleTabBlocked({reason:`taken-over`})}),this.workspaceCoordinator=new Kt({attachEditorScroller:e=>this.scrollSyncController.attachEditorScroller(e),beginDocumentLoad:()=>this.previewRenderer.beginDocumentLoad(),cleanupAfterSessionDestroy:()=>{this.canvasEmbed.unmount(),this.scrollSyncController.setLargeDocumentMode(!1),this.scrollSyncController.invalidatePreviewBlocks(),this.outlineController.cleanup(),this.followedCursorSignature=``,clearTimeout(this._backlinkRefreshTimer)},createEditorSession:(e,t)=>new e({editorContainer:this.elements.editorContainer,getFileList:t.getFileList,initialTheme:t.theme,lineInfoElement:this.elements.lineInfo,lineWrappingEnabled:t.lineWrappingEnabled,localUser:t.localUser,vimModeEnabled:t.vimModeEnabled,onImagePaste:t.onImagePaste,onAwarenessChange:t.onAwarenessChange,onCommentsChange:t.onCommentsChange,onConnectionChange:t.onConnectionChange,onContentChange:t.onContentChange,onSelectionChange:t.onSelectionChange,preferredUserName:t.preferredUserName}),getDisplayName:e=>this.getDisplayName(e),getFileList:()=>this.fileExplorer.flatDocumentFiles,getVaultFileList:()=>this.fileExplorer.flatFiles,getLineWrappingEnabled:()=>this.getStoredLineWrapping(),getVimModeEnabled:()=>this.getStoredVimMode(),getLocalUser:()=>this.lobby.getLocalUser(),getStoredUserName:()=>this.getStoredUserName(),getTheme:()=>this.themeController.getTheme(),isBaseFile:e=>this.isBaseFile(e),isCanvasFile:e=>this.isCanvasFile(e),isDrawioFile:e=>this.isDrawioFile(e),isExcalidrawFile:e=>this.isExcalidrawFile(e),isImageFile:e=>this.isImageFile(e),isPdfFile:e=>this.isPdfFile(e),isMermaidFile:e=>this.isMermaidFile(e),isPlantUmlFile:e=>this.isPlantUmlFile(e),isStructurizrWorkspaceFile:e=>this.isStructurizrWorkspaceFile(e),isTabActive:()=>this.isTabActive,loadBootstrapContent:async e=>{let t=await this.vaultApiClient.readFile(e);return typeof t?.content==`string`?t.content:null},loadEditorSessionClass:()=>this.loadEditorSessionClass(),loadBacklinks:e=>this.backlinksPanel.load(e),onBeforeFileOpen:()=>{clearTimeout(this._basePreviewRenderTimer),this._basePreviewRenderTimer=null,this.connectWorkspaceSync?.(),this.session=null,this.commentUi.attachSession(null),this.layoutController.reset(),this.workspacePreviewController.resetPreviewMode(),this.elements.emptyState?.classList.add(`hidden`),this.elements.editorPage?.classList.remove(`hidden`),this.elements.diffPage?.classList.add(`hidden`),this.clearInitialFileBootstrap()},onConnectionChange:e=>this.handleConnectionChange(e),onContentChange:({isBase:e,isHtml:t,isStructurizrWorkspace:n})=>{if(this.webMcpTools.refresh(),this.handleCommentEditorContentChange(),t){this.workspacePreviewController.renderHtmlFilePreview({content:this.session?.getText?.()??``});return}if(e){this.scheduleBaseFilePreview(this.currentFilePath,{source:this.session?.getText?.()??``});return}if(n){this.structurizrPreview.queueSync({filePath:this.currentFilePath,source:this.session?.getText?.()??``});return}let r=this.session?.getText?.()??``;!this.preferences.getViewMode()&&this.layoutController.currentView===`split`&&ke(Ae(r))&&this.layoutController.setView(`editor`,{persist:!1}),this.previewRenderer.queueRender()},onCommentsChange:e=>this.handleCommentThreadsChange(e),onFileAwarenessChange:e=>this.updateFileAwareness(e),onFileOpenError:({code:e}={})=>{this.currentFilePath=null;let t=e===`not-found`;this.showEditorLoadError(t?`File not found`:`Failed to load file`),this.syncWrapToggle(),this.toastController.show(t?`File not found`:`Failed to initialize editor`)},onFileOpenReady:()=>{this.hideEditorLoading(),this.currentFilePath&&this.preferences.recordRecentFile(this.currentFilePath)},onSelectionChange:e=>this.handleCommentSelectionChange(e),onImagePaste:e=>this.handleEditorImageInsert(e),onFileOpenMetric:(e,t)=>this.recordFileOpenMetric(e,t),onSessionAssigned:e=>{this.session=e,this.commentUi.attachSession(e)},onRenderDrawioPreview:e=>this.workspacePreviewController.renderDrawioFilePreview(e),onRenderBasePreview:e=>this.renderBaseFilePreview(e),onRenderCanvasPreview:e=>this.workspacePreviewController.renderCanvasFilePreview(e),onRenderExcalidrawPreview:e=>this.workspacePreviewController.renderExcalidrawFilePreview(e),onRenderHtmlPreview:e=>this.workspacePreviewController.renderHtmlFilePreview(e),onRenderImagePreview:e=>this.workspacePreviewController.renderImageFilePreview(e),onRenderPdfPreview:e=>this.workspacePreviewController.renderPdfFilePreview(e),onRenderStructurizrPreview:(e,t)=>this.workspacePreviewController.renderStructurizrFilePreview(e,t),onSyncWrapToggle:()=>this.syncWrapToggle(),onUpdateActiveFile:e=>this.fileExplorer.setActiveFile(e),onUpdateCurrentFile:e=>{this.currentFilePath=e},onUpdateLobbyCurrentFile:e=>this.lobby.setCurrentFile(e),onUpdateVisibleChrome:(e,{displayName:t})=>{this.workspacePreviewController.syncFileChrome(e,{drawioMode:this.currentDrawioMode,preferPreviewForBase:this.isBaseFile(e)}),this.syncCommentChrome(e),this.syncFileHistoryButton({filePath:e,mode:`editor`}),this.syncReviewFileChangesButton({filePath:e,mode:`editor`}),this.elements.activeFileName&&(this.elements.activeFileName.textContent=t)},onViewModeReset:()=>this.workspacePreviewController.resetPreviewMode(),renderPresence:()=>this.renderPresence(),scrollContainerForSession:e=>e.getScrollContainer(),shouldUseDrawioPreview:()=>!!this.runtimeConfig.drawioBaseUrl,showEditorLoading:()=>this.showEditorLoading(),stateStore:this}),this.workspaceRouteController=new jt({backlinksPanel:this.backlinksPanel,canvasEmbed:this.canvasEmbed,clearInitialFileBootstrap:()=>this.clearInitialFileBootstrap(),clearStaticPreviewDocument:()=>this.clearStaticPreviewDocument(),closeSidebarOnMobile:()=>this.closeSidebarOnMobile(),drawioEmbed:this.drawioEmbed,elements:this.elements,excalidrawEmbed:this.excalidrawEmbed,fileHistoryView:this.fileHistoryView,fileExplorer:this.fileExplorer,getIsTabActive:()=>this.isTabActive,getSessionLoadToken:()=>this.sessionLoadToken,gitDiffView:this.gitDiffView,gitPanel:this.gitPanel,imageLightbox:this.imageLightbox,layoutController:this.layoutController,lobby:this.lobby,navigation:this.navigation,previewRenderer:this.previewRenderer,requestPreviewRouteAnchor:(e,t)=>this.requestPreviewRouteAnchor(e,t),renderAvatars:()=>this.renderAvatars(),renderPresence:()=>this.renderPresence(),resetPreviewMode:()=>this.workspacePreviewController.resetPreviewMode(),scrollSyncController:this.scrollSyncController,setCurrentFilePath:e=>{this.currentFilePath=e,e||(this.commentUi.setCurrentFile(null,{supported:!1}),this.handleCommentThreadsChange([]),this.handleCommentSelectionChange(null))},setSession:e=>{this.session=e,this.commentUi.attachSession(e)},setSessionLoadToken:e=>{this.sessionLoadToken=e},setSidebarTab:e=>this.setSidebarTab(e),setSidebarVisibility:e=>this.setSidebarVisibility(e),showGitCommit:e=>this.showGitCommit(e),showGitDiff:e=>this.showGitDiff(e),showGitFileHistory:e=>this.showGitFileHistory(e),showGitFilePreview:e=>this.showGitFilePreview(e),showGitHistory:()=>this.showGitHistory(),syncMainChrome:e=>this.syncMainChrome(e),videoEmbed:this.videoEmbed,workspaceCoordinator:this.workspaceCoordinator})}get currentFilePath(){return this._currentFilePath}set currentFilePath(e){this._currentFilePath=e,document.title=e?`${this.getDisplayName(e)} — CollabMD`:`CollabMD — Collaborative Markdown Vault`}get session(){return this._session}set session(e){this._session=e,this.webMcpTools?.refresh()}publishFileOpenPerf(){typeof window<`u`&&(window.__COLLABMD_PERF__??={},window.__COLLABMD_PERF__.fileOpen=this._fileOpenPerf?{...this._fileOpenPerf,details:{...this._fileOpenPerf.details},marks:{...this._fileOpenPerf.marks}}:null)}recordFileOpenMetric(e,t={}){if(e===`open_started`){this._fileOpenPerf={details:{filePath:t.filePath||this.currentFilePath||``,loadToken:t.loadToken??0},marks:{open_started:performance.now()}},this.publishFileOpenPerf();return}this._fileOpenPerf&&(t.loadToken??this._fileOpenPerf.details.loadToken)===this._fileOpenPerf.details.loadToken&&(this._fileOpenPerf.marks[e]=performance.now(),t.filePath&&(this._fileOpenPerf.details.filePath=t.filePath),Object.entries(t).forEach(([e,t])=>{e!==`filePath`&&e!==`loadToken`&&(this._fileOpenPerf.details[e]=t)}),this.publishFileOpenPerf())}loadEditorSessionClass(){return this._editorSessionModulePromise||=A(()=>import(`./editor-session-CPsqXY_A.js`).then(e=>e.EditorSession),[],import.meta.url),this._editorSessionModulePromise}loadQuickSwitcherController(){return Promise.all([A(()=>import(`./quick-switcher-controller-DsK70I7K.js`),[],import.meta.url),A(()=>Promise.resolve({}),__vite__mapDeps([2]),import.meta.url)]).then(([e])=>e.QuickSwitcherController)}async ensureQuickSwitcher(){return kt(this)}async toggleQuickSwitcher(){return At(this)}};function Lc({container:e,vaults:t,getVaultUrl:n,onSelect:r}){e.removeAttribute(`role`),e.classList.add(`vault-dashboard`),e.innerHTML=`
|
|
933
|
+
<main class="vault-dashboard-card" aria-labelledby="vaultDashboardTitle">
|
|
934
|
+
<header class="vault-dashboard-header">
|
|
935
|
+
<div class="sidebar-brand">
|
|
936
|
+
<svg width="28" height="28" viewBox="0 0 32 32" fill="none" aria-hidden="true">
|
|
937
|
+
<rect x="3" y="4" width="17" height="24" rx="3" stroke="var(--color-primary)" stroke-width="2"></rect>
|
|
938
|
+
<rect x="12" y="4" width="17" height="24" rx="3" fill="var(--color-primary)"></rect>
|
|
939
|
+
<path d="M17 12h7m-7 4h7m-7 4h4" stroke="var(--color-primary-contrast)" stroke-width="1.5"></path>
|
|
940
|
+
</svg>
|
|
941
|
+
<span class="sidebar-title">CollabMD</span>
|
|
942
|
+
</div>
|
|
943
|
+
<h1 id="vaultDashboardTitle">Choose a vault</h1>
|
|
944
|
+
<p>Open a project to start collaborating.</p>
|
|
945
|
+
</header>
|
|
946
|
+
<div class="vault-dashboard-search">
|
|
947
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" aria-hidden="true"><circle cx="10.5" cy="10.5" r="6.5"></circle><path d="m16 16 4 4"></path></svg>
|
|
948
|
+
<input type="search" class="ui-input" aria-label="Find a vault" placeholder="Find a vault…">
|
|
949
|
+
</div>
|
|
950
|
+
<div class="vault-dashboard-list-heading">
|
|
951
|
+
<h2>Your vaults</h2>
|
|
952
|
+
<span class="ui-pill-badge ui-pill-badge--count ui-pill-badge--muted"></span>
|
|
953
|
+
</div>
|
|
954
|
+
<nav aria-label="Vaults"></nav>
|
|
955
|
+
<p class="ui-empty-state" role="status" hidden>No matching vaults.</p>
|
|
956
|
+
<footer class="vault-dashboard-footer">Press <kbd>Enter</kbd> to open the first match</footer>
|
|
957
|
+
</main>`,e.querySelector(`.ui-pill-badge`).textContent=String(t.length);let i=e.querySelector(`nav`),a=e.querySelector(`[role="status"]`),o=t.map(e=>{let t=document.createElement(`a`);return t.className=`ui-record-surface vault-dashboard-link`,t.href=n(e.id),t.innerHTML=`
|
|
958
|
+
<span class="vault-dashboard-icon" aria-hidden="true"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path></svg></span>
|
|
959
|
+
<span class="vault-dashboard-name"></span>
|
|
960
|
+
<svg class="vault-dashboard-arrow" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14m-5-5 5 5-5 5"></path></svg>`,t.querySelector(`.vault-dashboard-name`).textContent=e.name||e.id,t.addEventListener(`click`,()=>r?.(e.id)),i.append(t),{link:t,text:`${e.name||e.id} ${e.id}`.toLowerCase()}}),s=e.querySelector(`input`);s.addEventListener(`input`,()=>{let e=s.value.trim().toLowerCase();o.forEach(({link:t,text:n})=>{t.hidden=!(!e||n.includes(e)||qe(n,e))}),a.hidden=o.some(({link:e})=>!e.hidden)}),s.addEventListener(`keydown`,e=>{e.key===`Enter`&&(e.preventDefault(),o.find(({link:e})=>!e.hidden)?.link.click())}),s.focus()}async function Rc(){await ae();let e=Be(),t=new URL(window.location.href);if(e.vaultDashboard&&e.vaults.length>1&&!t.searchParams.has(`vault`)&&!t.searchParams.has(`file`)&&!t.hash){Lc({container:document.getElementById(`workspaceLoading`),vaults:e.vaults,getVaultUrl:e=>{let n=new URL(t);return n.searchParams.set(`vault`,e),n.toString()},onSelect:Me});return}Ue(),await new Ic().initialize(),delete document.documentElement.dataset.workspaceLoading,document.getElementById(`workspaceLoading`)?.remove()}function zc(){Rc().catch(()=>{let e=document.getElementById(`workspaceLoading`);e&&(e.textContent=`Unable to open the workspace. Reload to try again.`)})}document.readyState===`loading`?document.addEventListener(`DOMContentLoaded`,zc,{once:!0}):zc();
|