@arbidocs/blocks 0.4.147 → 0.4.151

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 (339) hide show
  1. package/dist/ConnectedNativeDocxComparison-OFPIXNJB.js +35 -0
  2. package/dist/ConnectedNativeDocxComparison-OFPIXNJB.js.map +1 -0
  3. package/dist/ConnectedNativeDocxComparison-Y5BNLNH6.cjs +44 -0
  4. package/dist/ConnectedNativeDocxComparison-Y5BNLNH6.cjs.map +1 -0
  5. package/dist/ConnectedNativeDocxEditor-HTEW5JAH.cjs +46 -0
  6. package/dist/ConnectedNativeDocxEditor-HTEW5JAH.cjs.map +1 -0
  7. package/dist/ConnectedNativeDocxEditor-LRYU5HPA.js +33 -0
  8. package/dist/ConnectedNativeDocxEditor-LRYU5HPA.js.map +1 -0
  9. package/dist/ConnectedStreamedWordArtifact-QAUVUCSX.js +35 -0
  10. package/dist/ConnectedStreamedWordArtifact-QAUVUCSX.js.map +1 -0
  11. package/dist/ConnectedStreamedWordArtifact-QW74LKHN.cjs +44 -0
  12. package/dist/ConnectedStreamedWordArtifact-QW74LKHN.cjs.map +1 -0
  13. package/dist/FactTextEditor-YESAU2IJ.js +25 -0
  14. package/dist/FactTextEditor-YESAU2IJ.js.map +1 -0
  15. package/dist/FactTextEditor-YUPBCTXK.cjs +27 -0
  16. package/dist/FactTextEditor-YUPBCTXK.cjs.map +1 -0
  17. package/dist/{NativeDocxEditor-BE2OEOTJ.cjs → NativeDocxEditor-5VBNM5I7.cjs} +8 -8
  18. package/dist/{NativeDocxEditor-BE2OEOTJ.cjs.map → NativeDocxEditor-5VBNM5I7.cjs.map} +1 -1
  19. package/dist/{NativeDocxEditor-KOPFMRYW.js → NativeDocxEditor-XT5ZLFGU.js} +4 -4
  20. package/dist/{NativeDocxEditor-KOPFMRYW.js.map → NativeDocxEditor-XT5ZLFGU.js.map} +1 -1
  21. package/dist/agents/index.cjs +263 -264
  22. package/dist/agents/index.js +6 -7
  23. package/dist/calendar/index.cjs +117 -125
  24. package/dist/calendar/index.d.ts +0 -1
  25. package/dist/calendar/index.js +1 -1
  26. package/dist/chat/index.cjs +78 -78
  27. package/dist/chat/index.js +3 -3
  28. package/dist/{chunk-2FL7QJKJ.js → chunk-265GOG4W.js} +3 -3
  29. package/dist/{chunk-2FL7QJKJ.js.map → chunk-265GOG4W.js.map} +1 -1
  30. package/dist/{chunk-LTU35TQN.cjs → chunk-2FLWPM3B.cjs} +636 -31
  31. package/dist/chunk-2FLWPM3B.cjs.map +1 -0
  32. package/dist/{chunk-SUUPR735.js → chunk-3PCBYOIZ.js} +4 -4
  33. package/dist/{chunk-SUUPR735.js.map → chunk-3PCBYOIZ.js.map} +1 -1
  34. package/dist/{chunk-WIZ7Z7FN.js → chunk-4236BRZK.js} +46 -221
  35. package/dist/chunk-4236BRZK.js.map +1 -0
  36. package/dist/{chunk-IL3WB3YX.cjs → chunk-4JNKXOFZ.cjs} +3 -3
  37. package/dist/{chunk-IL3WB3YX.cjs.map → chunk-4JNKXOFZ.cjs.map} +1 -1
  38. package/dist/{chunk-ODRHHWHY.cjs → chunk-4KMLM3GY.cjs} +4 -4
  39. package/dist/chunk-4KMLM3GY.cjs.map +1 -0
  40. package/dist/chunk-6I6CVX5G.cjs +22 -0
  41. package/dist/chunk-6I6CVX5G.cjs.map +1 -0
  42. package/dist/{chunk-MHFF5N65.cjs → chunk-757OYF6G.cjs} +4 -38
  43. package/dist/chunk-757OYF6G.cjs.map +1 -0
  44. package/dist/chunk-B3FMUFAW.cjs +1956 -0
  45. package/dist/chunk-B3FMUFAW.cjs.map +1 -0
  46. package/dist/{chunk-B3AHCIV5.js → chunk-BJ24VPOA.js} +4 -55
  47. package/dist/chunk-BJ24VPOA.js.map +1 -0
  48. package/dist/chunk-C7PTF6BQ.cjs +172 -0
  49. package/dist/chunk-C7PTF6BQ.cjs.map +1 -0
  50. package/dist/{chunk-LZRMXJIE.js → chunk-COA3S3CZ.js} +3 -3
  51. package/dist/{chunk-LZRMXJIE.js.map → chunk-COA3S3CZ.js.map} +1 -1
  52. package/dist/{chunk-VUR63NMQ.js → chunk-CROTH2BS.js} +6 -6
  53. package/dist/{chunk-VUR63NMQ.js.map → chunk-CROTH2BS.js.map} +1 -1
  54. package/dist/{chunk-AO7SK6WP.cjs → chunk-CU2O32Z4.cjs} +31 -31
  55. package/dist/{chunk-AO7SK6WP.cjs.map → chunk-CU2O32Z4.cjs.map} +1 -1
  56. package/dist/chunk-D3WFIFRY.cjs +659 -0
  57. package/dist/chunk-D3WFIFRY.cjs.map +1 -0
  58. package/dist/{chunk-DAHCRVPM.js → chunk-DB2OXRQC.js} +84 -82
  59. package/dist/chunk-DB2OXRQC.js.map +1 -0
  60. package/dist/{chunk-QXMR5YHC.js → chunk-DIB4JYUY.js} +19 -3
  61. package/dist/chunk-DIB4JYUY.js.map +1 -0
  62. package/dist/chunk-DVB5ZKOF.js +22 -0
  63. package/dist/chunk-DVB5ZKOF.js.map +1 -0
  64. package/dist/chunk-EYJMMGXF.js +19 -0
  65. package/dist/chunk-EYJMMGXF.js.map +1 -0
  66. package/dist/chunk-FAXXN7KI.cjs +213 -0
  67. package/dist/chunk-FAXXN7KI.cjs.map +1 -0
  68. package/dist/{chunk-2MJWWPHY.js → chunk-G4IYES7G.js} +140 -15
  69. package/dist/chunk-G4IYES7G.js.map +1 -0
  70. package/dist/{chunk-T5I4NRFP.cjs → chunk-GFOEWPAP.cjs} +8 -8
  71. package/dist/{chunk-T5I4NRFP.cjs.map → chunk-GFOEWPAP.cjs.map} +1 -1
  72. package/dist/{chunk-QI6AIHWP.cjs → chunk-GOWXP5KT.cjs} +145 -14
  73. package/dist/chunk-GOWXP5KT.cjs.map +1 -0
  74. package/dist/chunk-HALD6ZB5.cjs +18 -0
  75. package/dist/chunk-HALD6ZB5.cjs.map +1 -0
  76. package/dist/chunk-HUJF2XM2.js +6584 -0
  77. package/dist/chunk-HUJF2XM2.js.map +1 -0
  78. package/dist/{chunk-NRFAWUVD.js → chunk-JAANWQGB.js} +157 -157
  79. package/dist/chunk-JAANWQGB.js.map +1 -0
  80. package/dist/{chunk-7RJTEWYM.js → chunk-JGOST4IL.js} +350 -64
  81. package/dist/chunk-JGOST4IL.js.map +1 -0
  82. package/dist/chunk-KHXEIEXN.js +41 -0
  83. package/dist/chunk-KHXEIEXN.js.map +1 -0
  84. package/dist/chunk-KQYPP72K.js +644 -0
  85. package/dist/chunk-KQYPP72K.js.map +1 -0
  86. package/dist/chunk-KUT2Y7JF.cjs +43 -0
  87. package/dist/chunk-KUT2Y7JF.cjs.map +1 -0
  88. package/dist/{chunk-6YTHQ73P.cjs → chunk-LLYZGH3L.cjs} +3 -56
  89. package/dist/chunk-LLYZGH3L.cjs.map +1 -0
  90. package/dist/{chunk-YSHIC4NJ.cjs → chunk-LXTOOUEN.cjs} +159 -154
  91. package/dist/chunk-LXTOOUEN.cjs.map +1 -0
  92. package/dist/{chunk-EVUEIBNU.js → chunk-M4S75AEJ.js} +44 -5
  93. package/dist/chunk-M4S75AEJ.js.map +1 -0
  94. package/dist/{chunk-V5OAXIBN.cjs → chunk-NPR5BGFF.cjs} +11 -11
  95. package/dist/{chunk-V5OAXIBN.cjs.map → chunk-NPR5BGFF.cjs.map} +1 -1
  96. package/dist/{chunk-PLJ7PHWU.cjs → chunk-NS7NVX4E.cjs} +3 -3
  97. package/dist/{chunk-PLJ7PHWU.cjs.map → chunk-NS7NVX4E.cjs.map} +1 -1
  98. package/dist/{chunk-AINU3EJ6.cjs → chunk-Q4BY2CQQ.cjs} +92 -90
  99. package/dist/chunk-Q4BY2CQQ.cjs.map +1 -0
  100. package/dist/chunk-QN47Q4N7.js +16 -0
  101. package/dist/chunk-QN47Q4N7.js.map +1 -0
  102. package/dist/{chunk-I2QSDQQV.cjs → chunk-QT3A4PFC.cjs} +21 -2
  103. package/dist/chunk-QT3A4PFC.cjs.map +1 -0
  104. package/dist/{chunk-ZM26YEOT.js → chunk-RY2SODRN.js} +3 -3
  105. package/dist/{chunk-ZM26YEOT.js.map → chunk-RY2SODRN.js.map} +1 -1
  106. package/dist/chunk-SDOEHEJP.js +208 -0
  107. package/dist/chunk-SDOEHEJP.js.map +1 -0
  108. package/dist/{chunk-DETZZBG2.cjs → chunk-SIB6C7P7.cjs} +43 -2
  109. package/dist/chunk-SIB6C7P7.cjs.map +1 -0
  110. package/dist/{chunk-MFY2ZNP6.cjs → chunk-SMN32BQ3.cjs} +4 -4
  111. package/dist/chunk-SMN32BQ3.cjs.map +1 -0
  112. package/dist/chunk-T74Q3MCZ.cjs +6751 -0
  113. package/dist/chunk-T74Q3MCZ.cjs.map +1 -0
  114. package/dist/{chunk-AOSUHWIL.js → chunk-TZOQKV64.js} +4 -37
  115. package/dist/chunk-TZOQKV64.js.map +1 -0
  116. package/dist/{chunk-U37AYUPI.cjs → chunk-U6JQ4KMX.cjs} +46 -233
  117. package/dist/chunk-U6JQ4KMX.cjs.map +1 -0
  118. package/dist/chunk-WFA2GVZJ.js +16 -0
  119. package/dist/chunk-WFA2GVZJ.js.map +1 -0
  120. package/dist/chunk-WU34CHU5.js +1907 -0
  121. package/dist/chunk-WU34CHU5.js.map +1 -0
  122. package/dist/{chunk-O4YPVYPO.cjs → chunk-YAEXSCUW.cjs} +364 -60
  123. package/dist/chunk-YAEXSCUW.cjs.map +1 -0
  124. package/dist/{chunk-H74HEPKT.js → chunk-YXNNNP57.js} +598 -13
  125. package/dist/chunk-YXNNNP57.js.map +1 -0
  126. package/dist/chunk-Z27QMJ6S.cjs +25 -0
  127. package/dist/chunk-Z27QMJ6S.cjs.map +1 -0
  128. package/dist/{chunk-CSI2B2H5.js → chunk-Z4NQ3TED.js} +4 -4
  129. package/dist/chunk-Z4NQ3TED.js.map +1 -0
  130. package/dist/{chunk-DGV7HQA7.js → chunk-ZLEYLCE4.js} +4 -4
  131. package/dist/chunk-ZLEYLCE4.js.map +1 -0
  132. package/dist/chunk-ZNLTEZEF.js +170 -0
  133. package/dist/chunk-ZNLTEZEF.js.map +1 -0
  134. package/dist/chunk-ZP6Q3KXU.cjs +18 -0
  135. package/dist/chunk-ZP6Q3KXU.cjs.map +1 -0
  136. package/dist/citations/index.cjs +14 -14
  137. package/dist/citations/index.js +2 -2
  138. package/dist/collaboration/index.cjs +35 -35
  139. package/dist/collaboration/index.js +1 -1
  140. package/dist/connect/docx.cjs +21 -26
  141. package/dist/connect/docx.cjs.map +1 -1
  142. package/dist/connect/docx.js +10 -26
  143. package/dist/connect/docx.js.map +1 -1
  144. package/dist/connect/index.cjs +8662 -2824
  145. package/dist/connect/index.cjs.map +1 -1
  146. package/dist/connect/index.d.ts +10 -2
  147. package/dist/connect/index.js +8467 -2670
  148. package/dist/connect/index.js.map +1 -1
  149. package/dist/connect/viewer.cjs +2357 -0
  150. package/dist/connect/viewer.cjs.map +1 -0
  151. package/dist/connect/viewer.d.ts +8 -0
  152. package/dist/connect/viewer.js +2350 -0
  153. package/dist/connect/viewer.js.map +1 -0
  154. package/dist/connection/ConnectedWorkflowsTable.d.ts +2 -12
  155. package/dist/connection/ai.d.ts +2 -9
  156. package/dist/connection/billing/AddAddonDialog.d.ts +24 -0
  157. package/dist/connection/billing/BillingCard.d.ts +18 -0
  158. package/dist/connection/billing/BillingProjectEntity.d.ts +9 -0
  159. package/dist/connection/billing/ChangePlanDialog.d.ts +20 -0
  160. package/dist/connection/billing/ChangeProPlan.d.ts +20 -0
  161. package/dist/connection/billing/CheckoutTotal.d.ts +12 -0
  162. package/dist/connection/billing/DailyCapEditor.d.ts +4 -0
  163. package/dist/connection/billing/InvoicesModal.d.ts +6 -0
  164. package/dist/connection/billing/NewProjectFlow.d.ts +14 -0
  165. package/dist/connection/billing/PlanChangeLines.d.ts +13 -0
  166. package/dist/connection/billing/PlanSelector.d.ts +50 -0
  167. package/dist/connection/billing/ProjectBilling.d.ts +24 -0
  168. package/dist/connection/billing/ProjectDetail.d.ts +16 -0
  169. package/dist/connection/billing/ProjectUsageCard.d.ts +21 -0
  170. package/dist/connection/billing/ProjectUsageContent.d.ts +18 -0
  171. package/dist/connection/billing/ProjectsTable.d.ts +13 -0
  172. package/dist/connection/billing/ReduceAddonDialog.d.ts +18 -0
  173. package/dist/connection/billing/ReferralReward.d.ts +32 -0
  174. package/dist/connection/billing/SharedProjects.d.ts +13 -0
  175. package/dist/connection/billing/StripeCheckoutModal.d.ts +32 -0
  176. package/dist/connection/billing/SubscriptionPlans.d.ts +15 -0
  177. package/dist/connection/billing/SubscriptionStatus.d.ts +10 -0
  178. package/dist/connection/billing/addon-pricing.d.ts +97 -0
  179. package/dist/connection/billing/api-error.d.ts +6 -0
  180. package/dist/connection/billing/billing-country.d.ts +14 -0
  181. package/dist/connection/billing/billing-focus.d.ts +11 -0
  182. package/dist/connection/billing/index.d.ts +22 -0
  183. package/dist/connection/billing/plan-badge.d.ts +15 -0
  184. package/dist/connection/billing/plan-change-outcome.d.ts +15 -0
  185. package/dist/connection/billing/plan-constants.d.ts +29 -0
  186. package/dist/connection/billing/plan-pricing.d.ts +67 -0
  187. package/dist/connection/billing/quota-items.d.ts +33 -0
  188. package/dist/connection/billing/referral-reward.d.ts +28 -0
  189. package/dist/connection/billing/refusal-copy.d.ts +5 -0
  190. package/dist/connection/billing/reward-balance.d.ts +19 -0
  191. package/dist/connection/billing/support.d.ts +35 -0
  192. package/dist/connection/billing/tax-quote.d.ts +36 -0
  193. package/dist/connection/billing/useAddonPurchase.d.ts +32 -0
  194. package/dist/connection/billing/useAutoRefreshPendingProjects.d.ts +11 -0
  195. package/dist/connection/billing/useCheckoutQuote.d.ts +30 -0
  196. package/dist/connection/billing/useOpenBillingPortal.d.ts +12 -0
  197. package/dist/connection/calendar/CalendarSettingsDialog.d.ts +1 -1
  198. package/dist/connection/facts/ConnectedFactsPage.d.ts +50 -0
  199. package/dist/connection/facts/FactMarkdownEditor.d.ts +57 -0
  200. package/dist/connection/facts/FactSourcesPopover.d.ts +38 -0
  201. package/dist/connection/facts/FactTextEditor.d.ts +2 -0
  202. package/dist/connection/facts/factNouns.d.ts +4 -0
  203. package/dist/connection/facts/factPageColumns.d.ts +37 -0
  204. package/dist/connection/facts/types.d.ts +127 -0
  205. package/dist/connection/facts/useFactActions.d.ts +10 -0
  206. package/dist/connection/facts/useFactComposer.d.ts +54 -0
  207. package/dist/connection/facts/useFactFilters.d.ts +101 -0
  208. package/dist/connection/facts/useFactSelection.d.ts +82 -0
  209. package/dist/connection/facts/useFactsGrid.d.ts +87 -0
  210. package/dist/connection/facts/useFactsPageView.d.ts +4 -0
  211. package/dist/connection/mail/ConnectedMailComposer.d.ts +3 -1
  212. package/dist/connection/mail/ConnectedMailbox.d.ts +4 -2
  213. package/dist/connection/mail/MailComposerForm.d.ts +4 -2
  214. package/dist/connection/mail/MailRecipientInput.d.ts +14 -0
  215. package/dist/connection/mail/index.d.ts +1 -1
  216. package/dist/connection/mail/types.d.ts +10 -0
  217. package/dist/connection/search/ConnectedSearchPage.d.ts +64 -0
  218. package/dist/connection/search/SearchResultRows.d.ts +38 -0
  219. package/dist/connection/search/index.d.ts +2 -0
  220. package/dist/connection/tags/ConnectedTagTable.d.ts +108 -0
  221. package/dist/connection/tags/ConnectedTagsPage.d.ts +55 -0
  222. package/dist/connection/tags/DocTagPassages.d.ts +25 -0
  223. package/dist/connection/tags/GlossaryExport.d.ts +7 -0
  224. package/dist/connection/tags/TagCombineFilter.d.ts +14 -0
  225. package/dist/connection/tags/TagPlacement.d.ts +16 -0
  226. package/dist/connection/tags/TagsPageSections.d.ts +36 -0
  227. package/dist/connection/tags/tagCombine.d.ts +55 -0
  228. package/dist/connection/useConnectedWorkNotifications.d.ts +7 -24
  229. package/dist/connection/viewer/ConnectedDocumentToolsProvider.d.ts +11 -0
  230. package/dist/connection/viewer/ConnectedDocumentViewer.d.ts +21 -0
  231. package/dist/connection/viewer/FinaliseTranslationButton.d.ts +15 -0
  232. package/dist/connection/viewer/ViewerPdfPane.d.ts +46 -0
  233. package/dist/connection/viewer/parsed/ParsedPassage.d.ts +48 -0
  234. package/dist/connection/viewer/parsed/ParsedTextView.d.ts +17 -0
  235. package/dist/connection/viewer/parsed/PassageTagPanel.d.ts +18 -0
  236. package/dist/connection/viewer/parsed/citation-line.d.ts +17 -0
  237. package/dist/connection/viewer/parsed/document-tags.d.ts +8 -0
  238. package/dist/connection/viewer/parsed/useChunkTagging.d.ts +46 -0
  239. package/dist/connection/viewer/parsed/useCitationSelection.d.ts +27 -0
  240. package/dist/connection/viewer/parsed/useDocumentLabels.d.ts +38 -0
  241. package/dist/connection/viewer/parsed/useLazyPages.d.ts +18 -0
  242. package/dist/connection/viewer/parsed/usePageScrollSync.d.ts +17 -0
  243. package/dist/connection/viewer/parsed/usePassageCopy.d.ts +25 -0
  244. package/dist/connection/viewer/support.d.ts +97 -0
  245. package/dist/connection/viewer/useImageCrop.d.ts +13 -0
  246. package/dist/connection/viewer/useViewedDocument.d.ts +70 -0
  247. package/dist/connection/viewer/useViewerBlobs.d.ts +15 -0
  248. package/dist/connection/viewer/useViewerTabs.d.ts +18 -0
  249. package/dist/connection/viewer/useViewerVersions.d.ts +11 -0
  250. package/dist/connection/workspace-settings/useConnectedWorkspaceSettings.d.ts +6 -0
  251. package/dist/document-tools/index.cjs +59 -652
  252. package/dist/document-tools/index.cjs.map +1 -1
  253. package/dist/document-tools/index.js +2 -641
  254. package/dist/document-tools/index.js.map +1 -1
  255. package/dist/docx/index.cjs +48 -47
  256. package/dist/docx/index.js +4 -3
  257. package/dist/facts/FactsBulkBar.d.ts +6 -3
  258. package/dist/facts/cited-version-ref.d.ts +1 -0
  259. package/dist/facts/index.cjs +204 -1940
  260. package/dist/facts/index.cjs.map +1 -1
  261. package/dist/facts/index.d.ts +1 -0
  262. package/dist/facts/index.js +13 -1895
  263. package/dist/facts/index.js.map +1 -1
  264. package/dist/files/TagPassagePanel.d.ts +2 -1
  265. package/dist/files/ViewerChrome.d.ts +5 -4
  266. package/dist/files/ViewerControlBar.d.ts +12 -0
  267. package/dist/files/doc-labels.d.ts +35 -0
  268. package/dist/files/grid/FilterButton.d.ts +12 -0
  269. package/dist/files/grid/RowDensityControl.d.ts +18 -0
  270. package/dist/files/grid/row-density.d.ts +27 -0
  271. package/dist/files/index.cjs +778 -7099
  272. package/dist/files/index.cjs.map +1 -1
  273. package/dist/files/index.d.ts +5 -0
  274. package/dist/files/index.js +13 -6918
  275. package/dist/files/index.js.map +1 -1
  276. package/dist/index.cjs +993 -1209
  277. package/dist/index.cjs.map +1 -1
  278. package/dist/index.js +22 -355
  279. package/dist/index.js.map +1 -1
  280. package/dist/retrieval/SearchSnippet.d.ts +6 -0
  281. package/dist/retrieval/index.cjs +74 -41
  282. package/dist/retrieval/index.d.ts +2 -0
  283. package/dist/retrieval/index.js +2 -1
  284. package/dist/retrieval/search-results.d.ts +46 -0
  285. package/dist/settings/Billing.d.ts +0 -66
  286. package/dist/settings/SubscriptionParts.d.ts +1 -50
  287. package/dist/settings/index.cjs +166 -214
  288. package/dist/settings/index.d.ts +3 -2
  289. package/dist/settings/index.js +1 -1
  290. package/dist/settings/inverted-index-filter.d.ts +26 -0
  291. package/dist/studio/index.cjs +3 -3
  292. package/dist/studio/index.js +2 -2
  293. package/dist/tags/definitions.d.ts +10 -0
  294. package/dist/tags/index.d.ts +4 -1
  295. package/dist/tags/page/ExtractEntitiesDialog.d.ts +24 -0
  296. package/dist/tags/page/TagPicker.d.ts +16 -0
  297. package/dist/tags/page/tagsPageLabels.d.ts +36 -0
  298. package/dist/workflow-canvas/index.cjs +19 -20
  299. package/dist/workflow-canvas/index.cjs.map +1 -1
  300. package/dist/workflow-canvas/index.js +6 -7
  301. package/dist/workflow-canvas/index.js.map +1 -1
  302. package/node_modules/@arbidocs/coedit/package.json +1 -1
  303. package/package.json +13 -4
  304. package/dist/calendar/access-setup.d.ts +0 -8
  305. package/dist/chunk-2MJWWPHY.js.map +0 -1
  306. package/dist/chunk-3AFWGEDJ.cjs +0 -53
  307. package/dist/chunk-3AFWGEDJ.cjs.map +0 -1
  308. package/dist/chunk-6YTHQ73P.cjs.map +0 -1
  309. package/dist/chunk-7RJTEWYM.js.map +0 -1
  310. package/dist/chunk-AINU3EJ6.cjs.map +0 -1
  311. package/dist/chunk-AOSUHWIL.js.map +0 -1
  312. package/dist/chunk-B3AHCIV5.js.map +0 -1
  313. package/dist/chunk-CSI2B2H5.js.map +0 -1
  314. package/dist/chunk-DAHCRVPM.js.map +0 -1
  315. package/dist/chunk-DETZZBG2.cjs.map +0 -1
  316. package/dist/chunk-DGV7HQA7.js.map +0 -1
  317. package/dist/chunk-EVUEIBNU.js.map +0 -1
  318. package/dist/chunk-H74HEPKT.js.map +0 -1
  319. package/dist/chunk-I2QSDQQV.cjs.map +0 -1
  320. package/dist/chunk-J5CWKFSC.js +0 -170
  321. package/dist/chunk-J5CWKFSC.js.map +0 -1
  322. package/dist/chunk-LTU35TQN.cjs.map +0 -1
  323. package/dist/chunk-MFY2ZNP6.cjs.map +0 -1
  324. package/dist/chunk-MHFF5N65.cjs.map +0 -1
  325. package/dist/chunk-NRFAWUVD.js.map +0 -1
  326. package/dist/chunk-O4YPVYPO.cjs.map +0 -1
  327. package/dist/chunk-ODRHHWHY.cjs.map +0 -1
  328. package/dist/chunk-QI6AIHWP.cjs.map +0 -1
  329. package/dist/chunk-QXMR5YHC.js.map +0 -1
  330. package/dist/chunk-RFXJYIDV.js +0 -50
  331. package/dist/chunk-RFXJYIDV.js.map +0 -1
  332. package/dist/chunk-U37AYUPI.cjs.map +0 -1
  333. package/dist/chunk-WIZ7Z7FN.js.map +0 -1
  334. package/dist/chunk-XVUOMWMD.cjs +0 -177
  335. package/dist/chunk-XVUOMWMD.cjs.map +0 -1
  336. package/dist/chunk-YSHIC4NJ.cjs.map +0 -1
  337. package/dist/connection/ConnectedTagTable.d.ts +0 -32
  338. package/dist/connection/calendar/CopyField.d.ts +0 -9
  339. package/dist/connection/calendar/OpenAccessPanel.d.ts +0 -7
