collabmd 0.1.46 → 0.1.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/README.md +1 -0
  2. package/dist/client/assets/{CodeMirrorEditor-UCMRAMCV-CYM5nxUi.js → CodeMirrorEditor-UCMRAMCV-BPH4FJkv.js} +1 -1
  3. package/dist/client/assets/{abnfDiagram-N423BO3Z-CUMTFJhI.js → abnfDiagram-VCTEODGH-BNDLzJ7L.js} +1 -1
  4. package/dist/client/assets/architecture-7GRP2DOG-BMOPAkUC.js +1 -0
  5. package/dist/client/assets/{architectureDiagram-T3A2C74G-w25m71oV.js → architectureDiagram-5GKGNRK7-I39sYjHI.js} +1 -1
  6. package/dist/client/assets/base-BYODPHdS.js +1 -0
  7. package/dist/client/assets/blockDiagram-NRAW4CY4-C6DtJy5Y.js +129 -0
  8. package/dist/client/assets/browser-BKLM0ThC-IxjwuOIz-BBqQnUEb.js +1 -0
  9. package/dist/client/assets/c4Diagram-UCG6FXSJ-CtWtxS9_.js +38 -0
  10. package/dist/client/assets/channel-CaoKA_We.js +1 -0
  11. package/dist/client/assets/{chunk-U6XO7XAA-BFxjP5U3.js → chunk-2ZTRR5NV-C2qZJila.js} +1 -1
  12. package/dist/client/assets/{chunk-YOTPTUD7-D0vRKqYp.js → chunk-3Z5EZCMW-DMniOlPd.js} +1 -1
  13. package/dist/client/assets/{chunk-BIQX33UG-DZEsGuSn.js → chunk-5V3GS4D5-i-ZDOEnP.js} +1 -1
  14. package/dist/client/assets/{chunk-MOZMSUNE-XVucA-n6.js → chunk-6AZGARVD-BB6FqMl-.js} +1 -1
  15. package/dist/client/assets/{chunk-5JV3BV7I-Cy5pj3QY.js → chunk-6EIED4P4-DdUJkP0f.js} +1 -1
  16. package/dist/client/assets/{chunk-R7FJI6CG-Cnn3gE-Y.js → chunk-6K3QC6MW-CqVsVn-y.js} +1 -1
  17. package/dist/client/assets/{chunk-OSBZ3O6U-CrKZOUOr.js → chunk-6TQVIW2G-DKlLbNIP.js} +1 -1
  18. package/dist/client/assets/{chunk-JG7HCLWE-BYfiSaVt.js → chunk-747NJXEK-BFkZPlab.js} +1 -1
  19. package/dist/client/assets/{chunk-NSK5VX7P-TLH37VXI.js → chunk-75Z2AOVW-CdFSaPjz.js} +1 -1
  20. package/dist/client/assets/chunk-CKBBP62Z-DG26UiBv.js +2 -0
  21. package/dist/client/assets/{chunk-3NCLNEKW-Y2Jf_LI-.js → chunk-CLGD4ZFX-DQLgbQrv.js} +1 -1
  22. package/dist/client/assets/chunk-DSNCTWBM-8xkug7fQ.js +2 -0
  23. package/dist/client/assets/chunk-DU6HZSFF-COXDzJK1.js +127 -0
  24. package/dist/client/assets/{chunk-2GRJ4B5K-DhnlUv3F.js → chunk-F27PBJKO-CNHIFhjo.js} +1 -1
  25. package/dist/client/assets/{chunk-YGJVY4SA-CjSe7Bx7.js → chunk-FLYJHZSQ-Be7lKF17.js} +1 -1
  26. package/dist/client/assets/{chunk-KEIR6QF5-BICK3FdT.js → chunk-FOHPRMQF-DHwB1DNv.js} +2 -2
  27. package/dist/client/assets/{chunk-5RXB4S5H-BWrwFqMI.js → chunk-G27WJ6UU-D9-eg537.js} +2 -2
  28. package/dist/client/assets/chunk-GMAD6QVW-CbcBqPM5.js +72 -0
  29. package/dist/client/assets/{chunk-QBLGF6JB-CxAyS2mW.js → chunk-I5DQTOEV-Hm2LfiYI.js} +1 -1
  30. package/dist/client/assets/{chunk-5FCAYU7R-Dh5nylU8.js → chunk-ICYGCRZG-749o-pGJ.js} +1 -1
  31. package/dist/client/assets/{chunk-CQNSW5MT-B8S09OIh.js → chunk-IH6LHLGP-CC6I9F3i.js} +1 -1
  32. package/dist/client/assets/chunk-JQ64N6SF-DSFNH4bh.js +1 -0
  33. package/dist/client/assets/{chunk-CYSBUYHQ-C1Rf4art.js → chunk-KI3K4JFJ-Rma-0k_M.js} +1 -1
  34. package/dist/client/assets/{chunk-GF5L2VYU-DkJpO7ff.js → chunk-LCL6LL3I-DmDkVukh.js} +1 -1
  35. package/dist/client/assets/chunk-LNGE3PJU-DWpGwHrW.js +34 -0
  36. package/dist/client/assets/chunk-OBVCFTLP-BJR7u1jh.js +1 -0
  37. package/dist/client/assets/{chunk-5TONJI2A-DQOY3q1H.js → chunk-OUJLGHUK-D0j2JRSg.js} +1 -1
  38. package/dist/client/assets/chunk-P2QGCYS3-BRpqY32H.js +1 -0
  39. package/dist/client/assets/{chunk-KBJHAD2P-CB_3zWUf.js → chunk-POPQ4Y6H-Cb4SlVZF.js} +1 -1
  40. package/dist/client/assets/{chunk-4I5QYGJK-CCB2YcIH.js → chunk-PWAF6VOD-Cz8IwBB5.js} +1 -1
  41. package/dist/client/assets/chunk-R7TYR2AO-CTd0Yj98.js +10 -0
  42. package/dist/client/assets/chunk-RHFEMEQ7-CWY8cf4H.js +168 -0
  43. package/dist/client/assets/chunk-RM4UPSZO-CWRwxNWJ.js +41 -0
  44. package/dist/client/assets/{chunk-6Q2QTUOP-CPlWzBtc.js → chunk-SVP7TREG-CyHOmcac.js} +1 -1
  45. package/dist/client/assets/chunk-TEH6E4GO-DVayPj-q.js +62 -0
  46. package/dist/client/assets/{chunk-EMLP6XTP-RLD4nXpI.js → chunk-UY3FDG6J-CnmaAkG5.js} +1 -1
  47. package/dist/client/assets/{chunk-5HE753X5-Bw-yg4kO.js → chunk-XHIXRSVI-BFQ6B8BE.js} +1 -1
  48. package/dist/client/assets/classDiagram-DTDB5LWJ-7fEmn0zV.js +1 -0
  49. package/dist/client/assets/classDiagram-v2-JRS7N3AN-7fEmn0zV.js +1 -0
  50. package/dist/client/assets/{comment-ui-shared-BC4pt4w8.js → comment-ui-shared-DWkk9Vh3.js} +1 -1
  51. package/dist/client/assets/cynefin-OW5HDTMX-7tP7QfM3.js +1 -0
  52. package/dist/client/assets/{cynefinDiagram-MW4NZA55-CJxXfJek.js → cynefinDiagram-5FMLGOSQ-CdTPi2yO.js} +1 -1
  53. package/dist/client/assets/dagre-3AP2YEHR-5gtJtd0O.js +4 -0
  54. package/dist/client/assets/dagre-PrKaheQc.js +1 -0
  55. package/dist/client/assets/{diagram-7IWD3JNH-B2d2Bm15.js → diagram-S7CK7UJ4-BudWz9WU.js} +4 -4
  56. package/dist/client/assets/{diagram-UB23O5K3-DJcKCwv9.js → diagram-UQ7AKVKN-3v4rbH-s.js} +1 -1
  57. package/dist/client/assets/{diagram-B4RE2ZJO-NP4UAwjR.js → diagram-VSXAHHWV-CQRVEZR7.js} +1 -1
  58. package/dist/client/assets/{diagram-Q27KOJAE-DylDuwor.js → diagram-VX7I27RA-C_-rj0sw.js} +1 -1
  59. package/dist/client/assets/{diagram-LBJQPF4R-D1FJQV8t.js → diagram-Z3DM3KII-B4yxavgj.js} +1 -1
  60. package/dist/client/assets/direct-engine-DdrQKpgq-CtKfQzCt.js +5 -0
  61. package/dist/client/assets/dist-73RPdcyU.js +1 -0
  62. package/dist/client/assets/{dist-Bm6pf9Bl.js → dist-BJ1bJs33.js} +1 -1
  63. package/dist/client/assets/{dist-BalScOwZ.js → dist-BK9QvQrc.js} +1 -1
  64. package/dist/client/assets/{dist-DLMiIsNC.js → dist-BPHLJ09L.js} +1 -1
  65. package/dist/client/assets/{dist-Bf8f4HmM.js → dist-B_yQaEv_.js} +1 -1
  66. package/dist/client/assets/{dist-CC5IrQMG.js → dist-BeajGMhO.js} +1 -1
  67. package/dist/client/assets/{dist-PDZ3bSqm.js → dist-Bw3VIE_v.js} +1 -1
  68. package/dist/client/assets/{dist-xElaxbia.js → dist-ByrG2qBA.js} +1 -1
  69. package/dist/client/assets/{dist-ule2n6ak.js → dist-C5NgpdG5.js} +1 -1
  70. package/dist/client/assets/dist-CH-sQu3r.js +1 -0
  71. package/dist/client/assets/dist-CKS_-are.js +1 -0
  72. package/dist/client/assets/{dist-D-Z6FLem.js → dist-CdmKGRGr.js} +1 -1
  73. package/dist/client/assets/{dist-dtAdgL39.js → dist-CietwTVS.js} +1 -1
  74. package/dist/client/assets/{dist-jv4WdPnK.js → dist-D37Hyu3h.js} +1 -1
  75. package/dist/client/assets/dist-D3fehAZ2.js +2 -0
  76. package/dist/client/assets/{dist-BEwK4csK.js → dist-D5wCC32z.js} +1 -1
  77. package/dist/client/assets/{dist-shrl6K_0.js → dist-DDUn5zTz.js} +1 -1
  78. package/dist/client/assets/{dist-CZgOmxK6.js → dist-DGEbEfw4.js} +1 -1
  79. package/dist/client/assets/{dist-B5HTH2BO.js → dist-DVy5woUy.js} +1 -1
  80. package/dist/client/assets/{dist-DZKu9Cs8.js → dist-DZAAWTG-.js} +1 -1
  81. package/dist/client/assets/{dist-TjMh8n1u.js → dist-Dir5dDKZ.js} +1 -1
  82. package/dist/client/assets/dist-Dl_tpDSr.js +1 -0
  83. package/dist/client/assets/{dist-FWJsgGYI.js → dist-DuH3ZrHo.js} +1 -1
  84. package/dist/client/assets/{dist-BjHJDtyU.js → dist-DutPuFmC.js} +1 -1
  85. package/dist/client/assets/{dist-Cqhv5LAk.js → dist-LQ4kDCKz.js} +1 -1
  86. package/dist/client/assets/{dist-CCP_AKPG.js → dist-RKBTaQMb.js} +1 -1
  87. package/dist/client/assets/{dist-BoVBdSjk.js → dist-Tw-Fxpeb.js} +1 -1
  88. package/dist/client/assets/dist-eBx8q6Sy.js +1 -0
  89. package/dist/client/assets/{dist-rGBmqxC7.js → dist-mj2Ht75J.js} +1 -1
  90. package/dist/client/assets/{dist-BDt3rz7l.js → dist-netZOQtD.js} +1 -1
  91. package/dist/client/assets/{drawioEditor-BjiKJqlc.js → drawioEditor-DUVZjSSr.js} +2 -2
  92. package/dist/client/assets/{ebnfDiagram-BXEA7PRR-nw0wmA6y.js → ebnfDiagram-PWID7BFC-OXa8VEp1.js} +1 -1
  93. package/dist/client/assets/editor-session-DfZuRgB_.js +54 -0
  94. package/dist/client/assets/embedded-editor-base-DvMynhKu.css +1 -0
  95. package/dist/client/assets/embedpdf-BmE13ZZ0.js +1 -0
  96. package/dist/client/assets/embedpdf-DA4bA119-BPqZxwjc.js +2363 -0
  97. package/dist/client/assets/{en-7NFCYGKX-BrgYZAEe.js → en-SJ2YIMFF-CJBL3nkq.js} +1 -1
  98. package/dist/client/assets/erDiagram-SSCWMZ5O-C-iy6VkX.js +99 -0
  99. package/dist/client/assets/es-CAsWR6hG.js +22 -0
  100. package/dist/client/assets/eventmodeling-NTZA5JFV-BR2FzK4R.js +1 -0
  101. package/dist/client/assets/excalidraw-editor-BlcN6umJ.css +1 -0
  102. package/dist/client/assets/{excalidraw-editor-B46zsTFI.js → excalidraw-editor-D7pnUCLH.js} +2 -2
  103. package/dist/client/assets/{excalidrawEditor-CT2pHq7e.js → excalidrawEditor-B0jOK3lv.js} +2 -2
  104. package/dist/client/assets/export-page-Bs3xE1fg.js +57 -0
  105. package/dist/client/assets/{exportDocument-BaqcOAAW.js → exportDocument-Dg9MjkIk.js} +2 -2
  106. package/dist/client/assets/exportDocument-PnYU3v1s.css +1 -0
  107. package/dist/client/assets/flowDiagram-A5DVABFB-CiW1eN8C.js +1 -0
  108. package/dist/client/assets/{ganttDiagram-PKOTCBZU-BnM97BCT.js → ganttDiagram-EL5Y4UJY-DtKHAbez.js} +1 -1
  109. package/dist/client/assets/gitGraph-4MIJSDKK-DYlXv_yJ.js +1 -0
  110. package/dist/client/assets/{gitGraphDiagram-DS77QQ5N-BQpQhjuN.js → gitGraphDiagram-WWUBYQGX-oue8fQ5o.js} +1 -1
  111. package/dist/client/assets/github-dark.min-BV82VuKq.css +1 -0
  112. package/dist/client/assets/github.min-v3dd8CNH.css +1 -0
  113. package/dist/client/assets/image-ZVKINSPA-0zXSnE7M.js +1 -0
  114. package/dist/client/assets/index-BIpgxyGZ.css +1 -0
  115. package/dist/client/assets/{index-ClbjMBVt.js → index-Z5sI0Bj-.js} +2 -2
  116. package/dist/client/assets/info-A6RAGUB7-BlU-8_xu.js +1 -0
  117. package/dist/client/assets/{infoDiagram-6WML65LV-DYB8HCDQ.js → infoDiagram-RXCK75RN-BMzo6KIn.js} +1 -1
  118. package/dist/client/assets/{ishikawaDiagram-WSZJBQD7-Coz_P3t6.js → ishikawaDiagram-5VMMS53U-BIM3h287.js} +1 -1
  119. package/dist/client/assets/{journeyDiagram-NVQOT4AX-B6edChce.js → journeyDiagram-EYS64GPL-mF6Lh8O-.js} +1 -1
  120. package/dist/client/assets/{kanban-definition-27J2QSJJ-BFd9-cLc.js → kanban-definition-3QL26DDD-DLN2NyoR.js} +2 -2
  121. package/dist/client/assets/{line-B_S_S8kV.js → line-BfTWJmgf.js} +1 -1
  122. package/dist/client/assets/main-Dwnj9Gaq.js +903 -0
  123. package/dist/client/assets/{mermaid-parser.core-CUVdebAV.js → mermaid-parser.core-Bl0efOMt.js} +2 -2
  124. package/dist/client/assets/mermaid.core-CLZBlpIW.js +11 -0
  125. package/dist/client/assets/{mindmap-definition-FAOFIHXS-C9PQ38Al.js → mindmap-definition-FBJOCRG2-CRyHaHTk.js} +1 -1
  126. package/dist/client/assets/packet-AYTQ26CC-BSJEH9Lb.js +1 -0
  127. package/dist/client/assets/pdfium-RAgkpwfK.wasm +0 -0
  128. package/dist/client/assets/{pegDiagram-VL7TDLO6-BMZUrSaU.js → pegDiagram-XKGWAZYB-B31fKPR2.js} +1 -1
  129. package/dist/client/assets/pie-WAS4IAKB-qxv01Y8W.js +1 -0
  130. package/dist/client/assets/{pieDiagram-7S7Q4E2Y-h8kbCL9o.js → pieDiagram-E7YTZNPT-B5OZPb88.js} +1 -1
  131. package/dist/client/assets/preview-render-compiler-BApvlLLo.js +35 -0
  132. package/dist/client/assets/preview-render-compiler-BQ_3h9vD.js +1 -0
  133. package/dist/client/assets/preview-render-worker-BmN79bVc.js +60 -0
  134. package/dist/client/assets/prod-BiYPMR1i.js +177 -0
  135. package/dist/client/assets/prod-VxdGZ5Ly.js +1 -0
  136. package/dist/client/assets/{quadrantDiagram-CIZ2JOQS-CkElyfMi.js → quadrantDiagram-AXDQQJYC-Drrw14YH.js} +1 -1
  137. package/dist/client/assets/quick-switcher-controller-ButWPmCI.js +12 -0
  138. package/dist/client/assets/radar-RG4KPBEZ-B6h6pWOs.js +1 -0
  139. package/dist/client/assets/railroad-74A4TZTK-CGtTWdGc.js +1 -0
  140. package/dist/client/assets/railroad-abnf-HS5TGJTU-Cq7y22IA.js +1 -0
  141. package/dist/client/assets/railroad-ebnf-LZEXJU2U-V0aQVv9m.js +1 -0
  142. package/dist/client/assets/railroad-peg-WCYAUIDC-BQiIsX_p.js +1 -0
  143. package/dist/client/assets/{railroadDiagram-AXF67PYL-c75gnikD.js → railroadDiagram-O6MQD6OU-BPifP0MB.js} +1 -1
  144. package/dist/client/assets/{requirementDiagram-LRYGKXZP-mNxKLuHS.js → requirementDiagram-EFPCY7ZU-CRZG6mRB.js} +2 -2
  145. package/dist/client/assets/{sankeyDiagram-W5VNT64P-0OhplksI.js → sankeyDiagram-P5KCCOFB-DvarEJpo.js} +1 -1
  146. package/dist/client/assets/{sequenceDiagram-SI44F4Z6-BJ_yAocC.js → sequenceDiagram-WJ2MYXX4-B4oWlb-w.js} +1 -1
  147. package/dist/client/assets/{stateDiagram-OKZ733FA-Cc83O86s.js → stateDiagram-HBIQ2CUA-qbHIIqRZ.js} +1 -1
  148. package/dist/client/assets/stateDiagram-v2-4QOOHH4V-B--gjrit.js +1 -0
  149. package/dist/client/assets/swimlanes-XN3QIQJK-xB6CtUGj.js +1 -0
  150. package/dist/client/assets/swimlanesDiagram-VK2B7HYN-DO8XNXEg.js +8 -0
  151. package/dist/client/assets/{timeline-definition-Z64GVDOM-BWDAGTHz.js → timeline-definition-24CTP7MA-Lj_yTNlY.js} +1 -1
  152. package/dist/client/assets/treeView-Q6P3EWNA-BTTYcvrF.js +1 -0
  153. package/dist/client/assets/treemap-WGGIJYW6-Cg7tyfH8.js +1 -0
  154. package/dist/client/assets/{vennDiagram-T6HMQDX7-LOSsnlMB.js → vennDiagram-4TSXK5OY-BekRp5Y0.js} +1 -1
  155. package/dist/client/assets/wardley-WFR3VGLG-C6N1rULY.js +1 -0
  156. package/dist/client/assets/{wardleyDiagram-T6FBY63Y-BxII3foY.js → wardleyDiagram-VM6X3IG4-kdnV_Hdm.js} +1 -1
  157. package/dist/client/assets/worker-engine-m0rlHn8R-S8mpn_O0.js +17369 -0
  158. package/dist/client/assets/{xychartDiagram-ELKLHX3M-B-pTEjju.js → xychartDiagram-S5SC5T6Z-DufGwNSB.js} +3 -3
  159. package/dist/client/drawio-editor.html +1 -1
  160. package/dist/client/excalidraw-editor.html +1 -1
  161. package/dist/client/export-document.html +3 -3
  162. package/dist/client/index.html +17 -7
  163. package/package.json +19 -18
  164. package/src/client/app/index.html +14 -4
  165. package/src/client/application/app-shell/comments-feature.js +2 -3
  166. package/src/client/application/app-shell/git-feature.js +2 -2
  167. package/src/client/application/app-shell/presence-feature.js +2 -2
  168. package/src/client/application/app-shell/ui-feature-shell.js +64 -0
  169. package/src/client/application/app-shell-elements.js +1 -0
  170. package/src/client/application/pdf-preview-controller.js +53 -970
  171. package/src/client/application/preview-render-compiler.js +3 -0
  172. package/src/client/application/quick-switcher-loader.js +1 -1
  173. package/src/client/application/workspace-preview-controller.js +0 -3
  174. package/src/client/assets/vendor/highlight/github-dark.min.css +2 -10
  175. package/src/client/assets/vendor/highlight/github.min.css +2 -10
  176. package/src/client/bootstrap/collabmd-app-shell.js +10 -3
  177. package/src/client/excalidraw-editor.js +11 -0
  178. package/src/client/export/export-host.js +1 -1
  179. package/src/client/export/export-page.js +6 -2
  180. package/src/client/export/export-pipeline.js +60 -1
  181. package/src/client/presentation/comment-ui/comment-ui-render.js +4 -0
  182. package/src/client/presentation/comment-ui-controller.js +2 -0
  183. package/src/client/presentation/excalidraw-embed-controller.js +7 -0
  184. package/src/client/presentation/file-explorer-controller.js +0 -5
  185. package/src/client/presentation/file-explorer-view.js +41 -44
  186. package/src/client/presentation/file-tree-state.js +4 -3
  187. package/src/client/presentation/git-panel-controller.js +2 -2
  188. package/src/client/presentation/quick-switcher-controller.js +48 -9
  189. package/src/client/styles/features/preview-markdown.css +25 -0
  190. package/src/client/styles/features/quick-switcher.css +8 -0
  191. package/src/client/styles/foundation/themes.css +1 -0
  192. package/src/client/styles/layout/shell.css +7 -325
  193. package/src/client/styles/layout/sidebar.css +42 -4
  194. package/src/client/styles/overrides/highlightjs.css +20 -4
  195. package/src/server/infrastructure/git/git-service.js +23 -11
  196. package/src/server/infrastructure/http/create-git-api-command-handler.js +3 -1
  197. package/src/server/infrastructure/http/create-structurizr-api-handler.js +4 -2
  198. package/src/server/infrastructure/structurizr/structurizr-workspace-service.js +33 -7
  199. package/dist/client/assets/architecture-TIHT7OUA-CsHfPErM.js +0 -1
  200. package/dist/client/assets/base-CxPEiHuy.js +0 -1
  201. package/dist/client/assets/blockDiagram-VBNYF7ZC-CipJt9Jl.js +0 -132
  202. package/dist/client/assets/c4Diagram-5PPSVZJV-B5ktVx6g.js +0 -10
  203. package/dist/client/assets/channel-4Jkmq93I.js +0 -1
  204. package/dist/client/assets/chunk-7BUUIJ7U-Bb538aSH.js +0 -1
  205. package/dist/client/assets/chunk-7Z6QIM7H-BP9Pdsm9.js +0 -10
  206. package/dist/client/assets/chunk-ERSWUTIN-hHdvnhaY.js +0 -41
  207. package/dist/client/assets/chunk-I66GZJ75-CVFiiffQ.js +0 -127
  208. package/dist/client/assets/chunk-J7OUQ5F2-4CEb7pvH.js +0 -2
  209. package/dist/client/assets/chunk-JQJVKLGR-cx8X_24v.js +0 -156
  210. package/dist/client/assets/chunk-QR6OTTB3-CDAA_5Ib.js +0 -62
  211. package/dist/client/assets/chunk-RYQCIY6F-D-a0zH8K.js +0 -1
  212. package/dist/client/assets/chunk-UBXNYLIW-Bhk-PbFK.js +0 -1
  213. package/dist/client/assets/chunk-W5SLKNZC-BdNSCxZ9.js +0 -1
  214. package/dist/client/assets/chunk-WRU74C26-h6_XkD3_.js +0 -70
  215. package/dist/client/assets/chunk-ZIRB5QZD-O39ZBUk3.js +0 -32
  216. package/dist/client/assets/classDiagram-JCYQIIEL-L7lsyW_w.js +0 -1
  217. package/dist/client/assets/classDiagram-v2-OCEON4UE-L7lsyW_w.js +0 -1
  218. package/dist/client/assets/cynefin-VYW2F7L2-Ds2Fw2Y0.js +0 -1
  219. package/dist/client/assets/dagre-Buvkdvvj.js +0 -1
  220. package/dist/client/assets/dagre-VZM6K2ZE-L1xArOGs.js +0 -4
  221. package/dist/client/assets/dist-B5Jf1SLZ.js +0 -2
  222. package/dist/client/assets/dist-BKW4PALF.js +0 -1
  223. package/dist/client/assets/dist-BWcHHOx-.js +0 -1
  224. package/dist/client/assets/dist-DaYdhcVs.js +0 -1
  225. package/dist/client/assets/dist-Kh2COra_.js +0 -1
  226. package/dist/client/assets/dist-tOaegDYS2.js +0 -1
  227. package/dist/client/assets/editor-session-Cm9ekeNo.js +0 -54
  228. package/dist/client/assets/embedded-editor-base-CwTkk911.css +0 -1
  229. package/dist/client/assets/erDiagram-JOGREHBK-cYUpEKpf.js +0 -85
  230. package/dist/client/assets/es-DXGV3RHd.js +0 -22
  231. package/dist/client/assets/eventmodeling-45OFAUF4-CLEiVx5s.js +0 -1
  232. package/dist/client/assets/excalidraw-editor-Bt7gMSoh.css +0 -1
  233. package/dist/client/assets/export-page-A7NHawJY.js +0 -39
  234. package/dist/client/assets/exportDocument-B2L8fe34.css +0 -1
  235. package/dist/client/assets/flowDiagram-UKHOOZJN-D0ypP0Ez.js +0 -1
  236. package/dist/client/assets/gitGraph-TEB2WS4Q-CZFBqwW-.js +0 -1
  237. package/dist/client/assets/github-dark.min-Z5exjX_n.css +0 -1
  238. package/dist/client/assets/github.min-D2BCvnWf.css +0 -1
  239. package/dist/client/assets/image-QXRYHUNP-SWEV8H0J.js +0 -1
  240. package/dist/client/assets/index-Pum8ET-5.css +0 -1
  241. package/dist/client/assets/info-DKCQHKI2--1InqQeT.js +0 -1
  242. package/dist/client/assets/main-B3uPyqic.js +0 -893
  243. package/dist/client/assets/map-BaFkSB1l.js +0 -1
  244. package/dist/client/assets/mermaid.core-DN-lF51U.js +0 -11
  245. package/dist/client/assets/packet-7NZHBO7P-BGMXB0XL.js +0 -1
  246. package/dist/client/assets/pdf-BL9Pr2D5.js +0 -54
  247. package/dist/client/assets/pdf.worker-CLesOks4.mjs +0 -64857
  248. package/dist/client/assets/pdf_viewer-FVkkThnz.js +0 -551
  249. package/dist/client/assets/pie-RZYD4A2V-DgYg3tCt.js +0 -1
  250. package/dist/client/assets/preview-render-compiler-BD-XhkS2.js +0 -35
  251. package/dist/client/assets/preview-render-compiler-BKedaMxx.js +0 -1
  252. package/dist/client/assets/preview-render-worker-CiPqc9n6.js +0 -60
  253. package/dist/client/assets/prod-Dy20X7eT.js +0 -1
  254. package/dist/client/assets/prod-hnwh7wRM.js +0 -177
  255. package/dist/client/assets/quick-switcher-controller-fqOYR7qR.js +0 -12
  256. package/dist/client/assets/radar-I7S5WNFK-Ag-zp_Rq.js +0 -1
  257. package/dist/client/assets/railroad-3IZDKUUU-aibJDIDV.js +0 -1
  258. package/dist/client/assets/railroad-abnf-AHOZXSZD-BBMEuvIl.js +0 -1
  259. package/dist/client/assets/railroad-ebnf-EBAXGLYW-Be1nseej.js +0 -1
  260. package/dist/client/assets/railroad-peg-LSFZ7HO6-DIvD-Eyb.js +0 -1
  261. package/dist/client/assets/stateDiagram-v2-UEYNNEHI-B1-BufUk.js +0 -1
  262. package/dist/client/assets/swimlanes-SLNWSIFB-oVTWEJIj.js +0 -2
  263. package/dist/client/assets/swimlanesDiagram-ULZ7WXOC-C5OTVwEu.js +0 -8
  264. package/dist/client/assets/treeView-QDETBFTQ-uHZ-3Fz8.js +0 -1
  265. package/dist/client/assets/treemap-6X3UGDF4-BnUKyy3l.js +0 -1
  266. package/dist/client/assets/wardley-OPB4EBWU-Da7TLC2F.js +0 -1
  267. /package/dist/client/assets/{drawio-editor-FzY1cVw8.js → drawio-editor-BjrxTe3l.js} +0 -0
