@cardstack/boxel-cli 0.13.0-unstable.4 → 0.13.0-unstable.5

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 (1050) hide show
  1. package/bundled-realms/pretui/components/doc-report.gts +2 -2
  2. package/bundled-realms/pretui/components/doc-report.usage.gts +3 -3
  3. package/bundled-realms/pretui/components/form-field.md +1 -1
  4. package/bundled-realms/pretui/components/icon-button.md +1 -1
  5. package/bundled-realms/pretui/components/popup.md +1 -1
  6. package/bundled-realms/pretui/components/switch.gts +13 -0
  7. package/bundled-realms/pretui/components/switch.md +5 -3
  8. package/bundled-realms/pretui/components/theme-frame.gts +49 -22
  9. package/bundled-realms/pretui/components/tooltip.gts +141 -42
  10. package/bundled-realms/pretui/components/tooltip.md +10 -12
  11. package/bundled-realms/pretui/components/tooltip.usage.gts +3 -5
  12. package/bundled-realms/pretui/docs/structure.md +1 -1
  13. package/bundled-realms/pretui/internal/overlay.gts +4 -2
  14. package/bundled-realms/pretui/pretui-css.gts +6 -2
  15. package/bundled-realms/pretui/theme-scoped-css.gts +262 -0
  16. package/bundled-test-harness/assets/account-switch-failed-test-DwAZq6Sc.js +45 -0
  17. package/bundled-test-harness/assets/adapter-C_6pnsx1.js +2 -0
  18. package/bundled-test-harness/assets/add-field-to-card-definition-tool-test-zMYtJWBv.js +112 -0
  19. package/bundled-test-harness/assets/ai-assistant-create-workspace-test-CwhAV-Ow.js +130 -0
  20. package/bundled-test-harness/assets/ai-assistant-panel-relogin-test-DNgclkGJ.js +46 -0
  21. package/bundled-test-harness/assets/ai-assistant-test-DGYFiRTb.js +2223 -0
  22. package/bundled-test-harness/assets/ai-function-generation-test-Dj6WzKkh.js +1176 -0
  23. package/bundled-test-harness/assets/ai-module-creation-test-EsOoJpQ1.js +151 -0
  24. package/bundled-test-harness/assets/aibot-message-uGaCPn5o.js +1312 -0
  25. package/bundled-test-harness/assets/app-pIzBYfiZ.js +14146 -0
  26. package/bundled-test-harness/assets/apply-markdown-edit-test-CPhfeg1i.js +230 -0
  27. package/bundled-test-harness/assets/ask-user-picker-NVRkhKwt.js +370 -0
  28. package/bundled-test-harness/assets/ask-user-picker-test-SsZqFm9W.js +39 -0
  29. package/bundled-test-harness/assets/assistant-transcript-test-DesuBCIB.js +57 -0
  30. package/bundled-test-harness/assets/audio-metadata-extractor-test-8JM6oZXG.js +1176 -0
  31. package/bundled-test-harness/assets/authed-fetch-test-yPTMe-9V.js +73 -0
  32. package/bundled-test-harness/assets/avif-image-def-test-Kyknj908.js +187 -0
  33. package/bundled-test-harness/assets/basic-test-D9OrrMaq.js +139 -0
  34. package/bundled-test-harness/assets/binary-upload-dedupe-test-Dnxlbbu6.js +308 -0
  35. package/bundled-test-harness/assets/bot-registration-test-Bk2lTaCW.js +97 -0
  36. package/bundled-test-harness/assets/box-test-BbV9sMyU.js +50 -0
  37. package/bundled-test-harness/assets/brand-guide-attachments-test-z4wTsKbI.js +84 -0
  38. package/bundled-test-harness/assets/brand-guide-custom-css-test-BlSJE8xo.js +196 -0
  39. package/bundled-test-harness/assets/brand-guide-edit-test-DJ1OQ6IB.js +140 -0
  40. package/bundled-test-harness/assets/brand-logo-mark-field-test-ux7eetkO.js +86 -0
  41. package/bundled-test-harness/assets/broken-link-template-test-CqB3MWyw.js +192 -0
  42. package/bundled-test-harness/assets/bundled-base-modules-test-B2oNLZSJ.js +54 -0
  43. package/bundled-test-harness/assets/bundled-base-oracle-test-DelPfFjn.js +37 -0
  44. package/bundled-test-harness/assets/buried-stack-item-scroll-test-Ixsl1tS0.js +236 -0
  45. package/bundled-test-harness/assets/button-BvYQm_A1.js +141 -0
  46. package/bundled-test-harness/assets/bxl-cyclic-graph-test-p23WCLRW.js +47 -0
  47. package/bundled-test-harness/assets/bxl-expression-test-CVTQYT_C.js +250 -0
  48. package/bundled-test-harness/assets/bxl-indexing-test-D_A7X2sr.js +212 -0
  49. package/bundled-test-harness/assets/bxl-platform-module-test-Cltfyybp.js +71 -0
  50. package/bundled-test-harness/assets/can-invoke-test-DJi7jMaU.js +455 -0
  51. package/bundled-test-harness/assets/can-read-realm-test-CIz6WX_K.js +56 -0
  52. package/bundled-test-harness/assets/cancel-indexing-job-test-0LlrOgYK.js +69 -0
  53. package/bundled-test-harness/assets/capture-test-diHIWmh0.js +360 -0
  54. package/bundled-test-harness/assets/card-api-test-Ci9b0ghP.js +198 -0
  55. package/bundled-test-harness/assets/card-basics-test-RKQoQWZD.js +5364 -0
  56. package/bundled-test-harness/assets/card-chooser-paging-test-BoUyFMEw.js +235 -0
  57. package/bundled-test-harness/assets/card-chooser-test-7ZwhxxkH.js +393 -0
  58. package/bundled-test-harness/assets/card-context-search-results-KmkXJbmC.js +30 -0
  59. package/bundled-test-harness/assets/card-context-search-results-test-CpMr8OlX.js +184 -0
  60. package/bundled-test-harness/assets/card-def-field-def-relationships-test-ByPl5n55.js +562 -0
  61. package/bundled-test-harness/assets/card-def-menu-items-test-ohuHc0b4.js +228 -0
  62. package/bundled-test-harness/assets/card-delete-test-Be971b-V.js +466 -0
  63. package/bundled-test-harness/assets/card-error-3q1o3i0e.js +72 -0
  64. package/bundled-test-harness/assets/card-error-awaiting-index-test-DPgYKfbF.js +53 -0
  65. package/bundled-test-harness/assets/card-info-thumbnail-picker-test-CVfeJyjt.js +219 -0
  66. package/bundled-test-harness/assets/card-playground-test-D-7bi4PQ.js +1491 -0
  67. package/bundled-test-harness/assets/card-prerender-DemTfK_a.js +12939 -0
  68. package/bundled-test-harness/assets/card-thunk-error-test-DCBh1vRT.js +48 -0
  69. package/bundled-test-harness/assets/card-type-service-test-DXPrfVYk.js +161 -0
  70. package/bundled-test-harness/assets/check-correctness-test-DjE7r1X2.js +1093 -0
  71. package/bundled-test-harness/assets/check-domain-availability-test-U10xSKbY.js +98 -0
  72. package/bundled-test-harness/assets/chip-0r_r9SC8.js +44 -0
  73. package/bundled-test-harness/assets/choreo-Ci5dG5fv.js +2 -0
  74. package/bundled-test-harness/assets/choreo-D1K9RyjM.js +1031 -0
  75. package/bundled-test-harness/assets/choreo-feature-reel-test-vzmW-SFd.js +155 -0
  76. package/bundled-test-harness/assets/choreo-gallery-build-order-test-J6n0_PKm.js +436 -0
  77. package/bundled-test-harness/assets/choreo-gallery-compositor-test-DSi1N9bi.js +399 -0
  78. package/bundled-test-harness/assets/choreo-gallery-cover-test-BT05gNKC.js +214 -0
  79. package/bundled-test-harness/assets/choreo-gallery-crossing-stage-test-BIuLOZH6.js +133 -0
  80. package/bundled-test-harness/assets/choreo-gallery-demos-alive-test-ClGjpnj6.js +42 -0
  81. package/bundled-test-harness/assets/choreo-gallery-drift-test-OjxMXV0Y.js +620 -0
  82. package/bundled-test-harness/assets/choreo-gallery-escort-test-D6VL4FfT.js +187 -0
  83. package/bundled-test-harness/assets/choreo-gallery-films-test-DBcDHGx8.js +140 -0
  84. package/bundled-test-harness/assets/choreo-gallery-filter-test-BUghtJZe.js +46 -0
  85. package/bundled-test-harness/assets/choreo-gallery-fold-test-0D9-_h_I.js +180 -0
  86. package/bundled-test-harness/assets/choreo-gallery-guide-pages-test-DS41eNNV.js +114 -0
  87. package/bundled-test-harness/assets/choreo-gallery-guides-test-CZnaxUNJ.js +321 -0
  88. package/bundled-test-harness/assets/choreo-gallery-hang-test-WFvsJ-MJ.js +426 -0
  89. package/bundled-test-harness/assets/choreo-gallery-highlight-test-Dn0hYPLC.js +60 -0
  90. package/bundled-test-harness/assets/choreo-gallery-inline-edit-test-C5WvS67s.js +370 -0
  91. package/bundled-test-harness/assets/choreo-gallery-interruption-test-CgT9RKTe.js +176 -0
  92. package/bundled-test-harness/assets/choreo-gallery-lone-stack-test-BZgqbTJd.js +104 -0
  93. package/bundled-test-harness/assets/choreo-gallery-navigation-test-CWzXkvbW.js +193 -0
  94. package/bundled-test-harness/assets/choreo-gallery-playhead-transport-test-Dt71t4CU.js +111 -0
  95. package/bundled-test-harness/assets/choreo-gallery-poplayout-subtree-test-B_rDq4em.js +127 -0
  96. package/bundled-test-harness/assets/choreo-gallery-presence-modes-test-j_cZ9cAM.js +100 -0
  97. package/bundled-test-harness/assets/choreo-gallery-presentation-test-CIFKR65J.js +157 -0
  98. package/bundled-test-harness/assets/choreo-gallery-reduced-motion-test-BvRCiCvB.js +145 -0
  99. package/bundled-test-harness/assets/choreo-gallery-sheet-standalone-test-DgO2MBzU.js +89 -0
  100. package/bundled-test-harness/assets/choreo-gallery-sheet-test-BntUKT_P.js +48 -0
  101. package/bundled-test-harness/assets/choreo-gallery-site-test-CvSE6Jyq.js +237 -0
  102. package/bundled-test-harness/assets/choreo-gallery-stage-Dj6tFzon.js +256 -0
  103. package/bundled-test-harness/assets/choreo-gallery-stage-keyboard-test-CkDrAPA8.js +102 -0
  104. package/bundled-test-harness/assets/choreo-gallery-stages-test-DHUmzoRW.js +35 -0
  105. package/bundled-test-harness/assets/choreo-gallery-subdivision-test-BZ9-cDFh.js +138 -0
  106. package/bundled-test-harness/assets/choreo-gallery-table-plan-test-7uP6mZpo.js +144 -0
  107. package/bundled-test-harness/assets/choreo-gallery-theater-test-DgEue9FD.js +252 -0
  108. package/bundled-test-harness/assets/choreo-gallery-tuning-test-CfPx5iCp.js +95 -0
  109. package/bundled-test-harness/assets/choreo-gallery-widget-room-test-o9T2EFKq.js +88 -0
  110. package/bundled-test-harness/assets/choreo-gallery-wires-test-73JLkxn6.js +148 -0
  111. package/bundled-test-harness/assets/client-telemetry-test-DFM4mML2.js +340 -0
  112. package/bundled-test-harness/assets/clip-CsRtHZiN.js +92 -0
  113. package/bundled-test-harness/assets/clip-CycGr0Lf.js +2 -0
  114. package/bundled-test-harness/assets/code-block-DRE8KQZQ.js +502 -0
  115. package/bundled-test-harness/assets/code-ref-test-CDcqE8_C.js +163 -0
  116. package/bundled-test-harness/assets/code-submode-availability-test-DPTqZYYm.js +198 -0
  117. package/bundled-test-harness/assets/code-submode-test-AHV4mzJ4.js +1839 -0
  118. package/bundled-test-harness/assets/codeblocks-test-D9pbJMK8.js +418 -0
  119. package/bundled-test-harness/assets/codemirror-editor-test-BeAMVivu.js +1512 -0
  120. package/bundled-test-harness/assets/codemirror-embed-toolbar-test-Bnb7_KUT.js +366 -0
  121. package/bundled-test-harness/assets/color-field-test-CR6gGEqE.js +212 -0
  122. package/bundled-test-harness/assets/compaction-test-BSqAGv4g.js +150 -0
  123. package/bundled-test-harness/assets/computed-test-DtyZGgdc.js +1320 -0
  124. package/bundled-test-harness/assets/container-CEslVSTe.js +10884 -0
  125. package/bundled-test-harness/assets/content-preview-components-test-BztI4fz-.js +462 -0
  126. package/bundled-test-harness/assets/copy-and-edit-test-Cqw7kcur.js +292 -0
  127. package/bundled-test-harness/assets/copy-card-test-D5m3eVEH.js +218 -0
  128. package/bundled-test-harness/assets/copy-file-to-realm-test-FPY-6Ddm.js +148 -0
  129. package/bundled-test-harness/assets/copy-source-test-9pJD-qey.js +56 -0
  130. package/bundled-test-harness/assets/create-file-test-DjMf88u_.js +1086 -0
  131. package/bundled-test-harness/assets/create-file-test-XbgOqg38.js +464 -0
  132. package/bundled-test-harness/assets/create-listing-modal-test-DyGlGMWu.js +273 -0
  133. package/bundled-test-harness/assets/create-listing-pr-request-test-CBtIV0Z8.js +117 -0
  134. package/bundled-test-harness/assets/create-spec-test-4xR0gM7E.js +256 -0
  135. package/bundled-test-harness/assets/create-submission-workflow-test-DQpWrpGT.js +132 -0
  136. package/bundled-test-harness/assets/create-workspace-test-BQAudgpS.js +104 -0
  137. package/bundled-test-harness/assets/credential-fields-test-DXKBdbZD.js +200 -0
  138. package/bundled-test-harness/assets/csv-file-def-test-Cnp4y834.js +102 -0
  139. package/bundled-test-harness/assets/dashboard-CmuOhIYC.js +3628 -0
  140. package/bundled-test-harness/assets/dashboard-CzN49x74.css +2400 -0
  141. package/bundled-test-harness/assets/dashboard-add-workspace-test-T32hWB-g.js +50 -0
  142. package/bundled-test-harness/assets/dashboard-agents-test-BN5maCgQ.js +334 -0
  143. package/bundled-test-harness/assets/dashboard-archive-test-BzwUte_Z.js +128 -0
  144. package/bundled-test-harness/assets/dashboard-delete-test-D2Gcp81V.js +163 -0
  145. package/bundled-test-harness/assets/dashboard-duplicate-offer-test-BgKNIr35.js +71 -0
  146. package/bundled-test-harness/assets/dashboard-duplicate-test-D7JEWylc.js +222 -0
  147. package/bundled-test-harness/assets/dashboard-get-started-test-DOGPzGoA.js +374 -0
  148. package/bundled-test-harness/assets/dashboard-ir2bakJS.js +142 -0
  149. package/bundled-test-harness/assets/dashboard-pinned-cards-test-Bn_P9xJU.js +220 -0
  150. package/bundled-test-harness/assets/dashboard-publish-test-64sGQ0nG.js +70 -0
  151. package/bundled-test-harness/assets/dashboard-reindex-test-DJjYq1ct.js +115 -0
  152. package/bundled-test-harness/assets/dashboard-section-rail-test-ZkAhWu5V.js +169 -0
  153. package/bundled-test-harness/assets/dashboard-state-test-BbkpPB5L.js +162 -0
  154. package/bundled-test-harness/assets/dashboard-test-CBLdPrSt.js +545 -0
  155. package/bundled-test-harness/assets/dashboard-unreachable-notice-test-DFT3R1Zx.js +62 -0
  156. package/bundled-test-harness/assets/dashboard-workspace-test-DqBdCFo2.js +537 -0
  157. package/bundled-test-harness/assets/dashboard-workspaces-section-test-CH1HDfxR.js +410 -0
  158. package/bundled-test-harness/assets/data-file-def-preview-test-CNsZwQEJ.js +155 -0
  159. package/bundled-test-harness/assets/date-time-fields-test-CEFaZTnF.js +359 -0
  160. package/bundled-test-harness/assets/debug-message-test-0hv0RwE_.js +117 -0
  161. package/bundled-test-harness/assets/declared-captures-test-C-0yPRU7.js +879 -0
  162. package/bundled-test-harness/assets/delete-workspace-test-CZOwGy78.js +102 -0
  163. package/bundled-test-harness/assets/diffing-test-BEKI905O.js +210 -0
  164. package/bundled-test-harness/assets/download-file-to-realm-test-C1kAGDll.js +119 -0
  165. package/bundled-test-harness/assets/editor-test-C9x5ZY6g.js +688 -0
  166. package/bundled-test-harness/assets/edits-D76-aanh.js +651 -0
  167. package/bundled-test-harness/assets/email-field-test-LGkrB_2B.js +75 -0
  168. package/bundled-test-harness/assets/enum-field-test-CPyV1J-m.js +935 -0
  169. package/bundled-test-harness/assets/error-display-test-bWuUtfIG.js +343 -0
  170. package/bundled-test-harness/assets/evaluate-module-test-CbS5h8t3.js +91 -0
  171. package/bundled-test-harness/assets/execute-atomic-operations-test-B4Kfco0k.js +113 -0
  172. package/bundled-test-harness/assets/externals-CDQm-Lm7.js +4393 -0
  173. package/bundled-test-harness/assets/fallback-banner-live-delete-test-DQSiTzvj.js +207 -0
  174. package/bundled-test-harness/assets/fallback-banner-test-CJFKLpOy.js +225 -0
  175. package/bundled-test-harness/assets/fallback-banner-test-DQkrFE4-.js +53 -0
  176. package/bundled-test-harness/assets/fallback-models-test-CiWfmxaB.js +161 -0
  177. package/bundled-test-harness/assets/fetch-card-json-test-DULUqUEu.js +61 -0
  178. package/bundled-test-harness/assets/field-configuration-test-BXZq28xa.js +551 -0
  179. package/bundled-test-harness/assets/field-markdown-domain-test-DdXCifs6.js +616 -0
  180. package/bundled-test-harness/assets/field-markdown-oversize-test-DouPPTHX.js +88 -0
  181. package/bundled-test-harness/assets/field-markdown-primitives-test-DSRGJeyl.js +365 -0
  182. package/bundled-test-harness/assets/field-markdown-specialized-test-DlTYLl_s.js +534 -0
  183. package/bundled-test-harness/assets/field-playground-test-NhS4VvoN.js +894 -0
  184. package/bundled-test-harness/assets/field-support-predicates-test-DWpyT1Qf.js +167 -0
  185. package/bundled-test-harness/assets/file-attachment-test-m72-VerW.js +796 -0
  186. package/bundled-test-harness/assets/file-chooser-panel-test-DuAqD9bn.js +153 -0
  187. package/bundled-test-harness/assets/file-chooser-test-CjaXXwpT.js +504 -0
  188. package/bundled-test-harness/assets/file-def-format-templates-test-BDs4OmHq.js +380 -0
  189. package/bundled-test-harness/assets/file-def-live-reload-test-BqTdnq-W.js +124 -0
  190. package/bundled-test-harness/assets/file-def-menu-items-test-DqdINXsD.js +138 -0
  191. package/bundled-test-harness/assets/file-def-navigation-test-BPGr0SQy.js +109 -0
  192. package/bundled-test-harness/assets/file-def-serialization-test-CvjW-FlC.js +89 -0
  193. package/bundled-test-harness/assets/file-def-test-C-Yv_NjS.js +216 -0
  194. package/bundled-test-harness/assets/file-preview-live-reload-test-MzwGwasU.js +310 -0
  195. package/bundled-test-harness/assets/file-resource-primitives-test-D3GmfqNs.js +255 -0
  196. package/bundled-test-harness/assets/file-tree-from-index-test-CfldnUgm.js +96 -0
  197. package/bundled-test-harness/assets/file-tree-test--0ZCPRe9.js +851 -0
  198. package/bundled-test-harness/assets/file-view-model-test-BDIAeBV8.js +346 -0
  199. package/bundled-test-harness/assets/filedef-export-shape-test-B2tgU404.js +61 -0
  200. package/bundled-test-harness/assets/film-D1E-odYG.js +13 -0
  201. package/bundled-test-harness/assets/film-D25Y0ED6.js +2 -0
  202. package/bundled-test-harness/assets/film-D97U-ydx.js +4074 -0
  203. package/bundled-test-harness/assets/flac-audio-def-test-ByoXMoQ1.js +143 -0
  204. package/bundled-test-harness/assets/font-metadata-extractor-test-hawLTDTG.js +415 -0
  205. package/bundled-test-harness/assets/formatted-aibot-message-test-Bdx_-Ktn.js +109 -0
  206. package/bundled-test-harness/assets/formatted-user-message-test-CodbrU3t.js +43 -0
  207. package/bundled-test-harness/assets/freestyle-test-faQhSciz.js +17 -0
  208. package/bundled-test-harness/assets/full-reindex-realm-test-CE5RJTIC.js +101 -0
  209. package/bundled-test-harness/assets/garbage-collection-test-v-3sev77.js +403 -0
  210. package/bundled-test-harness/assets/general-test-DQuxDvXK.js +923 -0
  211. package/bundled-test-harness/assets/generate-example-cards-one-shot-test-CucWyrkH.js +65 -0
  212. package/bundled-test-harness/assets/generic-file-def-preview-test-_EDRsebi.js +71 -0
  213. package/bundled-test-harness/assets/get-available-realm-identifiers-test-CV023yek.js +47 -0
  214. package/bundled-test-harness/assets/get-catalog-realm-identifiers-test--DOu3DyV.js +47 -0
  215. package/bundled-test-harness/assets/get-default-writable-realm-test-Bic8jl6R.js +54 -0
  216. package/bundled-test-harness/assets/get-published-realms-test-DrA5YcFN.js +71 -0
  217. package/bundled-test-harness/assets/get-realm-of-resource-identifier-test-jfU6SIWn.js +54 -0
  218. package/bundled-test-harness/assets/get-relationship-membership-state-test-Ccy2Z7MN.js +1308 -0
  219. package/bundled-test-harness/assets/get-user-system-card-test-Bmq2lmWv.js +67 -0
  220. package/bundled-test-harness/assets/gif-image-def-test-N1mMQC-X.js +188 -0
  221. package/bundled-test-harness/assets/glimmer-motion-and-choreo-in-cards-test-DzPKH76g.js +160 -0
  222. package/bundled-test-harness/assets/glimmer-motion-and-choreo-test-D9mlcQuN.js +74 -0
  223. package/bundled-test-harness/assets/gts-file-def-test-BL1jpQ9J.js +100 -0
  224. package/bundled-test-harness/assets/head-format-preview-test-BVCaPQqc.js +158 -0
  225. package/bundled-test-harness/assets/helpers-Ds68JxHe.js +5 -0
  226. package/bundled-test-harness/assets/host-mode-service-B4bisRdR.js +262 -0
  227. package/bundled-test-harness/assets/host-mode-test-BmkN2PCJ.js +831 -0
  228. package/bundled-test-harness/assets/host-submode-test-C6SxQ796.js +1392 -0
  229. package/bundled-test-harness/assets/html-component-test-CNQ9wF0Q.js +65 -0
  230. package/bundled-test-harness/assets/html-def-test-BcaCVVQq.js +160 -0
  231. package/bundled-test-harness/assets/html-meta-extractor-test-BU1hjkTp.js +60 -0
  232. package/bundled-test-harness/assets/hydratable-card-test-CX6MWiti.js +426 -0
  233. package/bundled-test-harness/assets/icon-button-C1zH38Nc.js +67 -0
  234. package/bundled-test-harness/assets/image-metadata-extractor-test-CakSBPZ_.js +1109 -0
  235. package/bundled-test-harness/assets/index-changes-test-D8RtgfyG.js +367 -0
  236. package/bundled-test-harness/assets/index-query-engine-test-BOvxkx07.js +2593 -0
  237. package/bundled-test-harness/assets/index-writer-test-B_bR2fjw.js +3040 -0
  238. package/bundled-test-harness/assets/inspector-test-BwPXJj1S.js +2058 -0
  239. package/bundled-test-harness/assets/instance-filter-matcher-test-COAlkUed.js +788 -0
  240. package/bundled-test-harness/assets/instantiate-card-test-BVQhZjpq.js +164 -0
  241. package/bundled-test-harness/assets/interact-submode-creation-and-permissions-test-DzQLG41H.js +475 -0
  242. package/bundled-test-harness/assets/interact-submode-setup-C5bKXq73.js +566 -0
  243. package/bundled-test-harness/assets/invalidate-realm-identifiers-test-Cd3dpjhB.js +99 -0
  244. package/bundled-test-harness/assets/invite-user-to-room-test-Brabz1tt.js +142 -0
  245. package/bundled-test-harness/assets/invoke-card-operation-test-C1Q1FUf4.js +333 -0
  246. package/bundled-test-harness/assets/isolated-render-test-BLJfS7BU.js +51 -0
  247. package/bundled-test-harness/assets/job-scoped-doc-cache-test-Bgv5woaB.js +181 -0
  248. package/bundled-test-harness/assets/job-scoped-instance-residency-test-C_bB6KpR.js +103 -0
  249. package/bundled-test-harness/assets/jpg-image-def-test-gdLIKocD.js +697 -0
  250. package/bundled-test-harness/assets/json-file-def-test-CPYMRBY-.js +95 -0
  251. package/bundled-test-harness/assets/key-notices-badge-test-DemslfLw.js +155 -0
  252. package/bundled-test-harness/assets/key-readiness-test-5tq5JycL.js +190 -0
  253. package/bundled-test-harness/assets/linksto-broken-link-placeholder-test-BbhDZ2PH.js +398 -0
  254. package/bundled-test-harness/assets/linksto-error-sentinel-test-C2t7fFPi.js +238 -0
  255. package/bundled-test-harness/assets/linksto-many-broken-link-placeholder-test--U_UvUty.js +354 -0
  256. package/bundled-test-harness/assets/linksto-many-per-slot-access-test-Dj3Xy0ZF.js +303 -0
  257. package/bundled-test-harness/assets/linksto-sentinel-reload-test-D0dK4Jjs.js +197 -0
  258. package/bundled-test-harness/assets/linksto-sentinel-roundtrip-test---IYiXok.js +260 -0
  259. package/bundled-test-harness/assets/linksto-singular-js-access-contract-test-CT04MhES.js +196 -0
  260. package/bundled-test-harness/assets/lint-and-fix-test-aadgx7rX.js +51 -0
  261. package/bundled-test-harness/assets/live-test-BGij_vuc.js +100 -0
  262. package/bundled-test-harness/assets/live-test-CppvValf.js +2 -0
  263. package/bundled-test-harness/assets/load-default-skills-test-Cp2m_ebp.js +74 -0
  264. package/bundled-test-harness/assets/loader-parallel-prefetch-test-vU_26Jqu.js +257 -0
  265. package/bundled-test-harness/assets/loader-test-CTaw8K_B.js +482 -0
  266. package/bundled-test-harness/assets/loading-test-DGGt4qZZ.js +63 -0
  267. package/bundled-test-harness/assets/m4a-audio-def-test-DAiReOXH.js +190 -0
  268. package/bundled-test-harness/assets/main-DUKPWRts.js +5 -0
  269. package/bundled-test-harness/assets/markdown-embed-chooser-modal-test-CIXq9FqR.js +470 -0
  270. package/bundled-test-harness/assets/markdown-embed-chooser-test-zFGh9WfP.js +334 -0
  271. package/bundled-test-harness/assets/markdown-embed-preview-pane-test-Byn_WFwY.js +447 -0
  272. package/bundled-test-harness/assets/markdown-embed-preview-test-Y3iFMttg.js +368 -0
  273. package/bundled-test-harness/assets/markdown-fallback-test-Br1TPkLZ.js +316 -0
  274. package/bundled-test-harness/assets/markdown-file-def-test-Crm2MAnq.js +380 -0
  275. package/bundled-test-harness/assets/markdown-helpers-test-CZ9Vvywc.js +188 -0
  276. package/bundled-test-harness/assets/markdown-highlighting-test-CFMkoVDl.js +244 -0
  277. package/bundled-test-harness/assets/markdown-preview-Df5fp1SY.js +72 -0
  278. package/bundled-test-harness/assets/markdown-preview-test-DDaPzsVs.js +238 -0
  279. package/bundled-test-harness/assets/markdown-skill-frontmatter-test-aH6HQly1.js +146 -0
  280. package/bundled-test-harness/assets/markdown-skill-search-test-CiNLQs-5.js +80 -0
  281. package/bundled-test-harness/assets/matrix-service-account-switch-sessions-test-DaA8w1Jj.js +63 -0
  282. package/bundled-test-harness/assets/matrix-service-boot-assembly-test-21GIlf55.js +300 -0
  283. package/bundled-test-harness/assets/matrix-service-personal-realm-test-jn9DUENm.js +125 -0
  284. package/bundled-test-harness/assets/matrix-service-realm-servers-test-eNZVJakl.js +55 -0
  285. package/bundled-test-harness/assets/matrix-service-realms-list-updated-test-Cabm8_dY.js +132 -0
  286. package/bundled-test-harness/assets/matrix-service-relogin-test-C77EFgjc.js +59 -0
  287. package/bundled-test-harness/assets/matrix-service-sliding-sync-test-BgM0fPiO.js +35 -0
  288. package/bundled-test-harness/assets/menu-Cl50TSFe.js +3561 -0
  289. package/bundled-test-harness/assets/message-service-subscription-test-CfEqH2jP.js +110 -0
  290. package/bundled-test-harness/assets/message-service-test-DsTzH1In.js +144 -0
  291. package/bundled-test-harness/assets/message-tool-test-C5xVfTtj.js +33 -0
  292. package/bundled-test-harness/assets/midi-audio-def-test-goLRCNCZ.js +182 -0
  293. package/bundled-test-harness/assets/migrate-skill-test-yPCbVfxG.js +161 -0
  294. package/bundled-test-harness/assets/mini-YXjrY_tH.js +1404 -0
  295. package/bundled-test-harness/assets/mini-card-chooser-test-DrllikHB.js +272 -0
  296. package/bundled-test-harness/assets/mini-file-chooser-test-BfqayhmI.js +201 -0
  297. package/bundled-test-harness/assets/mock-matrix-C7BrPS6S.js +2 -0
  298. package/bundled-test-harness/assets/mock-matrix-FjsXmU7-.js +15107 -0
  299. package/bundled-test-harness/assets/modal-BgaZavcs.js +322 -0
  300. package/bundled-test-harness/assets/model-cost-tier-test-CZlu1zww.js +174 -0
  301. package/bundled-test-harness/assets/model-file-extract-test-CjEBupY5.js +206 -0
  302. package/bundled-test-harness/assets/module-transpile-cache-test-XW6DDsmz.js +67 -0
  303. package/bundled-test-harness/assets/monaco-test-DkoRuFiQ.js +100 -0
  304. package/bundled-test-harness/assets/mp3-audio-def-test-v369NNsQ.js +133 -0
  305. package/bundled-test-harness/assets/multiple-stacks-test-CJpYPWdM.js +208 -0
  306. package/bundled-test-harness/assets/nested-query-field-render-test-CfDrBcUN.js +249 -0
  307. package/bundled-test-harness/assets/no-stacks-test-MmsJeLpz.js +48 -0
  308. package/bundled-test-harness/assets/number-field-test-A7B2r0M5.js +184 -0
  309. package/bundled-test-harness/assets/office-file-def-test-BNRvFmCB.js +263 -0
  310. package/bundled-test-harness/assets/office-metadata-extractor-test-zlDoEIEp.js +218 -0
  311. package/bundled-test-harness/assets/office-poster-capture-test-DdFEaOxR.js +203 -0
  312. package/bundled-test-harness/assets/ogg-audio-def-test-kk91BzQY.js +196 -0
  313. package/bundled-test-harness/assets/open-create-listing-modal-test-D1Dl1pov.js +131 -0
  314. package/bundled-test-harness/assets/open-image-in-new-tab-test-DyCmdMyO.js +52 -0
  315. package/bundled-test-harness/assets/open-secure-window-test-dz1vPudF.js +253 -0
  316. package/bundled-test-harness/assets/open-workspace-test-BvTcskzP.js +46 -0
  317. package/bundled-test-harness/assets/operation-lowering-test-CKkamOQt.js +2957 -0
  318. package/bundled-test-harness/assets/operations-invocation-test-BMj42rQe.js +523 -0
  319. package/bundled-test-harness/assets/operations-optimistic-test-KJLyzT8v.js +203 -0
  320. package/bundled-test-harness/assets/operations-query-test-J3HcnaoK.js +459 -0
  321. package/bundled-test-harness/assets/operations-store-reconciliation-test-CkbGBMBQ.js +406 -0
  322. package/bundled-test-harness/assets/operations-test-C7zXXpRW.js +2518 -0
  323. package/bundled-test-harness/assets/operator-mode-acceptance-test-BPolI_RD.js +1195 -0
  324. package/bundled-test-harness/assets/operator-mode-card-chooser-test-CQ1v8med.js +1036 -0
  325. package/bundled-test-harness/assets/operator-mode-links-test-BMHEauS3.js +797 -0
  326. package/bundled-test-harness/assets/operator-mode-test-blL_JVF8.js +696 -0
  327. package/bundled-test-harness/assets/operator-mode-ui-test-BG6I7-Hc.js +1045 -0
  328. package/bundled-test-harness/assets/overlay-D2rQi8lJ.js +427 -0
  329. package/bundled-test-harness/assets/overlay-menu-items-test-D-zmRQQ0.js +331 -0
  330. package/bundled-test-harness/assets/overlays-COinwHCP.js +2 -0
  331. package/bundled-test-harness/assets/overlays-detached-element-test-C73nMXes.js +56 -0
  332. package/bundled-test-harness/assets/overlays-nTqcu69K.js +75 -0
  333. package/bundled-test-harness/assets/panel-D9SEMehG.js +15124 -0
  334. package/bundled-test-harness/assets/past-sessions-test-De9N4wVX.js +321 -0
  335. package/bundled-test-harness/assets/patch-fields-test-Bp2IE0Jw.js +1014 -0
  336. package/bundled-test-harness/assets/patch-instance-test-DssuRGKP.js +348 -0
  337. package/bundled-test-harness/assets/pdf-file-def-test-Barj9ffD.js +111 -0
  338. package/bundled-test-harness/assets/pdf-metadata-extractor-test-B7KnXcIm.js +130 -0
  339. package/bundled-test-harness/assets/permission-checking-realm-test-OBzvhDB_.js +306 -0
  340. package/bundled-test-harness/assets/persist-module-inspector-view-test-BIdbkdPr.js +60 -0
  341. package/bundled-test-harness/assets/persist-scroll-position-test-Bhb7wJiy.js +254 -0
  342. package/bundled-test-harness/assets/phone-number-field-test-C2yuCrXY.js +73 -0
  343. package/bundled-test-harness/assets/pill-menu-test-BIp91YXi.js +60 -0
  344. package/bundled-test-harness/assets/plate-DAr_pvwC.js +41 -0
  345. package/bundled-test-harness/assets/plate-DeoQd99m.js +2 -0
  346. package/bundled-test-harness/assets/player-BvXGBItd.js +2 -0
  347. package/bundled-test-harness/assets/player-CAVQUyKk.js +82 -0
  348. package/bundled-test-harness/assets/playground-B02e8uqB.js +58 -0
  349. package/bundled-test-harness/assets/plural-field-components-test-C1acuN-A.js +198 -0
  350. package/bundled-test-harness/assets/png-image-def-test-B9QeVo1f.js +266 -0
  351. package/bundled-test-harness/assets/policy-audit-confirmation-test-CeVquvc_.js +155 -0
  352. package/bundled-test-harness/assets/policy-scoped-search-test-SFPiIqR3.js +339 -0
  353. package/bundled-test-harness/assets/prerender-file-extract-test-HSJKAHyO.js +346 -0
  354. package/bundled-test-harness/assets/prerender-html-test-BTAcFCme.js +670 -0
  355. package/bundled-test-harness/assets/prerender-meta-test-Csyz2b21.js +614 -0
  356. package/bundled-test-harness/assets/prerender-module-test-DpTYAbmI.js +409 -0
  357. package/bundled-test-harness/assets/prerender-persistence-block-test-BhIt-7kK.js +124 -0
  358. package/bundled-test-harness/assets/prerender-pre-model-error-test-DxKPQKqx.js +61 -0
  359. package/bundled-test-harness/assets/prerender-serialize-cycle-test-C8V5YWQO.js +134 -0
  360. package/bundled-test-harness/assets/prerendered-html-read-test-Cq7JVGwg.js +191 -0
  361. package/bundled-test-harness/assets/pretui-components-test-Ducr9fLT.css +743 -0
  362. package/bundled-test-harness/assets/pretui-components-test-Hs0uyIUQ.js +992 -0
  363. package/bundled-test-harness/assets/pretui-primitives-CRs8NRm0.js +69 -0
  364. package/bundled-test-harness/assets/preview-format-test-cCqLrfdY.js +103 -0
  365. package/bundled-test-harness/assets/preview-test-BMqJSoR1.js +474 -0
  366. package/bundled-test-harness/assets/process-card-test-578tfDvr.js +94 -0
  367. package/bundled-test-harness/assets/profile-settings-modal-CVnNl7Yu.js +990 -0
  368. package/bundled-test-harness/assets/publish-realm-COoeWexp.js +82 -0
  369. package/bundled-test-harness/assets/publish-realm-test-a5nkx0Ov.js +210 -0
  370. package/bundled-test-harness/assets/query-field-barrier-test-qX3xVPfk.js +113 -0
  371. package/bundled-test-harness/assets/query-field-error-sentinel-test-V6JDPFLX.js +201 -0
  372. package/bundled-test-harness/assets/query-field-membership-status-test-CK7eDf-K.js +323 -0
  373. package/bundled-test-harness/assets/query-field-page-optin-test-B5YBHUvU.js +126 -0
  374. package/bundled-test-harness/assets/query-field-schema-test-D4SjOGlK.js +231 -0
  375. package/bundled-test-harness/assets/query-field-search-throttle-test-BVkm1-D8.js +154 -0
  376. package/bundled-test-harness/assets/query-field-stale-prerender-test-9g7hcD91.js +152 -0
  377. package/bundled-test-harness/assets/query-fields-test-CQYqhzpN.js +535 -0
  378. package/bundled-test-harness/assets/quick-look-test-icQwb1NJ.js +139 -0
  379. package/bundled-test-harness/assets/read-card-for-ai-assistant-test-D0mJorwH.js +91 -0
  380. package/bundled-test-harness/assets/read-file-for-ai-assistant-test-B_F_2GEB.js +45 -0
  381. package/bundled-test-harness/assets/read-source-test-BgJV4B4F.js +67 -0
  382. package/bundled-test-harness/assets/read-text-file-test-DaeLzg4u.js +124 -0
  383. package/bundled-test-harness/assets/realm-C_a9su1j.js +2858 -0
  384. package/bundled-test-harness/assets/realm-api-keys-D5USFOoS.js +2 -0
  385. package/bundled-test-harness/assets/realm-api-keys-m_VOcixC.js +578 -0
  386. package/bundled-test-harness/assets/realm-api-keys-test-C_uZnTmq.js +588 -0
  387. package/bundled-test-harness/assets/realm-api-keys-test-gtJ8XZCE.js +109 -0
  388. package/bundled-test-harness/assets/realm-config-m5eccPW8.js +833 -0
  389. package/bundled-test-harness/assets/realm-config-policy-standing-test-CXJ4ZMde.js +290 -0
  390. package/bundled-test-harness/assets/realm-config-routing-rule-edit-test-DoEunShH.js +274 -0
  391. package/bundled-test-harness/assets/realm-config-settings-test-BYi9i4O6.js +187 -0
  392. package/bundled-test-harness/assets/realm-field-test-B_PUoqnk.js +100 -0
  393. package/bundled-test-harness/assets/realm-indexing-test-8iLjeV_e.js +4380 -0
  394. package/bundled-test-harness/assets/realm-policy-fitted-test-Bptvra0U.js +206 -0
  395. package/bundled-test-harness/assets/realm-policy-test-DwG0qqXE.js +1141 -0
  396. package/bundled-test-harness/assets/realm-querying-test-Dvw26A6Q.js +1067 -0
  397. package/bundled-test-harness/assets/realm-server-form-agnostic-test-DrXQH0UP.js +96 -0
  398. package/bundled-test-harness/assets/realm-server-subscriber-test-Dkj23vQK.js +46 -0
  399. package/bundled-test-harness/assets/realm-service-info-test-CdRlDhj-.js +67 -0
  400. package/bundled-test-harness/assets/realm-test-DGYN48Qx.js +2364 -0
  401. package/bundled-test-harness/assets/realm-token-refresh-test-CEWATL9h.js +153 -0
  402. package/bundled-test-harness/assets/realm-url-tooltip-test-8ZjTNPuy.js +78 -0
  403. package/bundled-test-harness/assets/reasoning-test-WUx-4agu.js +221 -0
  404. package/bundled-test-harness/assets/recent-files-test-Dc6L6Dm4.js +450 -0
  405. package/bundled-test-harness/assets/reindex-realm-test-CFRSt39u.js +117 -0
  406. package/bundled-test-harness/assets/relationship-loading-state-test-FKbtOFUr.js +290 -0
  407. package/bundled-test-harness/assets/remix-card-test-CKGC_Sgq.js +58 -0
  408. package/bundled-test-harness/assets/rendered-markdown-B_jWmDrK.js +292 -0
  409. package/bundled-test-harness/assets/rendered-markdown-test-sdWhU0NA.js +587 -0
  410. package/bundled-test-harness/assets/resident-instance-reuse-test-BjdhE6CM.js +82 -0
  411. package/bundled-test-harness/assets/result-tile-o6dtjgX4.js +144 -0
  412. package/bundled-test-harness/assets/rich-markdown-field-test-VXr6l20h.js +1647 -0
  413. package/bundled-test-harness/assets/room-message-test-BYNhZ39n.js +484 -0
  414. package/bundled-test-harness/assets/run-FzaqmBEl.js +3959 -0
  415. package/bundled-test-harness/assets/run-realm-code-DsBUf1si.js +2964 -0
  416. package/bundled-test-harness/assets/run-realm-code-test-cS0DzaKo.js +3844 -0
  417. package/bundled-test-harness/assets/sanitize-module-list-test-CvuOOiUY.js +85 -0
  418. package/bundled-test-harness/assets/save-card-skip-index-wait-test-fpJ1eq32.js +89 -0
  419. package/bundled-test-harness/assets/schema-editor-test-NkKjCgyf.js +785 -0
  420. package/bundled-test-harness/assets/schema-generation-test-Dmg3lWl7.js +28 -0
  421. package/bundled-test-harness/assets/scrolling-test-Dd4gv_fj.js +412 -0
  422. package/bundled-test-harness/assets/search-adorn-test-CZebk7_y.js +136 -0
  423. package/bundled-test-harness/assets/search-and-choose-test-Bd4NZUup.js +154 -0
  424. package/bundled-test-harness/assets/search-correlation-id-test-DXKlEO55.js +139 -0
  425. package/bundled-test-harness/assets/search-entries-result-test-QQawA8Fm.js +234 -0
  426. package/bundled-test-harness/assets/search-entries-test-3DlqGPQq.js +1486 -0
  427. package/bundled-test-harness/assets/search-entries-tool-test-D1TvDE9D.js +504 -0
  428. package/bundled-test-harness/assets/search-google-images-test-DqsoQGr1.js +166 -0
  429. package/bundled-test-harness/assets/search-results-DGrNaPxh.js +266 -0
  430. package/bundled-test-harness/assets/search-results-test-CqVHYNRt.js +578 -0
  431. package/bundled-test-harness/assets/search-selection-menu-test-D6bIjKiH.js +108 -0
  432. package/bundled-test-harness/assets/search-sheet-files-test-Bf37TQXo.js +126 -0
  433. package/bundled-test-harness/assets/search-sheet-persistence-test-CV4_XdxR.js +131 -0
  434. package/bundled-test-harness/assets/search-test-Dlb-wg3a.js +2249 -0
  435. package/bundled-test-harness/assets/search-tool-test-BJLgVMoL.js +156 -0
  436. package/bundled-test-harness/assets/searchable-option-test-eJaIPH_L.js +322 -0
  437. package/bundled-test-harness/assets/searchable-search-doc-test-yH9fLGNS.js +1271 -0
  438. package/bundled-test-harness/assets/section-rail-CNFCebtT.js +113 -0
  439. package/bundled-test-harness/assets/section-rail-test-KNJAWWl6.js +256 -0
  440. package/bundled-test-harness/assets/secure-sign-in-Dyljp0Th.js +174 -0
  441. package/bundled-test-harness/assets/secure-sign-in-test-QnqNuTP3.js +373 -0
  442. package/bundled-test-harness/assets/segmented-control-DxJdoJ4Z.js +173 -0
  443. package/bundled-test-harness/assets/select-BiQTg2ts.js +175 -0
  444. package/bundled-test-harness/assets/send-ai-assistant-message-test-CAn7M2dZ.js +52 -0
  445. package/bundled-test-harness/assets/send-bot-trigger-event-test-qBu5E_jy.js +56 -0
  446. package/bundled-test-harness/assets/send-request-via-proxy-test-CLuwLBq_.js +380 -0
  447. package/bundled-test-harness/assets/sending-test-Dt9Dh2wW.js +659 -0
  448. package/bundled-test-harness/assets/serialization-rri-form-audit-test-hMJukiKt.js +136 -0
  449. package/bundled-test-harness/assets/serialization-test-W5e3wKbz.js +8758 -0
  450. package/bundled-test-harness/assets/set-user-system-card-test-CjgWLkNV.js +59 -0
  451. package/bundled-test-harness/assets/setup-CssMNvui.js +772 -0
  452. package/bundled-test-harness/assets/setup-D8YXvK-p.js +2 -0
  453. package/bundled-test-harness/assets/shared-link-target-reuse-test-D42UO8DC.js +207 -0
  454. package/bundled-test-harness/assets/show-card-test-CHEaS514.js +365 -0
  455. package/bundled-test-harness/assets/signed-capture-link-test-BgEu0F-S.js +132 -0
  456. package/bundled-test-harness/assets/single-stack-test-DYcu_v7Z.js +652 -0
  457. package/bundled-test-harness/assets/skills-test-BP8QNesE.js +648 -0
  458. package/bundled-test-harness/assets/skip-boot-index-guard-test-BzRIncDN.js +46 -0
  459. package/bundled-test-harness/assets/spec-test-BYvFR6Xb.js +1077 -0
  460. package/bundled-test-harness/assets/spinner-Bx9x55NA.js +49 -0
  461. package/bundled-test-harness/assets/src-LqENIikj.js +5 -0
  462. package/bundled-test-harness/assets/src-a4d10Hra.js +216 -0
  463. package/bundled-test-harness/assets/stick-to-bottom-resize-test-BBLiCR3X.js +56 -0
  464. package/bundled-test-harness/assets/store-add-test-D_9IHQjZ.js +50 -0
  465. package/bundled-test-harness/assets/store-module-rebuild-test-BRGZoLRV.js +454 -0
  466. package/bundled-test-harness/assets/store-search-test-3G8JHuj2.js +175 -0
  467. package/bundled-test-harness/assets/store-test-Dd4WQp7L.js +3672 -0
  468. package/bundled-test-harness/assets/structured-theme-test-11TNsgUW.js +377 -0
  469. package/bundled-test-harness/assets/summarize-session-test-CwzD_ZbD.js +172 -0
  470. package/bundled-test-harness/assets/svg-image-def-test-zV6aMK9q.js +167 -0
  471. package/bundled-test-harness/assets/switch-submode-test-DQU2cP5_.js +168 -0
  472. package/bundled-test-harness/assets/sync-openrouter-models-test-xrXVaC2H.js +97 -0
  473. package/bundled-test-harness/assets/test-support-QTh6wGxu.js +3 -0
  474. package/bundled-test-harness/assets/test-support-Tr-PYFgc.js +99 -0
  475. package/bundled-test-harness/assets/tests-zLlwPutr.js +3598 -0
  476. package/bundled-test-harness/assets/text-file-def-test-Cyq78UFY.js +94 -0
  477. package/bundled-test-harness/assets/text-input-validator-test-C1uDVZU7.js +156 -0
  478. package/bundled-test-harness/assets/text-suggestion-test-C4XAqWqY.js +340 -0
  479. package/bundled-test-harness/assets/theme-card-test-dVNz4tgU.js +621 -0
  480. package/bundled-test-harness/assets/theme-dashboard-nav-test-DYSn5pqo.js +196 -0
  481. package/bundled-test-harness/assets/theme-scheme-island-test-C1WpkfEP.js +264 -0
  482. package/bundled-test-harness/assets/theme-scoped-css-parity-test-BVluppsE.js +176 -0
  483. package/bundled-test-harness/assets/titles-0a1luoTq.js +52 -0
  484. package/bundled-test-harness/assets/titles-DKHNLVwC.js +2 -0
  485. package/bundled-test-harness/assets/to-device-streaming-test-3A6jI0_r.js +163 -0
  486. package/bundled-test-harness/assets/token-usage-test-33ovcqPk.js +160 -0
  487. package/bundled-test-harness/assets/tools-J_Knr_W6.js +774 -0
  488. package/bundled-test-harness/assets/tools-calling-test-CfqZX0Ed.js +200 -0
  489. package/bundled-test-harness/assets/tools-test-B4x58ZmI.js +1624 -0
  490. package/bundled-test-harness/assets/tools-test-DtUQp5ez.js +3204 -0
  491. package/bundled-test-harness/assets/tooltip-B0rEgyMW.css +66 -0
  492. package/bundled-test-harness/assets/tooltip-DvUMUgVX.js +195 -0
  493. package/bundled-test-harness/assets/transform-cards-test-CYQbZeD9.js +341 -0
  494. package/bundled-test-harness/assets/ts-file-def-preview-test-m39f8Zio.js +95 -0
  495. package/bundled-test-harness/assets/ts-file-def-test-xIcL5xWe.js +92 -0
  496. package/bundled-test-harness/assets/ttf-font-def-test-ClQ2SzFF.js +206 -0
  497. package/bundled-test-harness/assets/turn-settling-test-DqYk312r.js +160 -0
  498. package/bundled-test-harness/assets/turn-summary-Bmt7ZxTS.js +1039 -0
  499. package/bundled-test-harness/assets/unpublish-realm-test-0ToTJczx.js +102 -0
  500. package/bundled-test-harness/assets/update-room-skills-test-o_j8NOUV.js +240 -0
  501. package/bundled-test-harness/assets/use-ai-assistant-test-D7HFpxKJ.js +384 -0
  502. package/bundled-test-harness/assets/user-message-BAOt1hS3.js +262 -0
  503. package/bundled-test-harness/assets/validate-realm-test-e3xIbNLB.js +67 -0
  504. package/bundled-test-harness/assets/video-metadata-extractor-test-D8naLSlg.js +520 -0
  505. package/bundled-test-harness/assets/view-visually-test-BuhGau5E.js +335 -0
  506. package/bundled-test-harness/assets/virtual-network-reset-test-CgaFNGPi.js +96 -0
  507. package/bundled-test-harness/assets/wav-audio-def-test-CWG_UdCh.js +160 -0
  508. package/bundled-test-harness/assets/webp-image-def-test-sN4yw8Zu.js +226 -0
  509. package/bundled-test-harness/assets/workspace-0LfPqbYB.js +445 -0
  510. package/bundled-test-harness/assets/workspace-a11y-test-DQxYDRAP.js +197 -0
  511. package/bundled-test-harness/assets/workspace-actions-jGJSfl8M.js +588 -0
  512. package/bundled-test-harness/assets/workspace-behavior-test-BnF-bmBN.js +338 -0
  513. package/bundled-test-harness/assets/workspace-delete-multiple-test-D-rxPDuT.js +212 -0
  514. package/bundled-test-harness/assets/workspace-delete-summary-test-C2-Mve5R.js +63 -0
  515. package/bundled-test-harness/assets/workspace-hosting-test-BvDKdlOb.js +138 -0
  516. package/bundled-test-harness/assets/workspace-indexing-test-B34T3kqD.js +71 -0
  517. package/bundled-test-harness/assets/workspace-test-CJivgv-m.js +51 -0
  518. package/bundled-test-harness/assets/workspace-test-CuSRpPnQ.js +385 -0
  519. package/bundled-test-harness/assets/workspace-timestamp-labels-test-aWgjdbCp.js +68 -0
  520. package/bundled-test-harness/assets/workspace-unit-test-DHMUf2KT.js +122 -0
  521. package/bundled-test-harness/assets/write-binary-file-test-P-hVQuin.js +124 -0
  522. package/bundled-test-harness/assets/write-text-file-test-fXvJueDd.js +191 -0
  523. package/bundled-test-harness/assets/zip-archive-test-C2P5CUSR.js +285 -0
  524. package/bundled-test-harness/assets/zip-file-def-test-BfJZAmGt.js +164 -0
  525. package/bundled-test-harness/boxel-ui-checksum.txt +1 -1
  526. package/bundled-test-harness/index.html +47 -47
  527. package/bundled-test-harness/tests/index.html +49 -49
  528. package/bundled-types/boxel-ui/helpers/theme-scoped-css.ts +4 -0
  529. package/bundled-types/choreo/choreo.gts +13 -1
  530. package/bundled-types/choreo/run.ts +19 -0
  531. package/bundled-types/host-app/components/operator-mode/dashboard/get-started.gts +152 -7
  532. package/bundled-types/host-app/components/operator-mode/dashboard/index.gts +2 -0
  533. package/bundled-types/host-app/components/operator-mode/dashboard/workspace.gts +5 -3
  534. package/bundled-types/host-app/components/operator-mode/dashboard-modals/workspace-modals.gts +5 -22
  535. package/bundled-types/host-app/components/operator-mode/host-submode/publishing-realm-popover.gts +1 -1
  536. package/bundled-types/host-app/components/operator-mode/host-submode.gts +111 -37
  537. package/bundled-types/host-app/components/operator-mode/publish-realm-modal.gts +1 -0
  538. package/bundled-types/host-app/lib/modal-focus-trap.ts +33 -0
  539. package/bundled-types/host-app/lib/workspace-actions.ts +21 -0
  540. package/bundled-types/host-app/services/host-mode-service.ts +39 -0
  541. package/bundled-types/host-app/services/realm.ts +14 -0
  542. package/bundled-types/host-tests/helpers/dashboard.ts +67 -0
  543. package/package.json +1 -1
  544. package/bundled-test-harness/assets/account-switch-failed-test-FytUFiPO.js +0 -45
  545. package/bundled-test-harness/assets/adapter-DvmPwSZv.js +0 -2
  546. package/bundled-test-harness/assets/add-field-to-card-definition-tool-test-DN525jiY.js +0 -112
  547. package/bundled-test-harness/assets/ai-assistant-create-workspace-test-q3tKqVJQ.js +0 -130
  548. package/bundled-test-harness/assets/ai-assistant-panel-relogin-test-DgeXcCyi.js +0 -46
  549. package/bundled-test-harness/assets/ai-assistant-test-lDIGPKFP.js +0 -2223
  550. package/bundled-test-harness/assets/ai-function-generation-test-D5GbLyvL.js +0 -1176
  551. package/bundled-test-harness/assets/ai-module-creation-test-I3-j2beD.js +0 -151
  552. package/bundled-test-harness/assets/aibot-message-Dmsjifs6.js +0 -1312
  553. package/bundled-test-harness/assets/app-BS9_-DhN.js +0 -14146
  554. package/bundled-test-harness/assets/apply-markdown-edit-test-4zlwt0Db.js +0 -230
  555. package/bundled-test-harness/assets/ask-user-picker-Dr-0qpNr.js +0 -370
  556. package/bundled-test-harness/assets/ask-user-picker-test-633AFdmS.js +0 -39
  557. package/bundled-test-harness/assets/assistant-transcript-test-BgRnLvMg.js +0 -57
  558. package/bundled-test-harness/assets/audio-metadata-extractor-test-4xsQqL-0.js +0 -1176
  559. package/bundled-test-harness/assets/authed-fetch-test-663mT5_N.js +0 -73
  560. package/bundled-test-harness/assets/avif-image-def-test-h01BPIJy.js +0 -187
  561. package/bundled-test-harness/assets/basic-test-DiD6T-8Q.js +0 -139
  562. package/bundled-test-harness/assets/binary-upload-dedupe-test-CkjMPO_e.js +0 -308
  563. package/bundled-test-harness/assets/bot-registration-test-CFZHpwdj.js +0 -97
  564. package/bundled-test-harness/assets/box-test-C3pSy5ED.js +0 -50
  565. package/bundled-test-harness/assets/brand-guide-attachments-test-EoC_u7Vc.js +0 -84
  566. package/bundled-test-harness/assets/brand-guide-custom-css-test-Dn3fvblr.js +0 -196
  567. package/bundled-test-harness/assets/brand-guide-edit-test-NeiT3MyK.js +0 -140
  568. package/bundled-test-harness/assets/brand-logo-mark-field-test-C2A1EnBB.js +0 -86
  569. package/bundled-test-harness/assets/broken-link-template-test-CWn6V5zZ.js +0 -192
  570. package/bundled-test-harness/assets/bundled-base-modules-test-D7mLzpsw.js +0 -54
  571. package/bundled-test-harness/assets/bundled-base-oracle-test-I7xCId_k.js +0 -37
  572. package/bundled-test-harness/assets/buried-stack-item-scroll-test-DFBev0h-.js +0 -236
  573. package/bundled-test-harness/assets/button-BeSuhveJ.js +0 -207
  574. package/bundled-test-harness/assets/bxl-cyclic-graph-test-DPykwvvx.js +0 -47
  575. package/bundled-test-harness/assets/bxl-expression-test-LBWJiFb9.js +0 -250
  576. package/bundled-test-harness/assets/bxl-indexing-test-BuZmLk7y.js +0 -212
  577. package/bundled-test-harness/assets/bxl-platform-module-test-BNIvlkCM.js +0 -71
  578. package/bundled-test-harness/assets/can-invoke-test-t-bFIIeX.js +0 -455
  579. package/bundled-test-harness/assets/can-read-realm-test-2Q_MzRT9.js +0 -56
  580. package/bundled-test-harness/assets/cancel-indexing-job-test-QeYxEukn.js +0 -69
  581. package/bundled-test-harness/assets/capture-test-CJmJG8YR.js +0 -360
  582. package/bundled-test-harness/assets/card-api-test-B43I510H.js +0 -198
  583. package/bundled-test-harness/assets/card-basics-test-CBClzP2y.js +0 -5364
  584. package/bundled-test-harness/assets/card-chooser-paging-test-HEVzf6pR.js +0 -235
  585. package/bundled-test-harness/assets/card-chooser-test-GfjBRPFI.js +0 -393
  586. package/bundled-test-harness/assets/card-context-search-results-CoSr4EdS.js +0 -30
  587. package/bundled-test-harness/assets/card-context-search-results-test-BLMlZu9t.js +0 -184
  588. package/bundled-test-harness/assets/card-def-field-def-relationships-test-DEBOzKan.js +0 -562
  589. package/bundled-test-harness/assets/card-def-menu-items-test-88_h8o0D.js +0 -228
  590. package/bundled-test-harness/assets/card-delete-test-DKom1phy.js +0 -466
  591. package/bundled-test-harness/assets/card-error-awaiting-index-test-DEwgFZMP.js +0 -53
  592. package/bundled-test-harness/assets/card-error-r6_cXst9.js +0 -72
  593. package/bundled-test-harness/assets/card-info-thumbnail-picker-test-B7LiY15e.js +0 -219
  594. package/bundled-test-harness/assets/card-playground-test-CgyIJHui.js +0 -1491
  595. package/bundled-test-harness/assets/card-prerender-rPfzpIOU.js +0 -12939
  596. package/bundled-test-harness/assets/card-thunk-error-test-L0pvg4Ce.js +0 -48
  597. package/bundled-test-harness/assets/card-type-service-test-B2dhqxSD.js +0 -161
  598. package/bundled-test-harness/assets/check-correctness-test-DgqaLlCW.js +0 -1093
  599. package/bundled-test-harness/assets/check-domain-availability-test-B0hJHY5l.js +0 -98
  600. package/bundled-test-harness/assets/chip-D01NW3WH.js +0 -44
  601. package/bundled-test-harness/assets/choreo-D2Jl79RU.js +0 -1019
  602. package/bundled-test-harness/assets/choreo-_E8SOEe-.js +0 -2
  603. package/bundled-test-harness/assets/choreo-feature-reel-test-WLjsZDmS.js +0 -155
  604. package/bundled-test-harness/assets/choreo-gallery-build-order-test-6jnS8PsS.js +0 -436
  605. package/bundled-test-harness/assets/choreo-gallery-compositor-test-CbUZsVB6.js +0 -399
  606. package/bundled-test-harness/assets/choreo-gallery-cover-test-CbvAStgk.js +0 -214
  607. package/bundled-test-harness/assets/choreo-gallery-crossing-stage-test-tdjvUSa6.js +0 -133
  608. package/bundled-test-harness/assets/choreo-gallery-demos-alive-test-CsnM3hQK.js +0 -42
  609. package/bundled-test-harness/assets/choreo-gallery-drift-test-DG2LQTa7.js +0 -620
  610. package/bundled-test-harness/assets/choreo-gallery-escort-test-mn3-qXP1.js +0 -187
  611. package/bundled-test-harness/assets/choreo-gallery-films-test-BuktaC0D.js +0 -140
  612. package/bundled-test-harness/assets/choreo-gallery-filter-test-Dd-zpps0.js +0 -46
  613. package/bundled-test-harness/assets/choreo-gallery-fold-test-CWc1ijGc.js +0 -180
  614. package/bundled-test-harness/assets/choreo-gallery-guide-pages-test-tk2QmYPU.js +0 -114
  615. package/bundled-test-harness/assets/choreo-gallery-guides-test-DVbf1zM4.js +0 -321
  616. package/bundled-test-harness/assets/choreo-gallery-hang-test-B7EFp2dx.js +0 -426
  617. package/bundled-test-harness/assets/choreo-gallery-highlight-test-BFgbdesP.js +0 -60
  618. package/bundled-test-harness/assets/choreo-gallery-inline-edit-test-DJb8FC5R.js +0 -370
  619. package/bundled-test-harness/assets/choreo-gallery-interruption-test-DWyMXo5D.js +0 -176
  620. package/bundled-test-harness/assets/choreo-gallery-lone-stack-test-D3b8LsJ6.js +0 -104
  621. package/bundled-test-harness/assets/choreo-gallery-navigation-test-CjjU6Rvn.js +0 -193
  622. package/bundled-test-harness/assets/choreo-gallery-playhead-transport-test-Le_h3QWU.js +0 -111
  623. package/bundled-test-harness/assets/choreo-gallery-poplayout-subtree-test-Cp-DlWj4.js +0 -127
  624. package/bundled-test-harness/assets/choreo-gallery-presence-modes-test-DayS4GCJ.js +0 -100
  625. package/bundled-test-harness/assets/choreo-gallery-presentation-test-DeAfuFS7.js +0 -157
  626. package/bundled-test-harness/assets/choreo-gallery-reduced-motion-test-BgPWpggq.js +0 -145
  627. package/bundled-test-harness/assets/choreo-gallery-sheet-standalone-test-PzyoMNYv.js +0 -89
  628. package/bundled-test-harness/assets/choreo-gallery-sheet-test-CxaiNBkL.js +0 -48
  629. package/bundled-test-harness/assets/choreo-gallery-site-test-6xtSntS5.js +0 -237
  630. package/bundled-test-harness/assets/choreo-gallery-stage-E6Q5r-zU.js +0 -256
  631. package/bundled-test-harness/assets/choreo-gallery-stage-keyboard-test-C7aWMr9a.js +0 -102
  632. package/bundled-test-harness/assets/choreo-gallery-stages-test-CDWWgC61.js +0 -35
  633. package/bundled-test-harness/assets/choreo-gallery-subdivision-test-Bkp15XJv.js +0 -138
  634. package/bundled-test-harness/assets/choreo-gallery-table-plan-test-CcGRi_3O.js +0 -144
  635. package/bundled-test-harness/assets/choreo-gallery-theater-test-Qph5pLT_.js +0 -252
  636. package/bundled-test-harness/assets/choreo-gallery-tuning-test-C4DhFLVA.js +0 -95
  637. package/bundled-test-harness/assets/choreo-gallery-widget-room-test-LK493r1M.js +0 -88
  638. package/bundled-test-harness/assets/choreo-gallery-wires-test-B7SeUCc8.js +0 -148
  639. package/bundled-test-harness/assets/client-telemetry-test-DGmHzAFx.js +0 -340
  640. package/bundled-test-harness/assets/clip-BpYQPVz_.js +0 -2
  641. package/bundled-test-harness/assets/clip-CNaYbIwL.js +0 -92
  642. package/bundled-test-harness/assets/code-block-Cp2CJo5-.js +0 -502
  643. package/bundled-test-harness/assets/code-ref-test-C8JBHDb-.js +0 -163
  644. package/bundled-test-harness/assets/code-submode-availability-test-CzG1Tv6L.js +0 -198
  645. package/bundled-test-harness/assets/code-submode-test-BclVWjm5.js +0 -1839
  646. package/bundled-test-harness/assets/codeblocks-test-CmQlyxN7.js +0 -418
  647. package/bundled-test-harness/assets/codemirror-editor-test-B74H_yn8.js +0 -1512
  648. package/bundled-test-harness/assets/codemirror-embed-toolbar-test-Bz6VEysU.js +0 -366
  649. package/bundled-test-harness/assets/color-field-test-DMCPQKIP.js +0 -212
  650. package/bundled-test-harness/assets/compaction-test-saQCLBrQ.js +0 -150
  651. package/bundled-test-harness/assets/computed-test-C05HliJC.js +0 -1320
  652. package/bundled-test-harness/assets/container-Cqcwrd-m.js +0 -10857
  653. package/bundled-test-harness/assets/content-preview-components-test-DZPj4_CU.js +0 -462
  654. package/bundled-test-harness/assets/copy-and-edit-test-DiXTQNTF.js +0 -292
  655. package/bundled-test-harness/assets/copy-card-test-ys7GquUY.js +0 -218
  656. package/bundled-test-harness/assets/copy-file-to-realm-test-Gn0Wn4vT.js +0 -148
  657. package/bundled-test-harness/assets/copy-source-test-BTLrOmPm.js +0 -56
  658. package/bundled-test-harness/assets/create-file-test-BCeIW-Rt.js +0 -464
  659. package/bundled-test-harness/assets/create-file-test-DbHQ5JsS.js +0 -1086
  660. package/bundled-test-harness/assets/create-listing-modal-test-CeHc4ter.js +0 -273
  661. package/bundled-test-harness/assets/create-listing-pr-request-test-DXbJNfMh.js +0 -117
  662. package/bundled-test-harness/assets/create-spec-test-BDIZoyHT.js +0 -256
  663. package/bundled-test-harness/assets/create-submission-workflow-test-Bix5J-3A.js +0 -132
  664. package/bundled-test-harness/assets/create-workspace-test-BmNnLHwC.js +0 -104
  665. package/bundled-test-harness/assets/credential-fields-test-NK1F4QWn.js +0 -200
  666. package/bundled-test-harness/assets/csv-file-def-test-BSfs4TTP.js +0 -102
  667. package/bundled-test-harness/assets/dashboard-C4T7ffKY.js +0 -3576
  668. package/bundled-test-harness/assets/dashboard-CFeHuP5-.js +0 -81
  669. package/bundled-test-harness/assets/dashboard-DQlpW-ux.css +0 -2392
  670. package/bundled-test-harness/assets/dashboard-add-workspace-test--rr6objf.js +0 -50
  671. package/bundled-test-harness/assets/dashboard-agents-test-D1y8H4xH.js +0 -334
  672. package/bundled-test-harness/assets/dashboard-archive-test-bN4EQaXv.js +0 -128
  673. package/bundled-test-harness/assets/dashboard-delete-test-BvsASb8B.js +0 -163
  674. package/bundled-test-harness/assets/dashboard-duplicate-offer-test-DEsd5ZzZ.js +0 -71
  675. package/bundled-test-harness/assets/dashboard-duplicate-test-BnR0sTgB.js +0 -222
  676. package/bundled-test-harness/assets/dashboard-get-started-test-DG4uUXLv.js +0 -246
  677. package/bundled-test-harness/assets/dashboard-pinned-cards-test-AoGGVRAS.js +0 -220
  678. package/bundled-test-harness/assets/dashboard-reindex-test-BN9a96Xp.js +0 -115
  679. package/bundled-test-harness/assets/dashboard-section-rail-test-B3OT9V2T.js +0 -169
  680. package/bundled-test-harness/assets/dashboard-state-test-BY0Zqrmj.js +0 -162
  681. package/bundled-test-harness/assets/dashboard-test-C13oNpWt.js +0 -545
  682. package/bundled-test-harness/assets/dashboard-unreachable-notice-test-DZIV4x5j.js +0 -62
  683. package/bundled-test-harness/assets/dashboard-workspace-test-CBnOQViI.js +0 -537
  684. package/bundled-test-harness/assets/dashboard-workspaces-section-test-KU8ZVOYp.js +0 -396
  685. package/bundled-test-harness/assets/data-file-def-preview-test-CI5gcdtK.js +0 -155
  686. package/bundled-test-harness/assets/date-time-fields-test-D2CpR_Pb.js +0 -359
  687. package/bundled-test-harness/assets/debug-message-test-Df1kHesw.js +0 -117
  688. package/bundled-test-harness/assets/declared-captures-test-hQ43zuox.js +0 -879
  689. package/bundled-test-harness/assets/delete-workspace-test-BhfMKsix.js +0 -102
  690. package/bundled-test-harness/assets/diffing-test-CHRh55mC.js +0 -210
  691. package/bundled-test-harness/assets/download-file-to-realm-test-CC1HURCi.js +0 -119
  692. package/bundled-test-harness/assets/editor-test-DkeCv28f.js +0 -688
  693. package/bundled-test-harness/assets/edits-BSJqtUXM.js +0 -651
  694. package/bundled-test-harness/assets/email-field-test-DihK0suO.js +0 -75
  695. package/bundled-test-harness/assets/enum-field-test-Gja3bzt5.js +0 -935
  696. package/bundled-test-harness/assets/error-display-test-GhYZu7cp.js +0 -343
  697. package/bundled-test-harness/assets/evaluate-module-test-D_t4CiUq.js +0 -91
  698. package/bundled-test-harness/assets/execute-atomic-operations-test-xtou8Zeg.js +0 -113
  699. package/bundled-test-harness/assets/externals-B02-sD_L.js +0 -4393
  700. package/bundled-test-harness/assets/fallback-banner-live-delete-test-DtxzNXdE.js +0 -207
  701. package/bundled-test-harness/assets/fallback-banner-test-BfmiQ_68.js +0 -53
  702. package/bundled-test-harness/assets/fallback-banner-test-DLtTdmvn.js +0 -225
  703. package/bundled-test-harness/assets/fallback-models-test-BxNJxhfd.js +0 -161
  704. package/bundled-test-harness/assets/fetch-card-json-test-DofKbzvC.js +0 -61
  705. package/bundled-test-harness/assets/field-configuration-test-SUoPaXWy.js +0 -551
  706. package/bundled-test-harness/assets/field-markdown-domain-test-BwtR0dPP.js +0 -616
  707. package/bundled-test-harness/assets/field-markdown-oversize-test-D8UJcBc3.js +0 -88
  708. package/bundled-test-harness/assets/field-markdown-primitives-test-D5_ZdoDO.js +0 -365
  709. package/bundled-test-harness/assets/field-markdown-specialized-test-Dpd5hs04.js +0 -534
  710. package/bundled-test-harness/assets/field-playground-test-CzhYzKGv.js +0 -894
  711. package/bundled-test-harness/assets/field-support-predicates-test-BSvVOFth.js +0 -167
  712. package/bundled-test-harness/assets/file-attachment-test-fM-yFedm.js +0 -796
  713. package/bundled-test-harness/assets/file-chooser-panel-test-CKj8YTdY.js +0 -153
  714. package/bundled-test-harness/assets/file-chooser-test-Bs8jFXqa.js +0 -504
  715. package/bundled-test-harness/assets/file-def-format-templates-test-CxrRoWoD.js +0 -380
  716. package/bundled-test-harness/assets/file-def-live-reload-test-X_8YEkve.js +0 -124
  717. package/bundled-test-harness/assets/file-def-menu-items-test-Dx879o_o.js +0 -138
  718. package/bundled-test-harness/assets/file-def-navigation-test-MMI_EEO1.js +0 -109
  719. package/bundled-test-harness/assets/file-def-serialization-test-B5lguBQD.js +0 -89
  720. package/bundled-test-harness/assets/file-def-test-Di9QWcrj.js +0 -216
  721. package/bundled-test-harness/assets/file-preview-live-reload-test-aqx93A7c.js +0 -310
  722. package/bundled-test-harness/assets/file-resource-primitives-test-a5abpcSB.js +0 -255
  723. package/bundled-test-harness/assets/file-tree-from-index-test-CnruGxJ8.js +0 -96
  724. package/bundled-test-harness/assets/file-tree-test-BCyWDdSE.js +0 -851
  725. package/bundled-test-harness/assets/file-view-model-test-BfpLa01Y.js +0 -346
  726. package/bundled-test-harness/assets/filedef-export-shape-test-CQ9XbrzS.js +0 -61
  727. package/bundled-test-harness/assets/film-CL1zj_bJ.js +0 -2
  728. package/bundled-test-harness/assets/film-Dq_quZ31.js +0 -13
  729. package/bundled-test-harness/assets/film-xbkQa060.js +0 -4074
  730. package/bundled-test-harness/assets/flac-audio-def-test-BmVp9dMx.js +0 -143
  731. package/bundled-test-harness/assets/focus-Dm4wkM72.js +0 -306
  732. package/bundled-test-harness/assets/font-metadata-extractor-test-OWEh9_MS.js +0 -415
  733. package/bundled-test-harness/assets/formatted-aibot-message-test-BpHsWpuV.js +0 -109
  734. package/bundled-test-harness/assets/formatted-user-message-test-DZW5TAr0.js +0 -43
  735. package/bundled-test-harness/assets/freestyle-test-D_uaPU_3.js +0 -17
  736. package/bundled-test-harness/assets/full-reindex-realm-test-C6vHL5kC.js +0 -101
  737. package/bundled-test-harness/assets/garbage-collection-test-D-Ao4t2n.js +0 -403
  738. package/bundled-test-harness/assets/general-test-PSGI8W0z.js +0 -923
  739. package/bundled-test-harness/assets/generate-example-cards-one-shot-test-J-m-0E6W.js +0 -65
  740. package/bundled-test-harness/assets/generic-file-def-preview-test-BAsOhTYU.js +0 -71
  741. package/bundled-test-harness/assets/get-available-realm-identifiers-test-D5PBOr97.js +0 -47
  742. package/bundled-test-harness/assets/get-catalog-realm-identifiers-test-NM9UURHE.js +0 -47
  743. package/bundled-test-harness/assets/get-default-writable-realm-test-BxXc9a3J.js +0 -54
  744. package/bundled-test-harness/assets/get-published-realms-test-C8TJEc4-.js +0 -71
  745. package/bundled-test-harness/assets/get-realm-of-resource-identifier-test-Dt8CB6lS.js +0 -54
  746. package/bundled-test-harness/assets/get-relationship-membership-state-test-9_8x3myJ.js +0 -1308
  747. package/bundled-test-harness/assets/get-user-system-card-test-k0UO-uba.js +0 -67
  748. package/bundled-test-harness/assets/gif-image-def-test-BWrqPGDX.js +0 -188
  749. package/bundled-test-harness/assets/glimmer-motion-and-choreo-in-cards-test-BgG8QI9E.js +0 -160
  750. package/bundled-test-harness/assets/glimmer-motion-and-choreo-test-BKOvNyCN.js +0 -74
  751. package/bundled-test-harness/assets/gts-file-def-test-BCRHwDeZ.js +0 -100
  752. package/bundled-test-harness/assets/head-format-preview-test-DnfUhniI.js +0 -158
  753. package/bundled-test-harness/assets/helpers-DklkegO_.js +0 -5
  754. package/bundled-test-harness/assets/host-mode-service-vOfN0smp.js +0 -232
  755. package/bundled-test-harness/assets/host-mode-test-CCCJFz6_.js +0 -831
  756. package/bundled-test-harness/assets/host-submode-test-CtCfbuPA.js +0 -1342
  757. package/bundled-test-harness/assets/html-component-test-CWyhb5ZX.js +0 -65
  758. package/bundled-test-harness/assets/html-def-test-Cb8C2lUx.js +0 -160
  759. package/bundled-test-harness/assets/html-meta-extractor-test-BHT9Rtir.js +0 -60
  760. package/bundled-test-harness/assets/hydratable-card-test-DpgpdesD.js +0 -426
  761. package/bundled-test-harness/assets/icon-button-ABCGVF3C.js +0 -67
  762. package/bundled-test-harness/assets/image-metadata-extractor-test-ClhPTouq.js +0 -1109
  763. package/bundled-test-harness/assets/index-changes-test-CgnVr3LH.js +0 -367
  764. package/bundled-test-harness/assets/index-query-engine-test-CQTwju5_.js +0 -2593
  765. package/bundled-test-harness/assets/index-writer-test-IoVOoZT2.js +0 -3040
  766. package/bundled-test-harness/assets/inspector-test-BN2Ieb77.js +0 -2058
  767. package/bundled-test-harness/assets/instance-filter-matcher-test-Bq-_Sy89.js +0 -788
  768. package/bundled-test-harness/assets/instantiate-card-test-DEeDTzFV.js +0 -164
  769. package/bundled-test-harness/assets/interact-submode-creation-and-permissions-test-DP6kOyJS.js +0 -475
  770. package/bundled-test-harness/assets/interact-submode-setup-B0_cHqH-.js +0 -566
  771. package/bundled-test-harness/assets/invalidate-realm-identifiers-test-9uUD91Pw.js +0 -99
  772. package/bundled-test-harness/assets/invite-user-to-room-test-CcDA45Ac.js +0 -142
  773. package/bundled-test-harness/assets/invoke-card-operation-test-DmUtgueM.js +0 -333
  774. package/bundled-test-harness/assets/isolated-render-test-B2eXNHu6.js +0 -51
  775. package/bundled-test-harness/assets/job-scoped-doc-cache-test-DF9D7cOc.js +0 -181
  776. package/bundled-test-harness/assets/job-scoped-instance-residency-test-CSS8xUU5.js +0 -103
  777. package/bundled-test-harness/assets/jpg-image-def-test-voECMTht.js +0 -697
  778. package/bundled-test-harness/assets/json-file-def-test-8Y4KLjUC.js +0 -95
  779. package/bundled-test-harness/assets/key-notices-badge-test-d1mYqx0e.js +0 -155
  780. package/bundled-test-harness/assets/key-readiness-test-BtCg7PCk.js +0 -190
  781. package/bundled-test-harness/assets/linksto-broken-link-placeholder-test-CyCMbJnN.js +0 -398
  782. package/bundled-test-harness/assets/linksto-error-sentinel-test-BDW572-v.js +0 -238
  783. package/bundled-test-harness/assets/linksto-many-broken-link-placeholder-test-B4wM97hD.js +0 -354
  784. package/bundled-test-harness/assets/linksto-many-per-slot-access-test-BhJmtJ0_.js +0 -303
  785. package/bundled-test-harness/assets/linksto-sentinel-reload-test-BpBQ5V_i.js +0 -197
  786. package/bundled-test-harness/assets/linksto-sentinel-roundtrip-test-pkBBl4e9.js +0 -260
  787. package/bundled-test-harness/assets/linksto-singular-js-access-contract-test-Bb6wjUdD.js +0 -196
  788. package/bundled-test-harness/assets/lint-and-fix-test-CcMLn-co.js +0 -51
  789. package/bundled-test-harness/assets/live-test-AyBnq7BX.js +0 -2
  790. package/bundled-test-harness/assets/live-test-CgnAcIDw.js +0 -100
  791. package/bundled-test-harness/assets/load-default-skills-test-BIOwtx0Y.js +0 -74
  792. package/bundled-test-harness/assets/loader-parallel-prefetch-test-D5_oRSER.js +0 -257
  793. package/bundled-test-harness/assets/loader-test-DSc_jR1c.js +0 -482
  794. package/bundled-test-harness/assets/loading-test-8pldx7S-.js +0 -63
  795. package/bundled-test-harness/assets/m4a-audio-def-test-BDI5apzM.js +0 -190
  796. package/bundled-test-harness/assets/main-5kHyCkdm.js +0 -5
  797. package/bundled-test-harness/assets/markdown-embed-chooser-modal-test-Wud0s7WZ.js +0 -470
  798. package/bundled-test-harness/assets/markdown-embed-chooser-test-DVzzS-0C.js +0 -334
  799. package/bundled-test-harness/assets/markdown-embed-preview-pane-test-B5W_iqsi.js +0 -447
  800. package/bundled-test-harness/assets/markdown-embed-preview-test-CZF_s0fB.js +0 -368
  801. package/bundled-test-harness/assets/markdown-fallback-test-fT6BS4W7.js +0 -316
  802. package/bundled-test-harness/assets/markdown-file-def-test-B1aTzazR.js +0 -380
  803. package/bundled-test-harness/assets/markdown-helpers-test-gNKZf7Mw.js +0 -188
  804. package/bundled-test-harness/assets/markdown-highlighting-test-Du5_CQmD.js +0 -244
  805. package/bundled-test-harness/assets/markdown-preview-h-_aJhRc.js +0 -72
  806. package/bundled-test-harness/assets/markdown-preview-test-DJvoVsXw.js +0 -238
  807. package/bundled-test-harness/assets/markdown-skill-frontmatter-test-VwJi3Paj.js +0 -146
  808. package/bundled-test-harness/assets/markdown-skill-search-test-ysCdf0xM.js +0 -80
  809. package/bundled-test-harness/assets/matrix-service-account-switch-sessions-test-K2JuMy36.js +0 -63
  810. package/bundled-test-harness/assets/matrix-service-boot-assembly-test-CkdL_-os.js +0 -300
  811. package/bundled-test-harness/assets/matrix-service-personal-realm-test-Dy1DultK.js +0 -125
  812. package/bundled-test-harness/assets/matrix-service-realm-servers-test-DHDDKuEg.js +0 -55
  813. package/bundled-test-harness/assets/matrix-service-realms-list-updated-test-DcTbZpMl.js +0 -132
  814. package/bundled-test-harness/assets/matrix-service-relogin-test-D3NQktoa.js +0 -59
  815. package/bundled-test-harness/assets/matrix-service-sliding-sync-test-6CAflWOA.js +0 -35
  816. package/bundled-test-harness/assets/menu-kUSaJIPq.js +0 -3562
  817. package/bundled-test-harness/assets/message-service-subscription-test-DaQdgDWi.js +0 -110
  818. package/bundled-test-harness/assets/message-service-test-BsGEgM_m.js +0 -144
  819. package/bundled-test-harness/assets/message-tool-test-BB_4kw1V.js +0 -33
  820. package/bundled-test-harness/assets/midi-audio-def-test-BbbkFjqf.js +0 -182
  821. package/bundled-test-harness/assets/migrate-skill-test-X9xImDuq.js +0 -161
  822. package/bundled-test-harness/assets/mini-AwF31elJ.js +0 -1404
  823. package/bundled-test-harness/assets/mini-card-chooser-test-BZtrEiWu.js +0 -272
  824. package/bundled-test-harness/assets/mini-file-chooser-test-MIHW3kCI.js +0 -201
  825. package/bundled-test-harness/assets/mock-matrix-Dd8k0DNa.js +0 -15107
  826. package/bundled-test-harness/assets/mock-matrix-DhPN_34j.js +0 -2
  827. package/bundled-test-harness/assets/modal-LTh3_oHK.js +0 -322
  828. package/bundled-test-harness/assets/model-cost-tier-test-h1IkU9mp.js +0 -174
  829. package/bundled-test-harness/assets/model-file-extract-test-ntSo0wZF.js +0 -206
  830. package/bundled-test-harness/assets/module-transpile-cache-test-CDeRaaeP.js +0 -67
  831. package/bundled-test-harness/assets/monaco-test-C0Fa744D.js +0 -100
  832. package/bundled-test-harness/assets/mp3-audio-def-test-B4j4qR9H.js +0 -133
  833. package/bundled-test-harness/assets/multiple-stacks-test-BhA25ywL.js +0 -208
  834. package/bundled-test-harness/assets/nested-query-field-render-test-S9Y8YNKB.js +0 -249
  835. package/bundled-test-harness/assets/no-stacks-test-B7VciWyg.js +0 -48
  836. package/bundled-test-harness/assets/number-field-test-CS74lDPN.js +0 -184
  837. package/bundled-test-harness/assets/office-file-def-test-2cKc1pmd.js +0 -263
  838. package/bundled-test-harness/assets/office-metadata-extractor-test-DC8Fo-OW.js +0 -218
  839. package/bundled-test-harness/assets/office-poster-capture-test-Ba0_5UrT.js +0 -203
  840. package/bundled-test-harness/assets/ogg-audio-def-test-CIPQ1d4w.js +0 -196
  841. package/bundled-test-harness/assets/open-create-listing-modal-test-bmQkY5Zl.js +0 -131
  842. package/bundled-test-harness/assets/open-image-in-new-tab-test-DBD7_vMH.js +0 -52
  843. package/bundled-test-harness/assets/open-secure-window-test-BgeuYAqz.js +0 -253
  844. package/bundled-test-harness/assets/open-workspace-test-DRHGljV0.js +0 -46
  845. package/bundled-test-harness/assets/operation-lowering-test-CH1c0pSH.js +0 -2957
  846. package/bundled-test-harness/assets/operations-invocation-test-B1YkCLrv.js +0 -523
  847. package/bundled-test-harness/assets/operations-optimistic-test-DAbtOwsC.js +0 -203
  848. package/bundled-test-harness/assets/operations-query-test-9p1ZIDe-.js +0 -459
  849. package/bundled-test-harness/assets/operations-store-reconciliation-test-D0EQh3w2.js +0 -406
  850. package/bundled-test-harness/assets/operations-test-BQhlrfe3.js +0 -2518
  851. package/bundled-test-harness/assets/operator-mode-acceptance-test-DtHnonEb.js +0 -1195
  852. package/bundled-test-harness/assets/operator-mode-card-chooser-test-DQUxZxaq.js +0 -1036
  853. package/bundled-test-harness/assets/operator-mode-links-test-BJ26HllS.js +0 -797
  854. package/bundled-test-harness/assets/operator-mode-test-DIPDI0qt.js +0 -696
  855. package/bundled-test-harness/assets/operator-mode-ui-test-CfA-fAh4.js +0 -1045
  856. package/bundled-test-harness/assets/overlay-DecPh3nt.js +0 -123
  857. package/bundled-test-harness/assets/overlay-menu-items-test-C6XqjLtu.js +0 -331
  858. package/bundled-test-harness/assets/overlays-Ctp8ePzZ.js +0 -75
  859. package/bundled-test-harness/assets/overlays-CzWpSg5T.js +0 -2
  860. package/bundled-test-harness/assets/overlays-detached-element-test-DvL_8Bb5.js +0 -56
  861. package/bundled-test-harness/assets/panel-CImumikB.js +0 -15124
  862. package/bundled-test-harness/assets/past-sessions-test-N6riGN_I.js +0 -321
  863. package/bundled-test-harness/assets/patch-fields-test-D30_-KwQ.js +0 -1014
  864. package/bundled-test-harness/assets/patch-instance-test-C5rGscZq.js +0 -348
  865. package/bundled-test-harness/assets/pdf-file-def-test-DtiqGRvZ.js +0 -111
  866. package/bundled-test-harness/assets/pdf-metadata-extractor-test-FU02KmdV.js +0 -130
  867. package/bundled-test-harness/assets/permission-checking-realm-test-DqdNJDwU.js +0 -306
  868. package/bundled-test-harness/assets/persist-module-inspector-view-test-BHOAgPVy.js +0 -60
  869. package/bundled-test-harness/assets/persist-scroll-position-test-qtmS518r.js +0 -254
  870. package/bundled-test-harness/assets/phone-number-field-test-DhdaM7uL.js +0 -73
  871. package/bundled-test-harness/assets/pill-menu-test-C9Mrrepl.js +0 -60
  872. package/bundled-test-harness/assets/plate-9n-sXyCw.js +0 -41
  873. package/bundled-test-harness/assets/plate-BnZcAk-_.js +0 -2
  874. package/bundled-test-harness/assets/player-Cu5b4LEJ.js +0 -82
  875. package/bundled-test-harness/assets/player-unk2mkxV.js +0 -2
  876. package/bundled-test-harness/assets/playground-BwA8wFGK.js +0 -58
  877. package/bundled-test-harness/assets/plural-field-components-test-CFNQKETg.js +0 -198
  878. package/bundled-test-harness/assets/png-image-def-test-DG5Vhlqb.js +0 -266
  879. package/bundled-test-harness/assets/policy-audit-confirmation-test-yfKU47LR.js +0 -155
  880. package/bundled-test-harness/assets/policy-scoped-search-test-BjQRDYqR.js +0 -339
  881. package/bundled-test-harness/assets/prerender-file-extract-test-CEU4SaAZ.js +0 -346
  882. package/bundled-test-harness/assets/prerender-html-test-CGB3ClCS.js +0 -670
  883. package/bundled-test-harness/assets/prerender-meta-test-xqc4fW_0.js +0 -614
  884. package/bundled-test-harness/assets/prerender-module-test-CI1TmZw-.js +0 -409
  885. package/bundled-test-harness/assets/prerender-persistence-block-test-Da0dJO_N.js +0 -124
  886. package/bundled-test-harness/assets/prerender-pre-model-error-test-BVLyhk8R.js +0 -61
  887. package/bundled-test-harness/assets/prerender-serialize-cycle-test-glJFfxHU.js +0 -134
  888. package/bundled-test-harness/assets/prerendered-html-read-test-Mp4L0VHQ.js +0 -191
  889. package/bundled-test-harness/assets/pretui-components-test-BBpA9UnA.js +0 -991
  890. package/bundled-test-harness/assets/pretui-components-test-BqFq7rw_.css +0 -730
  891. package/bundled-test-harness/assets/preview-format-test-C55Bwcur.js +0 -103
  892. package/bundled-test-harness/assets/preview-test-CTAhRGU8.js +0 -474
  893. package/bundled-test-harness/assets/process-card-test-UjqpuxB7.js +0 -94
  894. package/bundled-test-harness/assets/profile-settings-modal-C8bCgTMK.js +0 -989
  895. package/bundled-test-harness/assets/publish-realm-ixUB4FPK.js +0 -82
  896. package/bundled-test-harness/assets/publish-realm-test-CrrsdL4W.js +0 -210
  897. package/bundled-test-harness/assets/query-field-barrier-test-DjivFE93.js +0 -113
  898. package/bundled-test-harness/assets/query-field-error-sentinel-test-0HwnV4Mw.js +0 -201
  899. package/bundled-test-harness/assets/query-field-membership-status-test-C8yTTBkc.js +0 -323
  900. package/bundled-test-harness/assets/query-field-page-optin-test-D4l_GcII.js +0 -126
  901. package/bundled-test-harness/assets/query-field-schema-test-DDbcNNm5.js +0 -231
  902. package/bundled-test-harness/assets/query-field-search-throttle-test-CXp50Ax0.js +0 -154
  903. package/bundled-test-harness/assets/query-field-stale-prerender-test-DErzt-Cv.js +0 -152
  904. package/bundled-test-harness/assets/query-fields-test-Dz67fdSl.js +0 -535
  905. package/bundled-test-harness/assets/quick-look-test-B1ijDsh_.js +0 -139
  906. package/bundled-test-harness/assets/read-card-for-ai-assistant-test-DJxZ16H_.js +0 -91
  907. package/bundled-test-harness/assets/read-file-for-ai-assistant-test-BoRQkZ8c.js +0 -45
  908. package/bundled-test-harness/assets/read-source-test-Bl-NjchO.js +0 -67
  909. package/bundled-test-harness/assets/read-text-file-test-CP37CZoo.js +0 -124
  910. package/bundled-test-harness/assets/realm-CaK5mkT-.js +0 -2852
  911. package/bundled-test-harness/assets/realm-api-keys-BNUFWbGR.js +0 -579
  912. package/bundled-test-harness/assets/realm-api-keys-CkshxhXC.js +0 -2
  913. package/bundled-test-harness/assets/realm-api-keys-test-BP8xifjn.js +0 -109
  914. package/bundled-test-harness/assets/realm-api-keys-test-CwdK9YXp.js +0 -588
  915. package/bundled-test-harness/assets/realm-config-iKwE3Htp.js +0 -833
  916. package/bundled-test-harness/assets/realm-config-policy-standing-test-BgVEIDnB.js +0 -290
  917. package/bundled-test-harness/assets/realm-config-routing-rule-edit-test-BoJoKzmX.js +0 -274
  918. package/bundled-test-harness/assets/realm-config-settings-test-Kxw-GHye.js +0 -187
  919. package/bundled-test-harness/assets/realm-field-test-CdGOxrFb.js +0 -100
  920. package/bundled-test-harness/assets/realm-indexing-test-CHtsBV2b.js +0 -4380
  921. package/bundled-test-harness/assets/realm-policy-fitted-test--DhNZSdC.js +0 -206
  922. package/bundled-test-harness/assets/realm-policy-test-D7714iVa.js +0 -1141
  923. package/bundled-test-harness/assets/realm-querying-test-Cj1ekZ0H.js +0 -1067
  924. package/bundled-test-harness/assets/realm-server-form-agnostic-test-CZFPNJfD.js +0 -96
  925. package/bundled-test-harness/assets/realm-server-subscriber-test-C86WmBp0.js +0 -46
  926. package/bundled-test-harness/assets/realm-service-info-test-CdgcwKDR.js +0 -67
  927. package/bundled-test-harness/assets/realm-test-DPoLsvKz.js +0 -2364
  928. package/bundled-test-harness/assets/realm-token-refresh-test-Ch35Siwi.js +0 -153
  929. package/bundled-test-harness/assets/realm-url-tooltip-test-x8xWOENK.js +0 -78
  930. package/bundled-test-harness/assets/reasoning-test-BxpE8Jvf.js +0 -221
  931. package/bundled-test-harness/assets/recent-files-test-DTmEzPLq.js +0 -450
  932. package/bundled-test-harness/assets/reindex-realm-test-BQ8KULn4.js +0 -117
  933. package/bundled-test-harness/assets/relationship-loading-state-test-BJoArPWf.js +0 -290
  934. package/bundled-test-harness/assets/remix-card-test-DsTA1KoG.js +0 -58
  935. package/bundled-test-harness/assets/rendered-markdown-DvukulDO.js +0 -292
  936. package/bundled-test-harness/assets/rendered-markdown-test-DxGptXSV.js +0 -587
  937. package/bundled-test-harness/assets/resident-instance-reuse-test-ZWnVu8uj.js +0 -82
  938. package/bundled-test-harness/assets/result-tile-CPyI6Vmv.js +0 -144
  939. package/bundled-test-harness/assets/rich-markdown-field-test-CdygoXIO.js +0 -1647
  940. package/bundled-test-harness/assets/room-message-test-D3NfMqH0.js +0 -484
  941. package/bundled-test-harness/assets/run-D_Px28eF.js +0 -3956
  942. package/bundled-test-harness/assets/run-realm-code-qWCZxmJ7.js +0 -2964
  943. package/bundled-test-harness/assets/run-realm-code-test-UzyeEJq6.js +0 -3844
  944. package/bundled-test-harness/assets/sanitize-module-list-test-Babq44bP.js +0 -85
  945. package/bundled-test-harness/assets/save-card-skip-index-wait-test-BcELXlQ_.js +0 -89
  946. package/bundled-test-harness/assets/schema-editor-test-CEvruZbt.js +0 -785
  947. package/bundled-test-harness/assets/schema-generation-test-hYAMdCrn.js +0 -28
  948. package/bundled-test-harness/assets/scrolling-test-DVIsh-_1.js +0 -412
  949. package/bundled-test-harness/assets/search-adorn-test-CkVhqFd0.js +0 -136
  950. package/bundled-test-harness/assets/search-and-choose-test-DUhOB3FV.js +0 -154
  951. package/bundled-test-harness/assets/search-correlation-id-test-Drn4r26N.js +0 -139
  952. package/bundled-test-harness/assets/search-entries-result-test-DTCRJ_wc.js +0 -234
  953. package/bundled-test-harness/assets/search-entries-test-CE0B47pw.js +0 -1486
  954. package/bundled-test-harness/assets/search-entries-tool-test-C4aG0ckM.js +0 -504
  955. package/bundled-test-harness/assets/search-google-images-test-LyhcB2f3.js +0 -166
  956. package/bundled-test-harness/assets/search-results-D4pSne0x.js +0 -266
  957. package/bundled-test-harness/assets/search-results-test-CRZHhqhn.js +0 -578
  958. package/bundled-test-harness/assets/search-selection-menu-test-B7Y3E_nj.js +0 -108
  959. package/bundled-test-harness/assets/search-sheet-files-test-C2y534g8.js +0 -126
  960. package/bundled-test-harness/assets/search-sheet-persistence-test-DePC59Bk.js +0 -131
  961. package/bundled-test-harness/assets/search-test-Dy8NxFkU.js +0 -2249
  962. package/bundled-test-harness/assets/search-tool-test-lctDaMH3.js +0 -156
  963. package/bundled-test-harness/assets/searchable-option-test-CE64M8oM.js +0 -322
  964. package/bundled-test-harness/assets/searchable-search-doc-test-C6u3mVvT.js +0 -1271
  965. package/bundled-test-harness/assets/section-rail-B_UQX00B.js +0 -113
  966. package/bundled-test-harness/assets/section-rail-test-DIda7MIw.js +0 -256
  967. package/bundled-test-harness/assets/secure-sign-in-CqqqfQG8.js +0 -174
  968. package/bundled-test-harness/assets/secure-sign-in-test-DimbVr_W.js +0 -373
  969. package/bundled-test-harness/assets/segmented-control-iePxSdTS.js +0 -173
  970. package/bundled-test-harness/assets/select-tNs6_xwW.js +0 -175
  971. package/bundled-test-harness/assets/send-ai-assistant-message-test-2GVrMF9Z.js +0 -52
  972. package/bundled-test-harness/assets/send-bot-trigger-event-test-B_3dKfGN.js +0 -56
  973. package/bundled-test-harness/assets/send-request-via-proxy-test-_clNWyYc.js +0 -380
  974. package/bundled-test-harness/assets/sending-test-DCPFXUVg.js +0 -659
  975. package/bundled-test-harness/assets/serialization-rri-form-audit-test-BI0zCs8Y.js +0 -136
  976. package/bundled-test-harness/assets/serialization-test-bjdtVlZL.js +0 -8758
  977. package/bundled-test-harness/assets/set-user-system-card-test-BUv1vL08.js +0 -59
  978. package/bundled-test-harness/assets/setup-BW1mmC7C.js +0 -772
  979. package/bundled-test-harness/assets/setup-DsIcFT-T.js +0 -2
  980. package/bundled-test-harness/assets/shared-link-target-reuse-test-9NeJEjkb.js +0 -207
  981. package/bundled-test-harness/assets/show-card-test-mfyLwusD.js +0 -365
  982. package/bundled-test-harness/assets/signed-capture-link-test-BOtKNCAM.js +0 -132
  983. package/bundled-test-harness/assets/single-stack-test-B4MGjaLk.js +0 -652
  984. package/bundled-test-harness/assets/skills-test-BuP-Yzk1.js +0 -648
  985. package/bundled-test-harness/assets/skip-boot-index-guard-test-Cmrx2-K7.js +0 -46
  986. package/bundled-test-harness/assets/spec-test-BhZDdhVQ.js +0 -1077
  987. package/bundled-test-harness/assets/spinner-CpIBUG9m.js +0 -49
  988. package/bundled-test-harness/assets/src-DGHttmW-.js +0 -216
  989. package/bundled-test-harness/assets/src-DaNDSbp7.js +0 -5
  990. package/bundled-test-harness/assets/stick-to-bottom-resize-test-Dpy3OVum.js +0 -56
  991. package/bundled-test-harness/assets/store-add-test-_IYS8o74.js +0 -50
  992. package/bundled-test-harness/assets/store-module-rebuild-test-B5VMaICy.js +0 -454
  993. package/bundled-test-harness/assets/store-search-test-C2VZabrH.js +0 -175
  994. package/bundled-test-harness/assets/store-test-D6PObxoD.js +0 -3672
  995. package/bundled-test-harness/assets/structured-theme-test-BHjVeMf-.js +0 -377
  996. package/bundled-test-harness/assets/summarize-session-test-BFtTuhe0.js +0 -172
  997. package/bundled-test-harness/assets/svg-image-def-test-BL6lkWUX.js +0 -167
  998. package/bundled-test-harness/assets/switch-submode-test-6Uv3bZMl.js +0 -168
  999. package/bundled-test-harness/assets/sync-openrouter-models-test-Dp9E05tL.js +0 -97
  1000. package/bundled-test-harness/assets/test-support-DYm8XZ0E.js +0 -3
  1001. package/bundled-test-harness/assets/test-support-DfnhiIMV.js +0 -99
  1002. package/bundled-test-harness/assets/tests-CZk0Iag2.js +0 -3596
  1003. package/bundled-test-harness/assets/text-file-def-test-CHdC0yIU.js +0 -94
  1004. package/bundled-test-harness/assets/text-input-validator-test-B9ZR8XPU.js +0 -156
  1005. package/bundled-test-harness/assets/text-suggestion-test-CGLspKFQ.js +0 -340
  1006. package/bundled-test-harness/assets/theme-card-test-CXZvSEvG.js +0 -621
  1007. package/bundled-test-harness/assets/theme-dashboard-nav-test-CkEE0ILk.js +0 -196
  1008. package/bundled-test-harness/assets/theme-scheme-island-test-URXTjipF.js +0 -264
  1009. package/bundled-test-harness/assets/titles-C6enAdIv.js +0 -2
  1010. package/bundled-test-harness/assets/titles-Dft1HoUT.js +0 -52
  1011. package/bundled-test-harness/assets/to-device-streaming-test-D33ZOc9o.js +0 -163
  1012. package/bundled-test-harness/assets/token-usage-test-BHQlU4J4.js +0 -160
  1013. package/bundled-test-harness/assets/tools-CrudqfS3.js +0 -774
  1014. package/bundled-test-harness/assets/tools-calling-test-jo7IREau.js +0 -200
  1015. package/bundled-test-harness/assets/tools-test-D1wMfUa0.js +0 -1624
  1016. package/bundled-test-harness/assets/tools-test-Dn1LYsXp.js +0 -3204
  1017. package/bundled-test-harness/assets/tooltip-8Wyz4IIn.css +0 -68
  1018. package/bundled-test-harness/assets/tooltip-CqwLzRz5.js +0 -134
  1019. package/bundled-test-harness/assets/transform-cards-test-BPhwPFtp.js +0 -341
  1020. package/bundled-test-harness/assets/ts-file-def-preview-test-Bq3zTgw8.js +0 -95
  1021. package/bundled-test-harness/assets/ts-file-def-test-GLswMl7O.js +0 -92
  1022. package/bundled-test-harness/assets/ttf-font-def-test-DQulvUWs.js +0 -206
  1023. package/bundled-test-harness/assets/turn-settling-test-BspmOUQP.js +0 -160
  1024. package/bundled-test-harness/assets/turn-summary-9A8nvC0-.js +0 -1039
  1025. package/bundled-test-harness/assets/unpublish-realm-test-SkYPEhDz.js +0 -102
  1026. package/bundled-test-harness/assets/update-room-skills-test-cTxb-WU6.js +0 -240
  1027. package/bundled-test-harness/assets/use-ai-assistant-test-uaqW1T_A.js +0 -384
  1028. package/bundled-test-harness/assets/user-message-BudkIP-3.js +0 -262
  1029. package/bundled-test-harness/assets/validate-realm-test-DxrGgH9n.js +0 -67
  1030. package/bundled-test-harness/assets/video-metadata-extractor-test-B2pe-Iqa.js +0 -520
  1031. package/bundled-test-harness/assets/view-visually-test-PNon6fUo.js +0 -335
  1032. package/bundled-test-harness/assets/virtual-network-reset-test-uYJLaQHf.js +0 -96
  1033. package/bundled-test-harness/assets/wav-audio-def-test-F4OrFFR4.js +0 -160
  1034. package/bundled-test-harness/assets/webp-image-def-test-B0a_-Vya.js +0 -226
  1035. package/bundled-test-harness/assets/workspace-Cyftysy9.js +0 -440
  1036. package/bundled-test-harness/assets/workspace-a11y-test-sKiPDcbl.js +0 -197
  1037. package/bundled-test-harness/assets/workspace-actions-BuawjFmZ.js +0 -561
  1038. package/bundled-test-harness/assets/workspace-behavior-test-CKa-pb3T.js +0 -338
  1039. package/bundled-test-harness/assets/workspace-delete-multiple-test-Dt2weG5R.js +0 -212
  1040. package/bundled-test-harness/assets/workspace-delete-summary-test-CkqgFqZ8.js +0 -63
  1041. package/bundled-test-harness/assets/workspace-hosting-test-Ci7EEtHP.js +0 -138
  1042. package/bundled-test-harness/assets/workspace-indexing-test-BPVxxY6W.js +0 -71
  1043. package/bundled-test-harness/assets/workspace-test-CWr7vFbg.js +0 -385
  1044. package/bundled-test-harness/assets/workspace-test-INNpQovc.js +0 -51
  1045. package/bundled-test-harness/assets/workspace-timestamp-labels-test-CigQb5wr.js +0 -68
  1046. package/bundled-test-harness/assets/workspace-unit-test-BwVKpuXT.js +0 -122
  1047. package/bundled-test-harness/assets/write-binary-file-test-BKP3gv1k.js +0 -124
  1048. package/bundled-test-harness/assets/write-text-file-test-B6ijTKTa.js +0 -191
  1049. package/bundled-test-harness/assets/zip-archive-test-C-PBzkTn.js +0 -285
  1050. package/bundled-test-harness/assets/zip-file-def-test-FyCzJT-9.js +0 -164
