@panphora/clayjs 1.17.0 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (467) hide show
  1. package/dist/all.js +1 -1
  2. package/dist/clay-dom.js +1 -1
  3. package/dist/clay-events.js +1 -1
  4. package/dist/clay-internals.js +1 -1
  5. package/dist/clay-options.js +1 -1
  6. package/dist/clay-router.js +1 -1
  7. package/dist/clay-ui.js +1 -1
  8. package/dist/clay-utils.js +1 -1
  9. package/dist/clay.js +1 -1
  10. package/dist/clay.standalone.js +72474 -62090
  11. package/dist/m/attrs/{save-freeze-MYNVXREN.js → save-freeze-LWGF6XUN.js} +1 -1
  12. package/dist/m/c-2GRUM77Q.js +30 -0
  13. package/dist/m/c-2KIEGNC4.js +1 -0
  14. package/dist/m/{c-AMSNPOCX.js → c-2KL3BD52.js} +1 -1
  15. package/dist/m/c-2ZZBC45O.js +1 -0
  16. package/dist/m/c-372N6H3B.js +1 -0
  17. package/dist/m/{c-4WKFKEKF.js → c-3G2DGZUP.js} +1 -1
  18. package/dist/m/c-3LDGIBMN.js +1 -0
  19. package/dist/m/c-3O7OBDCM.js +1 -0
  20. package/dist/m/c-4ASQPRQL.js +1 -0
  21. package/dist/m/c-4TXNLX4K.js +6 -0
  22. package/dist/m/c-4YU3BR4D.js +6 -0
  23. package/dist/m/c-5734MF2P.js +1 -0
  24. package/dist/m/c-57XDY6HC.js +1 -0
  25. package/dist/m/{c-KAU6E43D.js → c-5B4YBZXC.js} +1 -1
  26. package/dist/m/c-5ONTYIUI.js +1 -0
  27. package/dist/m/c-5OOVFCJM.js +1 -0
  28. package/dist/m/{c-3XIRD4NU.js → c-5T6NZHNM.js} +1 -1
  29. package/dist/m/{c-74MGYWZF.js → c-5ZQV7KC4.js} +1 -1
  30. package/dist/m/{c-7OLLJPWP.js → c-6DB2OLRJ.js} +1 -1
  31. package/dist/m/c-6DNRCPNM.js +1 -0
  32. package/dist/m/c-6UGWFMQC.js +2 -0
  33. package/dist/m/c-7K4SCQB7.js +1 -0
  34. package/dist/m/c-7MG5RU63.js +1 -0
  35. package/dist/m/c-7PRJCA3E.js +1 -0
  36. package/dist/m/c-A6L3FMUS.js +1 -0
  37. package/dist/m/c-AMU3BPPR.js +4 -0
  38. package/dist/m/{c-Y5HBBIQ4.js → c-AMYEFA2E.js} +1 -1
  39. package/dist/m/c-AQYCG7QW.js +1 -0
  40. package/dist/m/c-ATKAOH23.js +1 -0
  41. package/dist/m/c-B5CS55WR.js +1 -0
  42. package/dist/m/c-B5UJQT7W.js +1 -0
  43. package/dist/m/c-B7J4K2AE.js +3 -0
  44. package/dist/m/c-BHZYSHW4.js +1 -0
  45. package/dist/m/{c-VHM5XQHK.js → c-BIJALSRD.js} +1 -1
  46. package/dist/m/c-BJ7YQ5QZ.js +1 -0
  47. package/dist/m/{c-KIPQJX4B.js → c-BRLCTNMC.js} +1 -1
  48. package/dist/m/{c-VE6ZMYMC.js → c-BUAYFEV5.js} +1 -1
  49. package/dist/m/c-C6IPRG34.js +1 -0
  50. package/dist/m/{c-KU3ZFADW.js → c-CAS3NND4.js} +1 -1
  51. package/dist/m/{c-PS5ARVWR.js → c-CCQ25GFY.js} +1 -1
  52. package/dist/m/c-CJFDLD43.js +1 -0
  53. package/dist/m/c-COPTL5WB.js +1 -0
  54. package/dist/m/c-D3E4WJ4M.js +166 -0
  55. package/dist/m/c-D5IKEKXW.js +7 -0
  56. package/dist/m/c-DHBRA6DL.js +1 -0
  57. package/dist/m/c-DKLS74XB.js +72 -0
  58. package/dist/m/c-DVYGFTSK.js +3 -0
  59. package/dist/m/c-E3ZXARWA.js +1 -0
  60. package/dist/m/c-EK63G3CG.js +1 -0
  61. package/dist/m/c-ERQSNR6K.js +13 -0
  62. package/dist/m/c-EVYAISP3.js +1 -0
  63. package/dist/m/c-EXKHPOVC.js +3 -0
  64. package/dist/m/{c-QJ4OM3G6.js → c-FWKHM4E7.js} +1 -1
  65. package/dist/m/{c-4Q2XTQ2N.js → c-GBKB5WDL.js} +1 -1
  66. package/dist/m/c-GNDL3TKB.js +1 -0
  67. package/dist/m/c-GRWMD6O5.js +1 -0
  68. package/dist/m/c-GRXHHFPO.js +1 -0
  69. package/dist/m/c-HG2C77BM.js +4 -0
  70. package/dist/m/c-HHGJBU4D.js +1 -0
  71. package/dist/m/c-HMV6P4RX.js +1 -0
  72. package/dist/m/c-HMYWIHFG.js +1 -0
  73. package/dist/m/c-HT2DKBV2.js +1 -0
  74. package/dist/m/c-I2SCCUEW.js +1 -0
  75. package/dist/m/{c-TJ6WOJL3.js → c-ICJYHABF.js} +2 -2
  76. package/dist/m/c-IMZCWYHR.js +7 -0
  77. package/dist/m/c-IVMD3FEM.js +1 -0
  78. package/dist/m/{c-WDC5GVKU.js → c-IVTRVENZ.js} +1 -1
  79. package/dist/m/c-JKZJIUIP.js +1 -0
  80. package/dist/m/{c-UDUUJPFZ.js → c-JNLX3RJB.js} +1 -1
  81. package/dist/m/c-K3ADYNLU.js +1 -0
  82. package/dist/m/c-KGHVFRR3.js +1 -0
  83. package/dist/m/{c-5QWQ7A5L.js → c-KJJPV77R.js} +1 -1
  84. package/dist/m/{c-CZUSOB7V.js → c-KNPDOMDY.js} +1 -1
  85. package/dist/m/{c-EZU56NQV.js → c-KP64LT2A.js} +2 -2
  86. package/dist/m/c-KQ7E3PYY.js +1 -0
  87. package/dist/m/c-L3F5ZLIV.js +1 -0
  88. package/dist/m/{c-3RUU4TPX.js → c-L42OLXWM.js} +3 -2
  89. package/dist/m/c-L5VFATT6.js +1 -0
  90. package/dist/m/c-L7JL5TL3.js +3 -0
  91. package/dist/m/c-LKSL4AUJ.js +1 -0
  92. package/dist/m/c-M6FNQCTQ.js +1 -0
  93. package/dist/m/c-MCOOHCSG.js +1 -0
  94. package/dist/m/c-MHI3GYKF.js +1 -0
  95. package/dist/m/c-MWXFLW4J.js +1 -0
  96. package/dist/m/{c-5RJFTLSF.js → c-NEL7HQW3.js} +1 -1
  97. package/dist/m/{c-DCXOXBF3.js → c-NQJRVJ56.js} +1 -1
  98. package/dist/m/c-NWX3MFT4.js +1 -0
  99. package/dist/m/{c-HPURYVZS.js → c-OJYM642Q.js} +1 -1
  100. package/dist/m/c-OKXI52N7.js +1 -0
  101. package/dist/m/{c-R3L7ZJGB.js → c-OPLUZR3A.js} +1 -1
  102. package/dist/m/{c-GSFIGKOP.js → c-OTMKN2OO.js} +1 -1
  103. package/dist/m/{c-6NC5I2TV.js → c-OYRZ7XG2.js} +1 -1
  104. package/dist/m/{c-EVCQ3BKA.js → c-P3OFYUMA.js} +1 -1
  105. package/dist/m/c-PLN76GF3.js +6 -0
  106. package/dist/m/c-PLP4JKFC.js +1 -0
  107. package/dist/m/c-Q26MME6N.js +1 -0
  108. package/dist/m/{c-S7H2DRCB.js → c-Q3XOWZEV.js} +1 -1
  109. package/dist/m/{c-FRLHSY7E.js → c-QIKT6SKM.js} +1 -1
  110. package/dist/m/c-QIXT3Q7C.js +28 -0
  111. package/dist/m/c-QO4HNGCQ.js +1 -0
  112. package/dist/m/{c-JU3NK25H.js → c-R27DWQKX.js} +1 -1
  113. package/dist/m/{c-RSMOODDU.js → c-R2XUODVY.js} +1 -1
  114. package/dist/m/{c-QNKREOL6.js → c-R7LBFMF5.js} +1 -1
  115. package/dist/m/c-RND3G2S2.js +1 -0
  116. package/dist/m/{c-Q622NS2Y.js → c-S2U6NJU4.js} +1 -1
  117. package/dist/m/c-SPZPGD3R.js +1 -0
  118. package/dist/m/c-SW4YEG2D.js +8 -0
  119. package/dist/m/c-T637T7SN.js +1 -0
  120. package/dist/m/c-TJAXGIRV.js +1 -0
  121. package/dist/m/{c-RYUXUUBX.js → c-TNEM3RNM.js} +1 -1
  122. package/dist/m/c-TTB5EK4S.js +32 -0
  123. package/dist/m/c-U7SHNWDH.js +1 -0
  124. package/dist/m/c-UDHIVLYH.js +20 -0
  125. package/dist/m/{c-BBVGTQG7.js → c-UGNV5MFB.js} +1 -1
  126. package/dist/m/{c-QICP2YR5.js → c-UORXLSD3.js} +1 -1
  127. package/dist/m/c-UPD33ZPE.js +1 -0
  128. package/dist/m/c-URSMSFCB.js +1 -0
  129. package/dist/m/c-UY4QX42B.js +1 -0
  130. package/dist/m/c-V44KWI2L.js +4 -0
  131. package/dist/m/c-VILENZTD.js +1 -0
  132. package/dist/m/{c-HDDEEL77.js → c-VJYEVRYK.js} +1 -1
  133. package/dist/m/{c-SMBZG5X4.js → c-VR2BJ4AN.js} +1 -1
  134. package/dist/m/c-W4JCVLAB.js +1 -0
  135. package/dist/m/c-W6DQSHXI.js +135 -0
  136. package/dist/m/c-WBGWGOM7.js +1 -0
  137. package/dist/m/{c-4L3BTFRK.js → c-WCXLG3MV.js} +1 -1
  138. package/dist/m/c-WGW764WX.js +1 -0
  139. package/dist/m/c-WMRJKQ2V.js +5 -0
  140. package/dist/m/c-WNTYKCDG.js +1 -0
  141. package/dist/m/c-WQWIRWO3.js +72 -0
  142. package/dist/m/c-X5LNHET5.js +1 -0
  143. package/dist/m/{c-I2ZATQCD.js → c-X5TSXZYJ.js} +2 -2
  144. package/dist/m/c-XGH4GS2T.js +1 -0
  145. package/dist/m/c-Y6F2FORL.js +1 -0
  146. package/dist/m/c-YBKHUAK7.js +10 -0
  147. package/dist/m/c-YBSS55KU.js +20 -0
  148. package/dist/m/c-YCLU4UNT.js +2 -0
  149. package/dist/m/c-YVZ2L7CE.js +1 -0
  150. package/dist/m/c-ZK4GIZH2.js +1 -0
  151. package/dist/m/c-ZRXJD4G6.js +1 -0
  152. package/dist/m/c-ZWBI4HYK.js +1 -0
  153. package/dist/m/core/{admin-attrs-QHOKPJ7W.js → admin-attrs-YY7T5FGU.js} +1 -1
  154. package/dist/m/core/autosave-S6OMNDCK.js +1 -0
  155. package/dist/m/core/conflict-notice-IWHMHH43.js +1 -0
  156. package/dist/m/core/{host-permission-FNXVEFNE.js → host-permission-6EVJGNPL.js} +1 -1
  157. package/dist/m/core/is-edit-mode-GCX6767E.js +1 -0
  158. package/dist/m/core/{persist-JFYRHMRJ.js → persist-UKXV5KLA.js} +1 -1
  159. package/dist/m/core/recovery-DRFZRJED.js +1 -0
  160. package/dist/m/core/save-LYY7K6U7.js +1 -0
  161. package/dist/m/core/save-core-MKRPSEEO.js +1 -0
  162. package/dist/m/core/snapshot-NU3YM6GR.js +1 -0
  163. package/dist/m/core/unsaved-warning-7QTKEN7Z.js +1 -0
  164. package/dist/m/internals/{index-PVXGPUDA.js → index-TGLQINN3.js} +1 -1
  165. package/dist/m/loader-3BBNZZGM.js +1 -0
  166. package/dist/m/manifest-F449FF98.js +1 -0
  167. package/dist/m/manifest-edit-4396A009.js +1 -0
  168. package/dist/m/manifest.json +2111 -1573
  169. package/dist/m/page/{editor-NNJA4OKD.js → editor-6LRB3GE4.js} +123 -21
  170. package/dist/m/plugins/ai-edit-UTV7YO2I.js +6 -0
  171. package/dist/m/plugins/{cms-HP3LSTPN.js → cms-LRAOZHT7.js} +9 -9
  172. package/dist/m/plugins/{demo-RM5IR6AO.js → demo-OYO5GCAO.js} +1 -1
  173. package/dist/m/plugins/{derive-UAAA4V4S.js → derive-FRE5JJQE.js} +1 -1
  174. package/dist/m/plugins/indicator-4VDXWYTD.js +1 -0
  175. package/dist/m/plugins/live-AD4H6XSL.js +1 -0
  176. package/dist/m/plugins/menu-M5WW7DBF.js +1 -0
  177. package/dist/m/plugins/page-MD3T2ZX3.js +2 -0
  178. package/dist/m/plugins/page-view-PAWVZNFY.js +1 -0
  179. package/dist/m/plugins/{people-SGPJKANK.js → people-JCHVPF7P.js} +1 -1
  180. package/dist/m/plugins/quickcrop-BQ5YYFCH.js +26 -0
  181. package/dist/m/plugins/{richclay-NRQDSWX6.js → richclay-KLGETK77.js} +2 -2
  182. package/dist/m/plugins/sortable-4S6SQC3D.js +1 -0
  183. package/dist/m/plugins/source-TJXOIOYY.js +1 -0
  184. package/dist/m/plugins/undo-NLPGCJQY.js +1 -0
  185. package/dist/m/plugins/{unsent-HJFLQJ2O.js → unsent-OA4RGBUT.js} +1 -1
  186. package/dist/m/plugins/upgrade-HSUNDNJD.js +1 -0
  187. package/dist/m/plugins/{upload-WLYKK6TL.js → upload-NHGJXZK2.js} +1 -1
  188. package/dist/m/plugins/visitor-drafts-BW43DGY3.js +20 -0
  189. package/dist/m/plugins/visitor-drafts-owner-7ODQG7JX.js +1 -0
  190. package/dist/m/plugins/{wire-4N6GYAF6.js → wire-VBWXEXU2.js} +1 -1
  191. package/dist/m/reader-core-4W2KYEWQ.js +77 -0
  192. package/dist/m/route/route-62CHXL5B.js +1 -0
  193. package/dist/m/sync/live-sync-MO5DH33W.js +1 -0
  194. package/dist/m/ui/index-IVWN2QC4.js +1 -0
  195. package/dist/m/vendor/sap-core.vendor-RN4ZVY4X.js +6 -0
  196. package/dist/offline-manifest.json +1367 -930
  197. package/dist/page/themes/light-1.css +8 -7
  198. package/dist/server/core.cjs +1440 -288
  199. package/dist/server/offline-runtime.cjs +63 -63
  200. package/dist/server/offline-runtime.mjs +63 -63
  201. package/dist/server/page-compaction-worker.cjs +3710 -0
  202. package/dist/server/rooms.mjs +5 -0
  203. package/docs/guide.md +653 -101
  204. package/entries/sap.js +5 -5
  205. package/package.json +1 -1
  206. package/src/core/admin-contenteditable.js +5 -2
  207. package/src/core/admin-inputs.js +1 -0
  208. package/src/core/admin-onclick.js +2 -1
  209. package/src/core/conflict-notice-ui.js +4 -7
  210. package/src/core/download.js +2 -2
  211. package/src/core/host-meta.js +38 -0
  212. package/src/core/is-edit-mode.js +17 -1
  213. package/src/core/mode-key.js +125 -19
  214. package/src/core/mode-support.js +5 -0
  215. package/src/core/mode-transition.js +20 -6
  216. package/src/core/preserve-authored.js +4 -4
  217. package/src/core/recovery.js +121 -33
  218. package/src/core/save-accepted.js +33 -0
  219. package/src/core/save-core.js +106 -31
  220. package/src/core/save-job.js +108 -0
  221. package/src/core/save-prepare.js +53 -0
  222. package/src/core/save-size-notice.js +3 -1
  223. package/src/core/save-slices.js +15 -0
  224. package/src/core/save.js +557 -127
  225. package/src/core/serialize-steps.js +109 -0
  226. package/src/core/snapshot.js +170 -39
  227. package/src/core/source-map.js +83 -38
  228. package/src/core/stale-host-notice.js +1 -0
  229. package/src/core/upgrade-run.js +59 -8
  230. package/src/dom/active-element.js +5 -0
  231. package/src/lib/assets.js +1 -0
  232. package/src/lib/slice.js +65 -0
  233. package/src/lib/uimotion.js +774 -0
  234. package/src/lib/unsaved-state.js +2 -2
  235. package/src/live/fast-lane.js +10 -3
  236. package/src/live/local-lane.js +202 -11
  237. package/src/live/ops.js +16 -0
  238. package/src/live/page-compaction.js +162 -0
  239. package/src/live/server-lane.js +1 -0
  240. package/src/live/store.js +11 -3
  241. package/src/loader-logic.js +3 -1
  242. package/src/loader.js +14 -4
  243. package/src/page/adopt-boot.js +2 -1
  244. package/src/page/awareness.js +33 -2
  245. package/src/page/blocks.js +89 -27
  246. package/src/page/boot-pack.js +1 -1
  247. package/src/page/chart-tables.js +21 -3
  248. package/src/page/chart.js +406 -63
  249. package/src/page/checklist.js +10 -135
  250. package/src/page/checkpoint-proof.js +7 -1
  251. package/src/page/chrome.js +250 -51
  252. package/src/page/clipboard-shape.js +126 -0
  253. package/src/page/drag.js +33 -3
  254. package/src/page/editor.js +136 -25
  255. package/src/page/export-assets.js +357 -0
  256. package/src/page/export-html.js +209 -0
  257. package/src/page/export-markdown.js +361 -0
  258. package/src/page/features/checklist.js +428 -0
  259. package/src/page/features/export-html.js +189 -0
  260. package/src/page/features/export-markdown.js +169 -0
  261. package/src/page/features/import-markdown.js +349 -0
  262. package/src/page/features/media.js +61 -5
  263. package/src/page/features/registry.js +18 -0
  264. package/src/page/features/table.js +373 -83
  265. package/src/page/features/title-cover.js +331 -0
  266. package/src/page/features/title-icon.js +213 -0
  267. package/src/page/features/toc.js +87 -0
  268. package/src/page/format-command.js +25 -1
  269. package/src/page/format-gate.js +68 -18
  270. package/src/page/format-host.js +17 -0
  271. package/src/page/format-native-commands.js +21 -5
  272. package/src/page/image-actions.js +64 -0
  273. package/src/page/import-markdown.js +262 -0
  274. package/src/page/items.js +135 -17
  275. package/src/page/markdown.js +6 -2
  276. package/src/page/media.js +35 -119
  277. package/src/page/placeholder.js +14 -1
  278. package/src/page/projection.js +98 -10
  279. package/src/page/recover.js +10 -12
  280. package/src/page/recovery-ui.js +464 -0
  281. package/src/page/rich/chart.js +63 -7
  282. package/src/page/save-projection.js +28 -0
  283. package/src/page/save-states.js +13 -3
  284. package/src/page/schema.js +19 -3
  285. package/src/page/table-paste.js +3 -1
  286. package/src/page/table-style.js +4 -4
  287. package/src/page/table.js +44 -2
  288. package/src/page/themes/light-1.css +8 -7
  289. package/src/page/themes/light-1.source.css +8 -7
  290. package/src/page/toc-link.js +31 -0
  291. package/src/page/toc.js +5 -0
  292. package/src/page/view-hooks.js +38 -12
  293. package/src/page/view.js +13 -0
  294. package/src/page/ybind/binding.js +88 -5
  295. package/src/page/ybind/bridge.js +187 -20
  296. package/src/page/ybind/containment.js +162 -0
  297. package/src/page/ybind/doc.js +17 -9
  298. package/src/page/ybind/file-debt.js +63 -0
  299. package/src/page/ybind/layout.js +7 -2
  300. package/src/page/ybind/marks.js +1 -1
  301. package/src/page/ybind/moves.js +5 -4
  302. package/src/page/ybind/origins.js +106 -4
  303. package/src/page/ybind/parts.js +8 -1
  304. package/src/page/ybind/provider.js +113 -17
  305. package/src/page/ybind/recovery-proof.js +32 -9
  306. package/src/page/ybind/recovery-replay.js +558 -15
  307. package/src/page/ybind/recovery.js +174 -45
  308. package/src/page/ybind/table.js +67 -11
  309. package/src/page/ybind/walk-delta.js +258 -0
  310. package/src/page/ybind/walk.js +54 -29
  311. package/src/page/ybind/writer.js +1 -1
  312. package/src/plugins/ai-edit.js +13 -9
  313. package/src/plugins/indicator-chip.js +91 -0
  314. package/src/plugins/indicator.js +13 -80
  315. package/src/plugins/live.js +89 -14
  316. package/src/plugins/menu/actions.js +196 -0
  317. package/src/plugins/menu/people.js +279 -0
  318. package/src/plugins/menu/placement.js +121 -0
  319. package/src/plugins/menu/preferences.js +9 -0
  320. package/src/plugins/menu/seo.js +316 -397
  321. package/src/plugins/menu/style.js +171 -0
  322. package/src/plugins/menu/variants.js +296 -0
  323. package/src/plugins/menu.js +186 -183
  324. package/src/plugins/page-view.js +3 -2
  325. package/src/plugins/page.js +249 -44
  326. package/src/plugins/sortable.js +8 -1
  327. package/src/plugins/source.js +6 -0
  328. package/src/plugins/upgrade.js +51 -17
  329. package/src/plugins/upload-ui.js +12 -17
  330. package/src/plugins/visitor-drafts/bottom-ui.js +12 -4
  331. package/src/plugins/visitor-drafts/intro-style.js +7 -2
  332. package/src/plugins/visitor-drafts/intro.js +5 -3
  333. package/src/plugins/visitor-drafts/owner-chip.js +8 -12
  334. package/src/plugins/visitor-drafts/prompt.js +11 -9
  335. package/src/plugins/visitor-drafts/source.js +4 -3
  336. package/src/plugins/visitor-drafts/store.js +138 -9
  337. package/src/plugins/visitor-drafts/ui-memory.js +2 -2
  338. package/src/plugins/visitor-drafts-owner.js +4 -6
  339. package/src/plugins/visitor-drafts.js +5 -3
  340. package/src/recovery/store.js +1 -1
  341. package/src/route/route.js +4 -0
  342. package/src/server/rooms/index.js +5 -1
  343. package/src/server/rooms/live-data-rooms.js +302 -50
  344. package/src/server/rooms/page-compaction-worker.js +12 -0
  345. package/src/server/rooms/page-compactor.js +92 -0
  346. package/src/server/rooms/page-room-conformance.js +461 -0
  347. package/src/source/parse-steps.js +94 -0
  348. package/src/source/session.js +233 -57
  349. package/src/sync/editing-sender.js +12 -0
  350. package/src/sync/live-sync-edit.js +22 -2
  351. package/src/sync/live-sync.js +150 -23
  352. package/src/sync/page-relay.js +52 -0
  353. package/src/sync/presence-store.js +44 -4
  354. package/src/sync/presence.js +6 -3
  355. package/src/sync/saved-stream.js +11 -6
  356. package/src/ui/bevel-controls.js +1 -0
  357. package/src/ui/bevel-dialog.js +5 -2
  358. package/src/ui/editor-ui.js +77 -0
  359. package/src/ui/page-colour.js +281 -0
  360. package/src/ui/toast.js +16 -7
  361. package/src/vendor/hyper-html-api-upgrade.vendor.js +2 -2
  362. package/src/vendor/hyper-undo.vendor.js +1 -1
  363. package/src/vendor/hypercms.vendor.js +9 -9
  364. package/src/vendor/parse5.vendor.js +2 -2
  365. package/src/vendor/sap-core.vendor.js +5 -5
  366. package/dist/m/c-2SPVQSHC.js +0 -1
  367. package/dist/m/c-336SGU5W.js +0 -1
  368. package/dist/m/c-3H6BZDNJ.js +0 -6
  369. package/dist/m/c-4DFEJ2PO.js +0 -3
  370. package/dist/m/c-56QRZTZH.js +0 -1
  371. package/dist/m/c-5J4E7O4Y.js +0 -4
  372. package/dist/m/c-5LKDWQTL.js +0 -19
  373. package/dist/m/c-5V3MOVJT.js +0 -1
  374. package/dist/m/c-6AZOGAPE.js +0 -1
  375. package/dist/m/c-6CRUUXOX.js +0 -5
  376. package/dist/m/c-6HMB24EV.js +0 -1
  377. package/dist/m/c-6KEVEQ7L.js +0 -1
  378. package/dist/m/c-A3E3NIMC.js +0 -1
  379. package/dist/m/c-BQ6LOBEE.js +0 -1
  380. package/dist/m/c-BTDI4Y23.js +0 -1
  381. package/dist/m/c-CJ3A7ZKE.js +0 -1
  382. package/dist/m/c-CQHPGKX2.js +0 -1
  383. package/dist/m/c-DFS4XZJV.js +0 -2
  384. package/dist/m/c-DNENWY4O.js +0 -1
  385. package/dist/m/c-E4LIR5X5.js +0 -1
  386. package/dist/m/c-FDNHHZY5.js +0 -1
  387. package/dist/m/c-FROJUZMV.js +0 -1
  388. package/dist/m/c-G2JPKCTP.js +0 -1
  389. package/dist/m/c-GB6TU7WV.js +0 -1
  390. package/dist/m/c-GFJJEBTU.js +0 -1
  391. package/dist/m/c-GJAEGGXY.js +0 -1
  392. package/dist/m/c-GOWBDM6J.js +0 -1
  393. package/dist/m/c-HFKUVACH.js +0 -1
  394. package/dist/m/c-HHDFCNHV.js +0 -1
  395. package/dist/m/c-IEM4NTCS.js +0 -1
  396. package/dist/m/c-JDCX26UP.js +0 -25
  397. package/dist/m/c-KGVGROZT.js +0 -1
  398. package/dist/m/c-KQ6TYJAP.js +0 -135
  399. package/dist/m/c-LFPHCXY3.js +0 -1
  400. package/dist/m/c-LRPUO2MX.js +0 -1
  401. package/dist/m/c-LWLBHLVC.js +0 -3
  402. package/dist/m/c-M2L47S2X.js +0 -7
  403. package/dist/m/c-MFP2ZWD4.js +0 -1
  404. package/dist/m/c-MKSQ4Y57.js +0 -1
  405. package/dist/m/c-NUFFJVVJ.js +0 -1
  406. package/dist/m/c-NUHSPT5P.js +0 -1
  407. package/dist/m/c-O72HVYSA.js +0 -1
  408. package/dist/m/c-OIBUTDXI.js +0 -1
  409. package/dist/m/c-OW5QIGG3.js +0 -1
  410. package/dist/m/c-PGRCK73F.js +0 -1
  411. package/dist/m/c-Q7NQD65V.js +0 -1
  412. package/dist/m/c-QH63LQOS.js +0 -1
  413. package/dist/m/c-R7IWVINQ.js +0 -1
  414. package/dist/m/c-RM7J7BV2.js +0 -1
  415. package/dist/m/c-S4ZEH46B.js +0 -9
  416. package/dist/m/c-SDAXDM2D.js +0 -1
  417. package/dist/m/c-SMGU7RT3.js +0 -235
  418. package/dist/m/c-SPIORRYS.js +0 -1
  419. package/dist/m/c-SWLRT66R.js +0 -1
  420. package/dist/m/c-TCJTVAFN.js +0 -1
  421. package/dist/m/c-TQEMVJCS.js +0 -1
  422. package/dist/m/c-TYLXX4NF.js +0 -21
  423. package/dist/m/c-U62OB4BT.js +0 -1
  424. package/dist/m/c-U6YWUAR3.js +0 -8
  425. package/dist/m/c-UDCSU5G5.js +0 -2
  426. package/dist/m/c-VI5RMSVY.js +0 -1
  427. package/dist/m/c-VRZN56XY.js +0 -1
  428. package/dist/m/c-W5MCHEGA.js +0 -1
  429. package/dist/m/c-WNYBLIOZ.js +0 -1
  430. package/dist/m/c-WWXIDH4O.js +0 -28
  431. package/dist/m/c-XCNTK76U.js +0 -1
  432. package/dist/m/c-XMS6DPBR.js +0 -1
  433. package/dist/m/c-ZUCOKOHT.js +0 -1
  434. package/dist/m/c-ZVPVXTJF.js +0 -4
  435. package/dist/m/c-ZVRKXKM7.js +0 -1
  436. package/dist/m/core/autosave-HRYGUWV6.js +0 -1
  437. package/dist/m/core/conflict-notice-6MROJN2L.js +0 -1
  438. package/dist/m/core/is-edit-mode-KTWA3O5N.js +0 -1
  439. package/dist/m/core/recovery-FLTCC2OC.js +0 -1
  440. package/dist/m/core/save-HQZ4S667.js +0 -1
  441. package/dist/m/core/save-core-KGQWFUNH.js +0 -1
  442. package/dist/m/core/snapshot-EGQZNT45.js +0 -1
  443. package/dist/m/core/unsaved-warning-IDJLD66H.js +0 -1
  444. package/dist/m/loader-S4I7GKXR.js +0 -1
  445. package/dist/m/manifest-4C419D67.js +0 -1
  446. package/dist/m/manifest-edit-B077F288.js +0 -1
  447. package/dist/m/plugins/ai-edit-QN4PMMNL.js +0 -6
  448. package/dist/m/plugins/indicator-URDBBOQO.js +0 -1
  449. package/dist/m/plugins/live-HFWD4OIH.js +0 -1
  450. package/dist/m/plugins/menu-3HIEQSI6.js +0 -138
  451. package/dist/m/plugins/page-JOKB6XPR.js +0 -2
  452. package/dist/m/plugins/page-view-NXOJHNW6.js +0 -1
  453. package/dist/m/plugins/quickcrop-QNY3PKLD.js +0 -26
  454. package/dist/m/plugins/sortable-GWT4PWDV.js +0 -1
  455. package/dist/m/plugins/source-4ZRSAIYM.js +0 -1
  456. package/dist/m/plugins/undo-VDA5P7FH.js +0 -1
  457. package/dist/m/plugins/upgrade-W7FG5VFG.js +0 -1
  458. package/dist/m/plugins/visitor-drafts-LIDY7NH6.js +0 -21
  459. package/dist/m/plugins/visitor-drafts-owner-ZXCKBZE7.js +0 -1
  460. package/dist/m/reader-core-DXYCURFF.js +0 -68
  461. package/dist/m/route/route-KOCZSEGN.js +0 -1
  462. package/dist/m/sync/live-sync-J7VMYTKS.js +0 -1
  463. package/dist/m/ui/index-3JLVI27O.js +0 -1
  464. package/dist/m/vendor/sap-core.vendor-A7BMUYZT.js +0 -6
  465. /package/dist/m/{c-FILLTJA7.js → c-QTTJYJMA.js} +0 -0
  466. /package/dist/m/plugins/{quickcrop-QNY3PKLD.js.LEGAL.txt → quickcrop-BQ5YYFCH.js.LEGAL.txt} +0 -0
  467. /package/dist/m/plugins/{richclay-NRQDSWX6.js.LEGAL.txt → richclay-KLGETK77.js.LEGAL.txt} +0 -0