@@ -1,992 +1,75 @@
1
- import { clamp } from '../domain/vault-utils.js';
2
1
  import { resolveApiUrl } from '../domain/runtime-paths.js';
3
2
 
4
- const DEFAULT_PAGE_WIDTH = 612;
5
- const DEFAULT_PAGE_HEIGHT = 792;
6
- const MAX_PAGE_WIDTH = 960;
7
- const PAGE_RENDER_ROOT_MARGIN = '720px 0px';
8
- const MAX_DEVICE_PIXEL_RATIO = 2;
9
- const PDF_ZOOM = Object.freeze({
10
- default: 1,
11
- max: 2,
12
- min: 0.5,
13
- renderDebounceMs: 100,
14
- step: 0.25,
15
- wheelSensitivity: 0.01,
16
- });
17
- function isRenderingCancellation(error) {
18
- return error?.name === 'RenderingCancelledException' || error?.name === 'AbortException';
19
- }
3
+ const READ_ONLY_CATEGORIES = Object.freeze([
4
+ 'annotation',
5
+ 'document-capture',
6
+ 'document-close',
7
+ 'document-open',
8
+ 'document-print',
9
+ 'document-protect',
10
+ 'form',
11
+ 'history',
12
+ 'insert',
13
+ 'panel-comment',
14
+ 'redaction',
15
+ 'rotate',
16
+ ]);
20
17
 
