@opengeni/react 6.5.2-canary.41607687019001 → 6.7.0

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 (1154) hide show
  1. package/dist/app/app-state.d.ts +4 -0
  2. package/dist/app/app-state.js +19 -14
  3. package/dist/app/components/Composer.js +25 -23
  4. package/dist/app/components/agent/agent-capability-picker.js +10 -8
  5. package/dist/app/components/artifacts/artifact-browse-controls.js +4 -4
  6. package/dist/app/components/artifacts/artifact-library.js +21 -19
  7. package/dist/app/components/artifacts/artifact-page-chrome.js +3 -3
  8. package/dist/app/components/artifacts/artifact-viewer.js +23 -22
  9. package/dist/app/components/artifacts/artifact-viewer.js.map +1 -1
  10. package/dist/app/components/artifacts/chat-interactive-block.js +12 -12
  11. package/dist/app/components/artifacts/copy-artifact-link.js +7 -5
  12. package/dist/app/components/artifacts/file-reach-dialog.js +11 -9
  13. package/dist/app/components/artifacts/inline-chat-image.js +18 -18
  14. package/dist/app/components/artifacts/retained-file-preview.js +24 -23
  15. package/dist/app/components/artifacts/retained-text-preview.js +3 -3
  16. package/dist/app/components/artifacts/site-audience.js +6 -5
  17. package/dist/app/components/artifacts/site-conversations.js +16 -14
  18. package/dist/app/components/artifacts/site-data.js +18 -16
  19. package/dist/app/components/artifacts/site-public-link.js +3 -2
  20. package/dist/app/components/artifacts/site-publishing-page.js +39 -37
  21. package/dist/app/components/artifacts/site-publishing.js +34 -32
  22. package/dist/app/components/artifacts/site-settings.js +38 -36
  23. package/dist/app/components/artifacts/site-version-menu.js +8 -7
  24. package/dist/app/components/billing-class-mark.js +3 -3
  25. package/dist/app/components/bots/bot-launch-strip.js +17 -17
  26. package/dist/app/components/bots/bot-template-dialog.js +30 -28
  27. package/dist/app/components/bots/bot-template-shortcuts.js +19 -19
  28. package/dist/app/components/bots/bot-templates-page.js +38 -36
  29. package/dist/app/components/bots/bot-templates-page.js.map +1 -1
  30. package/dist/app/components/capabilities/capability-detail-sheet.js +13 -11
  31. package/dist/app/components/capabilities/capability-logo-source.js +13 -13
  32. package/dist/app/components/capabilities/capability-logo.js +4 -3
  33. package/dist/app/components/capabilities/connector-tool-permissions.js +8 -6
  34. package/dist/app/components/capabilities/native-connect-setup.js +14 -14
  35. package/dist/app/components/capabilities/own-logins-shared-heads-up.js +7 -6
  36. package/dist/app/components/capabilities/perform-capability-action.js +7 -6
  37. package/dist/app/components/capabilities/prepared-mcp-setup-card.js +17 -17
  38. package/dist/app/components/capabilities/session-capability-card.js +72 -70
  39. package/dist/app/components/capabilities/session-capability-card.js.map +1 -1
  40. package/dist/app/components/capabilities/session-chrome-card.js +28 -26
  41. package/dist/app/components/capabilities/session-connection-accounts.js +4 -3
  42. package/dist/app/components/capabilities/session-custom-mcp-card.js +20 -19
  43. package/dist/app/components/capabilities/session-github-card.js +22 -20
  44. package/dist/app/components/capabilities/session-machine-card.js +27 -25
  45. package/dist/app/components/capabilities/session-personal-github-card.js +16 -16
  46. package/dist/app/components/capabilities/session-plugin-card.js +10 -9
  47. package/dist/app/components/capabilities/use-capabilities-catalog.js +4 -3
  48. package/dist/app/components/capabilities/use-connection-accounts.js +5 -4
  49. package/dist/app/components/command-menu/chat-status.js +15 -13
  50. package/dist/app/components/command-menu/chat-switcher.js +35 -33
  51. package/dist/app/components/command-menu/chat-switcher.js.map +1 -1
  52. package/dist/app/components/command-menu/command-menu.js +53 -50
  53. package/dist/app/components/command-menu/command-menu.js.map +1 -1
  54. package/dist/app/components/command-menu/shortcut-sheet.js +18 -16
  55. package/dist/app/components/command-menu/shortcut-sheet.js.map +1 -1
  56. package/dist/app/components/common.js +4 -3
  57. package/dist/app/components/composer-capabilities-menu-body.js +4 -4
  58. package/dist/app/components/composer-mobile-plus-panel.js +8 -8
  59. package/dist/app/components/composer-mobile-plus.js +1 -1
  60. package/dist/app/components/credit-required-gate.js +3 -3
  61. package/dist/app/components/credit-required-prompt.js +10 -8
  62. package/dist/app/components/credit-required-prompt.js.map +1 -1
  63. package/dist/app/components/credits/checkout-credits-celebration.js +3 -2
  64. package/dist/app/components/credits/checkout-return.js +3 -2
  65. package/dist/app/components/credits/checkout-return.js.map +1 -1
  66. package/dist/app/components/credits/coupon-redeem.js +5 -4
  67. package/dist/app/components/credits/credit-refusal-notice.js +7 -5
  68. package/dist/app/components/cross-slot-deep-link-recovery.js +5 -4
  69. package/dist/app/components/desktop/app-shots.js +13 -11
  70. package/dist/app/components/desktop/computer-use.js +6 -4
  71. package/dist/app/components/desktop/this-computer.js +9 -7
  72. package/dist/app/components/feedback.js +5 -4
  73. package/dist/app/components/follow-up-repository-menu-body.js +8 -6
  74. package/dist/app/components/follow-up-repository-menu-body.js.map +1 -1
  75. package/dist/app/components/follow-up-repository-picker.js +1 -1
  76. package/dist/app/components/github-app-connect-launcher.js +5 -4
  77. package/dist/app/components/in-app-help-link.js +3 -3
  78. package/dist/app/components/knowledge/agent-learning-settings.js +3 -2
  79. package/dist/app/components/knowledge/agent-learning-settings.js.map +1 -1
  80. package/dist/app/components/machines/connect-machine-dialog.js +18 -16
  81. package/dist/app/components/manual-repository-editor.js +3 -2
  82. package/dist/app/components/markdown.js +6 -6
  83. package/dist/app/components/models/models-ui.js +12 -10
  84. package/dist/app/components/my-things.js +12 -10
  85. package/dist/app/components/my-things.js.map +1 -1
  86. package/dist/app/components/new-session-starters.js +3 -3
  87. package/dist/app/components/own-where-it-works.js +9 -7
  88. package/dist/app/components/personal-resource-attachment-surface.js +4 -4
  89. package/dist/app/components/pickers.js +5 -5
  90. package/dist/app/components/rail/channel-create-dialog.js +7 -5
  91. package/dist/app/components/rail/project-glyph.js +17 -17
  92. package/dist/app/components/rail/project-profile.js +31 -29
  93. package/dist/app/components/rail/rail-context.js +3 -3
  94. package/dist/app/components/rail/rail-sections.js +68 -66
  95. package/dist/app/components/rail/session-header.js +59 -57
  96. package/dist/app/components/rail/session-list.js +66 -64
  97. package/dist/app/components/rail/session-row-content.js +4 -4
  98. package/dist/app/components/rail/session-row-hover-details.js +14 -12
  99. package/dist/app/components/rail/session-shell.js +90 -88
  100. package/dist/app/components/rail/site-session-group-heading.js +8 -8
  101. package/dist/app/components/repository-picker.js +8 -6
  102. package/dist/app/components/secrets/session-secrets-panel.js +4 -3
  103. package/dist/app/components/secrets/vault-model.js +3 -2
  104. package/dist/app/components/session/agent-configuration-panel.js +25 -23
  105. package/dist/app/components/session/agent-configuration-panel.js.map +1 -1
  106. package/dist/app/components/session/artifact-link-boundary.js +3 -3
  107. package/dist/app/components/session/artifact-session-page.js +11 -9
  108. package/dist/app/components/session/banners.js +8 -8
  109. package/dist/app/components/session/codex-usage-notice.js +5 -3
  110. package/dist/app/components/session/console-new-conversation.js +42 -40
  111. package/dist/app/components/session/context-text-reader.js +3 -2
  112. package/dist/app/components/session/descendant-requests.js +39 -37
  113. package/dist/app/components/session/descendant-requests.js.map +1 -1
  114. package/dist/app/components/session/editable-artifacts-workspace.js +36 -34
  115. package/dist/app/components/session/editable-artifacts-workspace.js.map +1 -1
  116. package/dist/app/components/session/failed-session-banner.js +13 -11
  117. package/dist/app/components/session/failed-session-banner.js.map +1 -1
  118. package/dist/app/components/session/failure-recovery-boundary.js +3 -3
  119. package/dist/app/components/session/human-input-delegation-record.js +2 -2
  120. package/dist/app/components/session/human-input.js +33 -31
  121. package/dist/app/components/session/inspector.js +57 -55
  122. package/dist/app/components/session/inspector.js.map +1 -1
  123. package/dist/app/components/session/message-actions.js +5 -4
  124. package/dist/app/components/session/message-actions.js.map +1 -1
  125. package/dist/app/components/session/message-resource-attachments.js +12 -11
  126. package/dist/app/components/session/message-resource-attachments.js.map +1 -1
  127. package/dist/app/components/session/model-context-inspector.js +6 -4
  128. package/dist/app/components/session/model-recovery-notice.js +3 -3
  129. package/dist/app/components/session/new-session-settings-menu.js +11 -9
  130. package/dist/app/components/session/new-session-setup-strip.js +18 -18
  131. package/dist/app/components/session/sandbox-recovery-actions.js +3 -3
  132. package/dist/app/components/session/sandbox-switcher.js +10 -9
  133. package/dist/app/components/session/sandbox-workspace.js +47 -46
  134. package/dist/app/components/session/search-markdown-highlight.js +7 -7
  135. package/dist/app/components/session/search-results-view.js +8 -8
  136. package/dist/app/components/session/session-admin-access.js +13 -11
  137. package/dist/app/components/session/session-admission-notice.js +7 -5
  138. package/dist/app/components/session/session-avatar-picker.js +22 -20
  139. package/dist/app/components/session/session-avatar.js +16 -16
  140. package/dist/app/components/session/session-machine-access-notice.js +7 -5
  141. package/dist/app/components/session/session-profile-dialog.js +29 -27
  142. package/dist/app/components/session/session-profile-editor.js +30 -28
  143. package/dist/app/components/session/session-retention.js +10 -8
  144. package/dist/app/components/session/session-search-dialog.js +10 -10
  145. package/dist/app/components/session/session-skill-reviews.js +2 -1
  146. package/dist/app/components/session/session-skill-reviews.js.map +1 -1
  147. package/dist/app/components/session/session-tenancy-control.js +13 -11
  148. package/dist/app/components/session/session-tenancy-control.js.map +1 -1
  149. package/dist/app/components/session/session-unattended-setting.js +7 -5
  150. package/dist/app/components/session/session-usage-limit-section.js +11 -9
  151. package/dist/app/components/session/share-chat-dialog.js +9 -7
  152. package/dist/app/components/session/site-origin-link.js +3 -3
  153. package/dist/app/components/session/subagents.js +8 -8
  154. package/dist/app/components/session/subscription-account-indicator.js +6 -6
  155. package/dist/app/components/session-connectors-menu-body.js +4 -3
  156. package/dist/app/components/session-connectors-menu-body.js.map +1 -1
  157. package/dist/app/components/settings/row-select.js +7 -5
  158. package/dist/app/components/toaster.js +3 -2
  159. package/dist/app/components/transcription-settings.js +11 -9
  160. package/dist/app/components/ui/destructive-confirm.js +11 -9
  161. package/dist/app/components/usage/usage-entry.js +5 -5
  162. package/dist/app/components/window-bar.js +16 -14
  163. package/dist/app/components/workspace-composer-plus.js +22 -21
  164. package/dist/app/components/workspace-reach.js +6 -4
  165. package/dist/app/components/workspace-tenant-boundary.js +5 -4
  166. package/dist/app/embed/memory-navigation.js +3 -3
  167. package/dist/app/embed/session-app.js +211 -209
  168. package/dist/app/lib/actions/actions-provider.js +15 -13
  169. package/dist/app/lib/agent-capabilities.js +3 -3
  170. package/dist/app/lib/app-surfaces.js +7 -6
  171. package/dist/app/lib/archive-session.d.ts +9 -4
  172. package/dist/app/lib/archive-session.js +4 -2
  173. package/dist/app/lib/bot-templates.js +3 -2
  174. package/dist/app/lib/capabilities.js +3 -2
  175. package/dist/app/lib/codex-usage-query.js +2 -2
  176. package/dist/app/lib/composer-connectors.js +17 -16
  177. package/dist/app/lib/console-site.js +2 -2
  178. package/dist/app/lib/console-text.js +2 -2
  179. package/dist/app/lib/events.js +9 -9
  180. package/dist/app/lib/failed-session-copy.js +3 -3
  181. package/dist/app/lib/inbox.js +4 -2
  182. package/dist/app/lib/model-access-onboarding.js +3 -3
  183. package/dist/app/lib/move-chat-to-machine.js +3 -3
  184. package/dist/app/lib/navigation.js +2 -2
  185. package/dist/app/lib/session-branch-cache.js +6 -6
  186. package/dist/app/lib/session-create.js +4 -4
  187. package/dist/app/lib/session-group-pagination.js +6 -6
  188. package/dist/app/lib/session-hover-facts.js +13 -11
  189. package/dist/app/lib/session-model.js +2 -2
  190. package/dist/app/lib/session-rail.js +3 -3
  191. package/dist/app/lib/session-rename.js +3 -3
  192. package/dist/app/lib/session-restart-operation-controller.js +4 -3
  193. package/dist/app/lib/session-tenancy.js +3 -2
  194. package/dist/app/lib/session-usage-limit.js +3 -2
  195. package/dist/app/lib/sessions-group.js +5 -5
  196. package/dist/app/lib/site-publishing.js +3 -2
  197. package/dist/app/lib/site-tool-consent-dialog.js +9 -7
  198. package/dist/app/lib/site-tool-consent-dialog.js.map +1 -1
  199. package/dist/app/lib/site-tool-consent.js +1 -1
  200. package/dist/app/lib/subscription-plans.js +3 -2
  201. package/dist/app/lib/toast.js +2 -1
  202. package/dist/app/lib/turn-failure-analytics.js +4 -4
  203. package/dist/app/lib/use-duplicate-site.js +6 -5
  204. package/dist/app/lib/use-follow-up-repositories.js +6 -5
  205. package/dist/app/lib/use-workspace-integrations.js +4 -3
  206. package/dist/app/lib/use-workspace-machines.js +4 -4
  207. package/dist/app/lib/use-workspace-model-catalog.js +5 -4
  208. package/dist/app/lib/use-workspace-rigs.js +2 -2
  209. package/dist/app/lib/workspace-navigation-preference.js +4 -4
  210. package/dist/app/lib/workspace-scope-context.js +3 -3
  211. package/dist/app/routes/artifacts.js +67 -66
  212. package/dist/app/routes/artifacts.js.map +1 -1
  213. package/dist/app/routes/retained-artifact.js +42 -40
  214. package/dist/app/routes/retained-artifact.js.map +1 -1
  215. package/dist/app/routes/session-unavailable.js +8 -7
  216. package/dist/app/routes/session.js +119 -117
  217. package/dist/app/routes/sessions-index-hydration.js +5 -5
  218. package/dist/app/routes/sessions-index.js +104 -102
  219. package/dist/app/routes/site-view.js +67 -65
  220. package/dist/app/routes/site-view.js.map +1 -1
  221. package/dist/artifacts-document.js +4 -4
  222. package/dist/artifacts-presentation.js +4 -4
  223. package/dist/artifacts-spreadsheet.js +4 -4
  224. package/dist/artifacts.js +10 -10
  225. package/dist/automations.js +17 -15
  226. package/dist/automations.js.map +1 -1
  227. package/dist/browser-viewer-TC27OCIP.js +23 -0
  228. package/dist/chat-interactive-block-RWPQBHVS.js +18 -0
  229. package/dist/chunk-2BDT3UZQ.js +229 -0
  230. package/dist/chunk-2CLNIEK4.js +373 -0
  231. package/dist/chunk-2FSBSCZJ.js +451 -0
  232. package/dist/chunk-2I7HDP53.js +199 -0
  233. package/dist/chunk-2INLDVK3.js +15 -0
  234. package/dist/chunk-2KALVELR.js +126 -0
  235. package/dist/chunk-2M3J7ZWQ.js +418 -0
  236. package/dist/chunk-2OP6WLGV.js +708 -0
  237. package/dist/chunk-2RG7NIAS.js +2936 -0
  238. package/dist/chunk-2STUPWEL.js +135 -0
  239. package/dist/chunk-2YUOVM3G.js +271 -0
  240. package/dist/chunk-2Z3NQNTM.js +3670 -0
  241. package/dist/chunk-3CPWWGNK.js +920 -0
  242. package/dist/chunk-3ED2U6XE.js +37 -0
  243. package/dist/chunk-3GZA4BUW.js +216 -0
  244. package/dist/chunk-3IK6UYO6.js +1022 -0
  245. package/dist/chunk-3PZ7JZI2.js +431 -0
  246. package/dist/chunk-4DVJ6ONS.js +50 -0
  247. package/dist/chunk-4DVNUCRR.js +2386 -0
  248. package/dist/chunk-4DVNUCRR.js.map +1 -0
  249. package/dist/chunk-4E3ZJRTZ.js +41 -0
  250. package/dist/chunk-4SAWSRAA.js +141 -0
  251. package/dist/chunk-53AGXXZM.js +307 -0
  252. package/dist/chunk-54YW6SZZ.js +818 -0
  253. package/dist/chunk-57AZS3IE.js +2317 -0
  254. package/dist/chunk-5CPEEAFD.js +143 -0
  255. package/dist/chunk-5EWSRZ2Y.js +340 -0
  256. package/dist/chunk-5IE76VCY.js +387 -0
  257. package/dist/chunk-5NWEKLDZ.js +170 -0
  258. package/dist/chunk-5O2FCCHZ.js +198 -0
  259. package/dist/chunk-5QAY6K77.js +399 -0
  260. package/dist/chunk-5YKW2K6I.js +625 -0
  261. package/dist/chunk-5YKW2K6I.js.map +1 -0
  262. package/dist/chunk-6BCXNDEI.js +4116 -0
  263. package/dist/chunk-6BCXNDEI.js.map +1 -0
  264. package/dist/chunk-6DK6Z4UN.js +2599 -0
  265. package/dist/chunk-6DVCC7QS.js +702 -0
  266. package/dist/chunk-6JHU2UBS.js +2058 -0
  267. package/dist/chunk-6PZ7OBYU.js +490 -0
  268. package/dist/chunk-6WD2INST.js +539 -0
  269. package/dist/chunk-6WD2INST.js.map +1 -0
  270. package/dist/chunk-6WGRDRMA.js +163 -0
  271. package/dist/chunk-77WAKEAH.js +186 -0
  272. package/dist/chunk-7T2ZE3VT.js +5558 -0
  273. package/dist/chunk-7T2ZE3VT.js.map +1 -0
  274. package/dist/chunk-7TDO3CUM.js +393 -0
  275. package/dist/chunk-7TIX2UAR.js +247 -0
  276. package/dist/chunk-7V5REBCP.js +148 -0
  277. package/dist/chunk-7VMZGLYI.js +339 -0
  278. package/dist/chunk-7W37NS3I.js +236 -0
  279. package/dist/chunk-7X6SDK2C.js +111 -0
  280. package/dist/chunk-7ZNUHRP5.js +95 -0
  281. package/dist/chunk-A36PZALD.js +84 -0
  282. package/dist/chunk-AUI6VA63.js +107 -0
  283. package/dist/chunk-AW2MQB37.js +24 -0
  284. package/dist/chunk-AWKES45Y.js +198 -0
  285. package/dist/chunk-AXHZYXUV.js +132 -0
  286. package/dist/chunk-BHNSJVBC.js +129 -0
  287. package/dist/chunk-BJEJFISW.js +50 -0
  288. package/dist/chunk-BJFH6JI5.js +422 -0
  289. package/dist/chunk-BMICEQZQ.js +960 -0
  290. package/dist/chunk-BTLBYBLU.js +29 -0
  291. package/dist/chunk-BXBDYNRP.js +89 -0
  292. package/dist/chunk-C372BFOV.js +357 -0
  293. package/dist/chunk-C43KRXGA.js +234 -0
  294. package/dist/chunk-C43KRXGA.js.map +1 -0
  295. package/dist/chunk-CMKGILJK.js +4824 -0
  296. package/dist/chunk-CRAOSVHC.js +50 -0
  297. package/dist/chunk-CRU35QQH.js +281 -0
  298. package/dist/chunk-CUIWCGMA.js +172 -0
  299. package/dist/chunk-D5TWNFFE.js +38 -0
  300. package/dist/chunk-DF5EAHDN.js +4461 -0
  301. package/dist/chunk-DJAXC5OK.js +56 -0
  302. package/dist/chunk-DXBYWSL5.js +3550 -0
  303. package/dist/chunk-DXR5PDFP.js +84 -0
  304. package/dist/chunk-DZWARC4M.js +267 -0
  305. package/dist/chunk-DZXEDSQI.js +106 -0
  306. package/dist/chunk-E7XERZWC.js +48 -0
  307. package/dist/chunk-ECJBYNLJ.js +79 -0
  308. package/dist/chunk-EDI6SJ2N.js +43 -0
  309. package/dist/chunk-EWSOC6WF.js +114 -0
  310. package/dist/chunk-F2OPHAUN.js +103 -0
  311. package/dist/chunk-F4ISQGGM.js +81 -0
  312. package/dist/chunk-FO4LYKJL.js +197 -0
  313. package/dist/chunk-FPXASDG5.js +73 -0
  314. package/dist/chunk-FSOQDUCG.js +117 -0
  315. package/dist/chunk-FSOQDUCG.js.map +1 -0
  316. package/dist/chunk-FVXBNBHO.js +157 -0
  317. package/dist/chunk-FYWT2O76.js +34 -0
  318. package/dist/chunk-FYWT2O76.js.map +1 -0
  319. package/dist/chunk-FZC5N55X.js +981 -0
  320. package/dist/chunk-GAVYGBFI.js +99 -0
  321. package/dist/chunk-GFIMOUDT.js +846 -0
  322. package/dist/chunk-GFIMOUDT.js.map +1 -0
  323. package/dist/chunk-GKVJIDHF.js +33 -0
  324. package/dist/chunk-GVN5SZLX.js +212 -0
  325. package/dist/chunk-H3T7IWNA.js +134 -0
  326. package/dist/chunk-HAX4LCR5.js +261 -0
  327. package/dist/chunk-HC4JFZVU.js +121 -0
  328. package/dist/chunk-HEFPPMBQ.js +581 -0
  329. package/dist/chunk-HGKTHF2U.js +1356 -0
  330. package/dist/chunk-HGKTHF2U.js.map +1 -0
  331. package/dist/chunk-HNLR7Q4Z.js +83 -0
  332. package/dist/chunk-HSOXMJOT.js +12 -0
  333. package/dist/chunk-I4MRDSUF.js +281 -0
  334. package/dist/chunk-I4QEJ62Y.js +202 -0
  335. package/dist/chunk-I5B5L6Q4.js +56 -0
  336. package/dist/chunk-I5QZJODL.js +264 -0
  337. package/dist/chunk-I7ITSXSJ.js +603 -0
  338. package/dist/chunk-I7XIZRFD.js +390 -0
  339. package/dist/chunk-IDANQPRH.js +82 -0
  340. package/dist/chunk-IFB3WJ36.js +212 -0
  341. package/dist/chunk-IHTAKKTK.js +264 -0
  342. package/dist/chunk-IKXNLWAL.js +205 -0
  343. package/dist/chunk-IKXNLWAL.js.map +1 -0
  344. package/dist/chunk-ILDXWY37.js +173 -0
  345. package/dist/chunk-IMDQUHBJ.js +570 -0
  346. package/dist/chunk-IMZCQBOT.js +119 -0
  347. package/dist/chunk-IXPTECSC.js +403 -0
  348. package/dist/chunk-J255A3N5.js +71 -0
  349. package/dist/chunk-J5F5HPPW.js +141 -0
  350. package/dist/chunk-JDTGRRNU.js +5045 -0
  351. package/dist/chunk-JDTGRRNU.js.map +1 -0
  352. package/dist/chunk-JEA3QDX7.js +2469 -0
  353. package/dist/chunk-JEUPAVYY.js +156 -0
  354. package/dist/chunk-JKHKLL5W.js +194 -0
  355. package/dist/chunk-JQL7ZH6C.js +650 -0
  356. package/dist/chunk-JWB44UGJ.js +57 -0
  357. package/dist/chunk-JZ4NLCAP.js +333 -0
  358. package/dist/chunk-K2A5PXQ5.js +412 -0
  359. package/dist/chunk-K56XV3C3.js +623 -0
  360. package/dist/chunk-K6GAXXVA.js +23 -0
  361. package/dist/chunk-KCBMFSMS.js +199 -0
  362. package/dist/chunk-KF2FV3ZJ.js +268 -0
  363. package/dist/chunk-KJD65EJP.js +278 -0
  364. package/dist/chunk-KLEUWIMZ.js +386 -0
  365. package/dist/chunk-KODELWYT.js +309 -0
  366. package/dist/chunk-KRDR5RJD.js +83 -0
  367. package/dist/chunk-KUDGXAF7.js +914 -0
  368. package/dist/chunk-KY2R73CG.js +171 -0
  369. package/dist/chunk-KY2R73CG.js.map +1 -0
  370. package/dist/chunk-KYS77RPN.js +85 -0
  371. package/dist/chunk-L7YTNTIK.js +368 -0
  372. package/dist/chunk-LHPNABDH.js +686 -0
  373. package/dist/chunk-MFROMEKA.js +401 -0
  374. package/dist/chunk-MIHN76LX.js +2656 -0
  375. package/dist/chunk-MIYFS2XN.js +42 -0
  376. package/dist/chunk-MJUCFQMS.js +65 -0
  377. package/dist/chunk-MM4FNWI4.js +3064 -0
  378. package/dist/chunk-MNZG4OHU.js +790 -0
  379. package/dist/chunk-MVW6HNPI.js +250 -0
  380. package/dist/chunk-MVW6HNPI.js.map +1 -0
  381. package/dist/chunk-N6AACDUW.js +200 -0
  382. package/dist/chunk-NC55IFN3.js +781 -0
  383. package/dist/chunk-NC7PVOEK.js +98 -0
  384. package/dist/chunk-NCYMNCJO.js +70 -0
  385. package/dist/chunk-ND2BXV3P.js +259 -0
  386. package/dist/chunk-NDBTFUO6.js +272 -0
  387. package/dist/chunk-NDQJZ7HF.js +206 -0
  388. package/dist/chunk-NGJJJPZZ.js +162 -0
  389. package/dist/chunk-NJTSNNE7.js +251 -0
  390. package/dist/chunk-NPGISCU6.js +4159 -0
  391. package/dist/chunk-NPGISCU6.js.map +1 -0
  392. package/dist/chunk-NRTE7DNV.js +1270 -0
  393. package/dist/chunk-NULUNM7H.js +290 -0
  394. package/dist/chunk-NUNZS36W.js +227 -0
  395. package/dist/chunk-NW53H5RW.js +2424 -0
  396. package/dist/chunk-NXCMHIKI.js +263 -0
  397. package/dist/chunk-O3LKCBP5.js +159 -0
  398. package/dist/chunk-O4EA4F3W.js +103 -0
  399. package/dist/chunk-O4EA4F3W.js.map +1 -0
  400. package/dist/chunk-O4OOG3D6.js +116 -0
  401. package/dist/chunk-O4OOG3D6.js.map +1 -0
  402. package/dist/chunk-O6N4ABCA.js +376 -0
  403. package/dist/chunk-O732GAFC.js +112 -0
  404. package/dist/chunk-OF4TIKYC.js +690 -0
  405. package/dist/chunk-OMPVOMPP.js +70 -0
  406. package/dist/chunk-OPJJSKUK.js +118 -0
  407. package/dist/chunk-OPWCMA4D.js +196 -0
  408. package/dist/chunk-ORJPS5VN.js +1193 -0
  409. package/dist/chunk-OSY5K7L7.js +187 -0
  410. package/dist/chunk-OV6QJRT4.js +45 -0
  411. package/dist/chunk-OVKYVZMW.js +108 -0
  412. package/dist/chunk-OZCBM3UC.js +171 -0
  413. package/dist/chunk-P3A2EINJ.js +61 -0
  414. package/dist/chunk-PTAG4PDC.js +27 -0
  415. package/dist/chunk-PTF5B7TJ.js +298 -0
  416. package/dist/chunk-Q3DPEYX4.js +848 -0
  417. package/dist/chunk-Q6CGOPJD.js +215 -0
  418. package/dist/chunk-Q6CGOPJD.js.map +1 -0
  419. package/dist/chunk-QB2KMIDP.js +100 -0
  420. package/dist/chunk-QCSJ4CWE.js +1067 -0
  421. package/dist/chunk-QIOQ2NPQ.js +414 -0
  422. package/dist/chunk-QK5EFEUT.js +353 -0
  423. package/dist/chunk-QPQBLYQJ.js +41 -0
  424. package/dist/chunk-QPSGCC5D.js +184 -0
  425. package/dist/chunk-QZAAUQRN.js +474 -0
  426. package/dist/chunk-QZM6YDJW.js +489 -0
  427. package/dist/chunk-QZM6YDJW.js.map +1 -0
  428. package/dist/chunk-RGBI63KJ.js +188 -0
  429. package/dist/chunk-RLBKLAEY.js +138 -0
  430. package/dist/chunk-RMFKVOM7.js +304 -0
  431. package/dist/chunk-ROKQU7WG.js +258 -0
  432. package/dist/chunk-RPVREAU7.js +251 -0
  433. package/dist/chunk-RQKLF42C.js +723 -0
  434. package/dist/chunk-SC6RRD2D.js +38 -0
  435. package/dist/chunk-SC6RRD2D.js.map +1 -0
  436. package/dist/chunk-SEO7TICN.js +94 -0
  437. package/dist/chunk-SHHJCL7X.js +432 -0
  438. package/dist/chunk-SIRLACNZ.js +114 -0
  439. package/dist/chunk-SKPHMYAA.js +237 -0
  440. package/dist/chunk-SODC7T6L.js +1583 -0
  441. package/dist/chunk-SQJIKMN3.js +366 -0
  442. package/dist/chunk-SVINDKVW.js +26 -0
  443. package/dist/chunk-SYCDHPZF.js +335 -0
  444. package/dist/chunk-T2QX3FDP.js +133 -0
  445. package/dist/chunk-T3OWFVMS.js +1187 -0
  446. package/dist/chunk-T6XI5FLY.js +61 -0
  447. package/dist/chunk-T7OXJZCX.js +62 -0
  448. package/dist/chunk-TAT5USZN.js +353 -0
  449. package/dist/chunk-TPQTRNER.js +172 -0
  450. package/dist/chunk-TUIN4MB7.js +266 -0
  451. package/dist/chunk-TX3VECZU.js +71 -0
  452. package/dist/chunk-TXLIEOJX.js +9624 -0
  453. package/dist/chunk-U3DN4HEY.js +27 -0
  454. package/dist/chunk-U7XM7CB4.js +191 -0
  455. package/dist/chunk-UJK53QFL.js +140 -0
  456. package/dist/chunk-UMTXA2TH.js +319 -0
  457. package/dist/chunk-UPDSXFK5.js +199 -0
  458. package/dist/chunk-UTIAXH52.js +269 -0
  459. package/dist/chunk-UVN5TMHU.js +1184 -0
  460. package/dist/chunk-V4Z4B2E3.js +52 -0
  461. package/dist/chunk-V4Z4B2E3.js.map +1 -0
  462. package/dist/chunk-VGYXW3VG.js +246 -0
  463. package/dist/chunk-VS7AHPCZ.js +255 -0
  464. package/dist/chunk-VTTAJOQ7.js +121 -0
  465. package/dist/chunk-VWPOLUAO.js +99 -0
  466. package/dist/chunk-X3MWB2QU.js +3851 -0
  467. package/dist/chunk-X6KAJI3V.js +211 -0
  468. package/dist/chunk-XBLRHV5R.js +50 -0
  469. package/dist/chunk-XDFP2LMW.js +605 -0
  470. package/dist/chunk-XEQMZB3C.js +525 -0
  471. package/dist/chunk-XEYLT5VA.js +223 -0
  472. package/dist/chunk-XHIQ5I6N.js +918 -0
  473. package/dist/chunk-XLH7QY2R.js +378 -0
  474. package/dist/chunk-XWFAMUZQ.js +113 -0
  475. package/dist/chunk-Y4BB2KS2.js +294 -0
  476. package/dist/chunk-Y4BB2KS2.js.map +1 -0
  477. package/dist/chunk-Y4OBB2VN.js +84 -0
  478. package/dist/chunk-YCVD6CI3.js +234 -0
  479. package/dist/chunk-YENLNISG.js +270 -0
  480. package/dist/chunk-YIRVLKAX.js +351 -0
  481. package/dist/chunk-YL73CVNK.js +390 -0
  482. package/dist/chunk-YLS6QE5G.js +288 -0
  483. package/dist/chunk-YNF2OC54.js +366 -0
  484. package/dist/chunk-YNF2OC54.js.map +1 -0
  485. package/dist/chunk-YPWU5KPE.js +147 -0
  486. package/dist/chunk-YQXTDZSU.js +2984 -0
  487. package/dist/chunk-YSJEAAOL.js +178 -0
  488. package/dist/chunk-YWIFM7D7.js +499 -0
  489. package/dist/chunk-YWVI6ZMK.js +103 -0
  490. package/dist/chunk-Z4FMAFNH.js +847 -0
  491. package/dist/chunk-Z654FWNU.js +136 -0
  492. package/dist/chunk-Z7Y523PS.js +130 -0
  493. package/dist/chunk-ZD67RM6G.js +60 -0
  494. package/dist/chunk-ZEG4VPBL.js +187 -0
  495. package/dist/chunk-ZHDFQITM.js +283 -0
  496. package/dist/chunk-ZHDFQITM.js.map +1 -0
  497. package/dist/chunk-ZLYCOBHW.js +75 -0
  498. package/dist/chunk-ZNJ5MTXV.js +89 -0
  499. package/dist/chunk-ZSGY3H53.js +155 -0
  500. package/dist/chunk-ZTPXACWB.js +1788 -0
  501. package/dist/chunk-ZUA3JMI6.js +107 -0
  502. package/dist/chunk-ZYAZUPPV.js +559 -0
  503. package/dist/composer.js +8 -8
  504. package/dist/computer-viewer-TDDO25AV.js +21 -0
  505. package/dist/connect.js +12 -12
  506. package/dist/desktop-dictation.js +12 -10
  507. package/dist/desktop-dictation.js.map +1 -1
  508. package/dist/desktop.js +2 -2
  509. package/dist/editor.js +2 -2
  510. package/dist/embedded-new-voice-2G3VLPVQ.js +24 -0
  511. package/dist/embedded-voice-T5IWOWGD.js +24 -0
  512. package/dist/fleet-decision-row-WM64KXP3.js +361 -0
  513. package/dist/in-chat-connect-model.js +5 -5
  514. package/dist/index.js +51 -51
  515. package/dist/interaction.js +5 -5
  516. package/dist/machines.js +3 -3
  517. package/dist/meetings-recorder.js +1 -1
  518. package/dist/meetings.js +40 -32
  519. package/dist/meetings.js.map +1 -1
  520. package/dist/messages/en.d.ts +3 -0
  521. package/dist/messages.js +1 -1
  522. package/dist/model-policy-picker-menu-SMC6J6QN.js +22 -0
  523. package/dist/payment-page-card-G4U63KUV.js +223 -0
  524. package/dist/platform-activity-row-BUZGZAKZ.js +128 -0
  525. package/dist/queue-surface-implementation-4KUZ4PJV.js +908 -0
  526. package/dist/realtime.js +4 -4
  527. package/dist/recorder-host-WF2RRR56.js +69 -0
  528. package/dist/recorder-host-WF2RRR56.js.map +1 -0
  529. package/dist/recordings.js +3 -3
  530. package/dist/sandbox-files-ESDMOFSD.js +27 -0
  531. package/dist/session-app.js +211 -209
  532. package/dist/session-connect-cards-Q53KMMYY.js +25 -0
  533. package/dist/session-list-model.js +2 -2
  534. package/dist/session-realtime-CF3I35WJ.js +30 -0
  535. package/dist/session-realtime.js +2 -2
  536. package/dist/session-ui.js +33 -31
  537. package/dist/session.js +5 -5
  538. package/dist/sites.js +2 -2
  539. package/dist/terminal.js +2 -2
  540. package/dist/this-computer.js +3 -3
  541. package/dist/timeline-annotation-markers-CJK4RYZ4.js +157 -0
  542. package/dist/timeline-annotation-selection-67GF5H26.js +208 -0
  543. package/dist/timeline-annotations-dialog-ONJPQDJQ.js +283 -0
  544. package/dist/ui/access-list.js +11 -9
  545. package/dist/ui/access-list.js.map +1 -1
  546. package/dist/ui/api-error.d.ts +6 -3
  547. package/dist/ui/api-error.js +2 -1
  548. package/dist/ui/cadence-picker.js +6 -4
  549. package/dist/ui/choice-cards.js +5 -3
  550. package/dist/ui/confirm-dialog.js +2 -2
  551. package/dist/ui/copy-field.js +5 -3
  552. package/dist/ui/detail-page.js +2 -2
  553. package/dist/ui/detail-sheet.js +2 -2
  554. package/dist/ui/diff-view.js +4 -3
  555. package/dist/ui/disclosure.js +3 -3
  556. package/dist/ui/email-chips-input.js +5 -3
  557. package/dist/ui/error-message.js +2 -1
  558. package/dist/ui/error-reference.d.ts +15 -0
  559. package/dist/ui/error-text.d.ts +10 -0
  560. package/dist/ui/error-text.js +9 -0
  561. package/dist/ui/error-text.js.map +1 -0
  562. package/dist/ui/field.js +4 -2
  563. package/dist/ui/flush-form-page.js +8 -6
  564. package/dist/ui/form-dialog.js +7 -5
  565. package/dist/ui/list-row.js +3 -3
  566. package/dist/ui/load-failure.js +3 -2
  567. package/dist/ui/load-failure.js.map +1 -1
  568. package/dist/ui/notice.js +3 -1
  569. package/dist/ui/relative-time.js +2 -2
  570. package/dist/ui/revision-history.js +9 -7
  571. package/dist/ui/revision-history.js.map +1 -1
  572. package/dist/ui/role-select.js +10 -8
  573. package/dist/ui/segmented-control.js +4 -2
  574. package/dist/ui/select-menu.js +5 -3
  575. package/dist/ui/setting-row.js +3 -1
  576. package/dist/ui/switch.js +4 -2
  577. package/dist/ui/usage-meter.js +3 -3
  578. package/dist/ui/word-list-row.js +4 -2
  579. package/dist/usage.js +2 -2
  580. package/dist/workbench.js +4 -4
  581. package/package.json +5 -6
  582. package/src/app/app-state.tsx +126 -14
  583. package/src/app/components/artifacts/site-data.tsx +2 -2
  584. package/src/app/components/artifacts/site-settings.tsx +2 -2
  585. package/src/app/components/rail/session-list.tsx +7 -8
  586. package/src/app/components/rail/session-shell.tsx +3 -3
  587. package/src/app/components/repository-picker.tsx +8 -1
  588. package/src/app/components/session/model-context-inspector.tsx +2 -1
  589. package/src/app/components/session/session-admin-access.tsx +2 -2
  590. package/src/app/lib/actions/chat-operations.ts +4 -4
  591. package/src/app/lib/archive-session.test.tsx +265 -2
  592. package/src/app/lib/archive-session.tsx +175 -9
  593. package/src/app/lib/copy-link.ts +2 -2
  594. package/src/app/lib/inbox.tsx +2 -2
  595. package/src/app/lib/session-failure-toasts.ts +3 -2
  596. package/src/app/lib/toast.test.tsx +215 -0
  597. package/src/app/lib/toast.tsx +67 -2
  598. package/src/app/personal-github-reconnect.test.tsx +356 -0
  599. package/src/app/routes/artifacts.tsx +1 -2
  600. package/src/components/tool-action-review.tsx +14 -1
  601. package/src/meetings/delete-meeting-dialog.tsx +2 -1
  602. package/src/meetings/meeting-ask.tsx +2 -1
  603. package/src/meetings/meeting-detail-page.tsx +2 -1
  604. package/src/meetings/meeting-notes.tsx +2 -1
  605. package/src/meetings/meeting-settings.tsx +4 -1
  606. package/src/meetings/meeting-transcript.tsx +4 -1
  607. package/src/meetings/recorder-context.tsx +10 -0
  608. package/src/meetings/recorder-host.test.tsx +60 -2
  609. package/src/meetings/recorder-host.tsx +16 -3
  610. package/src/meetings/recorder-panel.tsx +2 -1
  611. package/src/meetings/recorder-workspace.test.tsx +26 -1
  612. package/src/messages/en.ts +6 -0
  613. package/src/ui/api-error.test.ts +29 -5
  614. package/src/ui/api-error.tsx +10 -4
  615. package/src/ui/error-message.tsx +8 -0
  616. package/src/ui/error-reference.test.ts +54 -0
  617. package/src/ui/error-reference.ts +51 -0
  618. package/src/ui/error-text.test.tsx +66 -0
  619. package/src/ui/error-text.tsx +49 -0
  620. package/src/ui/field.tsx +4 -1
  621. package/src/ui/notice.tsx +7 -2
  622. package/src/ui/setting-row.tsx +4 -1
  623. package/styles/app.css +12 -0
  624. package/styles/compiled.css +9 -0
  625. package/dist/browser-viewer-NOP5EAUO.js +0 -23
  626. package/dist/chat-interactive-block-G7O44JHR.js +0 -18
  627. package/dist/chunk-26RWVLRD.js +0 -135
  628. package/dist/chunk-2AHTY7OT.js +0 -247
  629. package/dist/chunk-2GDNWKSC.js +0 -3670
  630. package/dist/chunk-2JENKGCE.js +0 -339
  631. package/dist/chunk-2KYQC4T5.js +0 -155
  632. package/dist/chunk-2RREGDQH.js +0 -708
  633. package/dist/chunk-2T7DX6KR.js +0 -353
  634. package/dist/chunk-2VB2O4FQ.js +0 -920
  635. package/dist/chunk-2VTTKH23.js +0 -94
  636. package/dist/chunk-2XNG2KNT.js +0 -172
  637. package/dist/chunk-2YC6JQRO.js +0 -399
  638. package/dist/chunk-2ZVRJRXC.js +0 -27
  639. package/dist/chunk-35737UT4.js +0 -162
  640. package/dist/chunk-366XZ4PM.js +0 -41
  641. package/dist/chunk-36MIDGAH.js +0 -199
  642. package/dist/chunk-3FD76LXM.js +0 -212
  643. package/dist/chunk-3OVIXY4O.js +0 -213
  644. package/dist/chunk-3OVIXY4O.js.map +0 -1
  645. package/dist/chunk-3QNRBEYH.js +0 -432
  646. package/dist/chunk-3QX55WLC.js +0 -15
  647. package/dist/chunk-3USJPT2S.js +0 -1022
  648. package/dist/chunk-42CMQ5VR.js +0 -251
  649. package/dist/chunk-4LPOWQJY.js +0 -42
  650. package/dist/chunk-4NBTZRKT.js +0 -79
  651. package/dist/chunk-4OXI6HCV.js +0 -118
  652. package/dist/chunk-4SZZAFYQ.js +0 -2317
  653. package/dist/chunk-4TQL3WP2.js +0 -140
  654. package/dist/chunk-4Y6BK7IU.js +0 -196
  655. package/dist/chunk-4YD7YZC5.js +0 -373
  656. package/dist/chunk-5DTST3TP.js +0 -81
  657. package/dist/chunk-5FH5LQVS.js +0 -130
  658. package/dist/chunk-5KWMYPJV.js +0 -847
  659. package/dist/chunk-5MUJDC6C.js +0 -84
  660. package/dist/chunk-5QM2WPKV.js +0 -41
  661. package/dist/chunk-5WUN7XPD.js +0 -1184
  662. package/dist/chunk-64PO2WXU.js +0 -1067
  663. package/dist/chunk-6AHATAAY.js +0 -431
  664. package/dist/chunk-6ED2YWBT.js +0 -56
  665. package/dist/chunk-6GXVYAGR.js +0 -170
  666. package/dist/chunk-6H4SJBPE.js +0 -85
  667. package/dist/chunk-6MT3HHUB.js +0 -84
  668. package/dist/chunk-6UHCBH4G.js +0 -198
  669. package/dist/chunk-6WLX3NR3.js +0 -198
  670. package/dist/chunk-73NXYYWE.js +0 -112
  671. package/dist/chunk-76ERNKIZ.js +0 -603
  672. package/dist/chunk-776QZ573.js +0 -57
  673. package/dist/chunk-7BYWOFVH.js +0 -171
  674. package/dist/chunk-7O5CGGIQ.js +0 -108
  675. package/dist/chunk-7QOHRZ67.js +0 -251
  676. package/dist/chunk-7WIDB4PL.js +0 -2058
  677. package/dist/chunk-7WKP3DYJ.js +0 -37
  678. package/dist/chunk-7XOVTPDI.js +0 -227
  679. package/dist/chunk-AB5MBIXY.js +0 -281
  680. package/dist/chunk-ADNMXBCX.js +0 -1193
  681. package/dist/chunk-AFBJTUFK.js +0 -202
  682. package/dist/chunk-ALVRWCXE.js +0 -61
  683. package/dist/chunk-AOHU6O3M.js +0 -247
  684. package/dist/chunk-AOHU6O3M.js.map +0 -1
  685. package/dist/chunk-APW4T4SW.js +0 -270
  686. package/dist/chunk-AXBSYWKX.js +0 -2656
  687. package/dist/chunk-B2I5ZW35.js +0 -422
  688. package/dist/chunk-B3LMRTRF.js +0 -223
  689. package/dist/chunk-BE2XENG2.js +0 -292
  690. package/dist/chunk-BE2XENG2.js.map +0 -1
  691. package/dist/chunk-BF4SADKX.js +0 -29
  692. package/dist/chunk-BKP43KK4.js +0 -1788
  693. package/dist/chunk-BM3NEZ6X.js +0 -781
  694. package/dist/chunk-BT3BAGB5.js +0 -216
  695. package/dist/chunk-BTSYDIVJ.js +0 -357
  696. package/dist/chunk-BUBNGKWG.js +0 -70
  697. package/dist/chunk-BVUJV5WR.js +0 -126
  698. package/dist/chunk-BZO5ZMUP.js +0 -27
  699. package/dist/chunk-C3HUF3M2.js +0 -157
  700. package/dist/chunk-C5QCAOES.js +0 -264
  701. package/dist/chunk-CGK6ALQU.js +0 -159
  702. package/dist/chunk-CPYGO76Q.js +0 -335
  703. package/dist/chunk-CQH4FWYA.js +0 -490
  704. package/dist/chunk-CZP5QXNB.js +0 -234
  705. package/dist/chunk-D2TOWEYH.js +0 -266
  706. package/dist/chunk-D6L4GHRH.js +0 -340
  707. package/dist/chunk-DKT3N37I.js +0 -50
  708. package/dist/chunk-DMMJIFKA.js +0 -84
  709. package/dist/chunk-DO74DQC7.js +0 -26
  710. package/dist/chunk-DOFJZ2JU.js +0 -83
  711. package/dist/chunk-DSXVY5WZ.js +0 -119
  712. package/dist/chunk-E337C2VK.js +0 -82
  713. package/dist/chunk-E6NRSRBE.js +0 -114
  714. package/dist/chunk-E6SQKHAU.js +0 -114
  715. package/dist/chunk-E7UIVD7F.js +0 -236
  716. package/dist/chunk-EGBII4CP.js +0 -229
  717. package/dist/chunk-EILSAQVJ.js +0 -200
  718. package/dist/chunk-ELL6HSYR.js +0 -307
  719. package/dist/chunk-EUBGLFFR.js +0 -73
  720. package/dist/chunk-EW6RNWSH.js +0 -212
  721. package/dist/chunk-EYUT5Y6V.js +0 -2599
  722. package/dist/chunk-F7U3QPZ3.js +0 -304
  723. package/dist/chunk-FBTJKSTM.js +0 -1270
  724. package/dist/chunk-FC2FTSK3.js +0 -2424
  725. package/dist/chunk-FOGNA3BU.js +0 -148
  726. package/dist/chunk-FQFKHNC7.js +0 -650
  727. package/dist/chunk-FTCHM755.js +0 -50
  728. package/dist/chunk-FXSHP4JZ.js +0 -3550
  729. package/dist/chunk-G6ZZC543.js +0 -818
  730. package/dist/chunk-G7FU6PUA.js +0 -100
  731. package/dist/chunk-GA4YEAMX.js +0 -3851
  732. package/dist/chunk-GE33BGB7.js +0 -12
  733. package/dist/chunk-GQ67HSJY.js +0 -570
  734. package/dist/chunk-GXXZ3WAK.js +0 -106
  735. package/dist/chunk-H2TCRX3H.js +0 -237
  736. package/dist/chunk-HLL4PBO7.js +0 -60
  737. package/dist/chunk-HLOEPV5C.js +0 -259
  738. package/dist/chunk-HUAGBS4O.js +0 -56
  739. package/dist/chunk-I36GSRUJ.js +0 -211
  740. package/dist/chunk-I6VBHT7S.js +0 -261
  741. package/dist/chunk-ICNNNOXE.js +0 -333
  742. package/dist/chunk-ICX64J4U.js +0 -172
  743. package/dist/chunk-ID36Y46W.js +0 -5046
  744. package/dist/chunk-ID36Y46W.js.map +0 -1
  745. package/dist/chunk-IGVVXLKJ.js +0 -559
  746. package/dist/chunk-IKJLSBUI.js +0 -2984
  747. package/dist/chunk-IKMUFDVS.js +0 -50
  748. package/dist/chunk-IKUNOX7F.js +0 -255
  749. package/dist/chunk-ILKDYBON.js +0 -288
  750. package/dist/chunk-IVYJX3OY.js +0 -187
  751. package/dist/chunk-JCY4CMDH.js +0 -107
  752. package/dist/chunk-JJZPLGIP.js +0 -474
  753. package/dist/chunk-JW33RV4V.js +0 -143
  754. package/dist/chunk-JWPA6ZPZ.js +0 -351
  755. package/dist/chunk-JZ4QXS6D.js +0 -50
  756. package/dist/chunk-K42OUZQ3.js +0 -386
  757. package/dist/chunk-K5TOVX5A.js +0 -206
  758. package/dist/chunk-K63HGHZX.js +0 -99
  759. package/dist/chunk-K6R5T44I.js +0 -75
  760. package/dist/chunk-KHJ5PXFM.js +0 -914
  761. package/dist/chunk-KJZRQ55O.js +0 -2319
  762. package/dist/chunk-KJZRQ55O.js.map +0 -1
  763. package/dist/chunk-KKI55ZMW.js +0 -65
  764. package/dist/chunk-KRPLAAFP.js +0 -199
  765. package/dist/chunk-KVFEZDBO.js +0 -134
  766. package/dist/chunk-L4I665WK.js +0 -45
  767. package/dist/chunk-L4OF77LE.js +0 -110
  768. package/dist/chunk-L4OF77LE.js.map +0 -1
  769. package/dist/chunk-LA5T52RM.js +0 -70
  770. package/dist/chunk-LM2W5YAT.js +0 -401
  771. package/dist/chunk-LQ62ECE6.js +0 -390
  772. package/dist/chunk-LQDUHU3Y.js +0 -71
  773. package/dist/chunk-LRJIYTZW.js +0 -4157
  774. package/dist/chunk-LRJIYTZW.js.map +0 -1
  775. package/dist/chunk-LRN6GYAZ.js +0 -138
  776. package/dist/chunk-M4SDVTKJ.js +0 -790
  777. package/dist/chunk-MA6O7CM6.js +0 -99
  778. package/dist/chunk-MBIBB6GI.js +0 -197
  779. package/dist/chunk-MF3ZFB4H.js +0 -199
  780. package/dist/chunk-MJJGJMYJ.js +0 -98
  781. package/dist/chunk-MLJADQFI.js +0 -4824
  782. package/dist/chunk-MQG7RV3B.js +0 -62
  783. package/dist/chunk-MTTGSQA5.js +0 -186
  784. package/dist/chunk-MW7Y3T55.js +0 -525
  785. package/dist/chunk-MYUFMVCH.js +0 -121
  786. package/dist/chunk-N3OARGH2.js +0 -61
  787. package/dist/chunk-NB2HMRT2.js +0 -353
  788. package/dist/chunk-NFDFYWMV.js +0 -141
  789. package/dist/chunk-NWGNFN3N.js +0 -1187
  790. package/dist/chunk-NWJRPDIO.js +0 -840
  791. package/dist/chunk-NWJRPDIO.js.map +0 -1
  792. package/dist/chunk-NXWBBZJV.js +0 -267
  793. package/dist/chunk-NY2QWROL.js +0 -71
  794. package/dist/chunk-O2IOPP3R.js +0 -848
  795. package/dist/chunk-O2UWH5RG.js +0 -141
  796. package/dist/chunk-O5YWDLYF.js +0 -393
  797. package/dist/chunk-OBMCZO7E.js +0 -121
  798. package/dist/chunk-OD3DCCCB.js +0 -132
  799. package/dist/chunk-OMH7R6I3.js +0 -390
  800. package/dist/chunk-OSA5EQG5.js +0 -113
  801. package/dist/chunk-OSJ3MUTZ.js +0 -2936
  802. package/dist/chunk-OWAYJ2OV.js +0 -368
  803. package/dist/chunk-OYXBFSGK.js +0 -269
  804. package/dist/chunk-PC2EBA5G.js +0 -4116
  805. package/dist/chunk-PC2EBA5G.js.map +0 -1
  806. package/dist/chunk-PC2MVXIP.js +0 -363
  807. package/dist/chunk-PC2MVXIP.js.map +0 -1
  808. package/dist/chunk-PENGLDR5.js +0 -309
  809. package/dist/chunk-PSMAWRPL.js +0 -191
  810. package/dist/chunk-PW4IMTYR.js +0 -702
  811. package/dist/chunk-PW54V7T5.js +0 -387
  812. package/dist/chunk-Q2EXYSMO.js +0 -24
  813. package/dist/chunk-Q2XJK5I4.js +0 -51
  814. package/dist/chunk-Q2XJK5I4.js.map +0 -1
  815. package/dist/chunk-Q4EFRI6X.js +0 -258
  816. package/dist/chunk-Q52CXW6C.js +0 -48
  817. package/dist/chunk-Q6XQ2R37.js +0 -184
  818. package/dist/chunk-QAJ53XBW.js +0 -23
  819. package/dist/chunk-QDTKECT4.js +0 -129
  820. package/dist/chunk-QE3ZFGI3.js +0 -43
  821. package/dist/chunk-QHHSUR2Y.js +0 -298
  822. package/dist/chunk-QHNVNR7B.js +0 -173
  823. package/dist/chunk-QIK2Q6N5.js +0 -376
  824. package/dist/chunk-QWL4L366.js +0 -38
  825. package/dist/chunk-R3J2PTVQ.js +0 -690
  826. package/dist/chunk-RBRX5ZS3.js +0 -319
  827. package/dist/chunk-REX6JIC7.js +0 -33
  828. package/dist/chunk-RGZ7EEC3.js +0 -537
  829. package/dist/chunk-RGZ7EEC3.js.map +0 -1
  830. package/dist/chunk-RIPS7GFR.js +0 -960
  831. package/dist/chunk-RTBZNFNV.js +0 -1354
  832. package/dist/chunk-RTBZNFNV.js.map +0 -1
  833. package/dist/chunk-SKMNW4SW.js +0 -187
  834. package/dist/chunk-SRFARKXC.js +0 -623
  835. package/dist/chunk-SWIHWCTW.js +0 -4461
  836. package/dist/chunk-TA5CFTO4.js +0 -103
  837. package/dist/chunk-TF4ZVJLI.js +0 -156
  838. package/dist/chunk-TG7DADJR.js +0 -9624
  839. package/dist/chunk-TI4R2ZD5.js +0 -623
  840. package/dist/chunk-TI4R2ZD5.js.map +0 -1
  841. package/dist/chunk-TNKWOUWP.js +0 -412
  842. package/dist/chunk-TNUSPXPW.js +0 -5555
  843. package/dist/chunk-TNUSPXPW.js.map +0 -1
  844. package/dist/chunk-TNYFHKVV.js +0 -366
  845. package/dist/chunk-TPMZBOFH.js +0 -178
  846. package/dist/chunk-TW3LKRJF.js +0 -263
  847. package/dist/chunk-TZAO65I4.js +0 -83
  848. package/dist/chunk-U5EFEMYU.js +0 -89
  849. package/dist/chunk-U6M4LS3M.js +0 -378
  850. package/dist/chunk-UI4HI5QK.js +0 -918
  851. package/dist/chunk-UJDOWCQ3.js +0 -272
  852. package/dist/chunk-UJUQ2QOX.js +0 -581
  853. package/dist/chunk-UQ3IM6FY.js +0 -133
  854. package/dist/chunk-UYE47LO6.js +0 -246
  855. package/dist/chunk-VADHIT26.js +0 -89
  856. package/dist/chunk-VFQ3H6CO.js +0 -163
  857. package/dist/chunk-VGUN6VB2.js +0 -188
  858. package/dist/chunk-VGWWEVSD.js +0 -723
  859. package/dist/chunk-VIEFJ2DM.js +0 -2469
  860. package/dist/chunk-VLXM36VS.js +0 -268
  861. package/dist/chunk-W3BFRR2G.js +0 -499
  862. package/dist/chunk-W5MPXR3A.js +0 -981
  863. package/dist/chunk-W5OWKVZG.js +0 -136
  864. package/dist/chunk-W6FRORMX.js +0 -486
  865. package/dist/chunk-W6FRORMX.js.map +0 -1
  866. package/dist/chunk-W7XROSZO.js +0 -232
  867. package/dist/chunk-W7XROSZO.js.map +0 -1
  868. package/dist/chunk-WEZ5PXZP.js +0 -403
  869. package/dist/chunk-WHWUWN2X.js +0 -197
  870. package/dist/chunk-WHWUWN2X.js.map +0 -1
  871. package/dist/chunk-WLEDGIVS.js +0 -114
  872. package/dist/chunk-WLEDGIVS.js.map +0 -1
  873. package/dist/chunk-WNDAKLHG.js +0 -281
  874. package/dist/chunk-WTJ4PLMU.js +0 -103
  875. package/dist/chunk-WV2KPJUW.js +0 -107
  876. package/dist/chunk-X3VY5EGY.js +0 -277
  877. package/dist/chunk-X3VY5EGY.js.map +0 -1
  878. package/dist/chunk-XDBYWVCW.js +0 -418
  879. package/dist/chunk-XF7MA4U5.js +0 -36
  880. package/dist/chunk-XF7MA4U5.js.map +0 -1
  881. package/dist/chunk-XOSQP3YA.js +0 -605
  882. package/dist/chunk-XYBV4ZJQ.js +0 -271
  883. package/dist/chunk-YBKVGLQR.js +0 -147
  884. package/dist/chunk-YDCUBUWH.js +0 -1583
  885. package/dist/chunk-YG6NARQY.js +0 -51
  886. package/dist/chunk-YG6NARQY.js.map +0 -1
  887. package/dist/chunk-YSVD5HI4.js +0 -278
  888. package/dist/chunk-YT3WGNG6.js +0 -290
  889. package/dist/chunk-YYICQDK4.js +0 -414
  890. package/dist/chunk-YYLMZLI6.js +0 -686
  891. package/dist/chunk-ZAMTKG5U.js +0 -95
  892. package/dist/chunk-ZDLYSXKN.js +0 -111
  893. package/dist/chunk-ZG447FSS.js +0 -194
  894. package/dist/chunk-ZIT5KD4Q.js +0 -264
  895. package/dist/chunk-ZUDOVDKR.js +0 -3064
  896. package/dist/chunk-ZW2ECJ3A.js +0 -451
  897. package/dist/computer-viewer-LPZ763KF.js +0 -21
  898. package/dist/embedded-new-voice-YVMKSLKJ.js +0 -24
  899. package/dist/embedded-voice-BJPQFXSU.js +0 -24
  900. package/dist/fleet-decision-row-AA4H5CDT.js +0 -361
  901. package/dist/model-policy-picker-menu-HSMWVO4P.js +0 -22
  902. package/dist/payment-page-card-3LTSFJGN.js +0 -223
  903. package/dist/platform-activity-row-5VYV6TX4.js +0 -128
  904. package/dist/queue-surface-implementation-NXHZUKD2.js +0 -908
  905. package/dist/recorder-host-ZKRWTDBM.js +0 -57
  906. package/dist/recorder-host-ZKRWTDBM.js.map +0 -1
  907. package/dist/sandbox-files-YCMLQUFU.js +0 -27
  908. package/dist/session-connect-cards-KSQLMRM5.js +0 -25
  909. package/dist/session-realtime-ZR6JLG3Y.js +0 -30
  910. package/dist/timeline-annotation-markers-YAHDPWVG.js +0 -157
  911. package/dist/timeline-annotation-selection-KHXNCEJP.js +0 -208
  912. package/dist/timeline-annotations-dialog-Y4XD3N7B.js +0 -283
  913. /package/dist/{browser-viewer-NOP5EAUO.js.map → browser-viewer-TC27OCIP.js.map} +0 -0
  914. /package/dist/{chat-interactive-block-G7O44JHR.js.map → chat-interactive-block-RWPQBHVS.js.map} +0 -0
  915. /package/dist/{chunk-EGBII4CP.js.map → chunk-2BDT3UZQ.js.map} +0 -0
  916. /package/dist/{chunk-4YD7YZC5.js.map → chunk-2CLNIEK4.js.map} +0 -0
  917. /package/dist/{chunk-ZW2ECJ3A.js.map → chunk-2FSBSCZJ.js.map} +0 -0
  918. /package/dist/{chunk-KRPLAAFP.js.map → chunk-2I7HDP53.js.map} +0 -0
  919. /package/dist/{chunk-3QX55WLC.js.map → chunk-2INLDVK3.js.map} +0 -0
  920. /package/dist/{chunk-BVUJV5WR.js.map → chunk-2KALVELR.js.map} +0 -0
  921. /package/dist/{chunk-XDBYWVCW.js.map → chunk-2M3J7ZWQ.js.map} +0 -0
  922. /package/dist/{chunk-2RREGDQH.js.map → chunk-2OP6WLGV.js.map} +0 -0
  923. /package/dist/{chunk-OSJ3MUTZ.js.map → chunk-2RG7NIAS.js.map} +0 -0
  924. /package/dist/{chunk-26RWVLRD.js.map → chunk-2STUPWEL.js.map} +0 -0
  925. /package/dist/{chunk-XYBV4ZJQ.js.map → chunk-2YUOVM3G.js.map} +0 -0
  926. /package/dist/{chunk-2GDNWKSC.js.map → chunk-2Z3NQNTM.js.map} +0 -0
  927. /package/dist/{chunk-2VB2O4FQ.js.map → chunk-3CPWWGNK.js.map} +0 -0
  928. /package/dist/{chunk-7WKP3DYJ.js.map → chunk-3ED2U6XE.js.map} +0 -0
  929. /package/dist/{chunk-BT3BAGB5.js.map → chunk-3GZA4BUW.js.map} +0 -0
  930. /package/dist/{chunk-3USJPT2S.js.map → chunk-3IK6UYO6.js.map} +0 -0
  931. /package/dist/{chunk-6AHATAAY.js.map → chunk-3PZ7JZI2.js.map} +0 -0
  932. /package/dist/{chunk-JZ4QXS6D.js.map → chunk-4DVJ6ONS.js.map} +0 -0
  933. /package/dist/{chunk-5QM2WPKV.js.map → chunk-4E3ZJRTZ.js.map} +0 -0
  934. /package/dist/{chunk-NFDFYWMV.js.map → chunk-4SAWSRAA.js.map} +0 -0
  935. /package/dist/{chunk-ELL6HSYR.js.map → chunk-53AGXXZM.js.map} +0 -0
  936. /package/dist/{chunk-G6ZZC543.js.map → chunk-54YW6SZZ.js.map} +0 -0
  937. /package/dist/{chunk-4SZZAFYQ.js.map → chunk-57AZS3IE.js.map} +0 -0
  938. /package/dist/{chunk-JW33RV4V.js.map → chunk-5CPEEAFD.js.map} +0 -0
  939. /package/dist/{chunk-D6L4GHRH.js.map → chunk-5EWSRZ2Y.js.map} +0 -0
  940. /package/dist/{chunk-PW54V7T5.js.map → chunk-5IE76VCY.js.map} +0 -0
  941. /package/dist/{chunk-6GXVYAGR.js.map → chunk-5NWEKLDZ.js.map} +0 -0
  942. /package/dist/{chunk-6UHCBH4G.js.map → chunk-5O2FCCHZ.js.map} +0 -0
  943. /package/dist/{chunk-2YC6JQRO.js.map → chunk-5QAY6K77.js.map} +0 -0
  944. /package/dist/{chunk-EYUT5Y6V.js.map → chunk-6DK6Z4UN.js.map} +0 -0
  945. /package/dist/{chunk-PW4IMTYR.js.map → chunk-6DVCC7QS.js.map} +0 -0
  946. /package/dist/{chunk-7WIDB4PL.js.map → chunk-6JHU2UBS.js.map} +0 -0
  947. /package/dist/{chunk-CQH4FWYA.js.map → chunk-6PZ7OBYU.js.map} +0 -0
  948. /package/dist/{chunk-VFQ3H6CO.js.map → chunk-6WGRDRMA.js.map} +0 -0
  949. /package/dist/{chunk-MTTGSQA5.js.map → chunk-77WAKEAH.js.map} +0 -0
  950. /package/dist/{chunk-O5YWDLYF.js.map → chunk-7TDO3CUM.js.map} +0 -0
  951. /package/dist/{chunk-2AHTY7OT.js.map → chunk-7TIX2UAR.js.map} +0 -0
  952. /package/dist/{chunk-FOGNA3BU.js.map → chunk-7V5REBCP.js.map} +0 -0
  953. /package/dist/{chunk-2JENKGCE.js.map → chunk-7VMZGLYI.js.map} +0 -0
  954. /package/dist/{chunk-E7UIVD7F.js.map → chunk-7W37NS3I.js.map} +0 -0
  955. /package/dist/{chunk-ZDLYSXKN.js.map → chunk-7X6SDK2C.js.map} +0 -0
  956. /package/dist/{chunk-ZAMTKG5U.js.map → chunk-7ZNUHRP5.js.map} +0 -0
  957. /package/dist/{chunk-DMMJIFKA.js.map → chunk-A36PZALD.js.map} +0 -0
  958. /package/dist/{chunk-WV2KPJUW.js.map → chunk-AUI6VA63.js.map} +0 -0
  959. /package/dist/{chunk-Q2EXYSMO.js.map → chunk-AW2MQB37.js.map} +0 -0
  960. /package/dist/{chunk-6WLX3NR3.js.map → chunk-AWKES45Y.js.map} +0 -0
  961. /package/dist/{chunk-OD3DCCCB.js.map → chunk-AXHZYXUV.js.map} +0 -0
  962. /package/dist/{chunk-QDTKECT4.js.map → chunk-BHNSJVBC.js.map} +0 -0
  963. /package/dist/{chunk-FTCHM755.js.map → chunk-BJEJFISW.js.map} +0 -0
  964. /package/dist/{chunk-B2I5ZW35.js.map → chunk-BJFH6JI5.js.map} +0 -0
  965. /package/dist/{chunk-RIPS7GFR.js.map → chunk-BMICEQZQ.js.map} +0 -0
  966. /package/dist/{chunk-BF4SADKX.js.map → chunk-BTLBYBLU.js.map} +0 -0
  967. /package/dist/{chunk-U5EFEMYU.js.map → chunk-BXBDYNRP.js.map} +0 -0
  968. /package/dist/{chunk-BTSYDIVJ.js.map → chunk-C372BFOV.js.map} +0 -0
  969. /package/dist/{chunk-MLJADQFI.js.map → chunk-CMKGILJK.js.map} +0 -0
  970. /package/dist/{chunk-DKT3N37I.js.map → chunk-CRAOSVHC.js.map} +0 -0
  971. /package/dist/{chunk-WNDAKLHG.js.map → chunk-CRU35QQH.js.map} +0 -0
  972. /package/dist/{chunk-2XNG2KNT.js.map → chunk-CUIWCGMA.js.map} +0 -0
  973. /package/dist/{chunk-QWL4L366.js.map → chunk-D5TWNFFE.js.map} +0 -0
  974. /package/dist/{chunk-SWIHWCTW.js.map → chunk-DF5EAHDN.js.map} +0 -0
  975. /package/dist/{chunk-HUAGBS4O.js.map → chunk-DJAXC5OK.js.map} +0 -0
  976. /package/dist/{chunk-FXSHP4JZ.js.map → chunk-DXBYWSL5.js.map} +0 -0
  977. /package/dist/{chunk-5MUJDC6C.js.map → chunk-DXR5PDFP.js.map} +0 -0
  978. /package/dist/{chunk-NXWBBZJV.js.map → chunk-DZWARC4M.js.map} +0 -0
  979. /package/dist/{chunk-GXXZ3WAK.js.map → chunk-DZXEDSQI.js.map} +0 -0
  980. /package/dist/{chunk-Q52CXW6C.js.map → chunk-E7XERZWC.js.map} +0 -0
  981. /package/dist/{chunk-4NBTZRKT.js.map → chunk-ECJBYNLJ.js.map} +0 -0
  982. /package/dist/{chunk-QE3ZFGI3.js.map → chunk-EDI6SJ2N.js.map} +0 -0
  983. /package/dist/{chunk-E6NRSRBE.js.map → chunk-EWSOC6WF.js.map} +0 -0
  984. /package/dist/{chunk-TA5CFTO4.js.map → chunk-F2OPHAUN.js.map} +0 -0
  985. /package/dist/{chunk-5DTST3TP.js.map → chunk-F4ISQGGM.js.map} +0 -0
  986. /package/dist/{chunk-MBIBB6GI.js.map → chunk-FO4LYKJL.js.map} +0 -0
  987. /package/dist/{chunk-EUBGLFFR.js.map → chunk-FPXASDG5.js.map} +0 -0
  988. /package/dist/{chunk-C3HUF3M2.js.map → chunk-FVXBNBHO.js.map} +0 -0
  989. /package/dist/{chunk-W5MPXR3A.js.map → chunk-FZC5N55X.js.map} +0 -0
  990. /package/dist/{chunk-MA6O7CM6.js.map → chunk-GAVYGBFI.js.map} +0 -0
  991. /package/dist/{chunk-REX6JIC7.js.map → chunk-GKVJIDHF.js.map} +0 -0
  992. /package/dist/{chunk-EW6RNWSH.js.map → chunk-GVN5SZLX.js.map} +0 -0
  993. /package/dist/{chunk-KVFEZDBO.js.map → chunk-H3T7IWNA.js.map} +0 -0
  994. /package/dist/{chunk-I6VBHT7S.js.map → chunk-HAX4LCR5.js.map} +0 -0
  995. /package/dist/{chunk-OBMCZO7E.js.map → chunk-HC4JFZVU.js.map} +0 -0
  996. /package/dist/{chunk-UJUQ2QOX.js.map → chunk-HEFPPMBQ.js.map} +0 -0
  997. /package/dist/{chunk-DOFJZ2JU.js.map → chunk-HNLR7Q4Z.js.map} +0 -0
  998. /package/dist/{chunk-GE33BGB7.js.map → chunk-HSOXMJOT.js.map} +0 -0
  999. /package/dist/{chunk-AB5MBIXY.js.map → chunk-I4MRDSUF.js.map} +0 -0
  1000. /package/dist/{chunk-AFBJTUFK.js.map → chunk-I4QEJ62Y.js.map} +0 -0
  1001. /package/dist/{chunk-6ED2YWBT.js.map → chunk-I5B5L6Q4.js.map} +0 -0
  1002. /package/dist/{chunk-C5QCAOES.js.map → chunk-I5QZJODL.js.map} +0 -0
  1003. /package/dist/{chunk-76ERNKIZ.js.map → chunk-I7ITSXSJ.js.map} +0 -0
  1004. /package/dist/{chunk-OMH7R6I3.js.map → chunk-I7XIZRFD.js.map} +0 -0
  1005. /package/dist/{chunk-E337C2VK.js.map → chunk-IDANQPRH.js.map} +0 -0
  1006. /package/dist/{chunk-3FD76LXM.js.map → chunk-IFB3WJ36.js.map} +0 -0
  1007. /package/dist/{chunk-ZIT5KD4Q.js.map → chunk-IHTAKKTK.js.map} +0 -0
  1008. /package/dist/{chunk-QHNVNR7B.js.map → chunk-ILDXWY37.js.map} +0 -0
  1009. /package/dist/{chunk-GQ67HSJY.js.map → chunk-IMDQUHBJ.js.map} +0 -0
  1010. /package/dist/{chunk-DSXVY5WZ.js.map → chunk-IMZCQBOT.js.map} +0 -0
  1011. /package/dist/{chunk-WEZ5PXZP.js.map → chunk-IXPTECSC.js.map} +0 -0
  1012. /package/dist/{chunk-NY2QWROL.js.map → chunk-J255A3N5.js.map} +0 -0
  1013. /package/dist/{chunk-O2UWH5RG.js.map → chunk-J5F5HPPW.js.map} +0 -0
  1014. /package/dist/{chunk-VIEFJ2DM.js.map → chunk-JEA3QDX7.js.map} +0 -0
  1015. /package/dist/{chunk-TF4ZVJLI.js.map → chunk-JEUPAVYY.js.map} +0 -0
  1016. /package/dist/{chunk-ZG447FSS.js.map → chunk-JKHKLL5W.js.map} +0 -0
  1017. /package/dist/{chunk-FQFKHNC7.js.map → chunk-JQL7ZH6C.js.map} +0 -0
  1018. /package/dist/{chunk-776QZ573.js.map → chunk-JWB44UGJ.js.map} +0 -0
  1019. /package/dist/{chunk-ICNNNOXE.js.map → chunk-JZ4NLCAP.js.map} +0 -0
  1020. /package/dist/{chunk-TNKWOUWP.js.map → chunk-K2A5PXQ5.js.map} +0 -0
  1021. /package/dist/{chunk-SRFARKXC.js.map → chunk-K56XV3C3.js.map} +0 -0
  1022. /package/dist/{chunk-QAJ53XBW.js.map → chunk-K6GAXXVA.js.map} +0 -0
  1023. /package/dist/{chunk-MF3ZFB4H.js.map → chunk-KCBMFSMS.js.map} +0 -0
  1024. /package/dist/{chunk-VLXM36VS.js.map → chunk-KF2FV3ZJ.js.map} +0 -0
  1025. /package/dist/{chunk-YSVD5HI4.js.map → chunk-KJD65EJP.js.map} +0 -0
  1026. /package/dist/{chunk-K42OUZQ3.js.map → chunk-KLEUWIMZ.js.map} +0 -0
  1027. /package/dist/{chunk-PENGLDR5.js.map → chunk-KODELWYT.js.map} +0 -0
  1028. /package/dist/{chunk-TZAO65I4.js.map → chunk-KRDR5RJD.js.map} +0 -0
  1029. /package/dist/{chunk-KHJ5PXFM.js.map → chunk-KUDGXAF7.js.map} +0 -0
  1030. /package/dist/{chunk-6H4SJBPE.js.map → chunk-KYS77RPN.js.map} +0 -0
  1031. /package/dist/{chunk-OWAYJ2OV.js.map → chunk-L7YTNTIK.js.map} +0 -0
  1032. /package/dist/{chunk-YYLMZLI6.js.map → chunk-LHPNABDH.js.map} +0 -0
  1033. /package/dist/{chunk-LM2W5YAT.js.map → chunk-MFROMEKA.js.map} +0 -0
  1034. /package/dist/{chunk-AXBSYWKX.js.map → chunk-MIHN76LX.js.map} +0 -0
  1035. /package/dist/{chunk-4LPOWQJY.js.map → chunk-MIYFS2XN.js.map} +0 -0
  1036. /package/dist/{chunk-KKI55ZMW.js.map → chunk-MJUCFQMS.js.map} +0 -0
  1037. /package/dist/{chunk-ZUDOVDKR.js.map → chunk-MM4FNWI4.js.map} +0 -0
  1038. /package/dist/{chunk-M4SDVTKJ.js.map → chunk-MNZG4OHU.js.map} +0 -0
  1039. /package/dist/{chunk-EILSAQVJ.js.map → chunk-N6AACDUW.js.map} +0 -0
  1040. /package/dist/{chunk-BM3NEZ6X.js.map → chunk-NC55IFN3.js.map} +0 -0
  1041. /package/dist/{chunk-MJJGJMYJ.js.map → chunk-NC7PVOEK.js.map} +0 -0
  1042. /package/dist/{chunk-LA5T52RM.js.map → chunk-NCYMNCJO.js.map} +0 -0
  1043. /package/dist/{chunk-HLOEPV5C.js.map → chunk-ND2BXV3P.js.map} +0 -0
  1044. /package/dist/{chunk-UJDOWCQ3.js.map → chunk-NDBTFUO6.js.map} +0 -0
  1045. /package/dist/{chunk-K5TOVX5A.js.map → chunk-NDQJZ7HF.js.map} +0 -0
  1046. /package/dist/{chunk-35737UT4.js.map → chunk-NGJJJPZZ.js.map} +0 -0
  1047. /package/dist/{chunk-42CMQ5VR.js.map → chunk-NJTSNNE7.js.map} +0 -0
  1048. /package/dist/{chunk-FBTJKSTM.js.map → chunk-NRTE7DNV.js.map} +0 -0
  1049. /package/dist/{chunk-YT3WGNG6.js.map → chunk-NULUNM7H.js.map} +0 -0
  1050. /package/dist/{chunk-7XOVTPDI.js.map → chunk-NUNZS36W.js.map} +0 -0
  1051. /package/dist/{chunk-FC2FTSK3.js.map → chunk-NW53H5RW.js.map} +0 -0
  1052. /package/dist/{chunk-TW3LKRJF.js.map → chunk-NXCMHIKI.js.map} +0 -0
  1053. /package/dist/{chunk-CGK6ALQU.js.map → chunk-O3LKCBP5.js.map} +0 -0
  1054. /package/dist/{chunk-QIK2Q6N5.js.map → chunk-O6N4ABCA.js.map} +0 -0
  1055. /package/dist/{chunk-73NXYYWE.js.map → chunk-O732GAFC.js.map} +0 -0
  1056. /package/dist/{chunk-R3J2PTVQ.js.map → chunk-OF4TIKYC.js.map} +0 -0
  1057. /package/dist/{chunk-BUBNGKWG.js.map → chunk-OMPVOMPP.js.map} +0 -0
  1058. /package/dist/{chunk-4OXI6HCV.js.map → chunk-OPJJSKUK.js.map} +0 -0
  1059. /package/dist/{chunk-4Y6BK7IU.js.map → chunk-OPWCMA4D.js.map} +0 -0
  1060. /package/dist/{chunk-ADNMXBCX.js.map → chunk-ORJPS5VN.js.map} +0 -0
  1061. /package/dist/{chunk-SKMNW4SW.js.map → chunk-OSY5K7L7.js.map} +0 -0
  1062. /package/dist/{chunk-L4I665WK.js.map → chunk-OV6QJRT4.js.map} +0 -0
  1063. /package/dist/{chunk-7O5CGGIQ.js.map → chunk-OVKYVZMW.js.map} +0 -0
  1064. /package/dist/{chunk-7BYWOFVH.js.map → chunk-OZCBM3UC.js.map} +0 -0
  1065. /package/dist/{chunk-ALVRWCXE.js.map → chunk-P3A2EINJ.js.map} +0 -0
  1066. /package/dist/{chunk-BZO5ZMUP.js.map → chunk-PTAG4PDC.js.map} +0 -0
  1067. /package/dist/{chunk-QHHSUR2Y.js.map → chunk-PTF5B7TJ.js.map} +0 -0
  1068. /package/dist/{chunk-O2IOPP3R.js.map → chunk-Q3DPEYX4.js.map} +0 -0
  1069. /package/dist/{chunk-G7FU6PUA.js.map → chunk-QB2KMIDP.js.map} +0 -0
  1070. /package/dist/{chunk-64PO2WXU.js.map → chunk-QCSJ4CWE.js.map} +0 -0
  1071. /package/dist/{chunk-YYICQDK4.js.map → chunk-QIOQ2NPQ.js.map} +0 -0
  1072. /package/dist/{chunk-NB2HMRT2.js.map → chunk-QK5EFEUT.js.map} +0 -0
  1073. /package/dist/{chunk-366XZ4PM.js.map → chunk-QPQBLYQJ.js.map} +0 -0
  1074. /package/dist/{chunk-Q6XQ2R37.js.map → chunk-QPSGCC5D.js.map} +0 -0
  1075. /package/dist/{chunk-JJZPLGIP.js.map → chunk-QZAAUQRN.js.map} +0 -0
  1076. /package/dist/{chunk-VGUN6VB2.js.map → chunk-RGBI63KJ.js.map} +0 -0
  1077. /package/dist/{chunk-LRN6GYAZ.js.map → chunk-RLBKLAEY.js.map} +0 -0
  1078. /package/dist/{chunk-F7U3QPZ3.js.map → chunk-RMFKVOM7.js.map} +0 -0
  1079. /package/dist/{chunk-Q4EFRI6X.js.map → chunk-ROKQU7WG.js.map} +0 -0
  1080. /package/dist/{chunk-7QOHRZ67.js.map → chunk-RPVREAU7.js.map} +0 -0
  1081. /package/dist/{chunk-VGWWEVSD.js.map → chunk-RQKLF42C.js.map} +0 -0
  1082. /package/dist/{chunk-2VTTKH23.js.map → chunk-SEO7TICN.js.map} +0 -0
  1083. /package/dist/{chunk-3QNRBEYH.js.map → chunk-SHHJCL7X.js.map} +0 -0
  1084. /package/dist/{chunk-E6SQKHAU.js.map → chunk-SIRLACNZ.js.map} +0 -0
  1085. /package/dist/{chunk-H2TCRX3H.js.map → chunk-SKPHMYAA.js.map} +0 -0
  1086. /package/dist/{chunk-YDCUBUWH.js.map → chunk-SODC7T6L.js.map} +0 -0
  1087. /package/dist/{chunk-TNYFHKVV.js.map → chunk-SQJIKMN3.js.map} +0 -0
  1088. /package/dist/{chunk-DO74DQC7.js.map → chunk-SVINDKVW.js.map} +0 -0
  1089. /package/dist/{chunk-CPYGO76Q.js.map → chunk-SYCDHPZF.js.map} +0 -0
  1090. /package/dist/{chunk-UQ3IM6FY.js.map → chunk-T2QX3FDP.js.map} +0 -0
  1091. /package/dist/{chunk-NWGNFN3N.js.map → chunk-T3OWFVMS.js.map} +0 -0
  1092. /package/dist/{chunk-N3OARGH2.js.map → chunk-T6XI5FLY.js.map} +0 -0
  1093. /package/dist/{chunk-MQG7RV3B.js.map → chunk-T7OXJZCX.js.map} +0 -0
  1094. /package/dist/{chunk-2T7DX6KR.js.map → chunk-TAT5USZN.js.map} +0 -0
  1095. /package/dist/{chunk-ICX64J4U.js.map → chunk-TPQTRNER.js.map} +0 -0
  1096. /package/dist/{chunk-D2TOWEYH.js.map → chunk-TUIN4MB7.js.map} +0 -0
  1097. /package/dist/{chunk-LQDUHU3Y.js.map → chunk-TX3VECZU.js.map} +0 -0
  1098. /package/dist/{chunk-TG7DADJR.js.map → chunk-TXLIEOJX.js.map} +0 -0
  1099. /package/dist/{chunk-2ZVRJRXC.js.map → chunk-U3DN4HEY.js.map} +0 -0
  1100. /package/dist/{chunk-PSMAWRPL.js.map → chunk-U7XM7CB4.js.map} +0 -0
  1101. /package/dist/{chunk-4TQL3WP2.js.map → chunk-UJK53QFL.js.map} +0 -0
  1102. /package/dist/{chunk-RBRX5ZS3.js.map → chunk-UMTXA2TH.js.map} +0 -0
  1103. /package/dist/{chunk-36MIDGAH.js.map → chunk-UPDSXFK5.js.map} +0 -0
  1104. /package/dist/{chunk-OYXBFSGK.js.map → chunk-UTIAXH52.js.map} +0 -0
  1105. /package/dist/{chunk-5WUN7XPD.js.map → chunk-UVN5TMHU.js.map} +0 -0
  1106. /package/dist/{chunk-UYE47LO6.js.map → chunk-VGYXW3VG.js.map} +0 -0
  1107. /package/dist/{chunk-IKUNOX7F.js.map → chunk-VS7AHPCZ.js.map} +0 -0
  1108. /package/dist/{chunk-MYUFMVCH.js.map → chunk-VTTAJOQ7.js.map} +0 -0
  1109. /package/dist/{chunk-K63HGHZX.js.map → chunk-VWPOLUAO.js.map} +0 -0
  1110. /package/dist/{chunk-GA4YEAMX.js.map → chunk-X3MWB2QU.js.map} +0 -0
  1111. /package/dist/{chunk-I36GSRUJ.js.map → chunk-X6KAJI3V.js.map} +0 -0
  1112. /package/dist/{chunk-IKMUFDVS.js.map → chunk-XBLRHV5R.js.map} +0 -0
  1113. /package/dist/{chunk-XOSQP3YA.js.map → chunk-XDFP2LMW.js.map} +0 -0
  1114. /package/dist/{chunk-MW7Y3T55.js.map → chunk-XEQMZB3C.js.map} +0 -0
  1115. /package/dist/{chunk-B3LMRTRF.js.map → chunk-XEYLT5VA.js.map} +0 -0
  1116. /package/dist/{chunk-UI4HI5QK.js.map → chunk-XHIQ5I6N.js.map} +0 -0
  1117. /package/dist/{chunk-U6M4LS3M.js.map → chunk-XLH7QY2R.js.map} +0 -0
  1118. /package/dist/{chunk-OSA5EQG5.js.map → chunk-XWFAMUZQ.js.map} +0 -0
  1119. /package/dist/{chunk-6MT3HHUB.js.map → chunk-Y4OBB2VN.js.map} +0 -0
  1120. /package/dist/{chunk-CZP5QXNB.js.map → chunk-YCVD6CI3.js.map} +0 -0
  1121. /package/dist/{chunk-APW4T4SW.js.map → chunk-YENLNISG.js.map} +0 -0
  1122. /package/dist/{chunk-JWPA6ZPZ.js.map → chunk-YIRVLKAX.js.map} +0 -0
  1123. /package/dist/{chunk-LQ62ECE6.js.map → chunk-YL73CVNK.js.map} +0 -0
  1124. /package/dist/{chunk-ILKDYBON.js.map → chunk-YLS6QE5G.js.map} +0 -0
  1125. /package/dist/{chunk-YBKVGLQR.js.map → chunk-YPWU5KPE.js.map} +0 -0
  1126. /package/dist/{chunk-IKJLSBUI.js.map → chunk-YQXTDZSU.js.map} +0 -0
  1127. /package/dist/{chunk-TPMZBOFH.js.map → chunk-YSJEAAOL.js.map} +0 -0
  1128. /package/dist/{chunk-W3BFRR2G.js.map → chunk-YWIFM7D7.js.map} +0 -0
  1129. /package/dist/{chunk-WTJ4PLMU.js.map → chunk-YWVI6ZMK.js.map} +0 -0
  1130. /package/dist/{chunk-5KWMYPJV.js.map → chunk-Z4FMAFNH.js.map} +0 -0
  1131. /package/dist/{chunk-W5OWKVZG.js.map → chunk-Z654FWNU.js.map} +0 -0
  1132. /package/dist/{chunk-5FH5LQVS.js.map → chunk-Z7Y523PS.js.map} +0 -0
  1133. /package/dist/{chunk-HLL4PBO7.js.map → chunk-ZD67RM6G.js.map} +0 -0
  1134. /package/dist/{chunk-IVYJX3OY.js.map → chunk-ZEG4VPBL.js.map} +0 -0
  1135. /package/dist/{chunk-K6R5T44I.js.map → chunk-ZLYCOBHW.js.map} +0 -0
  1136. /package/dist/{chunk-VADHIT26.js.map → chunk-ZNJ5MTXV.js.map} +0 -0
  1137. /package/dist/{chunk-2KYQC4T5.js.map → chunk-ZSGY3H53.js.map} +0 -0
  1138. /package/dist/{chunk-BKP43KK4.js.map → chunk-ZTPXACWB.js.map} +0 -0
  1139. /package/dist/{chunk-JCY4CMDH.js.map → chunk-ZUA3JMI6.js.map} +0 -0
  1140. /package/dist/{chunk-IGVVXLKJ.js.map → chunk-ZYAZUPPV.js.map} +0 -0
  1141. /package/dist/{computer-viewer-LPZ763KF.js.map → computer-viewer-TDDO25AV.js.map} +0 -0
  1142. /package/dist/{embedded-new-voice-YVMKSLKJ.js.map → embedded-new-voice-2G3VLPVQ.js.map} +0 -0
  1143. /package/dist/{embedded-voice-BJPQFXSU.js.map → embedded-voice-T5IWOWGD.js.map} +0 -0
  1144. /package/dist/{fleet-decision-row-AA4H5CDT.js.map → fleet-decision-row-WM64KXP3.js.map} +0 -0
  1145. /package/dist/{model-policy-picker-menu-HSMWVO4P.js.map → model-policy-picker-menu-SMC6J6QN.js.map} +0 -0
  1146. /package/dist/{payment-page-card-3LTSFJGN.js.map → payment-page-card-G4U63KUV.js.map} +0 -0
  1147. /package/dist/{platform-activity-row-5VYV6TX4.js.map → platform-activity-row-BUZGZAKZ.js.map} +0 -0
  1148. /package/dist/{queue-surface-implementation-NXHZUKD2.js.map → queue-surface-implementation-4KUZ4PJV.js.map} +0 -0
  1149. /package/dist/{sandbox-files-YCMLQUFU.js.map → sandbox-files-ESDMOFSD.js.map} +0 -0
  1150. /package/dist/{session-connect-cards-KSQLMRM5.js.map → session-connect-cards-Q53KMMYY.js.map} +0 -0
  1151. /package/dist/{session-realtime-ZR6JLG3Y.js.map → session-realtime-CF3I35WJ.js.map} +0 -0
  1152. /package/dist/{timeline-annotation-markers-YAHDPWVG.js.map → timeline-annotation-markers-CJK4RYZ4.js.map} +0 -0
  1153. /package/dist/{timeline-annotation-selection-KHXNCEJP.js.map → timeline-annotation-selection-67GF5H26.js.map} +0 -0
  1154. /package/dist/{timeline-annotations-dialog-Y4XD3N7B.js.map → timeline-annotations-dialog-ONJPQDJQ.js.map} +0 -0