@@ -0,0 +1,2357 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var chunkT74Q3MCZ_cjs = require('../chunk-T74Q3MCZ.cjs');
5
+ var chunk6I6CVX5G_cjs = require('../chunk-6I6CVX5G.cjs');
6
+ require('../chunk-YAEXSCUW.cjs');
7
+ require('../chunk-223D4727.cjs');
8
+ var chunkGAYMJWTC_cjs = require('../chunk-GAYMJWTC.cjs');
9
+ var chunkGFNELPDP_cjs = require('../chunk-GFNELPDP.cjs');
10
+ var chunkD3WFIFRY_cjs = require('../chunk-D3WFIFRY.cjs');
11
+ require('../chunk-6MG62I5B.cjs');
12
+ var chunkUWIILWDI_cjs = require('../chunk-UWIILWDI.cjs');
13
+ var chunkJH6JTI76_cjs = require('../chunk-JH6JTI76.cjs');
14
+ require('../chunk-2WLXQGWC.cjs');
15
+ require('../chunk-COCGRJLA.cjs');
16
+ var chunkVLCY46K6_cjs = require('../chunk-VLCY46K6.cjs');
17
+ require('../chunk-FAXXN7KI.cjs');
18
+ require('../chunk-V46W7YLI.cjs');
19
+ var chunkLJJJ6CYH_cjs = require('../chunk-LJJJ6CYH.cjs');
20
+ require('../chunk-SIB6C7P7.cjs');
21
+ require('../chunk-DVUZTGVL.cjs');
22
+ require('../chunk-AHDJXIUB.cjs');
23
+ require('../chunk-DTROMMDX.cjs');
24
+ require('../chunk-V4ISCZJ7.cjs');
25
+ require('../chunk-2EI7NCUA.cjs');
26
+ require('../chunk-C2CWWEHO.cjs');
27
+ var chunk2YV7FBLO_cjs = require('../chunk-2YV7FBLO.cjs');
28
+ require('../chunk-VG24E4JJ.cjs');
29
+ require('../chunk-QVBZESYQ.cjs');
30
+ var chunk7RGLTF76_cjs = require('../chunk-7RGLTF76.cjs');
31
+ require('../chunk-5UHAWSEX.cjs');
32
+ require('../chunk-B6MVQCXW.cjs');
33
+ var chunkJKB7WT7L_cjs = require('../chunk-JKB7WT7L.cjs');
34
+ require('../chunk-32HW2Q33.cjs');
35
+ var chunkFX3K6LNZ_cjs = require('../chunk-FX3K6LNZ.cjs');
36
+ require('../chunk-PPCATBOY.cjs');
37
+ require('../chunk-MHVNT4J3.cjs');
38
+ var chunkLXTOOUEN_cjs = require('../chunk-LXTOOUEN.cjs');
39
+ var chunkKPZZ5FHE_cjs = require('../chunk-KPZZ5FHE.cjs');
40
+ require('../chunk-ULWRNGGE.cjs');
41
+ var chunkKDG6FER6_cjs = require('../chunk-KDG6FER6.cjs');
42
+ require('../chunk-DES3K4SD.cjs');
43
+ var React = require('react');
44
+ var lucideReact = require('lucide-react');
45
+ var react = require('@arbidocs/react');
46
+ var artifacts = require('@arbidocs/react/artifacts');
47
+ var documentTools = require('@arbidocs/react/document-tools');
48
+ var viewers = require('@arbidocs/react/viewers');
49
+ var ui = require('@arbidocs/react/ui');
50
+ var reactQuery = require('@tanstack/react-query');
51
+ var jsxRuntime = require('react/jsx-runtime');
52
+
53
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
54
+
55
+ var React__default = /*#__PURE__*/_interopDefault(React);
56
+
57
+ function ConnectedDocumentToolsProvider({ children }) {
58
+ const enclosing = documentTools.useOptionalDocumentTools();
59
+ return enclosing ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children }) : /* @__PURE__ */ jsxRuntime.jsx(OwnDocumentTools, { children });
60
+ }
61
+ function OwnDocumentTools({ children }) {
62
+ const arbi = react.useArbi();
63
+ const queryClient = reactQuery.useQueryClient();
64
+ const { user, ensureWorkspaceOpen } = chunkGFNELPDP_cjs.useConnectedWorkspace();
65
+ const { notify: environmentNotify, openDocument: openInHost } = chunkKPZZ5FHE_cjs.useBlocksEnvironment();
66
+ const client = arbi.isLoggedIn ? arbi.getClient().fetch : null;
67
+ const signer = React.useMemo(
68
+ () => user ? { name: user.name, email: user.email, externalId: user.externalId } : null,
69
+ [user]
70
+ );
71
+ const notify = React.useCallback(
72
+ (message, kind, options) => environmentNotify(message, kind, {
73
+ description: options?.description,
74
+ action: options?.action
75
+ }),
76
+ [environmentNotify]
77
+ );
78
+ const onDocumentsChanged = React.useCallback(
79
+ async (ids, change) => {
80
+ const refresh = [react.refreshDocuments(queryClient, arbi, ids)];
81
+ if (change === "signed" || change === "version")
82
+ for (const id of ids)
83
+ refresh.push(
84
+ queryClient.invalidateQueries({ queryKey: react.arbiQueryKeys.documentVersions(id) }),
85
+ queryClient.invalidateQueries({ queryKey: documentTools.documentBytesKey(id) })
86
+ );
87
+ await Promise.all(refresh);
88
+ },
89
+ [queryClient, arbi]
90
+ );
91
+ const uploadDocument = React.useCallback(
92
+ async (request) => {
93
+ if (!client) throw new Error("Sign in to save a copy.");
94
+ await ensureWorkspaceOpen();
95
+ return documentTools.clientUpload(client)(request);
96
+ },
97
+ [client, ensureWorkspaceOpen]
98
+ );
99
+ const openDocument = React.useCallback((ref) => openInHost(ref), [openInHost]);
100
+ if (!client) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
101
+ return /* @__PURE__ */ jsxRuntime.jsx(
102
+ documentTools.DocumentToolsProvider,
103
+ {
104
+ client,
105
+ user: signer,
106
+ notify,
107
+ openDocument,
108
+ onDocumentsChanged,
109
+ uploadDocument,
110
+ children
111
+ }
112
+ );
113
+ }
114
+ var isTranslationDraft = (doc) => !!doc?.derived_from?.some((d) => d.role === "translation") && !doc.derived_from.some((d) => d.role === "final");
115
+ function FinaliseTranslationButton({
116
+ document: document2,
117
+ isCompact
118
+ }) {
119
+ const finalise = react.useFinaliseTranslation();
120
+ const { openDocument } = documentTools.useDocumentTools();
121
+ const { notify } = chunkKPZZ5FHE_cjs.useBlocksEnvironment();
122
+ if (!document2 || !isTranslationDraft(document2)) return null;
123
+ const pending = finalise.isPending;
124
+ const onClick = async () => {
125
+ try {
126
+ const { document_ext_id: finalId } = await finalise.mutateAsync(document2.external_id);
127
+ notify("Saved the final PDF of this translation", "success");
128
+ openDocument?.(finalId);
129
+ } catch (error) {
130
+ const detail = error?.detail;
131
+ notify(
132
+ typeof detail === "string" ? detail : "The final PDF could not be saved. Try again.",
133
+ "error"
134
+ );
135
+ }
136
+ };
137
+ return /* @__PURE__ */ jsxRuntime.jsxs(
138
+ ui.Button,
139
+ {
140
+ type: "button",
141
+ variant: "outline",
142
+ size: isCompact ? "icon" : "sm",
143
+ title: "Finalise: save this translation as a new PDF, labelled Translation and linked to the original",
144
+ "aria-label": "Finalise",
145
+ "data-testid": "finalise-translation-button",
146
+ className: "pointer-coarse:min-h-11",
147
+ disabled: pending,
148
+ onClick: () => void onClick(),
149
+ children: [
150
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileCheck2, { className: "size-4" }),
151
+ !isCompact && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1", children: pending ? "Finalising\u2026" : "Finalise" })
152
+ ]
153
+ }
154
+ );
155
+ }
156
+ function useImageCrop(documentId, fileName, imageBlob) {
157
+ const { uploadDocument, onDocumentsChanged, openDocument } = documentTools.useDocumentTools();
158
+ const { notify } = chunkKPZZ5FHE_cjs.useBlocksEnvironment();
159
+ const [cropImageUrl, setCropImageUrl] = React.useState(null);
160
+ const handleOpenCrop = React.useCallback(() => {
161
+ if (!imageBlob) return;
162
+ setCropImageUrl(URL.createObjectURL(imageBlob));
163
+ }, [imageBlob]);
164
+ const closeCrop = React.useCallback(() => {
165
+ setCropImageUrl((url) => {
166
+ if (url) URL.revokeObjectURL(url);
167
+ return null;
168
+ });
169
+ }, []);
170
+ const handleCropComplete = React.useCallback(
171
+ async (result) => {
172
+ const baseName = (fileName || "image").replace(/\.[^.]+$/, "");
173
+ const file = new File([result.blob], `${baseName} (cropped).png`, { type: "image/png" });
174
+ try {
175
+ const response = await uploadDocument({
176
+ file,
177
+ query: { derived_from: [documentId], derived_role: "crop" }
178
+ });
179
+ const newDocId = response?.doc_ext_ids?.[0];
180
+ if (newDocId) {
181
+ await onDocumentsChanged?.([newDocId], "copy");
182
+ openDocument?.(newDocId);
183
+ }
184
+ notify("Cropped image saved", "success");
185
+ } catch {
186
+ notify("Failed to save the cropped image", "error");
187
+ } finally {
188
+ closeCrop();
189
+ }
190
+ },
191
+ [fileName, documentId, uploadDocument, onDocumentsChanged, openDocument, notify, closeCrop]
192
+ );
193
+ return { cropImageUrl, handleOpenCrop, closeCrop, handleCropComplete };
194
+ }
195
+ var DOCX_EXTENSIONS = /* @__PURE__ */ new Set([".docx", ".doc"]);
196
+ var XLSX_EXTENSIONS = /* @__PURE__ */ new Set([".xlsx", ".xls"]);
197
+ var EMAIL_EXTENSIONS = /* @__PURE__ */ new Set([".eml", ".msg"]);
198
+ function fileExtension(fileName) {
199
+ if (!fileName) return "";
200
+ return fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
201
+ }
202
+ function useViewedDocument(documentId) {
203
+ const support = chunk6I6CVX5G_cjs.useDocumentViewerSupport();
204
+ const [webmHasVideoTrack, setWebmHasVideoTrack] = React.useState(null);
205
+ React.useEffect(() => setWebmHasVideoTrack(null), [documentId]);
206
+ const streamingDoc = support.streamingDocuments?.[documentId];
207
+ const isStreaming = !!streamingDoc && !streamingDoc.isComplete;
208
+ const draftDoc = support.draftDocuments?.[documentId];
209
+ const isDraft = !!draftDoc;
210
+ const isCaptureDraft = draftDoc?.kind === "audio" || draftDoc?.kind === "photo" || draftDoc?.kind === "video";
211
+ const isTextDraft = draftDoc?.kind === "text";
212
+ const { workspaceId, live } = chunkGFNELPDP_cjs.useConnectedWorkspace();
213
+ const { data: record } = react.useDocument(documentId, {
214
+ enabled: live && !!workspaceId && !isStreaming && !isDraft,
215
+ // A new version (Save version, a signed copy) is processed before its PDF exists: keep
216
+ // re-reading until it is done, so the PDF tab and the signing tools come back on their own.
217
+ pollWhileProcessing: true
218
+ });
219
+ const documentData = record?.external_id === documentId ? record : void 0;
220
+ const { data: tags } = chunkGAYMJWTC_cjs.useConnectedTags();
221
+ const labelSummaries = React.useMemo(
222
+ () => chunkT74Q3MCZ_cjs.summariseDocTags(documentData?.doctags ?? [], tags.filter(chunkT74Q3MCZ_cjs.isDocumentLabel)),
223
+ [documentData, tags]
224
+ );
225
+ const fileName = documentData?.file_name;
226
+ const isMarkdown = fileExtension(fileName) === ".md";
227
+ const isImage = ui.isImageFile(fileName);
228
+ const isWebmFile = fileExtension(fileName) === ".webm";
229
+ const isVideo = isWebmFile && webmHasVideoTrack === false ? false : ui.isVideoFile(fileName);
230
+ const isAudio = isWebmFile && webmHasVideoTrack === false ? true : ui.isAudioFile(fileName);
231
+ const isBlobArtifact = streamingDoc?.mode === "image" || documentData?.wp_type === "artifact" && (isImage || isVideo || isAudio);
232
+ const isArtifact = (!!streamingDoc || isTextDraft || documentData?.wp_type === "artifact" || isMarkdown) && !isBlobArtifact;
233
+ const liveKind = isArtifact ? artifacts.artifactKindFromMode(streamingDoc?.mode ?? void 0) ?? artifacts.artifactKindFromFileName(fileName) : null;
234
+ const savedDocumentId = chunkJKB7WT7L_cjs.savedDocumentIdFor({
235
+ documentId,
236
+ isDraft,
237
+ isStreaming,
238
+ isBlobArtifact,
239
+ documentData
240
+ });
241
+ const { data: liveSourceFetched } = artifacts.useArtifactSource(
242
+ documentId,
243
+ !!liveKind && !streamingDoc && !!documentData && !isDraft
244
+ );
245
+ const liveSource = streamingDoc ? streamingDoc.content : liveSourceFetched ?? "";
246
+ const hasParsedDocStatus = documentData?.status === "completed" || documentData?.status === "low-content";
247
+ const { data: parsedDoc, isLoading: isParsedDocLoading } = react.useParsedDocument(
248
+ documentId,
249
+ "final",
250
+ {
251
+ enabled: !!documentId && live && !isStreaming && !isDraft && !isBlobArtifact && hasParsedDocStatus
252
+ }
253
+ );
254
+ const hasParsedContent = (parsedDoc?.chunks?.length ?? 0) > 0;
255
+ return {
256
+ workspaceId,
257
+ documentData,
258
+ streamingDoc,
259
+ isStreaming,
260
+ draftDoc,
261
+ isDraft,
262
+ isCaptureDraft,
263
+ isTextDraft,
264
+ labelSummaries,
265
+ isImage,
266
+ isWebmFile,
267
+ setWebmHasVideoTrack,
268
+ isVideo,
269
+ isAudio,
270
+ isMedia: isVideo || isAudio,
271
+ isBlobArtifact,
272
+ savedDocumentId,
273
+ isArtifact,
274
+ liveKind,
275
+ liveSource,
276
+ isDocx: DOCX_EXTENSIONS.has(fileExtension(fileName)),
277
+ isXlsx: XLSX_EXTENSIONS.has(fileExtension(fileName)),
278
+ isEmail: EMAIL_EXTENSIONS.has(fileExtension(fileName)),
279
+ isDownloadOnly: ui.isDownloadOnlyFile(fileName),
280
+ isParsedDocLoading,
281
+ hasParsedContent
282
+ };
283
+ }
284
+ function useViewerBlobs(documentId, doc) {
285
+ const { documentData, isArtifact, isDocx, isXlsx, isDownloadOnly, isWebmFile } = doc;
286
+ const { setWebmHasVideoTrack } = doc;
287
+ const { client, saveFile } = documentTools.useDocumentTools();
288
+ const { notify } = chunkKPZZ5FHE_cjs.useBlocksEnvironment();
289
+ const { loadOfflineCopy } = chunk6I6CVX5G_cjs.useDocumentViewerSupport();
290
+ const currentVersion = documentData?.current_version ?? 1;
291
+ const name = documentData?.file_name;
292
+ const original = ui.isImageFile(name) || ui.isVideoFile(name) || ui.isAudioFile(name);
293
+ const fallback = loadOfflineCopy && documentData && !artifacts.parseVersionRef(documentId).version ? () => loadOfflineCopy(documentData) : void 0;
294
+ const pdf = documentTools.useDocumentBytes(documentId, {
295
+ version: currentVersion,
296
+ kind: original ? "original" : "pdf",
297
+ enabled: !isArtifact && !!documentData && !isDownloadOnly && (!isDocx || documentData.status === "completed" || documentData.status === "low-content"),
298
+ fallback
299
+ });
300
+ const [pdfBlob, setPdfBlob] = React.useState(null);
301
+ React.useEffect(() => setPdfBlob(null), [documentId]);
302
+ React.useEffect(() => {
303
+ if (pdf.data) setPdfBlob(pdf.data);
304
+ }, [pdf.data]);
305
+ React.useEffect(() => {
306
+ if (!isWebmFile || !pdfBlob) return;
307
+ let cancelled = false;
308
+ void react.hasVideoTrack(pdfBlob).then((result) => {
309
+ if (!cancelled) setWebmHasVideoTrack(result);
310
+ });
311
+ return () => {
312
+ cancelled = true;
313
+ };
314
+ }, [isWebmFile, pdfBlob, setWebmHasVideoTrack]);
315
+ const xlsx = documentTools.useDocumentBytes(documentId, {
316
+ version: currentVersion,
317
+ kind: "original",
318
+ enabled: !isArtifact && !!documentData && isXlsx
319
+ });
320
+ const handleDirectDownload = React.useCallback(async () => {
321
+ try {
322
+ saveFile(await documentTools.fetchDocumentFile(client, documentId), documentData?.file_name || "download");
323
+ } catch {
324
+ notify("Failed to download file", "error");
325
+ }
326
+ }, [client, saveFile, notify, documentId, documentData?.file_name]);
327
+ return {
328
+ pdfBlob,
329
+ isPdfLoading: pdf.isLoading,
330
+ pdfError: pdf.error,
331
+ xlsxBlob: xlsx.data ?? null,
332
+ xlsxError: xlsx.error,
333
+ handleDirectDownload
334
+ };
335
+ }
336
+ function useViewerTabs(doc, isCompact, hasHistory = false) {
337
+ const {
338
+ documentData,
339
+ isArtifact,
340
+ isDocx,
341
+ isXlsx,
342
+ isEmail,
343
+ isVideo,
344
+ isAudio,
345
+ isImage,
346
+ liveKind,
347
+ hasParsedContent,
348
+ isParsedDocLoading
349
+ } = doc;
350
+ const session = react.useArbiSessionStore();
351
+ const {
352
+ tab: activeTab,
353
+ compareId,
354
+ tabRequest,
355
+ phonePdfChosen
356
+ } = react.useArbiSessionState((s) => s.documentViewer);
357
+ const setActiveTab = (tab) => session.setDocumentViewer({ tab });
358
+ const isTextFile = ui.friendlyFileType(documentData?.file_type, documentData?.file_name) === "Text";
359
+ const isPhone = chunkFX3K6LNZ_cjs.useIsPhone();
360
+ const phoneDefaultDecidedFor = React.useRef(null);
361
+ const hasDocumentData = !!documentData;
362
+ const documentKey = documentData?.external_id;
363
+ React.useEffect(() => {
364
+ if (isArtifact && (activeTab === "pdf" || !liveKind && activeTab === "docx")) {
365
+ setActiveTab(liveKind ? "preview" : "edit");
366
+ } else if (isDocx && activeTab === "pdf") {
367
+ setActiveTab("docx");
368
+ } else if (!liveKind && activeTab === "preview") {
369
+ setActiveTab(isArtifact ? "edit" : "pdf");
370
+ } else if (!isArtifact && documentData && activeTab === "edit") {
371
+ setActiveTab(isDocx ? "docx" : isXlsx ? "xlsx" : "pdf");
372
+ } else if (!isArtifact && !isDocx && !isXlsx && documentData && (activeTab === "docx" || activeTab === "xlsx")) {
373
+ setActiveTab("pdf");
374
+ }
375
+ }, [hasDocumentData, documentKey, isArtifact, isDocx, isXlsx, liveKind]);
376
+ React.useEffect(() => {
377
+ if (!tabRequest || !documentKey || tabRequest.documentId !== documentKey) return;
378
+ phoneDefaultDecidedFor.current = documentKey;
379
+ session.setDocumentViewer({ tabRequest: null, tab: tabRequest.tab });
380
+ }, [documentKey, tabRequest]);
381
+ const hasVersionsTab = isArtifact || isDocx || hasHistory;
382
+ React.useEffect(() => {
383
+ if (activeTab === "versions" && documentData && !hasVersionsTab) {
384
+ setActiveTab(isXlsx ? "xlsx" : "pdf");
385
+ }
386
+ }, [activeTab, documentData, hasVersionsTab]);
387
+ React.useEffect(() => {
388
+ if (activeTab === "html" && documentData !== void 0 && !isParsedDocLoading && !hasParsedContent && !compareId) {
389
+ setActiveTab(isArtifact ? "edit" : isDocx ? "docx" : isXlsx ? "xlsx" : "pdf");
390
+ }
391
+ }, [
392
+ activeTab,
393
+ documentData,
394
+ isParsedDocLoading,
395
+ hasParsedContent,
396
+ compareId,
397
+ isArtifact,
398
+ isDocx,
399
+ isXlsx
400
+ ]);
401
+ React.useEffect(() => {
402
+ if (!isPhone || !documentKey || isParsedDocLoading) return;
403
+ if (phoneDefaultDecidedFor.current === documentKey) return;
404
+ phoneDefaultDecidedFor.current = documentKey;
405
+ const opensOnPdf = !isArtifact && !isDocx && !isXlsx && !isVideo && !isAudio && !isImage && !isEmail;
406
+ if (opensOnPdf && hasParsedContent && !compareId && !phonePdfChosen && activeTab === "pdf") {
407
+ setActiveTab("html");
408
+ }
409
+ }, [isPhone, documentKey, isParsedDocLoading, hasParsedContent]);
410
+ const handleTabChange = (tabId) => {
411
+ const change = { tab: tabId };
412
+ if (tabId !== "html" && compareId) change.compareId = null;
413
+ if (isPhone && (tabId === "pdf" || tabId === "html")) change.phonePdfChosen = tabId === "pdf";
414
+ session.setDocumentViewer(change);
415
+ };
416
+ const mediaTab = isVideo ? { icon: /* @__PURE__ */ jsxRuntime.jsx(react.VidIcon, { size: 20 }), tooltip: "Video" } : isAudio ? { icon: /* @__PURE__ */ jsxRuntime.jsx(react.AudIcon, { size: 20 }), tooltip: "Audio" } : isImage ? { icon: /* @__PURE__ */ jsxRuntime.jsx(react.ImgIcon, { size: 20 }), tooltip: "Image" } : isEmail ? { icon: /* @__PURE__ */ jsxRuntime.jsx(react.EmlIcon, { size: 20 }), tooltip: "Email" } : isTextFile ? { icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "size-5" }), tooltip: "Text" } : documentData ? { icon: /* @__PURE__ */ jsxRuntime.jsx(react.PdfIcon, { size: 20 }), tooltip: "PDF" } : (
417
+ // The file type is unknown until the record loads: name no guess (a text file
418
+ // would flip from PDF to Text once it arrives).
419
+ { icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "size-5" }), tooltip: "Document" }
420
+ );
421
+ const tabLabel = (id, label) => !isCompact || activeTab === id || id === "html" ? label : void 0;
422
+ const versionsTab = {
423
+ id: "versions",
424
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "size-5" }),
425
+ tooltip: "Versions",
426
+ label: tabLabel("versions", "Versions")
427
+ };
428
+ const viewerTabs = [
429
+ ...isArtifact ? [
430
+ ...liveKind ? [
431
+ {
432
+ id: "preview",
433
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MonitorPlay, { className: "size-5" }),
434
+ tooltip: "Preview",
435
+ label: tabLabel("preview", "Preview")
436
+ }
437
+ ] : [],
438
+ {
439
+ id: "edit",
440
+ icon: liveKind ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Code, { className: "size-5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "size-5" }),
441
+ tooltip: liveKind ? "Code" : "Editor",
442
+ label: tabLabel("edit", liveKind ? "Code" : "Document")
443
+ },
444
+ versionsTab
445
+ ] : [
446
+ ...isDocx ? [
447
+ {
448
+ id: "docx",
449
+ icon: /* @__PURE__ */ jsxRuntime.jsx(react.DocIcon, { size: 20 }),
450
+ tooltip: "DOCX (with track changes & comments)",
451
+ label: tabLabel("docx", "DOCX")
452
+ }
453
+ ] : [],
454
+ ...isXlsx ? [
455
+ {
456
+ id: "xlsx",
457
+ icon: /* @__PURE__ */ jsxRuntime.jsx(react.XlsIcon, { size: 20 }),
458
+ tooltip: "Spreadsheet",
459
+ label: tabLabel("xlsx", "Sheet")
460
+ }
461
+ ] : [],
462
+ { id: "pdf", ...mediaTab, label: tabLabel("pdf", mediaTab.tooltip) },
463
+ ...hasVersionsTab ? [versionsTab] : []
464
+ ],
465
+ ...(hasParsedContent || compareId) && !liveKind ? [
466
+ {
467
+ id: "html",
468
+ icon: compareId ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "size-5" }) : /* @__PURE__ */ jsxRuntime.jsx(react.HtmlIcon, { size: 20 }),
469
+ tooltip: compareId ? "Word redline" : "HTML",
470
+ label: tabLabel("html", compareId ? "Compare" : "HTML")
471
+ }
472
+ ] : []
473
+ ];
474
+ return { activeTab, handleTabChange, viewerTabs };
475
+ }
476
+ function useViewerVersions(docId) {
477
+ const plainId = docId ? artifacts.parseVersionRef(docId).docId : "";
478
+ const { data: documents } = chunkGAYMJWTC_cjs.useConnectedDocuments();
479
+ const listed = React.useMemo(
480
+ () => plainId ? documents.find((d) => d.external_id === plainId) : void 0,
481
+ [documents, plainId]
482
+ );
483
+ const { data: history } = react.useDocumentVersionList(plainId, { enabled: !!plainId && !listed });
484
+ const versions = React.useMemo(
485
+ () => listed ? artifacts.documentVersions(listed) : artifacts.toArtifactVersions(plainId || null, history),
486
+ [listed, history, plainId]
487
+ );
488
+ const translations = React.useMemo(() => {
489
+ if (!plainId) return [];
490
+ return documents.flatMap((doc) => {
491
+ const link = doc.derived_from?.find(
492
+ (d) => d.role === "translation" && d.doc_ext_id === plainId
493
+ );
494
+ return link ? [
495
+ {
496
+ id: doc.external_id,
497
+ name: doc.doc_metadata?.title || doc.file_name || doc.external_id,
498
+ createdAt: doc.created_at,
499
+ sourceVersion: link.version ?? null,
500
+ final: !!doc.derived_from?.some((d) => d.role === "final")
501
+ }
502
+ ] : [];
503
+ }).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
504
+ }, [documents, plainId]);
505
+ return { versions, translations };
506
+ }
507
+
508
+ // src/connection/viewer/parsed/document-tags.ts
509
+ function isDocumentTag(tag) {
510
+ if (tag.kind === "search") return false;
511
+ const onDocs = (tag.doctag_count ?? 0) > 0;
512
+ const onFacts = (tag.facttag_count ?? 0) > 0;
513
+ return onDocs || !onFacts;
514
+ }
515
+ function hasChunkInCitations(citations, chunkExtId) {
516
+ return (citations ?? []).some((d) => d.chunks?.some((c) => c.chunk_id === chunkExtId));
517
+ }
518
+ function removeChunkFromCitations(citations, chunkExtId) {
519
+ if (!citations) return null;
520
+ const next = citations.map((d) => ({ ...d, chunks: (d.chunks ?? []).filter((c) => c.chunk_id !== chunkExtId) })).filter((d) => d.chunks.length > 0);
521
+ return next.length ? next : null;
522
+ }
523
+ function addChunkToCitations(citations, documentId, chunkExtId) {
524
+ const chunk = { chunk_id: chunkExtId, page: null };
525
+ const list = citations ?? [];
526
+ const idx = list.findIndex((d) => d.doc_ext_id === documentId);
527
+ if (idx === -1) return [...list, { doc_ext_id: documentId, chunks: [chunk] }];
528
+ const doc = list[idx];
529
+ if ((doc.chunks ?? []).some((c) => c.chunk_id === chunkExtId)) return list;
530
+ const next = [...list];
531
+ next[idx] = { ...doc, chunks: [...doc.chunks ?? [], chunk] };
532
+ return next;
533
+ }
534
+ function useChunkTagging({ documentId, documentDoctags }) {
535
+ const createDocTag = react.useAssignDocTags();
536
+ const updateDocTag = react.useUpdateDocTag();
537
+ const deleteDocTag = react.useRemoveDocTags();
538
+ const getChunkTagState = React.useCallback(
539
+ (chunkExtId) => {
540
+ const appliedTags = documentDoctags.filter(
541
+ (dt) => hasChunkInCitations(dt.citations, chunkExtId)
542
+ );
543
+ const isTagApplied = (tagExtId) => {
544
+ return appliedTags.some((dt) => dt.tag_ext_id === tagExtId);
545
+ };
546
+ const getDoctagForChunk = (tagExtId) => {
547
+ return appliedTags.find((dt) => dt.tag_ext_id === tagExtId);
548
+ };
549
+ return {
550
+ appliedTags,
551
+ isTagApplied,
552
+ getDoctagForChunk
553
+ };
554
+ },
555
+ [documentDoctags]
556
+ );
557
+ const toggleChunkTag = React.useCallback(
558
+ async (chunkExtId, tag, note) => {
559
+ const existingDoctag = documentDoctags.find((dt) => dt.tag_ext_id === tag.external_id);
560
+ const isChunkTagged = hasChunkInCitations(existingDoctag?.citations, chunkExtId);
561
+ if (isChunkTagged) {
562
+ const updatedCitations = removeChunkFromCitations(existingDoctag.citations, chunkExtId);
563
+ if (!updatedCitations) {
564
+ await deleteDocTag.mutateAsync({
565
+ tagId: tag.external_id,
566
+ docIds: [documentId]
567
+ });
568
+ } else {
569
+ await updateDocTag.mutateAsync({
570
+ tagId: tag.external_id,
571
+ docId: documentId,
572
+ citations: updatedCitations,
573
+ note: existingDoctag.note
574
+ });
575
+ }
576
+ } else {
577
+ if (existingDoctag) {
578
+ const updatedCitations = addChunkToCitations(
579
+ existingDoctag.citations,
580
+ documentId,
581
+ chunkExtId
582
+ );
583
+ await updateDocTag.mutateAsync({
584
+ tagId: tag.external_id,
585
+ docId: documentId,
586
+ citations: updatedCitations,
587
+ note: note ?? existingDoctag.note
588
+ });
589
+ } else {
590
+ const newCitations = addChunkToCitations(null, documentId, chunkExtId);
591
+ await createDocTag.mutateAsync({
592
+ tagId: tag.external_id,
593
+ docIds: [documentId],
594
+ citations: newCitations,
595
+ note
596
+ });
597
+ }
598
+ }
599
+ },
600
+ [documentId, documentDoctags, createDocTag, updateDocTag, deleteDocTag]
601
+ );
602
+ const updateChunkTagNote = React.useCallback(
603
+ async (_chunkExtId, tag, note) => {
604
+ const existingDoctag = documentDoctags.find((dt) => dt.tag_ext_id === tag.external_id);
605
+ if (!existingDoctag) return;
606
+ await updateDocTag.mutateAsync({
607
+ tagId: tag.external_id,
608
+ docId: documentId,
609
+ citations: existingDoctag.citations,
610
+ note
611
+ });
612
+ },
613
+ [documentId, documentDoctags, updateDocTag]
614
+ );
615
+ const getChunkTagColors = React.useCallback(
616
+ (chunkExtId, workspaceTags) => {
617
+ const { appliedTags } = getChunkTagState(chunkExtId);
618
+ return appliedTags.map((dt) => {
619
+ const tag = workspaceTags.find((t) => t.external_id === dt.tag_ext_id);
620
+ return tag?.external_id;
621
+ }).filter((id) => !!id);
622
+ },
623
+ [getChunkTagState]
624
+ );
625
+ const isLoading = createDocTag.isPending || updateDocTag.isPending || deleteDocTag.isPending;
626
+ return {
627
+ getChunkTagState,
628
+ toggleChunkTag,
629
+ updateChunkTagNote,
630
+ getChunkTagColors,
631
+ isLoading
632
+ };
633
+ }
634
+ var GROUP_TITLES = {
635
+ checkbox: "Label",
636
+ select: "Choice",
637
+ text: "Text",
638
+ number: "Number"
639
+ };
640
+ function PassageTagPanel({
641
+ documentId,
642
+ chunkExtId,
643
+ chunkContent,
644
+ pageNumber,
645
+ documentDoctags,
646
+ onClose,
647
+ onViewTaggedChunks
648
+ }) {
649
+ const { createTag } = chunk6I6CVX5G_cjs.useDocumentViewerSupport();
650
+ const [editingNoteTagId, setEditingNoteTagId] = React.useState(null);
651
+ const [noteValue, setNoteValue] = React.useState("");
652
+ const { data: allTags } = chunkGAYMJWTC_cjs.useConnectedTags();
653
+ const workspaceTags = React.useMemo(() => allTags.filter(isDocumentTag), [allTags]);
654
+ const { getChunkTagState, toggleChunkTag, updateChunkTagNote, isLoading } = useChunkTagging({
655
+ documentId,
656
+ documentDoctags
657
+ });
658
+ const chunkState = React.useMemo(() => getChunkTagState(chunkExtId), [getChunkTagState, chunkExtId]);
659
+ const groupedTags = React.useMemo(() => {
660
+ const groups2 = {
661
+ checkbox: [],
662
+ select: [],
663
+ text: [],
664
+ number: []
665
+ };
666
+ workspaceTags.forEach((tag) => {
667
+ const group = tag.kind === "label" ? "checkbox" : tag.kind === "annotation" ? tag.tag_type.type : null;
668
+ if (group && groups2[group]) {
669
+ groups2[group].push(tag);
670
+ }
671
+ });
672
+ return groups2;
673
+ }, [workspaceTags]);
674
+ const handleToggleTag = React.useCallback(
675
+ async (tag) => {
676
+ try {
677
+ await toggleChunkTag(chunkExtId, tag);
678
+ } catch (error) {
679
+ console.error("Failed to toggle chunk tag:", error);
680
+ }
681
+ },
682
+ [chunkExtId, toggleChunkTag]
683
+ );
684
+ const handleStartEditNote = React.useCallback(
685
+ (tagExtId) => {
686
+ const doctag = chunkState.getDoctagForChunk(tagExtId);
687
+ setNoteValue(doctag?.note || "");
688
+ setEditingNoteTagId(tagExtId);
689
+ },
690
+ [chunkState]
691
+ );
692
+ const handleSaveNote = React.useCallback(
693
+ async (tag) => {
694
+ try {
695
+ await updateChunkTagNote(chunkExtId, tag, noteValue || null);
696
+ } catch (error) {
697
+ console.error("Failed to save note:", error);
698
+ }
699
+ setEditingNoteTagId(null);
700
+ setNoteValue("");
701
+ },
702
+ [chunkExtId, noteValue, updateChunkTagNote]
703
+ );
704
+ const preview = React.useMemo(() => {
705
+ const maxLength = 200;
706
+ if (chunkContent.length <= maxLength) return chunkContent;
707
+ return chunkContent.slice(0, maxLength) + "...";
708
+ }, [chunkContent]);
709
+ const groups = React.useMemo(
710
+ () => Object.entries(groupedTags).filter(([, tags]) => tags.length > 0).map(([type, tags]) => ({
711
+ id: type,
712
+ title: GROUP_TITLES[type] ?? type,
713
+ tags: tags.map((tag) => ({
714
+ id: tag.external_id,
715
+ color: ui.getEntityColor(tag.external_id, "medium"),
716
+ isApplied: chunkState.isTagApplied(tag.external_id),
717
+ note: chunkState.getDoctagForChunk(tag.external_id)?.note,
718
+ badge: /* @__PURE__ */ jsxRuntime.jsx(ui.TagEntity, { tag, size: "sm", showTooltip: false })
719
+ }))
720
+ })),
721
+ [groupedTags, chunkState]
722
+ );
723
+ const tagById = React.useMemo(
724
+ () => new Map(workspaceTags.map((tag) => [tag.external_id, tag])),
725
+ [workspaceTags]
726
+ );
727
+ return /* @__PURE__ */ jsxRuntime.jsx(
728
+ chunkT74Q3MCZ_cjs.TagPassagePanel,
729
+ {
730
+ pageNumber,
731
+ preview,
732
+ groups,
733
+ isEmpty: workspaceTags.length === 0,
734
+ isBusy: isLoading,
735
+ editingNoteTagId,
736
+ noteValue,
737
+ onNoteChange: setNoteValue,
738
+ onToggle: (id) => {
739
+ const tag = tagById.get(id);
740
+ if (tag) void handleToggleTag(tag);
741
+ },
742
+ onViewTagged: onViewTaggedChunks,
743
+ onStartNote: handleStartEditNote,
744
+ onSaveNote: (id) => {
745
+ const tag = tagById.get(id);
746
+ if (tag) void handleSaveNote(tag);
747
+ },
748
+ onCancelNote: () => {
749
+ setEditingNoteTagId(null);
750
+ setNoteValue("");
751
+ },
752
+ onCreate: createTag,
753
+ onClose
754
+ }
755
+ );
756
+ }
757
+ var ParsedPassage = React.memo(function ParsedPassage2({
758
+ chunk,
759
+ pageNumber,
760
+ isHighlighted,
761
+ isSelected,
762
+ isCitationHighlight,
763
+ isActiveCitation,
764
+ factCitationActive,
765
+ isCitationMode,
766
+ runIsStart,
767
+ runIsEnd,
768
+ runEndIndex,
769
+ labels,
770
+ activeTagColor,
771
+ onTagPassage,
772
+ onShowLabel,
773
+ onRemoveLabel,
774
+ onChunkClick,
775
+ formatChunkWithCitation,
776
+ getPassageDeepLink,
777
+ copyToClipboard,
778
+ onOpenNavigator
779
+ }) {
780
+ const chunkId = chunk.chunkExtId;
781
+ const formattedContent = chunkId ? formatChunkWithCitation(chunk.content, pageNumber || void 0, chunkId) : "";
782
+ const isStrong = isActiveCitation || !factCitationActive && isSelected;
783
+ const isLight = isCitationHighlight || !factCitationActive && isHighlighted;
784
+ const ownIndex = chunk.chunkIndex !== void 0 ? chunk.chunkIndex + 1 : void 0;
785
+ const runLabel = runEndIndex !== void 0 && ownIndex !== void 0 && runEndIndex > ownIndex ? `\xB6${ownIndex}\u2013${runEndIndex}` : `\xB6${ownIndex ?? ""}`;
786
+ const showLabel = !!chunkId && (!isSelected || runIsStart);
787
+ const copyPassage = (type, text, href) => copyToClipboard(text, {
788
+ type,
789
+ documentTitle: chunk.docTitle || "Document",
790
+ pageNumber: pageNumber || void 0,
791
+ passageIndex: chunk.chunkIndex,
792
+ passageContent: formattedContent,
793
+ href
794
+ });
795
+ const passageItems = chunkId ? [
796
+ {
797
+ id: "copy-passage",
798
+ label: "Copy passage with citation",
799
+ primary: true,
800
+ testId: "passage-copy",
801
+ onSelect: () => copyPassage("passage", formattedContent, getPassageDeepLink(chunkId) || void 0)
802
+ },
803
+ {
804
+ id: "copy-link",
805
+ label: "Copy passage link",
806
+ testId: "passage-copy-link",
807
+ onSelect: () => {
808
+ const link = getPassageDeepLink(chunkId);
809
+ if (link) copyPassage("link", link, link);
810
+ }
811
+ },
812
+ ...onTagPassage ? [
813
+ {
814
+ id: "label",
815
+ label: "Label this passage",
816
+ testId: "passage-label",
817
+ onSelect: () => onTagPassage(chunkId)
818
+ }
819
+ ] : [],
820
+ ...onOpenNavigator ? [
821
+ {
822
+ id: "navigator",
823
+ label: "Open in navigator",
824
+ testId: "passage-navigator",
825
+ onSelect: onOpenNavigator
826
+ }
827
+ ] : []
828
+ ] : [];
829
+ const labelItems = chunkId ? labels.flatMap((l, i) => {
830
+ const suffix = labels.length > 1 ? ` \u201C${l.name}\u201D` : " label";
831
+ return [
832
+ ...onShowLabel ? [
833
+ {
834
+ id: `show-${l.tagExtId}`,
835
+ label: `Show${suffix}`,
836
+ primary: i === 0,
837
+ testId: "label-show",
838
+ onSelect: () => onShowLabel(l.tagExtId)
839
+ }
840
+ ] : [],
841
+ ...onRemoveLabel ? [
842
+ {
843
+ id: `remove-${l.tagExtId}`,
844
+ label: `Remove${suffix}`,
845
+ destructive: true,
846
+ testId: "label-remove",
847
+ onSelect: () => onRemoveLabel(chunkId, l.tagExtId)
848
+ }
849
+ ] : []
850
+ ];
851
+ }) : [];
852
+ return /* @__PURE__ */ jsxRuntime.jsx(
853
+ chunkT74Q3MCZ_cjs.HtmlPassage,
854
+ {
855
+ chunkId,
856
+ highlight: isStrong ? "strong" : isLight ? "light" : void 0,
857
+ isHit: isHighlighted,
858
+ isSelected,
859
+ runIsStart,
860
+ runIsEnd,
861
+ isClickable: isCitationMode,
862
+ onSelect: onChunkClick && chunkId ? (extend) => onChunkClick(chunkId, extend) : void 0,
863
+ isTagged: labels.length > 0,
864
+ activeTagColor,
865
+ tagMark: labels.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
866
+ chunkLXTOOUEN_cjs.LabelMark,
867
+ {
868
+ colors: labels.map((l) => l.color),
869
+ name: `Labels: ${labels.map((l) => l.name).join(", ")}`,
870
+ menuLabel: "Label actions",
871
+ testId: `passage-tag-dots-${chunkId}`,
872
+ preview: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block font-medium", children: labels.map((l) => l.name).join(", ") }),
873
+ items: labelItems
874
+ }
875
+ ) : void 0,
876
+ runMarker: isSelected && runIsStart ? /* @__PURE__ */ jsxRuntime.jsx(
877
+ chunkLXTOOUEN_cjs.NoteMark,
878
+ {
879
+ label: runLabel,
880
+ title: "Cited by this note \u2014 click a passage to add, shift-click for a range",
881
+ testId: `note-marker-${chunkId}`
882
+ }
883
+ ) : void 0,
884
+ mark: showLabel && chunkId ? /* @__PURE__ */ jsxRuntime.jsx(
885
+ chunkLXTOOUEN_cjs.PassageMark,
886
+ {
887
+ label: runLabel,
888
+ menuLabel: "Passage actions",
889
+ testId: `passage-mark-${chunkId}`,
890
+ items: passageItems
891
+ }
892
+ ) : void 0,
893
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.MarkdownRenderer, { children: chunk.content })
894
+ }
895
+ );
896
+ });
897
+
898
+ // src/connection/viewer/parsed/citation-line.ts
899
+ function formatCitation(data) {
900
+ const { documentTitle, documentDate, pageNumber } = data;
901
+ let citation = "";
902
+ if (documentTitle) {
903
+ citation += `${documentTitle}`;
904
+ }
905
+ if (documentDate) {
906
+ citation += documentTitle ? `, ${documentDate}` : documentDate;
907
+ }
908
+ if (pageNumber) {
909
+ citation += citation ? `, p. ${pageNumber}` : `p. ${pageNumber}`;
910
+ }
911
+ return citation;
912
+ }
913
+
914
+ // src/connection/viewer/parsed/usePassageCopy.ts
915
+ function usePassageCopy({
916
+ documentId,
917
+ documentData,
918
+ selectedWorkspaceId
919
+ }) {
920
+ const { notify, runtimeConfig } = chunkKPZZ5FHE_cjs.useBlocksEnvironment();
921
+ const deploymentDomain = runtimeConfig.deploymentDomain;
922
+ const formatChunkWithCitation = React.useCallback(
923
+ (chunkContent, pageNumber, chunkExtId) => {
924
+ const docDate = documentData?.doc_metadata?.doc_date;
925
+ const citation = formatCitation({
926
+ documentTitle: documentData?.doc_metadata?.title || documentData?.file_name || "",
927
+ documentDate: docDate ? new Date(docDate).toISOString().split("T")[0] : void 0,
928
+ pageNumber
929
+ });
930
+ const deepLinkUrl = selectedWorkspaceId && documentId && chunkExtId ? chunkLJJJ6CYH_cjs.buildDeepLinkUrl(
931
+ { workspaceId: selectedWorkspaceId, documentId, chunkId: chunkExtId },
932
+ deploymentDomain
933
+ ) : "";
934
+ let result = `"${chunkContent.trim()}"`;
935
+ if (citation) {
936
+ result += `
937
+
938
+ \u2014 ${citation}`;
939
+ }
940
+ if (deepLinkUrl) {
941
+ result += `
942
+ [ARBI Docs link](${deepLinkUrl})`;
943
+ }
944
+ return result;
945
+ },
946
+ [documentData, selectedWorkspaceId, documentId, deploymentDomain]
947
+ );
948
+ const getPassageDeepLink = React.useCallback(
949
+ (chunkExtId) => {
950
+ if (!selectedWorkspaceId || !documentId || !chunkExtId) {
951
+ return "";
952
+ }
953
+ return chunkLJJJ6CYH_cjs.buildDeepLinkUrl(
954
+ { workspaceId: selectedWorkspaceId, documentId, chunkId: chunkExtId },
955
+ deploymentDomain
956
+ );
957
+ },
958
+ [selectedWorkspaceId, documentId, deploymentDomain]
959
+ );
960
+ const copyToClipboard = React.useCallback(
961
+ async (text, passageInfo) => {
962
+ try {
963
+ if (passageInfo?.href) {
964
+ const isLink = passageInfo.type === "link";
965
+ const { documentTitle, pageNumber, passageIndex, href } = passageInfo;
966
+ const pageNotation = pageNumber ? `p.${pageNumber}` : "";
967
+ const passageNotation = passageIndex !== void 0 ? `(${passageIndex})` : "";
968
+ const citation = `${documentTitle}${pageNotation ? `, ${pageNotation}${passageNotation}` : ""}`;
969
+ let html;
970
+ let plainText;
971
+ if (isLink) {
972
+ html = `<a href="${href}" target="_blank" rel="noopener noreferrer">${citation}</a>`;
973
+ plainText = href;
974
+ } else {
975
+ const linkHtml = `<p><a href="${href}" target="_blank" rel="noopener noreferrer">${citation}</a></p>`;
976
+ html = `${linkHtml}<blockquote style="margin: 8px 0; padding-left: 12px; border-left: 3px solid #ccc;">${text}</blockquote>`;
977
+ plainText = `${href}
978
+
979
+ ${text}
980
+
981
+ \u2014 ${citation}`;
982
+ }
983
+ const clipboardItem = new ClipboardItem({
984
+ "text/html": new Blob([html], { type: "text/html" }),
985
+ "text/plain": new Blob([plainText], { type: "text/plain" })
986
+ });
987
+ await navigator.clipboard.write([clipboardItem]);
988
+ const prefix = isLink ? "Link copied:" : "Passage copied:";
989
+ const notificationElement = React__default.default.createElement(
990
+ "span",
991
+ { className: "inline-flex items-center gap-2" },
992
+ prefix,
993
+ React__default.default.createElement(chunkLXTOOUEN_cjs.PassagePill, {
994
+ icon: React__default.default.createElement(react.HtmlIcon, { size: 16, className: "flex-shrink-0" }),
995
+ documentTitle: passageInfo.documentTitle,
996
+ pageNumber: passageInfo.pageNumber,
997
+ passageIndex: passageInfo.passageIndex,
998
+ href: passageInfo.href,
999
+ onClick: (e) => e.stopPropagation(),
1000
+ showTooltip: false
1001
+ })
1002
+ );
1003
+ notify(notificationElement, "success", {
1004
+ workspaceId: selectedWorkspaceId || void 0,
1005
+ // The bell entry deep-links back to the copied passage.
1006
+ href: passageInfo.href
1007
+ });
1008
+ } else {
1009
+ await navigator.clipboard.writeText(text);
1010
+ notify("Copied to clipboard", "success");
1011
+ }
1012
+ } catch (err) {
1013
+ console.error("Clipboard copy failed:", err);
1014
+ notify("Failed to copy to clipboard.", "error");
1015
+ }
1016
+ },
1017
+ [selectedWorkspaceId, notify]
1018
+ );
1019
+ return {
1020
+ formatChunkWithCitation,
1021
+ getPassageDeepLink,
1022
+ copyToClipboard
1023
+ };
1024
+ }
1025
+ function useDocumentLabels(documentId, doctags, orderedChunkIds) {
1026
+ const { data: allTags } = chunkGAYMJWTC_cjs.useConnectedTags();
1027
+ const workspaceTags = React.useMemo(() => allTags.filter(isDocumentTag), [allTags]);
1028
+ const documentDoctags = React.useMemo(() => doctags ?? [], [doctags]);
1029
+ const tagSummaries = React.useMemo(
1030
+ () => chunkT74Q3MCZ_cjs.summariseDocTags(documentDoctags, workspaceTags),
1031
+ [documentDoctags, workspaceTags]
1032
+ );
1033
+ const labelSummaries = React.useMemo(
1034
+ () => chunkT74Q3MCZ_cjs.summariseDocTags(documentDoctags, workspaceTags.filter(chunkT74Q3MCZ_cjs.isDocumentLabel)),
1035
+ [documentDoctags, workspaceTags]
1036
+ );
1037
+ const labelsByChunk = React.useMemo(() => {
1038
+ const map = /* @__PURE__ */ new Map();
1039
+ for (const s of tagSummaries) {
1040
+ const label = {
1041
+ tagExtId: s.tagExtId,
1042
+ name: s.name,
1043
+ color: ui.getEntityColor(s.tagExtId, "medium")
1044
+ };
1045
+ for (const id of s.chunkIds) {
1046
+ const list = map.get(id);
1047
+ if (list) list.push(label);
1048
+ else map.set(id, [label]);
1049
+ }
1050
+ }
1051
+ return map;
1052
+ }, [tagSummaries]);
1053
+ const { toggleChunkTag } = useChunkTagging({ documentId, documentDoctags });
1054
+ const removeLabel = React.useCallback(
1055
+ async (chunkExtId, tagExtId) => {
1056
+ const tag = workspaceTags.find((t) => t.external_id === tagExtId);
1057
+ if (!tag) return;
1058
+ try {
1059
+ await toggleChunkTag(chunkExtId, tag);
1060
+ } catch (error) {
1061
+ console.error("Failed to remove passage label", error);
1062
+ }
1063
+ },
1064
+ [workspaceTags, toggleChunkTag]
1065
+ );
1066
+ const [activeTagExtId, setActiveTagExtId] = React.useState(null);
1067
+ const [tagCursor, setTagCursor] = React.useState(0);
1068
+ const [taggingChunkId, setTaggingChunkId] = React.useState(null);
1069
+ const activeTagSummary = tagSummaries.find((t) => t.tagExtId === activeTagExtId);
1070
+ const activeTagColor = activeTagExtId ? ui.getEntityColor(activeTagExtId, "medium") : void 0;
1071
+ const activeChunkIds = React.useMemo(
1072
+ () => new Set(activeTagSummary?.chunkIds ?? []),
1073
+ [activeTagSummary]
1074
+ );
1075
+ const orderedActiveIds = React.useMemo(
1076
+ () => orderedChunkIds.filter((id) => activeChunkIds.has(id)),
1077
+ [orderedChunkIds, activeChunkIds]
1078
+ );
1079
+ const gotoTagged = React.useCallback(
1080
+ (delta) => {
1081
+ if (orderedActiveIds.length === 0) return;
1082
+ const next = (tagCursor + delta + orderedActiveIds.length) % orderedActiveIds.length;
1083
+ setTagCursor(next);
1084
+ document.getElementById(orderedActiveIds[next])?.scrollIntoView({ behavior: "smooth", block: "center" });
1085
+ },
1086
+ [tagCursor, orderedActiveIds]
1087
+ );
1088
+ const selectTag = React.useCallback((tagExtId) => {
1089
+ setActiveTagExtId(tagExtId);
1090
+ setTagCursor(0);
1091
+ }, []);
1092
+ React.useEffect(() => {
1093
+ if (!activeTagExtId || orderedActiveIds.length === 0) return;
1094
+ document.getElementById(orderedActiveIds[0])?.scrollIntoView({ behavior: "smooth", block: "center" });
1095
+ }, [activeTagExtId]);
1096
+ return {
1097
+ documentDoctags,
1098
+ labelSummaries,
1099
+ labelsByChunk,
1100
+ removeLabel,
1101
+ activeTagExtId,
1102
+ activeTagColor,
1103
+ activeChunkIds,
1104
+ tagCursor,
1105
+ gotoTagged,
1106
+ selectTag,
1107
+ taggingChunkId,
1108
+ setTaggingChunkId
1109
+ };
1110
+ }
1111
+ var NONE = [];
1112
+ var noop = () => {
1113
+ };
1114
+ function useCitationSelection({
1115
+ documentId,
1116
+ containerRef,
1117
+ processedChunks,
1118
+ orderedChunkIds,
1119
+ pageOf
1120
+ }) {
1121
+ const { passageCitation } = chunk6I6CVX5G_cjs.useDocumentViewerSupport();
1122
+ const activeCitationContext = passageCitation?.active ?? null;
1123
+ const setPendingPassagesForCitation = passageCitation?.pick ?? noop;
1124
+ const setUnselectedPassagesForCitation = passageCitation?.unpick ?? noop;
1125
+ const viewingPassageId = react.useArbiSessionState((s) => s.viewingDocument?.passageId ?? null);
1126
+ const [selectedChunks, setSelectedChunks] = React.useState(/* @__PURE__ */ new Set());
1127
+ const selectedChunksRef = React.useRef(selectedChunks);
1128
+ selectedChunksRef.current = selectedChunks;
1129
+ const selectionAnchorRef = React.useRef(null);
1130
+ const factCitationChunkIds = passageCitation?.highlighted ?? NONE;
1131
+ const factCitationSet = React.useMemo(() => new Set(factCitationChunkIds), [factCitationChunkIds]);
1132
+ const factCitationActive = factCitationSet.size > 0;
1133
+ const factCitationSetRef = React.useRef(factCitationSet);
1134
+ factCitationSetRef.current = factCitationSet;
1135
+ const isCitationMode = !!activeCitationContext && activeCitationContext.documentId === documentId;
1136
+ const selectionRuns = React.useMemo(
1137
+ () => viewers.computeSelectionRuns(processedChunks, selectedChunks),
1138
+ [processedChunks, selectedChunks]
1139
+ );
1140
+ const runStartIds = React.useMemo(
1141
+ () => orderedChunkIds.filter((id) => selectionRuns.get(id)?.isStart),
1142
+ [orderedChunkIds, selectionRuns]
1143
+ );
1144
+ const [runCursor, setRunCursor] = React.useState(0);
1145
+ const gotoRun = React.useCallback(
1146
+ (delta) => {
1147
+ if (runStartIds.length === 0) return;
1148
+ const next = (runCursor + delta + runStartIds.length) % runStartIds.length;
1149
+ setRunCursor(next);
1150
+ document.getElementById(runStartIds[next])?.scrollIntoView({ behavior: "smooth", block: "center" });
1151
+ },
1152
+ [runCursor, runStartIds]
1153
+ );
1154
+ React.useEffect(() => {
1155
+ if (runCursor >= runStartIds.length) setRunCursor(0);
1156
+ }, [runStartIds.length, runCursor]);
1157
+ React.useEffect(() => {
1158
+ setSelectedChunks(/* @__PURE__ */ new Set());
1159
+ }, [activeCitationContext?.key, activeCitationContext?.documentId]);
1160
+ const handleSelectionEnd = React.useCallback(() => {
1161
+ if (!activeCitationContext || activeCitationContext.documentId !== documentId) return;
1162
+ const selection = window.getSelection();
1163
+ if (!selection || selection.isCollapsed || selection.rangeCount === 0) return;
1164
+ const container = containerRef.current;
1165
+ if (!container) return;
1166
+ const newSelectedChunks = /* @__PURE__ */ new Set();
1167
+ container.querySelectorAll("[data-chunk-id]").forEach((el) => {
1168
+ const chunkId = el.getAttribute("data-chunk-id");
1169
+ if (!chunkId) return;
1170
+ if (selection.containsNode(el, true)) newSelectedChunks.add(chunkId);
1171
+ });
1172
+ if (newSelectedChunks.size > 0) {
1173
+ setSelectedChunks((prev) => /* @__PURE__ */ new Set([...prev, ...newSelectedChunks]));
1174
+ setPendingPassagesForCitation(
1175
+ Array.from(newSelectedChunks).map((id) => ({ chunk_id: id, page: pageOf(id) }))
1176
+ );
1177
+ }
1178
+ selection.removeAllRanges();
1179
+ }, [activeCitationContext, documentId, containerRef, setPendingPassagesForCitation, pageOf]);
1180
+ const handleChunkClick = React.useCallback(
1181
+ (chunkId, extendFromAnchor) => {
1182
+ if (!activeCitationContext || activeCitationContext.documentId !== documentId) return;
1183
+ const anchorId = selectionAnchorRef.current;
1184
+ const anchorIdx = anchorId ? orderedChunkIds.indexOf(anchorId) : -1;
1185
+ const targetIdx = orderedChunkIds.indexOf(chunkId);
1186
+ if (extendFromAnchor && anchorIdx !== -1 && targetIdx !== -1) {
1187
+ const [from, to] = anchorIdx <= targetIdx ? [anchorIdx, targetIdx] : [targetIdx, anchorIdx];
1188
+ const range = orderedChunkIds.slice(from, to + 1);
1189
+ setSelectedChunks((prev) => /* @__PURE__ */ new Set([...prev, ...range]));
1190
+ setPendingPassagesForCitation(range.map((id) => ({ chunk_id: id, page: pageOf(id) })));
1191
+ return;
1192
+ }
1193
+ selectionAnchorRef.current = chunkId;
1194
+ const wasSelected = factCitationSetRef.current.size ? factCitationSetRef.current.has(chunkId) : selectedChunksRef.current.has(chunkId);
1195
+ setSelectedChunks((prev) => {
1196
+ const next = new Set(prev);
1197
+ if (wasSelected) next.delete(chunkId);
1198
+ else next.add(chunkId);
1199
+ return next;
1200
+ });
1201
+ if (wasSelected) setUnselectedPassagesForCitation([chunkId]);
1202
+ else setPendingPassagesForCitation([{ chunk_id: chunkId, page: pageOf(chunkId) }]);
1203
+ },
1204
+ [
1205
+ activeCitationContext,
1206
+ documentId,
1207
+ orderedChunkIds,
1208
+ setPendingPassagesForCitation,
1209
+ setUnselectedPassagesForCitation,
1210
+ pageOf
1211
+ ]
1212
+ );
1213
+ return {
1214
+ isCitationMode,
1215
+ selectedChunks,
1216
+ selectionRuns,
1217
+ runStartIds,
1218
+ runCursor,
1219
+ gotoRun,
1220
+ handleSelectionEnd,
1221
+ handleChunkClick,
1222
+ factCitationSet,
1223
+ factCitationActive,
1224
+ viewingPassageId
1225
+ };
1226
+ }
1227
+ function scrollToChunk(chunkId) {
1228
+ requestAnimationFrame(() => {
1229
+ const element = document.getElementById(chunkId);
1230
+ if (element) {
1231
+ element.scrollIntoView({ behavior: "auto", block: "center" });
1232
+ return;
1233
+ }
1234
+ setTimeout(() => {
1235
+ document.getElementById(chunkId)?.scrollIntoView({ behavior: "auto", block: "center" });
1236
+ }, 100);
1237
+ });
1238
+ }
1239
+ function usePageScrollSync({
1240
+ containerRef,
1241
+ processedChunksLength,
1242
+ scrollTrigger,
1243
+ onVisibilityUpdate
1244
+ }) {
1245
+ const session = react.useArbiSessionStore();
1246
+ const viewingId = react.useArbiSessionState((s) => s.viewingDocument?.id);
1247
+ const viewingDocumentPage = react.useArbiSessionState((s) => s.viewingDocument?.page ?? null);
1248
+ const viewingPassageId = react.useArbiSessionState((s) => s.viewingDocument?.passageId ?? null);
1249
+ const activeTab = react.useArbiSessionState((s) => s.documentViewer.tab);
1250
+ const setViewingDocumentPage = React.useCallback(
1251
+ (page) => {
1252
+ if (viewingId) session.setViewingDocument({ id: viewingId, page });
1253
+ },
1254
+ [session, viewingId]
1255
+ );
1256
+ const [highlighted, setHighlighted] = React.useState(null);
1257
+ const isChunkHighlighted = React.useCallback(
1258
+ (chunkId) => chunkId === highlighted,
1259
+ [highlighted]
1260
+ );
1261
+ const scrollCompleteRef = React.useRef(false);
1262
+ const viewingPassageIdRef = React.useRef(viewingPassageId);
1263
+ viewingPassageIdRef.current = viewingPassageId;
1264
+ React.useEffect(() => {
1265
+ if (activeTab !== "html") {
1266
+ scrollCompleteRef.current = false;
1267
+ }
1268
+ }, [activeTab]);
1269
+ React.useEffect(() => {
1270
+ if (activeTab !== "html" || processedChunksLength === 0) return;
1271
+ if (scrollCompleteRef.current) return;
1272
+ if (viewingPassageIdRef.current) {
1273
+ scrollCompleteRef.current = true;
1274
+ return;
1275
+ }
1276
+ requestAnimationFrame(() => {
1277
+ if (viewingDocumentPage) {
1278
+ const pageElement = document.getElementById(`page-${viewingDocumentPage}`);
1279
+ if (pageElement) {
1280
+ pageElement.scrollIntoView({ behavior: "auto", block: "start" });
1281
+ setTimeout(() => {
1282
+ scrollCompleteRef.current = true;
1283
+ }, 100);
1284
+ }
1285
+ } else {
1286
+ scrollCompleteRef.current = true;
1287
+ }
1288
+ });
1289
+ }, [activeTab, processedChunksLength]);
1290
+ const lastScrolledPassageRef = React.useRef(null);
1291
+ React.useEffect(() => {
1292
+ if (!viewingPassageId) {
1293
+ lastScrolledPassageRef.current = null;
1294
+ setHighlighted(null);
1295
+ }
1296
+ }, [viewingPassageId]);
1297
+ React.useEffect(() => {
1298
+ if (!viewingPassageId || activeTab !== "html" || processedChunksLength === 0) return;
1299
+ if (lastScrolledPassageRef.current === viewingPassageId) return;
1300
+ lastScrolledPassageRef.current = viewingPassageId;
1301
+ setHighlighted(viewingPassageId);
1302
+ scrollToChunk(viewingPassageId);
1303
+ }, [viewingPassageId, activeTab, processedChunksLength]);
1304
+ const viewingPageRef = React.useRef(viewingDocumentPage);
1305
+ viewingPageRef.current = viewingDocumentPage;
1306
+ React.useEffect(() => {
1307
+ const viewingDocumentPage2 = viewingPageRef.current;
1308
+ if (!scrollTrigger || processedChunksLength === 0 || !viewingDocumentPage2) return;
1309
+ scrollCompleteRef.current = false;
1310
+ requestAnimationFrame(() => {
1311
+ const pageElement = document.getElementById(`page-${viewingDocumentPage2}`);
1312
+ if (pageElement) {
1313
+ pageElement.scrollIntoView({ behavior: "smooth", block: "start" });
1314
+ }
1315
+ setTimeout(() => {
1316
+ scrollCompleteRef.current = true;
1317
+ }, 500);
1318
+ });
1319
+ }, [scrollTrigger, processedChunksLength]);
1320
+ const getPageElements = React.useCallback(
1321
+ () => Array.from(document.querySelectorAll('[id^="page-"]')),
1322
+ []
1323
+ );
1324
+ const getPageNumber = React.useCallback((element) => {
1325
+ const pageMatch = element.id.match(/page-(\d+)/);
1326
+ return pageMatch ? parseInt(pageMatch[1], 10) : 0;
1327
+ }, []);
1328
+ viewers.usePageIntersectionObserver({
1329
+ containerRef,
1330
+ scrollCompleteRef,
1331
+ isEnabled: activeTab === "html" && processedChunksLength > 0,
1332
+ getPageElements,
1333
+ getPageNumber,
1334
+ onPageChange: setViewingDocumentPage,
1335
+ onVisibilityUpdate,
1336
+ observeKey: processedChunksLength
1337
+ });
1338
+ return {
1339
+ isChunkHighlighted
1340
+ };
1341
+ }
1342
+
1343
+ // src/connection/viewer/parsed/useLazyPages.ts
1344
+ var LAZY_LOAD_BUFFER_BEFORE = 2;
1345
+ var LAZY_LOAD_BUFFER_AFTER = 5;
1346
+ var INITIAL_PAGES_TO_RENDER = 3;
1347
+ var PAGE_ASPECT_RATIO = 1.3;
1348
+ function useLazyPages({ containerRef, processedChunks, scrollTrigger }) {
1349
+ const [containerWidth, setContainerWidth] = React.useState(0);
1350
+ React.useEffect(() => {
1351
+ const el = containerRef.current;
1352
+ if (!el) return;
1353
+ const observer = new ResizeObserver((entries) => {
1354
+ setContainerWidth(entries[0]?.contentRect.width ?? 0);
1355
+ });
1356
+ observer.observe(el);
1357
+ return () => observer.disconnect();
1358
+ }, [containerRef]);
1359
+ const [renderedPages, setRenderedPages] = React.useState(
1360
+ () => new Set(Array.from({ length: INITIAL_PAGES_TO_RENDER }, (_, i) => i))
1361
+ );
1362
+ React.useEffect(() => {
1363
+ if (processedChunks.length === 0) return;
1364
+ const renderAll = () => {
1365
+ setRenderedPages((prev) => {
1366
+ if (prev.size === processedChunks.length) return prev;
1367
+ return new Set(Array.from({ length: processedChunks.length }, (_, i) => i));
1368
+ });
1369
+ };
1370
+ if (typeof window.requestIdleCallback !== "function") {
1371
+ const timer = setTimeout(renderAll, 200);
1372
+ return () => clearTimeout(timer);
1373
+ }
1374
+ const id = window.requestIdleCallback(renderAll);
1375
+ return () => window.cancelIdleCallback(id);
1376
+ }, [processedChunks.length]);
1377
+ const handleVisibilityUpdate = React.useCallback(
1378
+ (visibilityMap) => {
1379
+ const visiblePageNumbers = Array.from(visibilityMap.entries()).filter(([, ratio]) => ratio > 0).map(([pageNum]) => pageNum);
1380
+ if (visiblePageNumbers.length === 0) return;
1381
+ const visibleIndices = [];
1382
+ processedChunks.forEach((page, index) => {
1383
+ if (page.pageNumber !== null && visiblePageNumbers.includes(page.pageNumber)) {
1384
+ visibleIndices.push(index);
1385
+ }
1386
+ });
1387
+ if (visibleIndices.length === 0) return;
1388
+ const minIndex = Math.min(...visibleIndices);
1389
+ const maxIndex = Math.max(...visibleIndices);
1390
+ const pagesToRender = /* @__PURE__ */ new Set();
1391
+ for (let i = Math.max(0, minIndex - LAZY_LOAD_BUFFER_BEFORE); i <= Math.min(processedChunks.length - 1, maxIndex + LAZY_LOAD_BUFFER_AFTER); i++) {
1392
+ pagesToRender.add(i);
1393
+ }
1394
+ setRenderedPages((prev) => {
1395
+ for (const i of pagesToRender) if (!prev.has(i)) return /* @__PURE__ */ new Set([...prev, ...pagesToRender]);
1396
+ return prev;
1397
+ });
1398
+ },
1399
+ [processedChunks]
1400
+ );
1401
+ const viewingDocumentPage = react.useArbiSessionState((s) => s.viewingDocument?.page ?? null);
1402
+ const viewingPassageId = react.useArbiSessionState((s) => s.viewingDocument?.passageId ?? null);
1403
+ const activeTab = react.useArbiSessionState((s) => s.documentViewer.tab);
1404
+ React.useEffect(() => {
1405
+ if (!viewingDocumentPage || processedChunks.length === 0) return;
1406
+ if (!viewingPassageId && activeTab !== "html") return;
1407
+ const targetIndex = processedChunks.findIndex((p) => p.pageNumber === viewingDocumentPage);
1408
+ if (targetIndex === -1) return;
1409
+ setRenderedPages((prev) => {
1410
+ if (prev.has(targetIndex)) return prev;
1411
+ const next = new Set(prev);
1412
+ for (let i = Math.max(0, targetIndex - LAZY_LOAD_BUFFER_BEFORE); i <= Math.min(processedChunks.length - 1, targetIndex + LAZY_LOAD_BUFFER_AFTER); i++) {
1413
+ next.add(i);
1414
+ }
1415
+ return next;
1416
+ });
1417
+ }, [viewingPassageId, viewingDocumentPage, processedChunks, activeTab]);
1418
+ const tabSwitchScrolledRef = React.useRef(false);
1419
+ const passageScrolledRef = React.useRef(null);
1420
+ React.useEffect(() => {
1421
+ if (activeTab !== "html") tabSwitchScrolledRef.current = false;
1422
+ }, [activeTab]);
1423
+ React.useEffect(() => {
1424
+ if (!viewingPassageId) passageScrolledRef.current = null;
1425
+ }, [viewingPassageId]);
1426
+ React.useEffect(() => {
1427
+ if (activeTab !== "html" || !viewingDocumentPage) return;
1428
+ if (viewingPassageId && passageScrolledRef.current !== viewingPassageId) {
1429
+ const target = viewingPassageId;
1430
+ const deadline = performance.now() + 3e3;
1431
+ let raf = 0;
1432
+ const tick = () => {
1433
+ const el = document.getElementById(target);
1434
+ if (el) {
1435
+ passageScrolledRef.current = target;
1436
+ tabSwitchScrolledRef.current = true;
1437
+ el.scrollIntoView({ behavior: "auto", block: "center" });
1438
+ raf = requestAnimationFrame(
1439
+ () => el.scrollIntoView({ behavior: "auto", block: "center" })
1440
+ );
1441
+ return;
1442
+ }
1443
+ if (performance.now() < deadline) raf = requestAnimationFrame(tick);
1444
+ };
1445
+ raf = requestAnimationFrame(tick);
1446
+ return () => cancelAnimationFrame(raf);
1447
+ }
1448
+ if (tabSwitchScrolledRef.current) return;
1449
+ const pageElement = document.getElementById(`page-${viewingDocumentPage}`);
1450
+ if (!pageElement) return;
1451
+ tabSwitchScrolledRef.current = true;
1452
+ requestAnimationFrame(() => {
1453
+ pageElement.scrollIntoView({ behavior: "auto", block: "start" });
1454
+ });
1455
+ }, [renderedPages, activeTab, viewingDocumentPage, viewingPassageId]);
1456
+ const { isChunkHighlighted } = usePageScrollSync({
1457
+ containerRef,
1458
+ processedChunksLength: processedChunks.length,
1459
+ scrollTrigger,
1460
+ onVisibilityUpdate: handleVisibilityUpdate
1461
+ });
1462
+ return {
1463
+ renderedPages,
1464
+ isChunkHighlighted,
1465
+ placeholderHeight: containerWidth ? containerWidth * PAGE_ASPECT_RATIO : 500
1466
+ };
1467
+ }
1468
+ var EMPTY_LABELS = [];
1469
+ function ParsedTextView({
1470
+ documentId,
1471
+ stage = "final",
1472
+ onLoadSuccess,
1473
+ scrollTrigger,
1474
+ zoom = 1,
1475
+ onZoomChange
1476
+ }) {
1477
+ const { workspaceId } = chunkGFNELPDP_cjs.useConnectedWorkspace();
1478
+ const { openInNavigator } = chunk6I6CVX5G_cjs.useDocumentViewerSupport();
1479
+ const containerRef = React.useRef(null);
1480
+ const { data: documentRecord } = react.useDocument(artifacts.parseVersionRef(documentId).docId, {
1481
+ enabled: !!documentId && !!workspaceId
1482
+ });
1483
+ const documentData = documentRecord ?? void 0;
1484
+ const { data: parsedDoc, isLoading, error } = react.useParsedDocument(documentId, stage);
1485
+ const { processedChunks, maxPageNumber } = viewers.useProcessedChunks(
1486
+ parsedDoc?.chunks,
1487
+ parsedDoc?.footnotes || {}
1488
+ );
1489
+ const pageByChunk = React.useMemo(() => {
1490
+ const map = /* @__PURE__ */ new Map();
1491
+ for (const page of processedChunks) {
1492
+ for (const chunk of page.chunks) {
1493
+ if (chunk.chunkExtId) map.set(chunk.chunkExtId, page.pageNumber ?? void 0);
1494
+ }
1495
+ }
1496
+ return map;
1497
+ }, [processedChunks]);
1498
+ const pageOf = React.useCallback((id) => pageByChunk.get(id), [pageByChunk]);
1499
+ const orderedChunkIds = React.useMemo(
1500
+ () => processedChunks.flatMap(
1501
+ (page) => page.chunks.map((c) => c.chunkExtId).filter((id) => !!id)
1502
+ ),
1503
+ [processedChunks]
1504
+ );
1505
+ const totalPages = React.useMemo(
1506
+ () => processedChunks.filter((p) => p.pageNumber !== null).length,
1507
+ [processedChunks]
1508
+ );
1509
+ const labels = useDocumentLabels(documentId, documentData?.doctags, orderedChunkIds);
1510
+ const citation = useCitationSelection({
1511
+ documentId,
1512
+ containerRef,
1513
+ processedChunks,
1514
+ orderedChunkIds,
1515
+ pageOf
1516
+ });
1517
+ const { renderedPages, isChunkHighlighted, placeholderHeight } = useLazyPages({
1518
+ containerRef,
1519
+ processedChunks,
1520
+ scrollTrigger
1521
+ });
1522
+ viewers.useScrollAnchor(containerRef, processedChunks.length);
1523
+ viewers.usePinchZoom({ containerRef, zoom, onZoomChange });
1524
+ const { formatChunkWithCitation, getPassageDeepLink, copyToClipboard } = usePassageCopy({
1525
+ documentId,
1526
+ documentData,
1527
+ selectedWorkspaceId: workspaceId
1528
+ });
1529
+ const handleOpenNavigator = React.useMemo(
1530
+ () => openInNavigator ? () => openInNavigator(documentId) : void 0,
1531
+ [openInNavigator, documentId]
1532
+ );
1533
+ React.useEffect(() => {
1534
+ if (maxPageNumber > 0 && onLoadSuccess) {
1535
+ try {
1536
+ onLoadSuccess(maxPageNumber);
1537
+ } catch (err) {
1538
+ console.error("Error in onLoadSuccess callback:", err);
1539
+ }
1540
+ }
1541
+ }, [maxPageNumber, onLoadSuccess]);
1542
+ if (isLoading) return /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.ViewerMessage, { children: "Loading parsed document..." });
1543
+ if (error) {
1544
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.ViewerMessage, { children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-text", children: "Failed to load parsed document" }) });
1545
+ }
1546
+ const taggingChunk = labels.taggingChunkId ? processedChunks.flatMap((page) => page.chunks).find((c) => c.chunkExtId === labels.taggingChunkId) : void 0;
1547
+ return /* @__PURE__ */ jsxRuntime.jsxs(chunkT74Q3MCZ_cjs.HtmlViewerRoot, { children: [
1548
+ /* @__PURE__ */ jsxRuntime.jsx(
1549
+ chunkT74Q3MCZ_cjs.DocumentLabelBar,
1550
+ {
1551
+ summaries: labels.labelSummaries,
1552
+ activeTagExtId: labels.activeTagExtId,
1553
+ cursor: labels.tagCursor,
1554
+ onSelect: labels.selectTag,
1555
+ onStep: labels.gotoTagged
1556
+ }
1557
+ ),
1558
+ labels.taggingChunkId && /* @__PURE__ */ jsxRuntime.jsx(
1559
+ PassageTagPanel,
1560
+ {
1561
+ documentId,
1562
+ chunkExtId: labels.taggingChunkId,
1563
+ chunkContent: taggingChunk?.content ?? "",
1564
+ pageNumber: pageOf(labels.taggingChunkId),
1565
+ documentDoctags: labels.documentDoctags,
1566
+ onClose: () => labels.setTaggingChunkId(null),
1567
+ onViewTaggedChunks: (tagExtId) => {
1568
+ labels.selectTag(tagExtId);
1569
+ labels.setTaggingChunkId(null);
1570
+ }
1571
+ }
1572
+ ),
1573
+ !citation.factCitationActive && citation.runStartIds.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
1574
+ chunkT74Q3MCZ_cjs.CitedRunNav,
1575
+ {
1576
+ position: citation.runCursor + 1,
1577
+ total: citation.runStartIds.length,
1578
+ onStep: citation.gotoRun
1579
+ }
1580
+ ),
1581
+ /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.HtmlViewerSurface, { surfaceRef: containerRef, onMouseUp: citation.handleSelectionEnd, children: processedChunks.length > 0 ? processedChunks.map((page, pageIndex) => /* @__PURE__ */ jsxRuntime.jsx(
1582
+ chunkT74Q3MCZ_cjs.HtmlPage,
1583
+ {
1584
+ pageNumber: page.pageNumber,
1585
+ totalPages,
1586
+ isRendered: renderedPages.has(pageIndex),
1587
+ placeholderHeight,
1588
+ zoom,
1589
+ children: page.chunks.map((chunk, chunkIndex) => {
1590
+ const id = chunk.chunkExtId;
1591
+ const run = id ? citation.selectionRuns.get(id) : void 0;
1592
+ return /* @__PURE__ */ jsxRuntime.jsx(
1593
+ ParsedPassage,
1594
+ {
1595
+ chunk,
1596
+ pageNumber: page.pageNumber,
1597
+ isHighlighted: !!(id && isChunkHighlighted(id)),
1598
+ isSelected: !!(id && citation.selectedChunks.has(id)),
1599
+ isCitationHighlight: !!(id && citation.factCitationSet.has(id)),
1600
+ isActiveCitation: !!(id && citation.factCitationActive && citation.viewingPassageId === id && // Only while it is STILL cited: clicking it off must clear it.
1601
+ citation.factCitationSet.has(id)),
1602
+ factCitationActive: citation.factCitationActive,
1603
+ isCitationMode: citation.isCitationMode,
1604
+ runIsStart: !!run?.isStart,
1605
+ runIsEnd: !!run?.isEnd,
1606
+ runEndIndex: run?.endIndex,
1607
+ onChunkClick: citation.isCitationMode ? citation.handleChunkClick : void 0,
1608
+ formatChunkWithCitation,
1609
+ getPassageDeepLink,
1610
+ copyToClipboard,
1611
+ onOpenNavigator: handleOpenNavigator,
1612
+ labels: id ? labels.labelsByChunk.get(id) ?? EMPTY_LABELS : EMPTY_LABELS,
1613
+ activeTagColor: id && labels.activeChunkIds.has(id) ? labels.activeTagColor : void 0,
1614
+ onTagPassage: labels.setTaggingChunkId,
1615
+ onShowLabel: labels.selectTag,
1616
+ onRemoveLabel: labels.removeLabel
1617
+ },
1618
+ chunkIndex
1619
+ );
1620
+ })
1621
+ },
1622
+ pageIndex
1623
+ )) : /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.HtmlViewerEmpty, {}) })
1624
+ ] });
1625
+ }
1626
+ var AnnotatedPdfViewer = React.lazy(
1627
+ () => import('../document-tools/viewer/index.cjs').then((m) => ({ default: m.AnnotatedPdfViewer }))
1628
+ );
1629
+ var SignaturePlacementViewer = React.lazy(
1630
+ () => import('../document-tools/viewer/index.cjs').then((m) => ({ default: m.SignaturePlacementViewer }))
1631
+ );
1632
+ var SignatureRequestEditor = React.lazy(
1633
+ () => import('../document-tools/viewer/index.cjs').then((m) => ({ default: m.SignatureRequestEditor }))
1634
+ );
1635
+ var GuidedSigningViewer = React.lazy(
1636
+ () => import('../document-tools/viewer/index.cjs').then((m) => ({ default: m.GuidedSigningViewer }))
1637
+ );
1638
+ function SessionPdfViewer(props) {
1639
+ const session = react.useArbiSessionStore();
1640
+ const viewingId = react.useArbiSessionState((s) => s.viewingDocument?.id);
1641
+ const { isDetached } = chunk6I6CVX5G_cjs.useDocumentViewerSupport();
1642
+ const onPageChange = React.useCallback(
1643
+ (page) => {
1644
+ if (viewingId) session.setViewingDocument({ id: viewingId, page });
1645
+ },
1646
+ [session, viewingId]
1647
+ );
1648
+ return /* @__PURE__ */ jsxRuntime.jsx(viewers.PdfViewer, { ...props, onPageChange, disableFontFace: !!isDetached });
1649
+ }
1650
+ function ViewerPdfPane({
1651
+ documentId,
1652
+ doc,
1653
+ pdfBlob,
1654
+ isPdfLoading,
1655
+ pdfError,
1656
+ onDownload,
1657
+ viewerProps,
1658
+ signatureFlow,
1659
+ onSignatureFlow,
1660
+ currentUserId,
1661
+ placingSignature,
1662
+ onPlacingDone,
1663
+ annotating,
1664
+ markup,
1665
+ pdfSnapshotNumber,
1666
+ isSigned
1667
+ }) {
1668
+ const { documentData, isDownloadOnly, isVideo, isAudio, isImage, isDocx } = doc;
1669
+ const showMarkup = markup.hasMarkup && !markup.showOriginal;
1670
+ if (isDownloadOnly) {
1671
+ return /* @__PURE__ */ jsxRuntime.jsx(
1672
+ chunkT74Q3MCZ_cjs.ViewerPreviewUnavailable,
1673
+ {
1674
+ extension: fileExtension(documentData?.file_name),
1675
+ onDownload
1676
+ }
1677
+ );
1678
+ }
1679
+ const loadingLabel = isVideo ? "Loading video..." : isAudio ? "Loading audio..." : isImage ? "Loading image..." : !documentData ? "Loading document..." : ui.friendlyFileType(documentData.file_type, documentData.file_name) === "Text" ? "Loading text..." : "Loading PDF...";
1680
+ const errorLabel = isVideo ? "Failed to load video" : isAudio ? "Failed to load audio" : isImage ? "Failed to load image" : "Failed to load PDF";
1681
+ if (isDocx && documentData && !["completed", "low-content", "failed"].includes(documentData.status || "")) {
1682
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.ViewerMessage, { children: "PDF and search indexing are processing. Open the DOCX tab to edit now." });
1683
+ }
1684
+ if (isPdfLoading) return /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.ViewerMessage, { children: loadingLabel });
1685
+ if (pdfError) {
1686
+ return /* @__PURE__ */ jsxRuntime.jsx(
1687
+ chunkT74Q3MCZ_cjs.ViewerLoadError,
1688
+ {
1689
+ message: isVideo || isAudio || isImage ? `${errorLabel} \u2014 download it instead.` : "Couldn't display the PDF \u2014 download it instead.",
1690
+ onDownload
1691
+ }
1692
+ );
1693
+ }
1694
+ if (!pdfBlob) return /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.ViewerMessage, { children: loadingLabel });
1695
+ if (isVideo) return /* @__PURE__ */ jsxRuntime.jsx(viewers.VideoViewer, { blob: pdfBlob, title: documentData?.file_name || "Video" });
1696
+ if (isAudio) return /* @__PURE__ */ jsxRuntime.jsx(viewers.AudioViewer, { blob: pdfBlob, title: documentData?.file_name || "Audio" });
1697
+ if (isImage) {
1698
+ return /* @__PURE__ */ jsxRuntime.jsx(viewers.ImageViewer, { blob: pdfBlob, alt: documentData?.file_name || "Document image" });
1699
+ }
1700
+ if (signatureFlow?.kind === "prepare") {
1701
+ return /* @__PURE__ */ jsxRuntime.jsx(React.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.ViewerMessage, { children: "Loading\u2026" }), children: /* @__PURE__ */ jsxRuntime.jsx(
1702
+ SignatureRequestEditor,
1703
+ {
1704
+ ...viewerProps,
1705
+ file: pdfBlob,
1706
+ documentId,
1707
+ version: documentData?.current_version ?? void 0,
1708
+ draft: signatureFlow.draft,
1709
+ viewer: SessionPdfViewer,
1710
+ onCancel: () => onSignatureFlow(null),
1711
+ onSaved: () => onSignatureFlow(null)
1712
+ }
1713
+ ) });
1714
+ }
1715
+ if (signatureFlow?.kind === "sign" && currentUserId) {
1716
+ const { currentPage: _page, scrollTrigger: _trigger, ...guidedProps } = viewerProps;
1717
+ return /* @__PURE__ */ jsxRuntime.jsx(React.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.ViewerMessage, { children: "Loading\u2026" }), children: /* @__PURE__ */ jsxRuntime.jsx(
1718
+ GuidedSigningViewer,
1719
+ {
1720
+ ...guidedProps,
1721
+ file: pdfBlob,
1722
+ request: signatureFlow.request,
1723
+ signer: currentUserId,
1724
+ viewer: SessionPdfViewer,
1725
+ onClose: () => onSignatureFlow(null),
1726
+ onSigned: () => onSignatureFlow(null)
1727
+ }
1728
+ ) });
1729
+ }
1730
+ if (placingSignature) {
1731
+ return /* @__PURE__ */ jsxRuntime.jsx(React.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.ViewerMessage, { children: "Loading\u2026" }), children: /* @__PURE__ */ jsxRuntime.jsx(
1732
+ SignaturePlacementViewer,
1733
+ {
1734
+ ...viewerProps,
1735
+ file: pdfBlob,
1736
+ documentId,
1737
+ viewer: SessionPdfViewer,
1738
+ onCancel: () => onPlacingDone(),
1739
+ onContinue: (appearance) => onPlacingDone(appearance)
1740
+ }
1741
+ ) });
1742
+ }
1743
+ if (annotating || showMarkup) {
1744
+ return /* @__PURE__ */ jsxRuntime.jsx(
1745
+ React.Suspense,
1746
+ {
1747
+ fallback: /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.ViewerMessage, { children: annotating ? "Loading annotation tools\u2026" : "Loading markup\u2026" }),
1748
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1749
+ AnnotatedPdfViewer,
1750
+ {
1751
+ ...viewerProps,
1752
+ file: pdfBlob,
1753
+ documentId,
1754
+ version: pdfSnapshotNumber,
1755
+ editing: annotating,
1756
+ onMarkupChange: markup.onMarkupChange,
1757
+ fileName: documentData?.file_name,
1758
+ shared: documentData?.shared ?? false,
1759
+ folder: documentData?.folder,
1760
+ viewer: SessionPdfViewer,
1761
+ signed: isSigned
1762
+ },
1763
+ `${documentId}@${pdfSnapshotNumber ?? "current"}`
1764
+ )
1765
+ }
1766
+ );
1767
+ }
1768
+ return /* @__PURE__ */ jsxRuntime.jsx(SessionPdfViewer, { ...viewerProps, file: pdfBlob });
1769
+ }
1770
+ var NativeDocxEditor = React.lazy(
1771
+ () => import('../ConnectedNativeDocxEditor-HTEW5JAH.cjs').then((m) => ({
1772
+ default: m.ConnectedNativeDocxEditor
1773
+ }))
1774
+ );
1775
+ var StreamedWordArtifact = React.lazy(
1776
+ () => import('../ConnectedStreamedWordArtifact-QW74LKHN.cjs').then((m) => ({
1777
+ default: m.ConnectedStreamedWordArtifact
1778
+ }))
1779
+ );
1780
+ var NativeDocxComparison = React.lazy(
1781
+ () => import('../ConnectedNativeDocxComparison-Y5BNLNH6.cjs').then((m) => ({
1782
+ default: m.ConnectedNativeDocxComparison
1783
+ }))
1784
+ );
1785
+ var UPLOADED_NO_VERSIONS = "No earlier versions yet. Replacing, editing or signing this file adds a new version here.";
1786
+ function canChangeVisibility(doc, userId) {
1787
+ if (!doc || !userId) return false;
1788
+ return userId.startsWith("agt-") || (doc.created_by_ext_id?.startsWith("agt-") ?? false) || doc.created_by_ext_id === userId;
1789
+ }
1790
+ function ConnectedDocumentViewer(props) {
1791
+ const viewing = react.useArbiSessionState((s) => s.viewingDocument?.id);
1792
+ const openedId = props.documentId ?? viewing;
1793
+ if (!openedId) return null;
1794
+ return /* @__PURE__ */ jsxRuntime.jsx(ConnectedDocumentToolsProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(DocumentViewerContent, { ...props, openedId }) });
1795
+ }
1796
+ function DocumentViewerContent({
1797
+ openedId,
1798
+ headerActions,
1799
+ artifactRuntimeUrl = "/artifact-runtime/"
1800
+ }) {
1801
+ const arbi = react.useArbi();
1802
+ const session = react.useArbiSessionStore();
1803
+ const support = chunk6I6CVX5G_cjs.useDocumentViewerSupport();
1804
+ const formatDate = support.formatDate ?? chunkKDG6FER6_cjs.fmtDate;
1805
+ const tools = documentTools.useDocumentTools();
1806
+ const { openConversation, notify } = chunkKPZZ5FHE_cjs.useBlocksEnvironment();
1807
+ const { userId: currentUserId } = chunkGFNELPDP_cjs.useConnectedWorkspace();
1808
+ const documentId = artifacts.parseVersionRef(openedId).docId;
1809
+ const [totalPages, setTotalPages] = React.useState(0);
1810
+ const [isCompact, setIsCompact] = React.useState(false);
1811
+ const [pdfZoom, setPdfZoom] = React.useState(1);
1812
+ const {
1813
+ tab: zoomTab,
1814
+ textScale,
1815
+ compareId: compareDocumentId
1816
+ } = react.useArbiSessionState((s) => s.documentViewer);
1817
+ const zoom = zoomTab === "html" ? textScale : pdfZoom;
1818
+ const setZoom = React.useCallback(
1819
+ (next) => {
1820
+ const value = typeof next === "function" ? next(zoom) : next;
1821
+ if (zoomTab === "html") session.setDocumentViewer({ textScale: value });
1822
+ else setPdfZoom(value);
1823
+ },
1824
+ [zoomTab, session, zoom]
1825
+ );
1826
+ const [scrollTrigger, setScrollTrigger] = React.useState(0);
1827
+ const containerRef = React.useRef(null);
1828
+ const viewingDocumentPage = react.useArbiSessionState((s) => s.viewingDocument?.page ?? null);
1829
+ const setViewingDocumentPage = (page) => session.setViewingDocument({ id: openedId, page });
1830
+ const setViewingDocumentId = (id) => session.setViewingDocument({ id });
1831
+ const setActiveTab = (tab) => session.setDocumentViewer({ tab });
1832
+ const setCompareDocumentId = (id) => session.setDocumentViewer({ compareId: id });
1833
+ const { data: conversations } = chunkGAYMJWTC_cjs.useConnectedConversations();
1834
+ const snapshotRef = artifacts.parseVersionRef(openedId).version ? openedId : null;
1835
+ const { versions, translations } = useViewerVersions(documentId);
1836
+ const currentVersionId = versions.find((v) => v.isCurrent)?.id ?? documentId;
1837
+ const snapshotDocumentId = snapshotRef && snapshotRef !== currentVersionId ? snapshotRef : null;
1838
+ const doc = useViewedDocument(documentId);
1839
+ const setSnapshotDocumentId = (ref) => setViewingDocumentId(ref ?? documentId);
1840
+ chunkJKB7WT7L_cjs.useRegisterOpenDocument({
1841
+ documentId: doc.savedDocumentId,
1842
+ shownId: openedId,
1843
+ showLive: () => setViewingDocumentId(documentId),
1844
+ workspaceId: doc.workspaceId
1845
+ });
1846
+ const {
1847
+ documentData,
1848
+ streamingDoc,
1849
+ isStreaming,
1850
+ draftDoc,
1851
+ isDraft,
1852
+ isCaptureDraft,
1853
+ labelSummaries,
1854
+ isImage,
1855
+ isVideo,
1856
+ isAudio,
1857
+ isMedia,
1858
+ isArtifact,
1859
+ liveKind,
1860
+ liveSource,
1861
+ isDocx,
1862
+ isXlsx,
1863
+ isDownloadOnly
1864
+ } = doc;
1865
+ const threadTitle = (id) => conversations.find((c) => c.external_id === id)?.title?.trim() || "Its thread";
1866
+ const madeInId = documentData?.conversation_ext_id ?? null;
1867
+ const madeIn = madeInId ? { id: madeInId, title: threadTitle(madeInId) } : null;
1868
+ const pdfSnapshotId = snapshotDocumentId && !isDocx && !isArtifact ? snapshotDocumentId : null;
1869
+ const shownDocumentId = pdfSnapshotId || documentId;
1870
+ const blobs = useViewerBlobs(shownDocumentId, doc);
1871
+ const { pdfBlob, xlsxBlob, xlsxError, handleDirectDownload } = blobs;
1872
+ const [annotating, setAnnotating] = React.useState(false);
1873
+ React.useEffect(() => setAnnotating(false), [documentId]);
1874
+ const hasHistory = versions.length > 1 || (documentData?.current_version ?? 1) > 1 || translations.length > 0;
1875
+ const { activeTab, handleTabChange, viewerTabs } = useViewerTabs(doc, isCompact, hasHistory);
1876
+ const crop = useImageCrop(documentId, documentData?.file_name, pdfBlob);
1877
+ const [placingSignature, setPlacingSignature] = React.useState(false);
1878
+ const [signAppearance, setSignAppearance] = React.useState();
1879
+ const [isSignOpen, setIsSignOpen] = React.useState(false);
1880
+ React.useEffect(() => setPlacingSignature(false), [documentId, snapshotDocumentId]);
1881
+ const [signatureFlow, setSignatureFlow] = React.useState(null);
1882
+ React.useEffect(() => setSignatureFlow(null), [documentId, snapshotDocumentId]);
1883
+ const { data: signatureStatus } = documentTools.useDocumentSignatures(shownDocumentId, !isDraft && !liveKind);
1884
+ const isCoEditing = !snapshotDocumentId && !compareDocumentId && !isDraft && (activeTab === "docx" && isDocx || activeTab === "edit" && isArtifact && !liveKind && !isStreaming);
1885
+ const currentVersionLabel = isCoEditing ? void 0 : !snapshotDocumentId && !compareDocumentId && (isDocx || isArtifact && !liveKind) ? "Live" : artifacts.versionLabel(versions, snapshotDocumentId || documentId);
1886
+ const compareVersionLabel = artifacts.versionLabel(versions, compareDocumentId);
1887
+ const snapshotNumber = artifacts.findVersion(versions, snapshotDocumentId)?.number;
1888
+ const pdfSnapshotNumber = pdfSnapshotId ? snapshotNumber : void 0;
1889
+ const isSigned = !!signatureStatus?.signed;
1890
+ const markup = documentTools.useDocumentMarkup(documentData, pdfSnapshotNumber, isSigned);
1891
+ React.useEffect(() => {
1892
+ const container = containerRef.current;
1893
+ if (!container) return;
1894
+ const resizeObserver = new ResizeObserver((entries) => {
1895
+ for (const entry of entries) setIsCompact(entry.contentRect.width < 640);
1896
+ });
1897
+ resizeObserver.observe(container);
1898
+ return () => resizeObserver.disconnect();
1899
+ }, []);
1900
+ const handleLoadSuccess = React.useCallback((numPages) => setTotalPages(numPages), []);
1901
+ const goToPage = (page) => {
1902
+ setViewingDocumentPage(page);
1903
+ setScrollTrigger((prev) => prev + 1);
1904
+ };
1905
+ const stepPage = (delta) => {
1906
+ const next = (viewingDocumentPage || 1) + delta;
1907
+ if (next >= 1 && next <= totalPages) goToPage(next);
1908
+ };
1909
+ const documentTitle = streamingDoc?.title || draftDoc?.title || documentData?.doc_metadata?.title || documentData?.file_name || "Document";
1910
+ const pageNav = totalPages > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1911
+ /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.ViewerZoomControl, { zoom, onCycle: () => setZoom(viewers.cycleZoom(zoom)) }),
1912
+ /* @__PURE__ */ jsxRuntime.jsx(
1913
+ chunkT74Q3MCZ_cjs.PdfPageNav,
1914
+ {
1915
+ canPrev: (viewingDocumentPage || 1) > 1,
1916
+ canNext: (viewingDocumentPage || 1) < totalPages,
1917
+ onPrev: () => stepPage(-1),
1918
+ onNext: () => stepPage(1),
1919
+ counter: /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.ViewerPageCounter, { page: viewingDocumentPage || 1, total: totalPages, onGoTo: goToPage })
1920
+ }
1921
+ )
1922
+ ] });
1923
+ const isComparing = !!compareDocumentId;
1924
+ const compareTarget = compareDocumentId ? artifacts.parseVersionRef(compareDocumentId).docId : null;
1925
+ const compareIndicator = isComparing && compareTarget && /* @__PURE__ */ jsxRuntime.jsx(
1926
+ chunk2YV7FBLO_cjs.ArtifactCompareBar,
1927
+ {
1928
+ compareTarget: support.renderDocumentPill?.(compareTarget) ?? compareTarget,
1929
+ versionLabel: compareVersionLabel,
1930
+ mode: "flip",
1931
+ showTrackChanges: false,
1932
+ onToggleTrackChanges: () => {
1933
+ },
1934
+ onFlip: () => {
1935
+ setViewingDocumentId(compareDocumentId);
1936
+ setCompareDocumentId(documentId);
1937
+ },
1938
+ onStop: () => setCompareDocumentId(null)
1939
+ }
1940
+ );
1941
+ const titleBlock = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1942
+ isDraft ? support.renderDraftTitle?.(documentId) : /* @__PURE__ */ jsxRuntime.jsx(
1943
+ chunkT74Q3MCZ_cjs.ViewerTitle,
1944
+ {
1945
+ title: documentTitle,
1946
+ versionLabel: currentVersionLabel,
1947
+ shrink: !!liveKind || isCompact
1948
+ }
1949
+ ),
1950
+ isCompact && !isDraft && documentData?.shared && /* @__PURE__ */ jsxRuntime.jsx(chunkUWIILWDI_cjs.ViewerStatusNote, { testId: "document-shared-status", children: "Shared with the workspace" }),
1951
+ isCompact && activeTab === "pdf" && pdfBlob && markup.hasMarkup && !annotating && !placingSignature && /* @__PURE__ */ jsxRuntime.jsx(
1952
+ chunkD3WFIFRY_cjs.MarkupViewNote,
1953
+ {
1954
+ showOriginal: markup.showOriginal,
1955
+ onToggle: () => markup.setShowOriginal((on) => !on)
1956
+ }
1957
+ ),
1958
+ !isComparing && !liveKind && documentData && support.renderRelated?.(documentData),
1959
+ isStreaming && /* @__PURE__ */ jsxRuntime.jsx(chunkUWIILWDI_cjs.ViewerStatusNote, { pulse: true, children: "streaming..." }),
1960
+ isDraft && /* @__PURE__ */ jsxRuntime.jsx(chunkUWIILWDI_cjs.ViewerStatusNote, { testId: "draft-unsaved-indicator", children: "Draft \u2014 not saved" }),
1961
+ signatureStatus?.signed && /* @__PURE__ */ jsxRuntime.jsx(chunkD3WFIFRY_cjs.SignatureStatus, { status: signatureStatus, formatDate })
1962
+ ] });
1963
+ const leftContent = /* @__PURE__ */ jsxRuntime.jsxs(chunkUWIILWDI_cjs.ViewerHeaderStart, { children: [
1964
+ isDraft ? (
1965
+ // A draft's kind replaces the tabs: neither Versions nor the text view means anything
1966
+ // before the first save.
1967
+ support.renderDraftKind?.(documentId)
1968
+ ) : /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.ViewerTabBar, { tabs: viewerTabs, activeId: activeTab, onChange: handleTabChange }),
1969
+ !isCompact && titleBlock
1970
+ ] });
1971
+ const annotatable = documentTools.canAnnotate({
1972
+ activeTab,
1973
+ hasPdf: !!pdfBlob,
1974
+ isImage,
1975
+ isVideo,
1976
+ isAudio,
1977
+ isDownloadOnly,
1978
+ isDraft,
1979
+ isStreaming,
1980
+ isSnapshot: !!snapshotDocumentId,
1981
+ isComparing
1982
+ });
1983
+ const signatureBanner = !isDraft && !liveKind && !snapshotDocumentId && /* @__PURE__ */ jsxRuntime.jsx(
1984
+ chunkD3WFIFRY_cjs.SignatureRequestBanner,
1985
+ {
1986
+ documentId,
1987
+ hidden: !!signatureFlow,
1988
+ onSign: (request) => {
1989
+ setAnnotating(false);
1990
+ setPlacingSignature(false);
1991
+ if (activeTab !== "pdf") handleTabChange("pdf");
1992
+ setSignatureFlow({ kind: "sign", request });
1993
+ },
1994
+ onEditDraft: (draft) => {
1995
+ if (activeTab !== "pdf") handleTabChange("pdf");
1996
+ setSignatureFlow({ kind: "prepare", draft });
1997
+ }
1998
+ }
1999
+ );
2000
+ const share = () => {
2001
+ const name = (liveKind ? documentTitle : documentData?.file_name) || void 0;
2002
+ if (support.share) {
2003
+ support.share({ id: documentId, name, isPrivate: !documentData?.shared });
2004
+ return;
2005
+ }
2006
+ void arbi.documents.update([{ external_id: documentId, shared: !documentData?.shared }]).then(() => tools.onDocumentsChanged?.([documentId], "markup")).catch(() => notify("Couldn't change who can see this document", "error"));
2007
+ };
2008
+ const shownRef = snapshotDocumentId || documentId;
2009
+ const rightContent = /* @__PURE__ */ jsxRuntime.jsxs(chunkUWIILWDI_cjs.ViewerHeaderEnd, { isCompact, children: [
2010
+ annotatable && /* @__PURE__ */ jsxRuntime.jsx(
2011
+ chunkD3WFIFRY_cjs.AnnotateButton,
2012
+ {
2013
+ active: annotating,
2014
+ compact: isCompact,
2015
+ onClick: () => {
2016
+ setPlacingSignature(false);
2017
+ markup.setShowOriginal(false);
2018
+ setAnnotating((on) => !on);
2019
+ }
2020
+ }
2021
+ ),
2022
+ activeTab === "pdf" && pdfBlob && !placingSignature && (markup.hasMarkup || annotating) && /* @__PURE__ */ jsxRuntime.jsx(
2023
+ chunkD3WFIFRY_cjs.ShowOriginalButton,
2024
+ {
2025
+ active: markup.showOriginal,
2026
+ compact: isCompact,
2027
+ onClick: () => {
2028
+ setAnnotating(false);
2029
+ markup.setShowOriginal((on) => !on);
2030
+ }
2031
+ }
2032
+ ),
2033
+ activeTab === "pdf" && markup.hasMarkup && !annotating && /* @__PURE__ */ jsxRuntime.jsx(
2034
+ chunkD3WFIFRY_cjs.DownloadMarkupButton,
2035
+ {
2036
+ onClick: () => void markup.downloadMarkup(),
2037
+ disabledReason: isSigned ? documentTools.SIGNED_LOCKED_REASON : void 0
2038
+ }
2039
+ ),
2040
+ activeTab === "pdf" && isImage && pdfBlob && /* @__PURE__ */ jsxRuntime.jsx(
2041
+ chunkT74Q3MCZ_cjs.ViewerImageActions,
2042
+ {
2043
+ compact: isCompact,
2044
+ onUseAsReference: support.useImageAsReference ? () => support.useImageAsReference(documentId) : void 0,
2045
+ onCrop: crop.handleOpenCrop
2046
+ }
2047
+ ),
2048
+ madeIn && /* @__PURE__ */ jsxRuntime.jsxs(
2049
+ ui.Button,
2050
+ {
2051
+ type: "button",
2052
+ variant: "outline",
2053
+ size: isCompact ? "icon" : "sm",
2054
+ onClick: () => openConversation(madeIn.id, {
2055
+ messageId: documentData?.source_message_ext_id ?? void 0
2056
+ }),
2057
+ title: `Open the thread it was made in: ${madeIn.title}`,
2058
+ "aria-label": `Open the thread it was made in: ${madeIn.title}`,
2059
+ "data-testid": "document-open-thread",
2060
+ children: [
2061
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "size-4" }),
2062
+ !isCompact && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "max-w-[10rem] truncate", children: madeIn.title })
2063
+ ]
2064
+ }
2065
+ ),
2066
+ documentId && doc.workspaceId && /* @__PURE__ */ jsxRuntime.jsx(
2067
+ chunkVLCY46K6_cjs.ShareControl,
2068
+ {
2069
+ state: documentData?.shared ? "shared" : "private",
2070
+ onToggle: share,
2071
+ disabled: !canChangeVisibility(documentData, currentUserId),
2072
+ disabledTooltip: "Only the owner can change visibility",
2073
+ tooltip: documentData?.shared ? "Shared with the workspace \u2014 click to share with specific people" : "Share with the workspace, then optionally notify specific people by email",
2074
+ variant: "outline",
2075
+ compact: isCompact,
2076
+ showState: !isCompact,
2077
+ labels: {
2078
+ shared: ui.getEntityLabel("WORKSPACE"),
2079
+ private: "Only you",
2080
+ mixed: "Partly shared"
2081
+ },
2082
+ testId: "share-document-button",
2083
+ stateTestId: "document-title-shared-indicator"
2084
+ }
2085
+ ),
2086
+ tools.emailDocument && !isDraft && !isStreaming && documentData?.file_name && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2087
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mx-1 h-5 w-px bg-border", "aria-hidden": "true" }),
2088
+ /* @__PURE__ */ jsxRuntime.jsxs(
2089
+ ui.Button,
2090
+ {
2091
+ type: "button",
2092
+ variant: "outline",
2093
+ size: isCompact ? "icon" : "sm",
2094
+ title: "Email this document",
2095
+ "aria-label": "Email",
2096
+ "data-testid": "email-document-button",
2097
+ className: "pointer-coarse:min-h-11",
2098
+ onClick: () => tools.emailDocument?.(shownRef),
2099
+ children: [
2100
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Mail, { className: "size-4" }),
2101
+ !isCompact && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1", children: "Email" })
2102
+ ]
2103
+ }
2104
+ )
2105
+ ] }),
2106
+ support.translate && !isDraft && !isStreaming && !liveKind && !isImage && documentData?.file_name && /* @__PURE__ */ jsxRuntime.jsxs(
2107
+ ui.Button,
2108
+ {
2109
+ type: "button",
2110
+ variant: "outline",
2111
+ size: isCompact ? "icon" : "sm",
2112
+ title: "Translate into another language: a new editable document, original and translation side by side",
2113
+ "aria-label": "Translate",
2114
+ "data-testid": "translate-document-button",
2115
+ className: "pointer-coarse:min-h-11",
2116
+ onClick: () => support.translate(shownRef),
2117
+ children: [
2118
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Languages, { className: "size-4" }),
2119
+ !isCompact && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1", children: "Translate" })
2120
+ ]
2121
+ }
2122
+ ),
2123
+ !isStreaming && !snapshotDocumentId && /* @__PURE__ */ jsxRuntime.jsx(FinaliseTranslationButton, { document: documentData ?? void 0, isCompact }),
2124
+ annotatable && /* @__PURE__ */ jsxRuntime.jsx(
2125
+ chunkD3WFIFRY_cjs.SignButton,
2126
+ {
2127
+ active: placingSignature,
2128
+ compact: isCompact,
2129
+ onClick: () => {
2130
+ setAnnotating(false);
2131
+ setSignatureFlow(null);
2132
+ setPlacingSignature((on) => !on);
2133
+ }
2134
+ }
2135
+ ),
2136
+ annotatable && !isSigned && /* @__PURE__ */ jsxRuntime.jsx(
2137
+ chunkD3WFIFRY_cjs.RequestSignaturesButton,
2138
+ {
2139
+ active: signatureFlow?.kind === "prepare",
2140
+ compact: isCompact,
2141
+ onClick: () => {
2142
+ setAnnotating(false);
2143
+ setPlacingSignature(false);
2144
+ setSignatureFlow(signatureFlow?.kind === "prepare" ? null : { kind: "prepare" });
2145
+ }
2146
+ }
2147
+ ),
2148
+ isSignOpen && pdfBlob && /* @__PURE__ */ jsxRuntime.jsx(
2149
+ chunkJH6JTI76_cjs.SignDocumentDialog,
2150
+ {
2151
+ open: isSignOpen,
2152
+ onOpenChange: setIsSignOpen,
2153
+ documentId,
2154
+ pdfBlob,
2155
+ version: documentData?.current_version ?? void 0,
2156
+ appearance: signAppearance
2157
+ }
2158
+ ),
2159
+ headerActions
2160
+ ] });
2161
+ const viewerProps = {
2162
+ currentPage: viewingDocumentPage || void 0,
2163
+ onLoadSuccess: handleLoadSuccess,
2164
+ scrollTrigger,
2165
+ zoom,
2166
+ onZoomChange: setZoom
2167
+ };
2168
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2169
+ chunkT74Q3MCZ_cjs.ViewerFrame,
2170
+ {
2171
+ frameRef: containerRef,
2172
+ contentId: documentId,
2173
+ header: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2174
+ /* @__PURE__ */ jsxRuntime.jsx(
2175
+ chunk7RGLTF76_cjs.TabHeader,
2176
+ {
2177
+ tabs: [],
2178
+ activeTabId: activeTab,
2179
+ onTabChange: handleTabChange,
2180
+ leftContent,
2181
+ rightContent,
2182
+ variant: "underline"
2183
+ }
2184
+ ),
2185
+ isCompact && !isCoEditing && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-slot": "viewer-title-row", className: "flex min-w-0 items-center gap-2 px-3 pb-2", children: titleBlock }),
2186
+ snapshotDocumentId && /* @__PURE__ */ jsxRuntime.jsx(
2187
+ chunkD3WFIFRY_cjs.VersionSnapshotBar,
2188
+ {
2189
+ versionNumber: snapshotNumber,
2190
+ live: isDocx || isArtifact,
2191
+ onAsk: support.askAboutVersion ? () => support.askAboutVersion(snapshotDocumentId) : void 0,
2192
+ onReturn: () => setSnapshotDocumentId(null)
2193
+ }
2194
+ )
2195
+ ] }),
2196
+ compareRow: isComparing ? compareIndicator || void 0 : void 0,
2197
+ footer: (
2198
+ // Crop to a new document. Full resolution (no maxSize): a crop frames, it never downscales.
2199
+ /* @__PURE__ */ jsxRuntime.jsx(
2200
+ react.ImageCropModal,
2201
+ {
2202
+ open: crop.cropImageUrl !== null,
2203
+ image: crop.cropImageUrl,
2204
+ title: "Crop image",
2205
+ saveLabel: "Save as a copy",
2206
+ aspectOptions: react.DEFAULT_ASPECT_OPTIONS,
2207
+ output: { mimeType: "image/png" },
2208
+ onComplete: crop.handleCropComplete,
2209
+ onCancel: crop.closeCrop
2210
+ }
2211
+ )
2212
+ ),
2213
+ children: [
2214
+ isComparing && /* @__PURE__ */ jsxRuntime.jsx(React.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.ViewerMessage, { children: "Loading comparison\u2026" }), children: /* @__PURE__ */ jsxRuntime.jsx(
2215
+ NativeDocxComparison,
2216
+ {
2217
+ baseId: compareDocumentId,
2218
+ revisedId: documentId,
2219
+ title: documentTitle
2220
+ }
2221
+ ) }),
2222
+ isCaptureDraft && support.renderCaptureDraft?.(documentId),
2223
+ !isCaptureDraft && (activeTab === "pdf" || isMedia && activeTab === "html") && !isArtifact && !isComparing && /* @__PURE__ */ jsxRuntime.jsxs(chunkUWIILWDI_cjs.ViewerPane, { hidden: activeTab !== "pdf", children: [
2224
+ /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.DocumentLabelBar, { summaries: labelSummaries }),
2225
+ !isMedia && !isImage && signatureBanner,
2226
+ activeTab === "pdf" && !isMedia && !isImage && /* @__PURE__ */ jsxRuntime.jsx(
2227
+ chunkD3WFIFRY_cjs.MarkupNotices,
2228
+ {
2229
+ legacyPrompt: markup.legacyPrompt,
2230
+ olderNote: markup.olderNote,
2231
+ onOpenVersion: (n) => setSnapshotDocumentId(`${documentId}@v${n}`)
2232
+ }
2233
+ ),
2234
+ /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.ViewerControlBar, { controls: activeTab === "pdf" && pageNav, children: /* @__PURE__ */ jsxRuntime.jsx(
2235
+ ViewerPdfPane,
2236
+ {
2237
+ documentId,
2238
+ doc,
2239
+ pdfBlob,
2240
+ isPdfLoading: blobs.isPdfLoading,
2241
+ pdfError: blobs.pdfError,
2242
+ onDownload: () => void handleDirectDownload(),
2243
+ viewerProps,
2244
+ signatureFlow,
2245
+ onSignatureFlow: setSignatureFlow,
2246
+ currentUserId,
2247
+ placingSignature,
2248
+ onPlacingDone: (appearance) => {
2249
+ setPlacingSignature(false);
2250
+ if (!appearance) return;
2251
+ setSignAppearance(appearance);
2252
+ setIsSignOpen(true);
2253
+ },
2254
+ annotating,
2255
+ markup,
2256
+ pdfSnapshotNumber,
2257
+ isSigned
2258
+ }
2259
+ ) })
2260
+ ] }),
2261
+ activeTab === "preview" && isArtifact && liveKind && // The preview loads its JSX compiler on first use, so it stays out of the main bundle.
2262
+ /* @__PURE__ */ jsxRuntime.jsx(
2263
+ chunk2YV7FBLO_cjs.ArtifactPreview,
2264
+ {
2265
+ kind: liveKind,
2266
+ source: liveSource,
2267
+ isStreaming,
2268
+ runtimeUrl: artifactRuntimeUrl
2269
+ }
2270
+ ),
2271
+ activeTab === "edit" && isArtifact && liveKind && /* @__PURE__ */ jsxRuntime.jsx(chunk2YV7FBLO_cjs.ArtifactCodeView, { source: liveSource, fileName: documentData?.file_name ?? void 0 }),
2272
+ activeTab === "edit" && isArtifact && !liveKind && !isStreaming && !isComparing && /* @__PURE__ */ jsxRuntime.jsxs(React.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.ViewerMessage, { children: "Loading editor\u2026" }), children: [
2273
+ isSigned && !snapshotDocumentId && /* @__PURE__ */ jsxRuntime.jsx(chunkD3WFIFRY_cjs.SignedEditNote, {}),
2274
+ /* @__PURE__ */ jsxRuntime.jsx(
2275
+ NativeDocxEditor,
2276
+ {
2277
+ documentId: snapshotDocumentId || documentId,
2278
+ title: documentTitle,
2279
+ draftContent: isDraft ? draftDoc?.content || "" : void 0,
2280
+ snapshot: !!snapshotDocumentId,
2281
+ onSaved: (id) => {
2282
+ if (!isDraft) return;
2283
+ support.onDraftSaved?.(documentId, id);
2284
+ setViewingDocumentId(id);
2285
+ }
2286
+ },
2287
+ `${snapshotDocumentId || documentId}-${snapshotDocumentId ? "snapshot" : "live"}`
2288
+ )
2289
+ ] }),
2290
+ activeTab === "versions" && (isArtifact || isDocx || hasHistory) && !isComparing && /* @__PURE__ */ jsxRuntime.jsx(
2291
+ chunk2YV7FBLO_cjs.VersionTimeline,
2292
+ {
2293
+ versions: versions.map((v) => ({
2294
+ ...v,
2295
+ madeIn: v.thread ? {
2296
+ label: threadTitle(v.thread.conversationId),
2297
+ onOpen: () => openConversation(v.thread.conversationId, {
2298
+ messageId: v.thread.messageId ?? void 0
2299
+ })
2300
+ } : null
2301
+ })),
2302
+ currentId: currentVersionId,
2303
+ live: !!liveKind,
2304
+ labels: isArtifact ? void 0 : { emptyDocument: UPLOADED_NO_VERSIONS },
2305
+ formatDate,
2306
+ onOpen: (id) => {
2307
+ setSnapshotDocumentId(id === currentVersionId ? null : id);
2308
+ setActiveTab(isArtifact ? "edit" : isDocx ? "docx" : "pdf");
2309
+ },
2310
+ onCompare: (id) => session.setDocumentViewer({ compareId: id, tab: "html" }),
2311
+ translations,
2312
+ onOpenTranslation: (id) => setViewingDocumentId(id)
2313
+ }
2314
+ ),
2315
+ activeTab === "xlsx" && isXlsx && (xlsxBlob ? /* @__PURE__ */ jsxRuntime.jsx(viewers.XlsxViewer, { blob: xlsxBlob }) : /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.ViewerMessage, { children: xlsxError ? "Failed to load spreadsheet" : "Loading spreadsheet..." })),
2316
+ activeTab === "docx" && isDocx && !isComparing && /* @__PURE__ */ jsxRuntime.jsxs(React.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.ViewerMessage, { children: "Loading editor\u2026" }), children: [
2317
+ signatureBanner,
2318
+ isSigned && !snapshotDocumentId && /* @__PURE__ */ jsxRuntime.jsx(chunkD3WFIFRY_cjs.SignedEditNote, {}),
2319
+ /* @__PURE__ */ jsxRuntime.jsx(
2320
+ NativeDocxEditor,
2321
+ {
2322
+ documentId: snapshotDocumentId || documentId,
2323
+ title: documentTitle,
2324
+ snapshot: !!snapshotDocumentId
2325
+ },
2326
+ `${snapshotDocumentId || documentId}-${snapshotDocumentId ? "snapshot" : "live"}`
2327
+ )
2328
+ ] }),
2329
+ streamingDoc && isStreaming && isArtifact && !liveKind && !isComparing && (activeTab === "html" || activeTab === "edit") && /* @__PURE__ */ jsxRuntime.jsx(React.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.ViewerMessage, { children: "Opening draft\u2026" }), children: /* @__PURE__ */ jsxRuntime.jsx(
2330
+ StreamedWordArtifact,
2331
+ {
2332
+ documentId: documentId.startsWith("doc-") ? documentId : void 0,
2333
+ title: documentTitle,
2334
+ content: streamingDoc.content,
2335
+ busy: isStreaming
2336
+ },
2337
+ documentId
2338
+ ) }),
2339
+ !isCaptureDraft && !isComparing && activeTab === "html" && !(isStreaming && isArtifact && !liveKind) && /* @__PURE__ */ jsxRuntime.jsx(chunkUWIILWDI_cjs.ViewerPane, { children: /* @__PURE__ */ jsxRuntime.jsx(chunkT74Q3MCZ_cjs.ViewerControlBar, { controls: pageNav, children: /* @__PURE__ */ jsxRuntime.jsx(
2340
+ ParsedTextView,
2341
+ {
2342
+ documentId: pdfSnapshotId || documentId,
2343
+ onLoadSuccess: handleLoadSuccess,
2344
+ scrollTrigger,
2345
+ zoom,
2346
+ onZoomChange: setZoom
2347
+ }
2348
+ ) }) })
2349
+ ]
2350
+ }
2351
+ );
2352
+ }
2353
+
2354
+ exports.ConnectedDocumentToolsProvider = ConnectedDocumentToolsProvider;
2355
+ exports.ConnectedDocumentViewer = ConnectedDocumentViewer;
2356
+ //# sourceMappingURL=viewer.cjs.map
2357
+ //# sourceMappingURL=viewer.cjs.map