@@ -0,0 +1,774 @@
1
+ export const ease = {
2
+ standard: [0.33, 0, 0.67, 1],
3
+ out: [0.17, 0.17, 0.4, 1],
4
+ snap: [0.87, 0, 0.38, 1],
5
+ in: [0.69, 0, 0.83, 0.83],
6
+ pop: [0.27, 0, 0.73, 1],
7
+ settle: [0.17, 0, 0.83, 1],
8
+ linear: [0, 0, 1, 1],
9
+ }
10
+
11
+ const defaults = {
12
+ rise: { distance: 14, duration: 270, stagger: 125, fade: 0.2, fadeDuration: 210, ease: 'standard' },
13
+ cascade: { dx: 27, dy: 43, duration: 460, stagger: 167, fade: 0.7, fadeDuration: 290, ease: 'out' },
14
+ pop: { from: 0.9, duration: 210, ease: 'pop', overshoot: false, peak: 1.07, up: 275, down: 210, fade: 0, fadeDuration: 100 },
15
+ exit: { distance: 57, duration: 330, opacity: 0, ease: 'standard' },
16
+ slideOff: { dx: 150, dy: 0, duration: 460, stagger: 0, ease: 'in' },
17
+ hover: { scale: 1.03, lift: 4, rotate: 1, duration: 250, hold: 0, back: 290, ease: 'standard' },
18
+ press: { scale: 1.08, up: 125, down: 125 },
19
+ click: { settle: 160, cursorScale: 1.18, up: 125, down: 167, targetScale: 1.08, press: true },
20
+ move: { ease: 'standard', arc: 0.12, offset: [0.5, 0.5] },
21
+ ripple: { from: [0.94, 0.68], duration: 500, fade: 0.3, fadeAt: 290, fadeDuration: 210, ease: 'out' },
22
+ flip: { deg: 180, duration: 125, ease: 'standard' },
23
+ grow: { from: 0, duration: 600, ease: 'out', axis: 'x', stagger: 0 },
24
+ zoom: { scale: 1.28, focus: [0.5, 0.5], duration: 700, ease: 'snap' },
25
+ zoomOut: { duration: 420, ease: 'settle' },
26
+ reset: { duration: 420, ease: 'standard' },
27
+ }
28
+
29
+ const IDENTITY = { translate: [0, 0], scale: [1, 1], rotate: [0], opacity: [1] }
30
+ const round = n => Math.round(n * 1000) / 1000
31
+ const FORMAT = {
32
+ translate: v => `${round(v[0])}px ${round(v[1])}px`,
33
+ scale: v => `${round(v[0])} ${round(v[1])}`,
34
+ rotate: v => `${round(v[0])}deg`,
35
+ opacity: v => `${round(v[0])}`,
36
+ }
37
+ const CURSOR_SVG = '<svg viewBox="136 60 330 400" width="20" height="24" aria-hidden="true"><path d="M142 118C142 84 180 58 214 84L440 268C472 294 455 338 418 338L335 338C310 338 290 348 274 368L226 432C202 462 158 448 156 412Z" fill="currentColor"/></svg>'
38
+
39
+ function toBezier(e) {
40
+ const a = typeof e === 'string' ? ease[e] : e
41
+ if (!Array.isArray(a) || a.length !== 4) throw new Error(`uimotion: unknown ease "${e}"`)
42
+ return a
43
+ }
44
+
45
+ function cssEase(a) {
46
+ return a[0] === 0 && a[1] === 0 && a[2] === 1 && a[3] === 1 ? 'linear' : `cubic-bezier(${a.join(', ')})`
47
+ }
48
+
49
+ function bezierAt([x1, y1, x2, y2], x) {
50
+ if (x <= 0) return 0
51
+ if (x >= 1) return 1
52
+ const curve = (a, b, t) => 3 * a * t * (1 - t) ** 2 + 3 * b * t * t * (1 - t) + t ** 3
53
+ let lo = 0
54
+ let hi = 1
55
+ let t = x
56
+ for (let i = 0; i < 40; i++) {
57
+ const v = curve(x1, x2, t)
58
+ if (Math.abs(v - x) < 1e-6) break
59
+ if (v < x) lo = t
60
+ else hi = t
61
+ t = (lo + hi) / 2
62
+ }
63
+ return curve(y1, y2, t)
64
+ }
65
+
66
+ function vec(prop, v) {
67
+ if (Array.isArray(v)) return v
68
+ if (prop === 'scale') return [v, v]
69
+ if (prop === 'translate') throw new Error('uimotion: translate takes [x, y]')
70
+ return [v]
71
+ }
72
+
73
+ const same = (a, b) => a.every((n, i) => Math.abs(n - b[i]) < 1e-9)
74
+ const lerp = (a, b, u) => a.map((n, i) => n + (b[i] - n) * u)
75
+ const quad = (a, c, b, u) => a.map((n, i) => (1 - u) ** 2 * n + 2 * u * (1 - u) * c[i] + u * u * b[i])
76
+ const SAMPLES = 24
77
+ const EPSILON = 1e-6
78
+
79
+ function initialValue(keys) {
80
+ if (keys[0].t > 0) return keys[0].v
81
+ let i = 0
82
+ while (i < keys.length - 1 && keys[i + 1].t === keys[0].t) i++
83
+ return keys[i].v
84
+ }
85
+
86
+ function resolve(tweens, resets = []) {
87
+ if (!tweens.length) return []
88
+ const firstStart = Math.min(...tweens.map(t => t.start))
89
+ const list = [
90
+ ...tweens,
91
+ ...resets.filter(r => r.start >= firstStart).map(r => ({ ...r, toInitial: true })),
92
+ ].sort((a, b) => a.start - b.start)
93
+ const keys = []
94
+ let cur = IDENTITY[tweens[0].prop]
95
+ let lastEnd = -Infinity
96
+ let lastTween = null
97
+ for (const tw of list) {
98
+ if (tw.start < lastEnd - EPSILON) {
99
+ throw new Error(`uimotion: two ${tweens[0].prop} tweens overlap on the same element at ${Math.round(tw.start)} ms (the earlier one ends at ${Math.round(lastEnd)} ms, from ${lastTween.source ?? 'a step'})`)
100
+ }
101
+ const start = Math.max(tw.start, lastEnd)
102
+ const from = tw.from ?? cur
103
+ const to = tw.toInitial ? initialValue(keys) : tw.to ?? from
104
+ const last = keys[keys.length - 1]
105
+ if (keys.length && !same(from, cur)) keys.push({ t: start, v: cur, ease: ease.linear })
106
+ if (!(last && last.t === start && same(last.v, from))) keys.push({ t: start, v: from, ease: ease.linear })
107
+ const head = keys[keys.length - 1]
108
+ if (tw.path) {
109
+ for (let i = 1; i <= SAMPLES; i++) {
110
+ const u = i / SAMPLES
111
+ keys.push({ t: start + tw.dur * u, v: tw.path(bezierAt(tw.ease, u)), ease: ease.linear })
112
+ }
113
+ } else {
114
+ head.ease = tw.ease
115
+ keys.push({ t: start + tw.dur, v: to, ease: ease.linear })
116
+ }
117
+ cur = keys[keys.length - 1].v
118
+ lastEnd = start + tw.dur
119
+ lastTween = tw
120
+ }
121
+ return keys
122
+ }
123
+
124
+ function valueAt(keys, t, prop) {
125
+ if (!keys.length) return IDENTITY[prop]
126
+ if (t < keys[0].t) return keys[0].v
127
+ let i = 0
128
+ while (i < keys.length - 1 && keys[i + 1].t <= t) i++
129
+ const a = keys[i]
130
+ const b = keys[i + 1]
131
+ if (!b) return a.v
132
+ return lerp(a.v, b.v, bezierAt(a.ease, (t - a.t) / (b.t - a.t)))
133
+ }
134
+
135
+ function keyframes(keys, prop, total) {
136
+ const frames = keys.map(k => ({
137
+ offset: Math.min(1, Math.max(0, k.t / total)),
138
+ [prop]: FORMAT[prop](k.v),
139
+ easing: cssEase(k.ease),
140
+ }))
141
+ if (frames[0].offset > 0) frames.unshift({ ...frames[0], offset: 0, easing: 'linear' })
142
+ if (frames[frames.length - 1].offset < 1) frames.push({ ...frames[frames.length - 1], offset: 1, easing: 'linear' })
143
+ return frames
144
+ }
145
+
146
+ export function scene(stage, options) {
147
+ return new Scene(stage, options)
148
+ }
149
+
150
+ class Scene {
151
+ constructor(stage, { loop = true, cursor, still } = {}) {
152
+ this.stage = typeof stage === 'string' ? document.querySelector(stage) : stage
153
+ if (!this.stage) throw new Error(`uimotion: no stage "${stage}"`)
154
+ this.loop = loop
155
+ this.cursorStart = cursor
156
+ this.stillAt = still
157
+ this.tweens = []
158
+ this.resets = []
159
+ this.t = 0
160
+ this.last = { start: 0, end: 0 }
161
+ this.mode = null
162
+ this.rects = new Map()
163
+ this.animations = null
164
+ this.playing = false
165
+ this.rate = 1
166
+ const view = this.stage.ownerDocument?.defaultView
167
+ if (view && view.getComputedStyle(this.stage).position === 'static') this.stage.style.position = 'relative'
168
+ }
169
+
170
+ get duration() {
171
+ return Math.max(this.t, 1)
172
+ }
173
+
174
+ els(target) {
175
+ if (typeof target === 'string') {
176
+ const list = [...this.stage.querySelectorAll(target)]
177
+ if (!list.length) throw new Error(`uimotion: nothing matches "${target}"`)
178
+ return list
179
+ }
180
+ if (Array.isArray(target)) return target
181
+ if (target && typeof target.length === 'number' && !target.nodeType) return [...target]
182
+ return [target]
183
+ }
184
+
185
+ el(target) {
186
+ return this.els(target)[0]
187
+ }
188
+
189
+ nextStart() {
190
+ if (this.mode?.with != null) return this.last.start + this.mode.with
191
+ return this.mode?.at ?? this.t
192
+ }
193
+
194
+ step(name, build) {
195
+ const resume = this.animations ? { time: this.time, playing: this.playing } : null
196
+ this.animations?.forEach(a => a.cancel())
197
+ this.animations = null
198
+ const start = this.nextStart()
199
+ this.mode = null
200
+ this.source = `${name} at ${Math.round(start)} ms`
201
+ const before = this.tweens.length
202
+ let end = start + build(start)
203
+ for (const tw of this.tweens.slice(before)) end = Math.max(end, tw.start + tw.dur)
204
+ this.last = { start, end }
205
+ this.t = Math.max(this.t, end)
206
+ if (resume) {
207
+ this.seek(resume.time)
208
+ if (resume.playing) this.play()
209
+ }
210
+ return this
211
+ }
212
+
213
+ add(el, prop, start, dur, to, { from, ease: e = 'standard', path } = {}) {
214
+ this.tweens.push({
215
+ el,
216
+ prop,
217
+ start,
218
+ dur,
219
+ from: from == null ? undefined : vec(prop, from),
220
+ to: to == null ? undefined : vec(prop, to),
221
+ ease: toBezier(e),
222
+ path,
223
+ source: this.source,
224
+ })
225
+ }
226
+
227
+ current(el, prop, t) {
228
+ const keys = resolve(this.tweens.filter(tw => tw.el === el && tw.prop === prop), this.resets)
229
+ return valueAt(keys, t, prop)
230
+ }
231
+
232
+ rect(el) {
233
+ if (!this.rects.has(el)) {
234
+ const s = this.stage.getBoundingClientRect()
235
+ const r = el.getBoundingClientRect()
236
+ const k = this.stageScale()
237
+ const x = (r.left - s.left) / k - (this.stage.clientLeft || 0)
238
+ const y = (r.top - s.top) / k - (this.stage.clientTop || 0)
239
+ const w = r.width / k
240
+ const h = r.height / k
241
+ const origin = this.stage.ownerDocument?.defaultView?.getComputedStyle(el).transformOrigin
242
+ const [ox, oy] = (origin ?? '').split(' ').map(parseFloat)
243
+ this.rects.set(el, {
244
+ x, y, w, h,
245
+ origin: [x + (Number.isFinite(ox) ? ox : w / 2), y + (Number.isFinite(oy) ? oy : h / 2)],
246
+ })
247
+ }
248
+ return this.rects.get(el)
249
+ }
250
+
251
+ stageScale() {
252
+ const w = this.stage.getBoundingClientRect().width
253
+ return this.stage.offsetWidth ? w / this.stage.offsetWidth : 1
254
+ }
255
+
256
+ stageSize() {
257
+ const r = this.stage.getBoundingClientRect()
258
+ const k = this.stageScale()
259
+ return [r.width / k, r.height / k]
260
+ }
261
+
262
+ chain(el, until = this.stage) {
263
+ const nodes = []
264
+ for (let n = el; n && n !== until && n !== this.stage; n = n.parentElement) {
265
+ if (this.tweens.some(tw => tw.el === n)) nodes.push(n)
266
+ }
267
+ return nodes
268
+ }
269
+
270
+ transformAt(n, t) {
271
+ return {
272
+ o: this.rect(n).origin,
273
+ s: this.current(n, 'scale', t),
274
+ r: this.current(n, 'rotate', t)[0] * Math.PI / 180,
275
+ d: this.current(n, 'translate', t),
276
+ }
277
+ }
278
+
279
+ transformPoint(n, p, t) {
280
+ const { o, s, r, d } = this.transformAt(n, t)
281
+ const x = (p[0] - o[0]) * s[0]
282
+ const y = (p[1] - o[1]) * s[1]
283
+ return [o[0] + x * Math.cos(r) - y * Math.sin(r) + d[0], o[1] + x * Math.sin(r) + y * Math.cos(r) + d[1]]
284
+ }
285
+
286
+ untransformPoint(n, p, t) {
287
+ const { o, s, r, d } = this.transformAt(n, t)
288
+ const x = p[0] - o[0] - d[0]
289
+ const y = p[1] - o[1] - d[1]
290
+ return [o[0] + (x * Math.cos(r) + y * Math.sin(r)) / s[0], o[1] + (-x * Math.sin(r) + y * Math.cos(r)) / s[1]]
291
+ }
292
+
293
+ pointAt(el, t, [fx, fy] = [0.5, 0.5], until = this.stage) {
294
+ const r = this.rect(el)
295
+ let p = [r.x + r.w * fx, r.y + r.h * fy]
296
+ for (const n of this.chain(el, until)) p = this.transformPoint(n, p, t)
297
+ return p
298
+ }
299
+
300
+ cursorEl() {
301
+ if (this.cursor) return this.cursor
302
+ const doc = this.stage.ownerDocument
303
+ const el = doc.createElement('div')
304
+ el.className = 'uimotion-cursor'
305
+ el.setAttribute('aria-hidden', 'true')
306
+ el.setAttribute('clay', 'editor-ui')
307
+ el.innerHTML = CURSOR_SVG
308
+ Object.assign(el.style, {
309
+ position: 'absolute', left: '-1px', top: '-2px', width: '20px', height: '24px',
310
+ pointerEvents: 'none', zIndex: '10', transformOrigin: '1px 2px',
311
+ })
312
+ this.stage.append(el)
313
+ this.cursor = el
314
+ const [w, h] = this.stageSize()
315
+ const start = this.cursorStart ?? [w * 0.7, h * 0.85]
316
+ this.tweens.push({ el, prop: 'translate', start: 0, dur: 0, to: start, from: start, ease: ease.linear, source: 'cursor start' })
317
+ return el
318
+ }
319
+
320
+ with(offset = 0) {
321
+ this.mode = { with: offset }
322
+ return this
323
+ }
324
+
325
+ at(ms) {
326
+ this.mode = { at: ms }
327
+ return this
328
+ }
329
+
330
+ wait(ms) {
331
+ return this.step('wait', () => ms)
332
+ }
333
+
334
+ set(target, values) {
335
+ return this.step('set', start => {
336
+ for (const el of this.els(target)) {
337
+ for (const [prop, v] of Object.entries(values)) this.add(el, prop, start, 0, v, { ease: 'linear' })
338
+ }
339
+ return 0
340
+ })
341
+ }
342
+
343
+ tween(target, prop, to, { duration = 300, delay = 0, stagger = 0, ...opts } = {}) {
344
+ return this.step('tween', start => {
345
+ const list = this.els(target)
346
+ list.forEach((el, i) => this.add(el, prop, start + delay + i * stagger, duration, to, opts))
347
+ return delay + (list.length - 1) * stagger + duration
348
+ })
349
+ }
350
+
351
+ rise(target, opts) {
352
+ const o = { ...defaults.rise, ...opts }
353
+ return this.step('rise', start => {
354
+ const list = this.els(target)
355
+ list.forEach((el, i) => {
356
+ const t = start + i * o.stagger
357
+ this.add(el, 'translate', t, o.duration, [0, 0], { from: [0, o.distance], ease: o.ease })
358
+ this.add(el, 'opacity', t, o.fadeDuration, 1, { from: o.fade, ease: 'linear' })
359
+ })
360
+ return (list.length - 1) * o.stagger + o.duration
361
+ })
362
+ }
363
+
364
+ cascade(target, opts) {
365
+ const o = { ...defaults.cascade, ...opts }
366
+ return this.step('cascade', start => {
367
+ const list = this.els(target)
368
+ list.forEach((el, i) => {
369
+ const t = start + i * o.stagger
370
+ this.add(el, 'translate', t, o.duration, [0, 0], { from: [-o.dx, -o.dy], ease: o.ease })
371
+ this.add(el, 'opacity', t, o.fadeDuration, 1, { from: o.fade, ease: 'out' })
372
+ })
373
+ return (list.length - 1) * o.stagger + o.duration
374
+ })
375
+ }
376
+
377
+ pop(target, opts) {
378
+ const o = { ...defaults.pop, ...opts }
379
+ return this.step('pop', start => {
380
+ for (const el of this.els(target)) {
381
+ if (o.fade !== false) this.add(el, 'opacity', start, o.fadeDuration, 1, { from: o.fade, ease: 'linear' })
382
+ if (o.overshoot) {
383
+ this.add(el, 'scale', start, o.up, o.peak, { from: o.from, ease: 'linear' })
384
+ this.add(el, 'scale', start + o.up, o.down, 1, { ease: 'linear' })
385
+ } else {
386
+ this.add(el, 'scale', start, o.duration, 1, { from: o.from, ease: o.ease })
387
+ }
388
+ }
389
+ return o.overshoot ? o.up + o.down : o.duration
390
+ })
391
+ }
392
+
393
+ exit(target, opts) {
394
+ const o = { ...defaults.exit, ...opts }
395
+ return this.step('exit', start => {
396
+ for (const el of this.els(target)) {
397
+ const d = this.current(el, 'translate', start)
398
+ this.add(el, 'translate', start, o.duration, [d[0], d[1] - o.distance], { ease: o.ease })
399
+ this.add(el, 'opacity', start, o.duration, o.opacity, { ease: 'linear' })
400
+ }
401
+ return o.duration
402
+ })
403
+ }
404
+
405
+ slideOff(target, opts) {
406
+ const o = { ...defaults.slideOff, ...opts }
407
+ return this.step('slideOff', start => {
408
+ const list = this.els(target)
409
+ list.forEach((el, i) => {
410
+ const t = start + i * o.stagger
411
+ const d = this.current(el, 'translate', t)
412
+ this.add(el, 'translate', t, o.duration, [d[0] + o.dx, d[1] + o.dy], { ease: o.ease })
413
+ this.add(el, 'opacity', t, o.duration, 0, { ease: 'linear' })
414
+ })
415
+ return (list.length - 1) * o.stagger + o.duration
416
+ })
417
+ }
418
+
419
+ hover(target, opts) {
420
+ const o = { ...defaults.hover, ...opts }
421
+ return this.step('hover', start => {
422
+ for (const el of this.els(target)) {
423
+ const d = this.current(el, 'translate', start)
424
+ const s = this.current(el, 'scale', start)
425
+ const r = this.current(el, 'rotate', start)
426
+ const back = start + o.duration + o.hold
427
+ this.add(el, 'translate', start, o.duration, [d[0], d[1] - o.lift], { ease: o.ease })
428
+ this.add(el, 'scale', start, o.duration, [s[0] * o.scale, s[1] * o.scale], { ease: o.ease })
429
+ this.add(el, 'rotate', start, o.duration, [r[0] + o.rotate], { ease: o.ease })
430
+ this.add(el, 'translate', back, o.back, d, { ease: o.ease })
431
+ this.add(el, 'scale', back, o.back, s, { ease: o.ease })
432
+ this.add(el, 'rotate', back, o.back, r, { ease: o.ease })
433
+ }
434
+ return o.duration + o.hold + o.back
435
+ })
436
+ }
437
+
438
+ pulse(el, t, factor, up, down) {
439
+ const s = this.current(el, 'scale', t)
440
+ this.add(el, 'scale', t, up, [s[0] * factor, s[1] * factor], { ease: 'linear' })
441
+ this.add(el, 'scale', t + up, down, s, { ease: 'linear' })
442
+ }
443
+
444
+ press(target, opts) {
445
+ const o = { ...defaults.press, ...opts }
446
+ return this.step('press', start => {
447
+ for (const el of this.els(target)) this.pulse(el, start, o.scale, o.up, o.down)
448
+ return o.up + o.down
449
+ })
450
+ }
451
+
452
+ move(target, opts) {
453
+ const o = { ...defaults.move, ...opts }
454
+ return this.step('move', start => {
455
+ const c = this.cursorEl()
456
+ const a = this.current(c, 'translate', start)
457
+ const el = Array.isArray(target) ? null : this.el(target)
458
+ const aim = t => el ? this.pointAt(el, t, o.offset) : target
459
+ const timeFor = d => o.duration ?? (d < 120 ? 290 : Math.min(1000, 400 + d * 1.2))
460
+ let b = aim(start)
461
+ let dur = 0
462
+ for (let i = 0; i < 3; i++) {
463
+ dur = timeFor(Math.hypot(b[0] - a[0], b[1] - a[1]))
464
+ b = aim(start + dur)
465
+ }
466
+ const dist = Math.hypot(b[0] - a[0], b[1] - a[1])
467
+ if (dist < 1) return 0
468
+ const bow = dist < 120 ? 0 : o.arc * dist
469
+ let n = [-(b[1] - a[1]) / dist, (b[0] - a[0]) / dist]
470
+ if (n[1] < 0) n = [-n[0], -n[1]]
471
+ const ctrl = [(a[0] + b[0]) / 2 + n[0] * bow, (a[1] + b[1]) / 2 + n[1] * bow]
472
+ this.add(c, 'translate', start, dur, b, { ease: o.ease, path: u => quad(a, ctrl, b, u) })
473
+ return dur
474
+ })
475
+ }
476
+
477
+ click(target, opts = {}) {
478
+ const o = { ...defaults.click, ...opts }
479
+ if (target != null) {
480
+ const at = this.nextStart()
481
+ const p = Array.isArray(target) ? target : this.pointAt(this.el(target), at, o.offset)
482
+ const c = this.current(this.cursorEl(), 'translate', at)
483
+ if (Math.hypot(p[0] - c[0], p[1] - c[1]) > 2) {
484
+ this.move(target, { offset: o.offset, ...o.move })
485
+ this.mode = { at: this.last.end }
486
+ }
487
+ }
488
+ return this.step('click', start => {
489
+ const t = start + o.settle
490
+ this.pulse(this.cursorEl(), t, o.cursorScale, o.up, o.down)
491
+ if (target != null && !Array.isArray(target) && o.press) this.pulse(this.el(target), t, o.targetScale, o.up, o.up)
492
+ return o.settle + o.up + o.down
493
+ })
494
+ }
495
+
496
+ ripple(target, opts) {
497
+ const o = { ...defaults.ripple, ...opts }
498
+ return this.step('ripple', start => {
499
+ for (const el of this.els(target)) {
500
+ this.add(el, 'scale', start, o.duration, 1, { from: o.from, ease: o.ease })
501
+ this.add(el, 'opacity', start, 0, o.fade, { from: 0, ease: 'linear' })
502
+ this.add(el, 'opacity', start + o.fadeAt, o.fadeDuration, 0, { ease: 'linear' })
503
+ }
504
+ return Math.max(o.duration, o.fadeAt + o.fadeDuration)
505
+ })
506
+ }
507
+
508
+ flip(target, opts) {
509
+ const o = { ...defaults.flip, ...opts }
510
+ return this.step('flip', start => {
511
+ for (const el of this.els(target)) {
512
+ const r = this.current(el, 'rotate', start)
513
+ this.add(el, 'rotate', start, o.duration, [r[0] + o.deg], { ease: o.ease })
514
+ }
515
+ return o.duration
516
+ })
517
+ }
518
+
519
+ grow(target, opts) {
520
+ const o = { ...defaults.grow, ...opts }
521
+ return this.step('grow', start => {
522
+ const list = this.els(target)
523
+ const from = o.axis === 'x' ? [o.from, 1] : [1, o.from]
524
+ list.forEach((el, i) => this.add(el, 'scale', start + i * o.stagger, o.duration, [1, 1], { from, ease: o.ease }))
525
+ return (list.length - 1) * o.stagger + o.duration
526
+ })
527
+ }
528
+
529
+ zoom(target, opts) {
530
+ const o = { ...defaults.zoom, ...opts }
531
+ return this.step('zoom', start => {
532
+ const el = this.el(target)
533
+ const end = start + o.duration
534
+ const s = vec('scale', o.scale)
535
+ let d = [0, 0]
536
+ if (o.to) {
537
+ const p = Array.isArray(o.to) ? o.to : this.pointAt(this.el(o.to), end, [0.5, 0.5], el)
538
+ const st = this.stageSize()
539
+ let f = [st[0] * o.focus[0], st[1] * o.focus[1]]
540
+ for (const n of this.chain(el.parentElement).reverse()) f = this.untransformPoint(n, f, end)
541
+ const c = this.rect(el).origin
542
+ const r = this.current(el, 'rotate', end)[0] * Math.PI / 180
543
+ const x = (p[0] - c[0]) * s[0]
544
+ const y = (p[1] - c[1]) * s[1]
545
+ d = [f[0] - c[0] - (x * Math.cos(r) - y * Math.sin(r)), f[1] - c[1] - (x * Math.sin(r) + y * Math.cos(r))]
546
+ }
547
+ this.add(el, 'scale', start, o.duration, s, { ease: o.ease })
548
+ this.add(el, 'translate', start, o.duration, d, { ease: o.ease })
549
+ return o.duration
550
+ })
551
+ }
552
+
553
+ zoomOut(target, opts) {
554
+ const o = { ...defaults.zoomOut, ...opts }
555
+ return this.step('zoomOut', start => {
556
+ const el = this.el(target)
557
+ this.add(el, 'scale', start, o.duration, 1, { ease: o.ease })
558
+ this.add(el, 'translate', start, o.duration, [0, 0], { ease: o.ease })
559
+ return o.duration
560
+ })
561
+ }
562
+
563
+ reset(opts) {
564
+ const o = { ...defaults.reset, ...opts }
565
+ return this.step('reset', start => {
566
+ if (this.stillAt == null) this.stillAt = start
567
+ this.resets.push({ start, dur: o.duration, ease: toBezier(o.ease), source: `reset at ${Math.round(start)} ms` })
568
+ return o.duration
569
+ })
570
+ }
571
+
572
+ build() {
573
+ if (this.animations) return this.animations
574
+ const total = this.duration
575
+ const groups = new Map()
576
+ for (const tw of this.tweens) {
577
+ const key = groups.get(tw.el) ?? new Map()
578
+ groups.set(tw.el, key)
579
+ if (!key.has(tw.prop)) key.set(tw.prop, [])
580
+ key.get(tw.prop).push(tw)
581
+ }
582
+ const animations = []
583
+ try {
584
+ for (const [el, props] of groups) {
585
+ for (const [prop, list] of props) {
586
+ const keys = resolve(list, this.resets)
587
+ if (this.loop && this.resets.length && !same(keys[keys.length - 1].v, initialValue(keys))) {
588
+ const late = list.reduce((a, b) => (b.start > a.start ? b : a))
589
+ throw new Error(`uimotion: ${prop} on an element still changes after the last reset() (${late.source}), so the loop jumps. Move reset() to the end, or return it to its start value.`)
590
+ }
591
+ const anim = el.animate(keyframes(keys, prop, total), { duration: total, iterations: this.loop ? Infinity : 1, fill: 'both' })
592
+ anim.pause()
593
+ anim.playbackRate = this.rate
594
+ animations.push(anim)
595
+ }
596
+ }
597
+ } catch (error) {
598
+ animations.forEach(a => a.cancel())
599
+ throw error
600
+ }
601
+ this.animations = animations
602
+ if (this.stage.dataset) this.stage.dataset.uimotion = 'ready'
603
+ return animations
604
+ }
605
+
606
+ play() {
607
+ this.build()
608
+ const reduce = this.stage.ownerDocument.defaultView?.matchMedia?.('(prefers-reduced-motion: reduce)').matches
609
+ if (reduce) return this.seek(this.stillAt ?? (this.loop ? this.duration - 0.01 : this.duration))
610
+ this.animations.forEach(a => a.play())
611
+ this.playing = true
612
+ return this
613
+ }
614
+
615
+ pause() {
616
+ this.build().forEach(a => a.pause())
617
+ this.playing = false
618
+ return this
619
+ }
620
+
621
+ seek(ms) {
622
+ this.build().forEach(a => {
623
+ a.pause()
624
+ a.currentTime = ms
625
+ })
626
+ this.playing = false
627
+ return this
628
+ }
629
+
630
+ speed(rate) {
631
+ this.rate = rate
632
+ this.build().forEach(a => { a.playbackRate = rate })
633
+ return this
634
+ }
635
+
636
+ get time() {
637
+ const t = this.build()[0]?.currentTime ?? 0
638
+ return this.loop ? t % this.duration : Math.min(t, this.duration)
639
+ }
640
+
641
+ debug() {
642
+ const doc = this.stage.ownerDocument
643
+ const bar = doc.createElement('div')
644
+ bar.className = 'uimotion-debug'
645
+ bar.setAttribute('clay', 'editor-ui')
646
+ bar.style.cssText = 'display:flex;gap:8px;align-items:center;margin-top:8px;font:12px/1.4 ui-monospace,monospace'
647
+ bar.innerHTML = '<button type="button">Pause</button><input type="range" min="0" step="1" style="flex:1"><select><option>0.25</option><option>0.5</option><option selected>1</option></select><span></span>'
648
+ const [button, range, select, label] = bar.children
649
+ range.max = Math.round(this.duration)
650
+ this.stage.after(bar)
651
+ let playing = true
652
+ const show = t => { label.textContent = `${Math.round(t)} / ${Math.round(this.duration)} ms` }
653
+ button.onclick = () => {
654
+ playing = !playing
655
+ if (playing) this.play()
656
+ else this.pause()
657
+ button.textContent = playing ? 'Pause' : 'Play'
658
+ }
659
+ range.oninput = () => {
660
+ playing = false
661
+ button.textContent = 'Play'
662
+ this.seek(+range.value)
663
+ show(+range.value)
664
+ }
665
+ select.onchange = () => this.speed(+select.value)
666
+ const tick = () => {
667
+ if (playing) {
668
+ range.value = this.time
669
+ show(this.time)
670
+ }
671
+ doc.defaultView.requestAnimationFrame(tick)
672
+ }
673
+ tick()
674
+ return this
675
+ }
676
+ }
677
+
678
+ // A step that returns every animated property to its start value at this point, except
679
+ // opacity on `keep`, which the scene fades itself.
680
+ export function rewind(s, keep = []) {
681
+ return s.step('rewind', start => {
682
+ const groups = new Map()
683
+ for (const tw of s.tweens) {
684
+ if (tw.prop === 'opacity' && keep.includes(tw.el)) continue
685
+ const props = groups.get(tw.el) ?? new Map()
686
+ groups.set(tw.el, props)
687
+ if (!props.has(tw.prop)) props.set(tw.prop, [])
688
+ props.get(tw.prop).push(tw)
689
+ }
690
+ for (const [el, props] of groups) {
691
+ for (const [prop, list] of props) {
692
+ const keys = resolve(list, s.resets)
693
+ const v = initialValue(keys)
694
+ if (!same(valueAt(keys, start, prop), v)) s.add(el, prop, start, 0, v, { ease: 'linear' })
695
+ }
696
+ }
697
+ return 0
698
+ })
699
+ }
700
+
701
+ // Plays a scene in a stage while the stage is in the page: rebuilt when its width changes
702
+ // or the fonts arrive (keeping its place in the loop), paused while the tab is hidden or
703
+ // the stage is off screen, and stopped for good once the stage leaves the page.
704
+ export function mount(stage, build, { watch = stage, teardown, debug = false } = {}) {
705
+ const doc = stage.ownerDocument
706
+ let s = null
707
+ let width = 0
708
+ let onScreen = true
709
+ let queued = false
710
+ let queuedForce = false
711
+ let done = false
712
+ const shown = () => onScreen && doc.visibilityState !== 'hidden'
713
+ const sync = () => { if (s) shown() ? s.play() : s.pause() }
714
+ const clear = () => {
715
+ if (!s) return
716
+ s.animations?.forEach(a => a.cancel())
717
+ s.cursor?.remove()
718
+ if (stage.nextElementSibling?.classList.contains('uimotion-debug')) stage.nextElementSibling.remove()
719
+ teardown?.(stage)
720
+ delete stage.dataset.uimotion
721
+ delete stage.uimotionScene
722
+ s = null
723
+ width = 0
724
+ }
725
+ const stop = () => {
726
+ if (done) return
727
+ done = true
728
+ clear()
729
+ ro.disconnect()
730
+ io?.disconnect()
731
+ doc.removeEventListener('visibilitychange', sync)
732
+ }
733
+ const start = force => {
734
+ if (done) return
735
+ if (!stage.isConnected) return stop()
736
+ const w = stage.offsetWidth
737
+ if (!force && w === width) return
738
+ const time = s ? s.time : 0
739
+ clear()
740
+ if (!w) return
741
+ try {
742
+ s = build(stage)
743
+ width = w
744
+ stage.uimotionScene = s
745
+ s.seek(time)
746
+ sync()
747
+ if (debug) s.debug()
748
+ } catch (error) {
749
+ console.error(error)
750
+ clear()
751
+ }
752
+ }
753
+ const queue = force => {
754
+ queuedForce = queuedForce || force
755
+ if (queued) return
756
+ queued = true
757
+ requestAnimationFrame(() => {
758
+ queued = false
759
+ const f = queuedForce
760
+ queuedForce = false
761
+ start(f)
762
+ })
763
+ }
764
+ const ro = new ResizeObserver(() => (stage.isConnected ? queue(false) : stop()))
765
+ ro.observe(watch)
766
+ const io = typeof IntersectionObserver === 'function'
767
+ ? new IntersectionObserver(entries => { onScreen = entries[entries.length - 1].isIntersecting; sync() })
768
+ : null
769
+ io?.observe(stage)
770
+ doc.addEventListener('visibilitychange', sync)
771
+ if (doc.fonts && doc.fonts.status !== 'loaded') doc.fonts.ready.then(() => queue(true))
772
+ start(false)
773
+ return { stop, get scene() { return s } }
774
+ }