@@ -0,0 +1,3550 @@
1
+ "use client";
2
+ import {
3
+ useLatestTaskRunner
4
+ } from "./chunk-2DDJ6YH6.js";
5
+ import {
6
+ ArtifactSubmissionProvider,
7
+ ArtifactSurface,
8
+ EditableArtifactDownloadButton,
9
+ EditableArtifactMessage,
10
+ artifactSubmissionSessionKey,
11
+ asEditableArtifactError,
12
+ editableArtifactAccessRevoked,
13
+ editableArtifactProjectionKey,
14
+ editableArtifactStatusLabel,
15
+ useArtifactSubmissions,
16
+ useEditableArtifactView
17
+ } from "./chunk-7VMZGLYI.js";
18
+ import {
19
+ cn
20
+ } from "./chunk-TXS65BB2.js";
21
+ import {
22
+ useOpenGeniText
23
+ } from "./chunk-7T2ZE3VT.js";
24
+
25
+ // src/components/artifacts/presentation-editor.tsx
26
+ import {
27
+ ChevronLeftIcon,
28
+ ChevronRightIcon,
29
+ ExpandIcon,
30
+ FilePlus2Icon,
31
+ MinusIcon,
32
+ PlusIcon,
33
+ Trash2Icon,
34
+ TypeIcon
35
+ } from "lucide-react";
36
+ import {
37
+ useCallback,
38
+ useEffect,
39
+ useId,
40
+ useLayoutEffect,
41
+ useMemo,
42
+ useRef,
43
+ useState
44
+ } from "react";
45
+ import { jsx, jsxs } from "react/jsx-runtime";
46
+ var MIN_ZOOM = 0.2;
47
+ var MAX_ZOOM = 4;
48
+ var RAIL_ITEM_HEIGHT = 116;
49
+ var RAIL_OVERSCAN = 3;
50
+ var DEFAULT_RAIL_HEIGHT = 640;
51
+ var MOBILE_RAIL_ITEM_HEIGHT = 44;
52
+ var MOBILE_RAIL_OVERSCAN = 3;
53
+ var DEFAULT_MOBILE_LIST_HEIGHT = 264;
54
+ var DEFAULT_VIEWPORT = { width: 960, height: 640 };
55
+ var SPATIAL_TILE = 256;
56
+ var MAX_SPATIAL_BUCKETS_PER_OBJECT = 1024;
57
+ var CANVAS_OVERSCAN_PX = 96;
58
+ var MAX_CANVAS_EDGE = 8192;
59
+ var MAX_CANVAS_PIXELS = 16e6;
60
+ var MAX_EDITOR_GEOMETRY = 1e6;
61
+ var MAX_TABLE_CELLS_PER_PAINT = 2e4;
62
+ var MAX_PROJECTION_SLIDES = 1e5;
63
+ var MAX_PROJECTION_ELEMENTS_PER_SLIDE = 1e5;
64
+ var MAX_PROJECTION_GROUP_DEPTH = 16;
65
+ var MAX_PROJECTION_TABLE_CELLS = 1e6;
66
+ var MAX_PROJECTION_TEXT = 1e6;
67
+ function PresentationEditor(props) {
68
+ return /* @__PURE__ */ jsx(PresentationEditorCore, { ...props });
69
+ }
70
+ function PresentationProjectionEditor({
71
+ projection,
72
+ commit,
73
+ onCommandError,
74
+ onSlideChange,
75
+ onSelectionChange,
76
+ readOnly = false,
77
+ ...props
78
+ }) {
79
+ const view = useMemo(() => presentationViewFromProjection(projection), [projection]);
80
+ return /* @__PURE__ */ jsx(
81
+ PresentationEditorCore,
82
+ {
83
+ ...props,
84
+ presentation: view.presentation,
85
+ revision: projection.revision,
86
+ readOnly: readOnly || !commit,
87
+ onCommit: commit ? (command) => commit({ ...command, revision: projection.revision }) : void 0,
88
+ onCommandError,
89
+ onSlideChange: (slide, index) => {
90
+ const projected = view.slideById.get(slide.id);
91
+ if (projected) onSlideChange?.(projected, index);
92
+ },
93
+ onSelectionChange: (object, slide) => {
94
+ const projectedSlide = view.slideById.get(slide.id);
95
+ if (!projectedSlide) return;
96
+ onSelectionChange?.(
97
+ object ? view.elementById.get(object.id) ?? null : null,
98
+ projectedSlide
99
+ );
100
+ }
101
+ }
102
+ );
103
+ }
104
+ function nextSlideIndexFromKey(key, activeIndex, length) {
105
+ if (length === 0) return null;
106
+ if (key === "ArrowDown") return Math.min(length - 1, activeIndex + 1);
107
+ if (key === "ArrowUp") return Math.max(0, activeIndex - 1);
108
+ if (key === "Home") return 0;
109
+ if (key === "End") return length - 1;
110
+ return null;
111
+ }
112
+ function PresentationEditorCore({
113
+ presentation,
114
+ revision,
115
+ activeSlideId: controlledSlideId,
116
+ defaultActiveSlideId,
117
+ selectedObjectId: controlledSelectionId,
118
+ defaultSelectedObjectId = null,
119
+ zoom: controlledZoom,
120
+ defaultZoom = 0.75,
121
+ readOnly = false,
122
+ authoringBlockedReason,
123
+ className,
124
+ onSlideChange,
125
+ onSelectionChange,
126
+ onCommit,
127
+ onCommandError,
128
+ onZoomChange
129
+ }) {
130
+ const t = useOpenGeniText();
131
+ const mutationsBlocked = readOnly || authoringBlockedReason !== void 0;
132
+ const authoringStatus = readOnly ? null : authoringBlockedReason === "pending_conflict" ? t("artifacts.presentationEditor.anEarlierChangeNeedsAttention") : authoringBlockedReason === "prior_writer" ? t("artifacts.presentationEditor.savingEarlierChanges") : null;
133
+ const slides = presentation.slides.items;
134
+ const firstSlideId = slides[0]?.id ?? null;
135
+ const [localSlideId, setLocalSlideId] = useState(
136
+ defaultActiveSlideId ?? controlledSlideId ?? firstSlideId
137
+ );
138
+ const requestedSlideId = controlledSlideId ?? localSlideId;
139
+ const activeSlide = slides.find((slide) => slide.id === requestedSlideId) ?? slides[0] ?? null;
140
+ const activeIndex = activeSlide ? slides.indexOf(activeSlide) : -1;
141
+ const [localSelectionId, setLocalSelectionId] = useState(defaultSelectedObjectId);
142
+ const selectedId = controlledSelectionId === void 0 ? localSelectionId : controlledSelectionId;
143
+ const [localZoom, setLocalZoom] = useState(() => clampZoom(defaultZoom));
144
+ const zoom = clampZoom(controlledZoom ?? localZoom);
145
+ const [fitMode, setFitMode] = useState(false);
146
+ const [viewportMeasured, setViewportMeasured] = useState(false);
147
+ const [modelEpoch, setModelEpoch] = useState(0);
148
+ const [pendingCommands, setPendingCommands] = useState(0);
149
+ const [commandFailure, setCommandFailure] = useState(null);
150
+ const [rail, setRail] = useState({
151
+ scrollTop: 0,
152
+ height: DEFAULT_RAIL_HEIGHT
153
+ });
154
+ const [mobileSelectorOpen, setMobileSelectorOpen] = useState(false);
155
+ const [mobileRail, setMobileRail] = useState({
156
+ scrollTop: 0,
157
+ height: DEFAULT_MOBILE_LIST_HEIGHT
158
+ });
159
+ const [viewport, setViewport] = useState({
160
+ scrollLeft: 0,
161
+ scrollTop: 0,
162
+ ...DEFAULT_VIEWPORT,
163
+ stageLeft: 0,
164
+ stageTop: 0
165
+ });
166
+ const [draftPosition, setDraftPosition] = useState(null);
167
+ const [textEdit, setTextEdit] = useState(null);
168
+ const [textDraft, setTextDraft] = useState("");
169
+ const [paintEpoch, setPaintEpoch] = useState(0);
170
+ const railRef = useRef(null);
171
+ const mobileSelectorTriggerRef = useRef(null);
172
+ const mobileSelectorPanelRef = useRef(null);
173
+ const mobileRailRef = useRef(null);
174
+ const viewportRef = useRef(null);
175
+ const stageRef = useRef(null);
176
+ const canvasRef = useRef(null);
177
+ const overlayRef = useRef(null);
178
+ const editorRef = useRef(null);
179
+ const dragRef = useRef(null);
180
+ const textEditRef = useRef(null);
181
+ const imageCacheRef = useRef(/* @__PURE__ */ new Map());
182
+ const mountedRef = useRef(true);
183
+ const commandScopeRef = useRef(0);
184
+ const commandVersionsRef = useRef(/* @__PURE__ */ new Map());
185
+ const pendingSlideIdRef = useRef(null);
186
+ const pendingObjectIdRef = useRef(null);
187
+ const mobileRailScrollOnOpenRef = useRef(0);
188
+ const domId = useId().replaceAll(":", "");
189
+ const selectionProxyId = `${domId}-presentation-selection`;
190
+ const instructionsId = `${domId}-presentation-instructions`;
191
+ const objects = useMemo(
192
+ () => activeSlide ? listSlideObjects(activeSlide) : [],
193
+ // revision is a deliberate host invalidation token; modelEpoch covers local commits.
194
+ // oxlint-disable-next-line react-hooks/exhaustive-deps
195
+ [activeSlide, modelEpoch, revision]
196
+ );
197
+ const objectById = useMemo(
198
+ () => new Map(objects.map((entry) => [entry.id, entry])),
199
+ [objects]
200
+ );
201
+ const objectIndexById = useMemo(
202
+ () => new Map(objects.map((entry, index) => [entry.id, index])),
203
+ [objects]
204
+ );
205
+ const selected = selectedId ? objectById.get(selectedId) ?? null : null;
206
+ const spatialIndex = useMemo(
207
+ () => buildSpatialIndex(objects, presentation.slideSize),
208
+ [objects, presentation.slideSize]
209
+ );
210
+ const effectiveSelectedPosition = selected && draftPosition?.objectId === selected.id ? draftPosition.position : selected ? copyPosition(selected.object.position) : null;
211
+ useEffect(() => {
212
+ const pendingSlideId = pendingSlideIdRef.current;
213
+ if (pendingSlideId && controlledSlideId === void 0 && slides.some((slide) => slide.id === pendingSlideId)) {
214
+ pendingSlideIdRef.current = null;
215
+ setLocalSlideId(pendingSlideId);
216
+ return;
217
+ }
218
+ if (activeSlide && requestedSlideId !== activeSlide.id && controlledSlideId === void 0 && pendingSlideId === null) {
219
+ setLocalSlideId(activeSlide.id);
220
+ }
221
+ }, [activeSlide, controlledSlideId, requestedSlideId, slides]);
222
+ useEffect(() => {
223
+ if (selectedId && !objectById.has(selectedId) && controlledSelectionId === void 0) {
224
+ setLocalSelectionId(null);
225
+ }
226
+ }, [controlledSelectionId, objectById, selectedId]);
227
+ useEffect(() => {
228
+ const pendingObjectId = pendingObjectIdRef.current;
229
+ if (pendingObjectId && controlledSelectionId === void 0 && objectById.has(pendingObjectId)) {
230
+ pendingObjectIdRef.current = null;
231
+ setLocalSelectionId(pendingObjectId);
232
+ }
233
+ }, [controlledSelectionId, objectById]);
234
+ useLayoutEffect(() => {
235
+ const element = railRef.current;
236
+ if (!element || typeof ResizeObserver === "undefined") return;
237
+ const measure = () => setRail((current) => ({
238
+ scrollTop: element.scrollTop,
239
+ height: element.clientHeight || current.height
240
+ }));
241
+ measure();
242
+ const observer = new ResizeObserver(measure);
243
+ observer.observe(element);
244
+ return () => observer.disconnect();
245
+ }, []);
246
+ useLayoutEffect(() => {
247
+ if (!mobileSelectorOpen) return;
248
+ const element = mobileRailRef.current;
249
+ if (!element) return;
250
+ element.scrollTop = mobileRailScrollOnOpenRef.current;
251
+ element.focus();
252
+ const measure = () => setMobileRail((current) => ({
253
+ scrollTop: element.scrollTop,
254
+ height: element.clientHeight || current.height
255
+ }));
256
+ measure();
257
+ if (typeof ResizeObserver === "undefined") return;
258
+ const observer = new ResizeObserver(measure);
259
+ observer.observe(element);
260
+ return () => observer.disconnect();
261
+ }, [mobileSelectorOpen]);
262
+ useEffect(() => {
263
+ if (!mobileSelectorOpen) return;
264
+ const onPointerDown = (event) => {
265
+ const target = event.target;
266
+ if (!(target instanceof Node)) return;
267
+ if (mobileSelectorTriggerRef.current?.contains(target)) return;
268
+ if (mobileSelectorPanelRef.current?.contains(target)) return;
269
+ setMobileSelectorOpen(false);
270
+ };
271
+ const onKeyDown = (event) => {
272
+ if (event.key !== "Escape") return;
273
+ event.preventDefault();
274
+ setMobileSelectorOpen(false);
275
+ mobileSelectorTriggerRef.current?.focus();
276
+ };
277
+ document.addEventListener("pointerdown", onPointerDown);
278
+ document.addEventListener("keydown", onKeyDown);
279
+ return () => {
280
+ document.removeEventListener("pointerdown", onPointerDown);
281
+ document.removeEventListener("keydown", onKeyDown);
282
+ };
283
+ }, [mobileSelectorOpen]);
284
+ useLayoutEffect(() => {
285
+ const element = viewportRef.current;
286
+ if (!element) return;
287
+ const measure = () => {
288
+ const stage = stageRef.current;
289
+ const measuredWidth = element.clientWidth;
290
+ const measuredHeight = element.clientHeight;
291
+ const next = {
292
+ scrollLeft: element.scrollLeft,
293
+ scrollTop: element.scrollTop,
294
+ width: measuredWidth || DEFAULT_VIEWPORT.width,
295
+ height: measuredHeight || DEFAULT_VIEWPORT.height,
296
+ stageLeft: stage?.offsetLeft ?? 0,
297
+ stageTop: stage?.offsetTop ?? 0
298
+ };
299
+ setViewport((current) => sameViewport(current, next) ? current : next);
300
+ if (measuredWidth > 0 && measuredHeight > 0) setViewportMeasured(true);
301
+ };
302
+ measure();
303
+ if (typeof ResizeObserver === "undefined") return;
304
+ const observer = new ResizeObserver(measure);
305
+ observer.observe(element);
306
+ if (stageRef.current) observer.observe(stageRef.current);
307
+ return () => observer.disconnect();
308
+ }, [activeSlide?.id, presentation.slideSize.height, presentation.slideSize.width, zoom]);
309
+ useLayoutEffect(() => {
310
+ const imageCache = imageCacheRef.current;
311
+ return () => disposeCanvasImageCache(imageCache);
312
+ }, [activeSlide]);
313
+ useEffect(() => {
314
+ const edit = textEditRef.current;
315
+ const currentEntry = edit ? objectById.get(edit.shape.id) : null;
316
+ if (edit && activeSlide?.id === edit.slideId && currentEntry?.kind === "shape" && !currentEntry.readOnly && currentEntry.object.geometry !== "line") {
317
+ const rebound = {
318
+ ...edit,
319
+ shape: currentEntry.object
320
+ };
321
+ textEditRef.current = rebound;
322
+ setTextEdit(rebound);
323
+ } else {
324
+ textEditRef.current = null;
325
+ setTextEdit(null);
326
+ }
327
+ }, [activeSlide?.id, objectById]);
328
+ useEffect(() => {
329
+ dragRef.current = null;
330
+ setDraftPosition(null);
331
+ commandScopeRef.current += 1;
332
+ commandVersionsRef.current.clear();
333
+ setPendingCommands(0);
334
+ setCommandFailure(null);
335
+ }, [activeSlide?.id, revision]);
336
+ useEffect(() => {
337
+ const edit = textEditRef.current;
338
+ if (edit && edit.shape.id !== selectedId) {
339
+ textEditRef.current = null;
340
+ setTextEdit(null);
341
+ }
342
+ const drag = dragRef.current;
343
+ if (drag && drag.object.id !== selectedId) {
344
+ dragRef.current = null;
345
+ setDraftPosition(null);
346
+ }
347
+ }, [selectedId]);
348
+ useEffect(() => {
349
+ if (!readOnly) return;
350
+ dragRef.current = null;
351
+ setDraftPosition(null);
352
+ textEditRef.current = null;
353
+ setTextEdit(null);
354
+ }, [readOnly]);
355
+ useEffect(() => {
356
+ mountedRef.current = true;
357
+ return () => {
358
+ mountedRef.current = false;
359
+ dragRef.current = null;
360
+ textEditRef.current = null;
361
+ };
362
+ }, []);
363
+ useEffect(() => {
364
+ const element = railRef.current;
365
+ if (!element || activeIndex < 0) return;
366
+ const top = activeIndex * RAIL_ITEM_HEIGHT;
367
+ const bottom = top + RAIL_ITEM_HEIGHT;
368
+ const height = element.clientHeight || rail.height;
369
+ if (top >= element.scrollTop && bottom <= element.scrollTop + height) return;
370
+ const nextTop = Math.max(0, top - height / 2);
371
+ element.scrollTop = nextTop;
372
+ setRail((current) => ({ ...current, scrollTop: nextTop }));
373
+ }, [activeIndex, rail.height]);
374
+ const visibleSlideRegion = useMemo(() => {
375
+ const slideWidth = presentation.slideSize.width;
376
+ const slideHeight = presentation.slideSize.height;
377
+ const stageWidth2 = slideWidth * zoom;
378
+ const stageHeight2 = slideHeight * zoom;
379
+ if (stageWidth2 <= viewport.width && stageHeight2 <= viewport.height) {
380
+ return { left: 0, top: 0, width: slideWidth, height: slideHeight };
381
+ }
382
+ const overscan = CANVAS_OVERSCAN_PX / zoom;
383
+ const visibleLeft = Math.max(0, (viewport.scrollLeft - viewport.stageLeft) / zoom);
384
+ const visibleTop = Math.max(0, (viewport.scrollTop - viewport.stageTop) / zoom);
385
+ const left = Math.max(0, visibleLeft - overscan);
386
+ const top = Math.max(0, visibleTop - overscan);
387
+ return {
388
+ left,
389
+ top,
390
+ width: Math.max(0, Math.min(slideWidth - left, viewport.width / zoom + overscan * 2)),
391
+ height: Math.max(0, Math.min(slideHeight - top, viewport.height / zoom + overscan * 2))
392
+ };
393
+ }, [presentation.slideSize.height, presentation.slideSize.width, viewport, zoom]);
394
+ const visibleObjectIndexes = useMemo(() => {
395
+ if (!activeSlide) return [];
396
+ if (visibleSlideRegion.left === 0 && visibleSlideRegion.top === 0 && visibleSlideRegion.width === presentation.slideSize.width && visibleSlideRegion.height === presentation.slideSize.height) {
397
+ return objects.map((_, index) => index);
398
+ }
399
+ const visible = querySpatialIndex(spatialIndex, visibleSlideRegion);
400
+ const selectedIndex = selectedId ? objectIndexById.get(selectedId) ?? -1 : -1;
401
+ if (selectedIndex >= 0 && !visible.includes(selectedIndex)) visible.push(selectedIndex);
402
+ const draftIndex = draftPosition ? objectIndexById.get(draftPosition.objectId) ?? -1 : -1;
403
+ if (draftIndex >= 0 && !visible.includes(draftIndex)) visible.push(draftIndex);
404
+ return visible.sort((a, b) => a - b);
405
+ }, [
406
+ activeSlide,
407
+ objects,
408
+ objectIndexById,
409
+ presentation.slideSize,
410
+ draftPosition,
411
+ selectedId,
412
+ spatialIndex,
413
+ visibleSlideRegion
414
+ ]);
415
+ useLayoutEffect(() => {
416
+ const canvas = canvasRef.current;
417
+ if (!canvas || !activeSlide) return;
418
+ paintSlideCanvas(t, {
419
+ canvas,
420
+ slide: activeSlide,
421
+ slideSize: presentation.slideSize,
422
+ zoom,
423
+ objects,
424
+ objectIndexes: visibleObjectIndexes,
425
+ renderRegion: visibleSlideRegion,
426
+ draftPosition,
427
+ imageCache: imageCacheRef.current,
428
+ requestRepaint: () => setPaintEpoch((value) => value + 1)
429
+ });
430
+ }, [
431
+ activeSlide,
432
+ draftPosition,
433
+ objects,
434
+ paintEpoch,
435
+ presentation.slideSize,
436
+ visibleObjectIndexes,
437
+ visibleSlideRegion,
438
+ zoom,
439
+ t
440
+ ]);
441
+ const selectObject = useCallback(
442
+ (entry) => {
443
+ textEditRef.current = null;
444
+ setTextEdit(null);
445
+ setDraftPosition(null);
446
+ if (controlledSelectionId === void 0) setLocalSelectionId(entry?.id ?? null);
447
+ if (activeSlide) onSelectionChange?.(entry?.object ?? null, activeSlide);
448
+ },
449
+ [activeSlide, controlledSelectionId, onSelectionChange]
450
+ );
451
+ const selectSlide = useCallback(
452
+ (slide, index) => {
453
+ if (controlledSlideId === void 0) setLocalSlideId(slide.id);
454
+ selectObject(null);
455
+ onSlideChange?.(slide, index);
456
+ },
457
+ [controlledSlideId, onSlideChange, selectObject]
458
+ );
459
+ const changeZoom = useCallback(
460
+ (next) => {
461
+ const clamped = clampZoom(next);
462
+ setFitMode(false);
463
+ if (clamped === zoom) return;
464
+ if (controlledZoom === void 0) setLocalZoom(clamped);
465
+ onZoomChange?.(clamped);
466
+ },
467
+ [controlledZoom, onZoomChange, zoom]
468
+ );
469
+ const applyFittedZoom = useCallback(() => {
470
+ const next = fittedPresentationZoom(viewport, presentation.slideSize);
471
+ if (next === zoom) return;
472
+ if (controlledZoom === void 0) setLocalZoom(next);
473
+ onZoomChange?.(next);
474
+ }, [controlledZoom, onZoomChange, presentation.slideSize, viewport, zoom]);
475
+ const fitSlide = useCallback(() => {
476
+ setFitMode(true);
477
+ applyFittedZoom();
478
+ }, [applyFittedZoom]);
479
+ useLayoutEffect(() => {
480
+ if (!viewportMeasured || controlledZoom !== void 0) return;
481
+ const fitted = fittedPresentationZoom(viewport, presentation.slideSize);
482
+ if (!fitMode && zoom <= fitted) return;
483
+ if (!fitMode) setFitMode(true);
484
+ applyFittedZoom();
485
+ }, [
486
+ applyFittedZoom,
487
+ controlledZoom,
488
+ fitMode,
489
+ presentation.slideSize,
490
+ viewport,
491
+ viewportMeasured,
492
+ zoom
493
+ ]);
494
+ const runCommit = useCallback(
495
+ (key, command, rollback, retry) => {
496
+ if (mutationsBlocked || !onCommit) return;
497
+ const version = (commandVersionsRef.current.get(key) ?? 0) + 1;
498
+ commandVersionsRef.current.set(key, version);
499
+ const scope = commandScopeRef.current;
500
+ setCommandFailure(null);
501
+ let result;
502
+ try {
503
+ result = onCommit(command);
504
+ } catch (cause) {
505
+ if (!mountedRef.current || commandScopeRef.current !== scope || commandVersionsRef.current.get(key) !== version) {
506
+ return;
507
+ }
508
+ rollback();
509
+ const error = asPresentationError(cause);
510
+ setCommandFailure({ message: error.message, retry });
511
+ onCommandError?.(error);
512
+ return;
513
+ }
514
+ if (!result || typeof result.then !== "function") return;
515
+ setPendingCommands((current) => current + 1);
516
+ void Promise.resolve(result).then(
517
+ () => {
518
+ if (!mountedRef.current || commandScopeRef.current !== scope) return;
519
+ setPendingCommands((current) => Math.max(0, current - 1));
520
+ },
521
+ (cause) => {
522
+ if (!mountedRef.current || commandScopeRef.current !== scope) return;
523
+ setPendingCommands((current) => Math.max(0, current - 1));
524
+ if (commandVersionsRef.current.get(key) !== version) return;
525
+ rollback();
526
+ const error = asPresentationError(cause);
527
+ setCommandFailure({ message: error.message, retry });
528
+ onCommandError?.(error);
529
+ }
530
+ );
531
+ },
532
+ [mutationsBlocked, onCommandError, onCommit]
533
+ );
534
+ const commitPosition = useCallback(
535
+ (entry, kind, next) => {
536
+ if (!activeSlide || mutationsBlocked || entry.readOnly) return;
537
+ const before = copyPosition(entry.object.position);
538
+ const after = normalizeEditorPosition(next);
539
+ if (samePosition(before, after)) return;
540
+ entry.object.position = after;
541
+ setModelEpoch((value) => value + 1);
542
+ const command = {
543
+ kind,
544
+ slideId: activeSlide.id,
545
+ objectId: entry.id,
546
+ before,
547
+ after
548
+ };
549
+ const submit = () => runCommit(
550
+ `position:${activeSlide.id}:${entry.id}`,
551
+ command,
552
+ () => {
553
+ entry.object.position = before;
554
+ setModelEpoch((value) => value + 1);
555
+ },
556
+ () => {
557
+ entry.object.position = after;
558
+ setModelEpoch((value) => value + 1);
559
+ submit();
560
+ }
561
+ );
562
+ submit();
563
+ },
564
+ [activeSlide, mutationsBlocked, runCommit]
565
+ );
566
+ const insertSlide = useCallback(() => {
567
+ if (mutationsBlocked) return;
568
+ const slideId = randomPresentationId();
569
+ const index = activeIndex < 0 ? slides.length : activeIndex + 1;
570
+ const command = { kind: "slide-insert", slideId, index };
571
+ const submit = () => {
572
+ pendingSlideIdRef.current = slideId;
573
+ runCommit(
574
+ `slide-insert:${slideId}`,
575
+ command,
576
+ () => {
577
+ if (pendingSlideIdRef.current === slideId) pendingSlideIdRef.current = null;
578
+ },
579
+ submit
580
+ );
581
+ };
582
+ submit();
583
+ }, [activeIndex, mutationsBlocked, runCommit, slides.length]);
584
+ const deleteSlide = useCallback(() => {
585
+ if (mutationsBlocked || !activeSlide) return;
586
+ const command = {
587
+ kind: "slide-delete",
588
+ slideId: activeSlide.id,
589
+ index: activeIndex
590
+ };
591
+ const submit = () => runCommit(`slide-delete:${activeSlide.id}`, command, () => void 0, submit);
592
+ submit();
593
+ }, [activeIndex, activeSlide, mutationsBlocked, runCommit]);
594
+ const insertTextBox = useCallback(() => {
595
+ if (mutationsBlocked || !activeSlide) return;
596
+ const objectId = randomPresentationId();
597
+ const position = nextTextBoxPosition(objects, presentation.slideSize);
598
+ const command = {
599
+ kind: "object-insert",
600
+ slideId: activeSlide.id,
601
+ objectId,
602
+ index: activeSlide.elements.length,
603
+ position
604
+ };
605
+ const submit = () => {
606
+ pendingObjectIdRef.current = objectId;
607
+ runCommit(
608
+ `object-insert:${activeSlide.id}:${objectId}`,
609
+ command,
610
+ () => {
611
+ if (pendingObjectIdRef.current === objectId) pendingObjectIdRef.current = null;
612
+ },
613
+ submit
614
+ );
615
+ };
616
+ submit();
617
+ }, [activeSlide, objects, presentation.slideSize, mutationsBlocked, runCommit]);
618
+ const deleteObject = useCallback(() => {
619
+ if (mutationsBlocked || !activeSlide || !selected || selected.readOnly) return;
620
+ const command = {
621
+ kind: "object-delete",
622
+ slideId: activeSlide.id,
623
+ objectId: selected.id
624
+ };
625
+ const submit = () => runCommit(`object-delete:${activeSlide.id}:${selected.id}`, command, () => void 0, submit);
626
+ submit();
627
+ }, [activeSlide, mutationsBlocked, runCommit, selected]);
628
+ const startTextEdit = useCallback(
629
+ (entry) => {
630
+ if (mutationsBlocked || !entry || entry.readOnly || entry.kind !== "shape") return;
631
+ const shape = entry.object;
632
+ if (shape.geometry === "line") return;
633
+ const before = shape.text.toString();
634
+ if (!activeSlide) return;
635
+ const edit = { slideId: activeSlide.id, shape, before };
636
+ textEditRef.current = edit;
637
+ setTextEdit(edit);
638
+ setTextDraft(before);
639
+ },
640
+ [activeSlide, mutationsBlocked]
641
+ );
642
+ useEffect(() => {
643
+ if (!textEdit) return;
644
+ editorRef.current?.focus();
645
+ editorRef.current?.select();
646
+ }, [textEdit]);
647
+ const finishTextEdit = useCallback(
648
+ (cancel = false) => {
649
+ const edit = textEditRef.current;
650
+ if (!edit || !cancel && authoringBlockedReason !== void 0) return;
651
+ textEditRef.current = null;
652
+ setTextEdit(null);
653
+ const { shape, before, slideId } = edit;
654
+ if (!activeSlide || activeSlide.id !== slideId) return;
655
+ if (cancel || mutationsBlocked || before === textDraft) return;
656
+ shape.text.set(textDraft);
657
+ setModelEpoch((value) => value + 1);
658
+ const command = {
659
+ kind: "text",
660
+ slideId,
661
+ objectId: shape.id,
662
+ before,
663
+ after: textDraft
664
+ };
665
+ const submit = () => runCommit(
666
+ `text:${slideId}:${shape.id}`,
667
+ command,
668
+ () => {
669
+ shape.text.set(before);
670
+ setModelEpoch((value) => value + 1);
671
+ },
672
+ () => {
673
+ shape.text.set(textDraft);
674
+ setModelEpoch((value) => value + 1);
675
+ submit();
676
+ }
677
+ );
678
+ submit();
679
+ },
680
+ [activeSlide, authoringBlockedReason, mutationsBlocked, runCommit, textDraft]
681
+ );
682
+ const cycleObject = useCallback(
683
+ (direction) => {
684
+ if (objects.length === 0) return;
685
+ const current = selected ? objects.indexOf(selected) : direction === 1 ? -1 : 0;
686
+ const next = (current + direction + objects.length) % objects.length;
687
+ selectObject(objects[next] ?? null);
688
+ },
689
+ [objects, selectObject, selected]
690
+ );
691
+ const changeSlideBy = useCallback(
692
+ (amount) => {
693
+ if (activeIndex < 0) return;
694
+ const nextIndex = Math.max(0, Math.min(slides.length - 1, activeIndex + amount));
695
+ const next = slides[nextIndex];
696
+ if (next && next !== activeSlide) selectSlide(next, nextIndex);
697
+ },
698
+ [activeIndex, activeSlide, selectSlide, slides]
699
+ );
700
+ const toggleMobileSlideSelector = useCallback(() => {
701
+ setMobileSelectorOpen((open) => {
702
+ if (open) return false;
703
+ const index = Math.max(0, activeIndex);
704
+ const height = DEFAULT_MOBILE_LIST_HEIGHT;
705
+ const maxScroll = Math.max(0, slides.length * MOBILE_RAIL_ITEM_HEIGHT - height);
706
+ const scrollTop = Math.max(
707
+ 0,
708
+ Math.min(
709
+ maxScroll,
710
+ index * MOBILE_RAIL_ITEM_HEIGHT - height / 2 + MOBILE_RAIL_ITEM_HEIGHT / 2
711
+ )
712
+ );
713
+ mobileRailScrollOnOpenRef.current = scrollTop;
714
+ setMobileRail({ scrollTop, height });
715
+ return true;
716
+ });
717
+ }, [activeIndex, slides.length]);
718
+ const chooseMobileSlide = useCallback(
719
+ (slide, index) => {
720
+ if (slide !== activeSlide) selectSlide(slide, index);
721
+ setMobileSelectorOpen(false);
722
+ mobileSelectorTriggerRef.current?.focus();
723
+ },
724
+ [activeSlide, selectSlide]
725
+ );
726
+ const handleCanvasKeyDown = useCallback(
727
+ (event) => {
728
+ if (event.metaKey || event.ctrlKey) {
729
+ if (event.key === "+" || event.key === "=") {
730
+ event.preventDefault();
731
+ changeZoom(zoom * 1.15);
732
+ } else if (event.key === "-") {
733
+ event.preventDefault();
734
+ changeZoom(zoom / 1.15);
735
+ } else if (event.key === "0") {
736
+ event.preventDefault();
737
+ fitSlide();
738
+ }
739
+ return;
740
+ }
741
+ if (event.key === "]") {
742
+ event.preventDefault();
743
+ cycleObject(1);
744
+ return;
745
+ }
746
+ if (event.key === "[") {
747
+ event.preventDefault();
748
+ cycleObject(-1);
749
+ return;
750
+ }
751
+ if (event.key === "PageDown") {
752
+ event.preventDefault();
753
+ changeSlideBy(1);
754
+ return;
755
+ }
756
+ if (event.key === "PageUp") {
757
+ event.preventDefault();
758
+ changeSlideBy(-1);
759
+ return;
760
+ }
761
+ if (event.key === "Escape") {
762
+ event.preventDefault();
763
+ selectObject(null);
764
+ return;
765
+ }
766
+ if (event.key === "Enter" || event.key === "F2") {
767
+ if (selected?.kind === "shape") {
768
+ event.preventDefault();
769
+ startTextEdit(selected);
770
+ }
771
+ return;
772
+ }
773
+ if (!selected || !event.key.startsWith("Arrow")) return;
774
+ event.preventDefault();
775
+ if (mutationsBlocked || selected.readOnly) return;
776
+ const amount = event.shiftKey ? 10 : 1;
777
+ const dx = event.key === "ArrowLeft" ? -amount : event.key === "ArrowRight" ? amount : 0;
778
+ const dy = event.key === "ArrowUp" ? -amount : event.key === "ArrowDown" ? amount : 0;
779
+ const before = selected.object.position;
780
+ commitPosition(
781
+ selected,
782
+ event.altKey ? "resize" : "move",
783
+ event.altKey ? {
784
+ ...before,
785
+ width: Math.max(8, before.width + dx),
786
+ height: Math.max(8, before.height + dy)
787
+ } : { ...before, left: before.left + dx, top: before.top + dy }
788
+ );
789
+ },
790
+ [
791
+ changeSlideBy,
792
+ changeZoom,
793
+ commitPosition,
794
+ cycleObject,
795
+ fitSlide,
796
+ mutationsBlocked,
797
+ selectObject,
798
+ selected,
799
+ startTextEdit,
800
+ zoom
801
+ ]
802
+ );
803
+ const pointFromPointer = useCallback(
804
+ (event) => {
805
+ const rect = overlayRef.current?.getBoundingClientRect() ?? event.currentTarget.getBoundingClientRect();
806
+ const width = rect.width || presentation.slideSize.width * zoom;
807
+ const height = rect.height || presentation.slideSize.height * zoom;
808
+ return {
809
+ x: (event.clientX - rect.left) / Math.max(1, width) * presentation.slideSize.width,
810
+ y: (event.clientY - rect.top) / Math.max(1, height) * presentation.slideSize.height
811
+ };
812
+ },
813
+ [presentation.slideSize.height, presentation.slideSize.width, zoom]
814
+ );
815
+ const beginDrag = useCallback(
816
+ (event, entry, mode) => {
817
+ event.preventDefault();
818
+ event.stopPropagation();
819
+ selectObject(entry);
820
+ if (mutationsBlocked || entry.readOnly) return;
821
+ const start = pointFromPointer(event);
822
+ const before = copyPosition(entry.object.position);
823
+ dragRef.current = {
824
+ pointerId: event.pointerId,
825
+ mode,
826
+ object: entry.object,
827
+ rotation: objectRotation(entry),
828
+ start,
829
+ before
830
+ };
831
+ setDraftPosition({ objectId: entry.id, position: before });
832
+ overlayRef.current?.setPointerCapture?.(event.pointerId);
833
+ },
834
+ [pointFromPointer, mutationsBlocked, selectObject]
835
+ );
836
+ const handlePointerDown = useCallback(
837
+ (event) => {
838
+ if (event.button !== 0) return;
839
+ const point = pointFromPointer(event);
840
+ const hit = hitTest(spatialIndex, point.x, point.y);
841
+ if (!hit) {
842
+ selectObject(null);
843
+ return;
844
+ }
845
+ beginDrag(event, hit, "move");
846
+ },
847
+ [beginDrag, pointFromPointer, selectObject, spatialIndex]
848
+ );
849
+ const handlePointerMove = useCallback(
850
+ (event) => {
851
+ const drag = dragRef.current;
852
+ if (!drag || drag.pointerId !== event.pointerId || mutationsBlocked) return;
853
+ const point = pointFromPointer(event);
854
+ setDraftPosition({ objectId: drag.object.id, position: positionFromDrag(drag, point) });
855
+ },
856
+ [mutationsBlocked, pointFromPointer]
857
+ );
858
+ const finishDrag = useCallback(
859
+ (event, cancel = false) => {
860
+ const drag = dragRef.current;
861
+ if (!drag || drag.pointerId !== event.pointerId || !cancel && authoringBlockedReason !== void 0)
862
+ return;
863
+ dragRef.current = null;
864
+ const captureTarget = overlayRef.current;
865
+ if (captureTarget?.hasPointerCapture?.(event.pointerId)) {
866
+ captureTarget.releasePointerCapture(event.pointerId);
867
+ }
868
+ setDraftPosition(null);
869
+ if (cancel) return;
870
+ const entry = objectById.get(drag.object.id);
871
+ if (!entry) return;
872
+ const point = pointFromPointer(event);
873
+ commitPosition(entry, drag.mode, positionFromDrag(drag, point));
874
+ },
875
+ [authoringBlockedReason, commitPosition, objectById, pointFromPointer]
876
+ );
877
+ const handleLostPointerCapture = useCallback(
878
+ (event) => {
879
+ const drag = dragRef.current;
880
+ if (!drag || drag.pointerId !== event.pointerId || authoringBlockedReason !== void 0)
881
+ return;
882
+ dragRef.current = null;
883
+ setDraftPosition(null);
884
+ },
885
+ [authoringBlockedReason]
886
+ );
887
+ const railStart = Math.max(0, Math.floor(rail.scrollTop / RAIL_ITEM_HEIGHT) - RAIL_OVERSCAN);
888
+ const railEnd = Math.min(
889
+ slides.length,
890
+ Math.ceil((rail.scrollTop + rail.height) / RAIL_ITEM_HEIGHT) + RAIL_OVERSCAN
891
+ );
892
+ const mobileRailStart = Math.max(
893
+ 0,
894
+ Math.floor(mobileRail.scrollTop / MOBILE_RAIL_ITEM_HEIGHT) - MOBILE_RAIL_OVERSCAN
895
+ );
896
+ const mobileRailEnd = Math.min(
897
+ slides.length,
898
+ Math.ceil((mobileRail.scrollTop + mobileRail.height) / MOBILE_RAIL_ITEM_HEIGHT) + MOBILE_RAIL_OVERSCAN
899
+ );
900
+ const slideCountLabel = activeIndex >= 0 ? `${activeIndex + 1} / ${slides.length}` : `0 / ${slides.length}`;
901
+ const stageWidth = presentation.slideSize.width * zoom;
902
+ const stageHeight = presentation.slideSize.height * zoom;
903
+ return /* @__PURE__ */ jsxs(
904
+ "div",
905
+ {
906
+ className: cn("flex size-full min-w-0 flex-col bg-og-surface-1", className),
907
+ style: { minHeight: "22rem" },
908
+ "data-og-presentation-editor": true,
909
+ "data-og-painted-object-count": visibleObjectIndexes.length,
910
+ "data-og-command-state": commandFailure || authoringBlockedReason === "pending_conflict" ? "error" : pendingCommands > 0 || authoringBlockedReason === "prior_writer" ? "pending" : "idle",
911
+ "aria-busy": pendingCommands > 0 || authoringBlockedReason === "prior_writer" ? "true" : void 0,
912
+ children: [
913
+ /* @__PURE__ */ jsxs(
914
+ "div",
915
+ {
916
+ role: "toolbar",
917
+ "aria-label": t("artifacts.presentationEditor.presentationControls"),
918
+ className: "flex h-10 shrink-0 items-center border-b border-og-border bg-og-surface-2",
919
+ children: [
920
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-1 overflow-x-auto px-2 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden", children: [
921
+ /* @__PURE__ */ jsx(
922
+ "button",
923
+ {
924
+ type: "button",
925
+ "aria-label": t("artifacts.presentationEditor.previousSlide"),
926
+ disabled: activeIndex <= 0,
927
+ onClick: () => changeSlideBy(-1),
928
+ className: "grid size-7 shrink-0 place-items-center rounded-og-sm text-og-fg-muted hover:bg-og-surface-3 hover:text-og-fg disabled:opacity-35 [&>svg]:size-3.5",
929
+ children: /* @__PURE__ */ jsx(ChevronLeftIcon, {})
930
+ }
931
+ ),
932
+ /* @__PURE__ */ jsx(
933
+ "button",
934
+ {
935
+ ref: mobileSelectorTriggerRef,
936
+ type: "button",
937
+ "aria-label": t("artifacts.presentationEditor.chooseSlide"),
938
+ "aria-haspopup": "listbox",
939
+ "aria-expanded": mobileSelectorOpen,
940
+ "aria-controls": mobileSelectorOpen ? `${domId}-mobile-slides` : void 0,
941
+ disabled: slides.length === 0,
942
+ "data-og-mobile-slide-selector": true,
943
+ onClick: toggleMobileSlideSelector,
944
+ className: "inline-flex min-h-11 min-w-16 shrink-0 items-center justify-center rounded-og-sm px-2 text-og-xs tabular-nums text-og-fg-muted hover:bg-og-surface-3 hover:text-og-fg disabled:opacity-35 sm:hidden",
945
+ children: /* @__PURE__ */ jsx("span", { children: slideCountLabel })
946
+ }
947
+ ),
948
+ /* @__PURE__ */ jsx("span", { className: "hidden min-w-16 shrink-0 text-center text-og-xs tabular-nums text-og-fg-muted sm:inline", children: slideCountLabel }),
949
+ /* @__PURE__ */ jsx(
950
+ "button",
951
+ {
952
+ type: "button",
953
+ "aria-label": t("artifacts.presentationEditor.nextSlide"),
954
+ disabled: activeIndex < 0 || activeIndex >= slides.length - 1,
955
+ onClick: () => changeSlideBy(1),
956
+ className: "grid size-7 shrink-0 place-items-center rounded-og-sm text-og-fg-muted hover:bg-og-surface-3 hover:text-og-fg disabled:opacity-35 [&>svg]:size-3.5",
957
+ children: /* @__PURE__ */ jsx(ChevronRightIcon, {})
958
+ }
959
+ ),
960
+ /* @__PURE__ */ jsx(
961
+ "button",
962
+ {
963
+ type: "button",
964
+ "aria-label": t("artifacts.presentationEditor.addSlide"),
965
+ disabled: mutationsBlocked,
966
+ onClick: insertSlide,
967
+ className: "ml-0.5 grid size-7 shrink-0 place-items-center rounded-og-sm text-og-fg-muted hover:bg-og-surface-3 hover:text-og-fg disabled:opacity-35 [&>svg]:size-3.5",
968
+ children: /* @__PURE__ */ jsx(FilePlus2Icon, {})
969
+ }
970
+ ),
971
+ /* @__PURE__ */ jsx(
972
+ "button",
973
+ {
974
+ type: "button",
975
+ "aria-label": t("artifacts.presentationEditor.deleteSlide"),
976
+ disabled: mutationsBlocked || !activeSlide,
977
+ onClick: deleteSlide,
978
+ className: "grid size-7 shrink-0 place-items-center rounded-og-sm text-og-fg-muted hover:bg-og-surface-3 hover:text-og-status-failed disabled:opacity-35 [&>svg]:size-3.5",
979
+ children: /* @__PURE__ */ jsx(Trash2Icon, {})
980
+ }
981
+ ),
982
+ /* @__PURE__ */ jsx("span", { className: "mx-1 h-4 w-px shrink-0 bg-og-border" }),
983
+ /* @__PURE__ */ jsx(
984
+ "button",
985
+ {
986
+ type: "button",
987
+ "aria-label": t("artifacts.presentationEditor.zoomOut"),
988
+ onClick: () => changeZoom(zoom / 1.15),
989
+ className: "grid size-7 shrink-0 place-items-center rounded-og-sm text-og-fg-muted hover:bg-og-surface-3 hover:text-og-fg [&>svg]:size-3.5",
990
+ children: /* @__PURE__ */ jsx(MinusIcon, {})
991
+ }
992
+ ),
993
+ /* @__PURE__ */ jsxs("span", { className: "min-w-11 shrink-0 text-center text-og-xs tabular-nums text-og-fg-muted", children: [
994
+ Math.round(zoom * 100),
995
+ "%"
996
+ ] }),
997
+ /* @__PURE__ */ jsx(
998
+ "button",
999
+ {
1000
+ type: "button",
1001
+ "aria-label": t("artifacts.presentationEditor.zoomIn"),
1002
+ onClick: () => changeZoom(zoom * 1.15),
1003
+ className: "grid size-7 shrink-0 place-items-center rounded-og-sm text-og-fg-muted hover:bg-og-surface-3 hover:text-og-fg [&>svg]:size-3.5",
1004
+ children: /* @__PURE__ */ jsx(PlusIcon, {})
1005
+ }
1006
+ ),
1007
+ /* @__PURE__ */ jsx(
1008
+ "button",
1009
+ {
1010
+ type: "button",
1011
+ "aria-label": t("artifacts.presentationEditor.fitSlide"),
1012
+ onClick: fitSlide,
1013
+ className: "ml-0.5 grid size-7 shrink-0 place-items-center rounded-og-sm text-og-fg-muted hover:bg-og-surface-3 hover:text-og-fg [&>svg]:size-3.5",
1014
+ children: /* @__PURE__ */ jsx(ExpandIcon, {})
1015
+ }
1016
+ ),
1017
+ /* @__PURE__ */ jsx("span", { className: "mx-1 h-4 w-px shrink-0 bg-og-border" }),
1018
+ /* @__PURE__ */ jsx(
1019
+ "button",
1020
+ {
1021
+ type: "button",
1022
+ "aria-label": t("artifacts.presentationEditor.addTextBox"),
1023
+ disabled: mutationsBlocked || !activeSlide,
1024
+ onClick: insertTextBox,
1025
+ className: "grid size-7 shrink-0 place-items-center rounded-og-sm text-og-fg-muted hover:bg-og-surface-3 hover:text-og-fg disabled:opacity-35 [&>svg]:size-3.5",
1026
+ children: /* @__PURE__ */ jsx(TypeIcon, {})
1027
+ }
1028
+ ),
1029
+ /* @__PURE__ */ jsx(
1030
+ "button",
1031
+ {
1032
+ type: "button",
1033
+ "aria-label": t("artifacts.presentationEditor.deleteSelectedObject"),
1034
+ disabled: mutationsBlocked || !selected || selected.readOnly,
1035
+ onClick: deleteObject,
1036
+ className: "grid size-7 shrink-0 place-items-center rounded-og-sm text-og-fg-muted hover:bg-og-surface-3 hover:text-og-status-failed disabled:opacity-35 [&>svg]:size-3.5",
1037
+ children: /* @__PURE__ */ jsx(Trash2Icon, {})
1038
+ }
1039
+ )
1040
+ ] }),
1041
+ /* @__PURE__ */ jsx(
1042
+ "span",
1043
+ {
1044
+ className: "hidden max-w-44 shrink-0 truncate border-l border-og-border px-2 text-og-xs text-og-fg-subtle sm:block",
1045
+ title: commandFailure ? t("artifacts.presentationEditor.changeNotSaved") : authoringStatus ? authoringStatus : pendingCommands > 0 ? t("artifacts.presentationEditor.saving") : mutationsBlocked ? t("artifacts.presentationEditor.viewOnly") : selected ? `${objectLabel(t, selected)}${selected.readOnly ? " \xB7 View only" : ""}` : t("artifacts.presentationEditor.selectAnObjectToEdit"),
1046
+ children: commandFailure ? t("artifacts.presentationEditor.changeNotSaved") : authoringStatus ? authoringStatus : pendingCommands > 0 ? t("artifacts.presentationEditor.saving") : mutationsBlocked ? t("artifacts.presentationEditor.viewOnly") : selected ? `${objectLabel(t, selected)}${selected.readOnly ? " \xB7 View only" : ""}` : t("artifacts.presentationEditor.selectAnObjectToEdit")
1047
+ }
1048
+ )
1049
+ ]
1050
+ }
1051
+ ),
1052
+ /* @__PURE__ */ jsx("div", { role: "status", "aria-live": "polite", className: "sr-only", children: commandFailure?.message ?? authoringStatus ?? (pendingCommands > 0 ? t("artifacts.presentationEditor.savingPresentationChanges") : "") }),
1053
+ /* @__PURE__ */ jsxs("div", { className: "relative flex min-h-0 min-w-0 flex-1", children: [
1054
+ /* @__PURE__ */ jsx(
1055
+ "div",
1056
+ {
1057
+ ref: railRef,
1058
+ role: "listbox",
1059
+ tabIndex: 0,
1060
+ "aria-label": t("artifacts.presentationEditor.slides"),
1061
+ "aria-orientation": "vertical",
1062
+ "aria-activedescendant": activeSlide && activeIndex >= railStart && activeIndex < railEnd ? `${domId}-slide-${safeDomId(activeSlide.id)}` : void 0,
1063
+ className: "relative hidden w-40 shrink-0 overflow-y-auto border-r border-og-border bg-og-surface-2/70 outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-og-accent sm:block",
1064
+ "data-og-slide-rail": true,
1065
+ "data-og-window-start": railStart,
1066
+ "data-og-window-end": railEnd,
1067
+ onScroll: (event) => {
1068
+ const scrollTop = event.currentTarget.scrollTop;
1069
+ const height = event.currentTarget.clientHeight;
1070
+ setRail((current) => ({
1071
+ scrollTop,
1072
+ height: height || current.height
1073
+ }));
1074
+ },
1075
+ onKeyDown: (event) => {
1076
+ const nextIndex = nextSlideIndexFromKey(event.key, activeIndex, slides.length);
1077
+ if (nextIndex === null) return;
1078
+ event.preventDefault();
1079
+ const next = slides[nextIndex];
1080
+ if (next && next !== activeSlide) selectSlide(next, nextIndex);
1081
+ },
1082
+ children: /* @__PURE__ */ jsx("div", { className: "relative w-full", style: { height: slides.length * RAIL_ITEM_HEIGHT }, children: slides.slice(railStart, railEnd).map((slide, offset) => {
1083
+ const index = railStart + offset;
1084
+ const active = slide === activeSlide;
1085
+ return /* @__PURE__ */ jsxs(
1086
+ "button",
1087
+ {
1088
+ id: `${domId}-slide-${safeDomId(slide.id)}`,
1089
+ type: "button",
1090
+ role: "option",
1091
+ tabIndex: -1,
1092
+ "aria-selected": active,
1093
+ "aria-label": t("artifacts.presentationEditor.slideIndexValue", {
1094
+ index: index + 1,
1095
+ value: slide.title ? `: ${slide.title}` : ""
1096
+ }),
1097
+ onClick: () => selectSlide(slide, index),
1098
+ className: cn(
1099
+ "absolute left-0 flex w-full items-start gap-2 px-2 py-2 text-left transition-colors",
1100
+ active ? "bg-og-surface-3 text-og-fg" : "text-og-fg-muted hover:bg-og-surface-3/70"
1101
+ ),
1102
+ style: { top: index * RAIL_ITEM_HEIGHT, height: 116 },
1103
+ "data-og-slide-index": index,
1104
+ children: [
1105
+ /* @__PURE__ */ jsx("span", { className: "w-5 shrink-0 pt-0.5 text-right text-og-xs tabular-nums text-og-fg-subtle", children: index + 1 }),
1106
+ /* @__PURE__ */ jsx(
1107
+ "span",
1108
+ {
1109
+ className: cn(
1110
+ "block min-w-0 flex-1 overflow-hidden border bg-white shadow-og-sm",
1111
+ active ? "border-og-accent" : "border-og-border"
1112
+ ),
1113
+ style: { aspectRatio: "16 / 9", borderRadius: 3 },
1114
+ children: /* @__PURE__ */ jsx(
1115
+ SlideThumbnail,
1116
+ {
1117
+ slide,
1118
+ width: presentation.slideSize.width,
1119
+ height: presentation.slideSize.height,
1120
+ paintRevision: `${String(revision ?? "")}:${modelEpoch}`
1121
+ }
1122
+ )
1123
+ }
1124
+ )
1125
+ ]
1126
+ },
1127
+ slide.id
1128
+ );
1129
+ }) })
1130
+ }
1131
+ ),
1132
+ mobileSelectorOpen ? /* @__PURE__ */ jsx(
1133
+ "div",
1134
+ {
1135
+ ref: mobileSelectorPanelRef,
1136
+ className: "absolute left-2 top-2 z-40 max-w-56 overflow-hidden rounded-og-md border border-og-border bg-og-surface-1 shadow-og-md sm:hidden",
1137
+ style: { width: "calc(100% - 1rem)" },
1138
+ children: /* @__PURE__ */ jsx(
1139
+ "div",
1140
+ {
1141
+ ref: mobileRailRef,
1142
+ id: `${domId}-mobile-slides`,
1143
+ role: "listbox",
1144
+ tabIndex: 0,
1145
+ "aria-label": t("artifacts.presentationEditor.slides"),
1146
+ "aria-orientation": "vertical",
1147
+ "aria-activedescendant": activeSlide && activeIndex >= mobileRailStart && activeIndex < mobileRailEnd ? `${domId}-mobile-slide-${safeDomId(activeSlide.id)}` : void 0,
1148
+ className: "max-h-72 overflow-y-auto outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-og-accent",
1149
+ "data-og-mobile-slide-list": true,
1150
+ "data-og-window-start": mobileRailStart,
1151
+ "data-og-window-end": mobileRailEnd,
1152
+ onScroll: (event) => {
1153
+ const scrollTop = event.currentTarget.scrollTop;
1154
+ const height = event.currentTarget.clientHeight;
1155
+ setMobileRail((current) => ({
1156
+ scrollTop,
1157
+ height: height || current.height
1158
+ }));
1159
+ },
1160
+ onKeyDown: (event) => {
1161
+ if (event.key === "Escape") {
1162
+ event.preventDefault();
1163
+ setMobileSelectorOpen(false);
1164
+ mobileSelectorTriggerRef.current?.focus();
1165
+ return;
1166
+ }
1167
+ const nextIndex = nextSlideIndexFromKey(event.key, activeIndex, slides.length);
1168
+ if (nextIndex === null) return;
1169
+ event.preventDefault();
1170
+ const next = slides[nextIndex];
1171
+ if (!next) return;
1172
+ if (next !== activeSlide) selectSlide(next, nextIndex);
1173
+ const list = event.currentTarget;
1174
+ const top = nextIndex * MOBILE_RAIL_ITEM_HEIGHT;
1175
+ const bottom = top + MOBILE_RAIL_ITEM_HEIGHT;
1176
+ if (top < list.scrollTop) list.scrollTop = top;
1177
+ else if (bottom > list.scrollTop + list.clientHeight) {
1178
+ list.scrollTop = bottom - list.clientHeight;
1179
+ }
1180
+ },
1181
+ children: /* @__PURE__ */ jsx(
1182
+ "div",
1183
+ {
1184
+ className: "relative w-full",
1185
+ style: { height: slides.length * MOBILE_RAIL_ITEM_HEIGHT },
1186
+ children: slides.slice(mobileRailStart, mobileRailEnd).map((slide, offset) => {
1187
+ const index = mobileRailStart + offset;
1188
+ const active = slide === activeSlide;
1189
+ return /* @__PURE__ */ jsxs(
1190
+ "button",
1191
+ {
1192
+ id: `${domId}-mobile-slide-${safeDomId(slide.id)}`,
1193
+ type: "button",
1194
+ role: "option",
1195
+ tabIndex: -1,
1196
+ "aria-selected": active,
1197
+ "aria-label": t("artifacts.presentationEditor.slideIndexValue", {
1198
+ index: index + 1,
1199
+ value: slide.title ? `: ${slide.title}` : ""
1200
+ }),
1201
+ onClick: () => chooseMobileSlide(slide, index),
1202
+ className: cn(
1203
+ "absolute left-0 flex min-h-11 w-full items-center gap-2 px-2 text-left",
1204
+ active ? "bg-og-surface-3 text-og-fg" : "text-og-fg-muted hover:bg-og-surface-3/70"
1205
+ ),
1206
+ style: {
1207
+ top: index * MOBILE_RAIL_ITEM_HEIGHT,
1208
+ height: MOBILE_RAIL_ITEM_HEIGHT
1209
+ },
1210
+ "data-og-mobile-slide-index": index,
1211
+ children: [
1212
+ /* @__PURE__ */ jsx("span", { className: "w-7 shrink-0 text-right text-og-xs tabular-nums text-og-fg-subtle", children: index + 1 }),
1213
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-og-sm", children: slide.title || t("artifacts.presentationEditor.slideIndex", { index: index + 1 }) })
1214
+ ]
1215
+ },
1216
+ slide.id
1217
+ );
1218
+ })
1219
+ }
1220
+ )
1221
+ }
1222
+ )
1223
+ }
1224
+ ) : null,
1225
+ /* @__PURE__ */ jsxs(
1226
+ "div",
1227
+ {
1228
+ ref: viewportRef,
1229
+ className: "relative min-h-0 min-w-0 flex-1 overflow-auto bg-og-surface-3/60 p-6",
1230
+ onScroll: (event) => {
1231
+ const element = event.currentTarget;
1232
+ const width = element.clientWidth || viewport.width;
1233
+ const height = element.clientHeight || viewport.height;
1234
+ const next = {
1235
+ scrollLeft: element.scrollLeft,
1236
+ scrollTop: element.scrollTop,
1237
+ width,
1238
+ height,
1239
+ stageLeft: stageRef.current?.offsetLeft ?? 0,
1240
+ stageTop: stageRef.current?.offsetTop ?? 0
1241
+ };
1242
+ setViewport((current) => sameViewport(current, next) ? current : next);
1243
+ if (element.clientWidth > 0 && element.clientHeight > 0) setViewportMeasured(true);
1244
+ },
1245
+ "data-og-presentation-viewport": true,
1246
+ children: [
1247
+ commandFailure ? /* @__PURE__ */ jsxs(
1248
+ "div",
1249
+ {
1250
+ role: "alert",
1251
+ className: "absolute left-2 top-2 z-30 flex w-fit items-center gap-2 rounded-og-sm border border-og-status-failed/30 bg-og-surface-1/95 px-2 py-1 text-og-xs text-og-status-failed shadow-og-sm",
1252
+ style: { maxWidth: "calc(100% - 1rem)" },
1253
+ children: [
1254
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: commandFailure.message }),
1255
+ /* @__PURE__ */ jsx(
1256
+ "button",
1257
+ {
1258
+ type: "button",
1259
+ disabled: mutationsBlocked,
1260
+ onClick: () => {
1261
+ if (!mutationsBlocked) commandFailure.retry();
1262
+ },
1263
+ className: "shrink-0 rounded-og-xs px-1.5 py-0.5 font-medium outline-hidden hover:bg-og-surface-3 focus-visible:ring-2 focus-visible:ring-og-accent",
1264
+ children: t("artifacts.presentationEditor.retry")
1265
+ }
1266
+ )
1267
+ ]
1268
+ }
1269
+ ) : null,
1270
+ activeSlide ? /* @__PURE__ */ jsxs(
1271
+ "div",
1272
+ {
1273
+ ref: stageRef,
1274
+ className: "relative mx-auto shrink-0 overflow-hidden shadow-og-lg",
1275
+ style: { width: stageWidth, height: stageHeight, backgroundColor: "#fff" },
1276
+ "data-og-presentation-stage": true,
1277
+ "data-og-theme": "light",
1278
+ children: [
1279
+ /* @__PURE__ */ jsx(
1280
+ "canvas",
1281
+ {
1282
+ ref: canvasRef,
1283
+ "aria-hidden": true,
1284
+ className: "absolute inset-0 size-full",
1285
+ style: { width: stageWidth, height: stageHeight }
1286
+ }
1287
+ ),
1288
+ /* @__PURE__ */ jsx(
1289
+ "svg",
1290
+ {
1291
+ ref: overlayRef,
1292
+ role: "application",
1293
+ tabIndex: 0,
1294
+ "aria-label": t("artifacts.presentationEditor.slideActiveindexEditor", {
1295
+ activeIndex: activeIndex + 1
1296
+ }),
1297
+ "aria-describedby": selected ? `${instructionsId} ${selectionProxyId}` : instructionsId,
1298
+ "aria-readonly": mutationsBlocked || selected?.readOnly || void 0,
1299
+ viewBox: `0 0 ${presentation.slideSize.width} ${presentation.slideSize.height}`,
1300
+ className: "absolute inset-0 size-full touch-none outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-og-accent",
1301
+ onKeyDown: handleCanvasKeyDown,
1302
+ onPointerDown: handlePointerDown,
1303
+ onPointerMove: handlePointerMove,
1304
+ onPointerUp: (event) => finishDrag(event),
1305
+ onPointerCancel: (event) => finishDrag(event, true),
1306
+ onLostPointerCapture: handleLostPointerCapture,
1307
+ onDoubleClick: () => startTextEdit(selected),
1308
+ children: selected && effectiveSelectedPosition ? /* @__PURE__ */ jsxs(
1309
+ "g",
1310
+ {
1311
+ "data-og-presentation-object": selected.id,
1312
+ transform: selectionTransform(selected, effectiveSelectedPosition),
1313
+ children: [
1314
+ /* @__PURE__ */ jsx(
1315
+ "rect",
1316
+ {
1317
+ x: effectiveSelectedPosition.left,
1318
+ y: effectiveSelectedPosition.top,
1319
+ width: effectiveSelectedPosition.width,
1320
+ height: effectiveSelectedPosition.height,
1321
+ fill: "transparent",
1322
+ stroke: "var(--og-color-accent-deep)",
1323
+ strokeWidth: 2,
1324
+ vectorEffect: "non-scaling-stroke",
1325
+ pointerEvents: "none"
1326
+ }
1327
+ ),
1328
+ !mutationsBlocked && !selected.readOnly ? /* @__PURE__ */ jsx(
1329
+ "circle",
1330
+ {
1331
+ cx: effectiveSelectedPosition.left + effectiveSelectedPosition.width,
1332
+ cy: effectiveSelectedPosition.top + effectiveSelectedPosition.height,
1333
+ r: 6 / zoom,
1334
+ fill: "var(--og-color-accent-deep)",
1335
+ stroke: "white",
1336
+ strokeWidth: 1.5,
1337
+ vectorEffect: "non-scaling-stroke",
1338
+ className: "cursor-nwse-resize",
1339
+ onPointerDown: (event) => beginDrag(event, selected, "resize")
1340
+ }
1341
+ ) : null
1342
+ ]
1343
+ }
1344
+ ) : null
1345
+ }
1346
+ ),
1347
+ selected ? /* @__PURE__ */ jsx("span", { id: selectionProxyId, role: "status", "aria-live": "polite", className: "sr-only", children: accessibleObjectLabel(t, selected) }) : null,
1348
+ /* @__PURE__ */ jsx("span", { id: instructionsId, className: "sr-only", children: t("artifacts.presentationEditor.useBracketKeysToSelect") }),
1349
+ textEdit && selected?.id === textEdit.shape.id && effectiveSelectedPosition ? /* @__PURE__ */ jsx(
1350
+ "textarea",
1351
+ {
1352
+ ref: editorRef,
1353
+ "aria-label": t("artifacts.presentationEditor.editName", {
1354
+ name: textEdit.shape.name
1355
+ }),
1356
+ value: textDraft,
1357
+ readOnly: mutationsBlocked,
1358
+ maxLength: 1e6,
1359
+ onChange: (event) => {
1360
+ if (!mutationsBlocked) setTextDraft(event.currentTarget.value);
1361
+ },
1362
+ onInput: (event) => {
1363
+ if (!mutationsBlocked) setTextDraft(event.currentTarget.value);
1364
+ },
1365
+ onBlur: () => finishTextEdit(),
1366
+ onKeyDown: (event) => {
1367
+ if (event.key === "Escape") {
1368
+ event.preventDefault();
1369
+ finishTextEdit(true);
1370
+ } else if (event.key === "Enter" && (event.metaKey || event.ctrlKey)) {
1371
+ event.preventDefault();
1372
+ finishTextEdit();
1373
+ }
1374
+ },
1375
+ className: "absolute resize-none overflow-hidden border-2 border-og-accent p-1 outline-hidden",
1376
+ style: {
1377
+ left: effectiveSelectedPosition.left * zoom,
1378
+ top: effectiveSelectedPosition.top * zoom,
1379
+ width: effectiveSelectedPosition.width * zoom,
1380
+ height: effectiveSelectedPosition.height * zoom,
1381
+ backgroundColor: "#fffffff2",
1382
+ color: resolveColor(textEdit.shape.text.style.color ?? "slate-950"),
1383
+ fontFamily: textEdit.shape.text.style.fontFamily ?? "Arial, sans-serif",
1384
+ fontSize: Math.max(8, (textEdit.shape.text.style.fontSize ?? 18) * zoom),
1385
+ fontWeight: textEdit.shape.text.style.bold ? 700 : 400,
1386
+ fontStyle: textEdit.shape.text.style.italic ? "italic" : "normal",
1387
+ textAlign: textEdit.shape.text.style.alignment ?? "left",
1388
+ transform: textEdit.shape.rotation === 0 ? void 0 : `rotate(${textEdit.shape.rotation}deg)`,
1389
+ transformOrigin: "center"
1390
+ }
1391
+ }
1392
+ ) : null
1393
+ ]
1394
+ }
1395
+ ) : /* @__PURE__ */ jsx("div", { className: "grid size-full min-h-72 place-items-center text-og-sm text-og-fg-muted", children: t("artifacts.presentationEditor.thisPresentationHasNoSlides") })
1396
+ ]
1397
+ }
1398
+ )
1399
+ ] })
1400
+ ]
1401
+ }
1402
+ );
1403
+ }
1404
+ function PresentationArtifactSurface({
1405
+ presentation,
1406
+ title: titleProp,
1407
+ showHeader,
1408
+ subtitle,
1409
+ actions,
1410
+ busy,
1411
+ className,
1412
+ ...editorProps
1413
+ }) {
1414
+ const t = useOpenGeniText();
1415
+ const title = titleProp === void 0 ? t("artifacts.presentationEditor.presentation") : titleProp;
1416
+ const count = presentation.slides.items.length;
1417
+ return /* @__PURE__ */ jsx(
1418
+ ArtifactSurface,
1419
+ {
1420
+ modality: "presentation",
1421
+ title,
1422
+ showHeader,
1423
+ subtitle: subtitle ?? t("counts.slides", { count }),
1424
+ actions,
1425
+ busy,
1426
+ className,
1427
+ children: /* @__PURE__ */ jsx(PresentationEditor, { ...editorProps, presentation })
1428
+ }
1429
+ );
1430
+ }
1431
+ function PresentationProjectionArtifactSurface({
1432
+ projection,
1433
+ title: titleProp,
1434
+ showHeader,
1435
+ subtitle,
1436
+ actions,
1437
+ busy,
1438
+ className,
1439
+ ...editorProps
1440
+ }) {
1441
+ const t = useOpenGeniText();
1442
+ const title = titleProp === void 0 ? t("artifacts.presentationEditor.presentation") : titleProp;
1443
+ const count = projection.slides.length;
1444
+ return /* @__PURE__ */ jsx(
1445
+ ArtifactSurface,
1446
+ {
1447
+ modality: "presentation",
1448
+ title,
1449
+ showHeader,
1450
+ subtitle: subtitle ?? t("counts.slides", { count }),
1451
+ actions,
1452
+ busy,
1453
+ className,
1454
+ children: /* @__PURE__ */ jsx(PresentationProjectionEditor, { ...editorProps, projection })
1455
+ }
1456
+ );
1457
+ }
1458
+ function SlideThumbnail({
1459
+ slide,
1460
+ width,
1461
+ height,
1462
+ paintRevision
1463
+ }) {
1464
+ const t = useOpenGeniText();
1465
+ const canvasRef = useRef(null);
1466
+ const imageCacheRef = useRef(/* @__PURE__ */ new Map());
1467
+ const [paintEpoch, setPaintEpoch] = useState(0);
1468
+ useLayoutEffect(() => {
1469
+ const imageCache = imageCacheRef.current;
1470
+ return () => disposeCanvasImageCache(imageCache);
1471
+ }, []);
1472
+ useLayoutEffect(() => {
1473
+ const canvas = canvasRef.current;
1474
+ const context = canvas?.getContext("2d");
1475
+ if (!canvas || !context) return;
1476
+ const displayWidth = 112;
1477
+ const scale = displayWidth / width;
1478
+ canvas.width = Math.max(1, Math.round(width * scale));
1479
+ canvas.height = Math.max(1, Math.round(height * scale));
1480
+ context.setTransform(scale, 0, 0, scale, 0, 0);
1481
+ context.fillStyle = resolveColor(slide.background.fill);
1482
+ context.fillRect(0, 0, width, height);
1483
+ const objects = listSlideObjects(slide);
1484
+ const usedImageSources = /* @__PURE__ */ new Set();
1485
+ for (const entry of objects) {
1486
+ drawObject(
1487
+ t,
1488
+ context,
1489
+ entry,
1490
+ entry.object.position,
1491
+ imageCacheRef.current,
1492
+ () => setPaintEpoch((value) => value + 1),
1493
+ { left: 0, top: 0, width, height },
1494
+ scale,
1495
+ usedImageSources
1496
+ );
1497
+ }
1498
+ disposeUnusedCanvasImages(imageCacheRef.current, usedImageSources);
1499
+ }, [height, paintEpoch, paintRevision, slide, width, t]);
1500
+ return /* @__PURE__ */ jsx("canvas", { ref: canvasRef, "aria-hidden": true, className: "block size-full" });
1501
+ }
1502
+ function presentationViewFromProjection(projection) {
1503
+ if (projection.slides.length > MAX_PROJECTION_SLIDES) {
1504
+ throw new Error(`Presentation projection exceeds ${MAX_PROJECTION_SLIDES} slides`);
1505
+ }
1506
+ const slideById = /* @__PURE__ */ new Map();
1507
+ const elementById = /* @__PURE__ */ new Map();
1508
+ const slideSize = {
1509
+ width: Math.min(MAX_EDITOR_GEOMETRY, Math.max(1, finite(projection.slideSize.width, 1))),
1510
+ height: Math.min(MAX_EDITOR_GEOMETRY, Math.max(1, finite(projection.slideSize.height, 1)))
1511
+ };
1512
+ const slides = projection.slides.map((slideProjection) => {
1513
+ if (slideProjection.elements.length > MAX_PROJECTION_ELEMENTS_PER_SLIDE) {
1514
+ throw new Error(
1515
+ `Slide ${slideProjection.id} exceeds ${MAX_PROJECTION_ELEMENTS_PER_SLIDE} projected objects`
1516
+ );
1517
+ }
1518
+ slideById.set(slideProjection.id, slideProjection);
1519
+ const elements = slideProjection.elements.map(
1520
+ (element) => presentationElementView(element, elementById, 0)
1521
+ );
1522
+ return {
1523
+ id: slideProjection.id,
1524
+ title: boundedProjectionText(slideProjection.title ?? ""),
1525
+ background: { fill: cloneProjectionFill(slideProjection.background ?? "white") },
1526
+ elements
1527
+ };
1528
+ });
1529
+ return {
1530
+ presentation: {
1531
+ slideSize,
1532
+ slides: { items: slides }
1533
+ },
1534
+ slideById,
1535
+ elementById
1536
+ };
1537
+ }
1538
+ function presentationElementView(element, byId, depth) {
1539
+ if (depth > MAX_PROJECTION_GROUP_DEPTH) {
1540
+ throw new Error(`Presentation group depth exceeds ${MAX_PROJECTION_GROUP_DEPTH}`);
1541
+ }
1542
+ byId.set(element.id, element);
1543
+ const position = normalizeEditorPosition(element.position);
1544
+ switch (element.kind) {
1545
+ case "shape": {
1546
+ const text = mutableProjectionText(element.text, element.textStyle);
1547
+ return {
1548
+ id: element.id,
1549
+ name: boundedProjectionText(element.name),
1550
+ __projectionReadOnly: element.readOnly ?? false,
1551
+ geometry: element.geometry,
1552
+ position,
1553
+ fill: cloneProjectionFill(
1554
+ element.fill ?? (element.geometry === "textbox" ? "none" : "white")
1555
+ ),
1556
+ line: cloneProjectionLine(element.line),
1557
+ rotation: finite(element.rotation ?? 0, 0),
1558
+ borderRadius: element.borderRadius,
1559
+ text
1560
+ };
1561
+ }
1562
+ case "chart":
1563
+ return {
1564
+ id: element.id,
1565
+ name: boundedProjectionText(element.name),
1566
+ __projectionReadOnly: element.readOnly ?? false,
1567
+ type: element.type,
1568
+ position,
1569
+ title: boundedProjectionText(element.title ?? ""),
1570
+ series: {
1571
+ items: element.series.map((series) => ({
1572
+ name: boundedProjectionText(series.name),
1573
+ categories: (series.categories ?? []).map(boundedProjectionText),
1574
+ values: series.values.map((value) => finite(value, 0)),
1575
+ xValues: (series.xValues ?? []).map((value) => finite(value, 0)),
1576
+ bubbleSizes: (series.bubbleSizes ?? []).map((value) => finite(value, 0)),
1577
+ fill: series.fill ? cloneProjectionFill(series.fill) : void 0,
1578
+ line: cloneProjectionLine(series.line)
1579
+ }))
1580
+ },
1581
+ xAxis: element.xAxis ? { ...element.xAxis } : void 0,
1582
+ yAxis: element.yAxis ? { ...element.yAxis } : void 0,
1583
+ dataLabels: element.dataLabels ? { ...element.dataLabels } : void 0
1584
+ };
1585
+ case "image": {
1586
+ const source = safeProjectionImageSource(element.source);
1587
+ return {
1588
+ id: element.id,
1589
+ name: boundedProjectionText(element.name),
1590
+ __projectionReadOnly: element.readOnly ?? false,
1591
+ position,
1592
+ alt: boundedProjectionText(element.alt ?? ""),
1593
+ prompt: element.prompt ? boundedProjectionText(element.prompt) : void 0,
1594
+ fit: element.fit ?? "contain",
1595
+ crop: element.crop ? { ...element.crop } : void 0,
1596
+ geometry: element.geometry ?? "rect",
1597
+ borderRadius: element.borderRadius,
1598
+ rotation: finite(element.rotation ?? 0, 0),
1599
+ flipHorizontal: element.flipHorizontal ?? false,
1600
+ flipVertical: element.flipVertical ?? false,
1601
+ sourceForSvg: () => source
1602
+ };
1603
+ }
1604
+ case "table": {
1605
+ const columns = element.rows[0]?.length ?? 0;
1606
+ if (columns <= 0 || element.rows.some((row) => row.length !== columns) || element.rows.length * columns > MAX_PROJECTION_TABLE_CELLS) {
1607
+ throw new Error(`Table ${element.id} has an invalid or oversized projected grid`);
1608
+ }
1609
+ return {
1610
+ id: element.id,
1611
+ name: boundedProjectionText(element.name),
1612
+ __projectionReadOnly: element.readOnly ?? false,
1613
+ position,
1614
+ rows: element.rows.map(
1615
+ (row) => row.map(
1616
+ (cell) => cell ? {
1617
+ text: mutableProjectionText(cell.text, cell.textStyle),
1618
+ fill: cloneProjectionFill(cell.fill ?? "white"),
1619
+ rowSpan: boundedSpan(cell.rowSpan),
1620
+ colSpan: boundedSpan(cell.colSpan)
1621
+ } : null
1622
+ )
1623
+ ),
1624
+ columnWidths: [...element.columnWidths ?? []],
1625
+ rowHeights: [...element.rowHeights ?? []],
1626
+ fill: cloneProjectionFill(element.fill ?? "white"),
1627
+ line: cloneProjectionLine(element.line),
1628
+ textStyle: { ...element.textStyle ?? {} }
1629
+ };
1630
+ }
1631
+ case "group":
1632
+ return {
1633
+ id: element.id,
1634
+ name: boundedProjectionText(element.name),
1635
+ __projectionReadOnly: element.readOnly ?? false,
1636
+ position,
1637
+ childOffset: {
1638
+ left: finite(element.childOffset.left, 0),
1639
+ top: finite(element.childOffset.top, 0)
1640
+ },
1641
+ childExtent: {
1642
+ width: Math.max(1, finite(element.childExtent.width, 1)),
1643
+ height: Math.max(1, finite(element.childExtent.height, 1))
1644
+ },
1645
+ rotation: finite(element.rotation ?? 0, 0),
1646
+ flipHorizontal: element.flipHorizontal ?? false,
1647
+ flipVertical: element.flipVertical ?? false,
1648
+ children: element.children.map((child) => presentationElementView(child, byId, depth + 1))
1649
+ };
1650
+ case "connector":
1651
+ return {
1652
+ id: element.id,
1653
+ name: boundedProjectionText(element.name),
1654
+ __projectionReadOnly: element.readOnly ?? false,
1655
+ geometry: "line",
1656
+ position,
1657
+ fill: "none",
1658
+ line: cloneProjectionLine(element.line),
1659
+ rotation: 0,
1660
+ text: mutableProjectionText("", void 0)
1661
+ };
1662
+ }
1663
+ }
1664
+ function mutableProjectionText(initial, style) {
1665
+ let value = boundedProjectionText(initial);
1666
+ return {
1667
+ style: { ...style ?? {} },
1668
+ set(next) {
1669
+ value = boundedProjectionText(next);
1670
+ },
1671
+ toString() {
1672
+ return value;
1673
+ }
1674
+ };
1675
+ }
1676
+ function cloneProjectionFill(fill) {
1677
+ return typeof fill === "string" ? fill : { ...fill };
1678
+ }
1679
+ function cloneProjectionLine(line) {
1680
+ return {
1681
+ style: line?.style ?? "solid",
1682
+ fill: line?.fill ? cloneProjectionFill(line.fill) : "slate-900",
1683
+ width: Math.max(0, finite(line?.width ?? 1, 1))
1684
+ };
1685
+ }
1686
+ function boundedProjectionText(value) {
1687
+ return value.slice(0, MAX_PROJECTION_TEXT);
1688
+ }
1689
+ function boundedSpan(value) {
1690
+ return Math.max(1, Math.min(1e4, Math.floor(finite(value ?? 1, 1))));
1691
+ }
1692
+ function safeProjectionImageSource(source) {
1693
+ if (!source || source.length > 64 * 1024 * 1024) return void 0;
1694
+ if (/^data:image\/(?:png|jpeg|gif|webp);base64,/i.test(source) || source.startsWith("blob:")) {
1695
+ return source;
1696
+ }
1697
+ try {
1698
+ const base = globalThis.location?.href;
1699
+ if (!base) return void 0;
1700
+ const url = new URL(source, base);
1701
+ return url.origin === globalThis.location.origin && /^https?:$/.test(url.protocol) ? url.href : void 0;
1702
+ } catch {
1703
+ return void 0;
1704
+ }
1705
+ }
1706
+ function asPresentationError(cause) {
1707
+ return cause instanceof Error ? cause : new Error("Presentation change failed");
1708
+ }
1709
+ function listSlideObjects(slide) {
1710
+ return slide.elements.map(displayObjectFromElement);
1711
+ }
1712
+ function displayObjectFromElement(object) {
1713
+ const readOnly = object.__projectionReadOnly === true;
1714
+ if ("geometry" in object && "text" in object)
1715
+ return { id: object.id, kind: "shape", object, readOnly };
1716
+ if ("series" in object) return { id: object.id, kind: "chart", object, readOnly };
1717
+ if ("sourceForSvg" in object) return { id: object.id, kind: "image", object, readOnly };
1718
+ if ("rows" in object) return { id: object.id, kind: "table", object, readOnly };
1719
+ return { id: object.id, kind: "group", object, readOnly };
1720
+ }
1721
+ function buildSpatialIndex(objects, slideSize) {
1722
+ const buckets = /* @__PURE__ */ new Map();
1723
+ const overflowObjects = [];
1724
+ const bounds = objects.map(objectBounds);
1725
+ const maxX = Math.max(0, Math.ceil(slideSize.width / SPATIAL_TILE) - 1);
1726
+ const maxY = Math.max(0, Math.ceil(slideSize.height / SPATIAL_TILE) - 1);
1727
+ for (const [index, entry] of objects.entries()) {
1728
+ const objectBound = bounds[index] ?? entry.object.position;
1729
+ if (!intersects(objectBound, { left: 0, top: 0, ...slideSize })) continue;
1730
+ const left = Math.max(0, Math.floor(objectBound.left / SPATIAL_TILE));
1731
+ const top = Math.max(0, Math.floor(objectBound.top / SPATIAL_TILE));
1732
+ const right = Math.min(maxX, Math.floor((objectBound.left + objectBound.width) / SPATIAL_TILE));
1733
+ const bottom = Math.min(
1734
+ maxY,
1735
+ Math.floor((objectBound.top + objectBound.height) / SPATIAL_TILE)
1736
+ );
1737
+ const bucketCount = (right - left + 1) * (bottom - top + 1);
1738
+ if (!Number.isSafeInteger(bucketCount) || bucketCount > MAX_SPATIAL_BUCKETS_PER_OBJECT) {
1739
+ overflowObjects.push(index);
1740
+ continue;
1741
+ }
1742
+ for (let y = top; y <= bottom; y += 1) {
1743
+ for (let x = left; x <= right; x += 1) {
1744
+ const key = `${x}:${y}`;
1745
+ const bucket = buckets.get(key);
1746
+ if (bucket) bucket.push(index);
1747
+ else buckets.set(key, [index]);
1748
+ }
1749
+ }
1750
+ }
1751
+ return { objects, bounds, buckets, overflowObjects };
1752
+ }
1753
+ function querySpatialIndex(index, viewport) {
1754
+ const seen = new Set(index.overflowObjects);
1755
+ const left = Math.floor(viewport.left / SPATIAL_TILE);
1756
+ const top = Math.floor(viewport.top / SPATIAL_TILE);
1757
+ const right = Math.floor((viewport.left + viewport.width) / SPATIAL_TILE);
1758
+ const bottom = Math.floor((viewport.top + viewport.height) / SPATIAL_TILE);
1759
+ for (let y = top; y <= bottom; y += 1) {
1760
+ for (let x = left; x <= right; x += 1) {
1761
+ for (const objectIndex of index.buckets.get(`${x}:${y}`) ?? []) {
1762
+ if (intersects(index.bounds[objectIndex], viewport)) seen.add(objectIndex);
1763
+ }
1764
+ }
1765
+ }
1766
+ return [...seen].filter((objectIndex) => {
1767
+ return !!index.objects[objectIndex] && intersects(index.bounds[objectIndex], viewport);
1768
+ }).sort((a, b) => a - b);
1769
+ }
1770
+ function paintSlideCanvas(t, options) {
1771
+ const { canvas, slide, slideSize, zoom } = options;
1772
+ const context = canvas.getContext("2d");
1773
+ if (!context) return;
1774
+ const cssWidth = slideSize.width * zoom;
1775
+ const cssHeight = slideSize.height * zoom;
1776
+ const ratio = Math.max(
1777
+ 1e-4,
1778
+ Math.min(
1779
+ 2,
1780
+ Math.max(1, globalThis.devicePixelRatio || 1),
1781
+ MAX_CANVAS_EDGE / Math.max(1, cssWidth),
1782
+ MAX_CANVAS_EDGE / Math.max(1, cssHeight),
1783
+ Math.sqrt(MAX_CANVAS_PIXELS / Math.max(1, cssWidth * cssHeight))
1784
+ )
1785
+ );
1786
+ const pixelWidth = Math.max(1, Math.round(slideSize.width * zoom * ratio));
1787
+ const pixelHeight = Math.max(1, Math.round(slideSize.height * zoom * ratio));
1788
+ if (canvas.width !== pixelWidth) canvas.width = pixelWidth;
1789
+ if (canvas.height !== pixelHeight) canvas.height = pixelHeight;
1790
+ context.setTransform(zoom * ratio, 0, 0, zoom * ratio, 0, 0);
1791
+ context.clearRect(0, 0, slideSize.width, slideSize.height);
1792
+ context.fillStyle = resolveColor(slide.background.fill);
1793
+ context.fillRect(0, 0, slideSize.width, slideSize.height);
1794
+ const usedImageSources = /* @__PURE__ */ new Set();
1795
+ for (const index of options.objectIndexes) {
1796
+ const entry = options.objects[index];
1797
+ if (!entry) continue;
1798
+ const position = entry.id === options.draftPosition?.objectId ? options.draftPosition.position : entry.object.position;
1799
+ drawObject(
1800
+ t,
1801
+ context,
1802
+ entry,
1803
+ position,
1804
+ options.imageCache,
1805
+ options.requestRepaint,
1806
+ options.renderRegion,
1807
+ zoom * ratio,
1808
+ usedImageSources
1809
+ );
1810
+ }
1811
+ disposeUnusedCanvasImages(options.imageCache, usedImageSources);
1812
+ }
1813
+ function drawObject(t, context, entry, position, imageCache, requestRepaint, renderRegion, pixelScale, usedImageSources) {
1814
+ switch (entry.kind) {
1815
+ case "shape":
1816
+ drawShape(t, context, entry.object, position);
1817
+ return;
1818
+ case "chart":
1819
+ drawChart(t, context, entry.object, position);
1820
+ return;
1821
+ case "image": {
1822
+ const source = drawImage(
1823
+ t,
1824
+ context,
1825
+ entry.object,
1826
+ position,
1827
+ imageCache,
1828
+ requestRepaint
1829
+ );
1830
+ if (source) usedImageSources.add(source);
1831
+ return;
1832
+ }
1833
+ case "table":
1834
+ drawTable(t, context, entry.object, position, renderRegion, pixelScale);
1835
+ return;
1836
+ case "group":
1837
+ drawGroup(
1838
+ t,
1839
+ context,
1840
+ entry.object,
1841
+ position,
1842
+ imageCache,
1843
+ requestRepaint,
1844
+ renderRegion,
1845
+ pixelScale,
1846
+ usedImageSources
1847
+ );
1848
+ }
1849
+ }
1850
+ function drawTable(t, context, table, position, renderRegion, pixelScale) {
1851
+ const rowCount = table.rows.length;
1852
+ const columnCount = table.rows[0]?.length ?? 0;
1853
+ if (rowCount === 0 || columnCount === 0 || !intersects(position, renderRegion)) return;
1854
+ const columnWidths = normalizeTableTracks(table.columnWidths, columnCount, position.width);
1855
+ const rowHeights = normalizeTableTracks(table.rowHeights, rowCount, position.height);
1856
+ const columnOffsets = cumulativeOffsets(columnWidths, position.left);
1857
+ const rowOffsets = cumulativeOffsets(rowHeights, position.top);
1858
+ const columnStart = visibleTrackStart(columnOffsets, renderRegion.left);
1859
+ const columnEnd = visibleTrackEnd(columnOffsets, renderRegion.left + renderRegion.width);
1860
+ const rowStart = visibleTrackStart(rowOffsets, renderRegion.top);
1861
+ const rowEnd = visibleTrackEnd(rowOffsets, renderRegion.top + renderRegion.height);
1862
+ const visibleCellCount = (rowEnd - rowStart) * (columnEnd - columnStart);
1863
+ if (visibleCellCount > MAX_TABLE_CELLS_PER_PAINT) {
1864
+ drawTableOverview(context, table, position, columnOffsets, rowOffsets, {
1865
+ columnStart,
1866
+ columnEnd,
1867
+ rowStart,
1868
+ rowEnd
1869
+ });
1870
+ return;
1871
+ }
1872
+ context.save();
1873
+ for (let rowIndex = rowStart; rowIndex < rowEnd; rowIndex += 1) {
1874
+ const row = table.rows[rowIndex];
1875
+ if (!row) continue;
1876
+ for (let columnIndex = columnStart; columnIndex < columnEnd; columnIndex += 1) {
1877
+ const cell = row[columnIndex];
1878
+ if (!cell) continue;
1879
+ const rightIndex = Math.min(columnCount, columnIndex + cell.colSpan);
1880
+ const bottomIndex = Math.min(rowCount, rowIndex + cell.rowSpan);
1881
+ const left = columnOffsets[columnIndex] ?? position.left;
1882
+ const top = rowOffsets[rowIndex] ?? position.top;
1883
+ const right = columnOffsets[rightIndex] ?? position.left + position.width;
1884
+ const bottom = rowOffsets[bottomIndex] ?? position.top + position.height;
1885
+ const width = Math.max(1, right - left);
1886
+ const height = Math.max(1, bottom - top);
1887
+ context.beginPath();
1888
+ context.rect(left, top, width, height);
1889
+ applyFillAndLine(context, cell.fill, table.line, false);
1890
+ if (width * pixelScale >= 8 && height * pixelScale >= 8) {
1891
+ drawText(t, context, cell.text.toString(), cell.text.style, {
1892
+ left: left + 4,
1893
+ top: top + 2,
1894
+ width: Math.max(1, width - 8),
1895
+ height: Math.max(1, height - 4)
1896
+ });
1897
+ }
1898
+ }
1899
+ }
1900
+ context.restore();
1901
+ }
1902
+ function visibleTrackStart(offsets, value) {
1903
+ return Math.max(0, Math.min(offsets.length - 2, lowerBound(offsets, value) - 1));
1904
+ }
1905
+ function visibleTrackEnd(offsets, value) {
1906
+ return Math.max(0, Math.min(offsets.length - 1, lowerBound(offsets, value) + 1));
1907
+ }
1908
+ function lowerBound(values, target) {
1909
+ let low = 0;
1910
+ let high = values.length;
1911
+ while (low < high) {
1912
+ const middle = low + Math.floor((high - low) / 2);
1913
+ if ((values[middle] ?? Number.POSITIVE_INFINITY) < target) low = middle + 1;
1914
+ else high = middle;
1915
+ }
1916
+ return low;
1917
+ }
1918
+ function drawTableOverview(context, table, position, columnOffsets, rowOffsets, visible) {
1919
+ context.save();
1920
+ context.beginPath();
1921
+ context.rect(position.left, position.top, position.width, position.height);
1922
+ applyFillAndLine(context, table.fill, table.line, false);
1923
+ const columnStep = Math.max(1, Math.ceil((visible.columnEnd - visible.columnStart) / 96));
1924
+ const rowStep = Math.max(1, Math.ceil((visible.rowEnd - visible.rowStart) / 96));
1925
+ context.beginPath();
1926
+ for (let index = visible.columnStart; index <= visible.columnEnd; index += columnStep) {
1927
+ const x = columnOffsets[index];
1928
+ if (x === void 0) continue;
1929
+ context.moveTo(x, position.top);
1930
+ context.lineTo(x, position.top + position.height);
1931
+ }
1932
+ for (let index = visible.rowStart; index <= visible.rowEnd; index += rowStep) {
1933
+ const y = rowOffsets[index];
1934
+ if (y === void 0) continue;
1935
+ context.moveTo(position.left, y);
1936
+ context.lineTo(position.left + position.width, y);
1937
+ }
1938
+ applyFillAndLine(context, "none", table.line, true);
1939
+ context.restore();
1940
+ }
1941
+ function normalizeTableTracks(values, count, total) {
1942
+ if (values.length !== count) return Array.from({ length: count }, () => total / count);
1943
+ const sum = values.reduce((value, next) => value + next, 0);
1944
+ if (!Number.isFinite(sum) || sum <= 0) {
1945
+ return Array.from({ length: count }, () => total / count);
1946
+ }
1947
+ return values.map((value) => value / sum * total);
1948
+ }
1949
+ function cumulativeOffsets(tracks, start) {
1950
+ const offsets = [start];
1951
+ for (const track of tracks) offsets.push((offsets.at(-1) ?? start) + track);
1952
+ return offsets;
1953
+ }
1954
+ function drawGroup(t, context, group, position, imageCache, requestRepaint, renderRegion, pixelScale, usedImageSources) {
1955
+ const scaleX = position.width / group.childExtent.width;
1956
+ const scaleY = position.height / group.childExtent.height;
1957
+ const translatedX = position.left - group.childOffset.left * scaleX;
1958
+ const translatedY = position.top - group.childOffset.top * scaleY;
1959
+ const centerX = position.left + position.width / 2;
1960
+ const centerY = position.top + position.height / 2;
1961
+ context.save();
1962
+ context.translate(centerX, centerY);
1963
+ context.rotate(group.rotation * Math.PI / 180);
1964
+ context.scale(group.flipHorizontal ? -1 : 1, group.flipVertical ? -1 : 1);
1965
+ context.translate(-centerX, -centerY);
1966
+ context.translate(translatedX, translatedY);
1967
+ context.scale(scaleX, scaleY);
1968
+ const childRenderRegion = inverseGroupRegion(group, position, renderRegion);
1969
+ for (const child of group.children) {
1970
+ const entry = displayObjectFromElement(child);
1971
+ if (!intersects(objectBounds(entry), childRenderRegion)) continue;
1972
+ drawObject(
1973
+ t,
1974
+ context,
1975
+ entry,
1976
+ child.position,
1977
+ imageCache,
1978
+ requestRepaint,
1979
+ childRenderRegion,
1980
+ pixelScale * Math.min(Math.abs(scaleX), Math.abs(scaleY)),
1981
+ usedImageSources
1982
+ );
1983
+ }
1984
+ context.restore();
1985
+ }
1986
+ function inverseGroupRegion(group, position, region) {
1987
+ const scaleX = position.width / group.childExtent.width;
1988
+ const scaleY = position.height / group.childExtent.height;
1989
+ const translatedX = position.left - group.childOffset.left * scaleX;
1990
+ const translatedY = position.top - group.childOffset.top * scaleY;
1991
+ const centerX = position.left + position.width / 2;
1992
+ const centerY = position.top + position.height / 2;
1993
+ const radians = -group.rotation * Math.PI / 180;
1994
+ const cos = Math.cos(radians);
1995
+ const sin = Math.sin(radians);
1996
+ const points = [
1997
+ [region.left, region.top],
1998
+ [region.left + region.width, region.top],
1999
+ [region.left, region.top + region.height],
2000
+ [region.left + region.width, region.top + region.height]
2001
+ ].map(([x = 0, y = 0]) => {
2002
+ const dx = x - centerX;
2003
+ const dy = y - centerY;
2004
+ const rotatedX = dx * cos - dy * sin;
2005
+ const rotatedY = dx * sin + dy * cos;
2006
+ const unflippedX = rotatedX * (group.flipHorizontal ? -1 : 1) + centerX;
2007
+ const unflippedY = rotatedY * (group.flipVertical ? -1 : 1) + centerY;
2008
+ return {
2009
+ x: (unflippedX - translatedX) / scaleX,
2010
+ y: (unflippedY - translatedY) / scaleY
2011
+ };
2012
+ });
2013
+ const xs = points.map((point) => point.x);
2014
+ const ys = points.map((point) => point.y);
2015
+ const left = Math.min(...xs);
2016
+ const right = Math.max(...xs);
2017
+ const top = Math.min(...ys);
2018
+ const bottom = Math.max(...ys);
2019
+ return { left, top, width: right - left, height: bottom - top };
2020
+ }
2021
+ function drawShape(t, context, shape, position) {
2022
+ context.save();
2023
+ context.translate(position.left + position.width / 2, position.top + position.height / 2);
2024
+ context.rotate(shape.rotation * Math.PI / 180);
2025
+ const x = -position.width / 2;
2026
+ const y = -position.height / 2;
2027
+ context.beginPath();
2028
+ switch (shape.geometry) {
2029
+ case "ellipse":
2030
+ context.ellipse(0, 0, position.width / 2, position.height / 2, 0, 0, Math.PI * 2);
2031
+ break;
2032
+ case "triangle":
2033
+ context.moveTo(0, y);
2034
+ context.lineTo(x + position.width, y + position.height);
2035
+ context.lineTo(x, y + position.height);
2036
+ context.closePath();
2037
+ break;
2038
+ case "rightArrow": {
2039
+ const body = position.width * 0.65;
2040
+ context.moveTo(x, y + position.height * 0.25);
2041
+ context.lineTo(x + body, y + position.height * 0.25);
2042
+ context.lineTo(x + body, y);
2043
+ context.lineTo(x + position.width, 0);
2044
+ context.lineTo(x + body, y + position.height);
2045
+ context.lineTo(x + body, y + position.height * 0.75);
2046
+ context.lineTo(x, y + position.height * 0.75);
2047
+ context.closePath();
2048
+ break;
2049
+ }
2050
+ case "line":
2051
+ context.moveTo(x, y);
2052
+ context.lineTo(x + position.width, y + position.height);
2053
+ break;
2054
+ case "roundRect":
2055
+ roundedRect(
2056
+ context,
2057
+ x,
2058
+ y,
2059
+ position.width,
2060
+ position.height,
2061
+ resolveRadius(shape.borderRadius, position)
2062
+ );
2063
+ break;
2064
+ default:
2065
+ context.rect(x, y, position.width, position.height);
2066
+ }
2067
+ applyFillAndLine(context, shape.fill, shape.line, shape.geometry === "line");
2068
+ const text = shape.text.toString();
2069
+ if (text)
2070
+ drawText(t, context, text, shape.text.style, {
2071
+ left: x,
2072
+ top: y,
2073
+ width: position.width,
2074
+ height: position.height
2075
+ });
2076
+ context.restore();
2077
+ }
2078
+ function drawChart(t, context, chart, position) {
2079
+ context.save();
2080
+ context.fillStyle = "#ffffff";
2081
+ context.strokeStyle = "#e2e8f0";
2082
+ context.lineWidth = 1;
2083
+ context.fillRect(position.left, position.top, position.width, position.height);
2084
+ context.strokeRect(position.left, position.top, position.width, position.height);
2085
+ if (chart.title) {
2086
+ drawText(
2087
+ t,
2088
+ context,
2089
+ chart.title,
2090
+ { fontSize: 18, bold: true, alignment: "center" },
2091
+ {
2092
+ left: position.left + 16,
2093
+ top: position.top + 8,
2094
+ width: Math.max(1, position.width - 32),
2095
+ height: 28
2096
+ }
2097
+ );
2098
+ }
2099
+ const plot = {
2100
+ left: position.left + 36,
2101
+ top: position.top + (chart.title ? 46 : 20),
2102
+ width: Math.max(1, position.width - 56),
2103
+ height: Math.max(1, position.height - (chart.title ? 72 : 48))
2104
+ };
2105
+ const values = chart.series.items.flatMap((series) => series.values).filter(Number.isFinite);
2106
+ const minValue = Math.min(0, chart.yAxis?.min ?? Math.min(...values, 0));
2107
+ const maxValue = Math.max(1, chart.yAxis?.max ?? Math.max(...values, 1));
2108
+ const valueRange = Math.max(Number.EPSILON, maxValue - minValue);
2109
+ const yForValue = (value) => plot.top + plot.height - (value - minValue) / valueRange * plot.height;
2110
+ const palette = ["#2563eb", "#0f766e", "#f59e0b", "#dc2626", "#7c3aed"];
2111
+ if (chart.type === "pie" || chart.type === "doughnut") {
2112
+ const series = chart.series.items[0];
2113
+ const slices = series?.values.map((value) => Math.max(0, value)) ?? [];
2114
+ const total = slices.reduce((sum, value) => sum + value, 0);
2115
+ let angle = -Math.PI / 2;
2116
+ const radius = Math.min(plot.width, plot.height) * 0.42;
2117
+ const cx = plot.left + plot.width / 2;
2118
+ const cy = plot.top + plot.height / 2;
2119
+ slices.forEach((value, index) => {
2120
+ const next = angle + (total > 0 ? value / total * Math.PI * 2 : 0);
2121
+ context.beginPath();
2122
+ context.moveTo(cx, cy);
2123
+ context.arc(cx, cy, radius, angle, next);
2124
+ context.closePath();
2125
+ context.fillStyle = palette[index % palette.length] ?? "#2563eb";
2126
+ context.fill();
2127
+ angle = next;
2128
+ });
2129
+ if (chart.type === "doughnut") {
2130
+ context.beginPath();
2131
+ context.arc(cx, cy, radius * 0.55, 0, Math.PI * 2);
2132
+ context.fillStyle = "#ffffff";
2133
+ context.fill();
2134
+ }
2135
+ } else if (chart.type === "line" || chart.type === "area") {
2136
+ drawChartAxes(context, chart, plot, yForValue(0));
2137
+ chart.series.items.forEach((series, seriesIndex) => {
2138
+ if (series.values.length === 0) return;
2139
+ const points = series.values.map((value, index) => ({
2140
+ x: plot.left + index / Math.max(1, series.values.length - 1) * plot.width,
2141
+ y: yForValue(value)
2142
+ }));
2143
+ const color = resolveColor(
2144
+ series.line?.fill ?? series.fill ?? palette[seriesIndex % palette.length] ?? "#2563eb"
2145
+ );
2146
+ if (chart.type === "area") {
2147
+ context.beginPath();
2148
+ context.moveTo(points[0]?.x ?? plot.left, yForValue(0));
2149
+ for (const point of points) context.lineTo(point.x, point.y);
2150
+ context.lineTo(points.at(-1)?.x ?? plot.left + plot.width, yForValue(0));
2151
+ context.closePath();
2152
+ context.globalAlpha = 0.22;
2153
+ context.fillStyle = color;
2154
+ context.fill();
2155
+ context.globalAlpha = 1;
2156
+ }
2157
+ context.beginPath();
2158
+ points.forEach((point, index) => {
2159
+ if (index === 0) context.moveTo(point.x, point.y);
2160
+ else context.lineTo(point.x, point.y);
2161
+ });
2162
+ context.strokeStyle = color;
2163
+ context.lineWidth = series.line?.width ?? 3;
2164
+ context.stroke();
2165
+ for (const point of points) {
2166
+ context.beginPath();
2167
+ context.arc(point.x, point.y, 3, 0, Math.PI * 2);
2168
+ context.fillStyle = color;
2169
+ context.fill();
2170
+ }
2171
+ });
2172
+ } else if (chart.type === "scatter" || chart.type === "bubble") {
2173
+ drawChartAxes(context, chart, plot, yForValue(0));
2174
+ const xValues = chart.series.items.flatMap(
2175
+ (series) => series.values.map((_value, index) => series.xValues[index] ?? index)
2176
+ );
2177
+ const minX = chart.xAxis?.min ?? Math.min(...xValues, 0);
2178
+ const maxX = chart.xAxis?.max ?? Math.max(...xValues, 1);
2179
+ const xRange = Math.max(Number.EPSILON, maxX - minX);
2180
+ chart.series.items.forEach((series, seriesIndex) => {
2181
+ context.fillStyle = resolveColor(
2182
+ series.fill ?? palette[seriesIndex % palette.length] ?? "#2563eb"
2183
+ );
2184
+ series.values.forEach((value, index) => {
2185
+ const xValue = series.xValues[index] ?? index;
2186
+ const x = plot.left + (xValue - minX) / xRange * plot.width;
2187
+ const radius = chart.type === "bubble" ? Math.max(3, Math.sqrt(Math.max(0, series.bubbleSizes[index] ?? 9))) : 4;
2188
+ context.beginPath();
2189
+ context.arc(x, yForValue(value), radius, 0, Math.PI * 2);
2190
+ context.fill();
2191
+ });
2192
+ });
2193
+ } else if (chart.type === "radar") {
2194
+ drawRadarChart(context, chart, plot, palette);
2195
+ } else {
2196
+ drawChartAxes(context, chart, plot, yForValue(0));
2197
+ const count = Math.max(1, ...chart.series.items.map((series) => series.values.length));
2198
+ const groupWidth = plot.width / count;
2199
+ const barWidth = groupWidth * 0.72 / Math.max(1, chart.series.items.length);
2200
+ const baseline = yForValue(0);
2201
+ chart.series.items.forEach((series, seriesIndex) => {
2202
+ series.values.forEach((value, valueIndex) => {
2203
+ const valueY = yForValue(value);
2204
+ const height = Math.abs(baseline - valueY);
2205
+ context.fillStyle = resolveColor(
2206
+ series.fill ?? palette[seriesIndex % palette.length] ?? "#2563eb"
2207
+ );
2208
+ const left = plot.left + valueIndex * groupWidth + groupWidth * 0.14 + seriesIndex * barWidth;
2209
+ context.fillRect(left, Math.min(baseline, valueY), Math.max(1, barWidth), height);
2210
+ if (chart.dataLabels?.showValue) {
2211
+ drawText(
2212
+ t,
2213
+ context,
2214
+ String(value),
2215
+ { fontSize: 11, alignment: "center" },
2216
+ {
2217
+ left,
2218
+ top: Math.max(plot.top, Math.min(baseline, valueY) - 14),
2219
+ width: Math.max(1, barWidth),
2220
+ height: 14
2221
+ }
2222
+ );
2223
+ }
2224
+ });
2225
+ });
2226
+ }
2227
+ context.restore();
2228
+ }
2229
+ function drawChartAxes(context, chart, plot, baseline) {
2230
+ context.save();
2231
+ context.strokeStyle = "#94a3b8";
2232
+ context.lineWidth = 1;
2233
+ if (chart.xAxis?.visible !== false) {
2234
+ context.beginPath();
2235
+ context.moveTo(plot.left, Math.max(plot.top, Math.min(plot.top + plot.height, baseline)));
2236
+ context.lineTo(
2237
+ plot.left + plot.width,
2238
+ Math.max(plot.top, Math.min(plot.top + plot.height, baseline))
2239
+ );
2240
+ context.stroke();
2241
+ }
2242
+ if (chart.yAxis?.visible !== false) {
2243
+ context.beginPath();
2244
+ context.moveTo(plot.left, plot.top);
2245
+ context.lineTo(plot.left, plot.top + plot.height);
2246
+ context.stroke();
2247
+ }
2248
+ context.restore();
2249
+ }
2250
+ function drawRadarChart(context, chart, plot, palette) {
2251
+ const count = Math.max(3, ...chart.series.items.map((series) => series.values.length));
2252
+ const maximum = Math.max(
2253
+ 1,
2254
+ ...chart.series.items.flatMap((series) => series.values.map((value) => Math.max(0, value)))
2255
+ );
2256
+ const centerX = plot.left + plot.width / 2;
2257
+ const centerY = plot.top + plot.height / 2;
2258
+ const radius = Math.min(plot.width, plot.height) * 0.42;
2259
+ const point = (index, value) => {
2260
+ const angle = -Math.PI / 2 + index / count * Math.PI * 2;
2261
+ const scaled = Math.max(0, value) / maximum * radius;
2262
+ return { x: centerX + Math.cos(angle) * scaled, y: centerY + Math.sin(angle) * scaled };
2263
+ };
2264
+ context.save();
2265
+ context.strokeStyle = "#cbd5e1";
2266
+ for (let ring = 1; ring <= 4; ring += 1) {
2267
+ context.beginPath();
2268
+ for (let index = 0; index < count; index += 1) {
2269
+ const next = point(index, maximum * ring / 4);
2270
+ if (index === 0) context.moveTo(next.x, next.y);
2271
+ else context.lineTo(next.x, next.y);
2272
+ }
2273
+ context.closePath();
2274
+ context.stroke();
2275
+ }
2276
+ chart.series.items.forEach((series, seriesIndex) => {
2277
+ const color = resolveColor(series.fill ?? palette[seriesIndex % palette.length] ?? "#2563eb");
2278
+ context.beginPath();
2279
+ for (let index = 0; index < count; index += 1) {
2280
+ const next = point(index, series.values[index] ?? 0);
2281
+ if (index === 0) context.moveTo(next.x, next.y);
2282
+ else context.lineTo(next.x, next.y);
2283
+ }
2284
+ context.closePath();
2285
+ context.globalAlpha = 0.18;
2286
+ context.fillStyle = color;
2287
+ context.fill();
2288
+ context.globalAlpha = 1;
2289
+ context.strokeStyle = color;
2290
+ context.lineWidth = series.line?.width ?? 2;
2291
+ context.stroke();
2292
+ });
2293
+ context.restore();
2294
+ }
2295
+ function drawImage(t, context, image, position, imageCache, requestRepaint) {
2296
+ context.save();
2297
+ applyImageTransform(context, image, position);
2298
+ imageClipPath(context, image, position);
2299
+ context.clip();
2300
+ context.fillStyle = "#f1f5f9";
2301
+ context.fillRect(position.left, position.top, position.width, position.height);
2302
+ const source = imageSourceForCanvas(image);
2303
+ if (source && typeof Image !== "undefined") {
2304
+ let cached = imageCache.get(source);
2305
+ if (!cached) {
2306
+ const element = new Image();
2307
+ cached = { image: element, ready: false };
2308
+ imageCache.set(source, cached);
2309
+ element.onload = () => {
2310
+ const current = imageCache.get(source);
2311
+ if (!current || current.image !== element) return;
2312
+ current.ready = true;
2313
+ requestRepaint();
2314
+ };
2315
+ element.onerror = () => {
2316
+ const current = imageCache.get(source);
2317
+ if (current?.image === element) current.ready = false;
2318
+ };
2319
+ element.src = source;
2320
+ }
2321
+ if (cached.ready && cached.image.naturalWidth > 0 && cached.image.naturalHeight > 0) {
2322
+ drawFittedImage(context, cached.image, image, position);
2323
+ context.restore();
2324
+ return source;
2325
+ }
2326
+ }
2327
+ context.strokeStyle = "#94a3b8";
2328
+ context.lineWidth = 1;
2329
+ context.setLineDash([8, 6]);
2330
+ imageClipPath(context, image, position);
2331
+ context.stroke();
2332
+ context.setLineDash([]);
2333
+ drawText(
2334
+ t,
2335
+ context,
2336
+ image.alt || image.prompt || t("artifacts.presentationEditor.image"),
2337
+ { fontSize: 14, color: "slate-600" },
2338
+ {
2339
+ left: position.left + 12,
2340
+ top: position.top + 12,
2341
+ width: Math.max(1, position.width - 24),
2342
+ height: Math.max(1, position.height - 24)
2343
+ }
2344
+ );
2345
+ context.restore();
2346
+ return source;
2347
+ }
2348
+ function imageSourceForCanvas(image) {
2349
+ try {
2350
+ return image.sourceForSvg();
2351
+ } catch {
2352
+ return void 0;
2353
+ }
2354
+ }
2355
+ function applyImageTransform(context, image, position) {
2356
+ const centerX = position.left + position.width / 2;
2357
+ const centerY = position.top + position.height / 2;
2358
+ context.translate(centerX, centerY);
2359
+ context.rotate(image.rotation * Math.PI / 180);
2360
+ context.scale(image.flipHorizontal ? -1 : 1, image.flipVertical ? -1 : 1);
2361
+ context.translate(-centerX, -centerY);
2362
+ }
2363
+ function imageClipPath(context, image, position) {
2364
+ context.beginPath();
2365
+ if (image.geometry === "ellipse") {
2366
+ context.ellipse(
2367
+ position.left + position.width / 2,
2368
+ position.top + position.height / 2,
2369
+ position.width / 2,
2370
+ position.height / 2,
2371
+ 0,
2372
+ 0,
2373
+ Math.PI * 2
2374
+ );
2375
+ } else if (image.geometry === "roundRect") {
2376
+ roundedRect(
2377
+ context,
2378
+ position.left,
2379
+ position.top,
2380
+ position.width,
2381
+ position.height,
2382
+ resolveRadius(image.borderRadius, position)
2383
+ );
2384
+ } else {
2385
+ context.rect(position.left, position.top, position.width, position.height);
2386
+ }
2387
+ context.closePath();
2388
+ }
2389
+ function drawFittedImage(context, source, image, position) {
2390
+ const crop = image.crop ?? { left: 0, top: 0, right: 0, bottom: 0 };
2391
+ const sourceX = source.naturalWidth * crop.left;
2392
+ const sourceY = source.naturalHeight * crop.top;
2393
+ const sourceWidth = source.naturalWidth * (1 - crop.left - crop.right);
2394
+ const sourceHeight = source.naturalHeight * (1 - crop.top - crop.bottom);
2395
+ if (sourceWidth <= 0 || sourceHeight <= 0) return;
2396
+ const scale = image.fit === "cover" ? Math.max(position.width / sourceWidth, position.height / sourceHeight) : Math.min(position.width / sourceWidth, position.height / sourceHeight);
2397
+ const width = sourceWidth * scale;
2398
+ const height = sourceHeight * scale;
2399
+ const left = position.left + (position.width - width) / 2;
2400
+ const top = position.top + (position.height - height) / 2;
2401
+ context.drawImage(source, sourceX, sourceY, sourceWidth, sourceHeight, left, top, width, height);
2402
+ }
2403
+ function disposeCanvasImageCache(cache) {
2404
+ for (const entry of cache.values()) disposeCanvasImageEntry(entry);
2405
+ cache.clear();
2406
+ }
2407
+ function disposeUnusedCanvasImages(cache, usedSources) {
2408
+ for (const [source, entry] of cache) {
2409
+ if (usedSources.has(source)) continue;
2410
+ disposeCanvasImageEntry(entry);
2411
+ cache.delete(source);
2412
+ }
2413
+ }
2414
+ function disposeCanvasImageEntry(entry) {
2415
+ entry.image.onload = null;
2416
+ entry.image.onerror = null;
2417
+ entry.image.removeAttribute("src");
2418
+ }
2419
+ function drawText(t, context, text, style, position) {
2420
+ const fontSize = style.fontSize ?? 18;
2421
+ const fontStyle = style.italic ? "italic " : "";
2422
+ const fontWeight = style.bold ? "700 " : "400 ";
2423
+ context.font = `${fontStyle}${fontWeight}${fontSize}px ${style.fontFamily ?? t("artifacts.presentationEditor.arialSansSerif")}`;
2424
+ context.fillStyle = resolveColor(style.color ?? "slate-950");
2425
+ context.textAlign = style.alignment === "center" ? "center" : style.alignment === "right" ? "right" : "left";
2426
+ context.textBaseline = "top";
2427
+ const x = style.alignment === "center" ? position.left + position.width / 2 : style.alignment === "right" ? position.left + position.width : position.left;
2428
+ const lineHeight = fontSize * 1.2;
2429
+ const lines = wrapCanvasText(context, text, position.width);
2430
+ const totalHeight = lines.length * lineHeight;
2431
+ const top = style.verticalAlignment === "middle" ? position.top + (position.height - totalHeight) / 2 : style.verticalAlignment === "bottom" ? position.top + position.height - totalHeight : position.top;
2432
+ context.save();
2433
+ context.beginPath();
2434
+ context.rect(position.left, position.top, position.width, position.height);
2435
+ context.clip();
2436
+ lines.forEach((line, index) => context.fillText(line, x, top + index * lineHeight));
2437
+ context.restore();
2438
+ }
2439
+ function wrapCanvasText(context, text, width) {
2440
+ const result = [];
2441
+ for (const paragraph of text.split("\n")) {
2442
+ const words = paragraph.split(/\s+/).filter(Boolean);
2443
+ if (words.length === 0) {
2444
+ result.push("");
2445
+ continue;
2446
+ }
2447
+ let line = words[0] ?? "";
2448
+ for (let index = 1; index < words.length; index += 1) {
2449
+ const word = words[index] ?? "";
2450
+ const candidate = `${line} ${word}`;
2451
+ if (context.measureText(candidate).width <= width || line.length === 0) line = candidate;
2452
+ else {
2453
+ result.push(line);
2454
+ line = word;
2455
+ }
2456
+ }
2457
+ result.push(line);
2458
+ }
2459
+ return result;
2460
+ }
2461
+ function applyFillAndLine(context, fill, line, lineOnly) {
2462
+ if (!lineOnly && resolveColor(fill) !== "transparent") {
2463
+ context.fillStyle = resolveColor(fill);
2464
+ context.fill();
2465
+ }
2466
+ if (line.style !== "none" && resolveColor(line.fill ?? "slate-900") !== "transparent" && (line.width ?? 1) > 0) {
2467
+ context.strokeStyle = resolveColor(line.fill ?? "slate-900");
2468
+ context.lineWidth = line.width ?? 1;
2469
+ context.setLineDash(line.style === "dash" ? [8, 5] : line.style === "dot" ? [2, 4] : []);
2470
+ context.stroke();
2471
+ context.setLineDash([]);
2472
+ }
2473
+ }
2474
+ function roundedRect(context, x, y, width, height, radius) {
2475
+ const r = Math.min(Math.max(0, radius), width / 2, height / 2);
2476
+ context.moveTo(x + r, y);
2477
+ context.lineTo(x + width - r, y);
2478
+ context.quadraticCurveTo(x + width, y, x + width, y + r);
2479
+ context.lineTo(x + width, y + height - r);
2480
+ context.quadraticCurveTo(x + width, y + height, x + width - r, y + height);
2481
+ context.lineTo(x + r, y + height);
2482
+ context.quadraticCurveTo(x, y + height, x, y + height - r);
2483
+ context.lineTo(x, y + r);
2484
+ context.quadraticCurveTo(x, y, x + r, y);
2485
+ context.closePath();
2486
+ }
2487
+ function hitTest(index, x, y) {
2488
+ const candidates = querySpatialIndex(index, { left: x, top: y, width: 0, height: 0 });
2489
+ for (let candidateIndex = candidates.length - 1; candidateIndex >= 0; candidateIndex -= 1) {
2490
+ const entry = index.objects[candidates[candidateIndex] ?? -1];
2491
+ if (entry && objectContainsPoint(entry, x, y)) return entry;
2492
+ }
2493
+ return null;
2494
+ }
2495
+ function objectContainsPoint(entry, x, y) {
2496
+ const position = entry.object.position;
2497
+ const rotation = objectRotation(entry);
2498
+ if (rotation === 0) {
2499
+ return x >= position.left && x <= position.left + position.width && y >= position.top && y <= position.top + position.height;
2500
+ }
2501
+ const centerX = position.left + position.width / 2;
2502
+ const centerY = position.top + position.height / 2;
2503
+ const radians = -rotation * Math.PI / 180;
2504
+ const dx = x - centerX;
2505
+ const dy = y - centerY;
2506
+ const localX = dx * Math.cos(radians) - dy * Math.sin(radians) + centerX;
2507
+ const localY = dx * Math.sin(radians) + dy * Math.cos(radians) + centerY;
2508
+ return localX >= position.left && localX <= position.left + position.width && localY >= position.top && localY <= position.top + position.height;
2509
+ }
2510
+ function objectBounds(entry) {
2511
+ const position = entry.object.position;
2512
+ const rotation = objectRotation(entry);
2513
+ if (rotation === 0) return position;
2514
+ const radians = rotation * Math.PI / 180;
2515
+ const width = Math.abs(position.width * Math.cos(radians)) + Math.abs(position.height * Math.sin(radians));
2516
+ const height = Math.abs(position.width * Math.sin(radians)) + Math.abs(position.height * Math.cos(radians));
2517
+ return {
2518
+ left: position.left + (position.width - width) / 2,
2519
+ top: position.top + (position.height - height) / 2,
2520
+ width,
2521
+ height
2522
+ };
2523
+ }
2524
+ function objectRotation(entry) {
2525
+ if (entry.kind === "shape") return finite(entry.object.rotation, 0);
2526
+ if (entry.kind === "image") return finite(entry.object.rotation, 0);
2527
+ if (entry.kind === "group") return finite(entry.object.rotation, 0);
2528
+ return 0;
2529
+ }
2530
+ function objectLabel(t, entry) {
2531
+ const object = entry.object;
2532
+ if (entry.kind === "shape") {
2533
+ const shape = object;
2534
+ return shape.text.toString().trim() || shape.name || t("artifacts.presentationEditor.shape");
2535
+ }
2536
+ if (entry.kind === "chart")
2537
+ return object.title || object.name || t("artifacts.presentationEditor.chart");
2538
+ if (entry.kind === "image")
2539
+ return object.alt || object.name || t("artifacts.presentationEditor.image");
2540
+ if (entry.kind === "table") return object.name || t("artifacts.presentationEditor.table");
2541
+ return object.name || t("artifacts.presentationEditor.group");
2542
+ }
2543
+ function accessibleObjectLabel(t, entry) {
2544
+ const position = entry.object.position;
2545
+ return `${objectLabel(t, entry)}. Position ${Math.round(position.left)}, ${Math.round(position.top)}. Size ${Math.round(position.width)} by ${Math.round(position.height)}.`;
2546
+ }
2547
+ function nextTextBoxPosition(objects, slideSize) {
2548
+ const width = slideSize.width * 0.6;
2549
+ const height = Math.max(48, slideSize.height * 0.16);
2550
+ const lefts = [0.2, 0.08, 0.32].map(
2551
+ (ratio) => Math.max(0, Math.min(slideSize.width - width, slideSize.width * ratio))
2552
+ );
2553
+ const tops = [0.2, 0.42, 0.64, 0.06].map(
2554
+ (ratio) => Math.max(0, Math.min(slideSize.height - height, slideSize.height * ratio))
2555
+ );
2556
+ const occupied = objects.map(objectBounds);
2557
+ let best = null;
2558
+ let bestOverlap = Number.POSITIVE_INFINITY;
2559
+ for (const left of lefts) {
2560
+ for (const top of tops) {
2561
+ const candidate = normalizeEditorPosition({ left, top, width, height });
2562
+ const overlap = occupied.reduce(
2563
+ (total, bounds) => total + intersectionArea(candidate, bounds),
2564
+ 0
2565
+ );
2566
+ if (overlap < bestOverlap) {
2567
+ best = candidate;
2568
+ bestOverlap = overlap;
2569
+ if (overlap === 0) return candidate;
2570
+ }
2571
+ }
2572
+ }
2573
+ return best ?? normalizeEditorPosition({ left: 0, top: 0, width, height });
2574
+ }
2575
+ function intersectionArea(a, b) {
2576
+ const width = Math.max(
2577
+ 0,
2578
+ Math.min(a.left + a.width, b.left + b.width) - Math.max(a.left, b.left)
2579
+ );
2580
+ const height = Math.max(0, Math.min(a.top + a.height, b.top + b.height) - Math.max(a.top, b.top));
2581
+ return width * height;
2582
+ }
2583
+ function normalizeEditorPosition(position) {
2584
+ return {
2585
+ left: clampGeometry(finite(position.left, 0)),
2586
+ top: clampGeometry(finite(position.top, 0)),
2587
+ width: Math.min(MAX_EDITOR_GEOMETRY, Math.max(8, finite(position.width, 8))),
2588
+ height: Math.min(MAX_EDITOR_GEOMETRY, Math.max(8, finite(position.height, 8)))
2589
+ };
2590
+ }
2591
+ function clampGeometry(value) {
2592
+ return Math.max(-MAX_EDITOR_GEOMETRY, Math.min(MAX_EDITOR_GEOMETRY, value));
2593
+ }
2594
+ function positionFromDrag(drag, point) {
2595
+ const dx = point.x - drag.start.x;
2596
+ const dy = point.y - drag.start.y;
2597
+ const radians = -drag.rotation * Math.PI / 180;
2598
+ const resizeDx = dx * Math.cos(radians) - dy * Math.sin(radians);
2599
+ const resizeDy = dx * Math.sin(radians) + dy * Math.cos(radians);
2600
+ return normalizeEditorPosition(
2601
+ drag.mode === "move" ? {
2602
+ ...drag.before,
2603
+ left: drag.before.left + dx,
2604
+ top: drag.before.top + dy
2605
+ } : {
2606
+ ...drag.before,
2607
+ width: Math.max(8, drag.before.width + resizeDx),
2608
+ height: Math.max(8, drag.before.height + resizeDy)
2609
+ }
2610
+ );
2611
+ }
2612
+ function selectionTransform(entry, position) {
2613
+ const rotation = objectRotation(entry);
2614
+ if (rotation === 0) return void 0;
2615
+ const centerX = position.left + position.width / 2;
2616
+ const centerY = position.top + position.height / 2;
2617
+ return `rotate(${rotation} ${centerX} ${centerY})`;
2618
+ }
2619
+ function copyPosition(position) {
2620
+ return {
2621
+ left: position.left,
2622
+ top: position.top,
2623
+ width: position.width,
2624
+ height: position.height
2625
+ };
2626
+ }
2627
+ function samePosition(a, b) {
2628
+ return a.left === b.left && a.top === b.top && a.width === b.width && a.height === b.height;
2629
+ }
2630
+ function sameViewport(a, b) {
2631
+ return a.scrollLeft === b.scrollLeft && a.scrollTop === b.scrollTop && a.width === b.width && a.height === b.height && a.stageLeft === b.stageLeft && a.stageTop === b.stageTop;
2632
+ }
2633
+ function intersects(a, b) {
2634
+ return !!a && a.left <= b.left + b.width && a.left + a.width >= b.left && a.top <= b.top + b.height && a.top + a.height >= b.top;
2635
+ }
2636
+ function clampZoom(value) {
2637
+ return Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, finite(value, 0.75)));
2638
+ }
2639
+ function fittedPresentationZoom(viewport, slideSize) {
2640
+ const horizontalRoom = Math.max(1, viewport.width - 48);
2641
+ const verticalRoom = Math.max(1, viewport.height - 48);
2642
+ return clampZoom(Math.min(horizontalRoom / slideSize.width, verticalRoom / slideSize.height));
2643
+ }
2644
+ function finite(value, fallback) {
2645
+ return Number.isFinite(value) ? value : fallback;
2646
+ }
2647
+ function safeDomId(value) {
2648
+ return value.replaceAll(/[^a-zA-Z0-9_-]/g, "-");
2649
+ }
2650
+ function randomPresentationId() {
2651
+ for (; ; ) {
2652
+ const bytes = crypto.getRandomValues(new Uint8Array(16));
2653
+ if (bytes.some((byte) => byte !== 0)) {
2654
+ return [...bytes].map((byte) => byte.toString(16).padStart(2, "0")).join("");
2655
+ }
2656
+ }
2657
+ }
2658
+ function resolveRadius(value, position) {
2659
+ if (typeof value === "number") return value;
2660
+ const min = Math.min(position.width, position.height);
2661
+ const preset = value?.startsWith("rounded-") ? value.slice("rounded-".length) : void 0;
2662
+ if (preset === "full") return min / 2;
2663
+ if (preset === "2xl") return 16;
2664
+ if (preset === "xl") return 12;
2665
+ if (preset === "lg") return 8;
2666
+ return 6;
2667
+ }
2668
+ var COLORS = {
2669
+ none: "transparent",
2670
+ transparent: "transparent",
2671
+ white: "#ffffff",
2672
+ black: "#000000",
2673
+ "slate-50": "#f8fafc",
2674
+ "slate-100": "#f1f5f9",
2675
+ "slate-200": "#e2e8f0",
2676
+ "slate-300": "#cbd5e1",
2677
+ "slate-400": "#94a3b8",
2678
+ "slate-500": "#64748b",
2679
+ "slate-600": "#475569",
2680
+ "slate-700": "#334155",
2681
+ "slate-800": "#1e293b",
2682
+ "slate-900": "#0f172a",
2683
+ "slate-950": "#020617"
2684
+ };
2685
+ function resolveColor(fill) {
2686
+ const value = typeof fill === "string" ? fill : fill.color;
2687
+ return COLORS[value] ?? value;
2688
+ }
2689
+
2690
+ // src/components/artifacts/editable-presentation.tsx
2691
+ import {
2692
+ PRESENTATION_ARTIFACT_COMMAND_VERSION,
2693
+ PRESENTATION_ARTIFACT_QUERY_MAX_NODES,
2694
+ PRESENTATION_ARTIFACT_QUERY_MAX_SLIDES,
2695
+ PRESENTATION_ARTIFACT_QUERY_MAX_TEXT_BYTES,
2696
+ PRESENTATION_ARTIFACT_QUERY_RESPONSE_MAX_BYTES
2697
+ } from "@opengeni/sdk/editable-artifacts";
2698
+ import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
2699
+ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
2700
+ var EMU_PER_CSS_PIXEL = 9525;
2701
+ var PRESENTATION_CATALOG_PAGE = 128;
2702
+ var PRESENTATION_MAX_INTERACTIVE_SLIDES = 256;
2703
+ var PRESENTATION_MAX_INTERACTIVE_NODES = 16384;
2704
+ var PRESENTATION_MAX_INTERACTIVE_TEXT_BYTES = 4 * 1024 * 1024;
2705
+ var PRESENTATION_MAX_CATALOG_PAGES = 32;
2706
+ var PRESENTATION_SCENE_CONCURRENCY = 4;
2707
+ var PRESENTATION_COMPOSITION_ATTEMPTS = 3;
2708
+ var DEFAULT_PRESENTATION_TEXT_STYLE = Object.freeze({
2709
+ fontFamily: "Arial",
2710
+ fontSizeCentipoints: 1800,
2711
+ color: 255,
2712
+ bold: false,
2713
+ italic: false,
2714
+ underline: false,
2715
+ language: null
2716
+ });
2717
+ function EditablePresentationArtifactSurface(props) {
2718
+ return /* @__PURE__ */ jsx2(ArtifactSubmissionProvider, { children: /* @__PURE__ */ jsx2(EditablePresentationArtifactSurfaceSession, { ...props }) }, artifactSubmissionSessionKey(props.session));
2719
+ }
2720
+ function EditablePresentationArtifactSurfaceSession({
2721
+ session,
2722
+ title: titleProp,
2723
+ showHeader,
2724
+ subtitle,
2725
+ readOnly = false,
2726
+ onCommit,
2727
+ onCommandError,
2728
+ download,
2729
+ actions: actionsProp,
2730
+ ...surfaceProps
2731
+ }) {
2732
+ const t = useOpenGeniText();
2733
+ const title = titleProp === void 0 ? t("artifacts.editablePresentation.presentation") : titleProp;
2734
+ const view = useEditableArtifactView(session);
2735
+ const submissions = useArtifactSubmissions();
2736
+ const invalidator = editableArtifactProjectionKey(view);
2737
+ const [retryEpoch, setRetryEpoch] = useState2(0);
2738
+ const [state, setState] = useState2({
2739
+ composed: null,
2740
+ loading: true,
2741
+ error: null
2742
+ });
2743
+ const loadGeneration = useRef2(0);
2744
+ const scheduleLoad = useLatestTaskRunner(session);
2745
+ const sceneNodes = useRef2(/* @__PURE__ */ new Map());
2746
+ useEffect2(() => {
2747
+ const generation = ++loadGeneration.current;
2748
+ let cancelled = false;
2749
+ setState((current) => ({ ...current, loading: true, error: null }));
2750
+ scheduleLoad(async () => {
2751
+ if (cancelled || generation !== loadGeneration.current) return;
2752
+ await composePresentationEditorProjection(t, session).then(
2753
+ (composed) => {
2754
+ if (cancelled || generation !== loadGeneration.current) return;
2755
+ sceneNodes.current = new Map(composed.sceneNodes);
2756
+ setState({ composed, loading: false, error: null });
2757
+ },
2758
+ (cause) => {
2759
+ if (cancelled || generation !== loadGeneration.current) return;
2760
+ setState({
2761
+ composed: null,
2762
+ loading: false,
2763
+ error: asEditableArtifactError(
2764
+ cause,
2765
+ t("artifacts.editablePresentation.couldNotOpenThisPresentation")
2766
+ )
2767
+ });
2768
+ }
2769
+ );
2770
+ });
2771
+ return () => {
2772
+ cancelled = true;
2773
+ };
2774
+ }, [invalidator, retryEpoch, scheduleLoad, session, t]);
2775
+ const refresh = useCallback2(() => setRetryEpoch((value) => value + 1), []);
2776
+ const writable = !readOnly && view.writable;
2777
+ const applyCommit = useCallback2(
2778
+ async (commit) => {
2779
+ const composed = state.composed;
2780
+ if (!composed) throw new Error("Presentation projection is not ready");
2781
+ if (!writable)
2782
+ throw new Error(t("artifacts.editablePresentation.thisPresentationIsReadOnly"));
2783
+ if (view.authoringBlockedReason)
2784
+ throw new Error(t("artifacts.editablePresentation.anEarlierChangeMustSettle"));
2785
+ if (commit.revision !== void 0 && String(commit.revision) !== String(composed.projection.revision)) {
2786
+ throw new Error(t("artifacts.editablePresentation.thePresentationChangedRetryThis"));
2787
+ }
2788
+ if (commit.kind === "slide-insert") {
2789
+ await session.createPresentationSlide({
2790
+ slideId: commit.slideId,
2791
+ index: commit.index
2792
+ });
2793
+ notifyPresentationCommit(t, onCommit, onCommandError, commit);
2794
+ refresh();
2795
+ return;
2796
+ }
2797
+ if (commit.kind === "slide-delete") {
2798
+ await session.applyPresentationCommands({
2799
+ version: PRESENTATION_ARTIFACT_COMMAND_VERSION,
2800
+ commands: [{ kind: "slide.delete", id: commit.slideId }]
2801
+ });
2802
+ notifyPresentationCommit(t, onCommit, onCommandError, commit);
2803
+ refresh();
2804
+ return;
2805
+ }
2806
+ if (commit.kind === "object-insert") {
2807
+ await session.applyPresentationCommands({
2808
+ version: PRESENTATION_ARTIFACT_COMMAND_VERSION,
2809
+ commands: [
2810
+ {
2811
+ kind: "node.insert",
2812
+ owner: { kind: "slide", id: commit.slideId },
2813
+ parentId: null,
2814
+ index: commit.index,
2815
+ node: {
2816
+ id: commit.objectId,
2817
+ name: "Text box",
2818
+ bounds: {
2819
+ x: canonicalCoordinate(commit.position.left),
2820
+ y: canonicalCoordinate(commit.position.top),
2821
+ width: Math.max(1, canonicalCoordinate(commit.position.width)),
2822
+ height: Math.max(1, canonicalCoordinate(commit.position.height))
2823
+ },
2824
+ transform: { rotation: 0, flipHorizontal: false, flipVertical: false },
2825
+ content: {
2826
+ kind: "shape",
2827
+ geometry: "text-box",
2828
+ fill: { kind: "none" },
2829
+ line: { fill: { kind: "none" }, width: 0, dash: "solid" },
2830
+ text: emptyPresentationText(),
2831
+ placeholder: null
2832
+ }
2833
+ }
2834
+ }
2835
+ ]
2836
+ });
2837
+ notifyPresentationCommit(t, onCommit, onCommandError, commit);
2838
+ refresh();
2839
+ return;
2840
+ }
2841
+ if (commit.kind === "object-delete") {
2842
+ await session.applyPresentationCommands({
2843
+ version: PRESENTATION_ARTIFACT_COMMAND_VERSION,
2844
+ commands: [{ kind: "node.delete", id: commit.objectId }]
2845
+ });
2846
+ notifyPresentationCommit(t, onCommit, onCommandError, commit);
2847
+ refresh();
2848
+ return;
2849
+ }
2850
+ const key = sceneNodeKey(commit.slideId, commit.objectId);
2851
+ const node = sceneNodes.current.get(key);
2852
+ if (!node) throw new Error(t("artifacts.editablePresentation.theEditedPresentationObjectIs"));
2853
+ if (node.inherited || node.source.kind !== "slide" || node.source.id !== commit.slideId) {
2854
+ throw new Error(t("artifacts.editablePresentation.inheritedMasterAndLayoutObjects"));
2855
+ }
2856
+ let command;
2857
+ let nextNode;
2858
+ if (commit.kind === "text") {
2859
+ if (node.content.kind !== "shape" || node.content.text === null) {
2860
+ throw new Error(t("artifacts.editablePresentation.thisPresentationObjectDoesNot"));
2861
+ }
2862
+ if (flattenPresentationRichText(node.content.text) !== commit.before) {
2863
+ throw new Error(t("artifacts.editablePresentation.thePresentationTextChangedRetry"));
2864
+ }
2865
+ const text = replacePresentationRichText(node.content.text, commit.before, commit.after);
2866
+ const content = Object.freeze({ ...node.content, text });
2867
+ command = { kind: "node.content.set", id: node.id, content };
2868
+ nextNode = Object.freeze({ ...node, content });
2869
+ } else {
2870
+ const current = normalizeProjectedEditorPosition(projectPosition(node.bounds));
2871
+ if (!sameProjectedPosition(current, commit.before)) {
2872
+ throw new Error(t("artifacts.editablePresentation.thePresentationObjectChangedRetry"));
2873
+ }
2874
+ const bounds = commit.kind === "move" ? Object.freeze({
2875
+ ...node.bounds,
2876
+ x: canonicalCoordinate(commit.after.left),
2877
+ y: canonicalCoordinate(commit.after.top)
2878
+ }) : Object.freeze({
2879
+ ...node.bounds,
2880
+ width: Math.max(1, canonicalCoordinate(commit.after.width)),
2881
+ height: Math.max(1, canonicalCoordinate(commit.after.height))
2882
+ });
2883
+ command = { kind: "node.bounds.set", id: node.id, bounds };
2884
+ nextNode = Object.freeze({ ...node, bounds });
2885
+ }
2886
+ await session.applyPresentationCommands({
2887
+ version: PRESENTATION_ARTIFACT_COMMAND_VERSION,
2888
+ commands: [command]
2889
+ });
2890
+ sceneNodes.current.set(key, nextNode);
2891
+ notifyPresentationCommit(t, onCommit, onCommandError, commit);
2892
+ refresh();
2893
+ },
2894
+ [
2895
+ onCommandError,
2896
+ onCommit,
2897
+ refresh,
2898
+ session,
2899
+ state.composed,
2900
+ view.authoringBlockedReason,
2901
+ writable,
2902
+ t
2903
+ ]
2904
+ );
2905
+ const submitCommit = useCallback2(
2906
+ (commit) => submissions.run(() => applyCommit(commit)),
2907
+ [applyCommit, submissions]
2908
+ );
2909
+ const actions = download ? /* @__PURE__ */ jsxs2(Fragment, { children: [
2910
+ actionsProp,
2911
+ /* @__PURE__ */ jsx2(
2912
+ EditableArtifactDownloadButton,
2913
+ {
2914
+ session,
2915
+ title,
2916
+ download,
2917
+ format: "pptx"
2918
+ }
2919
+ )
2920
+ ] }) : actionsProp;
2921
+ const projection = state.composed?.projection ?? null;
2922
+ const status = editableArtifactStatusLabel(t, view);
2923
+ const accessRevoked = editableArtifactAccessRevoked(view);
2924
+ return projection && !accessRevoked ? /* @__PURE__ */ jsx2(
2925
+ PresentationProjectionArtifactSurface,
2926
+ {
2927
+ ...surfaceProps,
2928
+ title,
2929
+ showHeader,
2930
+ actions,
2931
+ subtitle: subtitle ?? writable ? t("counts.slides", { count: projection.slides.length }) : t("artifacts.readOnlySubtitle", {
2932
+ subtitle: t("counts.slides", { count: projection.slides.length })
2933
+ }),
2934
+ projection,
2935
+ commit: writable ? submitCommit : void 0,
2936
+ readOnly: !writable,
2937
+ authoringBlockedReason: view.authoringBlockedReason,
2938
+ busy: state.loading,
2939
+ onCommandError
2940
+ }
2941
+ ) : /* @__PURE__ */ jsx2(
2942
+ ArtifactSurface,
2943
+ {
2944
+ modality: "presentation",
2945
+ title,
2946
+ showHeader,
2947
+ subtitle: subtitle ?? status,
2948
+ actions: accessRevoked ? actionsProp : actions,
2949
+ busy: !accessRevoked && !state.error,
2950
+ className: surfaceProps.className,
2951
+ children: /* @__PURE__ */ jsx2(
2952
+ EditableArtifactMessage,
2953
+ {
2954
+ title: accessRevoked ? t("artifacts.editablePresentation.accessChanged") : state.error ? t("artifacts.editablePresentation.couldNotOpenThisPresentation") : t("artifacts.editablePresentation.openingPresentation"),
2955
+ detail: accessRevoked ? status : state.error?.message ?? status,
2956
+ retry: !accessRevoked && state.error ? refresh : void 0
2957
+ }
2958
+ )
2959
+ }
2960
+ );
2961
+ }
2962
+ async function composePresentationEditorProjection(t, session) {
2963
+ if (session.modality !== "presentation") {
2964
+ throw new Error("Expected a presentation artifact session");
2965
+ }
2966
+ let lastRevisionError = null;
2967
+ for (let attempt = 0; attempt < PRESENTATION_COMPOSITION_ATTEMPTS; attempt += 1) {
2968
+ try {
2969
+ return await composePresentationAttempt(session);
2970
+ } catch (cause) {
2971
+ const error = asEditableArtifactError(
2972
+ cause,
2973
+ t("artifacts.editablePresentation.couldNotProjectThisPresentation")
2974
+ );
2975
+ if (!isPresentationRevisionDrift(error) || attempt === PRESENTATION_COMPOSITION_ATTEMPTS - 1) {
2976
+ throw error;
2977
+ }
2978
+ lastRevisionError = error;
2979
+ }
2980
+ }
2981
+ throw lastRevisionError ?? new Error("Presentation changed while it was opening");
2982
+ }
2983
+ async function composePresentationAttempt(session) {
2984
+ const metadata = await session.queryPresentation({
2985
+ kind: "metadata",
2986
+ maxBytes: PRESENTATION_ARTIFACT_QUERY_RESPONSE_MAX_BYTES
2987
+ });
2988
+ if (metadata.kind !== "metadata") throw new Error("Presentation metadata response is malformed");
2989
+ if (metadata.slides > PRESENTATION_MAX_INTERACTIVE_SLIDES) {
2990
+ throw new Error(
2991
+ `Presentation exceeds the interactive limit of ${PRESENTATION_MAX_INTERACTIVE_SLIDES} slides`
2992
+ );
2993
+ }
2994
+ const catalog = await collectSlideCatalog(session, metadata.revision, metadata.slides);
2995
+ const scenes = [];
2996
+ for (let start = 0; start < catalog.length; start += PRESENTATION_SCENE_CONCURRENCY) {
2997
+ const batch = catalog.slice(start, start + PRESENTATION_SCENE_CONCURRENCY);
2998
+ const projected = await Promise.all(
2999
+ batch.map(
3000
+ (slide) => session.queryPresentationEditorSlide({
3001
+ kind: "editor-slide",
3002
+ slideId: slide.id,
3003
+ maxNodes: PRESENTATION_ARTIFACT_QUERY_MAX_NODES,
3004
+ maxTextBytes: PRESENTATION_ARTIFACT_QUERY_MAX_TEXT_BYTES,
3005
+ maxBytes: PRESENTATION_ARTIFACT_QUERY_RESPONSE_MAX_BYTES
3006
+ })
3007
+ )
3008
+ );
3009
+ for (const scene of projected) {
3010
+ if (scene.revision !== metadata.revision) {
3011
+ throw new Error("Presentation projection revision drifted");
3012
+ }
3013
+ if (scene.truncated) {
3014
+ throw new Error(`Slide ${scene.slide.index + 1} exceeds the bounded editor projection`);
3015
+ }
3016
+ scenes.push(scene);
3017
+ }
3018
+ }
3019
+ const totalNodes = scenes.reduce((sum, scene) => sum + scene.nodes.length, 0);
3020
+ const totalText = scenes.reduce((sum, scene) => sum + scene.projectedTextBytes, 0);
3021
+ if (totalNodes > PRESENTATION_MAX_INTERACTIVE_NODES) {
3022
+ throw new Error(
3023
+ `Presentation exceeds the interactive limit of ${PRESENTATION_MAX_INTERACTIVE_NODES} scene nodes`
3024
+ );
3025
+ }
3026
+ if (totalText > PRESENTATION_MAX_INTERACTIVE_TEXT_BYTES) {
3027
+ throw new Error(
3028
+ `Presentation exceeds the interactive limit of ${PRESENTATION_MAX_INTERACTIVE_TEXT_BYTES} text bytes`
3029
+ );
3030
+ }
3031
+ if (scenes.length !== catalog.length) {
3032
+ throw new Error("Presentation slides changed while they were opening");
3033
+ }
3034
+ const sceneNodeMap = /* @__PURE__ */ new Map();
3035
+ const slides = scenes.map((scene, index) => {
3036
+ if (scene.slide.id !== catalog[index]?.id || scene.slide.index !== index) {
3037
+ throw new Error("Presentation slide catalog changed while it was opening");
3038
+ }
3039
+ for (const node of scene.nodes) {
3040
+ sceneNodeMap.set(sceneNodeKey(scene.slide.id, node.id), node);
3041
+ }
3042
+ return projectPresentationSlide(scene);
3043
+ });
3044
+ return Object.freeze({
3045
+ projection: Object.freeze({
3046
+ revision: metadata.revision.toString(),
3047
+ slideSize: Object.freeze({
3048
+ width: displayCoordinate(metadata.slideSize.width),
3049
+ height: displayCoordinate(metadata.slideSize.height)
3050
+ }),
3051
+ slides: Object.freeze(slides)
3052
+ }),
3053
+ sceneNodes: sceneNodeMap
3054
+ });
3055
+ }
3056
+ async function collectSlideCatalog(session, revision, expectedSlides) {
3057
+ const slides = [];
3058
+ let startSlide = 0;
3059
+ let projectedText = 0;
3060
+ for (let page = 0; page < PRESENTATION_MAX_CATALOG_PAGES; page += 1) {
3061
+ const response = await session.queryPresentationSlideCatalog({
3062
+ kind: "slide-catalog",
3063
+ startSlide,
3064
+ maxSlides: Math.min(
3065
+ PRESENTATION_CATALOG_PAGE,
3066
+ PRESENTATION_ARTIFACT_QUERY_MAX_SLIDES,
3067
+ Math.max(1, expectedSlides - slides.length)
3068
+ ),
3069
+ maxTextBytes: PRESENTATION_ARTIFACT_QUERY_MAX_TEXT_BYTES,
3070
+ maxBytes: PRESENTATION_ARTIFACT_QUERY_RESPONSE_MAX_BYTES
3071
+ });
3072
+ if (response.revision !== revision) {
3073
+ throw new Error("Presentation projection revision drifted");
3074
+ }
3075
+ if (response.startSlide !== startSlide) {
3076
+ throw new Error("Presentation slide catalog cursor is malformed");
3077
+ }
3078
+ if (response.slides.some((slide, offset) => slide.index !== startSlide + offset)) {
3079
+ throw new Error("Presentation slide catalog order is malformed");
3080
+ }
3081
+ slides.push(...response.slides);
3082
+ projectedText += response.projectedTextBytes;
3083
+ if (slides.length > PRESENTATION_MAX_INTERACTIVE_SLIDES || projectedText > PRESENTATION_MAX_INTERACTIVE_TEXT_BYTES) {
3084
+ throw new Error("Presentation slide catalog exceeds its interactive limit");
3085
+ }
3086
+ if (response.nextSlide === null) {
3087
+ if (response.truncated || slides.length !== expectedSlides) {
3088
+ throw new Error("Presentation slide catalog is incomplete");
3089
+ }
3090
+ return slides;
3091
+ }
3092
+ if (!response.truncated || response.nextSlide <= startSlide || response.nextSlide !== startSlide + response.slides.length || response.slides.length === 0) {
3093
+ throw new Error("Presentation slide catalog did not advance");
3094
+ }
3095
+ startSlide = response.nextSlide;
3096
+ }
3097
+ throw new Error(`Presentation catalog exceeds ${PRESENTATION_MAX_CATALOG_PAGES} pages`);
3098
+ }
3099
+ function projectPresentationSlide(scene) {
3100
+ const byId = new Map(scene.nodes.map((node) => [node.id, node]));
3101
+ if (byId.size !== scene.nodes.length)
3102
+ throw new Error("Presentation slide contains duplicate IDs");
3103
+ const children = /* @__PURE__ */ new Map();
3104
+ for (const node of scene.nodes) {
3105
+ const entries = children.get(node.parentId) ?? [];
3106
+ entries.push(node);
3107
+ children.set(node.parentId, entries);
3108
+ }
3109
+ for (const entries of children.values()) {
3110
+ entries.sort((left, right) => left.order - right.order || left.id.localeCompare(right.id));
3111
+ }
3112
+ const visited = /* @__PURE__ */ new Set();
3113
+ const stack = /* @__PURE__ */ new Set();
3114
+ const projectNode = (node) => {
3115
+ if (stack.has(node.id)) throw new Error("Presentation group hierarchy contains a cycle");
3116
+ if (visited.has(node.id)) throw new Error("Presentation node appears more than once");
3117
+ stack.add(node.id);
3118
+ visited.add(node.id);
3119
+ const directChildren = children.get(node.id) ?? [];
3120
+ let orderedChildren = directChildren;
3121
+ if (node.content.kind === "group") {
3122
+ const directIds = new Set(directChildren.map((child) => child.id));
3123
+ if (node.content.children.length !== directChildren.length || node.content.children.some((id) => !directIds.has(id))) {
3124
+ throw new Error(`Presentation group ${node.id} hierarchy is inconsistent`);
3125
+ }
3126
+ orderedChildren = node.content.children.map((id) => byId.get(id));
3127
+ } else if (directChildren.length > 0) {
3128
+ throw new Error(`Presentation non-group node ${node.id} contains children`);
3129
+ }
3130
+ const result = projectPresentationNode(node, orderedChildren.map(projectNode));
3131
+ stack.delete(node.id);
3132
+ return result;
3133
+ };
3134
+ const elements = (children.get(null) ?? []).map(projectNode);
3135
+ if (visited.size !== scene.nodes.length) {
3136
+ throw new Error("Presentation slide contains orphaned hierarchy nodes");
3137
+ }
3138
+ return Object.freeze({
3139
+ id: scene.slide.id,
3140
+ title: scene.slide.title,
3141
+ background: projectFill(scene.slide.background),
3142
+ elements: Object.freeze(elements),
3143
+ layout: scene.slide.layout ? Object.freeze({
3144
+ id: scene.slide.layout.id,
3145
+ name: scene.slide.layout.name,
3146
+ masterId: scene.slide.layout.masterId,
3147
+ background: projectFill(scene.slide.layout.background)
3148
+ }) : null,
3149
+ notes: scene.notes ? projectRichText(scene.notes) : null
3150
+ });
3151
+ }
3152
+ function projectPresentationNode(node, children) {
3153
+ const metadata = {
3154
+ nodeSource: { ...node.source },
3155
+ inherited: node.inherited,
3156
+ parentId: node.parentId,
3157
+ order: node.order,
3158
+ readOnly: node.inherited || node.source.kind !== "slide"
3159
+ };
3160
+ const position = projectPosition(node.bounds);
3161
+ const rotation = node.transform.rotation / 6e4;
3162
+ const content = node.content;
3163
+ if (content.kind === "shape") {
3164
+ const richText = content.text ? projectRichText(content.text) : void 0;
3165
+ const textStyle = richText ? firstTextStyle(richText) : void 0;
3166
+ return Object.freeze({
3167
+ ...metadata,
3168
+ kind: "shape",
3169
+ id: node.id,
3170
+ name: node.name,
3171
+ geometry: projectShapeGeometry(content.geometry),
3172
+ position,
3173
+ fill: projectFill(content.fill),
3174
+ line: projectLine(content.line),
3175
+ rotation,
3176
+ text: content.text ? flattenPresentationRichText(content.text) : "",
3177
+ ...richText ? { richText } : {},
3178
+ ...textStyle ? { textStyle } : {}
3179
+ });
3180
+ }
3181
+ if (content.kind === "group") {
3182
+ return Object.freeze({
3183
+ ...metadata,
3184
+ kind: "group",
3185
+ id: node.id,
3186
+ name: node.name,
3187
+ position,
3188
+ childOffset: Object.freeze({
3189
+ left: displayCoordinate(content.childOffsetX),
3190
+ top: displayCoordinate(content.childOffsetY)
3191
+ }),
3192
+ childExtent: Object.freeze({
3193
+ width: displayCoordinate(content.childExtentWidth),
3194
+ height: displayCoordinate(content.childExtentHeight)
3195
+ }),
3196
+ rotation,
3197
+ flipHorizontal: node.transform.flipHorizontal,
3198
+ flipVertical: node.transform.flipVertical,
3199
+ children: Object.freeze([...children])
3200
+ });
3201
+ }
3202
+ if (content.kind === "connector") {
3203
+ return Object.freeze({
3204
+ ...metadata,
3205
+ kind: "connector",
3206
+ id: node.id,
3207
+ name: node.name,
3208
+ connectorKind: content.connectorKind,
3209
+ position,
3210
+ start: Object.freeze({
3211
+ nodeId: content.start.nodeId,
3212
+ x: displayCoordinate(content.start.x),
3213
+ y: displayCoordinate(content.start.y)
3214
+ }),
3215
+ end: Object.freeze({
3216
+ nodeId: content.end.nodeId,
3217
+ x: displayCoordinate(content.end.x),
3218
+ y: displayCoordinate(content.end.y)
3219
+ }),
3220
+ line: projectLine(content.line)
3221
+ });
3222
+ }
3223
+ if (content.kind === "chart") {
3224
+ const titleRichText = projectRichText(content.title);
3225
+ return Object.freeze({
3226
+ ...metadata,
3227
+ kind: "chart",
3228
+ id: node.id,
3229
+ name: node.name,
3230
+ type: content.chartType,
3231
+ position,
3232
+ title: flattenPresentationRichText(content.title),
3233
+ titleRichText,
3234
+ hasLegend: content.hasLegend,
3235
+ series: Object.freeze(
3236
+ content.series.map((series) => ({
3237
+ name: series.name,
3238
+ categories: Object.freeze([...series.categories]),
3239
+ values: Object.freeze([...series.values]),
3240
+ xValues: Object.freeze([...series.xValues]),
3241
+ bubbleSizes: Object.freeze([...series.bubbleSizes])
3242
+ }))
3243
+ )
3244
+ });
3245
+ }
3246
+ if (content.kind === "table") {
3247
+ return Object.freeze({
3248
+ ...metadata,
3249
+ kind: "table",
3250
+ id: node.id,
3251
+ name: node.name,
3252
+ position,
3253
+ rows: Object.freeze(
3254
+ content.rows.map(
3255
+ (row) => Object.freeze(
3256
+ row.map(
3257
+ (cell) => cell ? Object.freeze({
3258
+ text: flattenPresentationRichText(cell.text),
3259
+ richText: projectRichText(cell.text),
3260
+ fill: projectFill(cell.fill),
3261
+ rowSpan: cell.rowSpan,
3262
+ colSpan: cell.columnSpan
3263
+ }) : null
3264
+ )
3265
+ )
3266
+ )
3267
+ ),
3268
+ columnWidths: Object.freeze(content.columnWidths.map(displayCoordinate)),
3269
+ rowHeights: Object.freeze(content.rowHeights.map(displayCoordinate)),
3270
+ line: projectLine(content.line)
3271
+ });
3272
+ }
3273
+ return Object.freeze({
3274
+ ...metadata,
3275
+ kind: "image",
3276
+ id: node.id,
3277
+ name: node.name,
3278
+ position,
3279
+ alt: content.altText,
3280
+ fit: content.fit,
3281
+ rotation,
3282
+ flipHorizontal: node.transform.flipHorizontal,
3283
+ flipVertical: node.transform.flipVertical,
3284
+ digest: bytesToHex(content.digest),
3285
+ contentType: content.contentType,
3286
+ intrinsicWidth: content.intrinsicWidth,
3287
+ intrinsicHeight: content.intrinsicHeight
3288
+ });
3289
+ }
3290
+ function projectRichText(text) {
3291
+ return Object.freeze({
3292
+ verticalAlignment: text.verticalAlignment,
3293
+ paragraphs: Object.freeze(
3294
+ text.paragraphs.map(
3295
+ (paragraph) => Object.freeze({
3296
+ alignment: paragraph.alignment,
3297
+ runs: Object.freeze(
3298
+ paragraph.runs.map(
3299
+ (run) => Object.freeze({
3300
+ text: run.text,
3301
+ style: projectTextStyle(run.style, paragraph.alignment, text.verticalAlignment),
3302
+ language: run.style.language
3303
+ })
3304
+ )
3305
+ )
3306
+ })
3307
+ )
3308
+ )
3309
+ });
3310
+ }
3311
+ function projectTextStyle(style, alignment, verticalAlignment) {
3312
+ return Object.freeze({
3313
+ fontFamily: style.fontFamily,
3314
+ fontSize: style.fontSizeCentipoints / 100,
3315
+ color: rgbaCss(style.color),
3316
+ bold: style.bold,
3317
+ italic: style.italic,
3318
+ underline: style.underline,
3319
+ ...alignment ? { alignment } : {},
3320
+ ...verticalAlignment ? { verticalAlignment } : {}
3321
+ });
3322
+ }
3323
+ function firstTextStyle(text) {
3324
+ return text.paragraphs[0]?.runs[0]?.style;
3325
+ }
3326
+ function projectFill(fill) {
3327
+ return fill.kind === "none" ? "none" : Object.freeze({ type: "solid", color: rgbaCss(fill.color) });
3328
+ }
3329
+ function projectLine(line) {
3330
+ return Object.freeze({
3331
+ style: line.dash,
3332
+ fill: projectFill(line.fill),
3333
+ width: displayCoordinate(line.width)
3334
+ });
3335
+ }
3336
+ function projectPosition(bounds) {
3337
+ return Object.freeze({
3338
+ left: displayCoordinate(bounds.x),
3339
+ top: displayCoordinate(bounds.y),
3340
+ width: displayCoordinate(bounds.width),
3341
+ height: displayCoordinate(bounds.height)
3342
+ });
3343
+ }
3344
+ function displayCoordinate(value) {
3345
+ return value / EMU_PER_CSS_PIXEL;
3346
+ }
3347
+ function normalizeProjectedEditorPosition(position) {
3348
+ const clamp = (value) => Math.max(-1e6, Math.min(1e6, value));
3349
+ return {
3350
+ left: clamp(position.left),
3351
+ top: clamp(position.top),
3352
+ width: Math.min(1e6, Math.max(8, position.width)),
3353
+ height: Math.min(1e6, Math.max(8, position.height))
3354
+ };
3355
+ }
3356
+ function canonicalCoordinate(value) {
3357
+ if (!Number.isFinite(value)) throw new Error("Presentation coordinate must be finite");
3358
+ const canonical = Math.round(value * EMU_PER_CSS_PIXEL);
3359
+ if (!Number.isSafeInteger(canonical)) throw new Error("Presentation coordinate is out of range");
3360
+ return canonical;
3361
+ }
3362
+ function sameProjectedPosition(left, right) {
3363
+ return canonicalCoordinate(left.left) === canonicalCoordinate(right.left) && canonicalCoordinate(left.top) === canonicalCoordinate(right.top) && canonicalCoordinate(left.width) === canonicalCoordinate(right.width) && canonicalCoordinate(left.height) === canonicalCoordinate(right.height);
3364
+ }
3365
+ function projectShapeGeometry(geometry) {
3366
+ return {
3367
+ "text-box": "textbox",
3368
+ rectangle: "rect",
3369
+ "rounded-rectangle": "roundRect",
3370
+ ellipse: "ellipse",
3371
+ triangle: "triangle",
3372
+ "right-arrow": "rightArrow",
3373
+ line: "line"
3374
+ }[geometry];
3375
+ }
3376
+ function emptyPresentationText() {
3377
+ return Object.freeze({
3378
+ verticalAlignment: "middle",
3379
+ paragraphs: Object.freeze([
3380
+ Object.freeze({
3381
+ alignment: "left",
3382
+ runs: Object.freeze([Object.freeze({ text: "", style: DEFAULT_PRESENTATION_TEXT_STYLE })])
3383
+ })
3384
+ ])
3385
+ });
3386
+ }
3387
+ function flattenPresentationRichText(text) {
3388
+ return text.paragraphs.map((paragraph) => paragraph.runs.map((run) => run.text).join("")).join("\n");
3389
+ }
3390
+ function replacePresentationRichText(richText, before, after) {
3391
+ const canonicalBefore = flattenPresentationRichText(richText);
3392
+ if (canonicalBefore !== before) throw new Error("Presentation rich text does not match its edit");
3393
+ if (before === after) return richText;
3394
+ const diff = textReplacementRange(before, after);
3395
+ const spans = presentationStyleSpans(richText);
3396
+ const paragraphStarts = presentationParagraphStarts(richText);
3397
+ const insertionStyle = styleAtOffset(spans, diff.start) ?? DEFAULT_PRESENTATION_TEXT_STYLE;
3398
+ const insertionAlignment = alignmentAtOffset(richText, paragraphStarts, diff.start);
3399
+ const paragraphs = [];
3400
+ let newOffset = 0;
3401
+ for (const paragraphText of after.split("\n")) {
3402
+ const alignment = alignmentForNewOffset(
3403
+ richText,
3404
+ paragraphStarts,
3405
+ diff,
3406
+ newOffset,
3407
+ insertionAlignment
3408
+ );
3409
+ const runs = [];
3410
+ let localOffset = 0;
3411
+ for (const character of paragraphText) {
3412
+ const offset = newOffset + localOffset;
3413
+ const oldOffset = oldOffsetForNewOffset(diff, offset);
3414
+ const style = oldOffset === null ? insertionStyle : styleAtOffset(spans, oldOffset) ?? insertionStyle;
3415
+ const previous = runs.at(-1);
3416
+ if (previous && samePresentationTextStyle(previous.style, style)) previous.text += character;
3417
+ else runs.push({ text: character, style });
3418
+ localOffset += character.length;
3419
+ }
3420
+ paragraphs.push(
3421
+ Object.freeze({
3422
+ alignment,
3423
+ runs: Object.freeze(
3424
+ runs.map(
3425
+ (run) => Object.freeze({ text: run.text, style: Object.freeze({ ...run.style }) })
3426
+ )
3427
+ )
3428
+ })
3429
+ );
3430
+ newOffset += paragraphText.length + 1;
3431
+ }
3432
+ return Object.freeze({
3433
+ verticalAlignment: richText.verticalAlignment,
3434
+ paragraphs: Object.freeze(paragraphs)
3435
+ });
3436
+ }
3437
+ function textReplacementRange(before, after) {
3438
+ let start = 0;
3439
+ while (start < before.length && start < after.length && before.charCodeAt(start) === after.charCodeAt(start)) {
3440
+ start += 1;
3441
+ }
3442
+ while (start > 0 && (splitsSurrogate(before, start) || splitsSurrogate(after, start))) start -= 1;
3443
+ let suffix = 0;
3444
+ while (suffix < before.length - start && suffix < after.length - start && before.charCodeAt(before.length - suffix - 1) === after.charCodeAt(after.length - suffix - 1)) {
3445
+ suffix += 1;
3446
+ }
3447
+ while (suffix > 0 && (splitsSurrogate(before, before.length - suffix) || splitsSurrogate(after, after.length - suffix))) {
3448
+ suffix -= 1;
3449
+ }
3450
+ const oldEnd = before.length - suffix;
3451
+ const newEnd = after.length - suffix;
3452
+ return { start, oldEnd, newEnd, delta: oldEnd - newEnd };
3453
+ }
3454
+ function oldOffsetForNewOffset(diff, offset) {
3455
+ if (offset < diff.start) return offset;
3456
+ if (offset >= diff.newEnd) return offset + diff.delta;
3457
+ return null;
3458
+ }
3459
+ function presentationStyleSpans(text) {
3460
+ const spans = [];
3461
+ let offset = 0;
3462
+ text.paragraphs.forEach((paragraph, paragraphIndex) => {
3463
+ for (const run of paragraph.runs) {
3464
+ spans.push({ start: offset, end: offset + run.text.length, style: run.style });
3465
+ offset += run.text.length;
3466
+ }
3467
+ if (paragraphIndex < text.paragraphs.length - 1) offset += 1;
3468
+ });
3469
+ return spans;
3470
+ }
3471
+ function presentationParagraphStarts(text) {
3472
+ const starts = [];
3473
+ let offset = 0;
3474
+ text.paragraphs.forEach((paragraph, index) => {
3475
+ starts.push(offset);
3476
+ offset += paragraph.runs.reduce((sum, run) => sum + run.text.length, 0);
3477
+ if (index < text.paragraphs.length - 1) offset += 1;
3478
+ });
3479
+ return starts;
3480
+ }
3481
+ function styleAtOffset(spans, offset) {
3482
+ const containing = spans.find((span) => offset >= span.start && offset < span.end);
3483
+ if (containing) return containing.style;
3484
+ const before = [...spans].reverse().find((span) => span.end <= offset);
3485
+ return before?.style ?? spans[0]?.style ?? null;
3486
+ }
3487
+ function alignmentAtOffset(text, starts, offset) {
3488
+ let index = 0;
3489
+ while (index + 1 < starts.length && (starts[index + 1] ?? Number.POSITIVE_INFINITY) <= offset) {
3490
+ index += 1;
3491
+ }
3492
+ return text.paragraphs[index]?.alignment ?? "left";
3493
+ }
3494
+ function alignmentForNewOffset(text, starts, diff, newOffset, fallback) {
3495
+ const oldOffset = oldOffsetForNewOffset(diff, newOffset);
3496
+ return oldOffset === null ? fallback : alignmentAtOffset(text, starts, oldOffset);
3497
+ }
3498
+ function samePresentationTextStyle(left, right) {
3499
+ return left.fontFamily === right.fontFamily && left.fontSizeCentipoints === right.fontSizeCentipoints && left.color === right.color && left.bold === right.bold && left.italic === right.italic && left.underline === right.underline && left.language === right.language;
3500
+ }
3501
+ function splitsSurrogate(value, index) {
3502
+ if (index <= 0 || index >= value.length) return false;
3503
+ const left = value.charCodeAt(index - 1);
3504
+ const right = value.charCodeAt(index);
3505
+ return left >= 55296 && left <= 56319 && right >= 56320 && right <= 57343;
3506
+ }
3507
+ function rgbaCss(value) {
3508
+ const hex = (value >>> 0).toString(16).padStart(8, "0");
3509
+ return hex.endsWith("ff") ? `#${hex.slice(0, 6)}` : `#${hex}`;
3510
+ }
3511
+ function bytesToHex(value) {
3512
+ return [...value].map((byte) => byte.toString(16).padStart(2, "0")).join("");
3513
+ }
3514
+ function sceneNodeKey(slideId, nodeId) {
3515
+ return `${slideId}:${nodeId}`;
3516
+ }
3517
+ function isPresentationRevisionDrift(error) {
3518
+ return error.message.includes("changed while") || error.message.includes("revision drifted");
3519
+ }
3520
+ function notifyPresentationCommit(t, observer, onError, commit) {
3521
+ try {
3522
+ const result = observer?.(commit);
3523
+ if (result && typeof result.then === "function") {
3524
+ void Promise.resolve(result).catch(
3525
+ (cause) => onError?.(
3526
+ asEditableArtifactError(
3527
+ cause,
3528
+ t("artifacts.editablePresentation.presentationCommitObserverFailed")
3529
+ )
3530
+ )
3531
+ );
3532
+ }
3533
+ } catch (cause) {
3534
+ onError?.(
3535
+ asEditableArtifactError(
3536
+ cause,
3537
+ t("artifacts.editablePresentation.presentationCommitObserverFailed")
3538
+ )
3539
+ );
3540
+ }
3541
+ }
3542
+
3543
+ export {
3544
+ PresentationEditor,
3545
+ PresentationProjectionEditor,
3546
+ PresentationArtifactSurface,
3547
+ PresentationProjectionArtifactSurface,
3548
+ EditablePresentationArtifactSurface
3549
+ };
3550
+ //# sourceMappingURL=chunk-DXBYWSL5.js.map