@arbidocs/blocks 0.5.120 → 0.5.121

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 (413) hide show
  1. package/dist/ClippingMediaViewer-B6WG7Q64.cjs +156 -0
  2. package/dist/ClippingMediaViewer-B6WG7Q64.cjs.map +1 -0
  3. package/dist/ClippingPdfViewer-6GCVTV3V.cjs +79 -0
  4. package/dist/ClippingPdfViewer-6GCVTV3V.cjs.map +1 -0
  5. package/dist/{ConnectedCallDock-WER7R222.cjs → ConnectedCallDock-DC5V5OUJ.cjs} +25 -23
  6. package/dist/ConnectedCallDock-DC5V5OUJ.cjs.map +1 -0
  7. package/dist/{ConnectedCallRoom-T7OBQTYP.cjs → ConnectedCallRoom-FQLXWTFB.cjs} +18 -16
  8. package/dist/{ConnectedCallRoom-T7OBQTYP.cjs.map → ConnectedCallRoom-FQLXWTFB.cjs.map} +1 -1
  9. package/dist/{ConnectedNativeDocxComparison-SGE4R3M4.cjs → ConnectedNativeDocxComparison-4Q5S7VLD.cjs} +17 -17
  10. package/dist/{ConnectedNativeDocxComparison-SGE4R3M4.cjs.map → ConnectedNativeDocxComparison-4Q5S7VLD.cjs.map} +1 -1
  11. package/dist/ConnectedPresentation-4HLDZDWV.cjs +183 -0
  12. package/dist/ConnectedPresentation-4HLDZDWV.cjs.map +1 -0
  13. package/dist/{ConnectedProductionSetDialog-LHB4VQWC.cjs → ConnectedProductionSetDialog-4EAY6KAZ.cjs} +3 -3
  14. package/dist/{ConnectedProductionSetDialog-LHB4VQWC.cjs.map → ConnectedProductionSetDialog-4EAY6KAZ.cjs.map} +1 -1
  15. package/dist/ConnectedSlidesTab-7QDE2CZD.cjs +234 -0
  16. package/dist/ConnectedSlidesTab-7QDE2CZD.cjs.map +1 -0
  17. package/dist/{ConnectedStreamedWordArtifact-6MCLJRIT.cjs → ConnectedStreamedWordArtifact-FFOQJBOI.cjs} +17 -17
  18. package/dist/{ConnectedStreamedWordArtifact-6MCLJRIT.cjs.map → ConnectedStreamedWordArtifact-FFOQJBOI.cjs.map} +1 -1
  19. package/dist/{DocumentReviewCard-BPIAJJED.cjs → DocumentReviewCard-SNWVEZ7S.cjs} +17 -16
  20. package/dist/DocumentReviewCard-SNWVEZ7S.cjs.map +1 -0
  21. package/dist/{FilesViewerDialog-67WK3TZC.cjs → FilesViewerDialog-IZI63FOV.cjs} +52 -45
  22. package/dist/FilesViewerDialog-IZI63FOV.cjs.map +1 -0
  23. package/dist/{GridViewImpl-ZMJJWTOM.cjs → GridViewImpl-LTYET77Q.cjs} +3 -3
  24. package/dist/GridViewImpl-LTYET77Q.cjs.map +1 -0
  25. package/dist/{WorkspaceTableView-J3C6VH4T.cjs → WorkspaceTableView-TEIRB6VJ.cjs} +11 -10
  26. package/dist/WorkspaceTableView-TEIRB6VJ.cjs.map +1 -0
  27. package/dist/agents/index.cjs +297 -297
  28. package/dist/{ai-IM4A23YT.cjs → ai-KBYNRNZ6.cjs} +28 -26
  29. package/dist/ai-KBYNRNZ6.cjs.map +1 -0
  30. package/dist/calls/connected/CallControls.d.ts +2 -0
  31. package/dist/calls/connected/CallControls.js +71 -9
  32. package/dist/calls/connected/CallControls.js.map +2 -2
  33. package/dist/calls/connected/ShareDocumentDialog.d.ts +14 -0
  34. package/dist/calls/connected/ShareDocumentDialog.js +77 -0
  35. package/dist/calls/connected/ShareDocumentDialog.js.map +7 -0
  36. package/dist/calls/index.cjs +121 -121
  37. package/dist/chat/index.cjs +9 -8
  38. package/dist/{chunk-T23UTIRI.cjs → chunk-2PZT3J34.cjs} +6 -6
  39. package/dist/{chunk-T23UTIRI.cjs.map → chunk-2PZT3J34.cjs.map} +1 -1
  40. package/dist/{chunk-SGYSDABK.cjs → chunk-2W5E62EY.cjs} +6 -6
  41. package/dist/{chunk-SGYSDABK.cjs.map → chunk-2W5E62EY.cjs.map} +1 -1
  42. package/dist/{chunk-TDO5UWXF.cjs → chunk-3SCNXNHI.cjs} +5 -5
  43. package/dist/{chunk-TDO5UWXF.cjs.map → chunk-3SCNXNHI.cjs.map} +1 -1
  44. package/dist/{chunk-KTQOGT2L.cjs → chunk-474GPLCM.cjs} +7 -7
  45. package/dist/{chunk-KTQOGT2L.cjs.map → chunk-474GPLCM.cjs.map} +1 -1
  46. package/dist/{chunk-TP5PGWIO.cjs → chunk-4IOYQLKG.cjs} +3 -3
  47. package/dist/{chunk-TP5PGWIO.cjs.map → chunk-4IOYQLKG.cjs.map} +1 -1
  48. package/dist/{chunk-NY3YUCOW.cjs → chunk-4NPCDS2X.cjs} +3 -3
  49. package/dist/{chunk-NY3YUCOW.cjs.map → chunk-4NPCDS2X.cjs.map} +1 -1
  50. package/dist/{chunk-HA66DHW6.cjs → chunk-4RBQ44RY.cjs} +28 -28
  51. package/dist/chunk-4RBQ44RY.cjs.map +1 -0
  52. package/dist/{chunk-BQ5RIWWT.cjs → chunk-4VZZWYEC.cjs} +3 -3
  53. package/dist/{chunk-BQ5RIWWT.cjs.map → chunk-4VZZWYEC.cjs.map} +1 -1
  54. package/dist/{chunk-BP3IJ34D.cjs → chunk-52KGMAO5.cjs} +15 -15
  55. package/dist/{chunk-BP3IJ34D.cjs.map → chunk-52KGMAO5.cjs.map} +1 -1
  56. package/dist/{chunk-5IZFSAEZ.cjs → chunk-5534FYXP.cjs} +4 -4
  57. package/dist/{chunk-5IZFSAEZ.cjs.map → chunk-5534FYXP.cjs.map} +1 -1
  58. package/dist/chunk-5GCCUXMT.cjs +63 -0
  59. package/dist/chunk-5GCCUXMT.cjs.map +1 -0
  60. package/dist/chunk-5LTIZ44D.cjs +95 -0
  61. package/dist/chunk-5LTIZ44D.cjs.map +1 -0
  62. package/dist/{chunk-DFBDQKGE.cjs → chunk-734NPQNR.cjs} +4 -4
  63. package/dist/{chunk-DFBDQKGE.cjs.map → chunk-734NPQNR.cjs.map} +1 -1
  64. package/dist/{chunk-X36UR4A7.cjs → chunk-7VUJGHMY.cjs} +323 -96
  65. package/dist/chunk-7VUJGHMY.cjs.map +1 -0
  66. package/dist/chunk-AFQTQC7A.cjs +35 -0
  67. package/dist/chunk-AFQTQC7A.cjs.map +1 -0
  68. package/dist/{chunk-YYSBWMDJ.cjs → chunk-AY6EZSZB.cjs} +4 -4
  69. package/dist/{chunk-YYSBWMDJ.cjs.map → chunk-AY6EZSZB.cjs.map} +1 -1
  70. package/dist/{chunk-BUVIBHFU.cjs → chunk-BVAT4EVC.cjs} +38 -38
  71. package/dist/chunk-BVAT4EVC.cjs.map +1 -0
  72. package/dist/{chunk-ECLUFKYR.cjs → chunk-C2OICDMI.cjs} +10 -10
  73. package/dist/{chunk-ECLUFKYR.cjs.map → chunk-C2OICDMI.cjs.map} +1 -1
  74. package/dist/{chunk-CPR6EHG7.cjs → chunk-DR2AH7JL.cjs} +179 -55
  75. package/dist/chunk-DR2AH7JL.cjs.map +1 -0
  76. package/dist/{chunk-NJCK6V6U.cjs → chunk-EATIFPKP.cjs} +4 -60
  77. package/dist/chunk-EATIFPKP.cjs.map +1 -0
  78. package/dist/{chunk-B3LZITVF.cjs → chunk-EHP6OH5D.cjs} +11 -451
  79. package/dist/chunk-EHP6OH5D.cjs.map +1 -0
  80. package/dist/{chunk-775S43W7.cjs → chunk-ENGL7P3I.cjs} +31 -31
  81. package/dist/{chunk-775S43W7.cjs.map → chunk-ENGL7P3I.cjs.map} +1 -1
  82. package/dist/{chunk-VZCPMXWC.cjs → chunk-FKFQCK3C.cjs} +4 -4
  83. package/dist/{chunk-VZCPMXWC.cjs.map → chunk-FKFQCK3C.cjs.map} +1 -1
  84. package/dist/{chunk-6UTKM5AB.cjs → chunk-GKVE5JGB.cjs} +76 -76
  85. package/dist/chunk-GKVE5JGB.cjs.map +1 -0
  86. package/dist/{chunk-Q6CLWOP2.cjs → chunk-GPX5VC57.cjs} +50 -50
  87. package/dist/{chunk-Q6CLWOP2.cjs.map → chunk-GPX5VC57.cjs.map} +1 -1
  88. package/dist/{chunk-WAV762GP.cjs → chunk-GQXPNIRE.cjs} +6 -6
  89. package/dist/{chunk-WAV762GP.cjs.map → chunk-GQXPNIRE.cjs.map} +1 -1
  90. package/dist/chunk-GX2EBMJW.cjs +133 -0
  91. package/dist/chunk-GX2EBMJW.cjs.map +1 -0
  92. package/dist/{chunk-7OPOPYV6.cjs → chunk-H5OLHP2U.cjs} +3 -3
  93. package/dist/{chunk-7OPOPYV6.cjs.map → chunk-H5OLHP2U.cjs.map} +1 -1
  94. package/dist/chunk-HYUKPHCT.cjs +66 -0
  95. package/dist/chunk-HYUKPHCT.cjs.map +1 -0
  96. package/dist/{chunk-NLSWDP42.cjs → chunk-JQLWKNJO.cjs} +22 -12
  97. package/dist/chunk-JQLWKNJO.cjs.map +1 -0
  98. package/dist/{chunk-CKCG4NDB.cjs → chunk-JZEYHDWJ.cjs} +75 -75
  99. package/dist/{chunk-CKCG4NDB.cjs.map → chunk-JZEYHDWJ.cjs.map} +1 -1
  100. package/dist/{chunk-PGJYD67F.cjs → chunk-KNGZZC4O.cjs} +7 -6
  101. package/dist/chunk-KNGZZC4O.cjs.map +1 -0
  102. package/dist/{chunk-W6INT5GS.cjs → chunk-KP5AITQ4.cjs} +10 -10
  103. package/dist/{chunk-W6INT5GS.cjs.map → chunk-KP5AITQ4.cjs.map} +1 -1
  104. package/dist/{chunk-YYPZOEED.cjs → chunk-LHWOKOMP.cjs} +23 -2
  105. package/dist/chunk-LHWOKOMP.cjs.map +1 -0
  106. package/dist/{chunk-WXUU3COI.cjs → chunk-MZ2KZXNU.cjs} +3 -3
  107. package/dist/{chunk-WXUU3COI.cjs.map → chunk-MZ2KZXNU.cjs.map} +1 -1
  108. package/dist/chunk-NAJN32MF.cjs +154 -0
  109. package/dist/chunk-NAJN32MF.cjs.map +1 -0
  110. package/dist/{chunk-557MJ4IH.cjs → chunk-NLOETJCB.cjs} +17 -154
  111. package/dist/chunk-NLOETJCB.cjs.map +1 -0
  112. package/dist/{chunk-4XJEHKVZ.cjs → chunk-PIYYBPHH.cjs} +4 -4
  113. package/dist/{chunk-4XJEHKVZ.cjs.map → chunk-PIYYBPHH.cjs.map} +1 -1
  114. package/dist/chunk-Q3XJUXID.cjs +4774 -0
  115. package/dist/chunk-Q3XJUXID.cjs.map +1 -0
  116. package/dist/{chunk-325GVZE6.cjs → chunk-Q6DQGGP4.cjs} +3 -3
  117. package/dist/{chunk-325GVZE6.cjs.map → chunk-Q6DQGGP4.cjs.map} +1 -1
  118. package/dist/chunk-QFXILJMJ.cjs +458 -0
  119. package/dist/chunk-QFXILJMJ.cjs.map +1 -0
  120. package/dist/{chunk-QQWHG3KF.cjs → chunk-RYVZDFVO.cjs} +5 -5
  121. package/dist/{chunk-QQWHG3KF.cjs.map → chunk-RYVZDFVO.cjs.map} +1 -1
  122. package/dist/{chunk-EOG6OT5I.cjs → chunk-TXP2N3DC.cjs} +4 -4
  123. package/dist/{chunk-EOG6OT5I.cjs.map → chunk-TXP2N3DC.cjs.map} +1 -1
  124. package/dist/{chunk-KXIRVKCJ.cjs → chunk-UUENH4BJ.cjs} +3 -3
  125. package/dist/{chunk-KXIRVKCJ.cjs.map → chunk-UUENH4BJ.cjs.map} +1 -1
  126. package/dist/chunk-VJ5ZLRBD.cjs +27 -0
  127. package/dist/chunk-VJ5ZLRBD.cjs.map +1 -0
  128. package/dist/{chunk-3GWWOYGS.cjs → chunk-W6B3RYTX.cjs} +4 -4
  129. package/dist/{chunk-3GWWOYGS.cjs.map → chunk-W6B3RYTX.cjs.map} +1 -1
  130. package/dist/chunk-WOOOMTTA.cjs +19 -0
  131. package/dist/chunk-WOOOMTTA.cjs.map +1 -0
  132. package/dist/{chunk-CJYWHUZR.cjs → chunk-XCKHOXRP.cjs} +4 -4
  133. package/dist/{chunk-CJYWHUZR.cjs.map → chunk-XCKHOXRP.cjs.map} +1 -1
  134. package/dist/{chunk-6WMMZLEV.cjs → chunk-XJEXFEWG.cjs} +2 -27
  135. package/dist/chunk-XJEXFEWG.cjs.map +1 -0
  136. package/dist/chunk-XK4TVJKD.cjs +73 -0
  137. package/dist/chunk-XK4TVJKD.cjs.map +1 -0
  138. package/dist/chunk-XTR26TNE.cjs +1358 -0
  139. package/dist/chunk-XTR26TNE.cjs.map +1 -0
  140. package/dist/{chunk-E7TE2WVT.cjs → chunk-ZVEW3JBT.cjs} +3 -3
  141. package/dist/{chunk-E7TE2WVT.cjs.map → chunk-ZVEW3JBT.cjs.map} +1 -1
  142. package/dist/collaboration/index.cjs +70 -70
  143. package/dist/components/ZoomSlider.d.ts +25 -0
  144. package/dist/components/ZoomSlider.js +59 -0
  145. package/dist/components/ZoomSlider.js.map +7 -0
  146. package/dist/connect/docx.cjs +20 -20
  147. package/dist/connect/index.cjs +1150 -1232
  148. package/dist/connect/index.cjs.map +1 -1
  149. package/dist/connect/viewer.cjs +40 -34
  150. package/dist/connection/ai.d.ts +1 -1
  151. package/dist/connection/files/ConnectedNewFileMenu.d.ts +2 -1
  152. package/dist/connection/files/ConnectedNewFileMenu.js +9 -3
  153. package/dist/connection/files/ConnectedNewFileMenu.js.map +2 -2
  154. package/dist/connection/files/explorer/ConnectedFilesExplorer.js +1 -1
  155. package/dist/connection/files/explorer/ConnectedFilesExplorer.js.map +2 -2
  156. package/dist/connection/files/explorer/FileTiles.js +1 -1
  157. package/dist/connection/files/explorer/FileTiles.js.map +2 -2
  158. package/dist/connection/files/fields/documentField.js +1 -1
  159. package/dist/connection/files/fields/documentField.js.map +2 -2
  160. package/dist/connection/files/grid/documentColumns.js +1 -1
  161. package/dist/connection/files/grid/documentColumns.js.map +2 -2
  162. package/dist/connection/files/page/DocumentsFilterBarActions.js +17 -28
  163. package/dist/connection/files/page/DocumentsFilterBarActions.js.map +2 -2
  164. package/dist/connection/mail/useMailboxDefaults.js +1 -1
  165. package/dist/connection/mail/useMailboxDefaults.js.map +2 -2
  166. package/dist/connection/panels/useSessionPanelMode.js +3 -2
  167. package/dist/connection/panels/useSessionPanelMode.js.map +2 -2
  168. package/dist/connection/presentation/ClippingMediaViewer.d.ts +12 -0
  169. package/dist/connection/presentation/ClippingMediaViewer.js +153 -0
  170. package/dist/connection/presentation/ClippingMediaViewer.js.map +7 -0
  171. package/dist/connection/presentation/ClippingPdfViewer.d.ts +22 -0
  172. package/dist/connection/presentation/ClippingPdfViewer.js +75 -0
  173. package/dist/connection/presentation/ClippingPdfViewer.js.map +7 -0
  174. package/dist/connection/presentation/ConnectedPresentation.d.ts +12 -0
  175. package/dist/connection/presentation/ConnectedPresentation.js +100 -0
  176. package/dist/connection/presentation/ConnectedPresentation.js.map +7 -0
  177. package/dist/connection/presentation/ConnectedSlidesTab.d.ts +20 -0
  178. package/dist/connection/presentation/ConnectedSlidesTab.js +220 -0
  179. package/dist/connection/presentation/ConnectedSlidesTab.js.map +7 -0
  180. package/dist/connection/presentation/CropClipDialog.d.ts +11 -0
  181. package/dist/connection/presentation/CropClipDialog.js +86 -0
  182. package/dist/connection/presentation/CropClipDialog.js.map +7 -0
  183. package/dist/connection/presentation/GenerateTile.d.ts +4 -0
  184. package/dist/connection/presentation/GenerateTile.js +24 -0
  185. package/dist/connection/presentation/GenerateTile.js.map +7 -0
  186. package/dist/connection/presentation/LabelColumnMenu.d.ts +8 -0
  187. package/dist/connection/presentation/LabelColumnMenu.js +38 -0
  188. package/dist/connection/presentation/LabelColumnMenu.js.map +7 -0
  189. package/dist/connection/presentation/PresentationDialogs.d.ts +39 -0
  190. package/dist/connection/presentation/PresentationDialogs.js +295 -0
  191. package/dist/connection/presentation/PresentationDialogs.js.map +7 -0
  192. package/dist/connection/presentation/PresentationFileCard.d.ts +10 -0
  193. package/dist/connection/presentation/PresentationFileCard.js +35 -0
  194. package/dist/connection/presentation/PresentationFileCard.js.map +7 -0
  195. package/dist/connection/presentation/PresentationPill.d.ts +8 -0
  196. package/dist/connection/presentation/PresentationPill.js +44 -0
  197. package/dist/connection/presentation/PresentationPill.js.map +7 -0
  198. package/dist/connection/presentation/PresentationSlot.d.ts +7 -0
  199. package/dist/connection/presentation/PresentationSlot.js +35 -0
  200. package/dist/connection/presentation/PresentationSlot.js.map +7 -0
  201. package/dist/connection/presentation/requests.d.ts +16 -0
  202. package/dist/connection/presentation/requests.js +20 -0
  203. package/dist/connection/presentation/requests.js.map +7 -0
  204. package/dist/connection/presentation/useImageGeneration.d.ts +11 -0
  205. package/dist/connection/presentation/useImageGeneration.js +66 -0
  206. package/dist/connection/presentation/useImageGeneration.js.map +7 -0
  207. package/dist/connection/presentation/useLabelColumns.d.ts +15 -0
  208. package/dist/connection/presentation/useLabelColumns.js +33 -0
  209. package/dist/connection/presentation/useLabelColumns.js.map +7 -0
  210. package/dist/connection/presentation/usePresentationController.d.ts +15 -0
  211. package/dist/connection/presentation/usePresentationController.js +118 -0
  212. package/dist/connection/presentation/usePresentationController.js.map +7 -0
  213. package/dist/connection/presentation/usePresentationFiles.d.ts +44 -0
  214. package/dist/connection/presentation/usePresentationFiles.js +307 -0
  215. package/dist/connection/presentation/usePresentationFiles.js.map +7 -0
  216. package/dist/connection/presentation/useViewerClipping.d.ts +14 -0
  217. package/dist/connection/presentation/useViewerClipping.js +18 -0
  218. package/dist/connection/presentation/useViewerClipping.js.map +7 -0
  219. package/dist/connection/shell/ConnectedAppShell.js +5 -1
  220. package/dist/connection/shell/ConnectedAppShell.js.map +2 -2
  221. package/dist/connection/viewer/CleanViewControl.d.ts +8 -0
  222. package/dist/connection/viewer/CleanViewControl.js +76 -0
  223. package/dist/connection/viewer/CleanViewControl.js.map +7 -0
  224. package/dist/connection/viewer/ConnectedDocumentViewer.js +28 -29
  225. package/dist/connection/viewer/ConnectedDocumentViewer.js.map +2 -2
  226. package/dist/connection/viewer/ViewerCropModal.d.ts +5 -0
  227. package/dist/connection/viewer/ViewerCropModal.js +22 -0
  228. package/dist/connection/viewer/ViewerCropModal.js.map +7 -0
  229. package/dist/connection/viewer/ViewerPdfPane.d.ts +3 -1
  230. package/dist/connection/viewer/ViewerPdfPane.js +37 -0
  231. package/dist/connection/viewer/ViewerPdfPane.js.map +2 -2
  232. package/dist/connection/viewer/drafts.js +6 -4
  233. package/dist/connection/viewer/drafts.js.map +2 -2
  234. package/dist/connection/viewer/shareDocument.d.ts +11 -0
  235. package/dist/connection/viewer/shareDocument.js +11 -0
  236. package/dist/connection/viewer/shareDocument.js.map +7 -0
  237. package/dist/connection/viewer/slidesTabChunk.d.ts +2 -0
  238. package/dist/connection/viewer/slidesTabChunk.js +9 -0
  239. package/dist/connection/viewer/slidesTabChunk.js.map +7 -0
  240. package/dist/connection/viewer/useCleanView.d.ts +14 -0
  241. package/dist/connection/viewer/useCleanView.js +29 -0
  242. package/dist/connection/viewer/useCleanView.js.map +7 -0
  243. package/dist/connection/viewer/useViewedDocument.d.ts +1 -0
  244. package/dist/connection/viewer/useViewedDocument.js +9 -1
  245. package/dist/connection/viewer/useViewedDocument.js.map +2 -2
  246. package/dist/connection/viewer/useViewerTabs.js +18 -4
  247. package/dist/connection/viewer/useViewerTabs.js.map +2 -2
  248. package/dist/connection/workflows/ConnectedWorkflowStart.d.ts +14 -2
  249. package/dist/connection/workflows/ConnectedWorkflowStart.js +5 -2
  250. package/dist/connection/workflows/ConnectedWorkflowStart.js.map +2 -2
  251. package/dist/dashboards/index.cjs +1 -1
  252. package/dist/databases/index.cjs +49 -49
  253. package/dist/document-tools/DocumentToolButtons.d.ts +2 -0
  254. package/dist/document-tools/DocumentToolButtons.js +22 -1
  255. package/dist/document-tools/DocumentToolButtons.js.map +2 -2
  256. package/dist/document-tools/index.cjs +16 -12
  257. package/dist/document-tools/index.d.ts +1 -1
  258. package/dist/document-tools/index.js +2 -0
  259. package/dist/document-tools/index.js.map +2 -2
  260. package/dist/embed/index.cjs +41 -39
  261. package/dist/files/GridViewImpl.js +1 -1
  262. package/dist/files/GridViewImpl.js.map +2 -2
  263. package/dist/files/ViewerChrome.d.ts +5 -1
  264. package/dist/files/ViewerChrome.js +16 -6
  265. package/dist/files/ViewerChrome.js.map +2 -2
  266. package/dist/files/index.cjs +225 -225
  267. package/dist/files/navigator/DocumentSearchList.js +1 -1
  268. package/dist/files/navigator/DocumentSearchList.js.map +2 -2
  269. package/dist/index.cjs +1666 -1664
  270. package/dist/index.cjs.map +1 -1
  271. package/dist/presentation/BoxActionBar.d.ts +11 -0
  272. package/dist/presentation/BoxActionBar.js +182 -0
  273. package/dist/presentation/BoxActionBar.js.map +7 -0
  274. package/dist/presentation/ClipActionBar.d.ts +26 -0
  275. package/dist/presentation/ClipActionBar.js +103 -0
  276. package/dist/presentation/ClipActionBar.js.map +7 -0
  277. package/dist/presentation/ClipCaptureOverlay.d.ts +14 -0
  278. package/dist/presentation/ClipCaptureOverlay.js +69 -0
  279. package/dist/presentation/ClipCaptureOverlay.js.map +7 -0
  280. package/dist/presentation/ClipImage.d.ts +21 -0
  281. package/dist/presentation/ClipImage.js +119 -0
  282. package/dist/presentation/ClipImage.js.map +7 -0
  283. package/dist/presentation/ClipTray.d.ts +11 -0
  284. package/dist/presentation/ClipTray.js +152 -0
  285. package/dist/presentation/ClipTray.js.map +7 -0
  286. package/dist/presentation/ClipViewControls.d.ts +11 -0
  287. package/dist/presentation/ClipViewControls.js +142 -0
  288. package/dist/presentation/ClipViewControls.js.map +7 -0
  289. package/dist/presentation/DesignMenu.d.ts +8 -0
  290. package/dist/presentation/DesignMenu.js +199 -0
  291. package/dist/presentation/DesignMenu.js.map +7 -0
  292. package/dist/presentation/LayoutMenu.d.ts +17 -0
  293. package/dist/presentation/LayoutMenu.js +122 -0
  294. package/dist/presentation/LayoutMenu.js.map +7 -0
  295. package/dist/presentation/MediaClip.d.ts +15 -0
  296. package/dist/presentation/MediaClip.js +67 -0
  297. package/dist/presentation/MediaClip.js.map +7 -0
  298. package/dist/presentation/Notice.d.ts +6 -0
  299. package/dist/presentation/Notice.js +43 -0
  300. package/dist/presentation/Notice.js.map +7 -0
  301. package/dist/presentation/PresentationStage.d.ts +32 -0
  302. package/dist/presentation/PresentationStage.js +232 -0
  303. package/dist/presentation/PresentationStage.js.map +7 -0
  304. package/dist/presentation/PresenterView.d.ts +16 -0
  305. package/dist/presentation/PresenterView.js +69 -0
  306. package/dist/presentation/PresenterView.js.map +7 -0
  307. package/dist/presentation/SlideDecor.d.ts +25 -0
  308. package/dist/presentation/SlideDecor.js +189 -0
  309. package/dist/presentation/SlideDecor.js.map +7 -0
  310. package/dist/presentation/SlidesEditor.d.ts +25 -0
  311. package/dist/presentation/SlidesEditor.js +359 -0
  312. package/dist/presentation/SlidesEditor.js.map +7 -0
  313. package/dist/presentation/StageBox.d.ts +30 -0
  314. package/dist/presentation/StageBox.js +281 -0
  315. package/dist/presentation/StageBox.js.map +7 -0
  316. package/dist/presentation/StageItem.d.ts +37 -0
  317. package/dist/presentation/StageItem.js +211 -0
  318. package/dist/presentation/StageItem.js.map +7 -0
  319. package/dist/presentation/box-style.d.ts +6 -0
  320. package/dist/presentation/box-style.js +19 -0
  321. package/dist/presentation/box-style.js.map +7 -0
  322. package/dist/presentation/boxes.d.ts +105 -0
  323. package/dist/presentation/boxes.js +103 -0
  324. package/dist/presentation/boxes.js.map +7 -0
  325. package/dist/presentation/draw-boxes.d.ts +8 -0
  326. package/dist/presentation/draw-boxes.js +130 -0
  327. package/dist/presentation/draw-boxes.js.map +7 -0
  328. package/dist/presentation/export-boxes.d.ts +10 -0
  329. package/dist/presentation/export-boxes.js +74 -0
  330. package/dist/presentation/export-boxes.js.map +7 -0
  331. package/dist/presentation/export-pptx.d.ts +16 -0
  332. package/dist/presentation/export-pptx.js +194 -0
  333. package/dist/presentation/export-pptx.js.map +7 -0
  334. package/dist/presentation/import-pptx.d.ts +35 -0
  335. package/dist/presentation/import-pptx.js +659 -0
  336. package/dist/presentation/import-pptx.js.map +7 -0
  337. package/dist/presentation/merge-outside-edits.d.ts +12 -0
  338. package/dist/presentation/merge-outside-edits.js +35 -0
  339. package/dist/presentation/merge-outside-edits.js.map +7 -0
  340. package/dist/presentation/model.d.ts +201 -0
  341. package/dist/presentation/model.js +271 -0
  342. package/dist/presentation/model.js.map +7 -0
  343. package/dist/presentation/panel-id.d.ts +34 -0
  344. package/dist/presentation/panel-id.js +24 -0
  345. package/dist/presentation/panel-id.js.map +7 -0
  346. package/dist/presentation/persistence.d.ts +121 -0
  347. package/dist/presentation/persistence.js +141 -0
  348. package/dist/presentation/persistence.js.map +7 -0
  349. package/dist/presentation/pptx-data.d.ts +22 -0
  350. package/dist/presentation/pptx-data.js +83 -0
  351. package/dist/presentation/pptx-data.js.map +7 -0
  352. package/dist/presentation/pptx-xml.d.ts +90 -0
  353. package/dist/presentation/pptx-xml.js +333 -0
  354. package/dist/presentation/pptx-xml.js.map +7 -0
  355. package/dist/presentation/render-slides.d.ts +58 -0
  356. package/dist/presentation/render-slides.js +309 -0
  357. package/dist/presentation/render-slides.js.map +7 -0
  358. package/dist/presentation/saved-boxes.d.ts +11 -0
  359. package/dist/presentation/saved-boxes.js +80 -0
  360. package/dist/presentation/saved-boxes.js.map +7 -0
  361. package/dist/presentation/slide-layout.d.ts +54 -0
  362. package/dist/presentation/slide-layout.js +117 -0
  363. package/dist/presentation/slide-layout.js.map +7 -0
  364. package/dist/presentation/stage-videos.d.ts +5 -0
  365. package/dist/presentation/stage-videos.js +19 -0
  366. package/dist/presentation/stage-videos.js.map +7 -0
  367. package/dist/presentation/store.d.ts +203 -0
  368. package/dist/presentation/store.js +429 -0
  369. package/dist/presentation/store.js.map +7 -0
  370. package/dist/presentation/theme.d.ts +102 -0
  371. package/dist/presentation/theme.js +276 -0
  372. package/dist/presentation/theme.js.map +7 -0
  373. package/dist/presentation/useClipDrag.d.ts +26 -0
  374. package/dist/presentation/useClipDrag.js +65 -0
  375. package/dist/presentation/useClipDrag.js.map +7 -0
  376. package/dist/presentation/useObjectUrl.d.ts +6 -0
  377. package/dist/presentation/useObjectUrl.js +15 -0
  378. package/dist/presentation/useObjectUrl.js.map +7 -0
  379. package/dist/presentation/usePresenterKeys.d.ts +13 -0
  380. package/dist/presentation/usePresenterKeys.js +62 -0
  381. package/dist/presentation/usePresenterKeys.js.map +7 -0
  382. package/dist/settings/index.cjs +151 -150
  383. package/dist/shell/PanelPortal.js +1 -0
  384. package/dist/shell/PanelPortal.js.map +2 -2
  385. package/dist/shell/index.cjs +112 -110
  386. package/dist/shell/panel-windows.d.ts +2 -0
  387. package/dist/shell/panel-windows.js +7 -2
  388. package/dist/shell/panel-windows.js.map +2 -2
  389. package/dist/studio/index.cjs +28 -26
  390. package/dist/studio/index.cjs.map +1 -1
  391. package/dist/styles.css +1 -1
  392. package/dist/workflow-canvas/index.cjs +55 -54
  393. package/dist/workflow-canvas/index.cjs.map +1 -1
  394. package/node_modules/@arbidocs/coedit/package.json +1 -1
  395. package/package.json +6 -5
  396. package/dist/ConnectedCallDock-WER7R222.cjs.map +0 -1
  397. package/dist/DocumentReviewCard-BPIAJJED.cjs.map +0 -1
  398. package/dist/FilesViewerDialog-67WK3TZC.cjs.map +0 -1
  399. package/dist/GridViewImpl-ZMJJWTOM.cjs.map +0 -1
  400. package/dist/WorkspaceTableView-J3C6VH4T.cjs.map +0 -1
  401. package/dist/ai-IM4A23YT.cjs.map +0 -1
  402. package/dist/chunk-557MJ4IH.cjs.map +0 -1
  403. package/dist/chunk-6UTKM5AB.cjs.map +0 -1
  404. package/dist/chunk-6WMMZLEV.cjs.map +0 -1
  405. package/dist/chunk-B3LZITVF.cjs.map +0 -1
  406. package/dist/chunk-BUVIBHFU.cjs.map +0 -1
  407. package/dist/chunk-CPR6EHG7.cjs.map +0 -1
  408. package/dist/chunk-HA66DHW6.cjs.map +0 -1
  409. package/dist/chunk-NJCK6V6U.cjs.map +0 -1
  410. package/dist/chunk-NLSWDP42.cjs.map +0 -1
  411. package/dist/chunk-PGJYD67F.cjs.map +0 -1
  412. package/dist/chunk-X36UR4A7.cjs.map +0 -1
  413. package/dist/chunk-YYPZOEED.cjs.map +0 -1
