@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.
- package/dist/ClippingMediaViewer-B6WG7Q64.cjs +156 -0
- package/dist/ClippingMediaViewer-B6WG7Q64.cjs.map +1 -0
- package/dist/ClippingPdfViewer-6GCVTV3V.cjs +79 -0
- package/dist/ClippingPdfViewer-6GCVTV3V.cjs.map +1 -0
- package/dist/{ConnectedCallDock-WER7R222.cjs → ConnectedCallDock-DC5V5OUJ.cjs} +25 -23
- package/dist/ConnectedCallDock-DC5V5OUJ.cjs.map +1 -0
- package/dist/{ConnectedCallRoom-T7OBQTYP.cjs → ConnectedCallRoom-FQLXWTFB.cjs} +18 -16
- package/dist/{ConnectedCallRoom-T7OBQTYP.cjs.map → ConnectedCallRoom-FQLXWTFB.cjs.map} +1 -1
- package/dist/{ConnectedNativeDocxComparison-SGE4R3M4.cjs → ConnectedNativeDocxComparison-4Q5S7VLD.cjs} +17 -17
- package/dist/{ConnectedNativeDocxComparison-SGE4R3M4.cjs.map → ConnectedNativeDocxComparison-4Q5S7VLD.cjs.map} +1 -1
- package/dist/ConnectedPresentation-4HLDZDWV.cjs +183 -0
- package/dist/ConnectedPresentation-4HLDZDWV.cjs.map +1 -0
- package/dist/{ConnectedProductionSetDialog-LHB4VQWC.cjs → ConnectedProductionSetDialog-4EAY6KAZ.cjs} +3 -3
- package/dist/{ConnectedProductionSetDialog-LHB4VQWC.cjs.map → ConnectedProductionSetDialog-4EAY6KAZ.cjs.map} +1 -1
- package/dist/ConnectedSlidesTab-7QDE2CZD.cjs +234 -0
- package/dist/ConnectedSlidesTab-7QDE2CZD.cjs.map +1 -0
- package/dist/{ConnectedStreamedWordArtifact-6MCLJRIT.cjs → ConnectedStreamedWordArtifact-FFOQJBOI.cjs} +17 -17
- package/dist/{ConnectedStreamedWordArtifact-6MCLJRIT.cjs.map → ConnectedStreamedWordArtifact-FFOQJBOI.cjs.map} +1 -1
- package/dist/{DocumentReviewCard-BPIAJJED.cjs → DocumentReviewCard-SNWVEZ7S.cjs} +17 -16
- package/dist/DocumentReviewCard-SNWVEZ7S.cjs.map +1 -0
- package/dist/{FilesViewerDialog-67WK3TZC.cjs → FilesViewerDialog-IZI63FOV.cjs} +52 -45
- package/dist/FilesViewerDialog-IZI63FOV.cjs.map +1 -0
- package/dist/{GridViewImpl-ZMJJWTOM.cjs → GridViewImpl-LTYET77Q.cjs} +3 -3
- package/dist/GridViewImpl-LTYET77Q.cjs.map +1 -0
- package/dist/{WorkspaceTableView-J3C6VH4T.cjs → WorkspaceTableView-TEIRB6VJ.cjs} +11 -10
- package/dist/WorkspaceTableView-TEIRB6VJ.cjs.map +1 -0
- package/dist/agents/index.cjs +297 -297
- package/dist/{ai-IM4A23YT.cjs → ai-KBYNRNZ6.cjs} +28 -26
- package/dist/ai-KBYNRNZ6.cjs.map +1 -0
- package/dist/calls/connected/CallControls.d.ts +2 -0
- package/dist/calls/connected/CallControls.js +71 -9
- package/dist/calls/connected/CallControls.js.map +2 -2
- package/dist/calls/connected/ShareDocumentDialog.d.ts +14 -0
- package/dist/calls/connected/ShareDocumentDialog.js +77 -0
- package/dist/calls/connected/ShareDocumentDialog.js.map +7 -0
- package/dist/calls/index.cjs +121 -121
- package/dist/chat/index.cjs +9 -8
- package/dist/{chunk-T23UTIRI.cjs → chunk-2PZT3J34.cjs} +6 -6
- package/dist/{chunk-T23UTIRI.cjs.map → chunk-2PZT3J34.cjs.map} +1 -1
- package/dist/{chunk-SGYSDABK.cjs → chunk-2W5E62EY.cjs} +6 -6
- package/dist/{chunk-SGYSDABK.cjs.map → chunk-2W5E62EY.cjs.map} +1 -1
- package/dist/{chunk-TDO5UWXF.cjs → chunk-3SCNXNHI.cjs} +5 -5
- package/dist/{chunk-TDO5UWXF.cjs.map → chunk-3SCNXNHI.cjs.map} +1 -1
- package/dist/{chunk-KTQOGT2L.cjs → chunk-474GPLCM.cjs} +7 -7
- package/dist/{chunk-KTQOGT2L.cjs.map → chunk-474GPLCM.cjs.map} +1 -1
- package/dist/{chunk-TP5PGWIO.cjs → chunk-4IOYQLKG.cjs} +3 -3
- package/dist/{chunk-TP5PGWIO.cjs.map → chunk-4IOYQLKG.cjs.map} +1 -1
- package/dist/{chunk-NY3YUCOW.cjs → chunk-4NPCDS2X.cjs} +3 -3
- package/dist/{chunk-NY3YUCOW.cjs.map → chunk-4NPCDS2X.cjs.map} +1 -1
- package/dist/{chunk-HA66DHW6.cjs → chunk-4RBQ44RY.cjs} +28 -28
- package/dist/chunk-4RBQ44RY.cjs.map +1 -0
- package/dist/{chunk-BQ5RIWWT.cjs → chunk-4VZZWYEC.cjs} +3 -3
- package/dist/{chunk-BQ5RIWWT.cjs.map → chunk-4VZZWYEC.cjs.map} +1 -1
- package/dist/{chunk-BP3IJ34D.cjs → chunk-52KGMAO5.cjs} +15 -15
- package/dist/{chunk-BP3IJ34D.cjs.map → chunk-52KGMAO5.cjs.map} +1 -1
- package/dist/{chunk-5IZFSAEZ.cjs → chunk-5534FYXP.cjs} +4 -4
- package/dist/{chunk-5IZFSAEZ.cjs.map → chunk-5534FYXP.cjs.map} +1 -1
- package/dist/chunk-5GCCUXMT.cjs +63 -0
- package/dist/chunk-5GCCUXMT.cjs.map +1 -0
- package/dist/chunk-5LTIZ44D.cjs +95 -0
- package/dist/chunk-5LTIZ44D.cjs.map +1 -0
- package/dist/{chunk-DFBDQKGE.cjs → chunk-734NPQNR.cjs} +4 -4
- package/dist/{chunk-DFBDQKGE.cjs.map → chunk-734NPQNR.cjs.map} +1 -1
- package/dist/{chunk-X36UR4A7.cjs → chunk-7VUJGHMY.cjs} +323 -96
- package/dist/chunk-7VUJGHMY.cjs.map +1 -0
- package/dist/chunk-AFQTQC7A.cjs +35 -0
- package/dist/chunk-AFQTQC7A.cjs.map +1 -0
- package/dist/{chunk-YYSBWMDJ.cjs → chunk-AY6EZSZB.cjs} +4 -4
- package/dist/{chunk-YYSBWMDJ.cjs.map → chunk-AY6EZSZB.cjs.map} +1 -1
- package/dist/{chunk-BUVIBHFU.cjs → chunk-BVAT4EVC.cjs} +38 -38
- package/dist/chunk-BVAT4EVC.cjs.map +1 -0
- package/dist/{chunk-ECLUFKYR.cjs → chunk-C2OICDMI.cjs} +10 -10
- package/dist/{chunk-ECLUFKYR.cjs.map → chunk-C2OICDMI.cjs.map} +1 -1
- package/dist/{chunk-CPR6EHG7.cjs → chunk-DR2AH7JL.cjs} +179 -55
- package/dist/chunk-DR2AH7JL.cjs.map +1 -0
- package/dist/{chunk-NJCK6V6U.cjs → chunk-EATIFPKP.cjs} +4 -60
- package/dist/chunk-EATIFPKP.cjs.map +1 -0
- package/dist/{chunk-B3LZITVF.cjs → chunk-EHP6OH5D.cjs} +11 -451
- package/dist/chunk-EHP6OH5D.cjs.map +1 -0
- package/dist/{chunk-775S43W7.cjs → chunk-ENGL7P3I.cjs} +31 -31
- package/dist/{chunk-775S43W7.cjs.map → chunk-ENGL7P3I.cjs.map} +1 -1
- package/dist/{chunk-VZCPMXWC.cjs → chunk-FKFQCK3C.cjs} +4 -4
- package/dist/{chunk-VZCPMXWC.cjs.map → chunk-FKFQCK3C.cjs.map} +1 -1
- package/dist/{chunk-6UTKM5AB.cjs → chunk-GKVE5JGB.cjs} +76 -76
- package/dist/chunk-GKVE5JGB.cjs.map +1 -0
- package/dist/{chunk-Q6CLWOP2.cjs → chunk-GPX5VC57.cjs} +50 -50
- package/dist/{chunk-Q6CLWOP2.cjs.map → chunk-GPX5VC57.cjs.map} +1 -1
- package/dist/{chunk-WAV762GP.cjs → chunk-GQXPNIRE.cjs} +6 -6
- package/dist/{chunk-WAV762GP.cjs.map → chunk-GQXPNIRE.cjs.map} +1 -1
- package/dist/chunk-GX2EBMJW.cjs +133 -0
- package/dist/chunk-GX2EBMJW.cjs.map +1 -0
- package/dist/{chunk-7OPOPYV6.cjs → chunk-H5OLHP2U.cjs} +3 -3
- package/dist/{chunk-7OPOPYV6.cjs.map → chunk-H5OLHP2U.cjs.map} +1 -1
- package/dist/chunk-HYUKPHCT.cjs +66 -0
- package/dist/chunk-HYUKPHCT.cjs.map +1 -0
- package/dist/{chunk-NLSWDP42.cjs → chunk-JQLWKNJO.cjs} +22 -12
- package/dist/chunk-JQLWKNJO.cjs.map +1 -0
- package/dist/{chunk-CKCG4NDB.cjs → chunk-JZEYHDWJ.cjs} +75 -75
- package/dist/{chunk-CKCG4NDB.cjs.map → chunk-JZEYHDWJ.cjs.map} +1 -1
- package/dist/{chunk-PGJYD67F.cjs → chunk-KNGZZC4O.cjs} +7 -6
- package/dist/chunk-KNGZZC4O.cjs.map +1 -0
- package/dist/{chunk-W6INT5GS.cjs → chunk-KP5AITQ4.cjs} +10 -10
- package/dist/{chunk-W6INT5GS.cjs.map → chunk-KP5AITQ4.cjs.map} +1 -1
- package/dist/{chunk-YYPZOEED.cjs → chunk-LHWOKOMP.cjs} +23 -2
- package/dist/chunk-LHWOKOMP.cjs.map +1 -0
- package/dist/{chunk-WXUU3COI.cjs → chunk-MZ2KZXNU.cjs} +3 -3
- package/dist/{chunk-WXUU3COI.cjs.map → chunk-MZ2KZXNU.cjs.map} +1 -1
- package/dist/chunk-NAJN32MF.cjs +154 -0
- package/dist/chunk-NAJN32MF.cjs.map +1 -0
- package/dist/{chunk-557MJ4IH.cjs → chunk-NLOETJCB.cjs} +17 -154
- package/dist/chunk-NLOETJCB.cjs.map +1 -0
- package/dist/{chunk-4XJEHKVZ.cjs → chunk-PIYYBPHH.cjs} +4 -4
- package/dist/{chunk-4XJEHKVZ.cjs.map → chunk-PIYYBPHH.cjs.map} +1 -1
- package/dist/chunk-Q3XJUXID.cjs +4774 -0
- package/dist/chunk-Q3XJUXID.cjs.map +1 -0
- package/dist/{chunk-325GVZE6.cjs → chunk-Q6DQGGP4.cjs} +3 -3
- package/dist/{chunk-325GVZE6.cjs.map → chunk-Q6DQGGP4.cjs.map} +1 -1
- package/dist/chunk-QFXILJMJ.cjs +458 -0
- package/dist/chunk-QFXILJMJ.cjs.map +1 -0
- package/dist/{chunk-QQWHG3KF.cjs → chunk-RYVZDFVO.cjs} +5 -5
- package/dist/{chunk-QQWHG3KF.cjs.map → chunk-RYVZDFVO.cjs.map} +1 -1
- package/dist/{chunk-EOG6OT5I.cjs → chunk-TXP2N3DC.cjs} +4 -4
- package/dist/{chunk-EOG6OT5I.cjs.map → chunk-TXP2N3DC.cjs.map} +1 -1
- package/dist/{chunk-KXIRVKCJ.cjs → chunk-UUENH4BJ.cjs} +3 -3
- package/dist/{chunk-KXIRVKCJ.cjs.map → chunk-UUENH4BJ.cjs.map} +1 -1
- package/dist/chunk-VJ5ZLRBD.cjs +27 -0
- package/dist/chunk-VJ5ZLRBD.cjs.map +1 -0
- package/dist/{chunk-3GWWOYGS.cjs → chunk-W6B3RYTX.cjs} +4 -4
- package/dist/{chunk-3GWWOYGS.cjs.map → chunk-W6B3RYTX.cjs.map} +1 -1
- package/dist/chunk-WOOOMTTA.cjs +19 -0
- package/dist/chunk-WOOOMTTA.cjs.map +1 -0
- package/dist/{chunk-CJYWHUZR.cjs → chunk-XCKHOXRP.cjs} +4 -4
- package/dist/{chunk-CJYWHUZR.cjs.map → chunk-XCKHOXRP.cjs.map} +1 -1
- package/dist/{chunk-6WMMZLEV.cjs → chunk-XJEXFEWG.cjs} +2 -27
- package/dist/chunk-XJEXFEWG.cjs.map +1 -0
- package/dist/chunk-XK4TVJKD.cjs +73 -0
- package/dist/chunk-XK4TVJKD.cjs.map +1 -0
- package/dist/chunk-XTR26TNE.cjs +1358 -0
- package/dist/chunk-XTR26TNE.cjs.map +1 -0
- package/dist/{chunk-E7TE2WVT.cjs → chunk-ZVEW3JBT.cjs} +3 -3
- package/dist/{chunk-E7TE2WVT.cjs.map → chunk-ZVEW3JBT.cjs.map} +1 -1
- package/dist/collaboration/index.cjs +70 -70
- package/dist/components/ZoomSlider.d.ts +25 -0
- package/dist/components/ZoomSlider.js +59 -0
- package/dist/components/ZoomSlider.js.map +7 -0
- package/dist/connect/docx.cjs +20 -20
- package/dist/connect/index.cjs +1150 -1232
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/viewer.cjs +40 -34
- package/dist/connection/ai.d.ts +1 -1
- package/dist/connection/files/ConnectedNewFileMenu.d.ts +2 -1
- package/dist/connection/files/ConnectedNewFileMenu.js +9 -3
- package/dist/connection/files/ConnectedNewFileMenu.js.map +2 -2
- package/dist/connection/files/explorer/ConnectedFilesExplorer.js +1 -1
- package/dist/connection/files/explorer/ConnectedFilesExplorer.js.map +2 -2
- package/dist/connection/files/explorer/FileTiles.js +1 -1
- package/dist/connection/files/explorer/FileTiles.js.map +2 -2
- package/dist/connection/files/fields/documentField.js +1 -1
- package/dist/connection/files/fields/documentField.js.map +2 -2
- package/dist/connection/files/grid/documentColumns.js +1 -1
- package/dist/connection/files/grid/documentColumns.js.map +2 -2
- package/dist/connection/files/page/DocumentsFilterBarActions.js +17 -28
- package/dist/connection/files/page/DocumentsFilterBarActions.js.map +2 -2
- package/dist/connection/mail/useMailboxDefaults.js +1 -1
- package/dist/connection/mail/useMailboxDefaults.js.map +2 -2
- package/dist/connection/panels/useSessionPanelMode.js +3 -2
- package/dist/connection/panels/useSessionPanelMode.js.map +2 -2
- package/dist/connection/presentation/ClippingMediaViewer.d.ts +12 -0
- package/dist/connection/presentation/ClippingMediaViewer.js +153 -0
- package/dist/connection/presentation/ClippingMediaViewer.js.map +7 -0
- package/dist/connection/presentation/ClippingPdfViewer.d.ts +22 -0
- package/dist/connection/presentation/ClippingPdfViewer.js +75 -0
- package/dist/connection/presentation/ClippingPdfViewer.js.map +7 -0
- package/dist/connection/presentation/ConnectedPresentation.d.ts +12 -0
- package/dist/connection/presentation/ConnectedPresentation.js +100 -0
- package/dist/connection/presentation/ConnectedPresentation.js.map +7 -0
- package/dist/connection/presentation/ConnectedSlidesTab.d.ts +20 -0
- package/dist/connection/presentation/ConnectedSlidesTab.js +220 -0
- package/dist/connection/presentation/ConnectedSlidesTab.js.map +7 -0
- package/dist/connection/presentation/CropClipDialog.d.ts +11 -0
- package/dist/connection/presentation/CropClipDialog.js +86 -0
- package/dist/connection/presentation/CropClipDialog.js.map +7 -0
- package/dist/connection/presentation/GenerateTile.d.ts +4 -0
- package/dist/connection/presentation/GenerateTile.js +24 -0
- package/dist/connection/presentation/GenerateTile.js.map +7 -0
- package/dist/connection/presentation/LabelColumnMenu.d.ts +8 -0
- package/dist/connection/presentation/LabelColumnMenu.js +38 -0
- package/dist/connection/presentation/LabelColumnMenu.js.map +7 -0
- package/dist/connection/presentation/PresentationDialogs.d.ts +39 -0
- package/dist/connection/presentation/PresentationDialogs.js +295 -0
- package/dist/connection/presentation/PresentationDialogs.js.map +7 -0
- package/dist/connection/presentation/PresentationFileCard.d.ts +10 -0
- package/dist/connection/presentation/PresentationFileCard.js +35 -0
- package/dist/connection/presentation/PresentationFileCard.js.map +7 -0
- package/dist/connection/presentation/PresentationPill.d.ts +8 -0
- package/dist/connection/presentation/PresentationPill.js +44 -0
- package/dist/connection/presentation/PresentationPill.js.map +7 -0
- package/dist/connection/presentation/PresentationSlot.d.ts +7 -0
- package/dist/connection/presentation/PresentationSlot.js +35 -0
- package/dist/connection/presentation/PresentationSlot.js.map +7 -0
- package/dist/connection/presentation/requests.d.ts +16 -0
- package/dist/connection/presentation/requests.js +20 -0
- package/dist/connection/presentation/requests.js.map +7 -0
- package/dist/connection/presentation/useImageGeneration.d.ts +11 -0
- package/dist/connection/presentation/useImageGeneration.js +66 -0
- package/dist/connection/presentation/useImageGeneration.js.map +7 -0
- package/dist/connection/presentation/useLabelColumns.d.ts +15 -0
- package/dist/connection/presentation/useLabelColumns.js +33 -0
- package/dist/connection/presentation/useLabelColumns.js.map +7 -0
- package/dist/connection/presentation/usePresentationController.d.ts +15 -0
- package/dist/connection/presentation/usePresentationController.js +118 -0
- package/dist/connection/presentation/usePresentationController.js.map +7 -0
- package/dist/connection/presentation/usePresentationFiles.d.ts +44 -0
- package/dist/connection/presentation/usePresentationFiles.js +307 -0
- package/dist/connection/presentation/usePresentationFiles.js.map +7 -0
- package/dist/connection/presentation/useViewerClipping.d.ts +14 -0
- package/dist/connection/presentation/useViewerClipping.js +18 -0
- package/dist/connection/presentation/useViewerClipping.js.map +7 -0
- package/dist/connection/shell/ConnectedAppShell.js +5 -1
- package/dist/connection/shell/ConnectedAppShell.js.map +2 -2
- package/dist/connection/viewer/CleanViewControl.d.ts +8 -0
- package/dist/connection/viewer/CleanViewControl.js +76 -0
- package/dist/connection/viewer/CleanViewControl.js.map +7 -0
- package/dist/connection/viewer/ConnectedDocumentViewer.js +28 -29
- package/dist/connection/viewer/ConnectedDocumentViewer.js.map +2 -2
- package/dist/connection/viewer/ViewerCropModal.d.ts +5 -0
- package/dist/connection/viewer/ViewerCropModal.js +22 -0
- package/dist/connection/viewer/ViewerCropModal.js.map +7 -0
- package/dist/connection/viewer/ViewerPdfPane.d.ts +3 -1
- package/dist/connection/viewer/ViewerPdfPane.js +37 -0
- package/dist/connection/viewer/ViewerPdfPane.js.map +2 -2
- package/dist/connection/viewer/drafts.js +6 -4
- package/dist/connection/viewer/drafts.js.map +2 -2
- package/dist/connection/viewer/shareDocument.d.ts +11 -0
- package/dist/connection/viewer/shareDocument.js +11 -0
- package/dist/connection/viewer/shareDocument.js.map +7 -0
- package/dist/connection/viewer/slidesTabChunk.d.ts +2 -0
- package/dist/connection/viewer/slidesTabChunk.js +9 -0
- package/dist/connection/viewer/slidesTabChunk.js.map +7 -0
- package/dist/connection/viewer/useCleanView.d.ts +14 -0
- package/dist/connection/viewer/useCleanView.js +29 -0
- package/dist/connection/viewer/useCleanView.js.map +7 -0
- package/dist/connection/viewer/useViewedDocument.d.ts +1 -0
- package/dist/connection/viewer/useViewedDocument.js +9 -1
- package/dist/connection/viewer/useViewedDocument.js.map +2 -2
- package/dist/connection/viewer/useViewerTabs.js +18 -4
- package/dist/connection/viewer/useViewerTabs.js.map +2 -2
- package/dist/connection/workflows/ConnectedWorkflowStart.d.ts +14 -2
- package/dist/connection/workflows/ConnectedWorkflowStart.js +5 -2
- package/dist/connection/workflows/ConnectedWorkflowStart.js.map +2 -2
- package/dist/dashboards/index.cjs +1 -1
- package/dist/databases/index.cjs +49 -49
- package/dist/document-tools/DocumentToolButtons.d.ts +2 -0
- package/dist/document-tools/DocumentToolButtons.js +22 -1
- package/dist/document-tools/DocumentToolButtons.js.map +2 -2
- package/dist/document-tools/index.cjs +16 -12
- package/dist/document-tools/index.d.ts +1 -1
- package/dist/document-tools/index.js +2 -0
- package/dist/document-tools/index.js.map +2 -2
- package/dist/embed/index.cjs +41 -39
- package/dist/files/GridViewImpl.js +1 -1
- package/dist/files/GridViewImpl.js.map +2 -2
- package/dist/files/ViewerChrome.d.ts +5 -1
- package/dist/files/ViewerChrome.js +16 -6
- package/dist/files/ViewerChrome.js.map +2 -2
- package/dist/files/index.cjs +225 -225
- package/dist/files/navigator/DocumentSearchList.js +1 -1
- package/dist/files/navigator/DocumentSearchList.js.map +2 -2
- package/dist/index.cjs +1666 -1664
- package/dist/index.cjs.map +1 -1
- package/dist/presentation/BoxActionBar.d.ts +11 -0
- package/dist/presentation/BoxActionBar.js +182 -0
- package/dist/presentation/BoxActionBar.js.map +7 -0
- package/dist/presentation/ClipActionBar.d.ts +26 -0
- package/dist/presentation/ClipActionBar.js +103 -0
- package/dist/presentation/ClipActionBar.js.map +7 -0
- package/dist/presentation/ClipCaptureOverlay.d.ts +14 -0
- package/dist/presentation/ClipCaptureOverlay.js +69 -0
- package/dist/presentation/ClipCaptureOverlay.js.map +7 -0
- package/dist/presentation/ClipImage.d.ts +21 -0
- package/dist/presentation/ClipImage.js +119 -0
- package/dist/presentation/ClipImage.js.map +7 -0
- package/dist/presentation/ClipTray.d.ts +11 -0
- package/dist/presentation/ClipTray.js +152 -0
- package/dist/presentation/ClipTray.js.map +7 -0
- package/dist/presentation/ClipViewControls.d.ts +11 -0
- package/dist/presentation/ClipViewControls.js +142 -0
- package/dist/presentation/ClipViewControls.js.map +7 -0
- package/dist/presentation/DesignMenu.d.ts +8 -0
- package/dist/presentation/DesignMenu.js +199 -0
- package/dist/presentation/DesignMenu.js.map +7 -0
- package/dist/presentation/LayoutMenu.d.ts +17 -0
- package/dist/presentation/LayoutMenu.js +122 -0
- package/dist/presentation/LayoutMenu.js.map +7 -0
- package/dist/presentation/MediaClip.d.ts +15 -0
- package/dist/presentation/MediaClip.js +67 -0
- package/dist/presentation/MediaClip.js.map +7 -0
- package/dist/presentation/Notice.d.ts +6 -0
- package/dist/presentation/Notice.js +43 -0
- package/dist/presentation/Notice.js.map +7 -0
- package/dist/presentation/PresentationStage.d.ts +32 -0
- package/dist/presentation/PresentationStage.js +232 -0
- package/dist/presentation/PresentationStage.js.map +7 -0
- package/dist/presentation/PresenterView.d.ts +16 -0
- package/dist/presentation/PresenterView.js +69 -0
- package/dist/presentation/PresenterView.js.map +7 -0
- package/dist/presentation/SlideDecor.d.ts +25 -0
- package/dist/presentation/SlideDecor.js +189 -0
- package/dist/presentation/SlideDecor.js.map +7 -0
- package/dist/presentation/SlidesEditor.d.ts +25 -0
- package/dist/presentation/SlidesEditor.js +359 -0
- package/dist/presentation/SlidesEditor.js.map +7 -0
- package/dist/presentation/StageBox.d.ts +30 -0
- package/dist/presentation/StageBox.js +281 -0
- package/dist/presentation/StageBox.js.map +7 -0
- package/dist/presentation/StageItem.d.ts +37 -0
- package/dist/presentation/StageItem.js +211 -0
- package/dist/presentation/StageItem.js.map +7 -0
- package/dist/presentation/box-style.d.ts +6 -0
- package/dist/presentation/box-style.js +19 -0
- package/dist/presentation/box-style.js.map +7 -0
- package/dist/presentation/boxes.d.ts +105 -0
- package/dist/presentation/boxes.js +103 -0
- package/dist/presentation/boxes.js.map +7 -0
- package/dist/presentation/draw-boxes.d.ts +8 -0
- package/dist/presentation/draw-boxes.js +130 -0
- package/dist/presentation/draw-boxes.js.map +7 -0
- package/dist/presentation/export-boxes.d.ts +10 -0
- package/dist/presentation/export-boxes.js +74 -0
- package/dist/presentation/export-boxes.js.map +7 -0
- package/dist/presentation/export-pptx.d.ts +16 -0
- package/dist/presentation/export-pptx.js +194 -0
- package/dist/presentation/export-pptx.js.map +7 -0
- package/dist/presentation/import-pptx.d.ts +35 -0
- package/dist/presentation/import-pptx.js +659 -0
- package/dist/presentation/import-pptx.js.map +7 -0
- package/dist/presentation/merge-outside-edits.d.ts +12 -0
- package/dist/presentation/merge-outside-edits.js +35 -0
- package/dist/presentation/merge-outside-edits.js.map +7 -0
- package/dist/presentation/model.d.ts +201 -0
- package/dist/presentation/model.js +271 -0
- package/dist/presentation/model.js.map +7 -0
- package/dist/presentation/panel-id.d.ts +34 -0
- package/dist/presentation/panel-id.js +24 -0
- package/dist/presentation/panel-id.js.map +7 -0
- package/dist/presentation/persistence.d.ts +121 -0
- package/dist/presentation/persistence.js +141 -0
- package/dist/presentation/persistence.js.map +7 -0
- package/dist/presentation/pptx-data.d.ts +22 -0
- package/dist/presentation/pptx-data.js +83 -0
- package/dist/presentation/pptx-data.js.map +7 -0
- package/dist/presentation/pptx-xml.d.ts +90 -0
- package/dist/presentation/pptx-xml.js +333 -0
- package/dist/presentation/pptx-xml.js.map +7 -0
- package/dist/presentation/render-slides.d.ts +58 -0
- package/dist/presentation/render-slides.js +309 -0
- package/dist/presentation/render-slides.js.map +7 -0
- package/dist/presentation/saved-boxes.d.ts +11 -0
- package/dist/presentation/saved-boxes.js +80 -0
- package/dist/presentation/saved-boxes.js.map +7 -0
- package/dist/presentation/slide-layout.d.ts +54 -0
- package/dist/presentation/slide-layout.js +117 -0
- package/dist/presentation/slide-layout.js.map +7 -0
- package/dist/presentation/stage-videos.d.ts +5 -0
- package/dist/presentation/stage-videos.js +19 -0
- package/dist/presentation/stage-videos.js.map +7 -0
- package/dist/presentation/store.d.ts +203 -0
- package/dist/presentation/store.js +429 -0
- package/dist/presentation/store.js.map +7 -0
- package/dist/presentation/theme.d.ts +102 -0
- package/dist/presentation/theme.js +276 -0
- package/dist/presentation/theme.js.map +7 -0
- package/dist/presentation/useClipDrag.d.ts +26 -0
- package/dist/presentation/useClipDrag.js +65 -0
- package/dist/presentation/useClipDrag.js.map +7 -0
- package/dist/presentation/useObjectUrl.d.ts +6 -0
- package/dist/presentation/useObjectUrl.js +15 -0
- package/dist/presentation/useObjectUrl.js.map +7 -0
- package/dist/presentation/usePresenterKeys.d.ts +13 -0
- package/dist/presentation/usePresenterKeys.js +62 -0
- package/dist/presentation/usePresenterKeys.js.map +7 -0
- package/dist/settings/index.cjs +151 -150
- package/dist/shell/PanelPortal.js +1 -0
- package/dist/shell/PanelPortal.js.map +2 -2
- package/dist/shell/index.cjs +112 -110
- package/dist/shell/panel-windows.d.ts +2 -0
- package/dist/shell/panel-windows.js +7 -2
- package/dist/shell/panel-windows.js.map +2 -2
- package/dist/studio/index.cjs +28 -26
- package/dist/studio/index.cjs.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/workflow-canvas/index.cjs +55 -54
- package/dist/workflow-canvas/index.cjs.map +1 -1
- package/node_modules/@arbidocs/coedit/package.json +1 -1
- package/package.json +6 -5
- package/dist/ConnectedCallDock-WER7R222.cjs.map +0 -1
- package/dist/DocumentReviewCard-BPIAJJED.cjs.map +0 -1
- package/dist/FilesViewerDialog-67WK3TZC.cjs.map +0 -1
- package/dist/GridViewImpl-ZMJJWTOM.cjs.map +0 -1
- package/dist/WorkspaceTableView-J3C6VH4T.cjs.map +0 -1
- package/dist/ai-IM4A23YT.cjs.map +0 -1
- package/dist/chunk-557MJ4IH.cjs.map +0 -1
- package/dist/chunk-6UTKM5AB.cjs.map +0 -1
- package/dist/chunk-6WMMZLEV.cjs.map +0 -1
- package/dist/chunk-B3LZITVF.cjs.map +0 -1
- package/dist/chunk-BUVIBHFU.cjs.map +0 -1
- package/dist/chunk-CPR6EHG7.cjs.map +0 -1
- package/dist/chunk-HA66DHW6.cjs.map +0 -1
- package/dist/chunk-NJCK6V6U.cjs.map +0 -1
- package/dist/chunk-NLSWDP42.cjs.map +0 -1
- package/dist/chunk-PGJYD67F.cjs.map +0 -1
- package/dist/chunk-X36UR4A7.cjs.map +0 -1
- package/dist/chunk-YYPZOEED.cjs.map +0 -1
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A slide's text boxes and shapes: what a PowerPoint slide is made of besides pictures, so a deck
|
|
3
|
+
* imported from PowerPoint keeps its look and its words stay editable. A box sits in a frame of its
|
|
4
|
+
* own (fractions of the stage, its height free), holds styled text (paragraphs of runs) and can be
|
|
5
|
+
* a shape (a rectangle, a rounded one, an ellipse, a line) with a fill and an outline.
|
|
6
|
+
*
|
|
7
|
+
* Type sizes are points on PowerPoint's widescreen slide (13.333 × 7.5 in), so they read the same
|
|
8
|
+
* here, in the saved PDF and in an exported deck.
|
|
9
|
+
*/
|
|
10
|
+
/** A box's place: left, top, width and height as fractions of the stage. */
|
|
11
|
+
export interface BoxFrame {
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
w: number;
|
|
15
|
+
h: number;
|
|
16
|
+
}
|
|
17
|
+
export type BoxShape = 'text' | 'rect' | 'roundRect' | 'ellipse' | 'line';
|
|
18
|
+
export type TextAlign = 'left' | 'center' | 'right' | 'justify';
|
|
19
|
+
export type BoxAnchor = 'top' | 'middle' | 'bottom';
|
|
20
|
+
export interface TextRun {
|
|
21
|
+
text: string;
|
|
22
|
+
/** Points on the widescreen slide; absent: `DEFAULT_TEXT_SIZE`. */
|
|
23
|
+
size?: number;
|
|
24
|
+
bold?: boolean;
|
|
25
|
+
italic?: boolean;
|
|
26
|
+
underline?: boolean;
|
|
27
|
+
/** `#rrggbb`; absent: the theme's body text colour. */
|
|
28
|
+
color?: string;
|
|
29
|
+
/** A typeface name; absent: the theme's. */
|
|
30
|
+
font?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface Paragraph {
|
|
33
|
+
runs: TextRun[];
|
|
34
|
+
align?: TextAlign;
|
|
35
|
+
/** Its indent level (0 is the outermost). */
|
|
36
|
+
level?: number;
|
|
37
|
+
bullet?: boolean;
|
|
38
|
+
}
|
|
39
|
+
export interface SlideBox {
|
|
40
|
+
id: string;
|
|
41
|
+
frame: BoxFrame;
|
|
42
|
+
shape: BoxShape;
|
|
43
|
+
/** Degrees, clockwise. */
|
|
44
|
+
rotation?: number;
|
|
45
|
+
flipH?: boolean;
|
|
46
|
+
flipV?: boolean;
|
|
47
|
+
/** `#rrggbb`; absent: no fill. */
|
|
48
|
+
fill?: string;
|
|
49
|
+
/** The fill's opacity, 0–1 (default 1). */
|
|
50
|
+
fillAlpha?: number;
|
|
51
|
+
line?: {
|
|
52
|
+
color: string;
|
|
53
|
+
width: number;
|
|
54
|
+
dash?: boolean;
|
|
55
|
+
};
|
|
56
|
+
paragraphs: Paragraph[];
|
|
57
|
+
anchor?: BoxAnchor;
|
|
58
|
+
/** Room between the box's edge and its text, in points (default `DEFAULT_INSET`). */
|
|
59
|
+
inset?: number;
|
|
60
|
+
/** The slide's title or body text (a PowerPoint placeholder): what an outline reads. */
|
|
61
|
+
role?: 'title' | 'body';
|
|
62
|
+
/** Drawn over the slide's clips (default: under them). */
|
|
63
|
+
front?: boolean;
|
|
64
|
+
}
|
|
65
|
+
/** A slide's own background, over the theme's: an image (a media key), a gradient or a colour. */
|
|
66
|
+
export interface SlideBackground {
|
|
67
|
+
color?: string;
|
|
68
|
+
gradient?: {
|
|
69
|
+
from: string;
|
|
70
|
+
to: string;
|
|
71
|
+
angle: number;
|
|
72
|
+
};
|
|
73
|
+
image?: string;
|
|
74
|
+
}
|
|
75
|
+
/** PowerPoint's widescreen slide in points: type sizes are measured against it. */
|
|
76
|
+
export declare const SLIDE_POINTS: {
|
|
77
|
+
w: number;
|
|
78
|
+
h: number;
|
|
79
|
+
};
|
|
80
|
+
export declare const DEFAULT_TEXT_SIZE = 18;
|
|
81
|
+
export declare const DEFAULT_INSET = 7.2;
|
|
82
|
+
/** The smallest a box can be made (fractions of the stage). */
|
|
83
|
+
export declare const MIN_BOX = 0.02;
|
|
84
|
+
/** A size in points as a fraction of the stage width (the stage's `cqw` / 100). */
|
|
85
|
+
export declare const pointsToStage: (points: number) => number;
|
|
86
|
+
/** The text of a box, one line per paragraph. */
|
|
87
|
+
export declare const boxText: (box: Pick<SlideBox, "paragraphs">) => string;
|
|
88
|
+
/**
|
|
89
|
+
* New text typed into a box: one paragraph per line, each keeping the style of the paragraph it
|
|
90
|
+
* replaces (its first run's type, its alignment, level and bullet), so retyping keeps the look.
|
|
91
|
+
*/
|
|
92
|
+
export declare function withText(box: SlideBox, text: string): SlideBox;
|
|
93
|
+
/** Every run of a box changed by `change` (bold, a size, a colour: the whole box at once). */
|
|
94
|
+
export declare function styleRuns(box: SlideBox, change: (run: TextRun) => TextRun): SlideBox;
|
|
95
|
+
/** A box's first run (what its style controls show). */
|
|
96
|
+
export declare const firstRun: (box: SlideBox) => TextRun | undefined;
|
|
97
|
+
/** The box moved by `dx, dy`, kept on the stage. */
|
|
98
|
+
export declare function moveBox(frame: BoxFrame, dx: number, dy: number): BoxFrame;
|
|
99
|
+
/** A box handle: a corner or a side's middle. */
|
|
100
|
+
export type BoxHandle = 'nw' | 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w';
|
|
101
|
+
/** The box resized from `handle` by `dx, dy` (its shape is free; the opposite side stays put). */
|
|
102
|
+
export declare function stretchBox(frame: BoxFrame, handle: BoxHandle, dx: number, dy: number): BoxFrame;
|
|
103
|
+
export declare const nextBoxId: () => string;
|
|
104
|
+
/** A new box of `shape`, in the middle of the slide, ready to type in. */
|
|
105
|
+
export declare function newBox(shape: BoxShape, accent: string): SlideBox;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const SLIDE_POINTS = { w: 960, h: 540 };
|
|
3
|
+
const DEFAULT_TEXT_SIZE = 18;
|
|
4
|
+
const DEFAULT_INSET = 7.2;
|
|
5
|
+
const MIN_BOX = 0.02;
|
|
6
|
+
const pointsToStage = (points) => points / SLIDE_POINTS.w;
|
|
7
|
+
const boxText = (box) => box.paragraphs.map((paragraph) => paragraph.runs.map((run) => run.text).join("")).join("\n");
|
|
8
|
+
function withText(box, text) {
|
|
9
|
+
const lines = text.split("\n");
|
|
10
|
+
const fallback = box.paragraphs[box.paragraphs.length - 1] ?? { runs: [{ text: "" }] };
|
|
11
|
+
const paragraphs = lines.map((line, index) => {
|
|
12
|
+
const before = box.paragraphs[index] ?? fallback;
|
|
13
|
+
const { text: _old, ...style } = before.runs[0] ?? { text: "" };
|
|
14
|
+
void _old;
|
|
15
|
+
return { ...before, runs: [{ ...style, text: line }] };
|
|
16
|
+
});
|
|
17
|
+
return { ...box, paragraphs };
|
|
18
|
+
}
|
|
19
|
+
function styleRuns(box, change) {
|
|
20
|
+
return {
|
|
21
|
+
...box,
|
|
22
|
+
paragraphs: box.paragraphs.map((paragraph) => ({
|
|
23
|
+
...paragraph,
|
|
24
|
+
runs: paragraph.runs.map(change)
|
|
25
|
+
}))
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const firstRun = (box) => box.paragraphs.find((paragraph) => paragraph.runs.length)?.runs[0];
|
|
29
|
+
const clamp = (value, min, max) => max < min ? (min + max) / 2 : Math.min(Math.max(value, min), max);
|
|
30
|
+
function moveBox(frame, dx, dy) {
|
|
31
|
+
return {
|
|
32
|
+
...frame,
|
|
33
|
+
x: clamp(frame.x + dx, -frame.w / 2, 1 - frame.w / 2),
|
|
34
|
+
y: clamp(frame.y + dy, -frame.h / 2, 1 - frame.h / 2)
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function stretchBox(frame, handle, dx, dy) {
|
|
38
|
+
let { x, y, w, h } = frame;
|
|
39
|
+
if (handle.includes("w")) {
|
|
40
|
+
const right = x + w;
|
|
41
|
+
x = Math.min(x + dx, right - MIN_BOX);
|
|
42
|
+
w = right - x;
|
|
43
|
+
} else if (handle.includes("e")) {
|
|
44
|
+
w = Math.max(MIN_BOX, w + dx);
|
|
45
|
+
}
|
|
46
|
+
if (handle.startsWith("n")) {
|
|
47
|
+
const bottom = y + h;
|
|
48
|
+
y = Math.min(y + dy, bottom - MIN_BOX);
|
|
49
|
+
h = bottom - y;
|
|
50
|
+
} else if (handle.startsWith("s")) {
|
|
51
|
+
h = Math.max(MIN_BOX, h + dy);
|
|
52
|
+
}
|
|
53
|
+
return { x, y, w, h };
|
|
54
|
+
}
|
|
55
|
+
let sequence = 0;
|
|
56
|
+
const nextBoxId = () => `box-${Date.now().toString(36)}-${++sequence}`;
|
|
57
|
+
function newBox(shape, accent) {
|
|
58
|
+
const id = nextBoxId();
|
|
59
|
+
if (shape === "text") {
|
|
60
|
+
return {
|
|
61
|
+
id,
|
|
62
|
+
shape,
|
|
63
|
+
frame: { x: 0.3, y: 0.42, w: 0.4, h: 0.12 },
|
|
64
|
+
paragraphs: [{ runs: [{ text: "", size: 24 }] }],
|
|
65
|
+
front: true
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
if (shape === "line") {
|
|
69
|
+
return {
|
|
70
|
+
id,
|
|
71
|
+
shape,
|
|
72
|
+
frame: { x: 0.35, y: 0.5, w: 0.3, h: 0 },
|
|
73
|
+
line: { color: accent, width: 2 },
|
|
74
|
+
paragraphs: [],
|
|
75
|
+
front: true
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
id,
|
|
80
|
+
shape,
|
|
81
|
+
frame: { x: 0.35, y: 0.35, w: 0.3, h: 0.3 },
|
|
82
|
+
fill: accent,
|
|
83
|
+
paragraphs: [{ runs: [{ text: "", size: 20, color: "#ffffff" }], align: "center" }],
|
|
84
|
+
anchor: "middle",
|
|
85
|
+
front: false
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
export {
|
|
89
|
+
DEFAULT_INSET,
|
|
90
|
+
DEFAULT_TEXT_SIZE,
|
|
91
|
+
MIN_BOX,
|
|
92
|
+
SLIDE_POINTS,
|
|
93
|
+
boxText,
|
|
94
|
+
firstRun,
|
|
95
|
+
moveBox,
|
|
96
|
+
newBox,
|
|
97
|
+
nextBoxId,
|
|
98
|
+
pointsToStage,
|
|
99
|
+
stretchBox,
|
|
100
|
+
styleRuns,
|
|
101
|
+
withText
|
|
102
|
+
};
|
|
103
|
+
//# sourceMappingURL=boxes.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/presentation/boxes.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * A slide's text boxes and shapes: what a PowerPoint slide is made of besides pictures, so a deck\n * imported from PowerPoint keeps its look and its words stay editable. A box sits in a frame of its\n * own (fractions of the stage, its height free), holds styled text (paragraphs of runs) and can be\n * a shape (a rectangle, a rounded one, an ellipse, a line) with a fill and an outline.\n *\n * Type sizes are points on PowerPoint's widescreen slide (13.333 \u00D7 7.5 in), so they read the same\n * here, in the saved PDF and in an exported deck.\n */\n\n/** A box's place: left, top, width and height as fractions of the stage. */\nexport interface BoxFrame {\n x: number\n y: number\n w: number\n h: number\n}\n\nexport type BoxShape = 'text' | 'rect' | 'roundRect' | 'ellipse' | 'line'\nexport type TextAlign = 'left' | 'center' | 'right' | 'justify'\nexport type BoxAnchor = 'top' | 'middle' | 'bottom'\n\nexport interface TextRun {\n text: string\n /** Points on the widescreen slide; absent: `DEFAULT_TEXT_SIZE`. */\n size?: number\n bold?: boolean\n italic?: boolean\n underline?: boolean\n /** `#rrggbb`; absent: the theme's body text colour. */\n color?: string\n /** A typeface name; absent: the theme's. */\n font?: string\n}\n\nexport interface Paragraph {\n runs: TextRun[]\n align?: TextAlign\n /** Its indent level (0 is the outermost). */\n level?: number\n bullet?: boolean\n}\n\nexport interface SlideBox {\n id: string\n frame: BoxFrame\n shape: BoxShape\n /** Degrees, clockwise. */\n rotation?: number\n flipH?: boolean\n flipV?: boolean\n /** `#rrggbb`; absent: no fill. */\n fill?: string\n /** The fill's opacity, 0\u20131 (default 1). */\n fillAlpha?: number\n line?: { color: string; width: number; dash?: boolean }\n paragraphs: Paragraph[]\n anchor?: BoxAnchor\n /** Room between the box's edge and its text, in points (default `DEFAULT_INSET`). */\n inset?: number\n /** The slide's title or body text (a PowerPoint placeholder): what an outline reads. */\n role?: 'title' | 'body'\n /** Drawn over the slide's clips (default: under them). */\n front?: boolean\n}\n\n/** A slide's own background, over the theme's: an image (a media key), a gradient or a colour. */\nexport interface SlideBackground {\n color?: string\n gradient?: { from: string; to: string; angle: number }\n image?: string\n}\n\n/** PowerPoint's widescreen slide in points: type sizes are measured against it. */\nexport const SLIDE_POINTS = { w: 960, h: 540 }\nexport const DEFAULT_TEXT_SIZE = 18\nexport const DEFAULT_INSET = 7.2\n/** The smallest a box can be made (fractions of the stage). */\nexport const MIN_BOX = 0.02\n\n/** A size in points as a fraction of the stage width (the stage's `cqw` / 100). */\nexport const pointsToStage = (points: number): number => points / SLIDE_POINTS.w\n\n/** The text of a box, one line per paragraph. */\nexport const boxText = (box: Pick<SlideBox, 'paragraphs'>): string =>\n box.paragraphs.map((paragraph) => paragraph.runs.map((run) => run.text).join('')).join('\\n')\n\n/**\n * New text typed into a box: one paragraph per line, each keeping the style of the paragraph it\n * replaces (its first run's type, its alignment, level and bullet), so retyping keeps the look.\n */\nexport function withText(box: SlideBox, text: string): SlideBox {\n const lines = text.split('\\n')\n const fallback = box.paragraphs[box.paragraphs.length - 1] ?? { runs: [{ text: '' }] }\n const paragraphs = lines.map((line, index) => {\n const before = box.paragraphs[index] ?? fallback\n const { text: _old, ...style } = before.runs[0] ?? { text: '' }\n void _old\n return { ...before, runs: [{ ...style, text: line }] }\n })\n return { ...box, paragraphs }\n}\n\n/** Every run of a box changed by `change` (bold, a size, a colour: the whole box at once). */\nexport function styleRuns(box: SlideBox, change: (run: TextRun) => TextRun): SlideBox {\n return {\n ...box,\n paragraphs: box.paragraphs.map((paragraph) => ({\n ...paragraph,\n runs: paragraph.runs.map(change),\n })),\n }\n}\n\n/** A box's first run (what its style controls show). */\nexport const firstRun = (box: SlideBox): TextRun | undefined =>\n box.paragraphs.find((paragraph) => paragraph.runs.length)?.runs[0]\n\nconst clamp = (value: number, min: number, max: number) =>\n max < min ? (min + max) / 2 : Math.min(Math.max(value, min), max)\n\n/** The box moved by `dx, dy`, kept on the stage. */\nexport function moveBox(frame: BoxFrame, dx: number, dy: number): BoxFrame {\n return {\n ...frame,\n x: clamp(frame.x + dx, -frame.w / 2, 1 - frame.w / 2),\n y: clamp(frame.y + dy, -frame.h / 2, 1 - frame.h / 2),\n }\n}\n\n/** A box handle: a corner or a side's middle. */\nexport type BoxHandle = 'nw' | 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w'\n\n/** The box resized from `handle` by `dx, dy` (its shape is free; the opposite side stays put). */\nexport function stretchBox(frame: BoxFrame, handle: BoxHandle, dx: number, dy: number): BoxFrame {\n let { x, y, w, h } = frame\n if (handle.includes('w')) {\n const right = x + w\n x = Math.min(x + dx, right - MIN_BOX)\n w = right - x\n } else if (handle.includes('e')) {\n w = Math.max(MIN_BOX, w + dx)\n }\n if (handle.startsWith('n')) {\n const bottom = y + h\n y = Math.min(y + dy, bottom - MIN_BOX)\n h = bottom - y\n } else if (handle.startsWith('s')) {\n h = Math.max(MIN_BOX, h + dy)\n }\n return { x, y, w, h }\n}\n\nlet sequence = 0\nexport const nextBoxId = (): string => `box-${Date.now().toString(36)}-${++sequence}`\n\n/** A new box of `shape`, in the middle of the slide, ready to type in. */\nexport function newBox(shape: BoxShape, accent: string): SlideBox {\n const id = nextBoxId()\n if (shape === 'text') {\n return {\n id,\n shape,\n frame: { x: 0.3, y: 0.42, w: 0.4, h: 0.12 },\n paragraphs: [{ runs: [{ text: '', size: 24 }] }],\n front: true,\n }\n }\n if (shape === 'line') {\n return {\n id,\n shape,\n frame: { x: 0.35, y: 0.5, w: 0.3, h: 0 },\n line: { color: accent, width: 2 },\n paragraphs: [],\n front: true,\n }\n }\n return {\n id,\n shape,\n frame: { x: 0.35, y: 0.35, w: 0.3, h: 0.3 },\n fill: accent,\n paragraphs: [{ runs: [{ text: '', size: 20, color: '#ffffff' }], align: 'center' }],\n anchor: 'middle',\n front: false,\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A slide's text boxes and shapes drawn on a canvas, as the stage draws them (`StageBox`): for the
|
|
3
|
+
* saved PDF's pages. Text wraps by words across runs of different type.
|
|
4
|
+
*/
|
|
5
|
+
import { type SlideBox } from './boxes';
|
|
6
|
+
export declare function drawBox(context: CanvasRenderingContext2D, box: SlideBox, width: number, height: number, themeFont: string): void;
|
|
7
|
+
/** The words a box shows, for a searchable PDF. */
|
|
8
|
+
export declare const boxWords: (box: SlideBox) => string[];
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
DEFAULT_INSET,
|
|
4
|
+
DEFAULT_TEXT_SIZE,
|
|
5
|
+
pointsToStage
|
|
6
|
+
} from "./boxes.js";
|
|
7
|
+
import { TEXT_COLORS } from "./theme.js";
|
|
8
|
+
const LINE_HEIGHT = 1.2;
|
|
9
|
+
function fontOf(run, themeFont, width) {
|
|
10
|
+
const size = pointsToStage(run.size ?? DEFAULT_TEXT_SIZE) * width;
|
|
11
|
+
const family = run.font ? `"${run.font}", ${themeFont}` : themeFont;
|
|
12
|
+
return `${run.italic ? "italic " : ""}${run.bold ? 700 : 400} ${size}px ${family}`;
|
|
13
|
+
}
|
|
14
|
+
function outline(context, box, w, h) {
|
|
15
|
+
context.beginPath();
|
|
16
|
+
if (box.shape === "ellipse") context.ellipse(w / 2, h / 2, w / 2, h / 2, 0, 0, Math.PI * 2);
|
|
17
|
+
else if (box.shape === "roundRect") context.roundRect(0, 0, w, h, Math.min(w, h) / 6);
|
|
18
|
+
else context.rect(0, 0, w, h);
|
|
19
|
+
}
|
|
20
|
+
function drawBox(context, box, width, height, themeFont) {
|
|
21
|
+
const { frame } = box;
|
|
22
|
+
const w = frame.w * width;
|
|
23
|
+
const h = frame.h * height;
|
|
24
|
+
context.save();
|
|
25
|
+
context.translate(frame.x * width + w / 2, frame.y * height + h / 2);
|
|
26
|
+
if (box.rotation) context.rotate(box.rotation * Math.PI / 180);
|
|
27
|
+
context.translate(-w / 2, -h / 2);
|
|
28
|
+
const lineWidth = box.line ? Math.max(1, pointsToStage(box.line.width) * width) : 0;
|
|
29
|
+
if (box.shape === "line") {
|
|
30
|
+
context.strokeStyle = box.line?.color ?? TEXT_COLORS.body;
|
|
31
|
+
context.lineWidth = lineWidth || 1;
|
|
32
|
+
if (box.line?.dash) context.setLineDash([lineWidth * 3, lineWidth * 2]);
|
|
33
|
+
context.beginPath();
|
|
34
|
+
context.moveTo(0, box.flipV ? h : 0);
|
|
35
|
+
context.lineTo(w, box.flipV ? 0 : h);
|
|
36
|
+
context.stroke();
|
|
37
|
+
context.restore();
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (box.fill) {
|
|
41
|
+
context.globalAlpha = box.fillAlpha ?? 1;
|
|
42
|
+
context.fillStyle = box.fill;
|
|
43
|
+
outline(context, box, w, h);
|
|
44
|
+
context.fill();
|
|
45
|
+
context.globalAlpha = 1;
|
|
46
|
+
}
|
|
47
|
+
if (box.line && lineWidth) {
|
|
48
|
+
context.strokeStyle = box.line.color;
|
|
49
|
+
context.lineWidth = lineWidth;
|
|
50
|
+
if (box.line.dash) context.setLineDash([lineWidth * 3, lineWidth * 2]);
|
|
51
|
+
outline(context, box, w, h);
|
|
52
|
+
context.stroke();
|
|
53
|
+
context.setLineDash([]);
|
|
54
|
+
}
|
|
55
|
+
const inset = pointsToStage(box.inset ?? DEFAULT_INSET) * width;
|
|
56
|
+
const room = w - 2 * inset;
|
|
57
|
+
context.textBaseline = "alphabetic";
|
|
58
|
+
const lines = [];
|
|
59
|
+
for (const paragraph of box.paragraphs) {
|
|
60
|
+
const size = pointsToStage(paragraph.runs[0]?.size ?? DEFAULT_TEXT_SIZE) * width;
|
|
61
|
+
const indent = (paragraph.level ?? 0) * 0.5 * size + (paragraph.bullet ? size * 0.9 : 0);
|
|
62
|
+
const words = [];
|
|
63
|
+
for (const run of paragraph.runs) {
|
|
64
|
+
context.font = fontOf(run, themeFont, width);
|
|
65
|
+
for (const part of run.text.split(/(\s+)/).filter(Boolean)) {
|
|
66
|
+
words.push({ text: part, run, width: context.measureText(part).width });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
let line = [];
|
|
70
|
+
let used = 0;
|
|
71
|
+
let first = true;
|
|
72
|
+
const flush = () => {
|
|
73
|
+
lines.push({
|
|
74
|
+
pieces: line,
|
|
75
|
+
size,
|
|
76
|
+
align: paragraph.align ?? "left",
|
|
77
|
+
indent,
|
|
78
|
+
...first && paragraph.bullet ? { bullet: paragraph.runs[0] } : {}
|
|
79
|
+
});
|
|
80
|
+
first = false;
|
|
81
|
+
line = [];
|
|
82
|
+
used = 0;
|
|
83
|
+
};
|
|
84
|
+
for (const word of words) {
|
|
85
|
+
if (used + word.width > room - indent && line.length && word.text.trim()) flush();
|
|
86
|
+
if (!line.length && !word.text.trim()) continue;
|
|
87
|
+
line.push(word);
|
|
88
|
+
used += word.width;
|
|
89
|
+
}
|
|
90
|
+
flush();
|
|
91
|
+
}
|
|
92
|
+
const total = lines.reduce((sum, line) => sum + line.size * LINE_HEIGHT, 0);
|
|
93
|
+
const free = h - 2 * inset - total;
|
|
94
|
+
let y = inset + (box.anchor === "middle" ? free / 2 : box.anchor === "bottom" ? free : 0);
|
|
95
|
+
context.save();
|
|
96
|
+
context.beginPath();
|
|
97
|
+
context.rect(0, 0, w, h);
|
|
98
|
+
context.clip();
|
|
99
|
+
for (const line of lines) {
|
|
100
|
+
const lineWidth2 = line.pieces.reduce((sum, piece) => sum + piece.width, 0);
|
|
101
|
+
const space = room - line.indent;
|
|
102
|
+
let x = inset + line.indent + (line.align === "center" ? (space - lineWidth2) / 2 : line.align === "right" ? space - lineWidth2 : 0);
|
|
103
|
+
const baseline = y + line.size * (LINE_HEIGHT - 0.2);
|
|
104
|
+
if (line.bullet) {
|
|
105
|
+
context.font = fontOf(line.bullet, themeFont, width);
|
|
106
|
+
context.fillStyle = line.bullet.color ?? TEXT_COLORS.body;
|
|
107
|
+
context.fillText("\u2022", inset + line.indent - line.size * 0.9, baseline);
|
|
108
|
+
}
|
|
109
|
+
for (const piece of line.pieces) {
|
|
110
|
+
context.font = fontOf(piece.run, themeFont, width);
|
|
111
|
+
context.fillStyle = piece.run.color ?? TEXT_COLORS.body;
|
|
112
|
+
context.fillText(piece.text, x, baseline);
|
|
113
|
+
if (piece.run.underline) {
|
|
114
|
+
context.fillRect(x, baseline + line.size * 0.08, piece.width, Math.max(1, line.size * 0.05));
|
|
115
|
+
}
|
|
116
|
+
x += piece.width;
|
|
117
|
+
}
|
|
118
|
+
y += line.size * LINE_HEIGHT;
|
|
119
|
+
}
|
|
120
|
+
context.restore();
|
|
121
|
+
context.restore();
|
|
122
|
+
}
|
|
123
|
+
const boxWords = (box) => box.paragraphs.map(
|
|
124
|
+
(paragraph) => paragraph.runs.map((run) => run.text).join("").trim()
|
|
125
|
+
).filter(Boolean);
|
|
126
|
+
export {
|
|
127
|
+
boxWords,
|
|
128
|
+
drawBox
|
|
129
|
+
};
|
|
130
|
+
//# sourceMappingURL=draw-boxes.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/presentation/draw-boxes.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * A slide's text boxes and shapes drawn on a canvas, as the stage draws them (`StageBox`): for the\n * saved PDF's pages. Text wraps by words across runs of different type.\n */\n\nimport {\n DEFAULT_INSET,\n DEFAULT_TEXT_SIZE,\n pointsToStage,\n type SlideBox,\n type TextRun,\n} from './boxes'\nimport { TEXT_COLORS } from './theme'\n\nconst LINE_HEIGHT = 1.2\n\nfunction fontOf(run: TextRun, themeFont: string, width: number): string {\n const size = pointsToStage(run.size ?? DEFAULT_TEXT_SIZE) * width\n const family = run.font ? `\"${run.font}\", ${themeFont}` : themeFont\n return `${run.italic ? 'italic ' : ''}${run.bold ? 700 : 400} ${size}px ${family}`\n}\n\ninterface Piece {\n text: string\n run: TextRun\n width: number\n}\n\n/** The box's outline path (its shape) at `x, y, w, h`. */\nfunction outline(context: CanvasRenderingContext2D, box: SlideBox, w: number, h: number) {\n context.beginPath()\n if (box.shape === 'ellipse') context.ellipse(w / 2, h / 2, w / 2, h / 2, 0, 0, Math.PI * 2)\n else if (box.shape === 'roundRect') context.roundRect(0, 0, w, h, Math.min(w, h) / 6)\n else context.rect(0, 0, w, h)\n}\n\nexport function drawBox(\n context: CanvasRenderingContext2D,\n box: SlideBox,\n width: number,\n height: number,\n themeFont: string\n): void {\n const { frame } = box\n const w = frame.w * width\n const h = frame.h * height\n context.save()\n context.translate(frame.x * width + w / 2, frame.y * height + h / 2)\n if (box.rotation) context.rotate((box.rotation * Math.PI) / 180)\n context.translate(-w / 2, -h / 2)\n\n const lineWidth = box.line ? Math.max(1, pointsToStage(box.line.width) * width) : 0\n if (box.shape === 'line') {\n context.strokeStyle = box.line?.color ?? TEXT_COLORS.body\n context.lineWidth = lineWidth || 1\n if (box.line?.dash) context.setLineDash([lineWidth * 3, lineWidth * 2])\n context.beginPath()\n context.moveTo(0, box.flipV ? h : 0)\n context.lineTo(w, box.flipV ? 0 : h)\n context.stroke()\n context.restore()\n return\n }\n if (box.fill) {\n context.globalAlpha = box.fillAlpha ?? 1\n context.fillStyle = box.fill\n outline(context, box, w, h)\n context.fill()\n context.globalAlpha = 1\n }\n if (box.line && lineWidth) {\n context.strokeStyle = box.line.color\n context.lineWidth = lineWidth\n if (box.line.dash) context.setLineDash([lineWidth * 3, lineWidth * 2])\n outline(context, box, w, h)\n context.stroke()\n context.setLineDash([])\n }\n\n // The text: each paragraph wrapped to the box (inside its inset), placed by its anchor.\n const inset = pointsToStage(box.inset ?? DEFAULT_INSET) * width\n const room = w - 2 * inset\n context.textBaseline = 'alphabetic'\n const lines: {\n pieces: Piece[]\n size: number\n align: string\n indent: number\n bullet?: TextRun\n }[] = []\n for (const paragraph of box.paragraphs) {\n const size = pointsToStage(paragraph.runs[0]?.size ?? DEFAULT_TEXT_SIZE) * width\n const indent = (paragraph.level ?? 0) * 0.5 * size + (paragraph.bullet ? size * 0.9 : 0)\n const words: Piece[] = []\n for (const run of paragraph.runs) {\n context.font = fontOf(run, themeFont, width)\n for (const part of run.text.split(/(\\s+)/).filter(Boolean)) {\n words.push({ text: part, run, width: context.measureText(part).width })\n }\n }\n let line: Piece[] = []\n let used = 0\n let first = true\n const flush = () => {\n lines.push({\n pieces: line,\n size,\n align: paragraph.align ?? 'left',\n indent,\n ...(first && paragraph.bullet ? { bullet: paragraph.runs[0] } : {}),\n })\n first = false\n line = []\n used = 0\n }\n for (const word of words) {\n if (used + word.width > room - indent && line.length && word.text.trim()) flush()\n if (!line.length && !word.text.trim()) continue\n line.push(word)\n used += word.width\n }\n flush()\n }\n const total = lines.reduce((sum, line) => sum + line.size * LINE_HEIGHT, 0)\n const free = h - 2 * inset - total\n let y = inset + (box.anchor === 'middle' ? free / 2 : box.anchor === 'bottom' ? free : 0)\n context.save()\n context.beginPath()\n context.rect(0, 0, w, h)\n context.clip()\n for (const line of lines) {\n const lineWidth = line.pieces.reduce((sum, piece) => sum + piece.width, 0)\n const space = room - line.indent\n let x =\n inset +\n line.indent +\n (line.align === 'center'\n ? (space - lineWidth) / 2\n : line.align === 'right'\n ? space - lineWidth\n : 0)\n const baseline = y + line.size * (LINE_HEIGHT - 0.2)\n if (line.bullet) {\n context.font = fontOf(line.bullet, themeFont, width)\n context.fillStyle = line.bullet.color ?? TEXT_COLORS.body\n context.fillText('\u2022', inset + line.indent - line.size * 0.9, baseline)\n }\n for (const piece of line.pieces) {\n context.font = fontOf(piece.run, themeFont, width)\n context.fillStyle = piece.run.color ?? TEXT_COLORS.body\n context.fillText(piece.text, x, baseline)\n if (piece.run.underline) {\n context.fillRect(x, baseline + line.size * 0.08, piece.width, Math.max(1, line.size * 0.05))\n }\n x += piece.width\n }\n y += line.size * LINE_HEIGHT\n }\n context.restore()\n context.restore()\n}\n\n/** The words a box shows, for a searchable PDF. */\nexport const boxWords = (box: SlideBox): string[] =>\n box.paragraphs\n .map((paragraph) =>\n paragraph.runs\n .map((run) => run.text)\n .join('')\n .trim()\n )\n .filter(Boolean)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["lineWidth"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A slide's text boxes and shapes as PowerPoint's own: editable text (each run's type, colour and
|
|
3
|
+
* weight, each paragraph's alignment, level and bullet) in a shape with its fill and outline, so a
|
|
4
|
+
* deck imported from PowerPoint goes back to PowerPoint as it came.
|
|
5
|
+
*/
|
|
6
|
+
import type PptxGenJS from 'pptxgenjs';
|
|
7
|
+
import { type SlideBox } from './boxes';
|
|
8
|
+
type Slide = ReturnType<PptxGenJS['addSlide']>;
|
|
9
|
+
export declare function addBox(pptx: PptxGenJS, page: Slide, box: SlideBox, themeFont: string): void;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { DEFAULT_INSET, DEFAULT_TEXT_SIZE } from "./boxes.js";
|
|
3
|
+
import { TEXT_COLORS } from "./theme.js";
|
|
4
|
+
const SLIDE_INCHES = { w: 13.333, h: 7.5 };
|
|
5
|
+
const hex = (color) => color.replace("#", "").toUpperCase();
|
|
6
|
+
function addBox(pptx, page, box, themeFont) {
|
|
7
|
+
const { frame } = box;
|
|
8
|
+
const place = {
|
|
9
|
+
x: frame.x * SLIDE_INCHES.w,
|
|
10
|
+
y: frame.y * SLIDE_INCHES.h,
|
|
11
|
+
w: Math.max(0.01, frame.w * SLIDE_INCHES.w),
|
|
12
|
+
h: frame.h * SLIDE_INCHES.h,
|
|
13
|
+
...box.rotation ? { rotate: box.rotation } : {},
|
|
14
|
+
...box.flipH ? { flipH: true } : {},
|
|
15
|
+
...box.flipV ? { flipV: true } : {}
|
|
16
|
+
};
|
|
17
|
+
const line = box.line ? {
|
|
18
|
+
color: hex(box.line.color),
|
|
19
|
+
width: box.line.width,
|
|
20
|
+
...box.line.dash ? { dashType: "dash" } : {}
|
|
21
|
+
} : void 0;
|
|
22
|
+
if (box.shape === "line") {
|
|
23
|
+
page.addShape(pptx.ShapeType.line, {
|
|
24
|
+
...place,
|
|
25
|
+
line: line ?? { color: hex(TEXT_COLORS.body), width: 1 }
|
|
26
|
+
});
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const shape = box.shape === "ellipse" ? pptx.ShapeType.ellipse : box.shape === "roundRect" ? pptx.ShapeType.roundRect : pptx.ShapeType.rect;
|
|
30
|
+
const fill = box.fill ? {
|
|
31
|
+
color: hex(box.fill),
|
|
32
|
+
...box.fillAlpha !== void 0 ? { transparency: Math.round((1 - box.fillAlpha) * 100) } : {}
|
|
33
|
+
} : void 0;
|
|
34
|
+
const runs = [];
|
|
35
|
+
box.paragraphs.forEach((paragraph, p) => {
|
|
36
|
+
const last = p === box.paragraphs.length - 1;
|
|
37
|
+
const paragraphRuns = paragraph.runs.length ? paragraph.runs : [{ text: "" }];
|
|
38
|
+
paragraphRuns.forEach((run, r) => {
|
|
39
|
+
runs.push({
|
|
40
|
+
text: run.text,
|
|
41
|
+
options: {
|
|
42
|
+
fontSize: run.size ?? DEFAULT_TEXT_SIZE,
|
|
43
|
+
fontFace: run.font ?? themeFont,
|
|
44
|
+
color: hex(run.color ?? TEXT_COLORS.body),
|
|
45
|
+
...run.bold ? { bold: true } : {},
|
|
46
|
+
...run.italic ? { italic: true } : {},
|
|
47
|
+
...run.underline ? { underline: { style: "sng" } } : {},
|
|
48
|
+
align: paragraph.align ?? "left",
|
|
49
|
+
...paragraph.level ? { indentLevel: paragraph.level } : {},
|
|
50
|
+
...paragraph.bullet && r === 0 ? { bullet: true } : {},
|
|
51
|
+
...r === paragraphRuns.length - 1 && !last ? { breakLine: true } : {}
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
const text = runs.some((run) => run.text);
|
|
57
|
+
if (!text && box.shape === "text") return;
|
|
58
|
+
page.addText(text ? runs : "", {
|
|
59
|
+
...place,
|
|
60
|
+
shape,
|
|
61
|
+
...fill ? { fill } : {},
|
|
62
|
+
...line ? { line } : {},
|
|
63
|
+
// Its part in the slide (its title, its body), kept by name: read back when imported.
|
|
64
|
+
...box.role ? { objectName: `ARBI ${box.role}` } : {},
|
|
65
|
+
valign: box.anchor ?? "top",
|
|
66
|
+
margin: box.inset ?? DEFAULT_INSET,
|
|
67
|
+
lineSpacingMultiple: 1,
|
|
68
|
+
fit: "none"
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
export {
|
|
72
|
+
addBox
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=export-boxes.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/presentation/export-boxes.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * A slide's text boxes and shapes as PowerPoint's own: editable text (each run's type, colour and\n * weight, each paragraph's alignment, level and bullet) in a shape with its fill and outline, so a\n * deck imported from PowerPoint goes back to PowerPoint as it came.\n */\n\nimport type PptxGenJS from 'pptxgenjs'\nimport { DEFAULT_INSET, DEFAULT_TEXT_SIZE, type SlideBox } from './boxes'\nimport { TEXT_COLORS } from './theme'\n\n/** PowerPoint's widescreen slide, in inches. */\nconst SLIDE_INCHES = { w: 13.333, h: 7.5 }\nconst hex = (color: string) => color.replace('#', '').toUpperCase()\n\ntype Slide = ReturnType<PptxGenJS['addSlide']>\n\nexport function addBox(pptx: PptxGenJS, page: Slide, box: SlideBox, themeFont: string): void {\n const { frame } = box\n const place = {\n x: frame.x * SLIDE_INCHES.w,\n y: frame.y * SLIDE_INCHES.h,\n w: Math.max(0.01, frame.w * SLIDE_INCHES.w),\n h: frame.h * SLIDE_INCHES.h,\n ...(box.rotation ? { rotate: box.rotation } : {}),\n ...(box.flipH ? { flipH: true } : {}),\n ...(box.flipV ? { flipV: true } : {}),\n }\n const line = box.line\n ? {\n color: hex(box.line.color),\n width: box.line.width,\n ...(box.line.dash ? { dashType: 'dash' as const } : {}),\n }\n : undefined\n if (box.shape === 'line') {\n page.addShape(pptx.ShapeType.line, {\n ...place,\n line: line ?? { color: hex(TEXT_COLORS.body), width: 1 },\n })\n return\n }\n const shape =\n box.shape === 'ellipse'\n ? pptx.ShapeType.ellipse\n : box.shape === 'roundRect'\n ? pptx.ShapeType.roundRect\n : pptx.ShapeType.rect\n const fill = box.fill\n ? {\n color: hex(box.fill),\n ...(box.fillAlpha !== undefined\n ? { transparency: Math.round((1 - box.fillAlpha) * 100) }\n : {}),\n }\n : undefined\n const runs: PptxGenJS.TextProps[] = []\n box.paragraphs.forEach((paragraph, p) => {\n const last = p === box.paragraphs.length - 1\n const paragraphRuns = paragraph.runs.length ? paragraph.runs : [{ text: '' }]\n paragraphRuns.forEach((run, r) => {\n runs.push({\n text: run.text,\n options: {\n fontSize: run.size ?? DEFAULT_TEXT_SIZE,\n fontFace: run.font ?? themeFont,\n color: hex(run.color ?? TEXT_COLORS.body),\n ...(run.bold ? { bold: true } : {}),\n ...(run.italic ? { italic: true } : {}),\n ...(run.underline ? { underline: { style: 'sng' as const } } : {}),\n align: paragraph.align ?? 'left',\n ...(paragraph.level ? { indentLevel: paragraph.level } : {}),\n ...(paragraph.bullet && r === 0 ? { bullet: true } : {}),\n ...(r === paragraphRuns.length - 1 && !last ? { breakLine: true } : {}),\n },\n })\n })\n })\n const text = runs.some((run) => run.text)\n if (!text && box.shape === 'text') return\n page.addText(text ? runs : '', {\n ...place,\n shape,\n ...(fill ? { fill } : {}),\n ...(line ? { line } : {}),\n // Its part in the slide (its title, its body), kept by name: read back when imported.\n ...(box.role ? { objectName: `ARBI ${box.role}` } : {}),\n valign: box.anchor ?? 'top',\n margin: box.inset ?? DEFAULT_INSET,\n lineSpacingMultiple: 1,\n fit: 'none',\n })\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The presentation as a PowerPoint deck (.pptx), drawn from the same geometry as the stage and the
|
|
3
|
+
* saved PDF: each slide's themed background (an image, painted as the PDF's is), its title, rule
|
|
4
|
+
* and points as real, editable PowerPoint text in the theme's typeface, each clip as an image
|
|
5
|
+
* (redactions burnt in, at 1.5× the size it is shown, so it stays sharp on a projector) with its
|
|
6
|
+
* label, and the logo. PptxGenJS is loaded only when a deck is exported.
|
|
7
|
+
*/
|
|
8
|
+
import { type Clip, type Slide } from './model';
|
|
9
|
+
import { type SlideLook } from './render-slides';
|
|
10
|
+
export interface DeckContent {
|
|
11
|
+
title: string;
|
|
12
|
+
slides: readonly Slide[];
|
|
13
|
+
clips: readonly Clip[];
|
|
14
|
+
}
|
|
15
|
+
/** The deck as a .pptx file. */
|
|
16
|
+
export declare function buildPptx(deck: DeckContent, look: SlideLook): Promise<Blob>;
|