21
18
  export class PdfPreviewController {
22
- constructor({ previewContainer, outlineController = null }) {
23
- this.previewContainer = previewContainer;
24
- this.outlineController = outlineController;
25
- this.pdfJsPromise = null;
26
- this.pdfJsApi = null;
27
- this.pdfViewerApi = null;
28
- this.loadingTask = null;
29
- this.pdfDocument = null;
30
- this.findEventBus = null;
31
- this.findController = null;
32
- this.pdfLinkService = null;
33
- this.intersectionObserver = null;
34
- this.resizeObserver = null;
35
- this.pageStates = new Map();
36
- this.visiblePages = new Set();
19
+ constructor({ getTheme = () => 'dark', loadEmbedPdf } = {}) {
20
+ this.getTheme = getTheme;
21
+ this.loadEmbedPdf = loadEmbedPdf ?? (() => import('@embedpdf/snippet'));
37
22
  this.renderToken = 0;
38
- this.shell = null;
39
- this.zoom = PDF_ZOOM.default;
40
- this.zoomControls = null;
41
- this.navigationControls = null;
42
- this.searchControls = null;
43
- this.pdfNavigationStack = [];
44
- this.findState = null;
45
- this.currentPageNumber = 1;
46
- this.zoomRenderTimerId = 0;
47
- this.pageFitWidth = DEFAULT_PAGE_WIDTH;
48
- this.pageLayoutZoom = PDF_ZOOM.default;
49
- this.pinchStartDistance = 0;
50
- this.pinchStartZoom = PDF_ZOOM.default;
23
+ this.viewer = null;
51
24
  }
52
25
 
53
- async loadPdfJs() {
54
- if (!this.pdfJsPromise) {
55
- this.pdfJsPromise = import('pdfjs-dist').then(async (pdfjs) => {
56
- pdfjs.GlobalWorkerOptions.workerSrc = new URL(
57
- 'pdfjs-dist/build/pdf.worker.mjs',
58
- import.meta.url,
59
- ).toString();
60
- globalThis.pdfjsLib = pdfjs;
61
- const pdfViewer = await import('pdfjs-dist/web/pdf_viewer.mjs');
62
- return { pdfjs, pdfViewer };
63
- });
64
- }
65
-
66
- return this.pdfJsPromise;
67
- }
68
-
69
- async render({ filePath, renderHost, displayName }) {
26
+ async render({ filePath, renderHost }) {
27
+ this.cancel();
70
28
  const token = this.renderToken;
71
- this.zoom = PDF_ZOOM.default;
72
- this.pageLayoutZoom = PDF_ZOOM.default;
73
- this.pinchStartDistance = 0;
74
- this.pinchStartZoom = PDF_ZOOM.default;
75
- this.currentPageNumber = 1;
76
- this.pdfNavigationStack = [];
77
- this.outlineController?.clearPdfOutline?.();
78
- const url = resolveApiUrl(`/download/file?path=${encodeURIComponent(filePath)}`);
79
- const shell = this.createShell({ displayName, filePath, url });
80
- renderHost.replaceChildren(shell);
81
- this.shell = shell;
82
-
83
- try {
84
- const { pdfjs, pdfViewer } = await this.loadPdfJs();
85
- this.pdfJsApi = pdfjs;
86
- this.pdfViewerApi = pdfViewer;
87
- if (token !== this.renderToken) {
88
- return;
89
- }
90
-
91
- this.loadingTask = pdfjs.getDocument({ url });
92
- this.loadingTask.onPassword = (updatePassword, reason) => {
93
- if (token !== this.renderToken || this.shell !== shell) {
94
- updatePassword(new Error('PDF preview cancelled'));
95
- return;
96
- }
97
-
98
- this.showPasswordPrompt(shell, updatePassword, reason);
99
- };
100
- const pdfDocument = await this.loadingTask.promise;
101
- if (token !== this.renderToken) {
102
- await pdfDocument.destroy();
103
- return;
104
- }
105
-
106
- this.pdfDocument = pdfDocument;
107
- this.initializeFindController(pdfDocument, pdfViewer);
108
- void this.loadPdfOutline(pdfDocument, token);
109
- this.buildPageStates(pdfDocument.numPages, shell.querySelector('.pdf-file-preview-pages'));
110
- this.setStatus(`${pdfDocument.numPages} ${pdfDocument.numPages === 1 ? 'page' : 'pages'}`);
111
- this.observePages(token);
112
- if (this.searchControls?.input.value.trim()) {
113
- this.dispatchFind();
114
- }
115
- } catch (error) {
116
- if (token === this.renderToken && !isRenderingCancellation(error)) {
117
- this.showError(shell);
118
- }
119
- } finally {
120
- if (token === this.renderToken) {
121
- this.loadingTask = null;
122
- }
123
- }
124
- }
29
+ const viewerHost = document.createElement('div');
30
+ viewerHost.className = 'pdf-file-preview-viewer';
31
+ viewerHost.setAttribute('aria-label', `${String(filePath).split('/').pop() || filePath} PDF preview`);
32
+ renderHost.replaceChildren(viewerHost);
125
33
 
126
- showPasswordPrompt(shell, updatePassword, reason) {
127
- const pages = shell.querySelector('.pdf-file-preview-pages');
128
- if (!pages) {
129
- return;
130
- }
131
-
132
- const isIncorrectPassword = reason === this.pdfJsApi?.PasswordResponses?.INCORRECT_PASSWORD;
133
- this.setStatus(isIncorrectPassword ? 'Incorrect password' : 'Password required');
134
-
135
- const prompt = document.createElement('form');
136
- prompt.className = 'pdf-file-preview-password-prompt';
137
-
138
- const heading = document.createElement('h2');
139
- heading.className = 'pdf-file-preview-password-title';
140
- heading.textContent = isIncorrectPassword ? 'Incorrect PDF password' : 'Password required';
141
-
142
- const copy = document.createElement('p');
143
- copy.className = 'pdf-file-preview-password-copy';
144
- copy.textContent = isIncorrectPassword
145
- ? 'The password was incorrect. Try again.'
146
- : 'Enter the password to preview this PDF.';
147
-
148
- const label = document.createElement('label');
149
- label.className = 'pdf-file-preview-password-field';
150
- label.textContent = 'PDF password';
151
-
152
- const input = document.createElement('input');
153
- input.type = 'password';
154
- input.className = 'ui-input';
155
- input.autocomplete = 'off';
156
- input.spellcheck = false;
157
- input.setAttribute('aria-label', 'PDF password');
158
- label.appendChild(input);
159
-
160
- const submit = document.createElement('button');
161
- submit.type = 'submit';
162
- submit.className = 'ui-button ui-button--primary';
163
- submit.textContent = 'Unlock PDF';
164
- prompt.addEventListener('submit', (event) => {
165
- event.preventDefault();
166
- submit.disabled = true;
167
- input.disabled = true;
168
- updatePassword(input.value);
169
- });
170
-
171
- prompt.append(heading, copy, label, submit);
172
- pages.replaceChildren(prompt);
173
- input.focus();
174
- }
175
-
176
- async loadPdfOutline(pdfDocument, token) {
177
34
  try {
178
- const outline = typeof pdfDocument.getOutline === 'function'
179
- ? await pdfDocument.getOutline()
180
- : null;
181
- if (token !== this.renderToken || this.pdfDocument !== pdfDocument) {
182
- return;
183
- }
184
-
185
- if (!Array.isArray(outline) || outline.length === 0) {
186
- this.outlineController?.clearPdfOutline?.();
187
- return;
188
- }
189
-
190
- this.outlineController?.setPdfOutline?.(
191
- outline,
192
- (item) => this.navigateToPdfOutline(item, pdfDocument, token),
193
- );
194
- } catch {
195
- if (token === this.renderToken && this.pdfDocument === pdfDocument) {
196
- this.outlineController?.clearPdfOutline?.();
197
- }
198
- }
199
- }
200
-
201
- async navigateToPdfOutline(item, pdfDocument, token) {
202
- if (token !== this.renderToken || this.pdfDocument !== pdfDocument) {
203
- return;
204
- }
205
-
206
- const url = typeof item?.url === 'string' ? item.url.trim() : '';
207
- if (url) {
208
- try {
209
- const parsedUrl = new URL(url, window.location.href);
210
- if (parsedUrl.protocol === 'http:' || parsedUrl.protocol === 'https:') {
211
- window.open(parsedUrl.href, '_blank', 'noopener,noreferrer');
212
- }
213
- } catch {
214
- // Ignore malformed PDF outline URLs.
215
- }
216
- return;
217
- }
218
-
219
- const linkService = this.pdfLinkService;
220
- if (!linkService || linkService.pdfDocument !== pdfDocument || item?.dest == null) {
221
- return;
222
- }
223
-
224
- try {
225
- await linkService.goToDestination(item.dest);
226
- } catch {
227
- // Ignore outline entries with invalid destinations.
228
- }
229
- }
230
-
231
- initializeFindController(pdfDocument, pdfViewer) {
232
- const previewController = this;
233
- const eventBus = new pdfViewer.EventBus();
234
- const setPage = (value) => {
235
- if (previewController.pdfDocument !== pdfDocument) {
236
- return;
237
- }
238
-
239
- previewController.currentPageNumber = clamp(
240
- Number(value) || 1,
241
- 1,
242
- pdfDocument.numPages,
243
- );
244
- previewController.scrollToPage(previewController.currentPageNumber);
245
- };
246
- const pageViewer = {
247
- get currentPageNumber() {
248
- return previewController.currentPageNumber;
249
- },
250
- set currentPageNumber(value) {
251
- setPage(value);
252
- },
253
- scrollPageIntoView({ pageNumber, destArray }) {
254
- if (destArray) {
255
- previewController.recordPdfNavigation(previewController.currentPageNumber, pageNumber);
256
- }
257
- setPage(pageNumber);
258
- },
259
- };
260
- const linkService = new pdfViewer.PDFLinkService({ eventBus });
261
- linkService.setDocument(pdfDocument);
262
- linkService.setViewer(pageViewer);
263
- const findController = new pdfViewer.PDFFindController({
264
- eventBus,
265
- linkService,
266
- delay: 0,
267
- updateMatchesCountOnProgress: true,
268
- });
269
-
270
- this.findState = pdfViewer.FindState.FOUND;
271
- findController.onIsPageVisible = (pageNumber) => this.visiblePages.has(pageNumber);
272
- eventBus.on('updatefindmatchescount', ({ matchesCount }) => (
273
- this.updateFindStatus(matchesCount, true)
274
- ));
275
- eventBus.on('updatefindcontrolstate', ({ state, matchesCount }) => {
276
- this.findState = state;
277
- this.updateFindStatus(matchesCount);
278
- });
279
-
280
- this.findEventBus = eventBus;
281
- this.findController = findController;
282
- this.pdfLinkService = linkService;
283
- findController.setDocument(pdfDocument);
284
- this.updateFindControls();
285
- }
286
-
287
- scrollToPage(pageNumber) {
288
- const pageShell = this.pageStates.get(pageNumber)?.pageShell;
289
- pageShell?.scrollIntoView?.({
290
- behavior: 'auto',
291
- block: 'center',
292
- inline: 'nearest',
293
- });
294
- }
295
-
296
- recordPdfNavigation(fromPageNumber, toPageNumber) {
297
- if (!Number.isInteger(fromPageNumber)
298
- || !Number.isInteger(toPageNumber)
299
- || fromPageNumber === toPageNumber) {
300
- return;
301
- }
302
-
303
- this.pdfNavigationStack.push(fromPageNumber);
304
- this.updateNavigationControls();
305
- }
306
-
307
- goBack() {
308
- const pageNumber = this.pdfNavigationStack.pop();
309
- if (!Number.isInteger(pageNumber)) {
310
- this.updateNavigationControls();
311
- return;
312
- }
313
-
314
- this.currentPageNumber = pageNumber;
315
- this.scrollToPage(pageNumber);
316
- this.updateNavigationControls();
317
- }
318
-
319
- updateNavigationControls() {
320
- if (this.navigationControls?.backButton) {
321
- this.navigationControls.backButton.disabled = this.pdfNavigationStack.length === 0;
322
- }
323
- }
324
-
325
- setFindStatus(text) {
326
- if (this.searchControls?.status) {
327
- this.searchControls.status.textContent = text;
328
- }
329
- }
330
-
331
- updateFindStatus(matchesCount, showProgress = false) {
332
- if (!this.searchControls?.input.value.trim()) {
333
- this.setFindStatus('');
334
- return;
335
- }
336
-
337
- const current = Number(matchesCount?.current) || 0;
338
- const total = Number(matchesCount?.total) || 0;
339
- const pending = this.findState === this.pdfViewerApi?.FindState.PENDING;
340
- const status = pending && (!showProgress || total === 0)
341
- ? 'Searching…'
342
- : total > 0
343
- ? `${current} of ${total}`
344
- : 'No matches';
345
- this.setFindStatus(status);
346
- }
347
-
348
- updateFindControls() {
349
- const controls = this.searchControls;
350
- if (!controls) {
351
- return;
352
- }
353
-
354
- const disabled = !controls.input.value.trim() || !this.findController;
355
- controls.previousButton.disabled = disabled;
356
- controls.nextButton.disabled = disabled;
357
- }
358
-
359
- dispatchFind() {
360
- const query = this.searchControls?.input.value.trim() || '';
361
- if (!query) {
362
- this.findState = this.pdfViewerApi?.FindState.FOUND ?? null;
363
- this.findEventBus?.dispatch('findbarclose', { source: this });
364
- this.setFindStatus('');
365
- this.updateFindControls();
366
- return;
367
- }
368
-
369
- if (!this.findEventBus || !this.findController) {
370
- this.setFindStatus('Loading…');
371
- this.updateFindControls();
372
- return;
373
- }
374
-
375
- this.findState = this.pdfViewerApi?.FindState.PENDING ?? null;
376
- this.setFindStatus('Searching…');
377
- this.updateFindControls();
378
- this.findEventBus.dispatch('find', {
379
- source: this,
380
- type: '',
381
- query,
382
- phraseSearch: true,
383
- caseSensitive: false,
384
- entireWord: false,
385
- highlightAll: true,
386
- findPrevious: false,
387
- matchDiacritics: false,
388
- });
389
- }
390
-
391
- dispatchFindAgain(findPrevious = false) {
392
- const query = this.searchControls?.input.value.trim() || '';
393
- if (!query || !this.findEventBus || !this.findController) {
394
- return;
395
- }
396
-
397
- this.findEventBus.dispatch('find', {
398
- source: this,
399
- type: 'again',
400
- query,
401
- phraseSearch: true,
402
- caseSensitive: false,
403
- entireWord: false,
404
- highlightAll: true,
405
- findPrevious,
406
- matchDiacritics: false,
407
- });
408
- }
409
-
410
- createShell({ displayName, filePath, url }) {
411
- const shell = document.createElement('section');
412
- shell.className = 'pdf-file-preview-shell';
413
- shell.setAttribute('aria-label', `${displayName} PDF preview`);
414
-
415
- const toolbar = document.createElement('div');
416
- toolbar.className = 'pdf-file-preview-toolbar';
417
-
418
- const status = document.createElement('span');
419
- status.className = 'pdf-file-preview-status';
420
- status.setAttribute('role', 'status');
421
- status.setAttribute('aria-live', 'polite');
422
- status.textContent = 'Loading PDF preview…';
423
-
424
- const zoomControls = document.createElement('div');
425
- zoomControls.className = 'pdf-file-preview-zoom-controls';
426
-
427
- const zoomOutButton = document.createElement('button');
428
- zoomOutButton.type = 'button';
429
- zoomOutButton.className = 'pdf-file-preview-zoom-button ui-preview-action';
430
- zoomOutButton.setAttribute('aria-label', 'Zoom out');
431
- zoomOutButton.title = 'Zoom out';
432
- zoomOutButton.textContent = '−';
433
- zoomOutButton.addEventListener('click', () => this.setZoom(this.zoom - PDF_ZOOM.step));
434
-
435
- const zoomLabel = document.createElement('span');
436
- zoomLabel.className = 'pdf-file-preview-zoom-label';
437
- zoomLabel.setAttribute('aria-live', 'polite');
438
-
439
- const zoomInButton = document.createElement('button');
440
- zoomInButton.type = 'button';
441
- zoomInButton.className = 'pdf-file-preview-zoom-button ui-preview-action';
442
- zoomInButton.setAttribute('aria-label', 'Zoom in');
443
- zoomInButton.title = 'Zoom in';
444
- zoomInButton.textContent = '+';
445
- zoomInButton.addEventListener('click', () => this.setZoom(this.zoom + PDF_ZOOM.step));
446
-
447
- zoomControls.append(zoomOutButton, zoomLabel, zoomInButton);
448
- this.zoomControls = { zoomInButton, zoomLabel, zoomOutButton };
449
- this.updateZoomControls();
450
-
451
- const backButton = document.createElement('button');
452
- backButton.type = 'button';
453
- backButton.className = 'pdf-file-preview-back-button ui-preview-action';
454
- backButton.setAttribute('aria-label', 'Back to previous page');
455
- backButton.title = 'Back to previous page';
456
- backButton.textContent = '←';
457
- backButton.addEventListener('click', () => this.goBack());
458
- this.navigationControls = { backButton };
459
- this.updateNavigationControls();
460
-
461
- const download = document.createElement('a');
462
- download.className = 'pdf-file-preview-download';
463
- download.href = url;
464
- download.download = String(filePath).split('/').pop() || displayName;
465
- download.textContent = 'Download';
466
- download.setAttribute('aria-label', `Download ${displayName}`);
467
-
468
- const findControls = document.createElement('div');
469
- findControls.className = 'pdf-file-preview-find-controls';
470
-
471
- const findInput = document.createElement('input');
472
- findInput.type = 'search';
473
- findInput.className = 'pdf-file-preview-find-input';
474
- findInput.placeholder = 'Find in PDF';
475
- findInput.setAttribute('aria-label', 'Find in PDF');
476
- findInput.addEventListener('input', () => this.dispatchFind());
477
- findInput.addEventListener('keydown', (event) => {
478
- if (event.key === 'Escape') {
479
- event.preventDefault();
480
- findInput.value = '';
481
- this.dispatchFind();
482
- findInput.blur();
483
- return;
484
- }
485
-
486
- if (event.key === 'Enter') {
487
- event.preventDefault();
488
- this.dispatchFindAgain(event.shiftKey);
489
- }
490
- });
491
-
492
- const findStatus = document.createElement('span');
493
- findStatus.className = 'pdf-file-preview-find-status';
494
- findStatus.setAttribute('role', 'status');
495
- findStatus.setAttribute('aria-live', 'polite');
496
-
497
- const previousButton = document.createElement('button');
498
- previousButton.type = 'button';
499
- previousButton.className = 'pdf-file-preview-find-button ui-preview-action';
500
- previousButton.setAttribute('aria-label', 'Previous match');
501
- previousButton.title = 'Previous match';
502
- previousButton.textContent = '‹';
503
- previousButton.addEventListener('click', () => this.dispatchFindAgain(true));
504
-
505
- const nextButton = document.createElement('button');
506
- nextButton.type = 'button';
507
- nextButton.className = 'pdf-file-preview-find-button ui-preview-action';
508
- nextButton.setAttribute('aria-label', 'Next match');
509
- nextButton.title = 'Next match';
510
- nextButton.textContent = '›';
511
- nextButton.addEventListener('click', () => this.dispatchFindAgain());
512
-
513
- findControls.append(findInput, findStatus, previousButton, nextButton);
514
- this.searchControls = {
515
- input: findInput,
516
- nextButton,
517
- previousButton,
518
- status: findStatus,
519
- };
520
- this.updateFindControls();
521
-
522
- const toolbarStart = document.createElement('div');
523
- toolbarStart.className = 'pdf-file-preview-toolbar-start';
524
- toolbarStart.append(backButton, status, zoomControls, findControls);
525
- toolbar.append(toolbarStart, download);
526
-
527
- const pages = document.createElement('div');
528
- pages.className = 'pdf-file-preview-pages';
529
- pages.setAttribute('aria-label', 'PDF pages');
530
- pages.addEventListener('wheel', (event) => this.handleWheelZoom(event), { passive: false });
531
- pages.addEventListener('touchstart', (event) => this.handleTouchStart(event), { passive: true });
532
- pages.addEventListener('touchmove', (event) => this.handleTouchMove(event), { passive: false });
533
- const finishPinch = (event) => this.handleTouchEnd(event);
534
- pages.addEventListener('touchend', finishPinch, { passive: true });
535
- pages.addEventListener('touchcancel', finishPinch, { passive: true });
536
- shell.append(toolbar, pages);
537
- return shell;
538
- }
539
-
540
- buildPageStates(pageCount, pagesElement) {
541
- this.pageStates.clear();
542
- this.visiblePages.clear();
543
- pagesElement.replaceChildren();
544
-
545
- for (let pageNumber = 1; pageNumber <= pageCount; pageNumber += 1) {
546
- const pageShell = document.createElement('article');
547
- pageShell.className = 'pdf-page';
548
- pageShell.dataset.pageNumber = String(pageNumber);
549
- pageShell.setAttribute('aria-label', `Page ${pageNumber} of ${pageCount}`);
550
- pageShell.style.aspectRatio = `${DEFAULT_PAGE_WIDTH} / ${DEFAULT_PAGE_HEIGHT}`;
551
- pagesElement.appendChild(pageShell);
552
- this.pageStates.set(pageNumber, {
553
- canvas: null,
554
- needsRender: false,
555
- page: null,
556
- pageShell,
557
- renderPromise: null,
558
- renderTask: null,
559
- renderedWidth: 0,
560
- pageView: null,
561
- });
562
- }
563
-
564
- this.commitPageZoom();
565
- }
566
-
567
- observePages(token) {
568
- const pagesElement = this.shell?.querySelector('.pdf-file-preview-pages');
569
- if (!pagesElement) {
570
- return;
571
- }
572
-
573
- if (typeof IntersectionObserver === 'function') {
574
- this.intersectionObserver = new IntersectionObserver(
575
- (entries) => this.handlePageIntersections(entries, token),
576
- {
577
- root: this.previewContainer,
578
- rootMargin: PAGE_RENDER_ROOT_MARGIN,
35
+ const { default: EmbedPDF, LockModeType, ZoomMode } = await this.loadEmbedPdf();
36
+ if (token !== this.renderToken || !viewerHost.isConnected) return;
37
+
38
+ const viewer = EmbedPDF.init({
39
+ type: 'container',
40
+ target: viewerHost,
41
+ src: resolveApiUrl(`/download/file?path=${encodeURIComponent(filePath)}`),
42
+ annotations: { locked: { type: LockModeType.All } },
43
+ disabledCategories: READ_ONLY_CATEGORIES,
44
+ fontFallback: null,
45
+ fonts: { signature: null, ui: null },
46
+ stamp: { defaultLibrary: false, manifests: [] },
47
+ tabBar: 'never',
48
+ theme: { preference: this.getTheme() },
49
+ wasmUrl: new URL('@embedpdf/pdfium/pdfium.wasm', import.meta.url).toString(),
50
+ zoom: {
51
+ defaultZoomLevel: ZoomMode.FitWidth,
52
+ maxZoom: 2,
53
+ minZoom: 0.5,
54
+ zoomStep: 0.25,
579
55
  },
580
- );
581
- this.pageStates.forEach(({ pageShell }) => this.intersectionObserver.observe(pageShell));
582
- } else {
583
- this.visiblePages.add(1);
584
- void this.renderPage(1, token);
585
- }
586
-
587
- if (typeof ResizeObserver === 'function') {
588
- this.resizeObserver = new ResizeObserver(() => {
589
- this.commitPageZoom({ preserveLiveZoom: Boolean(this.zoomRenderTimerId) });
590
- this.scheduleVisiblePageRender();
591
56
  });
592
- this.resizeObserver.observe(pagesElement);
593
- }
594
- }
595
-
596
- handlePageIntersections(entries, token) {
597
- if (token !== this.renderToken) {
598
- return;
599
- }
600
-
601
- entries.forEach((entry) => {
602
- const pageNumber = Number(entry.target.dataset.pageNumber);
603
- if (entry.isIntersecting) {
604
- this.visiblePages.add(pageNumber);
605
- this.currentPageNumber = Math.min(...this.visiblePages);
606
- void this.renderPage(pageNumber, token);
607
- return;
608
- }
609
-
610
- this.visiblePages.delete(pageNumber);
611
- this.releasePage(pageNumber);
612
- });
613
- }
614
-
615
- disposePageView(state, pageView = state.pageView) {
616
- if (!pageView) {
617
- return;
618
- }
619
-
620
- pageView.reset?.();
621
- pageView.div?.remove();
622
- if (state.pageView === pageView) {
623
- state.pageView = null;
624
- state.canvas = null;
625
- state.renderTask = null;
626
- state.renderedWidth = 0;
627
- }
628
- }
629
-
630
- async renderPage(pageNumber, token) {
631
- const state = this.pageStates.get(pageNumber);
632
- if (!state || !this.pdfDocument || token !== this.renderToken) {
633
- return;
634
- }
635
-
636
- const width = this.getPageWidth(state.pageShell);
637
- if (state.canvas && Math.abs(state.renderedWidth - width) < 1) {
638
- state.needsRender = false;
639
- return;
640
- }
641
- if (state.renderPromise) {
642
- return state.renderPromise;
643
- }
644
-
645
- state.needsRender = false;
646
- state.renderPromise = (async () => {
647
- let pageView = null;
648
- let committed = false;
649
- try {
650
- const page = state.page ?? await this.pdfDocument.getPage(pageNumber);
651
- if (token !== this.renderToken) {
652
- return;
653
- }
654
-
655
- state.page = page;
656
- const baseViewport = page.getViewport({ scale: 1 });
657
- state.pageShell.style.aspectRatio = `${baseViewport.width} / ${baseViewport.height}`;
658
- const scale = width / baseViewport.width;
659
- const viewport = page.getViewport({ scale });
660
- const userUnit = viewport.userUnit || 1;
661
- state.pageShell.style.setProperty('--scale-factor', String(viewport.scale));
662
- state.pageShell.style.setProperty('--user-unit', String(userUnit));
663
- state.pageShell.style.setProperty('--total-scale-factor', String(viewport.scale * userUnit));
664
- state.pageShell.style.setProperty('--scale-round-x', '1px');
665
- state.pageShell.style.setProperty('--scale-round-y', '1px');
666
-
667
- this.disposePageView(state);
668
- pageView = new this.pdfViewerApi.PDFPageView({
669
- annotationMode: this.pdfJsApi.AnnotationMode.ENABLE,
670
- container: state.pageShell,
671
- defaultViewport: viewport,
672
- enableAutoLinking: false,
673
- eventBus: this.findEventBus,
674
- id: pageNumber,
675
- layerProperties: {
676
- findController: this.findController,
677
- linkService: this.pdfLinkService,
678
- },
679
- maxCanvasPixels: Math.ceil(
680
- viewport.width * viewport.height * MAX_DEVICE_PIXEL_RATIO ** 2,
681
- ),
682
- scale: viewport.scale / this.pdfJsApi.PixelsPerInch.PDF_TO_CSS_UNITS,
683
- textLayerMode: 1,
684
- });
685
- pageView.setPdfPage(page);
686
- state.pageView = pageView;
687
- const drawPromise = pageView.draw();
688
- state.renderTask = pageView.renderTask;
689
- await drawPromise;
690
-
691
- if (pageView.canvas) {
692
- pageView.canvas.className = 'pdf-page-canvas';
693
- pageView.canvas.setAttribute('aria-label', `Rendered page ${pageNumber}`);
694
- }
695
-
696
- const isCurrentRender = token === this.renderToken
697
- && this.visiblePages.has(pageNumber)
698
- && state.pageView === pageView
699
- && pageView.canvas
700
- && Math.abs(this.getPageWidth(state.pageShell) - width) < 1;
701
- if (!isCurrentRender) {
702
- this.disposePageView(state, pageView);
703
- if (token === this.renderToken && this.visiblePages.has(pageNumber)) {
704
- this.scheduleVisiblePageRender();
705
- }
706
- return;
707
- }
708
-
709
- state.canvas = pageView.canvas;
710
- state.renderedWidth = width;
711
- committed = true;
712
- } catch (error) {
713
- if (pageView && !committed) {
714
- this.disposePageView(state, pageView);
715
- }
716
- if (!isRenderingCancellation(error) && token === this.renderToken) {
717
- state.pageShell.replaceChildren();
718
- this.setStatus(`Unable to render page ${pageNumber}`);
719
- }
720
- } finally {
721
- if (state.pageView === pageView) {
722
- state.renderTask = null;
723
- }
724
- }
725
- })().finally(() => {
726
- state.renderPromise = null;
727
- const shouldRetry = state.needsRender;
728
- state.needsRender = false;
729
- if (shouldRetry && this.visiblePages.has(pageNumber) && token === this.renderToken) {
730
- void this.renderPage(pageNumber, token);
731
- }
732
- });
733
-
734
- return state.renderPromise;
735
- }
736
-
737
- handleWheelZoom(event) {
738
- if (!event.ctrlKey) {
739
- return;
740
- }
741
-
742
- event.preventDefault();
743
- const deltaY = Number.isFinite(event.deltaY) ? event.deltaY : 0;
744
- const wheelDelta = clamp(
745
- -deltaY * PDF_ZOOM.wheelSensitivity,
746
- -PDF_ZOOM.step / 2,
747
- PDF_ZOOM.step / 2,
748
- );
749
- if (wheelDelta !== 0) {
750
- this.setZoom(this.zoom + wheelDelta);
751
- }
752
- }
753
-
754
- getPinchDistance(touches) {
755
- if (!touches || touches.length !== 2) {
756
- return 0;
757
- }
758
-
759
- const [first, second] = touches;
760
- const distance = Math.hypot(
761
- second.clientX - first.clientX,
762
- second.clientY - first.clientY,
763
- );
764
- return Number.isFinite(distance) && distance > 0 ? distance : 0;
765
- }
766
-
767
- handleTouchStart(event) {
768
- if (event.touches?.length !== 2) {
769
- return;
770
- }
771
-
772
- const distance = this.getPinchDistance(event.touches);
773
- if (distance > 0) {
774
- this.pinchStartDistance = distance;
775
- this.pinchStartZoom = this.zoom;
776
- }
777
- }
778
-
779
- handleTouchMove(event) {
780
- if (event.touches?.length !== 2) {
781
- return;
782
- }
783
-
784
- if (!this.pinchStartDistance) {
785
- this.handleTouchStart(event);
786
- }
787
57
 
788
- const distance = this.getPinchDistance(event.touches);
789
- if (!distance || !this.pinchStartDistance) {
790
- return;
791
- }
792
-
793
- this.setZoom(this.pinchStartZoom * (distance / this.pinchStartDistance));
794
- event.preventDefault();
795
- }
796
-
797
- handleTouchEnd(event) {
798
- if (event.touches?.length === 2) {
799
- return;
800
- }
801
-
802
- this.pinchStartDistance = 0;
803
- this.pinchStartZoom = this.zoom;
804
- }
805
-
806
- cancelVisiblePageRenders() {
807
- this.visiblePages.forEach((pageNumber) => {
808
- const state = this.pageStates.get(pageNumber);
809
- if (!state) {
810
- return;
811
- }
812
-
813
- state.needsRender = false;
814
- this.disposePageView(state);
815
- });
816
- }
817
-
818
- scheduleVisiblePageRender() {
819
- if (this.zoomRenderTimerId) {
820
- window.clearTimeout(this.zoomRenderTimerId);
821
- }
822
-
823
- this.zoomRenderTimerId = window.setTimeout(() => {
824
- this.zoomRenderTimerId = 0;
825
- this.commitPageZoom({ measure: false });
826
- this.visiblePages.forEach((pageNumber) => {
827
- const state = this.pageStates.get(pageNumber);
828
- if (state) {
829
- state.needsRender = true;
830
- }
831
- void this.renderPage(pageNumber, this.renderToken);
832
- });
833
- }, PDF_ZOOM.renderDebounceMs);
834
- }
835
-
836
- setZoom(zoom) {
837
- const nextZoom = clamp(zoom, PDF_ZOOM.min, PDF_ZOOM.max);
838
- if (nextZoom === this.zoom) {
839
- return;
840
- }
841
-
842
- this.cancelVisiblePageRenders();
843
- this.zoom = nextZoom;
844
- this.updateZoomControls();
845
- this.applyLivePageZoom();
846
- this.scheduleVisiblePageRender();
847
- }
848
-
849
- updateZoomControls() {
850
- if (!this.zoomControls) {
851
- return;
852
- }
853
-
854
- const percentage = `${Math.round(this.zoom * 100)}%`;
855
- this.zoomControls.zoomLabel.textContent = percentage;
856
- this.zoomControls.zoomLabel.setAttribute('aria-label', `Zoom ${percentage}`);
857
- this.zoomControls.zoomOutButton.disabled = this.zoom <= PDF_ZOOM.min;
858
- this.zoomControls.zoomInButton.disabled = this.zoom >= PDF_ZOOM.max;
859
- }
860
-
861
- applyLivePageZoom() {
862
- const pagesElement = this.shell?.querySelector('.pdf-file-preview-pages');
863
- if (!pagesElement) {
864
- return;
865
- }
866
-
867
- const scale = this.pageLayoutZoom > 0 ? this.zoom / this.pageLayoutZoom : 1;
868
- if (Math.abs(scale - 1) < 0.001) {
869
- pagesElement.style.removeProperty('transform');
870
- pagesElement.style.removeProperty('transform-origin');
871
- pagesElement.style.removeProperty('will-change');
872
- return;
873
- }
874
-
875
- pagesElement.style.transformOrigin = 'top center';
876
- pagesElement.style.transform = `scale(${scale})`;
877
- pagesElement.style.willChange = 'transform';
878
- }
879
-
880
- commitPageZoom({ measure = true, preserveLiveZoom = false } = {}) {
881
- const pagesElement = this.shell?.querySelector('.pdf-file-preview-pages');
882
- if (!pagesElement) {
883
- return;
884
- }
885
-
886
- if (measure) {
887
- const styles = window.getComputedStyle(pagesElement);
888
- const horizontalPadding = Number.parseFloat(styles.paddingLeft || '0')
889
- + Number.parseFloat(styles.paddingRight || '0');
890
- const availableWidth = pagesElement.clientWidth - horizontalPadding;
891
- this.pageFitWidth = Math.min(
892
- MAX_PAGE_WIDTH,
893
- availableWidth > 0 ? availableWidth : (this.previewContainer?.clientWidth || DEFAULT_PAGE_WIDTH),
894
- );
895
- }
896
-
897
- const layoutZoom = preserveLiveZoom ? this.pageLayoutZoom : this.zoom;
898
- pagesElement.style.setProperty(
899
- '--pdf-page-width',
900
- `${Math.max(1, this.pageFitWidth * layoutZoom)}px`,
901
- );
902
- if (preserveLiveZoom) {
903
- return;
904
- }
905
-
906
- this.pageLayoutZoom = this.zoom;
907
- pagesElement.style.removeProperty('transform');
908
- pagesElement.style.removeProperty('transform-origin');
909
- pagesElement.style.removeProperty('will-change');
910
- }
911
-
912
- getPageWidth(pageShell) {
913
- return pageShell.offsetWidth
914
- || pageShell.getBoundingClientRect().width
915
- || this.previewContainer?.clientWidth
916
- || DEFAULT_PAGE_WIDTH;
917
- }
918
-
919
- releasePage(pageNumber) {
920
- const state = this.pageStates.get(pageNumber);
921
- if (!state) {
922
- return;
923
- }
924
-
925
- state.needsRender = true;
926
- this.disposePageView(state);
927
- state.pageShell.replaceChildren();
928
- }
929
-
930
- setStatus(text) {
931
- const status = this.shell?.querySelector('.pdf-file-preview-status');
932
- if (status) {
933
- status.textContent = text;
58
+ this.viewer = viewer;
59
+ } catch {
60
+ if (token !== this.renderToken) return;
61
+ viewerHost.classList.add('pdf-file-preview-error');
62
+ viewerHost.textContent = 'This PDF could not be rendered in the browser.';
934
63
  }
935
64
  }
936
65
 
937
- showError(shell) {
938
- this.setStatus('Unable to render PDF');
939
- const pages = shell.querySelector('.pdf-file-preview-pages');
940
- if (!pages) {
941
- return;
942
- }
943
-
944
- const error = document.createElement('div');
945
- error.className = 'pdf-file-preview-error';
946
- error.textContent = 'This PDF could not be rendered in the browser.';
947
-
948
- pages.replaceChildren(error);
66
+ setTheme(theme) {
67
+ this.viewer?.setTheme?.(theme);
949
68
  }
950
69
 
951
70
  cancel() {
952
71
  this.renderToken += 1;
953
- if (this.zoomRenderTimerId) {
954
- window.clearTimeout(this.zoomRenderTimerId);
955
- this.zoomRenderTimerId = 0;
956
- }
957
- this.intersectionObserver?.disconnect();
958
- this.resizeObserver?.disconnect();
959
- this.intersectionObserver = null;
960
- this.resizeObserver = null;
961
- this.pageStates.forEach((state) => this.disposePageView(state));
962
- this.findEventBus?.dispatch('findbarclose', { source: this });
963
- this.findController?.setDocument(null);
964
- this.outlineController?.clearPdfOutline?.();
965
- const loadingTaskDestroy = this.loadingTask?.destroy?.();
966
- loadingTaskDestroy?.catch?.(() => {});
967
- const pdfDocumentDestroy = this.pdfDocument?.destroy?.();
968
- pdfDocumentDestroy?.catch?.(() => {});
969
- this.loadingTask = null;
970
- this.pdfDocument = null;
971
- this.findEventBus = null;
972
- this.findController = null;
973
- this.pdfLinkService = null;
974
- this.pdfJsApi = null;
975
- this.pdfViewerApi = null;
976
- this.pageStates.clear();
977
- this.visiblePages.clear();
978
- this.zoomControls = null;
979
- this.navigationControls = null;
980
- this.searchControls = null;
981
- this.pdfNavigationStack = [];
982
- this.findState = null;
983
- this.currentPageNumber = 1;
984
- this.zoom = PDF_ZOOM.default;
985
- this.pageFitWidth = DEFAULT_PAGE_WIDTH;
986
- this.pageLayoutZoom = PDF_ZOOM.default;
987
- this.pinchStartDistance = 0;
988
- this.pinchStartZoom = PDF_ZOOM.default;
989
- this.shell = null;
72
+ this.viewer?.remove();
73
+ this.viewer = null;
990
74
  }
991
-
992
75
  }