@@ -0,0 +1,66 @@
1
+ "use client";
2
+ import { useCallback } from "react";
3
+ import { useArbi, useArbiSessionState } from "@arbidocs/react";
4
+ import { GENERATE_IMAGE_ID } from "../../agents/workflows/catalogue/seed.js";
5
+ import { PROMPT_BINDINGS } from "../workflows/launch-bindings.js";
6
+ import { mediaCaption } from "../../presentation/model.js";
7
+ import { usePresentation } from "../../presentation/store.js";
8
+ const WHOLE = { x: 0, y: 0, w: 1, h: 1 };
9
+ async function aspectOf(blob) {
10
+ const bitmap = await createImageBitmap(blob);
11
+ const aspect = bitmap.width / bitmap.height;
12
+ bitmap.close();
13
+ return aspect;
14
+ }
15
+ function useGenerateImageLaunch() {
16
+ const arbi = useArbi();
17
+ const workspaceId = useArbiSessionState((s) => s.workspaceId);
18
+ return useCallback(
19
+ async ({ inputs }) => {
20
+ if (!arbi || !workspaceId) throw new Error("Open a workspace to generate images.");
21
+ const prompt = typeof inputs.prompt === "string" ? inputs.prompt.trim() : "";
22
+ if (!prompt) return;
23
+ const tools = PROMPT_BINDINGS[GENERATE_IMAGE_ID].tools?.(inputs);
24
+ let image;
25
+ let answer = "";
26
+ let failure = "";
27
+ await arbi.assistant.ask(
28
+ { question: `/image ${prompt}`, workspaceId, ...tools ? { tools } : {} },
29
+ {
30
+ onToken: (token) => {
31
+ answer += token;
32
+ },
33
+ onError: (error) => {
34
+ failure = error instanceof Error ? error.message : String(error);
35
+ },
36
+ onArtifact: (artifact) => {
37
+ if (artifact.mode === "image" && artifact.doc_ext_id) image = artifact;
38
+ }
39
+ }
40
+ ).catch((error) => {
41
+ failure ||= error instanceof Error ? error.message : String(error);
42
+ });
43
+ const documentId = image?.doc_ext_id;
44
+ if (!documentId)
45
+ throw new Error(failure || answer.trim() || "The image could not be generated.");
46
+ const source = await (await arbi.documents.download(documentId)).blob();
47
+ const fileName = `${prompt.split("\n")[0].slice(0, 60)}.png`;
48
+ usePresentation.getState().addClip({
49
+ kind: "image",
50
+ documentId,
51
+ fileName,
52
+ page: 1,
53
+ rect: WHOLE,
54
+ aspect: await aspectOf(source),
55
+ masks: [],
56
+ source,
57
+ caption: mediaCaption(fileName)
58
+ });
59
+ },
60
+ [arbi, workspaceId]
61
+ );
62
+ }
63
+ export {
64
+ useGenerateImageLaunch
65
+ };
66
+ //# sourceMappingURL=useImageGeneration.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/connection/presentation/useImageGeneration.ts"],
4
+ "sourcesContent": ["/**\n * Generate image, for a presentation: the app's own Generate image dialog (the workflow's form:\n * prompt, source images to edit or combine, shape) launched here instead of into a chat. The run is\n * the platform's `/image` command sent exactly as that workflow sends it (`PROMPT_BINDINGS`: the\n * shape and source images ride structured tool arguments); like the workflow it leaves a thread\n * and the image as a document in the workspace. The image is then added to the presentation as a\n * clip of the whole picture.\n */\n\nimport { useCallback } from 'react'\nimport { useArbi, useArbiSessionState } from '@arbidocs/react'\nimport type { ArtifactEvent } from '@arbidocs/sdk/browser'\nimport { GENERATE_IMAGE_ID } from '../../agents/workflows/catalogue/seed'\nimport type { OnWorkflowLaunch } from '../../agents/workflows/types'\nimport { PROMPT_BINDINGS } from '../workflows/launch-bindings'\nimport { mediaCaption } from '../../presentation/model'\nimport { usePresentation } from '../../presentation/store'\n\nconst WHOLE = { x: 0, y: 0, w: 1, h: 1 }\n\n/** An image's width / height. */\nasync function aspectOf(blob: Blob): Promise<number> {\n const bitmap = await createImageBitmap(blob)\n const aspect = bitmap.width / bitmap.height\n bitmap.close()\n return aspect\n}\n\n/** The Generate image dialog's launch, run for the presentation: the image becomes a clip. */\nexport function useGenerateImageLaunch(): OnWorkflowLaunch {\n const arbi = useArbi()\n const workspaceId = useArbiSessionState((s) => s.workspaceId)\n\n return useCallback(\n async ({ inputs }) => {\n if (!arbi || !workspaceId) throw new Error('Open a workspace to generate images.')\n const prompt = typeof inputs.prompt === 'string' ? inputs.prompt.trim() : ''\n if (!prompt) return\n const tools = PROMPT_BINDINGS[GENERATE_IMAGE_ID].tools?.(inputs)\n let image: ArtifactEvent | undefined\n let answer = ''\n let failure = ''\n await arbi.assistant\n .ask(\n { question: `/image ${prompt}`, workspaceId, ...(tools ? { tools } : {}) },\n {\n onToken: (token) => {\n answer += token\n },\n onError: (error) => {\n failure = error instanceof Error ? error.message : String(error)\n },\n onArtifact: (artifact) => {\n if (artifact.mode === 'image' && artifact.doc_ext_id) image = artifact\n },\n }\n )\n .catch((error: unknown) => {\n failure ||= error instanceof Error ? error.message : String(error)\n })\n const documentId = image?.doc_ext_id\n // `/image` reports a refused or failed generation as its answer text.\n if (!documentId)\n throw new Error(failure || answer.trim() || 'The image could not be generated.')\n const source = await (await arbi.documents.download(documentId)).blob()\n const fileName = `${prompt.split('\\n')[0].slice(0, 60)}.png`\n usePresentation.getState().addClip({\n kind: 'image',\n documentId,\n fileName,\n page: 1,\n rect: WHOLE,\n aspect: await aspectOf(source),\n masks: [],\n source,\n caption: mediaCaption(fileName),\n })\n },\n [arbi, workspaceId]\n )\n}\n"],
5
+ "mappings": ";AASA,SAAS,mBAAmB;AAC5B,SAAS,SAAS,2BAA2B;AAE7C,SAAS,yBAAyB;AAElC,SAAS,uBAAuB;AAChC,SAAS,oBAAoB;AAC7B,SAAS,uBAAuB;AAEhC,MAAM,QAAQ,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAGvC,eAAe,SAAS,MAA6B;AACnD,QAAM,SAAS,MAAM,kBAAkB,IAAI;AAC3C,QAAM,SAAS,OAAO,QAAQ,OAAO;AACrC,SAAO,MAAM;AACb,SAAO;AACT;AAGO,SAAS,yBAA2C;AACzD,QAAM,OAAO,QAAQ;AACrB,QAAM,cAAc,oBAAoB,CAAC,MAAM,EAAE,WAAW;AAE5D,SAAO;AAAA,IACL,OAAO,EAAE,OAAO,MAAM;AACpB,UAAI,CAAC,QAAQ,CAAC,YAAa,OAAM,IAAI,MAAM,sCAAsC;AACjF,YAAM,SAAS,OAAO,OAAO,WAAW,WAAW,OAAO,OAAO,KAAK,IAAI;AAC1E,UAAI,CAAC,OAAQ;AACb,YAAM,QAAQ,gBAAgB,iBAAiB,EAAE,QAAQ,MAAM;AAC/D,UAAI;AACJ,UAAI,SAAS;AACb,UAAI,UAAU;AACd,YAAM,KAAK,UACR;AAAA,QACC,EAAE,UAAU,UAAU,MAAM,IAAI,aAAa,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC,EAAG;AAAA,QACzE;AAAA,UACE,SAAS,CAAC,UAAU;AAClB,sBAAU;AAAA,UACZ;AAAA,UACA,SAAS,CAAC,UAAU;AAClB,sBAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,UACjE;AAAA,UACA,YAAY,CAAC,aAAa;AACxB,gBAAI,SAAS,SAAS,WAAW,SAAS,WAAY,SAAQ;AAAA,UAChE;AAAA,QACF;AAAA,MACF,EACC,MAAM,CAAC,UAAmB;AACzB,oBAAY,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MACnE,CAAC;AACH,YAAM,aAAa,OAAO;AAE1B,UAAI,CAAC;AACH,cAAM,IAAI,MAAM,WAAW,OAAO,KAAK,KAAK,mCAAmC;AACjF,YAAM,SAAS,OAAO,MAAM,KAAK,UAAU,SAAS,UAAU,GAAG,KAAK;AACtE,YAAM,WAAW,GAAG,OAAO,MAAM,IAAI,EAAE,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC;AACtD,sBAAgB,SAAS,EAAE,QAAQ;AAAA,QACjC,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA,MAAM;AAAA,QACN,MAAM;AAAA,QACN,QAAQ,MAAM,SAAS,MAAM;AAAA,QAC7B,OAAO,CAAC;AAAA,QACR;AAAA,QACA,SAAS,aAAa,QAAQ;AAAA,MAChC,CAAC;AAAA,IACH;AAAA,IACA,CAAC,MAAM,WAAW;AAAA,EACpB;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Labelling clips with an annotation column: an Exhibit column's "R-100" leads the label of every
3
+ * clip of that document ("R-100 · Statement of case · p. 3"), so a hearing bundle's numbering is on
4
+ * the slide. The values are read live from the documents (editing one in Files updates the slides);
5
+ * only the column's choice is saved with the presentation.
6
+ */
7
+ export interface LabelColumn {
8
+ id: string;
9
+ name: string;
10
+ }
11
+ /**
12
+ * The workspace's columns a clip can be labelled with, and (while the presentation is open) each
13
+ * clip document's value in the chosen one, kept in the presentation store.
14
+ */
15
+ export declare function useLabelColumns(active: boolean): LabelColumn[];
@@ -0,0 +1,33 @@
1
+ "use client";
2
+ import { useEffect, useMemo } from "react";
3
+ import { useArbiSessionState, useDocuments, useTags } from "@arbidocs/react";
4
+ import { usePresentation } from "../../presentation/store.js";
5
+ const VALUE_FORMATS = /* @__PURE__ */ new Set(["text", "number", "select"]);
6
+ function useLabelColumns(active) {
7
+ const workspaceId = useArbiSessionState((s) => s.workspaceId);
8
+ const { data: tags } = useTags(workspaceId, { enabled: active });
9
+ const { data: documents } = useDocuments(workspaceId, { enabled: active });
10
+ const labelColumn = usePresentation((s) => s.labelColumn);
11
+ const documentIds = usePresentation((s) => s.clips.map((clip) => clip.documentId).join(" "));
12
+ const columns = useMemo(
13
+ () => (tags ?? []).filter((tag) => tag.kind !== "search" && VALUE_FORMATS.has(tag.tag_type.type)).map((tag) => ({ id: tag.external_id, name: tag.name })).sort((a, b) => a.name.localeCompare(b.name)),
14
+ [tags]
15
+ );
16
+ useEffect(() => {
17
+ const values = {};
18
+ if (labelColumn) {
19
+ const wanted = new Set(documentIds.split(" "));
20
+ for (const doc of documents ?? []) {
21
+ if (!wanted.has(doc.external_id)) continue;
22
+ const note = doc.doctags?.find((dt) => dt.tag_ext_id === labelColumn)?.note?.trim();
23
+ if (note) values[doc.external_id] = note;
24
+ }
25
+ }
26
+ usePresentation.getState().setColumnValues(values);
27
+ }, [labelColumn, documentIds, documents]);
28
+ return columns;
29
+ }
30
+ export {
31
+ useLabelColumns
32
+ };
33
+ //# sourceMappingURL=useLabelColumns.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/connection/presentation/useLabelColumns.ts"],
4
+ "sourcesContent": ["/**\n * Labelling clips with an annotation column: an Exhibit column's \"R-100\" leads the label of every\n * clip of that document (\"R-100 \u00B7 Statement of case \u00B7 p. 3\"), so a hearing bundle's numbering is on\n * the slide. The values are read live from the documents (editing one in Files updates the slides);\n * only the column's choice is saved with the presentation.\n */\n\nimport { useEffect, useMemo } from 'react'\nimport { useArbiSessionState, useDocuments, useTags } from '@arbidocs/react'\nimport { usePresentation } from '../../presentation/store'\n\n/** Column formats that hold one value per document (a checkbox only says yes or no). */\nconst VALUE_FORMATS = new Set(['text', 'number', 'select'])\n\nexport interface LabelColumn {\n id: string\n name: string\n}\n\n/**\n * The workspace's columns a clip can be labelled with, and (while the presentation is open) each\n * clip document's value in the chosen one, kept in the presentation store.\n */\nexport function useLabelColumns(active: boolean): LabelColumn[] {\n const workspaceId = useArbiSessionState((s) => s.workspaceId)\n const { data: tags } = useTags(workspaceId, { enabled: active })\n const { data: documents } = useDocuments(workspaceId, { enabled: active })\n const labelColumn = usePresentation((s) => s.labelColumn)\n const documentIds = usePresentation((s) => s.clips.map((clip) => clip.documentId).join(' '))\n\n const columns = useMemo(\n () =>\n (tags ?? [])\n .filter((tag) => tag.kind !== 'search' && VALUE_FORMATS.has(tag.tag_type.type))\n .map((tag) => ({ id: tag.external_id, name: tag.name }))\n .sort((a, b) => a.name.localeCompare(b.name)),\n [tags]\n )\n\n useEffect(() => {\n const values: Record<string, string> = {}\n if (labelColumn) {\n const wanted = new Set(documentIds.split(' '))\n for (const doc of documents ?? []) {\n if (!wanted.has(doc.external_id)) continue\n const note = doc.doctags?.find((dt) => dt.tag_ext_id === labelColumn)?.note?.trim()\n if (note) values[doc.external_id] = note\n }\n }\n usePresentation.getState().setColumnValues(values)\n }, [labelColumn, documentIds, documents])\n\n return columns\n}\n"],
5
+ "mappings": ";AAOA,SAAS,WAAW,eAAe;AACnC,SAAS,qBAAqB,cAAc,eAAe;AAC3D,SAAS,uBAAuB;AAGhC,MAAM,gBAAgB,oBAAI,IAAI,CAAC,QAAQ,UAAU,QAAQ,CAAC;AAWnD,SAAS,gBAAgB,QAAgC;AAC9D,QAAM,cAAc,oBAAoB,CAAC,MAAM,EAAE,WAAW;AAC5D,QAAM,EAAE,MAAM,KAAK,IAAI,QAAQ,aAAa,EAAE,SAAS,OAAO,CAAC;AAC/D,QAAM,EAAE,MAAM,UAAU,IAAI,aAAa,aAAa,EAAE,SAAS,OAAO,CAAC;AACzE,QAAM,cAAc,gBAAgB,CAAC,MAAM,EAAE,WAAW;AACxD,QAAM,cAAc,gBAAgB,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,SAAS,KAAK,UAAU,EAAE,KAAK,GAAG,CAAC;AAE3F,QAAM,UAAU;AAAA,IACd,OACG,QAAQ,CAAC,GACP,OAAO,CAAC,QAAQ,IAAI,SAAS,YAAY,cAAc,IAAI,IAAI,SAAS,IAAI,CAAC,EAC7E,IAAI,CAAC,SAAS,EAAE,IAAI,IAAI,aAAa,MAAM,IAAI,KAAK,EAAE,EACtD,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAAA,IAChD,CAAC,IAAI;AAAA,EACP;AAEA,YAAU,MAAM;AACd,UAAM,SAAiC,CAAC;AACxC,QAAI,aAAa;AACf,YAAM,SAAS,IAAI,IAAI,YAAY,MAAM,GAAG,CAAC;AAC7C,iBAAW,OAAO,aAAa,CAAC,GAAG;AACjC,YAAI,CAAC,OAAO,IAAI,IAAI,WAAW,EAAG;AAClC,cAAM,OAAO,IAAI,SAAS,KAAK,CAAC,OAAO,GAAG,eAAe,WAAW,GAAG,MAAM,KAAK;AAClF,YAAI,KAAM,QAAO,IAAI,WAAW,IAAI;AAAA,MACtC;AAAA,IACF;AACA,oBAAgB,SAAS,EAAE,gBAAgB,MAAM;AAAA,EACnD,GAAG,CAAC,aAAa,aAAa,SAAS,CAAC;AAExC,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * What the presentation editor gets from the session, wherever it is mounted (the viewer's slides
3
+ * tab, or the presentation's own window): Save, the "…" menu (Open, New from template, Save as,
4
+ * Save as template, Export PowerPoint, Export PDF, label column), Generate image, crop and the logo
5
+ * picker, and the dialogs they open (rendered by the host, in its own window).
6
+ */
7
+ import { type ReactNode } from 'react';
8
+ import type { SlidesEditorProps } from '../../presentation/SlidesEditor';
9
+ export interface PresentationController {
10
+ /** The editor's session parts (the host adds its own actions and Present). */
11
+ editor: Omit<SlidesEditorProps, 'onPresent'>;
12
+ /** The dialogs, for the host to render in its window. */
13
+ dialogs: ReactNode;
14
+ }
15
+ export declare function usePresentationController(active: boolean): PresentationController;
@@ -0,0 +1,118 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { useCallback, useState } from "react";
4
+ import { Save } from "lucide-react";
5
+ import { useArbiSessionStore } from "@arbidocs/react";
6
+ import { Button, DropdownMenuItem } from "@arbidocs/react/ui";
7
+ import { usePresentation } from "../../presentation/store.js";
8
+ import {
9
+ ChooseLogoDialog,
10
+ GenerateImageDialog,
11
+ OpenPresentationDialog,
12
+ SavePresentationDialog
13
+ } from "./PresentationDialogs.js";
14
+ import { CropClipDialog } from "./CropClipDialog.js";
15
+ import { LabelColumnMenu } from "./LabelColumnMenu.js";
16
+ import { GenerateTile } from "./GenerateTile.js";
17
+ import { editPresentation } from "./requests.js";
18
+ import { useLabelColumns } from "./useLabelColumns.js";
19
+ import { usePresentationFiles } from "./usePresentationFiles.js";
20
+ function usePresentationController(active) {
21
+ const session = useArbiSessionStore();
22
+ const notify = usePresentation((s) => s.notify);
23
+ const { save, canSave } = usePresentationFiles();
24
+ const labelColumns = useLabelColumns(active);
25
+ const [dialog, setDialog] = useState(null);
26
+ const [reference, setReference] = useState(null);
27
+ const [cropping, setCropping] = useState(null);
28
+ const cropClip = usePresentation((s) => s.clips.find((c) => c.id === cropping) ?? null);
29
+ const [saving, setSaving] = useState(false);
30
+ const close = (open) => !open && setDialog(null);
31
+ const quickSave = useCallback(async () => {
32
+ const { savedId, title } = usePresentation.getState();
33
+ if (!savedId) return setDialog("save");
34
+ setSaving(true);
35
+ try {
36
+ await save(title);
37
+ notify("Presentation saved", "success");
38
+ } catch (error) {
39
+ notify(
40
+ error instanceof Error ? error.message : "The presentation could not be saved",
41
+ "error"
42
+ );
43
+ } finally {
44
+ setSaving(false);
45
+ }
46
+ }, [save, notify]);
47
+ const generate = useCallback((referenceId) => {
48
+ setReference(referenceId);
49
+ setDialog("generate");
50
+ }, []);
51
+ const saveModes = ["save", "saveAs", "export", "template"];
52
+ const dialogs = /* @__PURE__ */ jsxs(Fragment, { children: [
53
+ /* @__PURE__ */ jsx(
54
+ SavePresentationDialog,
55
+ {
56
+ open: saveModes.includes(dialog),
57
+ mode: saveModes.includes(dialog) ? dialog : "save",
58
+ onOpenChange: close
59
+ }
60
+ ),
61
+ /* @__PURE__ */ jsx(
62
+ OpenPresentationDialog,
63
+ {
64
+ open: dialog === "open" || dialog === "fromTemplate",
65
+ templates: dialog === "fromTemplate",
66
+ onOpened: (id) => editPresentation(session, id ? { kind: "open", documentId: id } : { kind: "new" }),
67
+ onOpenChange: close
68
+ }
69
+ ),
70
+ /* @__PURE__ */ jsx(ChooseLogoDialog, { open: dialog === "logo", onOpenChange: close }),
71
+ /* @__PURE__ */ jsx(CropClipDialog, { clip: cropClip, onOpenChange: (open) => !open && setCropping(null) }),
72
+ /* @__PURE__ */ jsx(
73
+ GenerateImageDialog,
74
+ {
75
+ open: dialog === "generate",
76
+ referenceId: reference,
77
+ onOpenChange: close
78
+ }
79
+ )
80
+ ] });
81
+ const editor = {
82
+ actions: canSave && /* @__PURE__ */ jsx(
83
+ Button,
84
+ {
85
+ type: "button",
86
+ size: "icon",
87
+ variant: "ghost",
88
+ className: "size-8 text-muted-foreground hover:text-foreground pointer-coarse:size-11",
89
+ title: "Save (in Files \u203A Presentations)",
90
+ "aria-label": "Save",
91
+ disabled: saving,
92
+ onClick: () => void quickSave(),
93
+ "data-testid": "presentation-save",
94
+ children: /* @__PURE__ */ jsx(Save, { className: "size-4" })
95
+ }
96
+ ),
97
+ menuItems: canSave && /* @__PURE__ */ jsxs(Fragment, { children: [
98
+ /* @__PURE__ */ jsx(DropdownMenuItem, { onSelect: () => setDialog("open"), children: "Open\u2026" }),
99
+ /* @__PURE__ */ jsx(DropdownMenuItem, { onSelect: () => setDialog("fromTemplate"), children: "New from template\u2026" }),
100
+ /* @__PURE__ */ jsx(DropdownMenuItem, { onSelect: () => setDialog("saveAs"), children: "Save as\u2026" }),
101
+ /* @__PURE__ */ jsx(DropdownMenuItem, { onSelect: () => setDialog("template"), children: "Save as template\u2026" }),
102
+ /* @__PURE__ */ jsx(DropdownMenuItem, { onSelect: () => setDialog("export"), children: "Export PDF\u2026" }),
103
+ /* @__PURE__ */ jsx(LabelColumnMenu, { columns: labelColumns })
104
+ ] }),
105
+ trayStart: canSave && /* @__PURE__ */ jsx(GenerateTile, { onClick: () => generate(null) }),
106
+ onChooseLogo: canSave ? () => setDialog("logo") : void 0,
107
+ onEditImage: (clipId) => {
108
+ const clip = usePresentation.getState().clips.find((c) => c.id === clipId);
109
+ if (clip) generate(clip.documentId);
110
+ },
111
+ onCropImage: setCropping
112
+ };
113
+ return { editor, dialogs };
114
+ }
115
+ export {
116
+ usePresentationController
117
+ };
118
+ //# sourceMappingURL=usePresentationController.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/connection/presentation/usePresentationController.tsx"],
4
+ "sourcesContent": ["/**\n * What the presentation editor gets from the session, wherever it is mounted (the viewer's slides\n * tab, or the presentation's own window): Save, the \"\u2026\" menu (Open, New from template, Save as,\n * Save as template, Export PowerPoint, Export PDF, label column), Generate image, crop and the logo\n * picker, and the dialogs they open (rendered by the host, in its own window).\n */\n\nimport { useCallback, useState, type ReactNode } from 'react'\nimport { Save } from 'lucide-react'\nimport { useArbiSessionStore } from '@arbidocs/react'\nimport { Button, DropdownMenuItem } from '@arbidocs/react/ui'\nimport type { SlidesEditorProps } from '../../presentation/SlidesEditor'\nimport { usePresentation } from '../../presentation/store'\nimport {\n ChooseLogoDialog,\n GenerateImageDialog,\n OpenPresentationDialog,\n SavePresentationDialog,\n type SaveMode,\n} from './PresentationDialogs'\nimport { CropClipDialog } from './CropClipDialog'\nimport { LabelColumnMenu } from './LabelColumnMenu'\nimport { GenerateTile } from './GenerateTile'\nimport { editPresentation } from './requests'\nimport { useLabelColumns } from './useLabelColumns'\nimport { usePresentationFiles } from './usePresentationFiles'\n\ntype Dialog = SaveMode | 'open' | 'fromTemplate' | 'generate' | 'logo'\n\nexport interface PresentationController {\n /** The editor's session parts (the host adds its own actions and Present). */\n editor: Omit<SlidesEditorProps, 'onPresent'>\n /** The dialogs, for the host to render in its window. */\n dialogs: ReactNode\n}\n\nexport function usePresentationController(active: boolean): PresentationController {\n const session = useArbiSessionStore()\n const notify = usePresentation((s) => s.notify)\n const { save, canSave } = usePresentationFiles()\n const labelColumns = useLabelColumns(active)\n const [dialog, setDialog] = useState<Dialog | null>(null)\n const [reference, setReference] = useState<string | null>(null)\n const [cropping, setCropping] = useState<string | null>(null)\n const cropClip = usePresentation((s) => s.clips.find((c) => c.id === cropping) ?? null)\n const [saving, setSaving] = useState(false)\n const close = (open: boolean) => !open && setDialog(null)\n\n // Saved before: save again (a new version) at once; never saved: ask for a title.\n const quickSave = useCallback(async () => {\n const { savedId, title } = usePresentation.getState()\n if (!savedId) return setDialog('save')\n setSaving(true)\n try {\n await save(title)\n notify('Presentation saved', 'success')\n } catch (error) {\n notify(\n error instanceof Error ? error.message : 'The presentation could not be saved',\n 'error'\n )\n } finally {\n setSaving(false)\n }\n }, [save, notify])\n\n const generate = useCallback((referenceId: string | null) => {\n setReference(referenceId)\n setDialog('generate')\n }, [])\n\n const saveModes: SaveMode[] = ['save', 'saveAs', 'export', 'template']\n const dialogs = (\n <>\n <SavePresentationDialog\n open={saveModes.includes(dialog as SaveMode)}\n mode={saveModes.includes(dialog as SaveMode) ? (dialog as SaveMode) : 'save'}\n onOpenChange={close}\n />\n <OpenPresentationDialog\n open={dialog === 'open' || dialog === 'fromTemplate'}\n templates={dialog === 'fromTemplate'}\n // A saved one opens in the viewer's slides tab (its document); a template, as a new one.\n onOpened={(id) =>\n editPresentation(session, id ? { kind: 'open', documentId: id } : { kind: 'new' })\n }\n onOpenChange={close}\n />\n <ChooseLogoDialog open={dialog === 'logo'} onOpenChange={close} />\n <CropClipDialog clip={cropClip} onOpenChange={(open) => !open && setCropping(null)} />\n <GenerateImageDialog\n open={dialog === 'generate'}\n referenceId={reference}\n onOpenChange={close}\n />\n </>\n )\n\n const editor: PresentationController['editor'] = {\n actions: canSave && (\n <Button\n type=\"button\"\n size=\"icon\"\n variant=\"ghost\"\n className=\"size-8 text-muted-foreground hover:text-foreground pointer-coarse:size-11\"\n title=\"Save (in Files \u203A Presentations)\"\n aria-label=\"Save\"\n disabled={saving}\n onClick={() => void quickSave()}\n data-testid=\"presentation-save\"\n >\n <Save className=\"size-4\" />\n </Button>\n ),\n menuItems: canSave && (\n <>\n <DropdownMenuItem onSelect={() => setDialog('open')}>Open\u2026</DropdownMenuItem>\n <DropdownMenuItem onSelect={() => setDialog('fromTemplate')}>\n New from template\u2026\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={() => setDialog('saveAs')}>Save as\u2026</DropdownMenuItem>\n <DropdownMenuItem onSelect={() => setDialog('template')}>\n Save as template\u2026\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={() => setDialog('export')}>Export PDF\u2026</DropdownMenuItem>\n <LabelColumnMenu columns={labelColumns} />\n </>\n ),\n trayStart: canSave && <GenerateTile onClick={() => generate(null)} />,\n onChooseLogo: canSave ? () => setDialog('logo') : undefined,\n onEditImage: (clipId) => {\n const clip = usePresentation.getState().clips.find((c) => c.id === clipId)\n if (clip) generate(clip.documentId)\n },\n onCropImage: setCropping,\n }\n return { editor, dialogs }\n}\n"],
5
+ "mappings": ";AAyEI,mBACE,KADF;AAlEJ,SAAS,aAAa,gBAAgC;AACtD,SAAS,YAAY;AACrB,SAAS,2BAA2B;AACpC,SAAS,QAAQ,wBAAwB;AAEzC,SAAS,uBAAuB;AAChC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,sBAAsB;AAC/B,SAAS,uBAAuB;AAChC,SAAS,oBAAoB;AAC7B,SAAS,wBAAwB;AACjC,SAAS,uBAAuB;AAChC,SAAS,4BAA4B;AAW9B,SAAS,0BAA0B,QAAyC;AACjF,QAAM,UAAU,oBAAoB;AACpC,QAAM,SAAS,gBAAgB,CAAC,MAAM,EAAE,MAAM;AAC9C,QAAM,EAAE,MAAM,QAAQ,IAAI,qBAAqB;AAC/C,QAAM,eAAe,gBAAgB,MAAM;AAC3C,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAwB,IAAI;AACxD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAwB,IAAI;AAC9D,QAAM,CAAC,UAAU,WAAW,IAAI,SAAwB,IAAI;AAC5D,QAAM,WAAW,gBAAgB,CAAC,MAAM,EAAE,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ,KAAK,IAAI;AACtF,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAC1C,QAAM,QAAQ,CAAC,SAAkB,CAAC,QAAQ,UAAU,IAAI;AAGxD,QAAM,YAAY,YAAY,YAAY;AACxC,UAAM,EAAE,SAAS,MAAM,IAAI,gBAAgB,SAAS;AACpD,QAAI,CAAC,QAAS,QAAO,UAAU,MAAM;AACrC,cAAU,IAAI;AACd,QAAI;AACF,YAAM,KAAK,KAAK;AAChB,aAAO,sBAAsB,SAAS;AAAA,IACxC,SAAS,OAAO;AACd;AAAA,QACE,iBAAiB,QAAQ,MAAM,UAAU;AAAA,QACzC;AAAA,MACF;AAAA,IACF,UAAE;AACA,gBAAU,KAAK;AAAA,IACjB;AAAA,EACF,GAAG,CAAC,MAAM,MAAM,CAAC;AAEjB,QAAM,WAAW,YAAY,CAAC,gBAA+B;AAC3D,iBAAa,WAAW;AACxB,cAAU,UAAU;AAAA,EACtB,GAAG,CAAC,CAAC;AAEL,QAAM,YAAwB,CAAC,QAAQ,UAAU,UAAU,UAAU;AACrE,QAAM,UACJ,iCACE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,UAAU,SAAS,MAAkB;AAAA,QAC3C,MAAM,UAAU,SAAS,MAAkB,IAAK,SAAsB;AAAA,QACtE,cAAc;AAAA;AAAA,IAChB;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,WAAW,UAAU,WAAW;AAAA,QACtC,WAAW,WAAW;AAAA,QAEtB,UAAU,CAAC,OACT,iBAAiB,SAAS,KAAK,EAAE,MAAM,QAAQ,YAAY,GAAG,IAAI,EAAE,MAAM,MAAM,CAAC;AAAA,QAEnF,cAAc;AAAA;AAAA,IAChB;AAAA,IACA,oBAAC,oBAAiB,MAAM,WAAW,QAAQ,cAAc,OAAO;AAAA,IAChE,oBAAC,kBAAe,MAAM,UAAU,cAAc,CAAC,SAAS,CAAC,QAAQ,YAAY,IAAI,GAAG;AAAA,IACpF;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,WAAW;AAAA,QACjB,aAAa;AAAA,QACb,cAAc;AAAA;AAAA,IAChB;AAAA,KACF;AAGF,QAAM,SAA2C;AAAA,IAC/C,SAAS,WACP;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,MAAK;AAAA,QACL,SAAQ;AAAA,QACR,WAAU;AAAA,QACV,OAAM;AAAA,QACN,cAAW;AAAA,QACX,UAAU;AAAA,QACV,SAAS,MAAM,KAAK,UAAU;AAAA,QAC9B,eAAY;AAAA,QAEZ,8BAAC,QAAK,WAAU,UAAS;AAAA;AAAA,IAC3B;AAAA,IAEF,WAAW,WACT,iCACE;AAAA,0BAAC,oBAAiB,UAAU,MAAM,UAAU,MAAM,GAAG,wBAAK;AAAA,MAC1D,oBAAC,oBAAiB,UAAU,MAAM,UAAU,cAAc,GAAG,qCAE7D;AAAA,MACA,oBAAC,oBAAiB,UAAU,MAAM,UAAU,QAAQ,GAAG,2BAAQ;AAAA,MAC/D,oBAAC,oBAAiB,UAAU,MAAM,UAAU,UAAU,GAAG,oCAEzD;AAAA,MACA,oBAAC,oBAAiB,UAAU,MAAM,UAAU,QAAQ,GAAG,8BAAW;AAAA,MAClE,oBAAC,mBAAgB,SAAS,cAAc;AAAA,OAC1C;AAAA,IAEF,WAAW,WAAW,oBAAC,gBAAa,SAAS,MAAM,SAAS,IAAI,GAAG;AAAA,IACnE,cAAc,UAAU,MAAM,UAAU,MAAM,IAAI;AAAA,IAClD,aAAa,CAAC,WAAW;AACvB,YAAM,OAAO,gBAAgB,SAAS,EAAE,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM;AACzE,UAAI,KAAM,UAAS,KAAK,UAAU;AAAA,IACpC;AAAA,IACA,aAAa;AAAA,EACf;AACA,SAAO,EAAE,QAAQ,QAAQ;AAC3B;",
6
+ "names": []
7
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Saving and opening presentations as documents of the open workspace's `Presentations` folder:
3
+ * a PowerPoint file (`<title>.pptx`: its slides as editable PowerPoint, the presentation's own data
4
+ * inside it, `pptx-data`). Saving again adds a version to the same document; Export PDF saves a
5
+ * PDF of the slides.
6
+ *
7
+ * Opening fetches each clip's source again: the PDF the viewer shows for a page clip (so Word and
8
+ * text documents work too), the original file for an image or a video. A page clip's redactions
9
+ * are read again from the markup; a clip whose source or redactions cannot be read is left out
10
+ * (never shown unredacted), and how many were is reported.
11
+ *
12
+ * Presentations saved before they were PowerPoint files (a PDF with the data attached, or the data
13
+ * alone) still open; their first save makes a PowerPoint file of them.
14
+ */
15
+ /** What opening a presentation found besides its content. */
16
+ export interface OpenedPresentation {
17
+ /** Clips whose source could not be opened (left out). */
18
+ missing: number;
19
+ /** Changed outside the editor (an agent): the slides are drawn again on the next save. */
20
+ stale: boolean;
21
+ /** A PowerPoint made elsewhere, imported: what did not come across as it was. */
22
+ imported?: {
23
+ notes: string[];
24
+ };
25
+ /** Slides (1-based) changed in PowerPoint since the editor saved it, brought in. */
26
+ changedOutside?: number[];
27
+ }
28
+ export interface SavedPresentationEntry {
29
+ id: string;
30
+ title: string;
31
+ updatedAt: string | null;
32
+ }
33
+ export declare function usePresentationFiles(): {
34
+ save: (title: string, { asNew, template }?: {
35
+ asNew?: boolean;
36
+ template?: boolean;
37
+ }) => Promise<string>;
38
+ exportPdf: (title: string) => Promise<string>;
39
+ list: (scope?: "presentations" | "templates") => Promise<SavedPresentationEntry[]>;
40
+ open: (id: string, version?: number) => Promise<OpenedPresentation>;
41
+ startFromTemplate: (id: string) => Promise<void>;
42
+ downloadFile: (id: string) => Promise<Blob>;
43
+ canSave: boolean;
44
+ };
@@ -0,0 +1,307 @@
1
+ "use client";
2
+ import { useCallback } from "react";
3
+ import { useArbi, useArbiSessionState } from "@arbidocs/react";
4
+ import { isPresentationFileName } from "@arbidocs/react/ui";
5
+ import {
6
+ createMarkupStore,
7
+ fetchDocumentPdf,
8
+ imagesToPdf,
9
+ MarkupStoreError,
10
+ readPdfAttachment,
11
+ useDocumentTools
12
+ } from "@arbidocs/react/document-tools";
13
+ import {
14
+ EXPORTS_FOLDER,
15
+ PRESENTATIONS_FOLDER,
16
+ PRESENTATION_ATTACHMENT,
17
+ TEMPLATES_FOLDER,
18
+ parsePresentation,
19
+ presentationFileName,
20
+ presentationTitle,
21
+ safeFileStem,
22
+ serializePresentation
23
+ } from "../../presentation/persistence.js";
24
+ import { usePresentation } from "../../presentation/store.js";
25
+ import { renderSlide } from "../../presentation/render-slides.js";
26
+ import { buildPptx } from "../../presentation/export-pptx.js";
27
+ import {
28
+ isZipBytes,
29
+ readPptxPresentationData,
30
+ writePptxPresentationData
31
+ } from "../../presentation/pptx-data.js";
32
+ import { importPptx, slideFingerprints } from "../../presentation/import-pptx.js";
33
+ import { mergeOutsideEdits } from "../../presentation/merge-outside-edits.js";
34
+ const PPTX_TYPE = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
35
+ const SLIDE_PAGE = { width: 1280, height: 720 };
36
+ function dataUrlBlob(url) {
37
+ const [head, body] = url.split(",", 2);
38
+ const type = /^data:([^;]+)/.exec(head)?.[1] ?? "application/octet-stream";
39
+ const binary = atob(body ?? "");
40
+ const bytes = new Uint8Array(binary.length);
41
+ for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
42
+ return new Blob([bytes], { type });
43
+ }
44
+ async function presentationData(bytes) {
45
+ if (isZipBytes(bytes)) return readPptxPresentationData(bytes);
46
+ const isPdf = bytes[0] === 37 && bytes[1] === 80 && bytes[2] === 68 && bytes[3] === 70;
47
+ if (!isPdf) return new TextDecoder().decode(bytes);
48
+ const data = await readPdfAttachment(bytes, PRESENTATION_ATTACHMENT);
49
+ if (!data) {
50
+ throw new Error(
51
+ "This PDF has no editable presentation in it (it may have been changed outside ARBI)."
52
+ );
53
+ }
54
+ return new TextDecoder().decode(data);
55
+ }
56
+ function current(withoutClips) {
57
+ const state = usePresentation.getState();
58
+ return withoutClips ? {
59
+ ...state,
60
+ clips: [],
61
+ slides: state.slides.map((slide) => ({ ...slide, items: [] }))
62
+ } : state;
63
+ }
64
+ const lookOf = (state) => ({
65
+ labels: state.captions,
66
+ columnValues: state.columnValues,
67
+ theme: state.theme,
68
+ logo: state.logoImage,
69
+ media: state.media
70
+ });
71
+ function usePresentationFiles() {
72
+ const arbi = useArbi();
73
+ const { client } = useDocumentTools();
74
+ const workspaceId = useArbiSessionState((s) => s.workspaceId);
75
+ const buildFile = useCallback(async (title, withoutClips) => {
76
+ const state = current(withoutClips);
77
+ const deck = await buildPptx({ title, slides: state.slides, clips: state.clips }, lookOf(state));
78
+ const fingerprints = await slideFingerprints(deck);
79
+ const data = serializePresentation({ ...state, title, fingerprints });
80
+ return writePptxPresentationData(deck, JSON.stringify(data, null, 2));
81
+ }, []);
82
+ const save = useCallback(
83
+ async (title, { asNew = false, template = false } = {}) => {
84
+ if (!arbi || !workspaceId) throw new Error("Open a workspace to save the presentation.");
85
+ const state = usePresentation.getState();
86
+ const versionOf = asNew || template ? null : state.savedId;
87
+ const deck = await buildFile(title, template);
88
+ const file = new File([deck], presentationFileName(title), { type: PPTX_TYPE });
89
+ const result = await arbi.documents.upload([file], {
90
+ folder: template ? TEMPLATES_FOLDER : PRESENTATIONS_FOLDER,
91
+ workspaceExtId: workspaceId,
92
+ ...versionOf ? { versionOf } : {}
93
+ });
94
+ const id = versionOf ?? result.doc_ext_ids?.[0];
95
+ if (!id) throw new Error("The presentation could not be saved.");
96
+ if (!template) {
97
+ const [doc] = await arbi.documents.get([id]).catch(() => []);
98
+ state.setSaved(id, title, doc?.current_version ?? null);
99
+ }
100
+ return id;
101
+ },
102
+ [arbi, workspaceId, buildFile]
103
+ );
104
+ const exportPdf = useCallback(
105
+ async (title) => {
106
+ if (!arbi || !workspaceId) throw new Error("Open a workspace to export the PDF.");
107
+ const state = current(false);
108
+ const pages = [];
109
+ for (const slide of state.slides) {
110
+ const { image, text } = await renderSlide(slide, state.clips, lookOf(state));
111
+ pages.push({ image, text, width: SLIDE_PAGE.width, height: SLIDE_PAGE.height });
112
+ }
113
+ const pdf = await imagesToPdf(pages, { title });
114
+ const result = await arbi.documents.upload(
115
+ [new File([pdf], `${safeFileStem(title)}.pdf`, { type: "application/pdf" })],
116
+ { folder: EXPORTS_FOLDER, workspaceExtId: workspaceId }
117
+ );
118
+ const id = result.doc_ext_ids?.[0];
119
+ if (!id) throw new Error("The PDF could not be saved.");
120
+ return id;
121
+ },
122
+ [arbi, workspaceId]
123
+ );
124
+ const list = useCallback(
125
+ async (scope = "presentations") => {
126
+ if (!arbi || !workspaceId) return [];
127
+ const docs = await arbi.documents.list({ workspaceId });
128
+ return docs.filter((doc) => {
129
+ const folder = doc.folder ?? "";
130
+ if (!isPresentationFileName(doc.file_name, folder)) return false;
131
+ return scope === "templates" ? folder === TEMPLATES_FOLDER : folder.startsWith(PRESENTATIONS_FOLDER) && folder !== TEMPLATES_FOLDER && !folder.startsWith(EXPORTS_FOLDER);
132
+ }).map((doc) => ({
133
+ id: doc.external_id,
134
+ title: presentationTitle(doc.file_name ?? ""),
135
+ updatedAt: doc.updated_at ?? doc.created_at ?? null
136
+ })).sort((a, b) => (a.updatedAt ?? "") < (b.updatedAt ?? "") ? 1 : -1);
137
+ },
138
+ [arbi, workspaceId]
139
+ );
140
+ const readSaved = useCallback(
141
+ async (id, version) => {
142
+ if (!arbi) throw new Error("Sign in to open a presentation.");
143
+ const response = await arbi.documents.download(id, version);
144
+ const bytes = new Uint8Array(await response.arrayBuffer());
145
+ const text = await presentationData(bytes);
146
+ const [doc] = await arbi.documents.get([id]).catch(() => []);
147
+ const openedVersion = version ?? doc?.current_version ?? null;
148
+ if (text === null) {
149
+ const imported = await importPptx(bytes, {
150
+ title: presentationTitle(doc?.file_name ?? "Presentation.pptx"),
151
+ documentId: id,
152
+ version: version ?? doc?.current_version,
153
+ fileName: doc?.file_name ?? void 0
154
+ });
155
+ return {
156
+ saved: imported.saved,
157
+ legacy: false,
158
+ imported: { notes: imported.notes },
159
+ openedVersion
160
+ };
161
+ }
162
+ let saved = parsePresentation(text);
163
+ let changedOutside;
164
+ if (isZipBytes(bytes) && saved.slides.some((slide) => slide.fingerprint)) {
165
+ const now = await slideFingerprints(bytes);
166
+ const unchanged = now.length === saved.slides.length && now.every((fingerprint, i) => fingerprint === saved.slides[i].fingerprint);
167
+ if (!unchanged) {
168
+ const imported = await importPptx(bytes, {
169
+ title: saved.title,
170
+ documentId: id,
171
+ version: version ?? doc?.current_version,
172
+ fileName: doc?.file_name ?? void 0
173
+ });
174
+ const merged = mergeOutsideEdits(saved, imported.saved, now);
175
+ saved = merged.saved;
176
+ changedOutside = merged.changed;
177
+ }
178
+ }
179
+ return {
180
+ saved,
181
+ // Saved before presentations were PowerPoint files: its next save is a new PowerPoint
182
+ // file, not a version of this one (a document's versions keep one format).
183
+ legacy: !isZipBytes(bytes),
184
+ changedOutside,
185
+ openedVersion
186
+ };
187
+ },
188
+ [arbi]
189
+ );
190
+ const startFromTemplate = useCallback(
191
+ async (id) => {
192
+ const { saved } = await readSaved(id);
193
+ usePresentation.getState().load({
194
+ title: "Untitled presentation",
195
+ savedId: null,
196
+ captions: saved.captions,
197
+ labelColumn: saved.labelColumn ?? null,
198
+ theme: saved.theme,
199
+ clips: [],
200
+ slides: saved.slides.map((slide) => ({ ...slide, items: [] })),
201
+ media: saved.media
202
+ });
203
+ },
204
+ [readSaved]
205
+ );
206
+ const downloadFile = useCallback(
207
+ async (id) => {
208
+ if (!arbi) throw new Error("Sign in to read the file.");
209
+ return (await arbi.documents.download(id)).blob();
210
+ },
211
+ [arbi]
212
+ );
213
+ const open = useCallback(
214
+ async (id, version) => {
215
+ if (!arbi) throw new Error("Sign in to open a presentation.");
216
+ const { saved, legacy, imported, changedOutside, openedVersion } = await readSaved(
217
+ id,
218
+ version
219
+ );
220
+ const media = saved.media ?? {};
221
+ const sources = /* @__PURE__ */ new Map();
222
+ const sourceOf = (clip) => {
223
+ if (clip.media) {
224
+ const url = media[clip.media];
225
+ return url ? Promise.resolve(dataUrlBlob(url)) : Promise.reject(new Error("No image"));
226
+ }
227
+ const key = `${clip.kind === "pdf" ? "pdf" : "file"}:${clip.documentId}@${clip.version ?? ""}`;
228
+ let pending = sources.get(key);
229
+ if (!pending) {
230
+ pending = clip.kind === "pdf" ? fetchDocumentPdf(client, clip.documentId, { version: clip.version ?? null }) : arbi.documents.download(clip.documentId, clip.version).then((r) => r.blob());
231
+ sources.set(key, pending);
232
+ }
233
+ return pending;
234
+ };
235
+ const markups = /* @__PURE__ */ new Map();
236
+ const masksOf = (clip) => {
237
+ const key = `${clip.documentId}@${clip.version ?? ""}`;
238
+ let pending = markups.get(key);
239
+ if (!pending) {
240
+ pending = createMarkupStore({ version: clip.version, client }).load(clip.documentId).then((layer) => {
241
+ const byPage = /* @__PURE__ */ new Map();
242
+ for (const mark of layer.annotations) {
243
+ if (mark.kind !== "redaction" || mark.status === "rejected") continue;
244
+ byPage.set(mark.page, [...byPage.get(mark.page) ?? [], ...mark.rects]);
245
+ }
246
+ return byPage;
247
+ }).catch((error) => {
248
+ if (error instanceof MarkupStoreError && error.status === 404) return /* @__PURE__ */ new Map();
249
+ throw error;
250
+ });
251
+ markups.set(key, pending);
252
+ }
253
+ return pending;
254
+ };
255
+ const opened = await Promise.all(
256
+ saved.clips.map(async (clip) => {
257
+ try {
258
+ const [source, masks] = await Promise.all([
259
+ sourceOf(clip),
260
+ clip.kind === "pdf" && !clip.media ? masksOf(clip) : Promise.resolve(/* @__PURE__ */ new Map())
261
+ ]);
262
+ return { ...clip, source, masks: masks.get(clip.page) ?? [] };
263
+ } catch {
264
+ return null;
265
+ }
266
+ })
267
+ );
268
+ const kept = [];
269
+ const newIndex = opened.map((clip) => clip ? kept.push(clip) - 1 : -1);
270
+ usePresentation.getState().load({
271
+ title: saved.title,
272
+ savedId: legacy ? null : id,
273
+ version: legacy ? null : openedVersion,
274
+ boundTo: id,
275
+ captions: saved.captions,
276
+ labelColumn: saved.labelColumn ?? null,
277
+ theme: saved.theme,
278
+ clips: kept,
279
+ slides: saved.slides.map((slide) => ({
280
+ ...slide,
281
+ items: slide.items.filter((item) => newIndex[item.clip] >= 0).map((item) => ({ ...item, clip: newIndex[item.clip] }))
282
+ })),
283
+ media
284
+ });
285
+ return {
286
+ missing: opened.length - kept.length,
287
+ stale: saved.slidesStale === true,
288
+ ...imported ? { imported } : {},
289
+ ...changedOutside?.length ? { changedOutside } : {}
290
+ };
291
+ },
292
+ [arbi, client, readSaved]
293
+ );
294
+ return {
295
+ save,
296
+ exportPdf,
297
+ list,
298
+ open,
299
+ startFromTemplate,
300
+ downloadFile,
301
+ canSave: !!arbi && !!workspaceId
302
+ };
303
+ }
304
+ export {
305
+ usePresentationFiles
306
+ };
307
+ //# sourceMappingURL=usePresentationFiles.js.map