@@ -0,0 +1,3959 @@
1
+ import "./chunk-Rp0pCe6z.js";
2
+ import { $ as flushKeyframeResolvers, Ft as easingDefinitionToFunction, Nt as time, _t as generateLinearEasing, bt as mix, gt as maxGeneratorDuration, ht as calcGeneratorDuration, nn as registerBusyProbe, pt as spring, vt as cancelFrame, yt as frame } from "./layout-group-BS0gklZp.js";
3
+ import { C as animateTarget, c as defineParticipantArg, l as setParticipantHost, w as positionalKeys } from "./node-BWOLCOMI.js";
4
+ import "./src-CbBcj3xm.js";
5
+ import { r as scaleTransition, t as motionSpeed } from "./speed-bIo0tyrM.js";
6
+ //#region ../choreo/src/measure.ts
7
+ /**
8
+ * One measurement layer, for everything that measures.
9
+ *
10
+ * The region and the beacon registry both turn a DOMRect into the three spaces
11
+ * a step can ask for — page, region-relative, offset-parent-relative — and they
12
+ * have to agree exactly, because a Move routinely reads one sprite's `page` and
13
+ * another's. Ember Animated learned the same thing the hard way and ended up
14
+ * with a single bounds module; two copies of `minus` that drift by a scroll
15
+ * offset produce a flight that lands next to its target, which is the kind of
16
+ * bug that looks like a spring problem for a day.
17
+ */
18
+ defineParticipantArg("pack", (el, pack) => {
19
+ if (pack === "content") el.setAttribute("data-choreo-pack", "content");
20
+ else el.removeAttribute("data-choreo-pack");
21
+ });
22
+ /** a box in page space */
23
+ var rect = (r) => ({
24
+ height: r.height,
25
+ width: r.width,
26
+ x: r.left,
27
+ y: r.top
28
+ });
29
+ /** `a` expressed relative to `b`'s top-left, keeping a's size */
30
+ var minus = (a, b) => ({
31
+ height: a.height,
32
+ width: a.width,
33
+ x: a.left - b.left,
34
+ y: a.top - b.top
35
+ });
36
+ /** an element's box together with the box it is positioned inside */
37
+ /**
38
+ * The shrink-wrap of `el`'s contents — the ink — not the stretched layout
39
+ * box. A full-bleed title (`left:0; right:0; width:auto`) still has a
40
+ * word-sized range; Crossing crop must match THAT, or the type explodes
41
+ * into a viewport strip. Empty / collapsed → undefined, so the frame wins.
42
+ */
43
+ var inkBox = (el) => {
44
+ const doc = el.ownerDocument;
45
+ if (!doc) return;
46
+ const range = doc.createRange();
47
+ range.selectNodeContents(el);
48
+ const r = range.getBoundingClientRect();
49
+ if (r.width < .5 && r.height < .5) return;
50
+ return r;
51
+ };
52
+ var substanceOf = (el) => {
53
+ const marked = el.querySelector("[data-choreo-substance]")?.getBoundingClientRect();
54
+ if (marked) return marked;
55
+ if (el.getAttribute("data-choreo-pack") === "content") return inkBox(el);
56
+ };
57
+ /** the containing block a `position: absolute` child would be placed against */
58
+ var offsetBox = (el) => (el.offsetParent ?? el.parentElement ?? el).getBoundingClientRect();
59
+ /**
60
+ * Does the element have a layout box? One under `display: none` (its own or
61
+ * an ancestor's, as with the `hidden` attribute) measures as an empty rect at
62
+ * the page origin, which is no place to move from or to.
63
+ */
64
+ var isRendered = (el) => el.getClientRects().length > 0;
65
+ /** `undefined` for an element with no layout box (see `isRendered`) */
66
+ var measure = (el) => isRendered(el) ? snapshotOf(el) : void 0;
67
+ var snapshotOf = (el) => ({
68
+ el: el.getBoundingClientRect(),
69
+ paint: getComputedStyle(el).backgroundColor,
70
+ parent: offsetBox(el),
71
+ substance: substanceOf(el)
72
+ });
73
+ /** the three spaces, from a snapshot and the region's own box */
74
+ var boundsOf = (snap, root) => ({
75
+ context: minus(snap.el, root),
76
+ page: rect(snap.el),
77
+ paint: snap.paint,
78
+ parent: minus(snap.el, snap.parent),
79
+ substance: snap.substance && rect(snap.substance)
80
+ });
81
+ /** measure an element straight into bounds — what a beacon needs */
82
+ var measureBounds = (el, root) => {
83
+ const snap = measure(el);
84
+ return snap && boundsOf(snap, root);
85
+ };
86
+ //#endregion
87
+ //#region ../choreo/src/beacons.ts
88
+ /**
89
+ * Beacons — a named box that does not animate.
90
+ *
91
+ * Ember Animated's primitive: `<AnimatedBeacon>` measures its child when a
92
+ * transition starts, stores a sprite on the motion service, and a generator
93
+ * reads `context.beacons` to say "start here" or "end there". The beacon
94
+ * itself never moves.
95
+ *
96
+ * <button {{beacon 'trash'}}>Trash</button>
97
+ *
98
+ * <Choreo as |c|>
99
+ * …
100
+ * <c.Move @of={{c.removed 'row'}} @to={{c.beacon 'trash'}} />
101
+ * </Choreo>
102
+ *
103
+ * This is deliberately NOT `layoutId`. `layoutId` pairs two real elements that
104
+ * share an identity and morphs one into the other — putting it on a leaving row
105
+ * and on the bin would make the bin a shared element, and it would stretch. A
106
+ * beacon has no identity in the changeset: it is not inserted, kept or removed,
107
+ * it is a point other sprites may borrow. A beacon moving on its own never
108
+ * starts a run.
109
+ *
110
+ * The registry is document-global on purpose. The case that wants beacons is an
111
+ * inbox — the trash lives in the chrome, the list lives in the outlet, and they
112
+ * are different regions precisely so their changesets stay apart. A region-local
113
+ * registry could not see across that boundary, which is the whole point.
114
+ * packages/choreo-gallery/realm/docs/nested-choreo.md has the reasoning.
115
+ */
116
+ /** name → the element claiming it. First registration this pass wins, as Ember Animated's `hasBeacon` does. */
117
+ var registry = /* @__PURE__ */ new Map();
118
+ function registerBeacon(name, element) {
119
+ if (!registry.has(name)) registry.set(name, element);
120
+ return () => {
121
+ if (registry.get(name) === element) registry.delete(name);
122
+ };
123
+ }
124
+ /**
125
+ * Measure the live beacons, in the same window the region measures `final`.
126
+ *
127
+ * Re-measured every pass, never cached: the trash can move without the list
128
+ * rendering at all — a header that hides, a column that resizes, a scroll.
129
+ *
130
+ * A region passes the names its score asked for, so a pass measures only
131
+ * those: a page can claim hundreds of beacons (every chip a sheet may open
132
+ * from), and each region measuring every one on every pass would cost a
133
+ * layout read per beacon per region. Without `names`, every claimed beacon
134
+ * is measured.
135
+ */
136
+ function measureBeacons(root, names) {
137
+ const out = /* @__PURE__ */ new Map();
138
+ const wanted = names ? [...names].map((name) => [name, registry.get(name)]) : [...registry];
139
+ for (const [name, el] of wanted) {
140
+ if (!el?.isConnected) continue;
141
+ const bounds = measureBounds(el, root);
142
+ if (bounds) out.set(name, bounds);
143
+ }
144
+ return out;
145
+ }
146
+ /**
147
+ * Forget every claimed name. The registry outlives any one owner, so a test
148
+ * that tore down mid-flight would otherwise leave a dead element holding a
149
+ * name the next test wants — first-wins turns into first-test-wins.
150
+ * `setupChoreo(hooks)` runs this before and after every test; nothing in an
151
+ * app should.
152
+ */
153
+ function resetBeacons() {
154
+ registry.clear();
155
+ }
156
+ //#endregion
157
+ //#region ../choreo/src/gesture.ts
158
+ /**
159
+ * `c.gesture` — the live drag as a first-class geometry source (§6.1, §6.4).
160
+ *
161
+ * A document-level pointer tracker (listeners, not timers) keeps the last
162
+ * pointer position and a short velocity window. A Move that borrows
163
+ * `{{c.gesture}}` as its `@from` starts from wherever the finger let go —
164
+ * sized as the sprite, centred on the pointer — and any spring that flies
165
+ * it inherits the pointer's velocity, so a toss leaves at the speed it was
166
+ * thrown.
167
+ */
168
+ var GESTURE = { gesture: true };
169
+ function isGestureRef(v) {
170
+ return typeof v === "object" && v !== null && v.gesture === true;
171
+ }
172
+ var samples = [];
173
+ var tracking = false;
174
+ function record(event) {
175
+ const now = performance.now();
176
+ samples.push({
177
+ t: now,
178
+ x: event.clientX,
179
+ y: event.clientY
180
+ });
181
+ if (samples.length > 8) samples.shift();
182
+ }
183
+ /** idempotent; the first <Choreo> turns it on */
184
+ function trackGestures() {
185
+ if (tracking || typeof window === "undefined") return;
186
+ tracking = true;
187
+ window.addEventListener("pointerdown", record, {
188
+ capture: true,
189
+ passive: true
190
+ });
191
+ window.addEventListener("pointermove", record, {
192
+ capture: true,
193
+ passive: true
194
+ });
195
+ window.addEventListener("pointerup", record, {
196
+ capture: true,
197
+ passive: true
198
+ });
199
+ }
200
+ /** the pointer's page position now, or null before any pointer event */
201
+ function gesturePoint() {
202
+ const last = samples[samples.length - 1];
203
+ return last ? {
204
+ x: last.x,
205
+ y: last.y
206
+ } : null;
207
+ }
208
+ /** units per second over the recent window — what a spring inherits */
209
+ function gestureVelocity() {
210
+ if (samples.length < 2) return {
211
+ x: 0,
212
+ y: 0
213
+ };
214
+ const now = performance.now();
215
+ const a = samples.filter((s) => now - s.t < 120)[0] ?? samples[samples.length - 2];
216
+ const b = samples[samples.length - 1];
217
+ const dt = (b.t - a.t) / 1e3;
218
+ if (dt <= 0) return {
219
+ x: 0,
220
+ y: 0
221
+ };
222
+ return {
223
+ x: (b.x - a.x) / dt,
224
+ y: (b.y - a.y) / dt
225
+ };
226
+ }
227
+ /** the gesture as a box: the sprite\'s own size, centred on the pointer */
228
+ function gestureBounds(size) {
229
+ const point = gesturePoint();
230
+ if (!point) return null;
231
+ const page = {
232
+ height: size.height,
233
+ width: size.width,
234
+ x: point.x - size.width / 2,
235
+ y: point.y - size.height / 2
236
+ };
237
+ return {
238
+ context: page,
239
+ page,
240
+ parent: page
241
+ };
242
+ }
243
+ /** test-support: forget everything between tests */
244
+ function resetGestures() {
245
+ samples = [];
246
+ }
247
+ //#endregion
248
+ //#region ../choreo/src/compile.ts
249
+ /**
250
+ * boxel-motion's OrchestrationMatrix, as a cue list: the timeline tree becomes
251
+ * one (sprite, start, duration) per step per sprite. Sequences add, parallels
252
+ * overlay; a spring's length is computed with the engine's own generator so a
253
+ * sequence can follow one — the thing the legacy could not do.
254
+ */
255
+ var isBlock = (node) => node.kind === "sequence" || node.kind === "parallel";
256
+ var isGate = (node) => node.kind === "gate";
257
+ var DEFAULT_SPRING = {
258
+ damping: 30,
259
+ stiffness: 300
260
+ };
261
+ /**
262
+ * What `c.Follow` is allowed to drive: paint, never layout. See the throw
263
+ * in the 'follow' case for why the line is drawn exactly here.
264
+ */
265
+ var DERIVABLE = new Set([
266
+ "filter",
267
+ "opacity",
268
+ "rotate",
269
+ "rotateX",
270
+ "rotateY",
271
+ "rotateZ",
272
+ "scale",
273
+ "scaleX",
274
+ "scaleY",
275
+ "skewX",
276
+ "skewY",
277
+ "x",
278
+ "y",
279
+ "z"
280
+ ]);
281
+ /** the shared offstage <svg> that path geometry is sampled inside */
282
+ var pathHost;
283
+ function samplePath(d, samples = 64) {
284
+ if (!pathHost) {
285
+ pathHost = document.createElementNS("http://www.w3.org/2000/svg", "svg");
286
+ pathHost.setAttribute("aria-hidden", "true");
287
+ pathHost.style.cssText = "position:absolute;width:0;height:0;overflow:hidden";
288
+ document.body.appendChild(pathHost);
289
+ }
290
+ const el = document.createElementNS("http://www.w3.org/2000/svg", "path");
291
+ el.setAttribute("d", d);
292
+ pathHost.appendChild(el);
293
+ try {
294
+ const length = el.getTotalLength();
295
+ return Array.from({ length: samples + 1 }, (_, i) => {
296
+ const pt = el.getPointAtLength(length * i / samples);
297
+ return {
298
+ x: pt.x,
299
+ y: pt.y
300
+ };
301
+ });
302
+ } finally {
303
+ el.remove();
304
+ }
305
+ }
306
+ /**
307
+ * Similarity-map a drawn path so its start is the sprite's start and its end
308
+ * is the measured landing (§4.4): the path bends the journey, never the
309
+ * destination. Complex multiplication: m = D / v rotates and scales the
310
+ * author's stroke onto the real displacement.
311
+ */
312
+ function mapFlight(raw, dx, dy) {
313
+ const s0 = raw[0];
314
+ const e = raw[raw.length - 1];
315
+ const vx = e.x - s0.x;
316
+ const vy = e.y - s0.y;
317
+ const mag = vx * vx + vy * vy;
318
+ if (mag < 1e-6) return raw.map((_, i) => ({
319
+ x: dx * i / (raw.length - 1),
320
+ y: dy * i / (raw.length - 1)
321
+ }));
322
+ const mr = (dx * vx + dy * vy) / mag;
323
+ const mi = (dy * vx - dx * vy) / mag;
324
+ return raw.map((pt) => {
325
+ const px = pt.x - s0.x;
326
+ const py = pt.y - s0.y;
327
+ return {
328
+ x: px * mr - py * mi,
329
+ y: px * mi + py * mr
330
+ };
331
+ });
332
+ }
333
+ var resolve = (v, sprite, cs) => typeof v === "function" ? v(sprite, cs) : v;
334
+ var single = (v) => Array.isArray(v) ? v[0] : v;
335
+ var num = (v) => {
336
+ if (typeof v === "number") return v;
337
+ const n = parseFloat(String(v));
338
+ return Number.isNaN(n) ? 0 : n;
339
+ };
340
+ /** the value a spring starts from when the step does not say: the engine's, else the computed style's */
341
+ function currentValue(sprite, key) {
342
+ const ve = sprite.node.visualElement;
343
+ if (ve?.hasValue(key)) return num(ve.getValue(key).get());
344
+ const latest = ve?.latestValues?.[key];
345
+ if (latest !== void 0) return num(latest);
346
+ return num(getComputedStyle(sprite.element).getPropertyValue(key.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase())));
347
+ }
348
+ function springDuration(from, to, spec) {
349
+ if (from === to) return 0;
350
+ const generator = spring({
351
+ keyframes: [from, to],
352
+ ...spec
353
+ });
354
+ return Math.min(calcGeneratorDuration(generator), maxGeneratorDuration);
355
+ }
356
+ /** a cue before it is placed on the run's clock; `offset` is its rung of the stagger ladder */
357
+ /**
358
+ * The rung each index takes on the stagger ladder, under a delivery order.
359
+ * 'center' delivers from the middle outward; 'random' shuffles per run —
360
+ * seeded input is the native driver's requirement, not this one's.
361
+ */
362
+ function ladder(n, order) {
363
+ const ranks = Array.from({ length: n }, (_, i) => i);
364
+ switch (order) {
365
+ case "reverse": return ranks.map((i) => n - 1 - i);
366
+ case "center": {
367
+ const mid = (n - 1) / 2;
368
+ const byDistance = [...ranks].sort((a, b) => Math.abs(a - mid) - Math.abs(b - mid));
369
+ const out = new Array(n);
370
+ byDistance.forEach((index, rank) => out[index] = rank);
371
+ return out;
372
+ }
373
+ case "random": {
374
+ const shuffled = [...ranks];
375
+ for (let i = n - 1; i > 0; i--) {
376
+ const j = Math.floor(Math.random() * (i + 1));
377
+ [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
378
+ }
379
+ const out = new Array(n);
380
+ shuffled.forEach((index, rank) => out[index] = rank);
381
+ return out;
382
+ }
383
+ default: return ranks;
384
+ }
385
+ }
386
+ function resolveTarget(step, sprite, cs) {
387
+ const target = {};
388
+ let longest = 0;
389
+ for (const key in step.props) {
390
+ const to = resolve(step.props[key], sprite, cs);
391
+ if (Array.isArray(to)) {
392
+ if (step.kind === "spring" && to.length > 2) throw new Error(`choreo: a spring animates between two keyframes; \`${key}\` was given ${to.length}`);
393
+ target[key] = to;
394
+ if (step.kind === "spring") longest = Math.max(longest, springDuration(num(to[0]), num(to[to.length - 1]), step.spring ?? DEFAULT_SPRING));
395
+ } else {
396
+ target[key] = to;
397
+ if (step.kind === "spring") longest = Math.max(longest, springDuration(currentValue(sprite, key), num(to), step.spring ?? DEFAULT_SPRING));
398
+ }
399
+ }
400
+ return {
401
+ longest,
402
+ target
403
+ };
404
+ }
405
+ /**
406
+ * The two boxes a shape-matched flight aligns: the declared subjects
407
+ * ([data-choreo-substance], or pack="content" ink) when either end has
408
+ * one — Keynote matches OBJECTS, not slide frames — with the undeclared
409
+ * end derived by fraction (content laid out proportionally keeps one
410
+ * fraction at both scales; the return trip's card, whose demo has not
411
+ * boarded yet, has nothing to measure). Neither end declared: the frames
412
+ * themselves.
413
+ */
414
+ function matchBoxes(initial, final, from, to, z) {
415
+ const subI = initial.substance && descale(initial.substance, z);
416
+ const subF = final.substance && descale(final.substance, z);
417
+ if (!subI && !subF) return {
418
+ from,
419
+ to
420
+ };
421
+ const map = (s, a, b) => ({
422
+ height: s.height / (a.height || 1) * b.height,
423
+ width: s.width / (a.width || 1) * b.width,
424
+ x: b.x + (s.x - a.x) / (a.width || 1) * b.width,
425
+ y: b.y + (s.y - a.y) / (a.height || 1) * b.height
426
+ });
427
+ return {
428
+ from: subI ?? map(subF, to, from),
429
+ to: subF ?? map(subI, from, to)
430
+ };
431
+ }
432
+ var centreOf = (r) => ({
433
+ x: r.x + r.width / 2,
434
+ y: r.y + r.height / 2
435
+ });
436
+ /** a page-space box, divided back into local space by the measure-time zoom */
437
+ function descale(r, z) {
438
+ return z === 1 ? r : {
439
+ height: r.height / z,
440
+ width: r.width / z,
441
+ x: r.x / z,
442
+ y: r.y / z
443
+ };
444
+ }
445
+ function resolveMove(step, sprite, cs) {
446
+ const size = (sprite.final ?? sprite.initial)?.page ?? {
447
+ height: 0,
448
+ width: 0,
449
+ x: 0,
450
+ y: 0
451
+ };
452
+ const hot = step.from && isGestureRef(step.from);
453
+ const borrowedFrom = step.from ? hot ? gestureBounds(size) : cs.beacon(step.from.beacon) : null;
454
+ const borrowedTo = step.to ? cs.beacon(step.to.beacon) : null;
455
+ const initial = borrowedFrom ?? sprite.initial;
456
+ const final = borrowedTo ?? sprite.final;
457
+ if (!initial || !final) return null;
458
+ const z = cs.measureZoom ?? 1;
459
+ const parentSpace = step.space === "parent" && !borrowedFrom && !borrowedTo;
460
+ const from = descale(parentSpace ? initial.parent : initial.page, z);
461
+ const to = descale(parentSpace ? final.parent : final.page, z);
462
+ const target = {};
463
+ const pairs = [];
464
+ const scaleMode = step.size === "scale" || step.size === "crop";
465
+ const cropMode = step.size === "crop";
466
+ const m = scaleMode ? matchBoxes(initial, final, from, to, z) : null;
467
+ const dx = m ? centreOf(m.to).x - centreOf(m.from).x : to.x - from.x;
468
+ const dy = m ? cropMode ? m.to.y - m.from.y : centreOf(m.to).y - centreOf(m.from).y : to.y - from.y;
469
+ /**
470
+ * Which end the element is actually sitting on decides the sign.
471
+ *
472
+ * The usual FLIP case is a kept sprite: the pass has already put it at its
473
+ * destination, so it is pulled back by the delta and animated to zero. A
474
+ * REMOVED sprite is the other way round — the region has locked it in the
475
+ * orphan layer at the place it was, so it starts at zero and travels the
476
+ * delta. That is the only case that can have a `final` at all, and it only
477
+ * has one because a beacon lent it one.
478
+ */
479
+ const holdsStart = sprite.type === "removed";
480
+ const leg = (d) => holdsStart ? [0, d] : [-d, 0];
481
+ let flight;
482
+ if (step.path && (dx !== 0 || dy !== 0)) {
483
+ flight = {
484
+ points: mapFlight(samplePath(step.path), dx, dy),
485
+ rest: holdsStart ? {
486
+ x: 0,
487
+ y: 0
488
+ } : {
489
+ x: dx,
490
+ y: dy
491
+ },
492
+ rotate: step.rotate
493
+ };
494
+ pairs.push(leg(Math.hypot(dx, dy)));
495
+ } else if (m) {
496
+ const crop = cropMode;
497
+ const rx = m.from.width / (m.to.width || 1) || 1;
498
+ const ry = m.from.height / (m.to.height || 1) || 1;
499
+ const su = rx;
500
+ const sx = crop ? su : rx;
501
+ const sy = crop ? su : ry;
502
+ const fx = holdsStart ? 1 / sx : sx;
503
+ const fy = holdsStart ? 1 / sy : sy;
504
+ const anchor = centreOf(holdsStart ? from : to);
505
+ const matched = holdsStart ? m.from : m.to;
506
+ const pinned = crop ? {
507
+ x: centreOf(matched).x,
508
+ y: matched.y
509
+ } : centreOf(matched);
510
+ const cx = (1 - fx) * (pinned.x - anchor.x);
511
+ const cy = (1 - fy) * (pinned.y - anchor.y);
512
+ const x = holdsStart ? dx + cx : -dx + cx;
513
+ const y = holdsStart ? dy + cy : -dy + cy;
514
+ if (x !== 0) {
515
+ target["x"] = holdsStart ? [0, x] : [x, 0];
516
+ pairs.push(holdsStart ? [0, x] : [x, 0]);
517
+ }
518
+ if (y !== 0) {
519
+ target["y"] = holdsStart ? [0, y] : [y, 0];
520
+ pairs.push(holdsStart ? [0, y] : [y, 0]);
521
+ }
522
+ if (crop) {
523
+ if (fx !== 1) target["scale"] = holdsStart ? [1, fx] : [fx, 1];
524
+ const frame = holdsStart ? from : to;
525
+ const window = holdsStart ? m.to : m.from;
526
+ const f = holdsStart ? fx : sx;
527
+ const d = {
528
+ x,
529
+ y
530
+ };
531
+ const pre = (edge) => anchor.y + (edge - anchor.y - d.y) / f;
532
+ const clamp = (v) => Math.max(0, v);
533
+ const b = clamp(frame.y + frame.height - pre(window.y + window.height));
534
+ if (b > .5) {
535
+ const far = `inset(0px 0px ${b.toFixed(2)}px 0px)`;
536
+ const rest = "inset(0px 0px 0px 0px)";
537
+ target["clipPath"] = holdsStart ? [rest, far] : [far, rest];
538
+ }
539
+ } else {
540
+ if (fx !== 1) target["scaleX"] = holdsStart ? [1, fx] : [fx, 1];
541
+ if (fy !== 1) target["scaleY"] = holdsStart ? [1, fy] : [fy, 1];
542
+ }
543
+ } else {
544
+ if (dx !== 0) {
545
+ target["x"] = leg(dx);
546
+ pairs.push(leg(dx));
547
+ }
548
+ if (dy !== 0) {
549
+ target["y"] = leg(dy);
550
+ pairs.push(leg(dy));
551
+ }
552
+ }
553
+ if (scaleMode) {} else if (step.size !== false) {
554
+ if (from.width !== to.width) {
555
+ target["width"] = [from.width, to.width];
556
+ pairs.push([from.width, to.width]);
557
+ }
558
+ if (from.height !== to.height) {
559
+ target["height"] = [from.height, to.height];
560
+ pairs.push([from.height, to.height]);
561
+ }
562
+ }
563
+ if (!pairs.length) return null;
564
+ let longest = step.ms ?? 0;
565
+ if (step.ms === void 0) {
566
+ const spec = step.spring ?? DEFAULT_SPRING;
567
+ for (const [a, b] of pairs) longest = Math.max(longest, springDuration(a, b, spec));
568
+ }
569
+ return {
570
+ flight,
571
+ longest,
572
+ target,
573
+ velocity: hot ? gestureVelocity() : void 0
574
+ };
575
+ }
576
+ /** parse a computed rgb()/rgba() color into channels, or null */
577
+ function rgbOf(css) {
578
+ if (!css) return null;
579
+ const m = /^rgba?\(([\d.]+),\s*([\d.]+),\s*([\d.]+)(?:,\s*([\d.]+))?\)$/.exec(css);
580
+ if (!m) return null;
581
+ return {
582
+ a: m[4] === void 0 ? 1 : parseFloat(m[4]),
583
+ b: parseFloat(m[3]),
584
+ g: parseFloat(m[2]),
585
+ r: parseFloat(m[1])
586
+ };
587
+ }
588
+ /**
589
+ * A skin's EFFECTIVE color: its background alpha-blended against the ground
590
+ * it stood on — opacity turned into an actual color (§4.7). Null when the
591
+ * skin has no visible background (type over transparency crossfades as
592
+ * opacity, there is nothing to solidify) or wears a color this parser does
593
+ * not speak, in which case the crossfade stays a plain dissolve.
594
+ */
595
+ function effective(paint, ground) {
596
+ const src = rgbOf(paint);
597
+ if (!src || src.a === 0) return null;
598
+ if (src.a === 1) return `rgb(${src.r}, ${src.g}, ${src.b})`;
599
+ const dst = rgbOf(ground);
600
+ if (!dst) return null;
601
+ const mix = (s, d) => Math.round(s * src.a + d * (1 - src.a));
602
+ return `rgb(${mix(src.r, dst.r)}, ${mix(src.g, dst.g)}, ${mix(src.b, dst.b)})`;
603
+ }
604
+ var tweenTransition = (step, ms) => ({
605
+ duration: ms / 1e3,
606
+ ease: step.ease ?? "easeInOut",
607
+ type: "tween",
608
+ ..."times" in step && step.times ? { times: step.times } : {}
609
+ });
610
+ var springTransition = (spec) => ({
611
+ ...spec ?? DEFAULT_SPRING,
612
+ type: "spring"
613
+ });
614
+ function resolveStep(step, cs, exclude) {
615
+ const sprites = cs.sprites(step.of ?? {}).filter((s) => !exclude || !exclude.has(s));
616
+ const delay = step.delay ?? 0;
617
+ const cues = [];
618
+ const stagger = step.stagger ?? 0;
619
+ /** text delivery: the sprite is split and the ladder happens INSIDE the
620
+ * step's span, so the sprites themselves are not laddered */
621
+ const splitting = (step.kind === "tween" || step.kind === "spring") && step.by !== void 0 && step.by !== "item";
622
+ const order = step.kind === "tween" || step.kind === "spring" ? step.order ?? "forward" : "forward";
623
+ const ranks = splitting ? [] : ladder(sprites.length, order);
624
+ let longest = 0;
625
+ let open = false;
626
+ for (const [index, sprite] of sprites.entries()) {
627
+ if ((step.kind === "camera" || step.kind === "camera3d" || step.kind === "tether" || step.of === void 0) && index > 0) break;
628
+ const offset = splitting ? 0 : stagger * (ranks[index] ?? index);
629
+ switch (step.kind) {
630
+ case "tween": {
631
+ const { target } = resolveTarget(step, sprite, cs);
632
+ if (step.times !== void 0) {
633
+ const times = step.times;
634
+ if (times.length < 2 || times[0] !== 0 || times[times.length - 1] !== 1 || times.some((time, i) => !Number.isFinite(time) || time < 0 || time > 1 || i > 0 && time <= times[i - 1]) || Object.values(target).some((value) => Array.isArray(value) && value.length !== times.length)) throw new Error("choreo: Tween times must increase from 0 to 1 and match every keyframe array");
635
+ }
636
+ if (Object.keys(target).length) {
637
+ const loop = step.repeat === Infinity;
638
+ const plays = loop ? 1 : 1 + (step.repeat ?? 0);
639
+ const length = step.ms * plays;
640
+ const transition = tweenTransition(step, step.ms);
641
+ if (step.repeat) {
642
+ transition["repeat"] = step.repeat;
643
+ transition["repeatType"] = step.repeatType ?? "loop";
644
+ }
645
+ cues.push({
646
+ delivery: splitting ? {
647
+ by: step.by,
648
+ order,
649
+ stagger
650
+ } : void 0,
651
+ duration: length,
652
+ kind: "tween",
653
+ loop: loop || void 0,
654
+ offset,
655
+ sprite,
656
+ target,
657
+ transition
658
+ });
659
+ longest = Math.max(longest, offset + (loop ? step.ms : length));
660
+ }
661
+ break;
662
+ }
663
+ case "spring": {
664
+ const { target, longest: d } = resolveTarget(step, sprite, cs);
665
+ if (Object.keys(target).length) {
666
+ cues.push({
667
+ delivery: splitting ? {
668
+ by: step.by,
669
+ order,
670
+ stagger
671
+ } : void 0,
672
+ duration: d,
673
+ kind: "spring",
674
+ offset,
675
+ sprite,
676
+ target,
677
+ transition: springTransition(step.spring)
678
+ });
679
+ longest = Math.max(longest, offset + d);
680
+ }
681
+ break;
682
+ }
683
+ case "move": {
684
+ const r = resolveMove(step, sprite, cs);
685
+ if (r) {
686
+ const transition = step.ms === void 0 ? springTransition(step.spring) : tweenTransition(step, step.ms);
687
+ if (r.velocity && step.ms === void 0) {
688
+ if (r.target["x"]) transition["x"] = {
689
+ ...transition,
690
+ velocity: r.velocity.x
691
+ };
692
+ if (r.target["y"]) transition["y"] = {
693
+ ...transition,
694
+ velocity: r.velocity.y
695
+ };
696
+ }
697
+ cues.push({
698
+ duration: r.longest,
699
+ flight: r.flight,
700
+ kind: "move",
701
+ offset,
702
+ sprite,
703
+ target: r.target,
704
+ transition
705
+ });
706
+ longest = Math.max(longest, offset + r.longest);
707
+ const cp = sprite.counterpart;
708
+ const swap = step.swap ?? "during";
709
+ if (cp && !cp.sent && swap !== "none" && sprite.final && cp.initial) {
710
+ const cpz = cs.measureZoom ?? 1;
711
+ const from = descale(cp.initial.page, cpz);
712
+ const to = descale(sprite.final.page, cpz);
713
+ const cpTarget = {};
714
+ if (step.size === "scale" || step.size === "crop") {
715
+ const crop = step.size === "crop";
716
+ const cpm = matchBoxes(cp.initial, sprite.final, from, to, cpz);
717
+ const mf = centreOf(cpm.from);
718
+ const mt = centreOf(cpm.to);
719
+ const anchor = centreOf(from);
720
+ const rx = cpm.to.width / (cpm.from.width || 1) || 1;
721
+ const ry = cpm.to.height / (cpm.from.height || 1) || 1;
722
+ const eu = rx;
723
+ const ex = crop ? eu : rx;
724
+ const ey = crop ? eu : ry;
725
+ const dxe = mt.x - anchor.x - ex * (mf.x - anchor.x);
726
+ const dye = crop ? cpm.to.y - anchor.y - ey * (cpm.from.y - anchor.y) : mt.y - anchor.y - ey * (mf.y - anchor.y);
727
+ if (dxe !== 0) cpTarget["x"] = [0, dxe];
728
+ if (dye !== 0) cpTarget["y"] = [0, dye];
729
+ if (crop) {
730
+ if (ex !== 1) cpTarget["scale"] = [1, ex];
731
+ const pre = (edge) => anchor.y + (edge - anchor.y - dye) / ex;
732
+ const clamp = (v) => Math.max(0, v);
733
+ const cb = clamp(from.y + from.height - pre(cpm.to.y + cpm.to.height));
734
+ if (cb > .5) cpTarget["clipPath"] = ["inset(0px 0px 0px 0px)", `inset(0px 0px ${cb.toFixed(2)}px 0px)`];
735
+ } else {
736
+ if (ex !== 1) cpTarget["scaleX"] = [1, ex];
737
+ if (ey !== 1) cpTarget["scaleY"] = [1, ey];
738
+ }
739
+ } else {
740
+ if (to.x !== from.x) cpTarget["x"] = [0, to.x - from.x];
741
+ if (to.y !== from.y) cpTarget["y"] = [0, to.y - from.y];
742
+ if (step.size !== false) {
743
+ if (from.width !== to.width) cpTarget["width"] = [from.width, to.width];
744
+ if (from.height !== to.height) cpTarget["height"] = [from.height, to.height];
745
+ }
746
+ }
747
+ if (Object.keys(cpTarget).length) cues.push({
748
+ duration: r.longest,
749
+ kind: "move",
750
+ offset,
751
+ sprite: cp,
752
+ target: cpTarget,
753
+ transition
754
+ });
755
+ if (swap === "during") {
756
+ const oldSkin = effective(cp.initial?.paint, cs.ground);
757
+ const newSkin = effective(sprite.final?.paint, cs.ground);
758
+ const fade = {
759
+ duration: r.longest / 1e3,
760
+ ease: "easeInOut"
761
+ };
762
+ if (oldSkin && newSkin) {
763
+ cues.push({
764
+ borrow: true,
765
+ duration: r.longest,
766
+ kind: "tween",
767
+ offset,
768
+ sprite,
769
+ target: { backgroundColor: [oldSkin, newSkin] },
770
+ transition: fade
771
+ });
772
+ cues.push({
773
+ duration: r.longest,
774
+ hold: {
775
+ fill: false,
776
+ values: { zIndex: 3 }
777
+ },
778
+ kind: "hold",
779
+ offset,
780
+ sprite: cp
781
+ });
782
+ } else cues.push({
783
+ duration: r.longest,
784
+ kind: "tween",
785
+ offset,
786
+ sprite,
787
+ target: { opacity: [0, 1] },
788
+ transition: fade
789
+ });
790
+ cues.push({
791
+ duration: r.longest,
792
+ kind: "tween",
793
+ offset,
794
+ sprite: cp,
795
+ target: { opacity: [1, 0] },
796
+ transition: fade
797
+ });
798
+ } else cues.push({
799
+ duration: r.longest,
800
+ hold: {
801
+ fill: false,
802
+ values: { opacity: 0 }
803
+ },
804
+ kind: "hold",
805
+ offset,
806
+ sprite
807
+ });
808
+ }
809
+ }
810
+ break;
811
+ }
812
+ case "hold": {
813
+ const values = {};
814
+ for (const key in step.props) values[key] = single(resolve(step.props[key], sprite, cs));
815
+ cues.push({
816
+ duration: step.ms ?? 0,
817
+ hold: {
818
+ fill: step.fill ?? false,
819
+ values
820
+ },
821
+ kind: "hold",
822
+ offset,
823
+ sprite
824
+ });
825
+ if (step.ms === void 0) open = true;
826
+ else longest = Math.max(longest, offset + step.ms);
827
+ break;
828
+ }
829
+ case "camera": {
830
+ const ms = step.ms ?? 600;
831
+ const fitting = step.fit !== void 0;
832
+ const aiming = step.aim !== void 0;
833
+ const aimQuery = fitting ? step.fit : step.aim ?? step.origin;
834
+ const originSprite = aimQuery ? cs.sprite(aimQuery) : null;
835
+ const box = originSprite?.final?.context ?? originSprite?.initial?.context;
836
+ const oz = cs.measureZoom ?? 1;
837
+ const origin = box ? {
838
+ x: (box.x + box.width / 2) / oz,
839
+ y: (box.y + box.height / 2) / oz
840
+ } : void 0;
841
+ let to = {
842
+ x: step.x,
843
+ y: step.y,
844
+ zoom: step.zoom
845
+ };
846
+ const by = step.panBy || step.zoomBy !== void 0 ? {
847
+ x: step.panBy?.x,
848
+ y: step.panBy?.y,
849
+ zoom: step.zoomBy
850
+ } : void 0;
851
+ if (aiming && !fitting) to = box && origin && cs.frame ? {
852
+ x: cs.frame.width / 2 - origin.x,
853
+ y: cs.frame.height / 2 - origin.y,
854
+ zoom: void 0
855
+ } : {
856
+ x: 0,
857
+ y: 0,
858
+ zoom: 1
859
+ };
860
+ if (fitting) if (box && origin && cs.frame) {
861
+ const zoom = step.zoom ?? (step.margin ?? .72) * Math.min(cs.frame.width * oz / box.width, cs.frame.height * oz / box.height);
862
+ to = {
863
+ x: cs.frame.width / 2 - origin.x,
864
+ y: cs.frame.height / 2 - origin.y,
865
+ zoom
866
+ };
867
+ } else to = {
868
+ x: 0,
869
+ y: 0,
870
+ zoom: 1
871
+ };
872
+ cues.push({
873
+ camera: {
874
+ by,
875
+ centre: cs.frame ? {
876
+ x: cs.frame.width / 2,
877
+ y: cs.frame.height / 2
878
+ } : void 0,
879
+ origin,
880
+ steady: step.steady ? cs.sprites(step.steady) : [],
881
+ to
882
+ },
883
+ duration: ms,
884
+ kind: "camera",
885
+ offset,
886
+ sprite,
887
+ transition: step.spring ? springTransition(step.spring) : {
888
+ duration: ms / 1e3,
889
+ ease: step.ease ?? "easeInOut"
890
+ }
891
+ });
892
+ longest = Math.max(longest, offset + ms);
893
+ break;
894
+ }
895
+ case "camera3d": {
896
+ const ms = step.ms ?? 600;
897
+ cues.push({
898
+ camera3d: {
899
+ by: step.by,
900
+ settle: step.settle,
901
+ tension: step.tension,
902
+ through: step.through,
903
+ to: {
904
+ dolly: step.dolly,
905
+ look: step.look,
906
+ pitch: step.pitch,
907
+ x: step.x,
908
+ y: step.y,
909
+ yaw: step.yaw
910
+ }
911
+ },
912
+ duration: ms,
913
+ kind: "camera3d",
914
+ offset,
915
+ sprite,
916
+ transition: step.spring ? springTransition(step.spring) : {
917
+ duration: ms / 1e3,
918
+ ease: step.ease ?? "easeInOut"
919
+ }
920
+ });
921
+ longest = Math.max(longest, offset + ms);
922
+ break;
923
+ }
924
+ case "tether":
925
+ cues.push({
926
+ duration: step.ms ?? 0,
927
+ kind: "tether",
928
+ offset,
929
+ sprite,
930
+ tether: {
931
+ from: cs.sprites(step.from)[0] ?? null,
932
+ name: step.name,
933
+ path: step.path,
934
+ to: cs.sprites(step.to)[0] ?? null
935
+ }
936
+ });
937
+ if (step.ms === void 0) open = true;
938
+ else longest = Math.max(longest, offset + step.ms);
939
+ break;
940
+ case "follow": {
941
+ for (const key of Object.keys(step.rest)) if (!DERIVABLE.has(key)) throw new Error(`choreo: c.Follow cannot drive '${key}' — a derived value is computed every frame, so it may only write transform, opacity and filter properties, never layout`);
942
+ const fz = cs.measureZoom ?? 1;
943
+ const inZ = (r) => ({
944
+ height: r.height / fz,
945
+ width: r.width / fz,
946
+ x: r.x / fz,
947
+ y: r.y / fz
948
+ });
949
+ const restBounds = sprite.final ?? sprite.initial;
950
+ if (!restBounds) break;
951
+ const followed = [];
952
+ for (const source of cs.sprites(step.to)) {
953
+ const toB = source.final ?? source.initial;
954
+ const fromB = source.initial ?? source.final;
955
+ if (toB && fromB) followed.push({
956
+ from: inZ(fromB.context),
957
+ sprite: source,
958
+ to: inZ(toB.context)
959
+ });
960
+ }
961
+ const ms = step.ms;
962
+ cues.push({
963
+ derive: {
964
+ read: step.read,
965
+ rest: step.rest,
966
+ restBox: inZ(restBounds.context),
967
+ sources: followed
968
+ },
969
+ duration: ms ?? 0,
970
+ kind: "follow",
971
+ offset,
972
+ sprite
973
+ });
974
+ if (ms === void 0) open = true;
975
+ else longest = Math.max(longest, offset + ms);
976
+ break;
977
+ }
978
+ case "scroll": {
979
+ const ms = step.ms ?? 420;
980
+ cues.push({
981
+ duration: ms,
982
+ kind: "scroll",
983
+ offset,
984
+ scroll: { align: step.align ?? "center" },
985
+ sprite
986
+ });
987
+ longest = Math.max(longest, offset + ms);
988
+ break;
989
+ }
990
+ case "raise":
991
+ cues.push({
992
+ duration: step.ms ?? 0,
993
+ kind: "raise",
994
+ offset,
995
+ raise: { shadow: step.shadow ?? false },
996
+ sprite
997
+ });
998
+ if (step.ms === void 0) open = true;
999
+ else longest = Math.max(longest, offset + step.ms);
1000
+ break;
1001
+ case "attach":
1002
+ cues.push({
1003
+ attach: {
1004
+ end: step.end ?? "hold",
1005
+ exact: step.exact ?? false,
1006
+ in: step.in ?? 0,
1007
+ rate: step.rate ?? 1,
1008
+ region: step.region
1009
+ },
1010
+ duration: step.ms,
1011
+ kind: "attach",
1012
+ offset,
1013
+ sprite
1014
+ });
1015
+ longest = Math.max(longest, offset + step.ms);
1016
+ break;
1017
+ case "wait":
1018
+ cues.push({
1019
+ duration: step.ms,
1020
+ kind: "wait",
1021
+ offset,
1022
+ sprite
1023
+ });
1024
+ longest = Math.max(longest, offset + step.ms);
1025
+ break;
1026
+ case "perform":
1027
+ cues.push({
1028
+ duration: 0,
1029
+ kind: "perform",
1030
+ offset,
1031
+ perform: {
1032
+ action: step.action,
1033
+ payload: step.payload,
1034
+ target: step.target
1035
+ },
1036
+ sprite
1037
+ });
1038
+ longest = Math.max(longest, offset);
1039
+ break;
1040
+ }
1041
+ }
1042
+ return {
1043
+ cues,
1044
+ duration: cues.length ? delay + longest : 0,
1045
+ open
1046
+ };
1047
+ }
1048
+ function compile(tree, cs) {
1049
+ const explicit = /* @__PURE__ */ new Set();
1050
+ const claim = (node) => {
1051
+ if (isGate(node)) return;
1052
+ if (isBlock(node)) {
1053
+ node.children.forEach(claim);
1054
+ return;
1055
+ }
1056
+ if (node.generic || node.kind !== "tween" && node.kind !== "spring" && node.kind !== "move" && node.kind !== "hold") return;
1057
+ const q = node.of;
1058
+ if (!(Array.isArray(q) ? q.length > 0 : q.id !== void 0 || q.role !== void 0 || q.type !== void 0)) return;
1059
+ for (const s of cs.sprites(q)) explicit.add(s);
1060
+ };
1061
+ tree.forEach(claim);
1062
+ const resolved = /* @__PURE__ */ new Map();
1063
+ const of = (step) => {
1064
+ let r = resolved.get(step);
1065
+ if (!r) {
1066
+ r = resolveStep(step, cs, step.generic ? explicit : void 0);
1067
+ resolved.set(step, r);
1068
+ }
1069
+ return r;
1070
+ };
1071
+ /**
1072
+ * A node's own length, anchoring aside — for a block, the span its
1073
+ * children occupy, which is what a `@name` on it promises to anyone who
1074
+ * anchors against it.
1075
+ */
1076
+ const extent = (node) => {
1077
+ if (isGate(node)) return 0;
1078
+ if (!isBlock(node)) return of(node).duration;
1079
+ return node.kind === "sequence" ? node.children.reduce((sum, c) => sum + measure(c), 0) : node.children.reduce((max, c) => Math.max(max, measure(c)), 0);
1080
+ };
1081
+ /** what a node contributes to its parent's flow */
1082
+ const measure = (node) => {
1083
+ if (isGate(node)) return 0;
1084
+ if (node.at) return 0;
1085
+ return isBlock(node) ? (node.delay ?? 0) + extent(node) : of(node).duration;
1086
+ };
1087
+ const out = [];
1088
+ const seen = /* @__PURE__ */ new Set();
1089
+ const checkNames = (node) => {
1090
+ if (isGate(node)) return;
1091
+ if (node.name) {
1092
+ if (seen.has(node.name)) throw new Error(`choreo: two steps named '${node.name}'`);
1093
+ seen.add(node.name);
1094
+ }
1095
+ if (isBlock(node)) node.children.forEach(checkNames);
1096
+ };
1097
+ tree.forEach(checkNames);
1098
+ /** where each named step landed: when it starts (delay spent) and how long it plays */
1099
+ const names = /* @__PURE__ */ new Map();
1100
+ const gates = [];
1101
+ /**
1102
+ * A pause is a total order (§4.1): a gate may only stand in a sequence
1103
+ * that no parallel contains — including the implicit parallel that is the
1104
+ * region's root when it has more than one top-level node.
1105
+ */
1106
+ const forbidGates = (node) => {
1107
+ if (isGate(node)) throw new Error("choreo: a gate inside a parallel has no meaning — a pause is a total order; only an uncontained sequence can hold one");
1108
+ if (isBlock(node)) node.children.forEach(forbidGates);
1109
+ };
1110
+ /**
1111
+ * The whole score's span — computed BEFORE anything is placed, because an
1112
+ * open step's window depends on it.
1113
+ *
1114
+ * A score of nothing but open steps measures zero, and an open step's
1115
+ * window is "the enclosing block's span" — so the annotation the author
1116
+ * asked to be simply ON compiled to a zero-length run that ended on the
1117
+ * frame it was born. That is not a short wire, it is no wire; the app
1118
+ * that hit it wrote `ms: 3_600_000` to get an hour of clock out of a
1119
+ * step whose real lifetime is the scene's. So a score with no length of
1120
+ * its own does not borrow zero: its open cues STAND (§4.6), and the run
1121
+ * holds them until it is cancelled or replaced.
1122
+ */
1123
+ const root = measure({
1124
+ children: tree,
1125
+ kind: "parallel"
1126
+ });
1127
+ const standingScore = root === 0;
1128
+ /** did any cue actually take the standing window? */
1129
+ let stood = false;
1130
+ /** span: the time a hold without @duration is allowed to last from `start` */
1131
+ const place = (node, start, span) => {
1132
+ if (isGate(node)) {
1133
+ gates.push({
1134
+ at: start,
1135
+ auto: node.ms
1136
+ });
1137
+ return;
1138
+ }
1139
+ /** where an anchored node begins — the same arithmetic for a step and a block */
1140
+ const anchored = (ref) => {
1141
+ const target = names.get(ref.anchor);
1142
+ if (!target) throw new Error(`choreo: @at names '${ref.anchor}', which is not a step above this one — anchors point up the score`);
1143
+ return ref.edge === "end" ? target.start + target.duration + (ref.delay ?? 0) * 1e3 : target.start + (ref.progress ?? 0) * target.duration;
1144
+ };
1145
+ if (!isBlock(node)) {
1146
+ const r = of(node);
1147
+ const delay = node.delay ?? 0;
1148
+ let base = start;
1149
+ if (node.at) {
1150
+ if (r.open) throw new Error("choreo: an anchored hold needs its own @duration — lifted out of its block, it has no span to borrow");
1151
+ base = anchored(node.at);
1152
+ }
1153
+ if (node.name) names.set(node.name, {
1154
+ duration: Math.max(0, r.duration - delay),
1155
+ start: base + delay
1156
+ });
1157
+ for (const cue of r.cues) {
1158
+ const { offset, ...rest } = cue;
1159
+ const borrows = r.open && (cue.kind === "hold" || cue.kind === "raise" || cue.kind === "tether" || cue.kind === "follow");
1160
+ if (borrows && standingScore) stood = true;
1161
+ out.push({
1162
+ ...rest,
1163
+ duration: borrows ? standingScore ? Infinity : Math.max(0, span - delay - offset) : cue.duration,
1164
+ standing: borrows && standingScore ? true : void 0,
1165
+ start: base + delay + offset
1166
+ });
1167
+ }
1168
+ return;
1169
+ }
1170
+ const total = extent(node);
1171
+ const from = (node.at ? anchored(node.at) : start) + (node.delay ?? 0);
1172
+ if (node.name) names.set(node.name, {
1173
+ duration: total,
1174
+ start: from
1175
+ });
1176
+ if (node.kind === "sequence") {
1177
+ let offset = 0;
1178
+ for (const child of node.children) {
1179
+ place(child, from + offset, total - offset);
1180
+ offset += measure(child);
1181
+ }
1182
+ return;
1183
+ }
1184
+ node.children.forEach(forbidGates);
1185
+ for (const child of node.children) place(child, from, total);
1186
+ };
1187
+ if (tree.length > 1) tree.forEach(forbidGates);
1188
+ for (const node of tree) place(node, 0, root);
1189
+ gates.sort((a, b) => a.at - b.at);
1190
+ const derived = out.filter((cue) => cue.derive);
1191
+ if (!derived.length) return {
1192
+ cues: out,
1193
+ gates,
1194
+ open: stood
1195
+ };
1196
+ const nameOf = (sprite) => sprite.id ?? sprite.role ?? "a sprite";
1197
+ const drivenBy = /* @__PURE__ */ new Map();
1198
+ for (const cue of derived) drivenBy.set(cue.sprite, cue);
1199
+ for (const cue of derived) for (const source of cue.derive.sources) if (drivenBy.has(source.sprite)) throw new Error(`choreo: c.Follow on '${nameOf(cue.sprite)}' reads '${nameOf(source.sprite)}', which is itself derived — a follower may not follow a follower`);
1200
+ return {
1201
+ cues: [...out.filter((cue) => !cue.derive), ...derived],
1202
+ gates,
1203
+ open: stood
1204
+ };
1205
+ }
1206
+ /**
1207
+ * A replacement pass's continuity cue (§3.1): the prior run was driving
1208
+ * this sprite through space and the new score does not name it. Unnamed
1209
+ * it would be released to its rest in one frame — the whole-bay snap —
1210
+ * so the region completes the score: one shape-matched move from the
1211
+ * painted box (which is what a mid-flight sprite's `initial` IS, by
1212
+ * design) to its rest. Transform-only, so a continuation can never
1213
+ * reflow the scene it is tidying; on the interrupted cue's own spring
1214
+ * when it had one, so the carry-on keeps the flight's character.
1215
+ */
1216
+ function continuation(sprite, cs, inherited) {
1217
+ const r = resolveMove({
1218
+ kind: "move",
1219
+ of: {},
1220
+ size: "scale"
1221
+ }, sprite, cs);
1222
+ if (!r) return null;
1223
+ const springy = inherited && (inherited["type"] === "spring" || "stiffness" in inherited || "visualDuration" in inherited || "bounce" in inherited);
1224
+ return {
1225
+ duration: r.longest,
1226
+ flight: r.flight,
1227
+ kind: "move",
1228
+ sprite,
1229
+ start: 0,
1230
+ target: r.target,
1231
+ transition: springy ? inherited : springTransition(void 0)
1232
+ };
1233
+ }
1234
+ /**
1235
+ * A replacement pass's continuity cue for a cut-short tween (§3.1): the
1236
+ * prior run was taking these values (an opacity, mostly) somewhere and the
1237
+ * new score does not. Stopped where they stood they would stay there for
1238
+ * good — a fade-in frozen at a few percent — so the region carries each on
1239
+ * from its painted value to where it was going, over the time it had left,
1240
+ * after the delay it had left (a staggered arrival that had not begun).
1241
+ */
1242
+ function fadeOn(sprite, to, remaining, delay = 0) {
1243
+ return {
1244
+ duration: remaining,
1245
+ kind: "tween",
1246
+ sprite,
1247
+ start: delay,
1248
+ target: { ...to },
1249
+ transition: {
1250
+ duration: remaining / 1e3,
1251
+ ease: "easeOut"
1252
+ }
1253
+ };
1254
+ }
1255
+ /**
1256
+ * Whether two compiled scores are the SAME statement — used by the region
1257
+ * to keep an in-flight run when an unrelated render replays the pass (the
1258
+ * render detector is volatile by design, so on a busy page every region
1259
+ * re-passes on every app render; a neighbouring demo writing tracked state
1260
+ * per frame must not restart this region's clock).
1261
+ *
1262
+ * The comparison is deliberately conservative. A FLIGHT is measured off the
1263
+ * page and is not comparable by value: any cue carrying one makes the scores
1264
+ * different, and the pass replays exactly as it always did. Values that ARE
1265
+ * comparable (targets, transitions, delivery plans, holds, camera aims)
1266
+ * compare structurally, so an edit that retimes or re-aims anything replays.
1267
+ *
1268
+ * Tethers, raises and scrolls used to be lumped in with flights, and that was
1269
+ * wrong in a way that only showed up on standing annotations: a wire that is
1270
+ * simply ON was recompiled to the identical statement on every pass and, being
1271
+ * declared different every time, had its run torn down and rebuilt — the path
1272
+ * element removed from the layer and a new one appended, sixty times a second
1273
+ * on a busy page. None of the three carries measured geometry in its cue: a
1274
+ * tether is two sprites and a function, a raise is a sprite and a flag, a
1275
+ * scroll is a sprite and an alignment. They compare by IDENTITY, which is
1276
+ * exactly what "the same statement" means for them — and it matters most for
1277
+ * the scroll, where replacing the cue is a visible restart of the scroll.
1278
+ */
1279
+ function sameScore(a, b) {
1280
+ return a.length === b.length && a.every((cue, i) => sameCue(cue, b[i]));
1281
+ }
1282
+ function sameCue(a, b) {
1283
+ if (a.kind !== b.kind || a.sprite.node !== b.sprite.node || a.start !== b.start || a.duration !== b.duration || (a.loop ?? false) !== (b.loop ?? false)) return false;
1284
+ if (a.flight || b.flight) return false;
1285
+ if (a.tether || b.tether) {
1286
+ if (!a.tether || !b.tether || a.tether.from?.node !== b.tether.from?.node || a.tether.to?.node !== b.tether.to?.node || a.tether.path !== b.tether.path || a.tether.name !== b.tether.name) return false;
1287
+ }
1288
+ if (a.raise || b.raise) {
1289
+ if (!a.raise || !b.raise || a.raise.shadow !== b.raise.shadow) return false;
1290
+ }
1291
+ if (a.attach || b.attach) {
1292
+ if (!a.attach || !b.attach || a.attach.region !== b.attach.region || a.attach.in !== b.attach.in || a.attach.rate !== b.attach.rate || a.attach.end !== b.attach.end) return false;
1293
+ }
1294
+ if (a.scroll || b.scroll) {
1295
+ if (!a.scroll || !b.scroll || a.scroll.align !== b.scroll.align) return false;
1296
+ }
1297
+ const plain = (v) => JSON.stringify(v ?? null);
1298
+ const cam = (c) => c ? {
1299
+ centre: c.centre ?? null,
1300
+ origin: c.origin ?? null,
1301
+ steady: c.steady.length,
1302
+ to: c.to
1303
+ } : null;
1304
+ return plain(a.target) === plain(b.target) && plain(a.transition) === plain(b.transition) && plain(a.delivery) === plain(b.delivery) && plain(a.hold) === plain(b.hold) && plain(cam(a.camera)) === plain(cam(b.camera)) && plain(a.camera3d) === plain(b.camera3d);
1305
+ }
1306
+ //#endregion
1307
+ //#region ../choreo/src/far.ts
1308
+ /**
1309
+ * Far matching — one identity, two regions.
1310
+ *
1311
+ * A `<Choreo>` is a scene: it reconciles its own participants and nothing else.
1312
+ * That is the point of nesting, and it is why an element that leaves one region
1313
+ * and appears in another looks like a death and an unrelated birth rather than
1314
+ * one continuous flight.
1315
+ *
1316
+ * Ember Animated calls the two halves `sentSprites` and `receivedSprites` and
1317
+ * pairs them at a `farMatch` rendezvous — every animator that is starting this
1318
+ * pass parks, they all wake together, and each reads the others' lists. The
1319
+ * legacy boxel-motion described this but never built it.
1320
+ *
1321
+ * The rendezvous here is a barrier in the render pass itself, not a timed one.
1322
+ * Every region that will animate this pass announces itself while Glimmer is
1323
+ * still rendering (`join`), the first announcement books one post-render
1324
+ * callback for all of them, and that callback runs three phases in order:
1325
+ *
1326
+ * 1. MEASURE — every region builds its changeset. Nobody has run anything,
1327
+ * so nobody's in-flight values are polluting anybody else's measurement.
1328
+ * 2. MATCH — inserted ids are paired against removed ids in OTHER regions.
1329
+ * 3. RUN — every region compiles and plays its own timeline.
1330
+ *
1331
+ * All three are synchronous, so no frame is painted between a region measuring
1332
+ * and a region pinning its start values. That matters: the whole reason cues
1333
+ * pin synchronously is that one frame of the destination layout is visible
1334
+ * otherwise, and a barrier that yielded would hand that frame back.
1335
+ *
1336
+ * The pairing itself is the same shape as the counterpart matching a region
1337
+ * already does within itself. The receiving element is the one that flies: it
1338
+ * takes the sender's bounds as an `initial` it never had, and the sender is
1339
+ * dropped rather than orphaned, because the thing it would animate is already
1340
+ * being animated somewhere else.
1341
+ *
1342
+ * Bounds cross the boundary in PAGE space, which is the only space the two
1343
+ * regions agree on — a region-relative measurement means nothing to a region
1344
+ * somewhere else on the page.
1345
+ */
1346
+ /** one region's measured pass, waiting for the others before it runs */
1347
+ var intents = /* @__PURE__ */ new Set();
1348
+ var booked = false;
1349
+ /** a seam for the region to book the callback without far.ts importing the scheduler */
1350
+ var schedule = (fn) => fn();
1351
+ function setPassScheduler(fn) {
1352
+ schedule = fn;
1353
+ }
1354
+ /**
1355
+ * Announce that this region has a pass coming. Called while Glimmer is still
1356
+ * rendering, so by the time the barrier runs, every region taking part in this
1357
+ * pass is known — which is what lets the match be synchronous.
1358
+ */
1359
+ function join(host) {
1360
+ intents.add(host);
1361
+ if (!booked) {
1362
+ booked = true;
1363
+ schedule(runBarrier);
1364
+ }
1365
+ }
1366
+ function leave(host) {
1367
+ intents.delete(host);
1368
+ }
1369
+ /** a booked barrier is work outstanding: nothing has measured yet */
1370
+ registerBusyProbe(() => booked && "far-match barrier booked");
1371
+ /**
1372
+ * Drop a barrier that will never run. A test torn down between `join` and the
1373
+ * post-render callback leaves a destroyed region parked in `intents`, and the
1374
+ * next test's first pass would try to measure it. `setupChoreo(hooks)` runs
1375
+ * this before and after every test.
1376
+ */
1377
+ function resetBarrier() {
1378
+ intents.clear();
1379
+ booked = false;
1380
+ }
1381
+ /** mount everything rendered this pass before ANY region measures */
1382
+ var beforeMeasure = () => {};
1383
+ function setBeforeMeasure(fn) {
1384
+ beforeMeasure = fn;
1385
+ }
1386
+ /**
1387
+ * SETTLE: state that the pass implies but that is not markup, settled after
1388
+ * this pass's mounts and before any region measures. A scroll owner (a list
1389
+ * that keeps its scroll at the newest content, or holds a row in place while
1390
+ * rows above it change) holds its anchor here: a scroll position is state,
1391
+ * so it lands in the same pass as the change that moved it, and every region
1392
+ * measures the page as the reader will see it. An element the scroll kept
1393
+ * still then reads as not moved and gets no motion; only what really moved
1394
+ * on screen does.
1395
+ *
1396
+ * A settler only runs inside a barrier, and a barrier runs only when a
1397
+ * region joins a pass: with no region mounted, every region idle, or motion
1398
+ * off, no settler runs. So the owner sets its scroll through its own path as
1399
+ * well (on render or on resize, as it would with no Choreo on the page), and
1400
+ * the settler only makes that happen before regions measure. State never
1401
+ * depends on a settler (ADR 007 §1.1).
1402
+ *
1403
+ * Settlers run in registration order; one that throws is reported and the
1404
+ * pass goes on. Returns the unregister function.
1405
+ */
1406
+ var settlers = /* @__PURE__ */ new Set();
1407
+ function registerSettle(fn) {
1408
+ settlers.add(fn);
1409
+ return () => {
1410
+ settlers.delete(fn);
1411
+ };
1412
+ }
1413
+ function runBarrier() {
1414
+ booked = false;
1415
+ const hosts = [...intents];
1416
+ intents.clear();
1417
+ beforeMeasure();
1418
+ for (const settle of [...settlers]) try {
1419
+ settle();
1420
+ } catch (e) {
1421
+ queueMicrotask(() => {
1422
+ throw e;
1423
+ });
1424
+ }
1425
+ const passes = [];
1426
+ for (const host of hosts) {
1427
+ const pass = host.measurePass();
1428
+ if (pass) passes.push(pass);
1429
+ }
1430
+ if (passes.length > 1) match(passes);
1431
+ for (const pass of passes) pass.host.finishPass(pass);
1432
+ }
1433
+ var deltaOf = (s) => s.initial && s.final ? {
1434
+ height: s.final.page.height - s.initial.page.height,
1435
+ width: s.final.page.width - s.initial.page.width,
1436
+ x: s.final.page.x - s.initial.page.x,
1437
+ y: s.final.page.y - s.initial.page.y
1438
+ } : void 0;
1439
+ /**
1440
+ * Pair an id inserted in one region against the same id removed in another.
1441
+ *
1442
+ * The receiver becomes a kept sprite carrying the sender as its counterpart —
1443
+ * exactly what same-region counterpart matching produces, so every step that
1444
+ * already understands `kept` and `counterpart` works across the boundary with
1445
+ * no further teaching. The sender is flagged `sent` so its own region knows to
1446
+ * let it go quietly instead of playing a removal for it.
1447
+ */
1448
+ function match(passes) {
1449
+ for (const pass of passes) for (const s of pass.inserted) {
1450
+ if (s.id === null || s.counterpart) continue;
1451
+ for (const other of passes) {
1452
+ if (other === pass) continue;
1453
+ const sender = other.removed.find((r) => r.id === s.id && !r.counterpart && !r.sent);
1454
+ if (sender) {
1455
+ sender.sent = true;
1456
+ s.counterpart = sender;
1457
+ s.initial = sender.initial;
1458
+ s.type = "kept";
1459
+ s.delta = deltaOf(s);
1460
+ break;
1461
+ }
1462
+ }
1463
+ }
1464
+ }
1465
+ //#endregion
1466
+ //#region ../choreo/src/registry.ts
1467
+ /**
1468
+ * A region is a participant host (glimmer-motion/participant): its root
1469
+ * renders `data-motion-host` beside `data-choreo`, and registering a region
1470
+ * here registers it as that element's participant host too, so the {{motion}}
1471
+ * elements inside join it. The lookups below are Choreo's own, for code that
1472
+ * already speaks in regions.
1473
+ */
1474
+ /** anything that can put a node on a region's timeline — a step component, or a lane from outside */
1475
+ var hosts = /* @__PURE__ */ new WeakMap();
1476
+ /** regions rendered with `@id`, so an attachment can name one without a DOM query per frame */
1477
+ var hostsById = /* @__PURE__ */ new Map();
1478
+ function setChoreoHost(el, host) {
1479
+ const id = el.getAttribute("data-choreo");
1480
+ if (host) {
1481
+ hosts.set(el, host);
1482
+ setParticipantHost(el, host);
1483
+ if (id) hostsById.set(id, host);
1484
+ } else {
1485
+ const mine = hosts.get(el);
1486
+ hosts.delete(el);
1487
+ setParticipantHost(el, void 0);
1488
+ if (id && mine && hostsById.get(id) === mine) hostsById.delete(id);
1489
+ }
1490
+ }
1491
+ function closestChoreo(el) {
1492
+ const root = el.parentElement?.closest("[data-choreo]");
1493
+ return root ? hosts.get(root) : void 0;
1494
+ }
1495
+ /** the host of a region element itself (not an ancestor's) */
1496
+ function choreoHostAt(el) {
1497
+ return hosts.get(el);
1498
+ }
1499
+ /** the host of the region rendered with `@id` — a lane's way of naming the region it plays in */
1500
+ function choreoHostById(id) {
1501
+ return hostsById.get(id);
1502
+ }
1503
+ //#endregion
1504
+ //#region ../choreo/src/deliver.ts
1505
+ /**
1506
+ * Text delivery — `@by='word' | 'character' | 'paragraph'` (§4.3).
1507
+ *
1508
+ * The split is a run-time costume, not a render: the sprite's own text
1509
+ * nodes are lifted out whole and kept (Glimmer still owns them — a tracked
1510
+ * update mid-flight writes into the detached node and comes back at
1511
+ * restore), stand-in spans deliver the animation, and the restore puts the
1512
+ * original nodes back exactly where they were. Assistive tech reads the
1513
+ * full text throughout: the container carries it as a label while the
1514
+ * chopped-up copy is hidden.
1515
+ *
1516
+ * Slots play on the platform's own animations (WAAPI), not the engine:
1517
+ * they are ephemeral, their schedule is computed once, and a spring's
1518
+ * clock arrives pre-sampled through the generator — the same shape the
1519
+ * native driver uses for everything.
1520
+ */
1521
+ var spanFor = (text) => {
1522
+ const span = document.createElement("span");
1523
+ span.textContent = text;
1524
+ span.setAttribute("aria-hidden", "true");
1525
+ span.style.display = "inline-block";
1526
+ span.style.whiteSpace = "pre";
1527
+ return span;
1528
+ };
1529
+ function textNodesOf(root) {
1530
+ const out = [];
1531
+ const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
1532
+ for (let n = walker.nextNode(); n; n = walker.nextNode()) if ((n.textContent ?? "").length) out.push(n);
1533
+ return out;
1534
+ }
1535
+ function unitsOf(text, by) {
1536
+ if (by === "character") return Array.from(text);
1537
+ return text.match(/\S+\s*|\s+/g) ?? [];
1538
+ }
1539
+ function split(el, by) {
1540
+ if (by === "paragraph") {
1541
+ const slots = Array.from(el.children).filter((c) => c instanceof HTMLElement);
1542
+ if (!slots.length) throw new Error("choreo: @by='paragraph' needs child elements to deliver");
1543
+ return {
1544
+ restore() {},
1545
+ slots: slots.map((s) => ({ el: s }))
1546
+ };
1547
+ }
1548
+ const originals = textNodesOf(el);
1549
+ if (!originals.length) throw new Error(`choreo: @by='${by}' needs text to deliver`);
1550
+ const ws = getComputedStyle(el).whiteSpace;
1551
+ const collapsing = ws === "normal" || ws === "nowrap" || ws === "pre-line";
1552
+ const textOf = (node, index) => {
1553
+ let text = node.textContent ?? "";
1554
+ if (collapsing) {
1555
+ text = text.replace(/\s+/g, " ");
1556
+ if (index === 0) text = text.replace(/^ /, "");
1557
+ if (index === originals.length - 1) text = text.replace(/ $/, "");
1558
+ }
1559
+ return text;
1560
+ };
1561
+ const label = el.getAttribute("aria-label");
1562
+ el.setAttribute("aria-label", el.textContent ?? "");
1563
+ const slots = [];
1564
+ const undo = [];
1565
+ for (const [index, node] of originals.entries()) {
1566
+ const parent = node.parentNode;
1567
+ const marker = document.createComment("choreo-delivery");
1568
+ parent.replaceChild(marker, node);
1569
+ const spans = [];
1570
+ for (const unit of unitsOf(textOf(node, index), by)) {
1571
+ const span = spanFor(unit);
1572
+ parent.insertBefore(span, marker);
1573
+ spans.push(span);
1574
+ if (by === "character" && /^\s+$/.test(unit)) continue;
1575
+ slots.push({ el: span });
1576
+ }
1577
+ undo.push(() => {
1578
+ for (const span of spans) span.remove();
1579
+ marker.parentNode?.replaceChild(node, marker);
1580
+ });
1581
+ }
1582
+ let restored = false;
1583
+ return {
1584
+ restore() {
1585
+ if (restored) return;
1586
+ restored = true;
1587
+ undo.reverse().forEach((fn) => fn());
1588
+ if (label === null) el.removeAttribute("aria-label");
1589
+ else el.setAttribute("aria-label", label);
1590
+ },
1591
+ slots
1592
+ };
1593
+ }
1594
+ /**
1595
+ * `@stagger` seconds between starts, window = what remains of the span; with
1596
+ * no stagger, the Build Order demo's policy: a 0.55-of-span window with the
1597
+ * starts distributed across the remainder.
1598
+ */
1599
+ function windows(n, span, stagger) {
1600
+ if (n <= 1 || span <= 0) return Array.from({ length: n }, () => ({
1601
+ at: 0,
1602
+ ms: span
1603
+ }));
1604
+ if (stagger > 0) {
1605
+ const ms = Math.max(1, span - (n - 1) * stagger);
1606
+ return Array.from({ length: n }, (_, i) => ({
1607
+ at: i * stagger,
1608
+ ms
1609
+ }));
1610
+ }
1611
+ const ms = span * .55;
1612
+ return Array.from({ length: n }, (_, i) => ({
1613
+ at: i * (span - ms) / (n - 1),
1614
+ ms
1615
+ }));
1616
+ }
1617
+ var UNITLESS = new Set([
1618
+ "opacity",
1619
+ "scale",
1620
+ "scaleX",
1621
+ "scaleY"
1622
+ ]);
1623
+ var TRANSFORMS = {
1624
+ rotate: (v) => `rotate(${v}deg)`,
1625
+ scale: (v) => `scale(${v})`,
1626
+ x: (v) => `translateX(${v}px)`,
1627
+ y: (v) => `translateY(${v}px)`
1628
+ };
1629
+ /**
1630
+ * cue.target without the keys that move a box: the positional keys motion-dom
1631
+ * jumps rather than animates when motion is reduced. Opacity, colour and
1632
+ * filters are left to animate.
1633
+ */
1634
+ function withoutMovement(target) {
1635
+ const out = {};
1636
+ for (const key in target) if (!positionalKeys.has(key)) out[key] = target[key];
1637
+ return out;
1638
+ }
1639
+ /** cue.target, as WAAPI property-indexed keyframes */
1640
+ function keyframesOf(target, times, ease) {
1641
+ const out = {};
1642
+ const transforms = /* @__PURE__ */ new Map();
1643
+ for (const key in target) {
1644
+ const raw = target[key];
1645
+ const values = (Array.isArray(raw) ? raw : [raw]).map(String);
1646
+ if (TRANSFORMS[key]) transforms.set(key, values);
1647
+ else out[UNITLESS.has(key) || isNaN(Number(values[0])) ? key : key] = values;
1648
+ }
1649
+ if (transforms.size) {
1650
+ const length = Math.max(...[...transforms.values()].map((v) => v.length));
1651
+ const frames = [];
1652
+ for (let i = 0; i < length; i++) {
1653
+ const parts = [];
1654
+ for (const [key, values] of transforms) parts.push(TRANSFORMS[key](values[Math.min(i, values.length - 1)]));
1655
+ frames.push(parts.join(" "));
1656
+ }
1657
+ out["transform"] = frames;
1658
+ }
1659
+ return times ? {
1660
+ ...out,
1661
+ offset: times,
1662
+ easing: times.map(() => ease ?? "linear")
1663
+ } : out;
1664
+ }
1665
+ var NAMED = {
1666
+ anticipate: "cubic-bezier(0.68,-0.6,0.32,1.6)",
1667
+ backIn: "cubic-bezier(0.36,0,0.66,-0.56)",
1668
+ backInOut: "cubic-bezier(0.68,-0.6,0.32,1.6)",
1669
+ backOut: "cubic-bezier(0.34,1.56,0.64,1)",
1670
+ circIn: "cubic-bezier(0.55,0,1,0.45)",
1671
+ circInOut: "cubic-bezier(0.85,0,0.15,1)",
1672
+ circOut: "cubic-bezier(0,0.55,0.45,1)",
1673
+ easeIn: "ease-in",
1674
+ easeInOut: "ease-in-out",
1675
+ easeOut: "ease-out",
1676
+ linear: "linear"
1677
+ };
1678
+ function cssEasing(ease, ms) {
1679
+ if (ease === void 0) return "ease-in-out";
1680
+ if (typeof ease === "string") return NAMED[ease] ?? "ease-in-out";
1681
+ if (Array.isArray(ease)) return `cubic-bezier(${ease.join(",")})`;
1682
+ return generateLinearEasing(ease, ms);
1683
+ }
1684
+ /** a spring's clock, pre-sampled: its real duration and a linear() easing */
1685
+ function springEasing(spec) {
1686
+ const generator = spring({
1687
+ keyframes: [0, 100],
1688
+ ...spec ?? {}
1689
+ });
1690
+ const ms = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration);
1691
+ const progress = (t) => generator.next(t * ms).value / 100;
1692
+ return {
1693
+ easing: generateLinearEasing(progress, ms),
1694
+ ms
1695
+ };
1696
+ }
1697
+ /**
1698
+ * play one delivery cue: split, animate the slots, restore, land the end
1699
+ * values. With `reduced`, the slots keep their windows but not their
1700
+ * movement: a word fades in where it stands rather than rising into place.
1701
+ */
1702
+ function deliver(cue, speed, reduced = false) {
1703
+ const { by, order, stagger } = cue.delivery;
1704
+ if (by === "item") throw new Error("choreo: item delivery is the ladder, not a split");
1705
+ const parts = split(cue.sprite.element, by);
1706
+ const ranks = ladder(parts.slots.length, order);
1707
+ const spans = windows(parts.slots.length, cue.duration, stagger);
1708
+ const times = cue.transition?.times;
1709
+ const target = reduced ? withoutMovement(cue.target) : cue.target ?? {};
1710
+ const keyframes = keyframesOf(target, Object.keys(target).length ? times : void 0, cssEasing(cue.transition?.ease, cue.duration));
1711
+ const sprung = cue.kind === "spring" ? springEasing(cue.transition) : void 0;
1712
+ const animations = [];
1713
+ for (const [index, slot] of parts.slots.entries()) {
1714
+ const w = spans[ranks[index] ?? index];
1715
+ const ms = sprung ? Math.min(sprung.ms, w.ms) : w.ms;
1716
+ animations.push(slot.el.animate(keyframes, {
1717
+ delay: w.at * speed,
1718
+ duration: Math.max(1, ms * speed),
1719
+ easing: times ? "linear" : sprung ? sprung.easing : cssEasing(cue.transition?.ease, ms),
1720
+ fill: "both"
1721
+ }));
1722
+ }
1723
+ let done = false;
1724
+ let held = false;
1725
+ const land = () => {
1726
+ if (done) return;
1727
+ done = true;
1728
+ const ve = cue.sprite.node.visualElement;
1729
+ if (ve && cue.target) {
1730
+ for (const key in cue.target) {
1731
+ const raw = cue.target[key];
1732
+ const end = Array.isArray(raw) ? raw[raw.length - 1] : raw;
1733
+ ve.getValue(key, end).jump(end);
1734
+ }
1735
+ ve.render();
1736
+ }
1737
+ parts.restore();
1738
+ };
1739
+ return {
1740
+ cancel() {
1741
+ done = true;
1742
+ animations.forEach((a) => a.cancel());
1743
+ parts.restore();
1744
+ },
1745
+ complete() {
1746
+ animations.forEach((a) => {
1747
+ try {
1748
+ a.finish();
1749
+ } catch {
1750
+ a.cancel();
1751
+ }
1752
+ });
1753
+ land();
1754
+ },
1755
+ finished: Promise.all(animations.map((a) => a.finished.catch(() => {}))).then(land),
1756
+ get inFlight() {
1757
+ return !done && !held;
1758
+ },
1759
+ pause() {
1760
+ held = true;
1761
+ animations.forEach((a) => a.pause());
1762
+ },
1763
+ play() {
1764
+ held = false;
1765
+ animations.forEach((a) => a.play());
1766
+ },
1767
+ seek(ms) {
1768
+ const t = Math.max(0, ms * speed);
1769
+ animations.forEach((a) => a.currentTime = t);
1770
+ },
1771
+ speed(rate) {
1772
+ animations.forEach((a) => a.playbackRate = rate);
1773
+ }
1774
+ };
1775
+ }
1776
+ //#endregion
1777
+ //#region ../choreo/src/path.ts
1778
+ /**
1779
+ * THE CAMERA'S PATH — the arithmetic behind `c.Camera3D @through`, and
1780
+ * the only place in Choreo that owns a curve rather than a tween.
1781
+ *
1782
+ * Everything here is a pure function of PROGRESS. That is the whole
1783
+ * point: a seek must land the shot exactly where playing there would, so
1784
+ * nothing in this file may remember a previous frame. A spline that is
1785
+ * sampled rather than integrated can be scrubbed, rendered a frame at a
1786
+ * time, and played, and all three agree by construction.
1787
+ */
1788
+ /**
1789
+ * One cardinal-spline component: Hermite through p1 and p2, tangents off
1790
+ * p0 and p3 scaled by `k = (1 - tension) / 2`. Tension 0 is the classic
1791
+ * Catmull-Rom — lively, and loose enough to overshoot between waypoints
1792
+ * that change direction; 1 collapses the tangents and the path goes
1793
+ * piecewise-linear. The default (0.5) is the steady hand: it still crosses
1794
+ * every waypoint with continuous velocity, but it does not sway on the way.
1795
+ */
1796
+ function crVal(p0, p1, p2, p3, u, k) {
1797
+ const m1 = k * (p2 - p0);
1798
+ const m2 = k * (p3 - p1);
1799
+ const u2 = u * u;
1800
+ const u3 = u2 * u;
1801
+ return (2 * u3 - 3 * u2 + 1) * p1 + (u3 - 2 * u2 + u) * m1 + (-2 * u3 + 3 * u2) * p2 + (u3 - u2) * m2;
1802
+ }
1803
+ /**
1804
+ * Resolve a `@through` path's control points: the pose in force first, then
1805
+ * each waypoint with its omissions carried forward. If ANY point carries a
1806
+ * look, every point gets one (the origin, when unstated), so the aim is
1807
+ * splined by the same arithmetic as the pose.
1808
+ */
1809
+ function resolveThrough(from, through) {
1810
+ const aimed = !!from.look || through.some((w) => w.look);
1811
+ const seed = {
1812
+ ...from,
1813
+ look: aimed ? from.look ?? {
1814
+ x: 0,
1815
+ y: 0,
1816
+ z: 0
1817
+ } : void 0
1818
+ };
1819
+ const pts = [seed];
1820
+ let prev = seed;
1821
+ for (const w of through) {
1822
+ const p = {
1823
+ dolly: w.dolly ?? prev.dolly,
1824
+ look: aimed ? w.look ?? prev.look : void 0,
1825
+ pitch: w.pitch ?? prev.pitch,
1826
+ x: w.x ?? prev.x,
1827
+ y: w.y ?? prev.y,
1828
+ yaw: w.yaw ?? prev.yaw
1829
+ };
1830
+ pts.push(p);
1831
+ prev = p;
1832
+ }
1833
+ return pts;
1834
+ }
1835
+ /** the shot a slot position falls in — points [a, e), window [w0, w1) */
1836
+ /**
1837
+ * WHICH SHOT A SLOT POSITION IS IN. A waypoint marked `cut` opens a new
1838
+ * one, and the two facts a caller needs about it are the points it may
1839
+ * reach for and the slice of the clock it owns — the second so that
1840
+ * nothing (a sample, a settle) ever reads across a seam.
1841
+ */
1842
+ function shotAt(through, points, segs, s) {
1843
+ let seams;
1844
+ for (const [n, w] of through.entries()) if (w.cut) (seams ??= []).push(n + 1);
1845
+ let a = 0;
1846
+ let e = points;
1847
+ let w0 = 0;
1848
+ let w1 = segs;
1849
+ if (seams) {
1850
+ if (seams[0] === 1) {
1851
+ a = 1;
1852
+ seams = seams.slice(1);
1853
+ }
1854
+ for (const seam of seams) {
1855
+ if (s < seam) {
1856
+ e = seam;
1857
+ w1 = seam;
1858
+ break;
1859
+ }
1860
+ a = seam;
1861
+ w0 = seam;
1862
+ }
1863
+ }
1864
+ return {
1865
+ a,
1866
+ e,
1867
+ w0,
1868
+ w1
1869
+ };
1870
+ }
1871
+ /**
1872
+ * Sample the spline at overall progress p ∈ [0, 1] (uniform segments).
1873
+ *
1874
+ * SPLICES (packages/choreo-gallery/realm/docs/choreo-splices.md): a waypoint marked `cut` starts a new
1875
+ * SHOT. Each shot is a clamped spline of its own points — endpoint
1876
+ * tangents one-sided, so no shot's velocity crosses a seam — and each
1877
+ * shot's window runs from its first slot to the next seam, its points
1878
+ * spread uniformly across it. The outgoing shot therefore plays through
1879
+ * the seam instant (its motion stretches by one slot rather than
1880
+ * parking), the incoming one begins exactly on it, and the sampled pose
1881
+ * is a step function at the seam. Waypoints keep their uniform slots, so
1882
+ * cues anchored to waypoint moments keep their clock. A cut on the first
1883
+ * waypoint drops the pose-in-force seed: the score opens inside its
1884
+ * first shot.
1885
+ */
1886
+ function sampleThrough(from, through, progress, tension) {
1887
+ const k = (1 - (tension ?? .5)) / 2;
1888
+ const pts = resolveThrough(from, through);
1889
+ const segs = pts.length - 1;
1890
+ const s = Math.min(segs - 1e-9, Math.max(0, progress * segs));
1891
+ const { a, e, w0, w1 } = shotAt(through, pts.length, segs, s);
1892
+ const m = e - a;
1893
+ const ss = (m === 1 ? 0 : Math.max(0, Math.min(.999999999, (s - w0) / (w1 - w0)))) * (m - 1);
1894
+ const i = a + Math.floor(ss);
1895
+ const u = m === 1 ? 0 : ss - Math.floor(ss);
1896
+ const P = (j) => pts[Math.max(a, Math.min(e - 1, j))];
1897
+ const p0 = P(i - 1);
1898
+ const p1 = P(i);
1899
+ const p2 = P(i + 1);
1900
+ const p3 = P(i + 2);
1901
+ const v = (key) => crVal(p0[key], p1[key], p2[key], p3[key], u, k);
1902
+ const out = {
1903
+ dolly: v("dolly"),
1904
+ pitch: v("pitch"),
1905
+ x: v("x"),
1906
+ y: v("y"),
1907
+ yaw: v("yaw")
1908
+ };
1909
+ if (p1.look && p2.look) {
1910
+ const l = (a) => crVal((p0.look ?? p1.look)[a], p1.look[a], p2.look[a], (p3.look ?? p2.look)[a], u, k);
1911
+ out.look = {
1912
+ x: l("x"),
1913
+ y: l("y"),
1914
+ z: l("z")
1915
+ };
1916
+ }
1917
+ return out;
1918
+ }
1919
+ /**
1920
+ * A SETTLE — the operator's second hand, written as a function of time.
1921
+ *
1922
+ * A cardinal spline crosses its waypoints with continuous velocity but
1923
+ * not continuous acceleration: at every control point the curvature
1924
+ * steps, and the eye reads that step as a tick. The usual cure is a
1925
+ * spring chasing the pose, which works and costs the two things a
1926
+ * seekable engine cannot pay — it remembers the last frame, so a scrub
1927
+ * lands somewhere a play would not, and it lags, so the camera is always
1928
+ * behind the score by however much smoothing it was given.
1929
+ *
1930
+ * This is the same cure without either cost: the reported pose is a
1931
+ * Hann-weighted average of the SAME spline sampled around the current
1932
+ * progress. Averaging a curve is a low-pass filter, and a Hann window
1933
+ * kills the acceleration steps outright, so the result is a hand rather
1934
+ * than a mechanism. Being centred, it has no lag — it reads slightly
1935
+ * ahead of the score exactly as much as it reads behind. Being an
1936
+ * average of one pure function, it is still a pure function: play,
1937
+ * scrub and frame-by-frame render all report the same pose.
1938
+ *
1939
+ * TWO EDGES IT MUST NOT CROSS. A cut is a step in the pose on purpose,
1940
+ * and an average that straddled it would smear the cut into a very fast
1941
+ * pan. The window is therefore TAPERED to the shot the progress is in:
1942
+ * near either edge the kernel shrinks to the room it has, reaching zero
1943
+ * at the edge itself. So a cut stays a cut, a path still lands exactly
1944
+ * on its last waypoint, and the pose handed forward to the next cue is
1945
+ * the waypoint rather than an average of one — the filter is an identity
1946
+ * at every boundary and a smoother everywhere else.
1947
+ *
1948
+ * The taper is `tanh`, not a `min`, and the difference is the whole
1949
+ * reason it works. A hard `min(width, 2 × room)` has a corner in it
1950
+ * where the two branches meet, and a filter whose width has a corner
1951
+ * puts one back into what it filters: measured against a path with two
1952
+ * right-angle corners in it, the hard taper LOST ground as the window
1953
+ * widened (worst jerk 8.7e-4 at a window of 0.175, 2.5e-3 at 0.3) while
1954
+ * the smooth one held 8.0e-4 at every width against 4.2e-3 unfiltered.
1955
+ * `tanh(x) ≤ x` everywhere, which is what keeps the taps inside the
1956
+ * shot; it is smooth, which is what keeps the tick out.
1957
+ *
1958
+ * `width` is in progress, not seconds: the kinks being filtered are at
1959
+ * the waypoints, which are spread uniformly across the clock, so a
1960
+ * window measured against the clock is a window measured against the
1961
+ * spacing of the things it exists to smooth. The caller converts.
1962
+ */
1963
+ function settleThrough(from, through, progress, tension, width, taps = 15) {
1964
+ const pts = resolveThrough(from, through);
1965
+ const segs = pts.length - 1;
1966
+ const s = Math.min(segs - 1e-9, Math.max(0, progress * segs));
1967
+ const { w0, w1 } = shotAt(through, pts.length, segs, s);
1968
+ const lo = w0 / segs;
1969
+ const hi = w1 / segs;
1970
+ const p = Math.min(hi, Math.max(lo, progress));
1971
+ const room = Math.min(p - lo, hi - p);
1972
+ const w = width > 0 ? width * Math.tanh(2 * room / width) : 0;
1973
+ if (!(w > 1e-6) || taps < 3) return sampleThrough(from, through, progress, tension);
1974
+ const aimed = !!from.look || through.some((t) => t.look);
1975
+ let sum = 0;
1976
+ let dolly = 0;
1977
+ let pitch = 0;
1978
+ let x = 0;
1979
+ let y = 0;
1980
+ let yaw = 0;
1981
+ let lx = 0;
1982
+ let ly = 0;
1983
+ let lz = 0;
1984
+ for (let i = 0; i < taps; i += 1) {
1985
+ const f = (i + 1) / (taps + 1);
1986
+ const weight = .5 - .5 * Math.cos(2 * Math.PI * f);
1987
+ const q = sampleThrough(from, through, p + (f - .5) * w, tension);
1988
+ sum += weight;
1989
+ dolly += weight * q.dolly;
1990
+ pitch += weight * q.pitch;
1991
+ x += weight * q.x;
1992
+ y += weight * q.y;
1993
+ yaw += weight * q.yaw;
1994
+ if (aimed && q.look) {
1995
+ lx += weight * q.look.x;
1996
+ ly += weight * q.look.y;
1997
+ lz += weight * q.look.z;
1998
+ }
1999
+ }
2000
+ const out = {
2001
+ dolly: dolly / sum,
2002
+ pitch: pitch / sum,
2003
+ x: x / sum,
2004
+ y: y / sum,
2005
+ yaw: yaw / sum
2006
+ };
2007
+ if (aimed) out.look = {
2008
+ x: lx / sum,
2009
+ y: ly / sum,
2010
+ z: lz / sum
2011
+ };
2012
+ return out;
2013
+ }
2014
+ //#endregion
2015
+ //#region ../choreo/src/run.ts
2016
+ /**
2017
+ * Play a cue list on the motion-dom engine — as a run you can hold (§4.6).
2018
+ *
2019
+ * The old executor fired timers and forgot; this one owns a master clock.
2020
+ * Cues start when the clock crosses them, a gate parks the clock until
2021
+ * `advance()` (§4.1), `time` is settable in either direction (a scrubbed
2022
+ * frame is a still), and `speed` scales the whole score. Ambient loops and
2023
+ * text deliveries ride the platform's own animations, so a busy probe never
2024
+ * mistakes an idle loop for motion.
2025
+ *
2026
+ * The clock runs in tempo-scaled milliseconds; the public face (`time`,
2027
+ * `duration`) speaks seconds at 1×, as Motion's playback controls do.
2028
+ */
2029
+ /** the properties whose mid-flight drive means a sprite is IN SPACE — a
2030
+ * replacement pass must carry these on, never snap them (§3.1) */
2031
+ var MIDFLIGHT_KEYS = [
2032
+ "height",
2033
+ "rotate",
2034
+ "scale",
2035
+ "scaleX",
2036
+ "scaleY",
2037
+ "width",
2038
+ "x",
2039
+ "y"
2040
+ ];
2041
+ /** how fast each value was moving, in units per second, keyed by element then property */
2042
+ /**
2043
+ * Where each ambient loop stood in its cycle, from 0 to 1, keyed by sprite
2044
+ * then by the loop's properties (see loopKey).
2045
+ */
2046
+ /** a loop's properties, which tell it apart from another loop on its sprite */
2047
+ var loopKey = (cue) => Object.keys(cue.target ?? {}).sort().join(",");
2048
+ /** a tween a replacement pass carries on: see Run.midfade */
2049
+ function isSpring(transition) {
2050
+ if (!transition) return false;
2051
+ if (transition["type"]) return transition["type"] === "spring";
2052
+ return "bounce" in transition || "damping" in transition || "stiffness" in transition || "visualDuration" in transition;
2053
+ }
2054
+ /**
2055
+ * Controls that wrap a platform Animation rather than a motion-dom one: the
2056
+ * frame clock's hold-back has no tween to move in them, and no private
2057
+ * fields to find.
2058
+ */
2059
+ var platformControlled = /* @__PURE__ */ new WeakSet();
2060
+ /**
2061
+ * A platform Animation in the controls shape the transport speaks, so
2062
+ * setPaused / speed / stopTrack drive it exactly like an engine animation.
2063
+ */
2064
+ function platformControls(animation) {
2065
+ const controls = {
2066
+ cancel: () => animation.cancel(),
2067
+ pause: () => animation.pause(),
2068
+ play: () => animation.play(),
2069
+ get speed() {
2070
+ return animation.playbackRate;
2071
+ },
2072
+ set speed(rate) {
2073
+ animation.playbackRate = rate;
2074
+ },
2075
+ get state() {
2076
+ return animation.playState;
2077
+ },
2078
+ stop: () => animation.cancel(),
2079
+ get time() {
2080
+ return (animation.currentTime ?? 0) / 1e3;
2081
+ },
2082
+ set time(seconds) {
2083
+ animation.currentTime = seconds * 1e3;
2084
+ }
2085
+ };
2086
+ platformControlled.add(controls);
2087
+ return controls;
2088
+ }
2089
+ function carryVelocity(transition, cue, inherit) {
2090
+ if (!inherit || !cue.target || !isSpring(transition)) return transition;
2091
+ const was = inherit.get(cue.sprite.element) ?? (cue.sprite.counterpart && inherit.get(cue.sprite.counterpart.element));
2092
+ if (!was) return transition;
2093
+ let out = transition;
2094
+ for (const key in cue.target) {
2095
+ const velocity = was.get(key);
2096
+ if (velocity) {
2097
+ if (out === transition) out = { ...transition };
2098
+ out[key] = {
2099
+ ...transition,
2100
+ velocity
2101
+ };
2102
+ }
2103
+ }
2104
+ return out;
2105
+ }
2106
+ var dash = (key) => key.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase());
2107
+ var noop = () => {};
2108
+ var SIZES = {
2109
+ height: true,
2110
+ width: true
2111
+ };
2112
+ function applyHold(ve, el, values) {
2113
+ const held = [];
2114
+ for (const key in values) {
2115
+ const had = ve.hasValue(key);
2116
+ const prior = had ? ve.getValue(key).get() : void 0;
2117
+ const priorStyle = key.startsWith("--") ? el.style.getPropertyValue(key) : el.style[key] ?? "";
2118
+ ve.getValue(key, values[key]).jump(values[key]);
2119
+ held.push({
2120
+ had,
2121
+ key,
2122
+ prior,
2123
+ priorStyle
2124
+ });
2125
+ }
2126
+ ve.scheduleRender();
2127
+ return held;
2128
+ }
2129
+ function releaseHold(ve, el, held) {
2130
+ for (const { had, key, prior, priorStyle } of held) if (had) ve.getValue(key)?.jump(prior);
2131
+ else {
2132
+ ve.removeValue(key);
2133
+ if (priorStyle) el.style.setProperty(dash(key), priorStyle);
2134
+ else el.style.removeProperty(dash(key));
2135
+ }
2136
+ ve.scheduleRender();
2137
+ }
2138
+ /** what one cue is doing right now */
2139
+ var warnedPrivateFields = false;
2140
+ /** let the next run that misses motion-dom's private fields say so again (a test's reset) */
2141
+ function resetRunWarnings() {
2142
+ warnedPrivateFields = false;
2143
+ }
2144
+ /** the run's frame clock reads motion-dom's private animation fields; say once when they are gone */
2145
+ function warnPrivateFieldsMoved() {
2146
+ if (warnedPrivateFields) return;
2147
+ warnedPrivateFields = true;
2148
+ console.warn("@cardstack/choreo: motion-dom no longer exposes the animation fields a run's frame clock reads (_animation, startTime, holdTime); a run compiled in a long task will open its tweens that far in, and with @maxFrameStep a long frame will skip them ahead instead of slowing them");
2149
+ }
2150
+ var ChoreoRun = class ChoreoRun {
2151
+ cues;
2152
+ velocities = /* @__PURE__ */ new Map();
2153
+ finished;
2154
+ master = 0;
2155
+ playing = true;
2156
+ parkedAt = null;
2157
+ rate = 1;
2158
+ scale = motionSpeed();
2159
+ reduced;
2160
+ standing;
2161
+ total;
2162
+ gates;
2163
+ tracks = [];
2164
+ rowEnd = /* @__PURE__ */ new Map();
2165
+ released = /* @__PURE__ */ new Set();
2166
+ pending;
2167
+ options;
2168
+ borrowedValues = [];
2169
+ /** rest is what releaseForMeasure jumps to: 0 for translates, 1 for scales, 'none' for clips */
2170
+ movedValues = [];
2171
+ /** what the last releaseForMeasure retired, so a kept pass can put it back */
2172
+ retired = {
2173
+ borrowed: [],
2174
+ moved: []
2175
+ };
2176
+ owned = [];
2177
+ cancelled = false;
2178
+ ended = false;
2179
+ resolveFinished;
2180
+ ticking = false;
2181
+ /**
2182
+ * The next tick is the first since the clock started (or resumed): it
2183
+ * paints the run where it stands and advances nothing. The frame loop's
2184
+ * delta on that tick is the time since ITS last frame, up to 40 ms, so a
2185
+ * run started by a render pass would otherwise open with that whole step
2186
+ * on its own clock: every cue the clock starts, gates, or drives frame by
2187
+ * frame (a camera, a wire, a later cue's start) would begin that far in.
2188
+ * The tweens the run started get the same fresh start from holdBack. A
2189
+ * run that opens `continuing` skips it.
2190
+ */
2191
+ freshClock = false;
2192
+ /**
2193
+ * The run replaces one in flight and has not painted yet. Its first frame
2194
+ * continues a motion already on screen, so it advances like any other
2195
+ * frame, the clock and its tweens alike: standing still there would draw
2196
+ * the last frame twice. A later start (a resume, a gate) is from rest.
2197
+ */
2198
+ continuing = false;
2199
+ /** the frame timestamp holdBack saw last; undefined before its first frame */
2200
+ lastStamp;
2201
+ /**
2202
+ * motion-dom's clock as the run (re)started ticking. That clock holds one
2203
+ * reading until the microtask queue next drains, and startTicking reads it
2204
+ * in the same synchronous call that started or resumed the run's tweens,
2205
+ * so this is the time they were dated from, however long the task ran
2206
+ * before it.
2207
+ */
2208
+ startedAt = 0;
2209
+ autoTimer;
2210
+ constructor(compiled, options) {
2211
+ this.options = options;
2212
+ this.continuing = options.continuing ?? false;
2213
+ this.reduced = options.reduced ?? false;
2214
+ this.camera = options.camera ?? {
2215
+ x: 0,
2216
+ y: 0,
2217
+ zoom: 1
2218
+ };
2219
+ this.camera3d = options.camera3d ?? {
2220
+ dolly: 1,
2221
+ pitch: 0,
2222
+ x: 0,
2223
+ y: 0,
2224
+ yaw: 0
2225
+ };
2226
+ this.initial3d = { ...this.camera3d };
2227
+ this.cameraAim = options.cameraAim ?? null;
2228
+ this.initialCamera = { ...this.camera };
2229
+ this.initialAim = this.cameraAim ? { ...this.cameraAim } : null;
2230
+ this.cues = compiled.cues;
2231
+ this.pending = new Set(options.removed);
2232
+ const s = this.scale;
2233
+ this.gates = compiled.gates.map((g) => ({
2234
+ at: g.at * s,
2235
+ auto: g.auto === void 0 ? void 0 : g.auto * s,
2236
+ opened: false
2237
+ }));
2238
+ this.standing = compiled.open ?? false;
2239
+ let total = 0;
2240
+ for (const cue of this.cues) {
2241
+ const start = cue.start * s;
2242
+ const duration = cue.duration * s;
2243
+ this.tracks.push({
2244
+ cue,
2245
+ end: start + duration,
2246
+ passed: false,
2247
+ start,
2248
+ started: false
2249
+ });
2250
+ if (!cue.loop && !cue.standing) total = Math.max(total, start + duration);
2251
+ this.rowEnd.set(cue.sprite, Math.max(this.rowEnd.get(cue.sprite) ?? 0, cue.standing ? start : start + duration));
2252
+ }
2253
+ for (const g of this.gates) total = Math.max(total, g.at);
2254
+ for (const [sprite, end] of this.rowEnd) if (sprite.counterpart) this.rowEnd.set(sprite.counterpart, Math.max(this.rowEnd.get(sprite.counterpart) ?? 0, end));
2255
+ this.total = total;
2256
+ this.finished = new Promise((resolve) => {
2257
+ this.resolveFinished = resolve;
2258
+ });
2259
+ this.pinStarts();
2260
+ this.evaluate();
2261
+ this.startTicking();
2262
+ activeRuns.add(this);
2263
+ this.finished.then(() => activeRuns.delete(this));
2264
+ }
2265
+ get duration() {
2266
+ return this.total / this.scale / 1e3;
2267
+ }
2268
+ get paused() {
2269
+ return !this.playing;
2270
+ }
2271
+ get time() {
2272
+ return this.master / this.scale / 1e3;
2273
+ }
2274
+ /**
2275
+ * The run's motion is under way on screen: it is playing, its clock has
2276
+ * not reached its end, and it has painted a frame since it started or
2277
+ * resumed, or carries on a run that had. A run compiled and replaced
2278
+ * before any frame was never seen moving, so its replacement starts from
2279
+ * rest.
2280
+ */
2281
+ get inFlight() {
2282
+ return this.ticking && this.master < this.total && (this.lastStamp !== void 0 || this.continuing);
2283
+ }
2284
+ set time(seconds) {
2285
+ this.seekTo(seconds * 1e3 * this.scale);
2286
+ }
2287
+ get speed() {
2288
+ return this.rate;
2289
+ }
2290
+ set speed(rate) {
2291
+ this.rate = rate;
2292
+ for (const t of this.tracks) {
2293
+ t.controls?.forEach((c) => c.speed = rate);
2294
+ if (t.delivery) t.delivery.speed(rate);
2295
+ if (t.loopAnimation) t.loopAnimation.playbackRate = rate;
2296
+ if (t.cameraAnimation) t.cameraAnimation.playbackRate = rate;
2297
+ }
2298
+ }
2299
+ get segment() {
2300
+ let n = 0;
2301
+ for (const g of this.gates) if (this.master > g.at || this.master === g.at && g.opened) n++;
2302
+ return n;
2303
+ }
2304
+ get parked() {
2305
+ return this.parkedAt !== null;
2306
+ }
2307
+ /**
2308
+ * ATTACH: write each attached region's clock from this one's.
2309
+ *
2310
+ * Several windows may name one region — a film's every beat has a plate
2311
+ * window, and the plate is one region re-keyed per beat — so the run
2312
+ * resolves ONE governing window per region on every evaluate: the window
2313
+ * that holds `now`; else the latest past one, if it holds; else the
2314
+ * earliest future one, which stands the child at its head (Remotion's
2315
+ * premount: mounted early, clock frozen at `in`). The child's run is
2316
+ * paused and told `in + (now − start) × rate`. No history is kept on
2317
+ * either side, which is what makes a seek into a window land where
2318
+ * playing there would.
2319
+ */
2320
+ driveAttachments(now) {
2321
+ let governing;
2322
+ for (const t of this.tracks) {
2323
+ const a = t.cue.attach;
2324
+ if (!a || t.refused) continue;
2325
+ governing ??= /* @__PURE__ */ new Map();
2326
+ const g = governing.get(a.region);
2327
+ if (!g) {
2328
+ governing.set(a.region, t);
2329
+ continue;
2330
+ }
2331
+ const rank = (x) => now >= x.start && now < x.end ? 2 : now >= x.end ? 1 : 0;
2332
+ const rt = rank(t);
2333
+ const rg = rank(g);
2334
+ if (rt > rg || rt === rg && rt === 1 && t.end > g.end || rt === rg && rt === 0 && t.start < g.start) governing.set(a.region, t);
2335
+ }
2336
+ if (!governing) return;
2337
+ for (const [region, t] of governing) {
2338
+ const a = t.cue.attach;
2339
+ const child = choreoHostById(region)?.currentRun() ?? null;
2340
+ if (!child || child === this) continue;
2341
+ if (a.exact && child.hasIntegrator()) {
2342
+ t.refused = true;
2343
+ console.error(`choreo: <Choreo "${region}"> is attached under an exact clock, but its score integrates (a spring or a follow): its state is its history, and a driven clock has none`);
2344
+ continue;
2345
+ }
2346
+ let local;
2347
+ if (now < t.start) local = a.in;
2348
+ else if (now < t.end) local = a.in + (now - t.start) / 1e3 / this.scale * a.rate;
2349
+ else if (a.end === "hold") local = a.in + t.cue.duration / 1e3 * a.rate;
2350
+ else continue;
2351
+ const inside = now >= t.start && now < t.end;
2352
+ if (this.playing && inside && !this.ended) {
2353
+ if (child.paused) {
2354
+ child.time = local;
2355
+ child.play();
2356
+ } else if (Math.abs(child.time - local) > 1 / 30) child.time = local;
2357
+ const speed = this.rate * a.rate;
2358
+ if (Math.abs(child.speed - speed) > 1e-6) child.speed = speed;
2359
+ continue;
2360
+ }
2361
+ if (!child.paused) child.pause();
2362
+ if (Math.abs(child.time - local) > 1e-4) child.time = local;
2363
+ }
2364
+ }
2365
+ /** does this run's score integrate — a spring, a follow — so that its state is its history? */
2366
+ hasIntegrator() {
2367
+ return this.tracks.some((t) => t.cue.kind === "spring" || !!t.cue.derive);
2368
+ }
2369
+ isDone() {
2370
+ return this.ended || this.cancelled;
2371
+ }
2372
+ isLooping() {
2373
+ return this.ended && !this.cancelled && this.tracks.length > 0 && this.tracks.every((t) => t.cue.loop && t.loopAnimation !== void 0 && t.loopAnimation.playState !== "idle");
2374
+ }
2375
+ /**
2376
+ * A text delivery is still standing in for its sprite's text. The clock
2377
+ * can end first: a delivery lands on its own platform animations, and the
2378
+ * run leaves it to finish its tail rather than cutting it short.
2379
+ */
2380
+ get delivering() {
2381
+ return !this.cancelled && this.tracks.some((t) => t.delivery?.inFlight === true);
2382
+ }
2383
+ loopPhases() {
2384
+ const out = /* @__PURE__ */ new Map();
2385
+ for (const t of this.tracks) {
2386
+ const animation = t.loopAnimation;
2387
+ if (!animation || animation.playState === "idle") continue;
2388
+ const cycle = Number(animation.effect?.getComputedTiming().duration);
2389
+ if (!(cycle > 0)) continue;
2390
+ const node = t.cue.sprite.node;
2391
+ let phases = out.get(node);
2392
+ if (!phases) out.set(node, phases = /* @__PURE__ */ new Map());
2393
+ phases.set(loopKey(t.cue), Number(animation.currentTime ?? 0) % cycle / cycle);
2394
+ }
2395
+ return out;
2396
+ }
2397
+ midflight() {
2398
+ const out = /* @__PURE__ */ new Map();
2399
+ if (this.isDone()) return out;
2400
+ for (const t of this.tracks) {
2401
+ const { cue } = t;
2402
+ if (!t.started || t.passed) continue;
2403
+ if (cue.flight !== void 0 || cue.target !== void 0 && MIDFLIGHT_KEYS.some((key) => key in cue.target)) out.set(cue.sprite.node, cue.transition);
2404
+ }
2405
+ return out;
2406
+ }
2407
+ midfade() {
2408
+ const out = /* @__PURE__ */ new Map();
2409
+ if (this.isDone()) return out;
2410
+ const now = this.master;
2411
+ const gate = this.gates.find((g) => !g.opened && g.at >= now)?.at;
2412
+ const scale = this.scale || 1;
2413
+ for (const t of this.tracks) {
2414
+ const { cue } = t;
2415
+ if (t.passed || t.end <= now || gate !== void 0 && t.start >= gate && !t.started || cue.kind !== "tween" || cue.loop || cue.borrow || !cue.target) continue;
2416
+ const { repeat, repeatType } = cue.transition ?? {};
2417
+ const first = typeof repeat === "number" && repeat % 2 === 1 && repeatType !== "loop";
2418
+ const to = {};
2419
+ for (const [key, value] of Object.entries(cue.target)) {
2420
+ if (MIDFLIGHT_KEYS.includes(key)) continue;
2421
+ const end = Array.isArray(value) ? value[first ? 0 : value.length - 1] : value;
2422
+ if (end !== void 0 && end !== null) to[key] = end;
2423
+ }
2424
+ if (!Object.keys(to).length) continue;
2425
+ const begins = Math.max(now, t.start);
2426
+ const fades = out.get(cue.sprite.node) ?? [];
2427
+ fades.push({
2428
+ delay: (begins - now) / scale,
2429
+ remaining: (t.end - begins) / scale,
2430
+ to
2431
+ });
2432
+ out.set(cue.sprite.node, fades);
2433
+ }
2434
+ return out;
2435
+ }
2436
+ pause() {
2437
+ if (!this.playing) return;
2438
+ this.playing = false;
2439
+ this.setPaused(true);
2440
+ this.driveAttachments(this.master);
2441
+ this.scheduleRestill();
2442
+ }
2443
+ play() {
2444
+ if (this.playing || this.ended || this.cancelled) return;
2445
+ if (this.parkedAt) return;
2446
+ this.playing = true;
2447
+ this.setPaused(false);
2448
+ this.startTicking();
2449
+ }
2450
+ advance() {
2451
+ if (this.ended || this.cancelled) return;
2452
+ const gate = this.parkedAt;
2453
+ if (gate) {
2454
+ gate.opened = true;
2455
+ this.parkedAt = null;
2456
+ clearTimeout(this.autoTimer);
2457
+ this.playing = true;
2458
+ this.setPaused(false);
2459
+ this.startTicking();
2460
+ return;
2461
+ }
2462
+ const next = this.gates.find((g) => !g.opened && g.at >= this.master);
2463
+ this.seekTo(next ? next.at : this.total);
2464
+ if (!next && this.master >= this.total && !this.standing) this.finish();
2465
+ }
2466
+ retreat() {
2467
+ if (this.cancelled) return false;
2468
+ const eps = 1e-6;
2469
+ const behind = this.gates.filter((g) => g.at < this.master - eps);
2470
+ const target = behind[behind.length - 1];
2471
+ if (!target) return false;
2472
+ clearTimeout(this.autoTimer);
2473
+ for (const g of this.gates) if (g.at >= target.at) g.opened = false;
2474
+ this.ended = false;
2475
+ this.master = Math.max(0, target.at - .5);
2476
+ this.playing = false;
2477
+ this.setPaused(true);
2478
+ this.evaluate();
2479
+ this.park(target, false);
2480
+ return true;
2481
+ }
2482
+ startTicking() {
2483
+ if (this.ticking || !this.playing || this.cancelled || this.ended) return;
2484
+ this.ticking = true;
2485
+ this.freshClock = !this.continuing;
2486
+ this.lastStamp = void 0;
2487
+ this.startedAt = time.now();
2488
+ frame.read(this.holdBack, !!this.options.maxFrameStep);
2489
+ frame.update(this.tick, true);
2490
+ }
2491
+ stopTicking() {
2492
+ if (this.ticking) {
2493
+ this.ticking = false;
2494
+ this.continuing = false;
2495
+ cancelFrame(this.tick);
2496
+ cancelFrame(this.holdBack);
2497
+ }
2498
+ }
2499
+ /** what one painted frame advances a running clock: the frame loop's delta, capped */
2500
+ frameStep(data) {
2501
+ const step = this.options.maxFrameStep;
2502
+ return step ? Math.min(data.delta, step) : data.delta;
2503
+ }
2504
+ /**
2505
+ * The fresh start and maxFrameStep for the animations themselves. The
2506
+ * run's own clock gets both in tick; the tweens and springs it started
2507
+ * run on motion-dom's frame clock, which takes the real time since their
2508
+ * start, so they would open and skip on their own. Before they update,
2509
+ * each one driven on the main thread has its start moved:
2510
+ *
2511
+ * - on the first frame the run paints, to this frame, less the progress
2512
+ * it had as the run started. A tween the pass began was dated from
2513
+ * motion-dom's clock, which holds one reading through a synchronous
2514
+ * stretch of work, so a pass late in a long one would date it back to
2515
+ * that reading and its first frame would show that much of it gone; it
2516
+ * opens at zero instead. A tween resuming with the run is dated from
2517
+ * the same reading less its held time, and keeps it. Every way the
2518
+ * clock stops (a pause, a gate, a seek) holds the run's tweens first,
2519
+ * and no gate stands inside a parallel, so no tween is still running
2520
+ * when the clock starts again. A `continuing` run moves them one
2521
+ * ordinary frame further, as its clock moves;
2522
+ * - after that, with a cap, on by the time past the cap since the last
2523
+ * frame: it resumes from where the last frame left it, plus one step.
2524
+ * Without a cap this runs on the first frame only.
2525
+ *
2526
+ * Animations on the compositor (WAAPI) start on the frame that commits
2527
+ * them and kept playing through a long frame; they are left alone.
2528
+ */
2529
+ holdBack = (data) => {
2530
+ const step = this.options.maxFrameStep;
2531
+ const last = this.lastStamp;
2532
+ this.lastStamp = data.timestamp;
2533
+ const opening = last === void 0 && this.continuing ? this.frameStep(data) : 0;
2534
+ if (last === void 0) this.continuing = false;
2535
+ for (const t of this.tracks) for (const c of t.controls ?? []) {
2536
+ if (platformControlled.has(c)) continue;
2537
+ const inner = c._animation;
2538
+ if (!inner || !("animation" in inner) && !("startTime" in inner && "holdTime" in inner)) warnPrivateFieldsMoved();
2539
+ if (!inner || "animation" in inner || typeof inner.startTime !== "number" || inner.holdTime !== null) continue;
2540
+ if (last === void 0) {
2541
+ const progress = Math.max(0, this.startedAt - inner.startTime);
2542
+ inner.startTime = data.timestamp - progress - opening;
2543
+ } else if (step && data.timestamp - last > step) inner.startTime += data.timestamp - last - step;
2544
+ }
2545
+ };
2546
+ tick = (data) => {
2547
+ if (!this.playing || this.cancelled || this.ended) {
2548
+ this.stopTicking();
2549
+ return;
2550
+ }
2551
+ const delta = this.freshClock ? 0 : this.frameStep(data);
2552
+ this.freshClock = false;
2553
+ const next = this.master + delta * this.rate;
2554
+ const gate = this.gates.find((g) => !g.opened && g.at >= this.master && g.at <= next);
2555
+ if (gate) {
2556
+ this.master = gate.at;
2557
+ this.evaluate(gate.at);
2558
+ this.park(gate);
2559
+ return;
2560
+ }
2561
+ this.master = next;
2562
+ this.evaluate();
2563
+ for (const [sprite, end] of this.rowEnd) if (this.master >= end && !this.released.has(sprite)) {
2564
+ this.released.add(sprite);
2565
+ if (this.pending.delete(sprite)) this.options.onSpriteDone(sprite);
2566
+ }
2567
+ if (this.master >= this.total && !this.standing) this.finish();
2568
+ };
2569
+ park(gate, auto = true) {
2570
+ gate.opened = false;
2571
+ this.parkedAt = gate;
2572
+ this.playing = false;
2573
+ this.stopTicking();
2574
+ /**
2575
+ * HAND BACK THE LEAVERS, but only when nobody is left to open the gate.
2576
+ *
2577
+ * `pending` is removed sprites and nothing else — elements a <Presence>
2578
+ * is holding in the document only because this run undertook to see them
2579
+ * out. Parking stops the clock (above), so from here nothing advances:
2580
+ * every row end still ahead of `master` is unreachable, `onSpriteDone`
2581
+ * can never fire for it, and `finished` never resolves. The Presence
2582
+ * waits on a beat that is not coming.
2583
+ *
2584
+ * `doomed` is what separates that from an ordinary build, and the
2585
+ * distinction is real rather than a hedge. A gated build parks with the
2586
+ * same sprites pending and means it: the slide is still on screen, the
2587
+ * click is still coming, and the leaver is meant to fly out when it
2588
+ * arrives — releasing it there would make the item vanish instead, which
2589
+ * is the animation the registration exists to protect. A region where
2590
+ * every participant is leaving has no slide left to click on. Nothing
2591
+ * stays, so nothing can ask, and the gate is waiting on an event that
2592
+ * cannot happen.
2593
+ *
2594
+ * That is not hypothetical. Rack's score is a gate followed by one
2595
+ * parallel over sixty-one tiles, held still until its slider asks — so
2596
+ * filtering its card out of the gallery compiled a score that parked at
2597
+ * t=0 with all sixty-one of its participants pending and a clock that
2598
+ * never moved. Because <Presence> releases its leavers as a BATCH, those
2599
+ * sixty-one held all forty cards leaving beside them: under the default
2600
+ * mode the survivors never closed up, and under popLayout forty
2601
+ * invisible cards stayed lifted over the grid taking clicks meant for
2602
+ * the two you could see.
2603
+ *
2604
+ * A parked run is a STILL, in this file's own words — settled, not in
2605
+ * flight. A still is not an exit animation, so there is nothing here to
2606
+ * cut short. If the gate is ever opened the elements are simply gone,
2607
+ * which is what leaving means.
2608
+ */
2609
+ if (this.options.doomed) for (const sprite of [...this.pending]) {
2610
+ this.pending.delete(sprite);
2611
+ this.options.onSpriteDone(sprite);
2612
+ }
2613
+ for (const t of this.tracks) if (t.started && !t.cue.loop && !t.cue.hold && t.end <= this.master) this.completeTrack(t);
2614
+ this.setPaused(true);
2615
+ this.scheduleRestill();
2616
+ if (auto && gate.auto !== void 0) this.autoTimer = setTimeout(() => {
2617
+ if (this.parkedAt === gate && !this.cancelled) this.advance();
2618
+ }, gate.auto / this.rate);
2619
+ }
2620
+ finish() {
2621
+ if (this.ended) return;
2622
+ this.ended = true;
2623
+ this.stopTicking();
2624
+ this.driveAttachments(this.master);
2625
+ this.options.onCamera?.({ ...this.camera });
2626
+ for (const t of this.tracks) if (t.started && !t.cue.loop && !t.cue.hold && !t.cue.delivery) this.completeTrack(t);
2627
+ this.releaseForMeasure();
2628
+ for (const sprite of [...this.pending]) {
2629
+ this.pending.delete(sprite);
2630
+ this.options.onSpriteDone(sprite);
2631
+ }
2632
+ this.resolveFinished();
2633
+ }
2634
+ setPaused(paused) {
2635
+ const now = this.master;
2636
+ for (const t of this.tracks) {
2637
+ if (!t.started) continue;
2638
+ const due = now >= t.start && (now < t.end || t.cue.loop);
2639
+ const run = !paused && due;
2640
+ t.controls?.forEach((c) => {
2641
+ if (run) {
2642
+ if (c.state === "running" || c.state === "paused") c.play();
2643
+ } else if (c.state === "running") c.pause();
2644
+ });
2645
+ if (t.delivery) if (paused && now >= t.end) t.delivery.complete();
2646
+ else (run ? t.delivery.play : t.delivery.pause)();
2647
+ if (t.loopAnimation) if (run) t.loopAnimation.play();
2648
+ else t.loopAnimation.pause();
2649
+ if (t.cameraAnimation) if (run) t.cameraAnimation.play();
2650
+ else t.cameraAnimation.pause();
2651
+ }
2652
+ }
2653
+ seekTo(target) {
2654
+ const gate = this.gates.find((g) => !g.opened && g.at >= this.master && g.at <= target);
2655
+ const clamped = Math.max(0, Math.min(gate ? gate.at : target, this.total));
2656
+ this.master = clamped;
2657
+ if (this.ended && clamped < this.total) this.ended = false;
2658
+ const wasPlaying = this.playing;
2659
+ this.playing = false;
2660
+ this.setPaused(true);
2661
+ this.reconstructCameraAt(gate ? gate.at : Infinity);
2662
+ this.evaluate(gate ? gate.at : Infinity);
2663
+ if (gate) {
2664
+ this.park(gate);
2665
+ return;
2666
+ }
2667
+ if (wasPlaying && !this.ended) {
2668
+ this.playing = true;
2669
+ this.setPaused(false);
2670
+ this.startTicking();
2671
+ return;
2672
+ }
2673
+ this.scheduleRestill();
2674
+ }
2675
+ /**
2676
+ * The one cost WAAPI acceleration charges a scrubbable run: a finished
2677
+ * accelerated animation commits its finals asynchronously, and that
2678
+ * commit can land AFTER a still's jump and overwrite it. So a still is
2679
+ * re-asserted on the two frames after it is entered — by then any
2680
+ * pending commit has landed, and the computed frame wins again.
2681
+ */
2682
+ restillPending = 0;
2683
+ scheduleRestill() {
2684
+ if (this.restillPending > 0) return;
2685
+ this.restillPending = 2;
2686
+ const pass = () => {
2687
+ if (this.playing || this.cancelled) {
2688
+ this.restillPending = 0;
2689
+ return;
2690
+ }
2691
+ this.restill();
2692
+ this.restillPending -= 1;
2693
+ if (this.restillPending > 0) frame.postRender(pass);
2694
+ };
2695
+ frame.postRender(pass);
2696
+ }
2697
+ restill() {
2698
+ const now = this.master;
2699
+ const rewinds = [];
2700
+ for (const t of this.tracks) {
2701
+ const { cue } = t;
2702
+ if (!cue.sprite.node.visualElement || cue.camera || cue.tether) continue;
2703
+ if (!t.started && t.origin && now < t.start) rewinds.push(t);
2704
+ else if (t.started && !t.controls && !t.delivery && !t.loopAnimation && (cue.target || cue.flight) && now >= t.start && now < t.end) this.sampleStill(t, now);
2705
+ }
2706
+ this.rewind(rewinds, now);
2707
+ }
2708
+ evaluate(limit = Infinity) {
2709
+ const now = this.master;
2710
+ const rewinds = [];
2711
+ /**
2712
+ * The shot is FOLDED, not remembered.
2713
+ *
2714
+ * Every other cue kind owns an element and can be started and rewound
2715
+ * in place. A camera3d cue owns one shared triple, and per-cue state
2716
+ * does not survive that: seeking back from cue two to inside cue one
2717
+ * runs cue one's lerp (correct) and then cue two's rewind (which
2718
+ * restores the pose cue two INHERITED — cue one's end), and the
2719
+ * second write wins because it comes later in the list. The shot
2720
+ * ended up at the boundary value for every seek backwards.
2721
+ *
2722
+ * So it is recomputed from the score on every evaluate: start at the
2723
+ * pose the run inherited, walk the cues in order, and let each one
2724
+ * pass through, lerp, or land. A relative cue resolves against
2725
+ * whatever the walk has accumulated by the time it is reached, which
2726
+ * is precisely "the pose in force at cue start" — and it means a
2727
+ * direct seek is identical to having played there, by construction
2728
+ * rather than by bookkeeping.
2729
+ */
2730
+ let shot = null;
2731
+ for (const t of this.tracks) {
2732
+ const { cue } = t;
2733
+ if (t.passed && now < t.end) {
2734
+ t.passed = false;
2735
+ if (now < t.start && t.origin) rewinds.push(t);
2736
+ }
2737
+ const fill = cue.hold?.fill ?? false;
2738
+ const inside = now >= t.start && t.start < limit && (now < t.end || cue.loop || fill);
2739
+ if (cue.camera) {
2740
+ if (inside && !t.started) {
2741
+ t.started = true;
2742
+ t.cameraFrom = { ...this.camera };
2743
+ const aimTo = cue.camera.origin ?? this.cameraAim ?? cue.camera.centre ?? {
2744
+ x: 0,
2745
+ y: 0
2746
+ };
2747
+ t.aimFrom = this.cameraAim ?? aimTo;
2748
+ t.aimTo = aimTo;
2749
+ this.cameraAim = aimTo;
2750
+ t.cameraTo = ChoreoRun.resolveCameraTo(cue.camera, t.cameraFrom);
2751
+ } else if (!inside && t.started && now < t.start) {
2752
+ t.started = false;
2753
+ t.cameraTo = void 0;
2754
+ t.cameraAnimation?.cancel();
2755
+ t.cameraAnimation = void 0;
2756
+ if (t.cameraFrom) {
2757
+ this.camera = { ...t.cameraFrom };
2758
+ this.cameraAim = t.aimFrom ?? null;
2759
+ t.cameraP = 0;
2760
+ this.applyCamera(t);
2761
+ }
2762
+ }
2763
+ if (t.started && (now < t.end || !t.passed)) {
2764
+ const p = now >= t.end ? 1 : this.cameraProgress(t, now - t.start);
2765
+ const from = t.cameraFrom;
2766
+ const to = t.cameraTo ?? ChoreoRun.resolveCameraTo(cue.camera, from);
2767
+ t.cameraP = p;
2768
+ this.camera = {
2769
+ x: from.x + (to.x - from.x) * p,
2770
+ y: from.y + (to.y - from.y) * p,
2771
+ zoom: from.zoom + (to.zoom - from.zoom) * p
2772
+ };
2773
+ if (this.playing && now < t.end) {
2774
+ if (!t.cameraAnimation) this.startCameraAnimation(t, now);
2775
+ else if (t.cameraAnimation.playState === "paused") t.cameraAnimation.play();
2776
+ } else if (t.cameraAnimation) if (now >= t.end) this.dropCameraAnimation(t);
2777
+ else {
2778
+ t.cameraAnimation.pause();
2779
+ t.cameraAnimation.currentTime = Math.max(0, now - t.start);
2780
+ }
2781
+ this.applyCamera(t);
2782
+ if (now >= t.end && this.playing && !t.passed) {
2783
+ t.passed = true;
2784
+ this.options.onCamera?.({ ...this.camera });
2785
+ }
2786
+ }
2787
+ continue;
2788
+ }
2789
+ if (cue.camera3d) {
2790
+ const from = shot ?? { ...this.initial3d };
2791
+ const through = cue.camera3d.through;
2792
+ if (through?.length) {
2793
+ /**
2794
+ * A PATH: the pose in force and the waypoints are the control
2795
+ * points of a Catmull-Rom spline, sampled at the cue's eased
2796
+ * progress. One clock over the whole chain, so the camera
2797
+ * CROSSES each waypoint with continuous velocity instead of
2798
+ * parking at it — and it stays a pure function of the clock,
2799
+ * which no per-frame integrator can claim.
2800
+ */
2801
+ if (now <= t.start) shot = from;
2802
+ else {
2803
+ const p = now >= t.end ? 1 : this.cameraProgress(t, now - t.start);
2804
+ const settle = cue.camera3d.settle;
2805
+ const span = t.end - t.start;
2806
+ shot = settle && span > 0 ? settleThrough(from, through, p, cue.camera3d.tension, settle * 1e3 / span) : sampleThrough(from, through, p, cue.camera3d.tension);
2807
+ }
2808
+ continue;
2809
+ }
2810
+ const want = cue.camera3d.to;
2811
+ const fromLook = from.look;
2812
+ const to = cue.camera3d.by ? {
2813
+ dolly: from.dolly * (want.dolly ?? 1),
2814
+ look: want.look ? {
2815
+ x: (fromLook?.x ?? 0) + want.look.x,
2816
+ y: (fromLook?.y ?? 0) + want.look.y,
2817
+ z: (fromLook?.z ?? 0) + want.look.z
2818
+ } : fromLook,
2819
+ pitch: from.pitch + (want.pitch ?? 0),
2820
+ x: from.x + (want.x ?? 0),
2821
+ y: from.y + (want.y ?? 0),
2822
+ yaw: from.yaw + (want.yaw ?? 0)
2823
+ } : {
2824
+ dolly: want.dolly ?? from.dolly,
2825
+ look: want.look ?? fromLook,
2826
+ pitch: want.pitch ?? from.pitch,
2827
+ x: want.x ?? from.x,
2828
+ y: want.y ?? from.y,
2829
+ yaw: want.yaw ?? from.yaw
2830
+ };
2831
+ if (now <= t.start) shot = from;
2832
+ else {
2833
+ const p = now >= t.end ? 1 : this.cameraProgress(t, now - t.start);
2834
+ shot = {
2835
+ dolly: from.dolly + (to.dolly - from.dolly) * p,
2836
+ pitch: from.pitch + (to.pitch - from.pitch) * p,
2837
+ x: from.x + (to.x - from.x) * p,
2838
+ y: from.y + (to.y - from.y) * p,
2839
+ yaw: from.yaw + (to.yaw - from.yaw) * p
2840
+ };
2841
+ if (to.look || fromLook) {
2842
+ const a = fromLook ?? {
2843
+ x: 0,
2844
+ y: 0,
2845
+ z: 0
2846
+ };
2847
+ const b = to.look ?? a;
2848
+ shot.look = {
2849
+ x: a.x + (b.x - a.x) * p,
2850
+ y: a.y + (b.y - a.y) * p,
2851
+ z: a.z + (b.z - a.z) * p
2852
+ };
2853
+ }
2854
+ }
2855
+ continue;
2856
+ }
2857
+ if (cue.tether) {
2858
+ if (inside && !t.started) {
2859
+ t.started = true;
2860
+ const layer = this.options.tetherLayer;
2861
+ if (layer) {
2862
+ t.wire = document.createElementNS("http://www.w3.org/2000/svg", "path");
2863
+ t.wire.setAttribute("data-choreo-tether", "");
2864
+ if (t.cue.tether?.name) t.wire.setAttribute("data-thread", t.cue.tether.name);
2865
+ layer.appendChild(t.wire);
2866
+ }
2867
+ } else if (!inside && t.started) {
2868
+ t.started = false;
2869
+ t.wire?.remove();
2870
+ t.wire = void 0;
2871
+ }
2872
+ if (t.started && t.wire) this.scheduleTetherDraw();
2873
+ continue;
2874
+ }
2875
+ if (cue.derive) {
2876
+ if (inside && !t.started) {
2877
+ t.started = true;
2878
+ const ve = cue.sprite.node.visualElement;
2879
+ if (ve) for (const [key, rest] of Object.entries(cue.derive.rest)) this.movedValues.push({
2880
+ key,
2881
+ rest,
2882
+ ve
2883
+ });
2884
+ } else if (!inside && t.started) {
2885
+ t.started = false;
2886
+ this.restDerived(t);
2887
+ }
2888
+ if (t.started) this.drive(t, now);
2889
+ continue;
2890
+ }
2891
+ if (cue.raise) {
2892
+ if (inside && !t.started) {
2893
+ t.started = true;
2894
+ this.promote(t);
2895
+ } else if (!inside && t.started) {
2896
+ t.started = false;
2897
+ this.restore(t);
2898
+ }
2899
+ continue;
2900
+ }
2901
+ if (cue.scroll) {
2902
+ if (inside && !t.started) {
2903
+ t.started = true;
2904
+ this.startScroll(t);
2905
+ } else if (!inside && t.started && now < t.start) {
2906
+ t.started = false;
2907
+ this.stopScroll(t, true);
2908
+ }
2909
+ if (t.started && t.scrolling) {
2910
+ const p = this.flightlessProgress(t, now - t.start);
2911
+ const { container, from, to } = t.scrolling;
2912
+ container.scrollTop = from.top + (to.top - from.top) * p;
2913
+ container.scrollLeft = from.left + (to.left - from.left) * p;
2914
+ if (p >= 1 && this.playing) this.stopScroll(t, false);
2915
+ }
2916
+ continue;
2917
+ }
2918
+ if (cue.hold) {
2919
+ if (inside && !t.started) {
2920
+ t.started = true;
2921
+ const ve = cue.sprite.node.visualElement;
2922
+ if (ve) t.held = applyHold(ve, cue.sprite.element, cue.hold.values);
2923
+ } else if (!inside && t.started) {
2924
+ t.started = false;
2925
+ const ve = cue.sprite.node.visualElement;
2926
+ if (ve && t.held) {
2927
+ releaseHold(ve, cue.sprite.element, t.held);
2928
+ t.held = void 0;
2929
+ }
2930
+ }
2931
+ continue;
2932
+ }
2933
+ if (cue.kind === "wait") continue;
2934
+ if (inside && !t.started) this.startTrack(t);
2935
+ else if (inside && t.started && this.playing && !t.controls && !t.delivery && !t.loopAnimation && (cue.target || cue.flight)) this.startTrack(t);
2936
+ else if (!inside && t.started && now < t.start) {
2937
+ t.passed = false;
2938
+ t.started = false;
2939
+ flushKeyframeResolvers();
2940
+ this.stopTrack(t);
2941
+ t.delivery?.cancel();
2942
+ t.delivery = void 0;
2943
+ t.loopAnimation?.cancel();
2944
+ t.loopAnimation = void 0;
2945
+ if (t.origin) rewinds.push(t);
2946
+ } else if (t.started && now >= t.end && !cue.loop && !this.playing) this.completeTrack(t);
2947
+ else if (!t.started && !t.passed && now >= t.end && !cue.loop) this.jumpFinals(t);
2948
+ if (t.started && !this.playing && now >= t.start) {
2949
+ if (t.delivery) {
2950
+ t.delivery.pause();
2951
+ t.delivery.seek(now - t.start);
2952
+ } else if (t.loopAnimation) {
2953
+ t.loopAnimation.pause();
2954
+ const cycle = t.end - t.start;
2955
+ t.loopAnimation.currentTime = cycle ? (now - t.start + (t.loopOffset ?? 0)) % cycle : 0;
2956
+ } else if (cue.target || cue.flight) {
2957
+ if (t.controls) {
2958
+ flushKeyframeResolvers();
2959
+ this.stopTrack(t);
2960
+ }
2961
+ this.sampleStill(t, now);
2962
+ }
2963
+ }
2964
+ }
2965
+ if (shot) {
2966
+ const was = this.camera3d;
2967
+ if (was.yaw !== shot.yaw || was.pitch !== shot.pitch || was.dolly !== shot.dolly || was.x !== shot.x || was.y !== shot.y || was.look?.x !== shot.look?.x || was.look?.y !== shot.look?.y || was.look?.z !== shot.look?.z) {
2968
+ this.camera3d = shot;
2969
+ this.options.onCamera3D?.({ ...shot });
2970
+ }
2971
+ }
2972
+ this.rewind(rewinds, now);
2973
+ this.driveAttachments(now);
2974
+ this.foldPerforms(limit);
2975
+ }
2976
+ /** perform tracks whose commands the host currently holds (see foldPerforms) */
2977
+ performed = /* @__PURE__ */ new Set();
2978
+ /** dispatches queued for after the render pass, in fold order */
2979
+ pendingPerforms = [];
2980
+ performFlushBooked = false;
2981
+ /**
2982
+ * The command fold (§C4): the set of Perform cues at or before the
2983
+ * clock IS the commanded state. Every evaluate — a play tick and a seek
2984
+ * alike — re-derives the eligible set; growth dispatches the new
2985
+ * commands in time order, and any shrink (a backward seek) resets the
2986
+ * host first and replays the whole remaining prefix. Commands are
2987
+ * idempotent statements of state by contract (`lamp.on`, never a
2988
+ * toggle), which is exactly what makes the replay a re-derivation.
2989
+ *
2990
+ * Dispatches are DEFERRED past the render pass: the constructor's first
2991
+ * evaluate runs while Glimmer may still be rendering, and a command
2992
+ * exists to mutate application state. A reset collapses the queue — the
2993
+ * dropped dispatches were never seen, and the replay that follows
2994
+ * restates everything still standing.
2995
+ */
2996
+ foldPerforms(limit) {
2997
+ if (!this.options.onPerform && !this.options.onPerformReset) return;
2998
+ const now = this.master;
2999
+ const eligible = this.tracks.filter((t) => t.cue.perform && now >= t.start && t.start < limit).sort((a, b) => a.start - b.start);
3000
+ const held = new Set(eligible);
3001
+ if ([...this.performed].some((t) => !held.has(t))) {
3002
+ this.performed.clear();
3003
+ this.pendingPerforms.length = 0;
3004
+ this.pendingPerforms.push("reset");
3005
+ }
3006
+ for (const t of eligible) {
3007
+ if (this.performed.has(t)) continue;
3008
+ this.performed.add(t);
3009
+ const p = t.cue.perform;
3010
+ this.pendingPerforms.push({
3011
+ action: p.action,
3012
+ payload: p.payload,
3013
+ target: p.target,
3014
+ time: t.start / this.scale / 1e3
3015
+ });
3016
+ }
3017
+ if (this.pendingPerforms.length && !this.performFlushBooked) {
3018
+ this.performFlushBooked = true;
3019
+ frame.postRender(() => {
3020
+ this.performFlushBooked = false;
3021
+ const queue = this.pendingPerforms;
3022
+ this.pendingPerforms = [];
3023
+ for (const item of queue) if (item === "reset") this.options.onPerformReset?.();
3024
+ else this.options.onPerform?.(item);
3025
+ });
3026
+ }
3027
+ }
3028
+ /**
3029
+ * Stand rewound tracks back on their origins — the part of a backward
3030
+ * seek that must be ORDERED. A sprite with sequential cues has one
3031
+ * origin per cue, each equal to the previous cue's landing; restored
3032
+ * in track order they clobber forward and the sprite ends up standing
3033
+ * on its LAST future cue's origin (the Playhead demo's hand parked on
3034
+ * 'place' after a scrub to zero; its receipt refusing to dismiss). So:
3035
+ * latest-first, which leaves the EARLIEST future cue's origin — the
3036
+ * value the timeline actually holds at `now` — standing; and a key
3037
+ * that any track AT or BEFORE `now` writes is not touched at all,
3038
+ * because that track's own sample or landing is the answer.
3039
+ */
3040
+ rewind(rewinds, now) {
3041
+ rewinds.sort((a, b) => b.start - a.start);
3042
+ for (const t of rewinds) {
3043
+ const ve = t.cue.sprite.node.visualElement;
3044
+ if (!ve || !t.origin) continue;
3045
+ let wrote = false;
3046
+ for (const key in t.origin) if (!this.tracks.some((s) => s !== t && s.start <= now && s.cue.target !== void 0 && key in s.cue.target && s.cue.sprite.node.visualElement === ve)) {
3047
+ ve.getValue(key, t.origin[key]).jump(t.origin[key]);
3048
+ wrote = true;
3049
+ }
3050
+ if (wrote) ve.render();
3051
+ }
3052
+ }
3053
+ /** the eased progress of a plain clock-driven track */
3054
+ flightlessProgress(t, ms) {
3055
+ if (this.reduced) return ms > 0 ? 1 : 0;
3056
+ const span = t.end - t.start;
3057
+ const raw = span > 0 ? Math.min(1, Math.max(0, ms / span)) : 1;
3058
+ return easingDefinitionToFunction("easeInOut")(raw);
3059
+ }
3060
+ /**
3061
+ * The orbit pose in force. Public for the same reason `camera` is: it is
3062
+ * hand-off state, and a replacement run must continue from where this
3063
+ * one left the shot rather than snapping back to the framing.
3064
+ */
3065
+ camera3d;
3066
+ initial3d;
3067
+ camera;
3068
+ /**
3069
+ * The aim point P in force, local px. With transform-origin pinned at
3070
+ * 0 0, the applied transform is translate(x + (1−z)·P) scale(z) — the
3071
+ * frame's centre cancels out of the algebra entirely, so neither a
3072
+ * board that reflows mid-cue nor a stage that changes height between
3073
+ * cues can move the picture: the formula reads no live DOM at all.
3074
+ * z = 1 is the identity for any P. Public because it is hand-off state:
3075
+ * the next run lerps from the point THIS run left aimed, exactly as it
3076
+ * inherits the camera.
3077
+ */
3078
+ cameraAim = null;
3079
+ /**
3080
+ * The absolute pose a camera cue lands on, resolved against the pose it
3081
+ * starts from. Absolute fields pass through; missing fields hold; a
3082
+ * relative cue (Pan / SlowZoom) offsets and multiplies the pose in
3083
+ * force — which is why resolution happens AT START (live) or during the
3084
+ * prefix fold (reconstruction), never at compile.
3085
+ */
3086
+ static resolveCameraTo(cue, from) {
3087
+ const { by, to } = cue;
3088
+ return {
3089
+ x: by?.x !== void 0 ? from.x + by.x : to.x ?? from.x,
3090
+ y: by?.y !== void 0 ? from.y + by.y : to.y ?? from.y,
3091
+ zoom: by?.zoom !== void 0 ? from.zoom * by.zoom : to.zoom ?? from.zoom
3092
+ };
3093
+ }
3094
+ cameraProgress(t, ms) {
3095
+ if (this.reduced) return ms > 0 ? 1 : 0;
3096
+ const span = t.end - t.start;
3097
+ const raw = span > 0 ? Math.min(1, Math.max(0, ms / span)) : 1;
3098
+ const transition = t.cue.transition;
3099
+ if (isSpring(transition)) return spring({
3100
+ keyframes: [0, 100],
3101
+ ...transition ?? {}
3102
+ }).next(ms / this.scale).value / 100;
3103
+ return easingDefinitionToFunction(transition?.ease ?? "easeInOut")(raw);
3104
+ }
3105
+ /**
3106
+ * The camera and aim this run inherited, frozen at construction — the
3107
+ * fold origin every reconstruction starts from. Public because a
3108
+ * replacement run that re-executes the SAME score must inherit this
3109
+ * origin, not the pose in force: the pose in force is what the score's
3110
+ * prefix already produced, and folding the prefix from it applies every
3111
+ * relative cue twice (the world-dock law).
3112
+ */
3113
+ initialCamera;
3114
+ initialAim;
3115
+ /**
3116
+ * Rebuild the camera fold from the score prefix before a seek's still
3117
+ * (packages/choreo-gallery/realm/design/external-clock-camera-seek-handoff.md). Forward playback folds
3118
+ * each camera cue's landing into the run's cumulative camera as the
3119
+ * clock crosses it — but a random-access seek can jump clean over a
3120
+ * window, and a cue that never starts never folds: the clock reads `t`
3121
+ * while the picture holds an earlier shot. So every camera track's
3122
+ * bookkeeping (started, cameraFrom, aimFrom/aimTo, cameraP) is
3123
+ * re-derived here in timeline order from the run's initial camera;
3124
+ * evaluate() then recomputes exactly the numbers forward playback would
3125
+ * have produced, and play-after-scrub resumes from them. Pure
3126
+ * arithmetic over frozen numbers, like the rest of the camera: no DOM
3127
+ * is read, so backward and repeated seeks agree to the pixel.
3128
+ */
3129
+ reconstructCameraAt(limit) {
3130
+ const cams = this.tracks.filter((t) => t.cue.camera);
3131
+ if (!cams.length) return;
3132
+ const now = this.master;
3133
+ cams.sort((a, b) => a.start - b.start);
3134
+ const state = { ...this.initialCamera };
3135
+ let aim = this.initialAim ? { ...this.initialAim } : null;
3136
+ for (const t of cams) {
3137
+ if (!(now >= t.start && t.start < limit)) {
3138
+ t.started = false;
3139
+ t.passed = false;
3140
+ t.cameraP = 0;
3141
+ t.cameraTo = void 0;
3142
+ t.aimFrom = aim ?? void 0;
3143
+ t.aimTo = aim ?? void 0;
3144
+ t.cameraAnimation?.cancel();
3145
+ t.cameraAnimation = void 0;
3146
+ continue;
3147
+ }
3148
+ const cue = t.cue.camera;
3149
+ const aimTo = cue.origin ?? aim ?? cue.centre ?? {
3150
+ x: 0,
3151
+ y: 0
3152
+ };
3153
+ t.started = true;
3154
+ t.passed = false;
3155
+ t.cameraFrom = { ...state };
3156
+ t.cameraTo = ChoreoRun.resolveCameraTo(cue, t.cameraFrom);
3157
+ t.aimFrom = aim ?? aimTo;
3158
+ t.aimTo = aimTo;
3159
+ aim = aimTo;
3160
+ if (now >= t.end) {
3161
+ state.x = t.cameraTo.x;
3162
+ state.y = t.cameraTo.y;
3163
+ state.zoom = t.cameraTo.zoom;
3164
+ t.cameraP = 1;
3165
+ t.cameraAnimation?.cancel();
3166
+ t.cameraAnimation = void 0;
3167
+ }
3168
+ }
3169
+ this.camera = state;
3170
+ this.cameraAim = aim;
3171
+ if (!cams.some((t) => t.started)) this.applyCamera(cams[0]);
3172
+ }
3173
+ /**
3174
+ * The damped counter-scale (§6.4): steady sprites scale with the host but
3175
+ * not 1:1 — pow(z, .30) zoomed out so they stay readable, pow(z, .70)
3176
+ * zoomed in so they don't feel stuck, clamped to what the eye tolerates.
3177
+ */
3178
+ static damped(zoom) {
3179
+ return Math.min(1.8, Math.max(.85, Math.pow(zoom, zoom < 1 ? .3 : .7))) / zoom;
3180
+ }
3181
+ /**
3182
+ * The frame's APPLIED transform for a camera state at aim progress `p`.
3183
+ *
3184
+ * Transform-origin is pinned at 0 0, so the applied transform is
3185
+ * translate(x + (1−z)·P) scale(z) with P the lerped aim point — pure
3186
+ * arithmetic over frozen numbers. Nothing here reads the DOM, so a board
3187
+ * that reflows mid-cue cannot move the camera, and every boundary
3188
+ * (landing, re-aim, next run) agrees to the pixel. At z = 1 the aim term
3189
+ * vanishes: an unpanned camera is EXACTLY the identity.
3190
+ */
3191
+ appliedCamera(t, state, p) {
3192
+ const from = t.aimFrom ?? t.aimTo ?? {
3193
+ x: 0,
3194
+ y: 0
3195
+ };
3196
+ const to = t.aimTo ?? from;
3197
+ const aim = {
3198
+ x: from.x + (to.x - from.x) * p,
3199
+ y: from.y + (to.y - from.y) * p
3200
+ };
3201
+ return {
3202
+ x: state.x + (1 - state.zoom) * aim.x,
3203
+ y: state.y + (1 - state.zoom) * aim.y,
3204
+ zoom: state.zoom
3205
+ };
3206
+ }
3207
+ static cameraCss(a) {
3208
+ return a.zoom === 1 && a.x === 0 && a.y === 0 ? "" : `translate(${a.x}px, ${a.y}px) scale(${a.zoom})`;
3209
+ }
3210
+ /**
3211
+ * Fly the region's frame on the platform: two transform keyframes and the
3212
+ * eased clock pre-sampled into a linear() easing. The biggest layer in the
3213
+ * region composites off the main thread for the whole move.
3214
+ */
3215
+ startCameraAnimation(t, now) {
3216
+ const host = this.options.cameraFrame;
3217
+ const from = t.cameraFrom;
3218
+ const cue = t.cue.camera;
3219
+ if (!host || !from || !cue) return;
3220
+ const final = t.cameraTo ?? ChoreoRun.resolveCameraTo(cue, from);
3221
+ const span = Math.max(1, t.end - t.start);
3222
+ const anim = host.animate([{ transform: ChoreoRun.cameraCss(this.appliedCamera(t, from, 0)) || "none" }, { transform: ChoreoRun.cameraCss(this.appliedCamera(t, final, 1)) || "none" }], {
3223
+ duration: span,
3224
+ easing: generateLinearEasing((p) => this.cameraProgress(t, p * span), span),
3225
+ fill: "both"
3226
+ });
3227
+ anim.playbackRate = this.rate;
3228
+ anim.currentTime = Math.max(0, now - t.start);
3229
+ t.cameraAnimation = anim;
3230
+ }
3231
+ /**
3232
+ * Retire the frame's platform animation and hand the picture back to
3233
+ * inline style, written from the shadow state — so a cancel mid-zoom
3234
+ * freezes exactly where the eye was, and a landing holds its final.
3235
+ */
3236
+ dropCameraAnimation(t) {
3237
+ if (!t.cameraAnimation) return;
3238
+ t.cameraAnimation.cancel();
3239
+ t.cameraAnimation = void 0;
3240
+ this.applyCamera(t);
3241
+ }
3242
+ applyCamera(t) {
3243
+ const frame = this.options.cameraFrame;
3244
+ if (!frame) return;
3245
+ const { zoom } = this.camera;
3246
+ frame.style.transformOrigin = "0px 0px";
3247
+ if (!t.cameraAnimation) frame.style.transform = ChoreoRun.cameraCss(this.appliedCamera(t, this.camera, t.cameraP ?? 1));
3248
+ for (const sprite of t.cue.camera?.steady ?? []) {
3249
+ const ve = sprite.node.visualElement;
3250
+ if (ve) {
3251
+ const counter = ChoreoRun.damped(zoom);
3252
+ ve.getValue("scale", counter).set(counter);
3253
+ }
3254
+ }
3255
+ }
3256
+ tetherDrawScheduled = false;
3257
+ scheduleTetherDraw() {
3258
+ if (this.tetherDrawScheduled) return;
3259
+ this.tetherDrawScheduled = true;
3260
+ frame.postRender(() => {
3261
+ this.tetherDrawScheduled = false;
3262
+ for (const t of this.tracks) if (t.started && t.wire) this.drawTether(t);
3263
+ });
3264
+ }
3265
+ /**
3266
+ * One frame of a derived value (§4.10): compose the context from the
3267
+ * pass's measurements, hand it to the author's function, write what
3268
+ * comes back.
3269
+ *
3270
+ * Nothing here touches the DOM — that is the design, not an
3271
+ * optimisation (packages/choreo-gallery/realm/docs/postmortem-follow.md). The resting boxes were
3272
+ * measured by the pass with every moved value released, and a source's
3273
+ * `now` is its resting box composed with the motion values driving it
3274
+ * this frame: JS-side numbers, not a measurement. So a follower is pure
3275
+ * BY CONSTRUCTION — there is no live box in reach, it cannot read back
3276
+ * its own output, and it cannot force a style recalculation in the
3277
+ * middle of a move. It is also correct under INTERRUPTION for free: a
3278
+ * replacement run's pass re-measures, so a run born mid-flight computes
3279
+ * from rests that are right immediately, with no "last frame" to
3280
+ * disagree with.
3281
+ *
3282
+ * `set`, not an animation: a derived value IS the frame, so there is
3283
+ * nothing to interpolate toward and nothing the compositor could be
3284
+ * given — this is the main-thread cost the step charges, and the reason
3285
+ * it is the same cost `c.Tether` already pays.
3286
+ */
3287
+ drive(t, now) {
3288
+ const derive = t.cue.derive;
3289
+ const ve = t.cue.sprite.node.visualElement;
3290
+ if (!derive || !ve) return;
3291
+ const sources = derive.sources.map(({ from, sprite, to }) => {
3292
+ const sv = sprite.node.visualElement;
3293
+ const num = (key) => {
3294
+ const value = sv?.getValue(key)?.get();
3295
+ return typeof value === "number" ? value : void 0;
3296
+ };
3297
+ const sx = num("scaleX") ?? num("scale") ?? 1;
3298
+ const sy = num("scaleY") ?? num("scale") ?? 1;
3299
+ const width = to.width * sx;
3300
+ const height = to.height * sy;
3301
+ return {
3302
+ from,
3303
+ now: {
3304
+ height,
3305
+ width,
3306
+ x: to.x + (num("x") ?? 0) + (to.width - width) / 2,
3307
+ y: to.y + (num("y") ?? 0) + (to.height - height) / 2
3308
+ },
3309
+ to
3310
+ };
3311
+ });
3312
+ const span = t.end - t.start;
3313
+ const values = derive.read({
3314
+ camera: { ...this.camera },
3315
+ p: span > 0 ? Math.max(0, Math.min(1, (now - t.start) / span)) : 1,
3316
+ rest: { ...derive.restBox },
3317
+ sources,
3318
+ t: now / 1e3
3319
+ });
3320
+ for (const [key, value] of Object.entries(values)) ve.getValue(key, value).set(value);
3321
+ ve.render();
3322
+ }
3323
+ /** the window closed (or was scrubbed out of): put the declared rest back */
3324
+ restDerived(t) {
3325
+ const rest = t.cue.derive?.rest;
3326
+ const ve = t.cue.sprite.node.visualElement;
3327
+ if (!rest || !ve) return;
3328
+ for (const [key, value] of Object.entries(rest)) ve.getValue(key, value).jump(value);
3329
+ ve.render();
3330
+ }
3331
+ drawTether(t) {
3332
+ const layer = this.options.tetherLayer;
3333
+ const tether = t.cue.tether;
3334
+ if (!layer || !tether || !t.wire) return;
3335
+ const inverse = layer.getScreenCTM()?.inverse();
3336
+ const box = layer.getBoundingClientRect();
3337
+ const toLocal = (clientX, clientY) => {
3338
+ if (!inverse) return {
3339
+ x: clientX - box.left,
3340
+ y: clientY - box.top
3341
+ };
3342
+ const p = new DOMPoint(clientX, clientY).matrixTransform(inverse);
3343
+ return {
3344
+ x: p.x,
3345
+ y: p.y
3346
+ };
3347
+ };
3348
+ const rectOf = (sprite) => {
3349
+ const el = sprite?.element;
3350
+ if (!el?.isConnected) return null;
3351
+ const r = el.getBoundingClientRect();
3352
+ const tl = toLocal(r.left, r.top);
3353
+ const br = toLocal(r.right, r.bottom);
3354
+ return {
3355
+ height: br.y - tl.y,
3356
+ width: br.x - tl.x,
3357
+ x: tl.x,
3358
+ y: tl.y
3359
+ };
3360
+ };
3361
+ const a = rectOf(tether.from);
3362
+ const b = rectOf(tether.to);
3363
+ if (a && b) t.wire.setAttribute("d", tether.path(a, b));
3364
+ }
3365
+ /**
3366
+ * The scale between the layer's own pixels and the screen's, per axis.
3367
+ *
3368
+ * A promotion reads client rects and writes LOCAL pixels, and every
3369
+ * transform above the region — a camera zoom, a page crossing carrying the
3370
+ * whole scene, any ancestor with a scale on it — sits between the two. Read
3371
+ * off the layer itself: its rect is what the screen shows, its offset size
3372
+ * is what its own coordinate system calls that. Dividing by the camera zoom
3373
+ * alone would catch the region's own transform and miss everything outside
3374
+ * it, which is the double-scale the tether draw already dodges by mapping
3375
+ * through the screen CTM.
3376
+ */
3377
+ static layerScale(el, box) {
3378
+ return {
3379
+ x: el.offsetWidth ? box.width / el.offsetWidth : 1,
3380
+ y: el.offsetHeight ? box.height / el.offsetHeight : 1
3381
+ };
3382
+ }
3383
+ promote(t) {
3384
+ const layer = this.options.raisedLayer;
3385
+ const el = t.cue.sprite.element;
3386
+ if (!layer || !el.isConnected || t.perch) return;
3387
+ const box = el.getBoundingClientRect();
3388
+ const layerBox = layer.getBoundingClientRect();
3389
+ const s = ChoreoRun.layerScale(layer, layerBox);
3390
+ const width = box.width / s.x;
3391
+ const height = box.height / s.y;
3392
+ const placeholder = document.createElement(el.tagName);
3393
+ placeholder.setAttribute("aria-hidden", "true");
3394
+ placeholder.style.cssText = `visibility:hidden;width:${width}px;height:${height}px;margin:0;flex:none`;
3395
+ const prior = el.style.cssText;
3396
+ el.parentNode?.insertBefore(placeholder, el);
3397
+ layer.appendChild(el);
3398
+ el.style.position = "absolute";
3399
+ el.style.left = `${(box.left - layerBox.left) / s.x}px`;
3400
+ el.style.top = `${(box.top - layerBox.top) / s.y}px`;
3401
+ el.style.width = `${width}px`;
3402
+ el.style.height = `${height}px`;
3403
+ el.style.margin = "0";
3404
+ if (t.cue.raise?.shadow) el.style.filter = "drop-shadow(0 18px 24px rgba(0,0,0,0.35))";
3405
+ t.perch = {
3406
+ placeholder,
3407
+ prior
3408
+ };
3409
+ }
3410
+ restore(t) {
3411
+ const el = t.cue.sprite.element;
3412
+ const perch = t.perch;
3413
+ if (!perch) return;
3414
+ t.perch = void 0;
3415
+ perch.placeholder.parentNode?.replaceChild(el, perch.placeholder);
3416
+ el.style.cssText = perch.prior;
3417
+ t.cue.sprite.node.visualElement?.scheduleRender();
3418
+ }
3419
+ startScroll(t) {
3420
+ const el = t.cue.sprite.element;
3421
+ let container = el.parentElement;
3422
+ while (container) {
3423
+ const cs = getComputedStyle(container);
3424
+ if (/(auto|scroll)/.test(cs.overflowY + cs.overflowX)) break;
3425
+ container = container.parentElement;
3426
+ }
3427
+ if (!container) return;
3428
+ const box = el.getBoundingClientRect();
3429
+ const cBox = container.getBoundingClientRect();
3430
+ const s = ChoreoRun.layerScale(container, cBox);
3431
+ const align = t.cue.scroll.align;
3432
+ const offsetY = (box.top - cBox.top) / s.y + container.scrollTop;
3433
+ const offsetX = (box.left - cBox.left) / s.x + container.scrollLeft;
3434
+ const factor = align === "center" ? .5 : align === "end" ? 1 : 0;
3435
+ const to = {
3436
+ left: Math.max(0, offsetX - (container.clientWidth - box.width / s.x) * factor),
3437
+ top: Math.max(0, offsetY - (container.clientHeight - box.height / s.y) * factor)
3438
+ };
3439
+ const onWheel = () => this.stopScroll(t, false);
3440
+ container.addEventListener("wheel", onWheel, { passive: true });
3441
+ container.addEventListener("touchmove", onWheel, { passive: true });
3442
+ t.scrolling = {
3443
+ cancelListener: () => {
3444
+ container.removeEventListener("wheel", onWheel);
3445
+ container.removeEventListener("touchmove", onWheel);
3446
+ },
3447
+ container,
3448
+ from: {
3449
+ left: container.scrollLeft,
3450
+ top: container.scrollTop
3451
+ },
3452
+ to
3453
+ };
3454
+ }
3455
+ stopScroll(t, rewind) {
3456
+ const s = t.scrolling;
3457
+ if (!s) return;
3458
+ t.scrolling = void 0;
3459
+ s.cancelListener();
3460
+ if (rewind) {
3461
+ s.container.scrollTop = s.from.top;
3462
+ s.container.scrollLeft = s.from.left;
3463
+ }
3464
+ }
3465
+ /** stop a track's animations at the value level — an async animation
3466
+ * cancelled before it resolves stays 'idle' forever if only the controls
3467
+ * are stopped, and its value then reads as animating for good */
3468
+ stopTrack(t) {
3469
+ t.controls?.forEach((c) => c.stop());
3470
+ t.controls = void 0;
3471
+ t.platform?.forEach((a) => a.cancel());
3472
+ t.platform = void 0;
3473
+ const ve = t.cue.sprite.node.visualElement;
3474
+ if (ve && t.cue.target) for (const key in t.cue.target) ve.getValue(key)?.stop();
3475
+ }
3476
+ /** land a cue's end values without ever having played it */
3477
+ jumpFinals(t) {
3478
+ const { cue } = t;
3479
+ const ve = cue.sprite.node.visualElement;
3480
+ if (!ve || !cue.target && !cue.flight) return;
3481
+ if (cue.flight) {
3482
+ this.applyFlight(t, 1);
3483
+ ve.render();
3484
+ if (!cue.target) {
3485
+ t.passed = true;
3486
+ return;
3487
+ }
3488
+ }
3489
+ if (!t.origin) {
3490
+ const origin = {};
3491
+ for (const key in cue.target) {
3492
+ const value = cue.target[key];
3493
+ if (Array.isArray(value)) origin[key] = value[0];
3494
+ else {
3495
+ const held = ve.getValue(key)?.get();
3496
+ origin[key] = held !== void 0 ? held : getComputedStyle(cue.sprite.element).getPropertyValue(dash(key)) || 0;
3497
+ }
3498
+ }
3499
+ t.origin = origin;
3500
+ }
3501
+ t.passed = true;
3502
+ for (const key in cue.target) {
3503
+ const raw = cue.target[key];
3504
+ const end = Array.isArray(raw) ? raw[raw.length - 1] : raw;
3505
+ ve.getValue(key, end).jump(end);
3506
+ }
3507
+ ve.render();
3508
+ }
3509
+ startTrack(t) {
3510
+ const { cue } = t;
3511
+ const ve = cue.sprite.node.visualElement;
3512
+ if (!ve) return;
3513
+ t.started = true;
3514
+ t.passed = false;
3515
+ if (cue.target && !t.origin) {
3516
+ const origin = {};
3517
+ for (const key in cue.target) {
3518
+ const value = cue.target[key];
3519
+ if (Array.isArray(value)) origin[key] = value[0];
3520
+ else {
3521
+ const held = ve.getValue(key)?.get();
3522
+ const latest = ve.latestValues[key];
3523
+ origin[key] = held !== void 0 ? held : latest !== void 0 ? latest : getComputedStyle(cue.sprite.element).getPropertyValue(dash(key)) || 0;
3524
+ }
3525
+ }
3526
+ t.origin = origin;
3527
+ }
3528
+ if (cue.delivery) {
3529
+ for (const key in cue.target) {
3530
+ const raw = cue.target[key];
3531
+ if (Array.isArray(raw)) {
3532
+ const end = raw[raw.length - 1];
3533
+ ve.getValue(key, end).jump(end);
3534
+ }
3535
+ }
3536
+ ve.render();
3537
+ t.delivery = deliver(cue, this.scale, this.reduced);
3538
+ if (!this.playing) t.delivery.pause();
3539
+ return;
3540
+ }
3541
+ if (cue.loop) {
3542
+ const target = this.reduced ? withoutMovement(cue.target) : cue.target;
3543
+ const el = cue.sprite.element;
3544
+ const cycle = t.end - t.start;
3545
+ const phase = this.options.loops?.get(cue.sprite.node)?.get(loopKey(cue));
3546
+ t.loopOffset = phase === void 0 ? void 0 : phase * cycle;
3547
+ const times = cue.transition?.times;
3548
+ const segmentEase = cssEasing(cue.transition?.ease, cycle);
3549
+ t.loopAnimation = el.animate(keyframesOf(target ?? {}, Object.keys(target ?? {}).length ? times : void 0, segmentEase), {
3550
+ duration: Math.max(1, cycle),
3551
+ easing: times ? "linear" : segmentEase,
3552
+ iterations: Infinity
3553
+ });
3554
+ t.loopAnimation.currentTime = (Math.max(0, this.master - t.start) + (t.loopOffset ?? 0)) % Math.max(1, cycle);
3555
+ t.loopAnimation.playbackRate = this.rate;
3556
+ if (!this.playing) t.loopAnimation.pause();
3557
+ return;
3558
+ }
3559
+ if (cue.flight) {
3560
+ this.startFlight(t);
3561
+ return;
3562
+ }
3563
+ if (!cue.target) return;
3564
+ if (!this.playing) {
3565
+ this.sampleStill(t, this.master);
3566
+ return;
3567
+ }
3568
+ const transition = carryVelocity(scaleTransition({
3569
+ ...cue.transition,
3570
+ reduceMotion: this.reduced
3571
+ }, this.scale), cue, this.options.inherit);
3572
+ t.controls = animateTarget(ve, {
3573
+ ...cue.target,
3574
+ transition
3575
+ });
3576
+ for (const c of t.controls) c.speed = this.rate;
3577
+ }
3578
+ /** put the sprite at progress `p` of its sampled flight path (§4.4) */
3579
+ applyFlight(t, p) {
3580
+ const { cue } = t;
3581
+ const ve = cue.sprite.node.visualElement;
3582
+ const flight = cue.flight;
3583
+ if (!ve || !flight) return;
3584
+ const pts = flight.points;
3585
+ const at = Math.min(pts.length - 1 - 1e-9, Math.max(0, p) * (pts.length - 1));
3586
+ const index = Math.floor(at);
3587
+ const local = at - index;
3588
+ const a = pts[index];
3589
+ const b = pts[Math.min(index + 1, pts.length - 1)];
3590
+ const x = a.x + (b.x - a.x) * local - flight.rest.x;
3591
+ const y = a.y + (b.y - a.y) * local - flight.rest.y;
3592
+ ve.getValue("x", x).set(x);
3593
+ ve.getValue("y", y).set(y);
3594
+ if (flight.rotate !== void 0) {
3595
+ const angle = Math.atan2(b.y - a.y, b.x - a.x) * 180 / Math.PI + (typeof flight.rotate === "number" ? flight.rotate : 0);
3596
+ ve.getValue("rotate", angle).set(angle);
3597
+ }
3598
+ }
3599
+ /** the eased progress a flight sits at, `ms` into its window */
3600
+ flightProgress(t, ms) {
3601
+ if (this.reduced) return ms > 0 ? 1 : 0;
3602
+ const span = t.end - t.start;
3603
+ const raw = span > 0 ? Math.min(1, Math.max(0, ms / span)) : 1;
3604
+ const transition = t.cue.transition;
3605
+ if (isSpring(transition)) {
3606
+ const pts = t.cue.flight.points;
3607
+ const end = pts[pts.length - 1];
3608
+ const distance = Math.hypot(end.x, end.y) || 1;
3609
+ return spring({
3610
+ keyframes: [0, distance],
3611
+ ...transition ?? {}
3612
+ }).next(ms / this.scale).value / distance;
3613
+ }
3614
+ return easingDefinitionToFunction(transition?.ease ?? "easeInOut")(raw);
3615
+ }
3616
+ /**
3617
+ * The sampled path as platform keyframes: each point becomes a transform,
3618
+ * uniformly spaced (the points were sampled uniformly in progress), and
3619
+ * the eased clock rides the animation's easing instead of per-frame JS.
3620
+ */
3621
+ flightKeyframes(t) {
3622
+ const flight = t.cue.flight;
3623
+ const pts = flight.points;
3624
+ const frames = [];
3625
+ for (let i = 0; i < pts.length; i++) {
3626
+ const p = pts[i];
3627
+ let transform = `translate(${p.x - flight.rest.x}px, ${p.y - flight.rest.y}px)`;
3628
+ if (flight.rotate !== void 0) {
3629
+ const a = pts[Math.max(0, i - 1)];
3630
+ const b = pts[Math.min(pts.length - 1, i + 1)];
3631
+ const angle = Math.atan2(b.y - a.y, b.x - a.x) * 180 / Math.PI + (typeof flight.rotate === "number" ? flight.rotate : 0);
3632
+ transform += ` rotate(${angle}deg)`;
3633
+ }
3634
+ frames.push({ transform });
3635
+ }
3636
+ return frames;
3637
+ }
3638
+ startFlight(t) {
3639
+ const { cue } = t;
3640
+ const ve = cue.sprite.node.visualElement;
3641
+ if (!ve) return;
3642
+ if (!this.playing) {
3643
+ this.sampleStill(t, this.master);
3644
+ return;
3645
+ }
3646
+ const span = Math.max(1, t.end - t.start);
3647
+ const controls = [];
3648
+ const anim = cue.sprite.element.animate(this.flightKeyframes(t), {
3649
+ duration: span,
3650
+ easing: generateLinearEasing((p) => this.flightProgress(t, p * span), span),
3651
+ fill: "both"
3652
+ });
3653
+ anim.playbackRate = this.rate;
3654
+ anim.currentTime = Math.min(span, Math.max(0, this.master - t.start));
3655
+ (t.platform ??= []).push(anim);
3656
+ controls.push(platformControls(anim));
3657
+ if (cue.target && Object.keys(cue.target).length) {
3658
+ const transition = scaleTransition({
3659
+ ...cue.transition,
3660
+ onUpdate: noop
3661
+ }, this.scale);
3662
+ controls.push(...animateTarget(ve, {
3663
+ ...cue.target,
3664
+ transition
3665
+ }));
3666
+ }
3667
+ for (const c of controls) c.speed = this.rate;
3668
+ t.controls = controls;
3669
+ }
3670
+ /** compute one still frame of a cue and jump the values onto the element */
3671
+ sampleStill(t, now) {
3672
+ const { cue } = t;
3673
+ const ve = cue.sprite.node.visualElement;
3674
+ if (!ve || !cue.target && !cue.flight) return;
3675
+ if (cue.flight) {
3676
+ this.applyFlight(t, this.flightProgress(t, now - t.start));
3677
+ ve.render();
3678
+ if (!cue.target) return;
3679
+ }
3680
+ const span = t.end - t.start;
3681
+ const p = span > 0 ? Math.min(1, Math.max(0, (now - t.start) / span)) : 1;
3682
+ const transition = cue.transition;
3683
+ const sprung = isSpring(transition);
3684
+ const ease = sprung ? null : easingDefinitionToFunction(transition?.ease ?? "easeInOut");
3685
+ for (const key in cue.target) {
3686
+ const raw = cue.target[key];
3687
+ const frames = Array.isArray(raw) ? raw : [t.origin?.[key] ?? 0, raw];
3688
+ const numeric = frames.map((f) => parseFloat(String(f)));
3689
+ if (numeric.some((n) => Number.isNaN(n))) {
3690
+ const segments = frames.length - 1;
3691
+ if (segments < 1) {
3692
+ ve.getValue(key, frames[0]).jump(frames[0]);
3693
+ continue;
3694
+ }
3695
+ let at;
3696
+ if (sprung) at = spring({
3697
+ keyframes: [0, segments],
3698
+ ...transition ?? {}
3699
+ }).next(now - t.start).value;
3700
+ else at = (ease ? ease(p) : p) * segments;
3701
+ at = Math.min(segments - 1e-9, Math.max(0, at));
3702
+ const index = Math.floor(at);
3703
+ const value = mix(frames[index], frames[index + 1])(at - index);
3704
+ ve.getValue(key, value).jump(value);
3705
+ continue;
3706
+ }
3707
+ let value;
3708
+ if (sprung) value = spring({
3709
+ keyframes: [numeric[0], numeric[numeric.length - 1]],
3710
+ ...transition ?? {}
3711
+ }).next(now - t.start).value;
3712
+ else {
3713
+ const times = Array.isArray(raw) ? transition?.times : void 0;
3714
+ const eased = ease ? ease(p) : p;
3715
+ const segments = numeric.length - 1;
3716
+ const at = Math.min(segments - 1e-9, eased * segments);
3717
+ const index = times ? p >= 1 ? segments - 1 : Math.max(0, times.findIndex((time) => time > p) - 1) : Math.max(0, Math.floor(at));
3718
+ const progress = times ? p >= 1 ? 1 : (p - times[index]) / (times[index + 1] - times[index]) : at - index;
3719
+ const local = times && ease ? ease(progress) : progress;
3720
+ value = numeric[index] + (numeric[index + 1] - numeric[index]) * local;
3721
+ }
3722
+ ve.getValue(key, value).jump(value);
3723
+ }
3724
+ ve.render();
3725
+ }
3726
+ completeTrack(t) {
3727
+ const { cue } = t;
3728
+ if (t.passed) return;
3729
+ t.passed = true;
3730
+ t.started = false;
3731
+ flushKeyframeResolvers();
3732
+ this.stopTrack(t);
3733
+ if (t.delivery) {
3734
+ t.delivery.complete();
3735
+ t.delivery = void 0;
3736
+ }
3737
+ const ve = cue.sprite.node.visualElement;
3738
+ if (ve && cue.flight) {
3739
+ this.applyFlight(t, 1);
3740
+ ve.render();
3741
+ }
3742
+ if (ve && cue.target) {
3743
+ for (const key in cue.target) {
3744
+ const raw = cue.target[key];
3745
+ const end = Array.isArray(raw) ? raw[raw.length - 1] : raw;
3746
+ ve.getValue(key, end).jump(end);
3747
+ }
3748
+ ve.render();
3749
+ }
3750
+ }
3751
+ pinStarts() {
3752
+ const pinned = /* @__PURE__ */ new Set();
3753
+ const rendered = /* @__PURE__ */ new Set();
3754
+ for (const t of [...this.tracks].sort((a, b) => a.start - b.start)) {
3755
+ const cue = t.cue;
3756
+ const ve = cue.sprite.node.visualElement;
3757
+ if (!ve || cue.loop) continue;
3758
+ if (cue.flight) {
3759
+ this.movedValues.push({
3760
+ key: "x",
3761
+ ve
3762
+ }, {
3763
+ key: "y",
3764
+ ve
3765
+ });
3766
+ this.owned.push({
3767
+ el: cue.sprite.element,
3768
+ key: "x",
3769
+ ve
3770
+ }, {
3771
+ el: cue.sprite.element,
3772
+ key: "y",
3773
+ ve
3774
+ });
3775
+ if (cue.flight.rotate !== void 0) this.movedValues.push({
3776
+ key: "rotate",
3777
+ ve
3778
+ });
3779
+ this.applyFlight({ ...t }, 0);
3780
+ rendered.add(ve);
3781
+ }
3782
+ if (!cue.target) continue;
3783
+ for (const key in cue.target) {
3784
+ const value = cue.target[key];
3785
+ if (!Array.isArray(value) || value[0] === void 0) continue;
3786
+ const seen = `${cue.sprite.node.layoutKey}:${key}`;
3787
+ if (pinned.has(seen)) continue;
3788
+ pinned.add(seen);
3789
+ this.owned.push({
3790
+ el: cue.sprite.element,
3791
+ key,
3792
+ ve
3793
+ });
3794
+ if (cue.kind === "move") if (key in SIZES) {
3795
+ if (!ve.hasValue(key)) this.borrowedValues.push({
3796
+ el: cue.sprite.element,
3797
+ key,
3798
+ prior: cue.sprite.element.style.getPropertyValue(dash(key)),
3799
+ ve
3800
+ });
3801
+ } else this.movedValues.push({
3802
+ key,
3803
+ rest: key.startsWith("scale") ? 1 : key === "clipPath" ? "none" : 0,
3804
+ ve
3805
+ });
3806
+ else if (cue.borrow && !ve.hasValue(key)) this.borrowedValues.push({
3807
+ el: cue.sprite.element,
3808
+ key,
3809
+ prior: cue.sprite.element.style.getPropertyValue(dash(key)),
3810
+ ve
3811
+ });
3812
+ ve.getValue(key, value[0]).jump(value[0]);
3813
+ rendered.add(ve);
3814
+ }
3815
+ }
3816
+ rendered.forEach((ve) => ve.render());
3817
+ }
3818
+ sampleVelocities() {
3819
+ for (const { ve, el, key } of this.owned) {
3820
+ let byKey = this.velocities.get(el);
3821
+ if (byKey?.has(key)) continue;
3822
+ const velocity = ve.getValue(key)?.getVelocity();
3823
+ if (!velocity) continue;
3824
+ if (!byKey) this.velocities.set(el, byKey = /* @__PURE__ */ new Map());
3825
+ byKey.set(key, velocity);
3826
+ }
3827
+ }
3828
+ releaseForMeasure() {
3829
+ this.sampleVelocities();
3830
+ for (const t of this.tracks) {
3831
+ t.platform?.forEach((a) => a.cancel());
3832
+ t.platform = void 0;
3833
+ this.dropCameraAnimation(t);
3834
+ }
3835
+ const touched = /* @__PURE__ */ new Set();
3836
+ this.retired = {
3837
+ borrowed: [],
3838
+ moved: []
3839
+ };
3840
+ for (const { ve, el, key, prior } of this.borrowedValues.splice(0)) {
3841
+ this.retired.borrowed.push({
3842
+ el,
3843
+ key,
3844
+ prior,
3845
+ value: ve.getValue(key)?.get(),
3846
+ ve
3847
+ });
3848
+ ve.removeValue(key);
3849
+ if (prior) el.style.setProperty(dash(key), prior);
3850
+ else el.style.removeProperty(dash(key));
3851
+ touched.add(ve);
3852
+ }
3853
+ for (const { ve, key, rest } of this.movedValues.splice(0)) {
3854
+ this.retired.moved.push({
3855
+ key,
3856
+ rest,
3857
+ value: ve.getValue(key)?.get(),
3858
+ ve
3859
+ });
3860
+ ve.getValue(key)?.jump(rest ?? 0);
3861
+ touched.add(ve);
3862
+ }
3863
+ touched.forEach((ve) => ve.render());
3864
+ }
3865
+ /**
3866
+ * A pass measured this run's world at rest and then decided to KEEP the
3867
+ * run — but the measurement itself was destructive: releaseForMeasure
3868
+ * cancels platform animations, returns borrowed values, and jumps every
3869
+ * moved value to rest, and a MotionValue.jump() STOPS the animation
3870
+ * driving it. Left like that, a kept run keeps its clock and its landing
3871
+ * but loses its picture: the flight freezes at rest until the finals
3872
+ * land — which on a busy page (the gallery: neighbours re-pass the
3873
+ * region every render) is every crossing, every time. So the keep path
3874
+ * calls this: moved and borrowed values are stood back where they were,
3875
+ * their bookkeeping is re-registered, every in-flight track's animation
3876
+ * is retired so evaluate re-enters it — the machinery a scrub-then-play
3877
+ * already uses — and the re-entered animations are seeked back onto the
3878
+ * run's own clock, so a keep is invisible rather than a restart.
3879
+ */
3880
+ reassert() {
3881
+ const { borrowed, moved } = this.retired;
3882
+ this.retired = {
3883
+ borrowed: [],
3884
+ moved: []
3885
+ };
3886
+ for (const { el, key, prior, value, ve } of borrowed) {
3887
+ if (value !== void 0) ve.getValue(key, value).jump(value);
3888
+ this.borrowedValues.push({
3889
+ el,
3890
+ key,
3891
+ prior,
3892
+ ve
3893
+ });
3894
+ }
3895
+ for (const { key, rest, value, ve } of moved) {
3896
+ if (value !== void 0) ve.getValue(key)?.jump(value);
3897
+ this.movedValues.push({
3898
+ key,
3899
+ rest,
3900
+ ve
3901
+ });
3902
+ }
3903
+ if (!this.playing) return;
3904
+ const now = this.master;
3905
+ const restarted = [];
3906
+ for (const t of this.tracks) if (t.started && !t.passed && now >= t.start && (now < t.end || t.cue.loop) && (t.cue.target || t.cue.flight)) {
3907
+ flushKeyframeResolvers();
3908
+ this.stopTrack(t);
3909
+ restarted.push(t);
3910
+ }
3911
+ this.evaluate();
3912
+ for (const t of restarted) if (!t.cue.flight) {
3913
+ const at = Math.max(0, now - t.start) / 1e3;
3914
+ t.controls?.forEach((c) => {
3915
+ c.time = at;
3916
+ });
3917
+ }
3918
+ }
3919
+ cancel(keep) {
3920
+ if (this.cancelled) return;
3921
+ this.cancelled = true;
3922
+ activeRuns.delete(this);
3923
+ this.stopTicking();
3924
+ clearTimeout(this.autoTimer);
3925
+ this.pendingPerforms.length = 0;
3926
+ this.options.onCamera?.({ ...this.camera });
3927
+ flushKeyframeResolvers();
3928
+ this.sampleVelocities();
3929
+ for (const t of this.tracks) {
3930
+ this.stopTrack(t);
3931
+ t.delivery?.cancel();
3932
+ t.loopAnimation?.cancel();
3933
+ this.dropCameraAnimation(t);
3934
+ this.restore(t);
3935
+ this.stopScroll(t, false);
3936
+ t.wire?.remove();
3937
+ t.wire = void 0;
3938
+ const ve = t.cue.sprite.node.visualElement;
3939
+ if (t.held && ve) {
3940
+ releaseHold(ve, t.cue.sprite.element, t.held);
3941
+ t.held = void 0;
3942
+ }
3943
+ }
3944
+ this.releaseForMeasure();
3945
+ for (const sprite of [...this.pending]) if (keep?.has(sprite.node)) this.pending.delete(sprite);
3946
+ else {
3947
+ this.pending.delete(sprite);
3948
+ this.options.onSpriteDone(sprite);
3949
+ }
3950
+ this.resolveFinished();
3951
+ }
3952
+ };
3953
+ /** every live run, for the test helpers that drive gates and clocks */
3954
+ var activeRuns = /* @__PURE__ */ new Set();
3955
+ function execute(compiled, options) {
3956
+ return new ChoreoRun(compiled, options);
3957
+ }
3958
+ //#endregion
3959
+ export { resetBeacons as C, measure as E, registerBeacon as S, isRendered as T, sameScore as _, choreoHostById as a, trackGestures as b, join as c, resetBarrier as d, setBeforeMeasure as f, fadeOn as g, continuation as h, choreoHostAt as i, leave as l, compile as m, execute as n, closestChoreo as o, setPassScheduler as p, resetRunWarnings as r, setChoreoHost as s, activeRuns as t, registerSettle as u, GESTURE as v, boundsOf as w, measureBeacons as x, resetGestures as y };