framefields 2.0.11 → 2.1.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 (559) hide show
  1. package/README.md +22 -5
  2. package/dist/audio/index.d.mts +4 -4
  3. package/dist/audio/index.mjs +13 -12
  4. package/dist/{audio-BHanw8Jb.d.mts → audio-C2fLC3Tx.d.mts} +3 -3
  5. package/dist/{audio-BHanw8Jb.d.mts.map → audio-C2fLC3Tx.d.mts.map} +1 -1
  6. package/dist/{audio-TAvPwzLR.mjs → audio-DJeVoE8b.mjs} +1 -1
  7. package/dist/{audio-TAvPwzLR.mjs.map → audio-DJeVoE8b.mjs.map} +1 -1
  8. package/dist/{audio-COOMNwL5.mjs → audio-D_4SeMRK.mjs} +4 -4
  9. package/dist/{audio-COOMNwL5.mjs.map → audio-D_4SeMRK.mjs.map} +1 -1
  10. package/dist/{client-CwRhflHE.mjs → client-dVxUnmHz.mjs} +1 -1
  11. package/dist/{client-CwRhflHE.mjs.map → client-dVxUnmHz.mjs.map} +1 -1
  12. package/dist/{dist-C_hjvkdN.mjs → dist-0QGroRYZ.mjs} +1 -1
  13. package/dist/{dist-C_hjvkdN.mjs.map → dist-0QGroRYZ.mjs.map} +1 -1
  14. package/dist/{dist-BYqNNwsl.mjs → dist-BY0bIWgr.mjs} +10 -2
  15. package/dist/dist-BY0bIWgr.mjs.map +1 -0
  16. package/dist/{dist-Cxi68OuY.mjs → dist-Bun_TUvZ.mjs} +26862 -25638
  17. package/dist/dist-Bun_TUvZ.mjs.map +1 -0
  18. package/dist/{dist-BAVZdFEJ.mjs → dist-DlzqyRar.mjs} +75 -618
  19. package/dist/dist-DlzqyRar.mjs.map +1 -0
  20. package/dist/{dist-cjs-TsA8LFXC.mjs → dist-cjs-91nR6B7Z.mjs} +3 -3
  21. package/dist/{dist-cjs-TsA8LFXC.mjs.map → dist-cjs-91nR6B7Z.mjs.map} +1 -1
  22. package/dist/{dist-cjs-DJ8fcQEe.mjs → dist-cjs-BAIenEMC.mjs} +11 -11
  23. package/dist/{dist-cjs-DJ8fcQEe.mjs.map → dist-cjs-BAIenEMC.mjs.map} +1 -1
  24. package/dist/{dist-cjs-BmyyWYWv.mjs → dist-cjs-BEQhh76X.mjs} +2 -2
  25. package/dist/{dist-cjs-BmyyWYWv.mjs.map → dist-cjs-BEQhh76X.mjs.map} +1 -1
  26. package/dist/{dist-cjs--pxyGFw2.mjs → dist-cjs-BYPq7pfw.mjs} +1 -1
  27. package/dist/{dist-cjs--pxyGFw2.mjs.map → dist-cjs-BYPq7pfw.mjs.map} +1 -1
  28. package/dist/{dist-cjs--lfMLs3U.mjs → dist-cjs-BocDqSCX.mjs} +4 -4
  29. package/dist/{dist-cjs--lfMLs3U.mjs.map → dist-cjs-BocDqSCX.mjs.map} +1 -1
  30. package/dist/{dist-cjs-CsU2sZoX.mjs → dist-cjs-CWiNggTl.mjs} +4 -4
  31. package/dist/{dist-cjs-CsU2sZoX.mjs.map → dist-cjs-CWiNggTl.mjs.map} +1 -1
  32. package/dist/{dist-cjs-DjzmP0-x.mjs → dist-cjs-CwabutT6.mjs} +13 -13
  33. package/dist/{dist-cjs-DjzmP0-x.mjs.map → dist-cjs-CwabutT6.mjs.map} +1 -1
  34. package/dist/{dist-cjs-BDpO-TH_.mjs → dist-cjs-D-EE4Ahy.mjs} +1 -1
  35. package/dist/{dist-cjs-BDpO-TH_.mjs.map → dist-cjs-D-EE4Ahy.mjs.map} +1 -1
  36. package/dist/{dist-cjs-CQwmMllY.mjs → dist-cjs-DNtDUWfk.mjs} +6 -6
  37. package/dist/{dist-cjs-CQwmMllY.mjs.map → dist-cjs-DNtDUWfk.mjs.map} +1 -1
  38. package/dist/{dist-cjs-CND_ghfH.mjs → dist-cjs-DbZhsgS0.mjs} +1 -1
  39. package/dist/{dist-cjs-CND_ghfH.mjs.map → dist-cjs-DbZhsgS0.mjs.map} +1 -1
  40. package/dist/{dist-cjs-CgFzrgj8.mjs → dist-cjs-Dh7REKcN.mjs} +1 -1
  41. package/dist/{dist-cjs-CgFzrgj8.mjs.map → dist-cjs-Dh7REKcN.mjs.map} +1 -1
  42. package/dist/{dist-cjs-DT2jJlcK.mjs → dist-cjs-Dobx0Nz-.mjs} +5 -5
  43. package/dist/{dist-cjs-DT2jJlcK.mjs.map → dist-cjs-Dobx0Nz-.mjs.map} +1 -1
  44. package/dist/{dist-cjs-DzjrlfbE.mjs → dist-cjs-Du0UpNof.mjs} +14 -14
  45. package/dist/{dist-cjs-DzjrlfbE.mjs.map → dist-cjs-Du0UpNof.mjs.map} +1 -1
  46. package/dist/dist-cjs-DyHiUfsr.mjs +6 -0
  47. package/dist/{dist-cjs-M-8QOgS_.mjs → dist-cjs-HHMfMF5a.mjs} +2 -2
  48. package/dist/{dist-cjs-M-8QOgS_.mjs.map → dist-cjs-HHMfMF5a.mjs.map} +1 -1
  49. package/dist/{dist-cjs-BiKQozdJ.mjs → dist-cjs-UJYQzLNT.mjs} +3 -3
  50. package/dist/{dist-cjs-BiKQozdJ.mjs.map → dist-cjs-UJYQzLNT.mjs.map} +1 -1
  51. package/dist/{dist-cjs-agQl9T8M.mjs → dist-cjs-UKxm5cFR.mjs} +6 -6
  52. package/dist/{dist-cjs-agQl9T8M.mjs.map → dist-cjs-UKxm5cFR.mjs.map} +1 -1
  53. package/dist/{dist-CbG3QxDw.mjs → dist-fjKpBYkc.mjs} +12 -27
  54. package/dist/dist-fjKpBYkc.mjs.map +1 -0
  55. package/dist/effects/index.d.mts +4 -4
  56. package/dist/effects/index.mjs +36 -34
  57. package/dist/{effects-DzbjFhyA.mjs → effects-FTlu0dri.mjs} +3 -3
  58. package/dist/{effects-DzbjFhyA.mjs.map → effects-FTlu0dri.mjs.map} +1 -1
  59. package/dist/{event-streams-BaNGaLxh.mjs → event-streams-DnRe8uwT.mjs} +2 -2
  60. package/dist/{event-streams-BaNGaLxh.mjs.map → event-streams-DnRe8uwT.mjs.map} +1 -1
  61. package/dist/fonts/index.d.mts +1 -1
  62. package/dist/fonts/index.mjs +3 -1
  63. package/dist/{fonts-C0W6TgJk.mjs → fonts-UM5xaBOx.mjs} +24 -11
  64. package/dist/fonts-UM5xaBOx.mjs.map +1 -0
  65. package/dist/gpu-RkpiFGOA.mjs +215 -0
  66. package/dist/gpu-RkpiFGOA.mjs.map +1 -0
  67. package/dist/{index-CYGpSVsf.d.mts → index-CHQ39_Oe.d.mts} +2 -2
  68. package/dist/{index-CYGpSVsf.d.mts.map → index-CHQ39_Oe.d.mts.map} +1 -1
  69. package/dist/{index-CDoTrMs1.d.mts → index-CzQseCtg.d.mts} +8 -8
  70. package/dist/{index-CDoTrMs1.d.mts.map → index-CzQseCtg.d.mts.map} +1 -1
  71. package/dist/{index-DDEPvMww.d.mts → index-D67p-rHX.d.mts} +3452 -1675
  72. package/dist/index-D67p-rHX.d.mts.map +1 -0
  73. package/dist/{index-9B8CJowc.d.mts → index-DPicEt8H.d.mts} +10 -2
  74. package/dist/index-DPicEt8H.d.mts.map +1 -0
  75. package/dist/{index-DGJp1d30.d.mts → index-Db8Z3AtX.d.mts} +3 -3
  76. package/dist/{index-DGJp1d30.d.mts.map → index-Db8Z3AtX.d.mts.map} +1 -1
  77. package/dist/{index-DRZu3ezy.d.mts → index-DsOqONsj.d.mts} +3 -3
  78. package/dist/{index-DRZu3ezy.d.mts.map → index-DsOqONsj.d.mts.map} +1 -1
  79. package/dist/{index-DnWsbbuZ.d.mts → index-l03NV8JS.d.mts} +7 -2
  80. package/dist/index-l03NV8JS.d.mts.map +1 -0
  81. package/dist/index.d.mts +28 -1841
  82. package/dist/index.d.mts.map +1 -1
  83. package/dist/index.mjs +79 -65
  84. package/dist/index.mjs.map +1 -1
  85. package/dist/{package-XpCRbTOA.mjs → package-CudzAF-n.mjs} +1 -1
  86. package/dist/{package-XpCRbTOA.mjs.map → package-CudzAF-n.mjs.map} +1 -1
  87. package/dist/preview/index.d.mts +2 -2
  88. package/dist/preview/index.mjs +13 -12
  89. package/dist/{preview-BV2C4Fk6.mjs → preview-DwClLMlU.mjs} +3 -3
  90. package/dist/{preview-BV2C4Fk6.mjs.map → preview-DwClLMlU.mjs.map} +1 -1
  91. package/dist/preview-engine/audio.mjs +1 -1
  92. package/dist/preview-engine/{chunk-Y6HWYPKX.mjs → chunk-3GNP7TJH.mjs} +3 -3
  93. package/dist/preview-engine/{chunk-LIHUEYI5.mjs → chunk-44CQSOYE.mjs} +2 -2
  94. package/dist/preview-engine/{chunk-6JW37VJA.mjs → chunk-5AUB4Y3L.mjs} +3 -23
  95. package/dist/preview-engine/chunk-5DOD2NVY.mjs +26 -0
  96. package/dist/preview-engine/chunk-5FC7GOWW.mjs +474 -0
  97. package/dist/preview-engine/chunk-5W4AFQP7.mjs +97 -0
  98. package/dist/preview-engine/chunk-63SFBHEH.mjs +1 -0
  99. package/dist/preview-engine/chunk-7EPIRODI.mjs +91 -0
  100. package/dist/preview-engine/{chunk-PQD5UPHG.mjs → chunk-7G3XIOP7.mjs} +1 -1
  101. package/dist/preview-engine/chunk-7J2FWGVD.mjs +1 -0
  102. package/dist/preview-engine/chunk-AXHB4J37.mjs +147 -0
  103. package/dist/preview-engine/chunk-AY7UX37L.mjs +450 -0
  104. package/dist/preview-engine/chunk-B43Z3J7J.mjs +5 -0
  105. package/dist/preview-engine/chunk-BWJS6G7R.mjs +314 -0
  106. package/dist/preview-engine/{chunk-24DXIKXL.mjs → chunk-DIGIQ5MJ.mjs} +2 -2
  107. package/dist/preview-engine/{chunk-AEK5BO3J.mjs → chunk-E4RAFHZM.mjs} +1 -1
  108. package/dist/preview-engine/chunk-ENKKLU7B.mjs +22 -0
  109. package/dist/preview-engine/{chunk-XLFYM7KH.mjs → chunk-EVXWDOCL.mjs} +2 -2
  110. package/dist/preview-engine/{chunk-EQ4QZRXB.mjs → chunk-EYWPOCZW.mjs} +2 -2
  111. package/dist/preview-engine/{chunk-IYVN2QEL.mjs → chunk-FLPSWDX4.mjs} +1 -1
  112. package/dist/preview-engine/chunk-FU7AIAMM.mjs +88 -0
  113. package/dist/preview-engine/{chunk-CBM7B7EW.mjs → chunk-GMGGDADT.mjs} +1 -1
  114. package/dist/preview-engine/chunk-GSFN4WCH.mjs +62 -0
  115. package/dist/preview-engine/chunk-HE4R7EZM.mjs +121 -0
  116. package/dist/preview-engine/chunk-IQC2I5A5.mjs +1 -0
  117. package/dist/preview-engine/{chunk-RJUAM52F.mjs → chunk-IR5DNNWR.mjs} +3 -23
  118. package/dist/preview-engine/chunk-IUPDOATX.mjs +114 -0
  119. package/dist/preview-engine/{chunk-GHMCGTJ2.mjs → chunk-J2R5R7YY.mjs} +3 -23
  120. package/dist/preview-engine/chunk-JAJOZG5P.mjs +1 -0
  121. package/dist/preview-engine/chunk-JXNG2ACR.mjs +118 -0
  122. package/dist/preview-engine/{chunk-V6VU46ZG.mjs → chunk-L6BH5J4P.mjs} +1 -1
  123. package/dist/preview-engine/chunk-LGVEFPOG.mjs +3 -0
  124. package/dist/preview-engine/{chunk-MDDF2GCF.mjs → chunk-MLY5M7Y5.mjs} +3 -23
  125. package/dist/preview-engine/chunk-NPD6W3RP.mjs +1 -0
  126. package/dist/preview-engine/chunk-OCX5AD23.mjs +1 -0
  127. package/dist/preview-engine/{chunk-D3TETPLI.mjs → chunk-OG62XGCT.mjs} +1 -1
  128. package/dist/preview-engine/chunk-OJ2PKBXE.mjs +40 -0
  129. package/dist/preview-engine/chunk-OKH2VU2U.mjs +97 -0
  130. package/dist/preview-engine/chunk-PAQNDZQB.mjs +83 -0
  131. package/dist/preview-engine/chunk-PEWYB6WP.mjs +43 -0
  132. package/dist/preview-engine/chunk-PL4IH5V4.mjs +89 -0
  133. package/dist/preview-engine/chunk-PSRQA3QW.mjs +84 -0
  134. package/dist/preview-engine/{chunk-QYRDQMNB.mjs → chunk-PXT52LEH.mjs} +3 -23
  135. package/dist/preview-engine/chunk-Q22PJXFJ.mjs +69 -0
  136. package/dist/preview-engine/chunk-Q4Z54DQ7.mjs +1 -0
  137. package/dist/preview-engine/{chunk-BHFI3Y4T.mjs → chunk-QBEUICZD.mjs} +1 -1
  138. package/dist/preview-engine/chunk-RQLMW6MA.mjs +4 -0
  139. package/dist/preview-engine/chunk-RSMO7NPN.mjs +1 -0
  140. package/dist/preview-engine/chunk-RW2F3XLQ.mjs +90 -0
  141. package/dist/preview-engine/{chunk-25IW7NYO.mjs → chunk-S2CTIJSI.mjs} +1 -1
  142. package/dist/preview-engine/chunk-SGPRLTNF.mjs +52 -0
  143. package/dist/preview-engine/{chunk-Y6FEU4TV.mjs → chunk-SZW5J72T.mjs} +3 -23
  144. package/dist/preview-engine/{chunk-ECPP3UG6.mjs → chunk-T2FE5VOW.mjs} +3 -23
  145. package/dist/preview-engine/{chunk-ZSIJB76A.mjs → chunk-TS3JI3BH.mjs} +2 -2
  146. package/dist/preview-engine/{chunk-AMBSW6OA.mjs → chunk-U4JIFQRR.mjs} +2 -2
  147. package/dist/preview-engine/{chunk-BJKH76OM.mjs → chunk-VXS5SIEC.mjs} +3 -23
  148. package/dist/preview-engine/chunk-WFGJXCZT.mjs +53 -0
  149. package/dist/preview-engine/chunk-WH5Q2NFN.mjs +32 -0
  150. package/dist/preview-engine/{chunk-AWTH2WZO.mjs → chunk-WUKH7BD7.mjs} +1 -1
  151. package/dist/preview-engine/chunk-XC5WZNOY.mjs +1448 -0
  152. package/dist/preview-engine/chunk-YQZOGEPZ.mjs +186 -0
  153. package/dist/preview-engine/{chunk-6256GQFP.mjs → chunk-ZDQF3OTC.mjs} +1 -1
  154. package/dist/preview-engine/chunk-ZIIFTWDH.mjs +58 -0
  155. package/dist/preview-engine/effects.mjs +1 -1
  156. package/dist/preview-engine/fonts.mjs +1 -1
  157. package/dist/preview-engine/framefields.mjs +127 -130
  158. package/dist/preview-engine/player.mjs +6 -6
  159. package/dist/preview-engine/renderers-2H7YEUTD.mjs +1 -0
  160. package/dist/preview-engine/renderers-2ILG23ED.mjs +1 -0
  161. package/dist/preview-engine/renderers-2P6KXWEZ.mjs +1 -0
  162. package/dist/preview-engine/renderers-2SVWAB42.mjs +1 -0
  163. package/dist/preview-engine/renderers-2VN3AH45.mjs +104 -0
  164. package/dist/preview-engine/renderers-3RC5FDWX.mjs +1 -0
  165. package/dist/preview-engine/renderers-57WDL6XN.mjs +1 -0
  166. package/dist/preview-engine/{renderers-CAUWP4XH.mjs → renderers-6OGFUSH6.mjs} +3 -23
  167. package/dist/preview-engine/renderers-6WH7NZCC.mjs +1 -0
  168. package/dist/preview-engine/renderers-7VJN5L3Z.mjs +1 -0
  169. package/dist/preview-engine/renderers-A6HM64UZ.mjs +1 -0
  170. package/dist/preview-engine/{renderers-WLH4HRUE.mjs → renderers-A7VH3ON5.mjs} +1 -1
  171. package/dist/preview-engine/renderers-B7DSGUMI.mjs +1 -0
  172. package/dist/preview-engine/renderers-BFNJ7VCI.mjs +1 -0
  173. package/dist/preview-engine/renderers-BSKZXITT.mjs +35 -0
  174. package/dist/preview-engine/renderers-CGYIDAVV.mjs +1 -0
  175. package/dist/preview-engine/renderers-CRRLV7IO.mjs +1 -0
  176. package/dist/preview-engine/{renderers-JQHUBWLL.mjs → renderers-D6T6IPER.mjs} +3 -23
  177. package/dist/preview-engine/renderers-DXHJAMZR.mjs +1 -0
  178. package/dist/preview-engine/renderers-ECA3P4ON.mjs +1 -0
  179. package/dist/preview-engine/{renderers-W5CVDJVH.mjs → renderers-F55XFVMP.mjs} +1 -1
  180. package/dist/preview-engine/renderers-FWGMNPYB.mjs +1 -0
  181. package/dist/preview-engine/renderers-H46TS3IG.mjs +228 -0
  182. package/dist/preview-engine/renderers-HXFRTIJD.mjs +1 -0
  183. package/dist/preview-engine/renderers-IWQ3V6AJ.mjs +1 -0
  184. package/dist/preview-engine/renderers-JHFT27YU.mjs +1 -0
  185. package/dist/preview-engine/renderers-KZWGSKRF.mjs +1 -0
  186. package/dist/preview-engine/renderers-MON4QFRF.mjs +1 -0
  187. package/dist/preview-engine/renderers-NQXMYNSY.mjs +1 -0
  188. package/dist/preview-engine/renderers-NWHS7N2L.mjs +1 -0
  189. package/dist/preview-engine/renderers-ORAIXUL3.mjs +1 -0
  190. package/dist/preview-engine/renderers-OT7D3BUA.mjs +1 -0
  191. package/dist/preview-engine/renderers-Q4OFCMXI.mjs +1 -0
  192. package/dist/preview-engine/renderers-QVZVEYP5.mjs +1 -0
  193. package/dist/preview-engine/renderers-RJO6H4FC.mjs +1 -0
  194. package/dist/preview-engine/renderers-RKDPX5JU.mjs +1 -0
  195. package/dist/preview-engine/{renderers-2US2NIUG.mjs → renderers-RLHTNLRE.mjs} +3 -23
  196. package/dist/preview-engine/renderers-SBFF7JP5.mjs +1 -0
  197. package/dist/preview-engine/renderers-SCJ6OKTB.mjs +1 -0
  198. package/dist/preview-engine/renderers-T4JMJXWL.mjs +1 -0
  199. package/dist/preview-engine/renderers-TAWT3ZSS.mjs +1 -0
  200. package/dist/preview-engine/renderers-U6KY34TP.mjs +100 -0
  201. package/dist/preview-engine/renderers-UHTO6BQA.mjs +1 -0
  202. package/dist/preview-engine/renderers-UNK6I4JJ.mjs +1 -0
  203. package/dist/preview-engine/renderers-UPTJJE5F.mjs +1 -0
  204. package/dist/preview-engine/renderers-W773SBPV.mjs +1 -0
  205. package/dist/preview-engine/renderers-XHTMRXC5.mjs +1 -0
  206. package/dist/preview-engine/renderers-YECY2YFT.mjs +1 -0
  207. package/dist/preview-engine/renderers-YMN6QXK7.mjs +1 -0
  208. package/dist/preview-engine/renderers-ZANPE3OK.mjs +1 -0
  209. package/dist/preview-engine/renderers-ZHTX73PR.mjs +1 -0
  210. package/dist/preview-engine/renderers-ZJTRANIX.mjs +1 -0
  211. package/dist/preview-engine/signals.mjs +1 -1
  212. package/dist/preview-engine/skia-canvas-QBXAOGPB.mjs +1 -0
  213. package/dist/{program-BmNKgzja.mjs → program-BqFVw5Mu.mjs} +93 -2335
  214. package/dist/program-BqFVw5Mu.mjs.map +1 -0
  215. package/dist/renderer/index.d.mts +2 -2
  216. package/dist/renderer/index.mjs +3 -3
  217. package/dist/{renderer-CnXW28b9.mjs → renderer-2Nf9ypST.mjs} +85 -279
  218. package/dist/renderer-2Nf9ypST.mjs.map +1 -0
  219. package/dist/{renderer-BREIjsUU.mjs → renderer-2uN2cd0y.mjs} +14 -40
  220. package/dist/renderer-2uN2cd0y.mjs.map +1 -0
  221. package/dist/renderer-31jAuNzF.mjs +5 -0
  222. package/dist/renderer-36EI7Rsz.mjs +5 -0
  223. package/dist/renderer-3io-cjTt.mjs +5 -0
  224. package/dist/renderer-9_zWTHbg.mjs +5 -0
  225. package/dist/{renderer-WSGuj_V6.mjs → renderer-B12_76qk.mjs} +4 -3
  226. package/dist/{renderer-WSGuj_V6.mjs.map → renderer-B12_76qk.mjs.map} +1 -1
  227. package/dist/{renderer-bsWnRNpJ.mjs → renderer-B4oS8ZFO.mjs} +29 -98
  228. package/dist/renderer-B4oS8ZFO.mjs.map +1 -0
  229. package/dist/renderer-B6KnbfdA.mjs +5 -0
  230. package/dist/renderer-B7Y2bmRc.mjs +5 -0
  231. package/dist/renderer-BA6miaaI.mjs +5 -0
  232. package/dist/{renderer-Bv6q84TU.mjs → renderer-BGr_cBKV.mjs} +61 -208
  233. package/dist/renderer-BGr_cBKV.mjs.map +1 -0
  234. package/dist/renderer-BHi-Q6Z_.mjs +5 -0
  235. package/dist/{renderer-Bv21DbWy.mjs → renderer-BLcu9RDt.mjs} +3 -1
  236. package/dist/{renderer-D2XD4QYk.mjs → renderer-BO2lYmtE.mjs} +34 -147
  237. package/dist/renderer-BO2lYmtE.mjs.map +1 -0
  238. package/dist/renderer-BOlN9HeG.mjs +5 -0
  239. package/dist/renderer-BSitV56h.mjs +268 -0
  240. package/dist/renderer-BSitV56h.mjs.map +1 -0
  241. package/dist/renderer-BTOW-ceB.mjs +5 -0
  242. package/dist/{renderer-Bhdf90Zq.mjs → renderer-BYqfkwLf.mjs} +51 -163
  243. package/dist/renderer-BYqfkwLf.mjs.map +1 -0
  244. package/dist/{renderer-bZU_ndxf.mjs → renderer-BajIOuZH.mjs} +2 -2
  245. package/dist/{renderer-bZU_ndxf.mjs.map → renderer-BajIOuZH.mjs.map} +1 -1
  246. package/dist/{renderer-DirxsOjq.mjs → renderer-BgnJUx24.mjs} +80 -258
  247. package/dist/renderer-BgnJUx24.mjs.map +1 -0
  248. package/dist/renderer-BiQ0PYOp.mjs +5 -0
  249. package/dist/{renderer-DIgsilTw.mjs → renderer-BjTq3a0L.mjs} +5 -4
  250. package/dist/{renderer-DIgsilTw.mjs.map → renderer-BjTq3a0L.mjs.map} +1 -1
  251. package/dist/{renderer-DEJwPRkR.mjs → renderer-BkN20ZKO.mjs} +15 -51
  252. package/dist/renderer-BkN20ZKO.mjs.map +1 -0
  253. package/dist/renderer-Bla7GDyV.mjs +5 -0
  254. package/dist/renderer-BoYyLVKy.mjs +5 -0
  255. package/dist/{renderer-D7zvPHKn.mjs → renderer-BpZaHFRc.mjs} +18 -28
  256. package/dist/renderer-BpZaHFRc.mjs.map +1 -0
  257. package/dist/renderer-BqOgb7bM.mjs +5 -0
  258. package/dist/{renderer-cgxO2xN6.mjs → renderer-Bq_dO0LG.mjs} +10 -17
  259. package/dist/renderer-Bq_dO0LG.mjs.map +1 -0
  260. package/dist/renderer-BqeM8yTJ.mjs +5 -0
  261. package/dist/{renderer-dncoIVdd.mjs → renderer-BqsV75Ml.mjs} +3 -1
  262. package/dist/{renderer-ChdLYS-G.mjs → renderer-Bs4tz_pw.mjs} +20 -87
  263. package/dist/renderer-Bs4tz_pw.mjs.map +1 -0
  264. package/dist/{renderer-DpGc-N3G.mjs → renderer-Bsaokil3.mjs} +24 -104
  265. package/dist/renderer-Bsaokil3.mjs.map +1 -0
  266. package/dist/{renderer-CXn5HAnK.mjs → renderer-BvG1GF1c.mjs} +10 -16
  267. package/dist/renderer-BvG1GF1c.mjs.map +1 -0
  268. package/dist/{renderer-CI7sG_cv.mjs → renderer-BvpSIFkw.mjs} +83 -266
  269. package/dist/renderer-BvpSIFkw.mjs.map +1 -0
  270. package/dist/{renderer-B8UaFNqb.mjs → renderer-BwAqwTQq.mjs} +62 -209
  271. package/dist/renderer-BwAqwTQq.mjs.map +1 -0
  272. package/dist/{renderer-CzPWB0Ss.mjs → renderer-BwVfhrEx.mjs} +13 -45
  273. package/dist/renderer-BwVfhrEx.mjs.map +1 -0
  274. package/dist/renderer-BzpRe50i.mjs +5 -0
  275. package/dist/renderer-C0eAPwpr.mjs +5 -0
  276. package/dist/{renderer-CtyD_Xju.mjs → renderer-C3RfT8Gv.mjs} +59 -194
  277. package/dist/renderer-C3RfT8Gv.mjs.map +1 -0
  278. package/dist/{renderer-B1YMwl2B.mjs → renderer-C3cYDT3m.mjs} +3 -1
  279. package/dist/{renderer-1VuQTY1Z.mjs → renderer-CEGbqT2m.mjs} +236 -96
  280. package/dist/renderer-CEGbqT2m.mjs.map +1 -0
  281. package/dist/{renderer-DxTs4Iyi.mjs → renderer-CGldH-Zx.mjs} +40 -142
  282. package/dist/renderer-CGldH-Zx.mjs.map +1 -0
  283. package/dist/renderer-CGn8V63v.mjs +5 -0
  284. package/dist/{renderer-kwmlLQOO.mjs → renderer-CH9Qtpy7.mjs} +4 -4
  285. package/dist/{renderer-kwmlLQOO.mjs.map → renderer-CH9Qtpy7.mjs.map} +1 -1
  286. package/dist/{renderer-ho_jXJ0H.mjs → renderer-CLyuu_19.mjs} +23 -117
  287. package/dist/renderer-CLyuu_19.mjs.map +1 -0
  288. package/dist/renderer-CM5Syo9r.mjs +5 -0
  289. package/dist/{renderer-D2nCGcjv.mjs → renderer-CRIM_XRK.mjs} +3 -3
  290. package/dist/{renderer-D2nCGcjv.mjs.map → renderer-CRIM_XRK.mjs.map} +1 -1
  291. package/dist/{renderer-BTdOMMEx.d.mts → renderer-CTGe8SqQ.d.mts} +2 -2
  292. package/dist/{renderer-BTdOMMEx.d.mts.map → renderer-CTGe8SqQ.d.mts.map} +1 -1
  293. package/dist/renderer-CWCEW6Wv.mjs +5 -0
  294. package/dist/{renderer-Dy0utCl7.mjs → renderer-CgyOylPO.mjs} +10 -17
  295. package/dist/renderer-CgyOylPO.mjs.map +1 -0
  296. package/dist/{renderer-C_TPMHiH.mjs → renderer-CjT5Zy-J.mjs} +81 -221
  297. package/dist/renderer-CjT5Zy-J.mjs.map +1 -0
  298. package/dist/{renderer-_uvdg48N.mjs → renderer-Cjq1s3br.mjs} +24 -93
  299. package/dist/renderer-Cjq1s3br.mjs.map +1 -0
  300. package/dist/renderer-Cl70zxkP.mjs +5 -0
  301. package/dist/renderer-ClJjoVpB.mjs +6 -0
  302. package/dist/{renderer-BSaYG8aw.mjs → renderer-CpKNqciR.mjs} +3 -1
  303. package/dist/{renderer-Bfgd4N0O.mjs → renderer-Cwhux4VX.mjs} +9 -16
  304. package/dist/renderer-Cwhux4VX.mjs.map +1 -0
  305. package/dist/{renderer-BJ1aTkZf.mjs → renderer-D0nWLogn.mjs} +99 -282
  306. package/dist/renderer-D0nWLogn.mjs.map +1 -0
  307. package/dist/{renderer-vqkKWqa5.mjs → renderer-D1lynYuy.mjs} +23 -107
  308. package/dist/renderer-D1lynYuy.mjs.map +1 -0
  309. package/dist/{renderer-B8-kzZdP.mjs → renderer-D4sYVV-I.mjs} +41 -140
  310. package/dist/renderer-D4sYVV-I.mjs.map +1 -0
  311. package/dist/{renderer-Bc04fivZ.mjs → renderer-D5z3WDkm.mjs} +99 -287
  312. package/dist/renderer-D5z3WDkm.mjs.map +1 -0
  313. package/dist/renderer-D8C-pamu.mjs +148 -0
  314. package/dist/renderer-D8C-pamu.mjs.map +1 -0
  315. package/dist/{renderer-D_1oDOCP.mjs → renderer-DAtBnNGC.mjs} +14 -69
  316. package/dist/renderer-DAtBnNGC.mjs.map +1 -0
  317. package/dist/{renderer-DZGtBUCx.mjs → renderer-DG1NFsSV.mjs} +35 -185
  318. package/dist/renderer-DG1NFsSV.mjs.map +1 -0
  319. package/dist/{renderer-BM05sB8m.mjs → renderer-DHAErBtJ.mjs} +11 -74
  320. package/dist/renderer-DHAErBtJ.mjs.map +1 -0
  321. package/dist/{renderer-RKsXlF_0.mjs → renderer-DIDSmoFA.mjs} +73 -73
  322. package/dist/{renderer-RKsXlF_0.mjs.map → renderer-DIDSmoFA.mjs.map} +1 -1
  323. package/dist/{renderer-BDbTWSpP.mjs → renderer-DKtP7-fr.mjs} +58 -234
  324. package/dist/renderer-DKtP7-fr.mjs.map +1 -0
  325. package/dist/renderer-DLnF-V_h.mjs +5 -0
  326. package/dist/renderer-DN1rjmcL.mjs +5 -0
  327. package/dist/{renderer-CfC_aiew.mjs → renderer-DOEsFT7Q.mjs} +57 -192
  328. package/dist/renderer-DOEsFT7Q.mjs.map +1 -0
  329. package/dist/{renderer-Ctk2zzfy.mjs → renderer-DPYB6ZcB.mjs} +57 -197
  330. package/dist/renderer-DPYB6ZcB.mjs.map +1 -0
  331. package/dist/{renderer-CWTpc4ff.mjs → renderer-DRsPCkxr.mjs} +76 -210
  332. package/dist/renderer-DRsPCkxr.mjs.map +1 -0
  333. package/dist/renderer-DXTw9Oqb.mjs +5 -0
  334. package/dist/{renderer-CaaOKMSd.mjs → renderer-DZLJnnU2.mjs} +63 -190
  335. package/dist/renderer-DZLJnnU2.mjs.map +1 -0
  336. package/dist/{renderer-B2ieylQ3.mjs → renderer-DZrQffIP.mjs} +56 -167
  337. package/dist/renderer-DZrQffIP.mjs.map +1 -0
  338. package/dist/renderer-DbAVSBNI.mjs +5 -0
  339. package/dist/renderer-Dg8rD--8.mjs +5 -0
  340. package/dist/{renderer-DML9qpmS.mjs → renderer-DhEyjn6Q.mjs} +52 -202
  341. package/dist/renderer-DhEyjn6Q.mjs.map +1 -0
  342. package/dist/{renderer-CdciwwMI.mjs → renderer-Dmv_Aj6x.mjs} +161 -457
  343. package/dist/renderer-Dmv_Aj6x.mjs.map +1 -0
  344. package/dist/renderer-DnFxegGu.mjs +5 -0
  345. package/dist/renderer-DnfmelHn.mjs +5 -0
  346. package/dist/{renderer-BIIWCg_J.mjs → renderer-Dpj68gTn.mjs} +11 -18
  347. package/dist/renderer-Dpj68gTn.mjs.map +1 -0
  348. package/dist/renderer-DuOjzggd.mjs +5 -0
  349. package/dist/renderer-DuuOlYIG.mjs +3 -0
  350. package/dist/renderer-DvYql0Cl.mjs +5 -0
  351. package/dist/{renderer-BfAWZziM.mjs → renderer-DzhRNdBS.mjs} +58 -225
  352. package/dist/renderer-DzhRNdBS.mjs.map +1 -0
  353. package/dist/renderer-GSFP7v2z.mjs +3 -0
  354. package/dist/renderer-LfUdjgjF.mjs +5 -0
  355. package/dist/{renderer-Djlb4TLO.mjs → renderer-Q63y7HP_.mjs} +8 -15
  356. package/dist/renderer-Q63y7HP_.mjs.map +1 -0
  357. package/dist/renderer-SecCv3U8.mjs +5 -0
  358. package/dist/{renderer-BhZZEyFX.mjs → renderer-mp1NN5zk.mjs} +4 -4
  359. package/dist/{renderer-BhZZEyFX.mjs.map → renderer-mp1NN5zk.mjs.map} +1 -1
  360. package/dist/renderer-oZyoB4CT.mjs +5 -0
  361. package/dist/renderer-rzci_kTy.mjs +5 -0
  362. package/dist/{renderer-CpkiHRhh.mjs → renderer-to9DwqXK.mjs} +17 -99
  363. package/dist/renderer-to9DwqXK.mjs.map +1 -0
  364. package/dist/{renderer-CepMDQ06.mjs → renderer-v0vuUUUI.mjs} +19 -106
  365. package/dist/renderer-v0vuUUUI.mjs.map +1 -0
  366. package/dist/renderer-vLaZuZbX.mjs +5 -0
  367. package/dist/{renderers-CP8CFWDs-DwQTx8S7.mjs → renderers-CP8CFWDs-DlFq8jmz.mjs} +4 -4
  368. package/dist/{renderers-CP8CFWDs-DwQTx8S7.mjs.map → renderers-CP8CFWDs-DlFq8jmz.mjs.map} +1 -1
  369. package/dist/signals/index.d.mts +5 -5
  370. package/dist/signals/index.mjs +7 -7
  371. package/dist/{signals-Bv1OweKd.mjs → signals-BDkO0xcZ.mjs} +3 -3
  372. package/dist/{signals-Bv1OweKd.mjs.map → signals-BDkO0xcZ.mjs.map} +1 -1
  373. package/dist/{signin-Db08vl-g.mjs → signin-SVSXQw9i.mjs} +9 -9
  374. package/dist/{signin-Db08vl-g.mjs.map → signin-SVSXQw9i.mjs.map} +1 -1
  375. package/dist/{sso-oidc-CpLz_lIu.mjs → sso-oidc-B3Sagl43.mjs} +9 -9
  376. package/dist/{sso-oidc-CpLz_lIu.mjs.map → sso-oidc-B3Sagl43.mjs.map} +1 -1
  377. package/dist/{sts-BQefGuml.mjs → sts-CYeWec9i.mjs} +2 -2
  378. package/dist/{sts-Dgl0kH-t.mjs → sts-ClVtt-bV.mjs} +9 -9
  379. package/dist/{sts-Dgl0kH-t.mjs.map → sts-ClVtt-bV.mjs.map} +1 -1
  380. package/package.json +55 -55
  381. package/dist/dist-BAVZdFEJ.mjs.map +0 -1
  382. package/dist/dist-BYqNNwsl.mjs.map +0 -1
  383. package/dist/dist-CbG3QxDw.mjs.map +0 -1
  384. package/dist/dist-Cxi68OuY.mjs.map +0 -1
  385. package/dist/dist-cjs-3pon9kTt.mjs +0 -6
  386. package/dist/fonts-C0W6TgJk.mjs.map +0 -1
  387. package/dist/index-9B8CJowc.d.mts.map +0 -1
  388. package/dist/index-DDEPvMww.d.mts.map +0 -1
  389. package/dist/index-DnWsbbuZ.d.mts.map +0 -1
  390. package/dist/preview-engine/chunk-36YGYLKD.mjs +0 -58
  391. package/dist/preview-engine/chunk-7O24H4YT.mjs +0 -117
  392. package/dist/preview-engine/chunk-AUFSM5KI.mjs +0 -141
  393. package/dist/preview-engine/chunk-BQ65MU6H.mjs +0 -138
  394. package/dist/preview-engine/chunk-BWDARDO6.mjs +0 -117
  395. package/dist/preview-engine/chunk-DLXQDDIN.mjs +0 -46
  396. package/dist/preview-engine/chunk-EJGLUZMW.mjs +0 -1
  397. package/dist/preview-engine/chunk-FE6RSVKZ.mjs +0 -73
  398. package/dist/preview-engine/chunk-FGHOHCFG.mjs +0 -110
  399. package/dist/preview-engine/chunk-HPIULG7P.mjs +0 -111
  400. package/dist/preview-engine/chunk-HRIKNYPF.mjs +0 -60
  401. package/dist/preview-engine/chunk-IMV5SBQV.mjs +0 -1
  402. package/dist/preview-engine/chunk-JPXQPP6J.mjs +0 -1
  403. package/dist/preview-engine/chunk-K52S5DJX.mjs +0 -109
  404. package/dist/preview-engine/chunk-L3IEJZ5S.mjs +0 -474
  405. package/dist/preview-engine/chunk-M7NMFDJ3.mjs +0 -3
  406. package/dist/preview-engine/chunk-MJM3NFEC.mjs +0 -315
  407. package/dist/preview-engine/chunk-NFAGEP43.mjs +0 -1448
  408. package/dist/preview-engine/chunk-NRHSNPZV.mjs +0 -182
  409. package/dist/preview-engine/chunk-OWOSYNMF.mjs +0 -104
  410. package/dist/preview-engine/chunk-Q66QQI6N.mjs +0 -8
  411. package/dist/preview-engine/chunk-QGBSLNFI.mjs +0 -52
  412. package/dist/preview-engine/chunk-QM3XFEJN.mjs +0 -63
  413. package/dist/preview-engine/chunk-R3ZH7YF3.mjs +0 -89
  414. package/dist/preview-engine/chunk-R6YNSBKL.mjs +0 -108
  415. package/dist/preview-engine/chunk-S4CSX6K5.mjs +0 -610
  416. package/dist/preview-engine/chunk-SNYAHQ25.mjs +0 -186
  417. package/dist/preview-engine/chunk-SRT2OCQW.mjs +0 -1
  418. package/dist/preview-engine/chunk-SUUUYXXT.mjs +0 -1
  419. package/dist/preview-engine/chunk-T6COGNOW.mjs +0 -134
  420. package/dist/preview-engine/chunk-XFYXT76H.mjs +0 -52
  421. package/dist/preview-engine/chunk-XUM42I4R.mjs +0 -1
  422. package/dist/preview-engine/chunk-YITWSOG4.mjs +0 -103
  423. package/dist/preview-engine/chunk-ZDCA6NVT.mjs +0 -82
  424. package/dist/preview-engine/chunk-ZNGOAGAI.mjs +0 -1
  425. package/dist/preview-engine/renderers-27Q5X3U6.mjs +0 -1
  426. package/dist/preview-engine/renderers-4AHH6BHF.mjs +0 -1
  427. package/dist/preview-engine/renderers-5BV6JGTU.mjs +0 -248
  428. package/dist/preview-engine/renderers-6PRVCTYV.mjs +0 -1
  429. package/dist/preview-engine/renderers-76PQY2SO.mjs +0 -1
  430. package/dist/preview-engine/renderers-7X2W6QWX.mjs +0 -1
  431. package/dist/preview-engine/renderers-B52QT6MT.mjs +0 -55
  432. package/dist/preview-engine/renderers-BE6RVJSE.mjs +0 -1
  433. package/dist/preview-engine/renderers-BMM2BH56.mjs +0 -1
  434. package/dist/preview-engine/renderers-CHOGQHVQ.mjs +0 -1
  435. package/dist/preview-engine/renderers-CRKRWR2Y.mjs +0 -1
  436. package/dist/preview-engine/renderers-DEYDSGJX.mjs +0 -1
  437. package/dist/preview-engine/renderers-DZTNRCR7.mjs +0 -1
  438. package/dist/preview-engine/renderers-ELO3KWTK.mjs +0 -1
  439. package/dist/preview-engine/renderers-EOJMPPAQ.mjs +0 -1
  440. package/dist/preview-engine/renderers-F2KJNDWA.mjs +0 -124
  441. package/dist/preview-engine/renderers-FCV4COVB.mjs +0 -1
  442. package/dist/preview-engine/renderers-G5KQISVL.mjs +0 -1
  443. package/dist/preview-engine/renderers-GJSUN5HU.mjs +0 -1
  444. package/dist/preview-engine/renderers-GMX2ZQDG.mjs +0 -1
  445. package/dist/preview-engine/renderers-GXCRINGC.mjs +0 -1
  446. package/dist/preview-engine/renderers-IHKORHMT.mjs +0 -1
  447. package/dist/preview-engine/renderers-JA4SLMG3.mjs +0 -1
  448. package/dist/preview-engine/renderers-JLN77CFZ.mjs +0 -1
  449. package/dist/preview-engine/renderers-KBFW7B5F.mjs +0 -1
  450. package/dist/preview-engine/renderers-LJRJMFCR.mjs +0 -1
  451. package/dist/preview-engine/renderers-LPAPZ5QS.mjs +0 -1
  452. package/dist/preview-engine/renderers-NQUDQEHY.mjs +0 -1
  453. package/dist/preview-engine/renderers-NS3AIJVG.mjs +0 -1
  454. package/dist/preview-engine/renderers-NSY2SDIE.mjs +0 -1
  455. package/dist/preview-engine/renderers-PW4OJWHF.mjs +0 -120
  456. package/dist/preview-engine/renderers-PWLWOZY4.mjs +0 -1
  457. package/dist/preview-engine/renderers-Q3MD34JN.mjs +0 -1
  458. package/dist/preview-engine/renderers-RXGNA2Q7.mjs +0 -1
  459. package/dist/preview-engine/renderers-TVTQ2R74.mjs +0 -1
  460. package/dist/preview-engine/renderers-VTTGFO55.mjs +0 -1
  461. package/dist/preview-engine/renderers-W3VVM5HB.mjs +0 -1
  462. package/dist/preview-engine/renderers-WG7QBD4D.mjs +0 -1
  463. package/dist/preview-engine/renderers-WLLJFZTF.mjs +0 -1
  464. package/dist/preview-engine/renderers-WN4SYFCU.mjs +0 -1
  465. package/dist/preview-engine/renderers-WSMLLSWX.mjs +0 -1
  466. package/dist/preview-engine/renderers-XFBSGTHU.mjs +0 -1
  467. package/dist/preview-engine/renderers-XFC6ZPO5.mjs +0 -1
  468. package/dist/preview-engine/renderers-XUHRY3XH.mjs +0 -1
  469. package/dist/preview-engine/renderers-YAOB5XU6.mjs +0 -1
  470. package/dist/preview-engine/renderers-YTB4FOHT.mjs +0 -1
  471. package/dist/preview-engine/renderers-ZIMBODX6.mjs +0 -1
  472. package/dist/program-BmNKgzja.mjs.map +0 -1
  473. package/dist/renderer-1VuQTY1Z.mjs.map +0 -1
  474. package/dist/renderer-6oMSare3.mjs +0 -3
  475. package/dist/renderer-B1ComPb2.mjs +0 -3
  476. package/dist/renderer-B2XzjK0z.mjs +0 -3
  477. package/dist/renderer-B2ieylQ3.mjs.map +0 -1
  478. package/dist/renderer-B8-kzZdP.mjs.map +0 -1
  479. package/dist/renderer-B8UaFNqb.mjs.map +0 -1
  480. package/dist/renderer-BDbTWSpP.mjs.map +0 -1
  481. package/dist/renderer-BIIWCg_J.mjs.map +0 -1
  482. package/dist/renderer-BJ1aTkZf.mjs.map +0 -1
  483. package/dist/renderer-BM05sB8m.mjs.map +0 -1
  484. package/dist/renderer-BQ5Bz5D0.mjs +0 -3
  485. package/dist/renderer-BREIjsUU.mjs.map +0 -1
  486. package/dist/renderer-BTu2EVhF.mjs +0 -3
  487. package/dist/renderer-BZcn_iBl.mjs +0 -3
  488. package/dist/renderer-Bc04fivZ.mjs.map +0 -1
  489. package/dist/renderer-BfAWZziM.mjs.map +0 -1
  490. package/dist/renderer-BfJSUjPN.mjs +0 -3
  491. package/dist/renderer-Bfgd4N0O.mjs.map +0 -1
  492. package/dist/renderer-Bhdf90Zq.mjs.map +0 -1
  493. package/dist/renderer-Bp6sDMa6.mjs +0 -3
  494. package/dist/renderer-Bt7_sb_Y.mjs +0 -3
  495. package/dist/renderer-Bv6q84TU.mjs.map +0 -1
  496. package/dist/renderer-C-H680_l.mjs +0 -3
  497. package/dist/renderer-C606ZPUn.mjs +0 -3
  498. package/dist/renderer-C9jyKn1i.mjs +0 -3
  499. package/dist/renderer-CDLrNgfo.mjs +0 -3
  500. package/dist/renderer-CERfcxgv.mjs +0 -3
  501. package/dist/renderer-CG5PzNkv.mjs +0 -3
  502. package/dist/renderer-CI7sG_cv.mjs.map +0 -1
  503. package/dist/renderer-CPoIMVdk.mjs +0 -3
  504. package/dist/renderer-CQdVj2JS.mjs +0 -3
  505. package/dist/renderer-CQiTodg9.mjs +0 -337
  506. package/dist/renderer-CQiTodg9.mjs.map +0 -1
  507. package/dist/renderer-CWTpc4ff.mjs.map +0 -1
  508. package/dist/renderer-CXn5HAnK.mjs.map +0 -1
  509. package/dist/renderer-CZgB5st8.mjs +0 -3
  510. package/dist/renderer-C_TPMHiH.mjs.map +0 -1
  511. package/dist/renderer-Ca7L1EOp.mjs +0 -3
  512. package/dist/renderer-CaaOKMSd.mjs.map +0 -1
  513. package/dist/renderer-CdciwwMI.mjs.map +0 -1
  514. package/dist/renderer-CepMDQ06.mjs.map +0 -1
  515. package/dist/renderer-CfC_aiew.mjs.map +0 -1
  516. package/dist/renderer-ChdLYS-G.mjs.map +0 -1
  517. package/dist/renderer-CkykdR_D.mjs +0 -3
  518. package/dist/renderer-Cl6GkeHx.mjs +0 -3
  519. package/dist/renderer-ClcjrFyo.mjs +0 -3
  520. package/dist/renderer-CnXW28b9.mjs.map +0 -1
  521. package/dist/renderer-CpkiHRhh.mjs.map +0 -1
  522. package/dist/renderer-CtVkU_GA.mjs +0 -44
  523. package/dist/renderer-CtVkU_GA.mjs.map +0 -1
  524. package/dist/renderer-Ctk2zzfy.mjs.map +0 -1
  525. package/dist/renderer-CtyD_Xju.mjs.map +0 -1
  526. package/dist/renderer-CySUP_wk.mjs +0 -3
  527. package/dist/renderer-CzPWB0Ss.mjs.map +0 -1
  528. package/dist/renderer-D2XD4QYk.mjs.map +0 -1
  529. package/dist/renderer-D2l_Odyg.mjs +0 -3
  530. package/dist/renderer-D7zvPHKn.mjs.map +0 -1
  531. package/dist/renderer-D9NnIx7o.mjs +0 -3
  532. package/dist/renderer-DCPCYySt.mjs +0 -3
  533. package/dist/renderer-DEJwPRkR.mjs.map +0 -1
  534. package/dist/renderer-DIkpJEOZ.mjs +0 -3
  535. package/dist/renderer-DML9qpmS.mjs.map +0 -1
  536. package/dist/renderer-DNSXPkf_.mjs +0 -3
  537. package/dist/renderer-DP-CvZ_Z.mjs +0 -3
  538. package/dist/renderer-DZGtBUCx.mjs.map +0 -1
  539. package/dist/renderer-D_1oDOCP.mjs.map +0 -1
  540. package/dist/renderer-DeXb8R6h.mjs +0 -3
  541. package/dist/renderer-DezO-ZaP.mjs +0 -4
  542. package/dist/renderer-DhXe04fC.mjs +0 -3
  543. package/dist/renderer-DirxsOjq.mjs.map +0 -1
  544. package/dist/renderer-Djlb4TLO.mjs.map +0 -1
  545. package/dist/renderer-DnH3SI7w.mjs +0 -3
  546. package/dist/renderer-DpGc-N3G.mjs.map +0 -1
  547. package/dist/renderer-Dpw4oi33.mjs +0 -3
  548. package/dist/renderer-DxTs4Iyi.mjs.map +0 -1
  549. package/dist/renderer-Dy0utCl7.mjs.map +0 -1
  550. package/dist/renderer-Md-ytU0v.mjs +0 -3
  551. package/dist/renderer-U-bhWO9Q.mjs +0 -3
  552. package/dist/renderer-_uvdg48N.mjs.map +0 -1
  553. package/dist/renderer-bsWnRNpJ.mjs.map +0 -1
  554. package/dist/renderer-cgxO2xN6.mjs.map +0 -1
  555. package/dist/renderer-d5-F_48R.mjs +0 -3
  556. package/dist/renderer-ho_jXJ0H.mjs.map +0 -1
  557. package/dist/renderer-vqkKWqa5.mjs.map +0 -1
  558. package/dist/renderer-zA5okHds.mjs +0 -3
  559. /package/dist/{renderer-C2n-EHxg.mjs → renderer-B-BcgA6d.mjs} +0 -0
@@ -1,6 +1,6 @@
1
- import { Bt as parseCssColor, Lt as mixColors, Vt as parseCssGradient, ht as createVirtualMedia, l as Color, wt as getActiveMediaMetadata } from "./dist-CbG3QxDw.mjs";
2
- import { t as ColorSchema } from "./dist-BYqNNwsl.mjs";
3
- import { rt as signalRegistry } from "./dist-Cxi68OuY.mjs";
1
+ import { Bt as parseCssColor, Lt as mixColors, Vt as parseCssGradient, ht as createVirtualMedia, l as Color, wt as getActiveMediaMetadata } from "./dist-fjKpBYkc.mjs";
2
+ import { t as ColorSchema } from "./dist-BY0bIWgr.mjs";
3
+ import { $t as TypewriterAnimatorSchema, An as signalRegistry, Kt as TextPathOptionsSchema, ht as AdvancedTextAnimatorSchema, kt as KineticMarqueeConfigSchema, pt as AETextAnimatorSchema } from "./dist-Bun_TUvZ.mjs";
4
4
  import { z } from "zod";
5
5
  import { loadYoga } from "yoga-layout/load";
6
6
 
@@ -1725,2348 +1725,94 @@ function lintComposition(config) {
1725
1725
  return;
1726
1726
  }
1727
1727
  if (node.kind === "camera") return;
1728
- const is3D = Boolean(node.is3D) || typeof node.z === "number" && node.z !== 0;
1729
- if (is3D || node.kind === "model3d") has3D = true;
1730
- if (node.roughness !== void 0 || node.metallic !== void 0) pbrNodes.push(id);
1731
- if (node.kind === "text" && backdrop && !animates(node, ["fill", "color"])) {
1732
- const fg = solidColor(node.fill ?? node.color);
1733
- const behind = solidColor(node.background) ?? backdrop;
1734
- if (fg) {
1735
- const ratio = Color.contrast(fg, behind);
1736
- if (ratio < MIN_TEXT_CONTRAST) push("warning", "low_contrast_text", `Text '${id}' (${fg}) on ${behind} has contrast ${ratio.toFixed(2)}:1 (aim for ≥ ${MIN_TEXT_CONTRAST}; ${Color.readableOn(behind)} reads well).`, id);
1737
- }
1738
- }
1739
- if (atRoot && !is3D && node.position === "absolute" && typeof node.x === "number" && typeof node.y === "number" && typeof node.width === "number" && typeof node.height === "number" && !animates(node, [
1740
- "x",
1741
- "y",
1742
- "translateX",
1743
- "translateY",
1744
- "scale",
1745
- "rotation"
1746
- ])) {
1747
- const { x, y, width, height } = node;
1748
- if (x + width <= 0 || y + height <= 0 || x >= W || y >= H) push("warning", "offscreen_layer", `'${id}' sits entirely outside the ${W}×${H} canvas (x ${x}, y ${y}) and never moves in.`, id);
1749
- }
1750
- for (const t of tracksOf(node)) {
1751
- const kfs = t.keyframes ?? [];
1752
- if ((!t.source || t.source.type === "keyframe") && kfs.length >= 2 && kfs.every((k) => JSON.stringify(k.value) === JSON.stringify(kfs[0].value))) push("info", "static_track", `'${id}' animates \`${t.prop}\` but every keyframe holds ${JSON.stringify(kfs[0].value)}.`, id);
1753
- }
1754
- const ownBackdrop = solidColor(node.background) ?? backdrop;
1755
- const children = node.children;
1756
- const fullFrame = node.x === 0 && node.y === 0 && node.width === W && node.height === H;
1757
- visitLevel(children ?? [], ownBackdrop, atRoot && fullFrame);
1758
- };
1759
- const visitLevel = (nodes, backdrop, atRoot) => {
1760
- let known = backdrop;
1761
- for (const n of byZ(nodes)) {
1762
- visit(n, known, atRoot);
1763
- if (paints(n)) known = null;
1764
- }
1765
- };
1766
- const rootBackdrop = solidColor(config.backgroundColor) ?? null;
1767
- visitLevel(config.layout, rootBackdrop, true);
1768
- if (hasEnvironment && ambientLights.length > 0) push("info", "ambient_with_environment", `The environment already fills shadows with light; ambient light ${ambientLights.join(", ")} adds flat light on top (remove it, or lower it, if the scene looks washed out).`);
1769
- if (shadowLights.length > 1) push("info", "multiple_shadow_lights", `${shadowLights.length} lights cast shadows (${shadowLights.join(", ")}); only the first one does.`);
1770
- if (has3D && pbrNodes.length > 0 && !hasEnvironment) push("info", "pbr_without_environment", `roughness / metallic are set (${pbrNodes.slice(0, 3).join(", ")}${pbrNodes.length > 3 ? ", …" : ""}) but the scene has no Layer.environment(): add one for physically based shading, reflections and tone mapping.`);
1771
- return out;
1772
- }
1773
- const GEOMETRY = [
1774
- "x",
1775
- "y",
1776
- "width",
1777
- "height"
1778
- ];
1779
- function hoistOne(owner) {
1780
- const matte = owner.matte;
1781
- const { matte: _drop, ...rest } = owner;
1782
- const self = { ...rest };
1783
- if (Array.isArray(self.children)) self.children = hoistMattes(self.children);
1784
- if (!matte?.node) return [self];
1785
- const src = matte.node;
1786
- const id = src.id ?? `${String(owner.id)}__matte`;
1787
- const node = {
1788
- position: "absolute",
1789
- ...src,
1790
- id,
1791
- matteOf: String(owner.id),
1792
- matteMode: matte.mode ?? "alpha"
1793
- };
1794
- if (GEOMETRY.every((k) => src[k] === void 0)) {
1795
- for (const k of GEOMETRY) if (typeof owner[k] === "number") node[k] = owner[k];
1796
- }
1797
- node.startFrame = (typeof owner.startFrame === "number" ? owner.startFrame : 0) + (typeof src.startFrame === "number" ? src.startFrame : 0);
1798
- if (src.durationFrames === void 0 && owner.durationFrames !== void 0) node.durationFrames = owner.durationFrames;
1799
- if (Array.isArray(node.children)) node.children = hoistMattes(node.children);
1800
- self.matteId = id;
1801
- return [self, node];
1802
- }
1803
- /** Returns the tree with every `matte` turned into a sibling matte layer. */
1804
- function hoistMattes(nodes) {
1805
- return nodes.flatMap((n) => hoistOne(n));
1806
- }
1807
- /**
1808
- * Fluent Builder for Extended Text Animators.
1809
- */
1810
- var AdvancedTextAnimatorBuilder = class AdvancedTextAnimatorBuilder$1 {
1811
- name;
1812
- props = {};
1813
- selectors = [];
1814
- constructor(name) {
1815
- this.name = name;
1816
- }
1817
- static create(name) {
1818
- return new AdvancedTextAnimatorBuilder$1(name);
1819
- }
1820
- /** Directional Skew */
1821
- skew(angleDeg, axisDeg = 0) {
1822
- this.props.skew = angleDeg;
1823
- this.props.skewAxis = axisDeg;
1824
- return this;
1825
- }
1826
- /** Anchor Point Grouping and Preset Pivot */
1827
- anchor(preset, grouping = "character", offsetX = 0, offsetY = 0) {
1828
- this.props.anchor = {
1829
- grouping,
1830
- preset,
1831
- anchorX: .5,
1832
- anchorY: .5,
1833
- offsetX,
1834
- offsetY
1835
- };
1836
- return this;
1837
- }
1838
- /** Custom Anchor Point Coordinates (0 to 1 normalized) */
1839
- anchorNormalized(ax, ay, grouping = "character") {
1840
- this.props.anchor = {
1841
- grouping,
1842
- preset: "custom",
1843
- anchorX: ax,
1844
- anchorY: ay,
1845
- offsetX: 0,
1846
- offsetY: 0
1847
- };
1848
- return this;
1849
- }
1850
- /** 3D Spatial Z-Depth */
1851
- translateZ(zPixels) {
1852
- this.props.translateZ = zPixels;
1853
- return this;
1854
- }
1855
- /** 3D Tilts */
1856
- tilt3D(rx = 0, ry = 0, rz = 0) {
1857
- this.props.rotationX = rx;
1858
- this.props.rotationY = ry;
1859
- this.props.rotationZ = rz;
1860
- return this;
1861
- }
1862
- /** 3D Rotation along X axis */
1863
- rotationX(deg) {
1864
- this.props.rotationX = deg;
1865
- return this;
1866
- }
1867
- /** 3D Rotation along Y axis */
1868
- rotationY(deg) {
1869
- this.props.rotationY = deg;
1870
- return this;
1871
- }
1872
- /** 3D Rotation along Z axis */
1873
- rotationZ(deg) {
1874
- this.props.rotationZ = deg;
1875
- return this;
1876
- }
1877
- /** 3D Volumetric Formations */
1878
- volumetricFormation(mode = "cylinder", radius = 300, pitch = 120, totalAngle = 360, perspective = 1200, axis = "y") {
1879
- this.props.formation = {
1880
- mode,
1881
- radius,
1882
- pitch,
1883
- totalAngle,
1884
- perspective,
1885
- axis
1886
- };
1887
- return this;
1888
- }
1889
- /** Dynamic Line Spacing (Leading) */
1890
- lineSpacing(extraLeadingPixels, lineAnchor = 0) {
1891
- this.props.lineSpacing = extraLeadingPixels;
1892
- this.props.lineAnchor = lineAnchor;
1893
- return this;
1894
- }
1895
- /** Normalized Line Anchor (0=top, 0.5=center, 1=bottom) */
1896
- lineAnchor(anchor) {
1897
- this.props.lineAnchor = anchor;
1898
- return this;
1899
- }
1900
- /** Inertial Spring Settling Physics */
1901
- spring(stiffness = 180, damping = 12, mass = 1, initialVelocity = 0) {
1902
- this.props.spring = {
1903
- stiffness,
1904
- damping,
1905
- mass,
1906
- initialVelocity,
1907
- overshootMultiplier: 1
1908
- };
1909
- return this;
1910
- }
1911
- /** Dynamic Stroke & Wireframe Properties */
1912
- stroke(widthPixels, color = "#ffffff", fillOpacity = 1) {
1913
- this.props.stroke = {
1914
- strokeWidth: widthPixels,
1915
- strokeColor: color,
1916
- strokeAlign: "center",
1917
- fillOpacity,
1918
- dashOffset: 0
1919
- };
1920
- return this;
1921
- }
1922
- /** Variable Font Axes */
1923
- variableFont(axes) {
1924
- this.props.variableAxes = axes;
1925
- return this;
1926
- }
1927
- /** Chromatic Aberration / Cyberpunk Glitch */
1928
- chromaticGlitch(redShiftX, redShiftY = 0, blueShiftX = -redShiftX, blueShiftY = 0) {
1929
- this.props.chromaticGlitch = {
1930
- redShiftX,
1931
- redShiftY,
1932
- blueShiftX,
1933
- blueShiftY,
1934
- sliceProbability: 0,
1935
- sliceAmplitude: 0
1936
- };
1937
- return this;
1938
- }
1939
- /** Multi-Band Audio Spectrum Equalizer */
1940
- audioSpectrum(signalChannel, minFreqHz = 60, maxFreqHz = 16e3, maxScale = 2.5) {
1941
- this.props.audioSpectrum = {
1942
- signalChannel,
1943
- minFreqHz,
1944
- maxFreqHz,
1945
- scaleAxis: "scaleY",
1946
- minScale: .2,
1947
- maxScale,
1948
- peakDecay: .8
1949
- };
1950
- return this;
1951
- }
1952
- /** Long Shadow Extrusion */
1953
- longShadow(angle = 45, length = 40, color = "#000000", startOpacity = .8, endOpacity = 0, steps = 16) {
1954
- this.props.longShadow = {
1955
- angle,
1956
- length,
1957
- color,
1958
- startOpacity,
1959
- endOpacity,
1960
- steps
1961
- };
1962
- return this;
1963
- }
1964
- /** Particle Dust / Quantum Dissolve */
1965
- particleDissolve(progress = 0, dispersalAngle = 90, maxDisplacement = 120) {
1966
- this.props.particleDissolve = {
1967
- progress,
1968
- dispersalAngle,
1969
- maxDisplacement,
1970
- turbulence: .5,
1971
- particleSize: 2
1972
- };
1973
- return this;
1974
- }
1975
- /** Add Expression Selector */
1976
- addExpressionSelector(expression, mode = "add") {
1977
- this.selectors.push({
1978
- type: "expression",
1979
- expression,
1980
- mode,
1981
- amount: 1
1982
- });
1983
- return this;
1984
- }
1985
- /** Alias for addExpressionSelector */
1986
- expressionSelector(expression, mode = "add") {
1987
- return this.addExpressionSelector(expression, mode);
1988
- }
1989
- /** Standard 2D Transforms */
1990
- x(v) {
1991
- this.props.x = v;
1992
- return this;
1993
- }
1994
- y(v) {
1995
- this.props.y = v;
1996
- return this;
1997
- }
1998
- scale(v) {
1999
- this.props.scale = v;
2000
- return this;
2001
- }
2002
- scaleX(v) {
2003
- this.props.scaleX = v;
2004
- return this;
2005
- }
2006
- scaleY(v) {
2007
- this.props.scaleY = v;
2008
- return this;
2009
- }
2010
- rotation(deg) {
2011
- this.props.rotation = deg;
2012
- return this;
2013
- }
2014
- opacity(v) {
2015
- this.props.opacity = v;
2016
- return this;
2017
- }
2018
- blur(v) {
2019
- this.props.blur = v;
2020
- return this;
2021
- }
2022
- fillColor(hex) {
2023
- this.props.fillColor = hex;
2024
- return this;
2025
- }
2026
- build() {
2027
- return {
2028
- name: this.name,
2029
- selectors: this.selectors,
2030
- props: this.props
2031
- };
2032
- }
2033
- };
2034
- /**
2035
- * @file packages/compositions/src/program/text-animations/advanced-types.ts
2036
- * Data contracts and Zod schemas for Advanced Motion Design & After Effects Extended Typography Engine.
2037
- */
2038
- const AnchorGroupingSchema = z.enum([
2039
- "character",
2040
- "word",
2041
- "line",
2042
- "all"
2043
- ]);
2044
- const AnchorPresetSchema = z.enum([
2045
- "center",
2046
- "baseline",
2047
- "bottom_left",
2048
- "bottom_center",
2049
- "bottom_right",
2050
- "top_left",
2051
- "top_center",
2052
- "top_right",
2053
- "custom"
2054
- ]);
2055
- const TextAnchorConfigSchema = z.object({
2056
- grouping: AnchorGroupingSchema.default("character"),
2057
- preset: AnchorPresetSchema.default("center"),
2058
- anchorX: z.number().default(.5),
2059
- anchorY: z.number().default(.5),
2060
- offsetX: z.number().default(0),
2061
- offsetY: z.number().default(0)
2062
- });
2063
- const SkewPropertiesSchema = z.object({
2064
- skew: z.number().min(-90).max(90),
2065
- skewAxis: z.number().default(0)
2066
- });
2067
- const LineSpacingDynamicsSchema = z.object({
2068
- lineSpacing: z.number(),
2069
- lineAnchor: z.number().min(0).max(1).default(0)
2070
- });
2071
- const VolumetricFormationModeSchema = z.enum([
2072
- "planar",
2073
- "vortex",
2074
- "cylinder",
2075
- "helix"
2076
- ]);
2077
- const VolumetricFormationConfigSchema = z.object({
2078
- mode: VolumetricFormationModeSchema.default("planar"),
2079
- radius: z.number().default(300),
2080
- pitch: z.number().default(120),
2081
- totalAngle: z.number().default(360),
2082
- axis: z.enum([
2083
- "x",
2084
- "y",
2085
- "z"
2086
- ]).default("y"),
2087
- perspective: z.number().positive().default(1200)
2088
- });
2089
- const Spatial3DPropertiesSchema = z.object({
2090
- translateZ: z.number().optional(),
2091
- rotationX: z.number().optional(),
2092
- rotationY: z.number().optional(),
2093
- rotationZ: z.number().optional(),
2094
- formation: VolumetricFormationConfigSchema.optional()
2095
- });
2096
- const SpringPhysicsSchema = z.object({
2097
- stiffness: z.number().positive().default(180),
2098
- damping: z.number().positive().default(12),
2099
- mass: z.number().positive().default(1),
2100
- initialVelocity: z.number().default(0),
2101
- overshootMultiplier: z.number().min(.5).max(3).default(1)
2102
- });
2103
- const ExpressionSelectorSchema = z.object({
2104
- type: z.literal("expression"),
2105
- name: z.string().optional(),
2106
- expression: z.string(),
2107
- mode: z.enum([
2108
- "add",
2109
- "subtract",
2110
- "intersect",
2111
- "min",
2112
- "max",
2113
- "difference"
2114
- ]).default("add"),
2115
- amount: z.number().default(1)
2116
- });
2117
- const DynamicStrokePropertiesSchema = z.object({
2118
- strokeWidth: z.number().min(0).default(0),
2119
- strokeColor: z.string().default("#ffffff"),
2120
- strokeAlign: z.enum([
2121
- "center",
2122
- "inside",
2123
- "outside"
2124
- ]).default("center"),
2125
- fillOpacity: z.number().min(0).max(1).default(1),
2126
- dashArray: z.tuple([z.number(), z.number()]).optional(),
2127
- dashOffset: z.number().default(0)
2128
- });
2129
- const KineticMarqueeConfigSchema = z.object({
2130
- direction: z.enum([
2131
- "left",
2132
- "right",
2133
- "up",
2134
- "down"
2135
- ]).default("left"),
2136
- velocity: z.number().default(120),
2137
- loop: z.boolean().default(true),
2138
- repeatGap: z.number().default(80),
2139
- snap: z.object({
2140
- enabled: z.boolean().default(false),
2141
- granularity: z.enum([
2142
- "character",
2143
- "word",
2144
- "line"
2145
- ]).default("word"),
2146
- stopIndex: z.number().default(0),
2147
- decelEase: z.string().default("cubic.out")
2148
- }).optional()
2149
- });
2150
- const VariableFontAxesSchema = z.object({
2151
- weight: z.number().min(100).max(1e3).optional(),
2152
- width: z.number().min(50).max(200).optional(),
2153
- slant: z.number().min(-25).max(25).optional(),
2154
- italic: z.number().min(0).max(1).optional(),
2155
- opticalSize: z.number().min(6).max(144).optional()
2156
- });
2157
- const ChromaticGlitchConfigSchema = z.object({
2158
- redShiftX: z.number().default(0),
2159
- redShiftY: z.number().default(0),
2160
- blueShiftX: z.number().default(0),
2161
- blueShiftY: z.number().default(0),
2162
- sliceProbability: z.number().min(0).max(1).default(0),
2163
- sliceAmplitude: z.number().default(0)
2164
- });
2165
- const AudioSpectrumTypographySchema = z.object({
2166
- signalChannel: z.string(),
2167
- minFreqHz: z.number().default(60),
2168
- maxFreqHz: z.number().default(16e3),
2169
- scaleAxis: z.enum([
2170
- "scaleY",
2171
- "scaleX",
2172
- "scale",
2173
- "y"
2174
- ]).default("scaleY"),
2175
- minScale: z.number().default(.2),
2176
- maxScale: z.number().default(2.5),
2177
- peakDecay: z.number().min(0).max(.99).default(.8)
2178
- });
2179
- const LongShadowConfigSchema = z.object({
2180
- angle: z.number().default(45),
2181
- length: z.number().min(0).default(0),
2182
- color: z.string().default("#000000"),
2183
- startOpacity: z.number().min(0).max(1).default(.8),
2184
- endOpacity: z.number().min(0).max(1).default(0),
2185
- steps: z.number().int().min(4).max(64).default(16)
2186
- });
2187
- const ParticleDissolveConfigSchema = z.object({
2188
- progress: z.number().min(0).max(1).default(0),
2189
- dispersalAngle: z.number().default(90),
2190
- maxDisplacement: z.number().default(120),
2191
- turbulence: z.number().default(.5),
2192
- particleSize: z.number().default(2)
2193
- });
2194
- const ExtendedGlyphPropertiesSchema = z.object({
2195
- x: z.number().optional(),
2196
- y: z.number().optional(),
2197
- translateZ: z.number().optional(),
2198
- scale: z.number().optional(),
2199
- scaleX: z.number().optional(),
2200
- scaleY: z.number().optional(),
2201
- rotation: z.number().optional(),
2202
- rotationX: z.number().optional(),
2203
- rotationY: z.number().optional(),
2204
- rotationZ: z.number().optional(),
2205
- formation: VolumetricFormationConfigSchema.optional(),
2206
- skew: z.number().optional(),
2207
- skewAxis: z.number().optional(),
2208
- tracking: z.number().optional(),
2209
- lineSpacing: z.number().optional(),
2210
- lineAnchor: z.number().optional(),
2211
- anchor: TextAnchorConfigSchema.optional(),
2212
- opacity: z.number().optional(),
2213
- blur: z.number().optional(),
2214
- fillColor: z.string().optional(),
2215
- stroke: DynamicStrokePropertiesSchema.optional(),
2216
- variableAxes: VariableFontAxesSchema.optional(),
2217
- chromaticGlitch: ChromaticGlitchConfigSchema.optional(),
2218
- longShadow: LongShadowConfigSchema.optional(),
2219
- particleDissolve: ParticleDissolveConfigSchema.optional(),
2220
- audioSpectrum: AudioSpectrumTypographySchema.optional(),
2221
- spring: SpringPhysicsSchema.optional()
2222
- });
2223
- const AdvancedTextAnimatorSchema = z.object({
2224
- name: z.string().default("AdvancedAnimator"),
2225
- selectors: z.array(z.record(z.string(), z.unknown())).default([]),
2226
- props: ExtendedGlyphPropertiesSchema
2227
- });
2228
- /**
2229
- * @file packages/compositions/src/program/text-animations/types.ts
2230
- * Data contracts and Zod schemas for After Effects Parity Text Animation Engine.
2231
- */
2232
- const Vec2Schema = z.object({
2233
- x: z.number(),
2234
- y: z.number()
2235
- });
2236
- const CubicBezierSegmentSchema = z.object({
2237
- p0: Vec2Schema,
2238
- p1: Vec2Schema,
2239
- p2: Vec2Schema,
2240
- p3: Vec2Schema
2241
- });
2242
- const TextPathSourceSchema = z.discriminatedUnion("type", [
2243
- z.object({
2244
- type: z.literal("svg"),
2245
- d: z.string().min(1, "SVG path string cannot be empty")
2246
- }),
2247
- z.object({
2248
- type: z.literal("bezier"),
2249
- segments: z.array(CubicBezierSegmentSchema).min(1)
2250
- }),
2251
- z.object({
2252
- type: z.literal("ellipse"),
2253
- cx: z.number(),
2254
- cy: z.number(),
2255
- rx: z.number().positive(),
2256
- ry: z.number().positive(),
2257
- startAngleDeg: z.number().default(0),
2258
- endAngleDeg: z.number().default(360)
2259
- }),
2260
- z.object({
2261
- type: z.literal("wave"),
2262
- startX: z.number(),
2263
- startY: z.number(),
2264
- length: z.number().positive(),
2265
- amplitude: z.number(),
2266
- frequency: z.number().positive(),
2267
- phaseDeg: z.number().default(0)
2268
- })
2269
- ]);
2270
- const TextPathOptionsSchema = z.object({
2271
- path: TextPathSourceSchema,
2272
- firstMargin: z.number().default(0),
2273
- lastMargin: z.number().default(0),
2274
- reversePath: z.boolean().default(false),
2275
- perpendicularToPath: z.boolean().default(true),
2276
- forceAlignment: z.boolean().default(false),
2277
- loop: z.boolean().default(false),
2278
- baselineOffset: z.enum([
2279
- "baseline",
2280
- "center",
2281
- "ascender",
2282
- "descender"
2283
- ]).default("baseline"),
2284
- baselineShift: z.number().default(0)
2285
- });
2286
- const TextCursorStyleSchema = z.enum([
2287
- "bar",
2288
- "underscore",
2289
- "block",
2290
- "custom"
2291
- ]);
2292
- const TextCursorConfigSchema = z.object({
2293
- enabled: z.boolean().default(true),
2294
- style: TextCursorStyleSchema.default("bar"),
2295
- customChar: z.string().default("|"),
2296
- color: z.string().optional(),
2297
- blinkFrequency: z.number().min(0).default(2),
2298
- hideOnComplete: z.boolean().default(false),
2299
- width: z.number().positive().default(2.5),
2300
- spacing: z.number().default(3)
2301
- });
2302
- const TypingCadenceSchema = z.discriminatedUnion("mode", [z.object({ mode: z.literal("constant") }), z.object({
2303
- mode: z.literal("human"),
2304
- jitter: z.number().min(0).max(1).default(.35),
2305
- commaPauseMultiplier: z.number().min(1).default(3),
2306
- sentencePauseMultiplier: z.number().min(1).default(5.5),
2307
- paragraphPauseMultiplier: z.number().min(1).default(7)
2308
- })]);
2309
- const TextScrambleConfigSchema = z.object({
2310
- enabled: z.boolean().default(false),
2311
- charset: z.enum([
2312
- "ascii",
2313
- "alphanumeric",
2314
- "matrix",
2315
- "binary",
2316
- "hex",
2317
- "custom"
2318
- ]).default("alphanumeric"),
2319
- customCharset: z.string().optional(),
2320
- scrambleFramesPerChar: z.number().int().min(1).default(8),
2321
- highlightProbability: z.number().min(0).max(1).default(.25),
2322
- scrambleColor: z.string().optional()
2323
- });
2324
- const TypewriterAnimatorSchema = z.object({
2325
- granularity: z.enum([
2326
- "character",
2327
- "word",
2328
- "line"
2329
- ]).default("character"),
2330
- cursor: TextCursorConfigSchema.default({
2331
- enabled: true,
2332
- style: "bar",
2333
- customChar: "|",
2334
- blinkFrequency: 2,
2335
- hideOnComplete: false,
2336
- width: 2.5,
2337
- spacing: 3
2338
- }),
2339
- cadence: TypingCadenceSchema.default({
2340
- mode: "human",
2341
- jitter: .35,
2342
- commaPauseMultiplier: 3,
2343
- sentencePauseMultiplier: 5.5,
2344
- paragraphPauseMultiplier: 7
2345
- }),
2346
- scramble: TextScrambleConfigSchema.default({
2347
- enabled: false,
2348
- charset: "alphanumeric",
2349
- scrambleFramesPerChar: 8,
2350
- highlightProbability: .25
2351
- }),
2352
- soundSync: z.boolean().default(false)
2353
- });
2354
- const SelectorBasedOnSchema = z.enum([
2355
- "characters",
2356
- "characters_excluding_spaces",
2357
- "words",
2358
- "lines"
2359
- ]);
2360
- const SelectorUnitsSchema = z.enum(["percentage", "index"]);
2361
- const SelectorShapeSchema = z.enum([
2362
- "square",
2363
- "ramp_up",
2364
- "ramp_down",
2365
- "triangle",
2366
- "round",
2367
- "smooth"
2368
- ]);
2369
- const SelectorModeSchema = z.enum([
2370
- "add",
2371
- "subtract",
2372
- "intersect",
2373
- "min",
2374
- "max",
2375
- "difference"
2376
- ]);
2377
- const TextRangeSelectorSchema = z.object({
2378
- type: z.literal("range"),
2379
- start: z.number().default(0),
2380
- end: z.number().default(1),
2381
- offset: z.number().default(0),
2382
- units: SelectorUnitsSchema.default("percentage"),
2383
- basedOn: SelectorBasedOnSchema.default("characters"),
2384
- shape: SelectorShapeSchema.default("square"),
2385
- mode: SelectorModeSchema.default("add"),
2386
- amount: z.number().min(-1).max(1).default(1),
2387
- easeHigh: z.number().min(-1).max(1).default(0),
2388
- easeLow: z.number().min(-1).max(1).default(0),
2389
- randomizeOrder: z.boolean().default(false),
2390
- randomSeed: z.number().int().default(12345)
2391
- });
2392
- const TextWigglySelectorSchema = z.object({
2393
- type: z.literal("wiggly"),
2394
- wigglesPerSecond: z.number().positive().default(2),
2395
- correlation: z.number().min(0).max(1).default(.5),
2396
- temporalPhaseDeg: z.number().default(0),
2397
- spatialPhaseDeg: z.number().default(0),
2398
- minAmount: z.number().min(-1).max(1).default(-1),
2399
- maxAmount: z.number().min(-1).max(1).default(1),
2400
- randomSeed: z.number().int().default(42),
2401
- basedOn: SelectorBasedOnSchema.default("characters"),
2402
- mode: SelectorModeSchema.default("intersect")
2403
- });
2404
- const TextSignalSelectorSchema = z.object({
2405
- type: z.literal("signal"),
2406
- signalId: z.string(),
2407
- multiplier: z.number().default(1),
2408
- offset: z.number().default(0),
2409
- phaseSpread: z.number().default(0),
2410
- basedOn: SelectorBasedOnSchema.default("characters"),
2411
- mode: SelectorModeSchema.default("add")
2412
- });
2413
- const TextSelectorSchema = z.discriminatedUnion("type", [
2414
- TextRangeSelectorSchema,
2415
- TextWigglySelectorSchema,
2416
- TextSignalSelectorSchema
2417
- ]);
2418
- const AnimatableGlyphPropsSchema = z.object({
2419
- x: z.number().optional(),
2420
- y: z.number().optional(),
2421
- z: z.number().optional(),
2422
- scale: z.number().optional(),
2423
- scaleX: z.number().optional(),
2424
- scaleY: z.number().optional(),
2425
- rotation: z.number().optional(),
2426
- rotationX: z.number().optional(),
2427
- rotationY: z.number().optional(),
2428
- skew: z.number().optional(),
2429
- skewAxis: z.number().optional(),
2430
- tracking: z.number().optional(),
2431
- lineSpacing: z.number().optional(),
2432
- opacity: z.number().min(0).max(1).optional(),
2433
- fillColor: z.string().optional(),
2434
- strokeColor: z.string().optional(),
2435
- strokeWidth: z.number().min(0).optional(),
2436
- blur: z.number().min(0).optional(),
2437
- characterOffset: z.number().int().optional()
2438
- });
2439
- const GlyphAnchorGroupingSchema = z.enum([
2440
- "character",
2441
- "word",
2442
- "line",
2443
- "all"
2444
- ]);
2445
- const GlyphAnchorPointSchema = z.object({
2446
- grouping: GlyphAnchorGroupingSchema.default("character"),
2447
- anchorX: z.number().default(.5),
2448
- anchorY: z.number().default(.8)
2449
- });
2450
- const AETextAnimatorSchema = z.object({
2451
- name: z.string().default("Animator"),
2452
- selectors: z.array(TextSelectorSchema).min(1),
2453
- props: AnimatableGlyphPropsSchema,
2454
- anchor: GlyphAnchorPointSchema.default({
2455
- grouping: "character",
2456
- anchorX: .5,
2457
- anchorY: .8
2458
- })
2459
- });
2460
- const EnhancedTextNodeSchema = z.object({
2461
- text: z.string(),
2462
- fontFamily: z.string().default("Inter"),
2463
- fontSize: z.number().positive().default(24),
2464
- fontWeight: z.union([z.number(), z.string()]).default(400),
2465
- fill: z.string().default("#ffffff"),
2466
- letterSpacing: z.number().default(0),
2467
- lineHeight: z.number().positive().default(1.2),
2468
- textAlign: z.enum([
2469
- "left",
2470
- "center",
2471
- "right"
2472
- ]).default("left"),
2473
- pathOptions: TextPathOptionsSchema.optional(),
2474
- typewriter: TypewriterAnimatorSchema.optional(),
2475
- animators: z.array(AETextAnimatorSchema).default([])
2476
- });
2477
- /**
2478
- * @file packages/compositions/src/program/text-animations/builder.ts
2479
- * Fluent builders for Path-Following Text and After Effects Text Animators.
2480
- */
2481
- /**
2482
- * Fluent builder for creating Path-Following Text configurations.
2483
- */
2484
- var TextPathBuilder = class TextPathBuilder$1 {
2485
- options = {
2486
- firstMargin: 0,
2487
- lastMargin: 0,
2488
- reversePath: false,
2489
- perpendicularToPath: true,
2490
- forceAlignment: false,
2491
- loop: false,
2492
- baselineOffset: "baseline",
2493
- baselineShift: 0
2494
- };
2495
- static fromSvg(svgPath) {
2496
- const builder = new TextPathBuilder$1();
2497
- builder.options.path = {
2498
- type: "svg",
2499
- d: svgPath
2500
- };
2501
- return builder;
2502
- }
2503
- static fromBezier(segments) {
2504
- const builder = new TextPathBuilder$1();
2505
- builder.options.path = {
2506
- type: "bezier",
2507
- segments
2508
- };
2509
- return builder;
2510
- }
2511
- static fromCurve(curve) {
2512
- return TextPathBuilder$1.fromBezier([curve]);
2513
- }
2514
- static circularBadge(cx, cy, radius) {
2515
- const builder = new TextPathBuilder$1();
2516
- builder.options.path = {
2517
- type: "ellipse",
2518
- cx,
2519
- cy,
2520
- rx: radius,
2521
- ry: radius,
2522
- startAngleDeg: 0,
2523
- endAngleDeg: 360
2524
- };
2525
- builder.options.loop = true;
2526
- return builder;
2527
- }
2528
- static ellipse(cx, cy, rx, ry, startAngleDeg = 0, endAngleDeg = 360) {
2529
- const builder = new TextPathBuilder$1();
2530
- builder.options.path = {
2531
- type: "ellipse",
2532
- cx,
2533
- cy,
2534
- rx,
2535
- ry,
2536
- startAngleDeg,
2537
- endAngleDeg
2538
- };
2539
- builder.options.loop = Math.abs(endAngleDeg - startAngleDeg) >= 360;
2540
- return builder;
2541
- }
2542
- static wave(startX, startY, length, amplitude, frequency, phaseDeg = 0) {
2543
- const builder = new TextPathBuilder$1();
2544
- builder.options.path = {
2545
- type: "wave",
2546
- startX,
2547
- startY,
2548
- length,
2549
- amplitude,
2550
- frequency,
2551
- phaseDeg
2552
- };
2553
- return builder;
2554
- }
2555
- firstMargin(margin) {
2556
- this.options.firstMargin = margin;
2557
- return this;
2558
- }
2559
- lastMargin(margin) {
2560
- this.options.lastMargin = margin;
2561
- return this;
2562
- }
2563
- reversePath(reverse) {
2564
- this.options.reversePath = reverse;
2565
- return this;
2566
- }
2567
- perpendicularToPath(perpendicular) {
2568
- this.options.perpendicularToPath = perpendicular;
2569
- return this;
2570
- }
2571
- forceAlignment(force) {
2572
- this.options.forceAlignment = force;
2573
- return this;
2574
- }
2575
- loop(isLoop) {
2576
- this.options.loop = isLoop;
2577
- return this;
2578
- }
2579
- baselineOffset(offset) {
2580
- this.options.baselineOffset = offset;
2581
- return this;
2582
- }
2583
- baselineShift(shiftPixels) {
2584
- this.options.baselineShift = shiftPixels;
2585
- return this;
2586
- }
2587
- build() {
2588
- return TextPathOptionsSchema.parse(this.options);
2589
- }
2590
- };
2591
- /**
2592
- * Fluent builder for After Effects Range, Wiggly, and Signal Animators.
2593
- */
2594
- var TextAnimatorBuilder = class TextAnimatorBuilder$1 {
2595
- name = "Animator";
2596
- selectors = [];
2597
- props = {};
2598
- anchor = {
2599
- grouping: "character",
2600
- anchorX: .5,
2601
- anchorY: .8
2602
- };
2603
- static create(name) {
2604
- const builder = new TextAnimatorBuilder$1();
2605
- builder.name = name;
2606
- return builder;
2607
- }
2608
- /** Adds an After Effects Range Selector */
2609
- addRangeSelector(config) {
2610
- const rawHigh = config.easeHigh ?? 0;
2611
- const easeHigh = Math.abs(rawHigh) > 1 ? rawHigh / 100 : rawHigh;
2612
- const rawLow = config.easeLow ?? 0;
2613
- const easeLow = Math.abs(rawLow) > 1 ? rawLow / 100 : rawLow;
2614
- this.selectors.push({
2615
- type: "range",
2616
- start: config.start ?? 0,
2617
- end: config.end ?? 1,
2618
- offset: config.offset ?? 0,
2619
- units: "percentage",
2620
- basedOn: config.basedOn ?? "characters",
2621
- shape: config.shape ?? "smooth",
2622
- mode: config.mode ?? "add",
2623
- amount: 1,
2624
- easeHigh: Math.max(-1, Math.min(1, easeHigh)),
2625
- easeLow: Math.max(-1, Math.min(1, easeLow)),
2626
- randomizeOrder: config.randomizeOrder ?? false,
2627
- randomSeed: config.randomSeed ?? 12345
2628
- });
2629
- return this;
2630
- }
2631
- /** Adds an After Effects Wiggly Selector for procedural organic flutter */
2632
- addWigglySelector(config) {
2633
- this.selectors.push({
2634
- type: "wiggly",
2635
- wigglesPerSecond: config.wigglesPerSecond ?? 2,
2636
- correlation: config.correlation ?? .5,
2637
- temporalPhaseDeg: 0,
2638
- spatialPhaseDeg: 0,
2639
- minAmount: config.minAmount ?? -1,
2640
- maxAmount: config.maxAmount ?? 1,
2641
- randomSeed: config.randomSeed ?? 42,
2642
- basedOn: "characters",
2643
- mode: config.mode ?? "intersect"
2644
- });
2645
- return this;
2646
- }
2647
- /** Adds a reactive signal selector */
2648
- addSignalSelector(signalId, multiplier = 1, phaseSpread = 0, offset = 0, mode = "add") {
2649
- this.selectors.push({
2650
- type: "signal",
2651
- signalId,
2652
- multiplier,
2653
- offset,
2654
- phaseSpread,
2655
- basedOn: "characters",
2656
- mode
2657
- });
2658
- return this;
2659
- }
2660
- x(pixels) {
2661
- this.props.x = pixels;
2662
- return this;
2663
- }
2664
- y(pixels) {
2665
- this.props.y = pixels;
2666
- return this;
2667
- }
2668
- z(pixels) {
2669
- this.props.z = pixels;
2670
- return this;
2671
- }
2672
- scale(scaleValue) {
2673
- this.props.scale = scaleValue;
2674
- return this;
2675
- }
2676
- scaleX(scaleValue) {
2677
- this.props.scaleX = scaleValue;
2678
- return this;
2679
- }
2680
- scaleY(scaleValue) {
2681
- this.props.scaleY = scaleValue;
2682
- return this;
2683
- }
2684
- rotation(degrees) {
2685
- this.props.rotation = degrees;
2686
- return this;
2687
- }
2688
- rotationX(degrees) {
2689
- this.props.rotationX = degrees;
2690
- return this;
2691
- }
2692
- rotationY(degrees) {
2693
- this.props.rotationY = degrees;
2694
- return this;
2695
- }
2696
- skew(degrees) {
2697
- this.props.skew = degrees;
2698
- return this;
2699
- }
2700
- skewAxis(degrees) {
2701
- this.props.skewAxis = degrees;
2702
- return this;
2703
- }
2704
- opacity(value) {
2705
- this.props.opacity = value;
2706
- return this;
2707
- }
2708
- blur(pixels) {
2709
- this.props.blur = pixels;
2710
- return this;
2711
- }
2712
- fill(colorHex) {
2713
- return this.fillColor(colorHex);
2714
- }
2715
- fillColor(colorHex) {
2716
- this.props.fillColor = colorHex;
2717
- return this;
2718
- }
2719
- strokeColor(colorHex) {
2720
- this.props.strokeColor = colorHex;
2721
- return this;
2722
- }
2723
- strokeWidth(pixels) {
2724
- this.props.strokeWidth = pixels;
2725
- return this;
2726
- }
2727
- tracking(spacingPixels) {
2728
- this.props.tracking = spacingPixels;
2729
- return this;
2730
- }
2731
- lineSpacing(spacingPixels) {
2732
- this.props.lineSpacing = spacingPixels;
2733
- return this;
2734
- }
2735
- characterOffset(offset) {
2736
- this.props.characterOffset = offset;
2737
- return this;
2738
- }
2739
- anchorGrouping(grouping, anchorX = .5, anchorY = .8) {
2740
- this.anchor = {
2741
- grouping,
2742
- anchorX,
2743
- anchorY
2744
- };
2745
- return this;
2746
- }
2747
- build() {
2748
- return AETextAnimatorSchema.parse({
2749
- name: this.name,
2750
- selectors: this.selectors,
2751
- props: this.props,
2752
- anchor: this.anchor
2753
- });
2754
- }
2755
- };
2756
- /**
2757
- * Evaluates closed-form underdamped harmonic oscillator for spring physics:
2758
- *
2759
- * x(t) = target + (x0 - target) * exp(-zeta * omega_n * t) *
2760
- * [ cos(omega_d * t) + (zeta / sqrt(1 - zeta^2)) * sin(omega_d * t) ]
2761
- *
2762
- * @param t Time in seconds since excitation
2763
- * @param stiffness Spring stiffness (k)
2764
- * @param damping Damping coefficient (c)
2765
- * @param mass Mass of glyph (m)
2766
- * @param initialVelocity Initial velocity (v0)
2767
- * @returns Settled scalar progress in [0, 1] with overshoot
2768
- */
2769
- function evaluateSpringProgress(t, stiffness = 180, damping = 12, mass = 1, initialVelocity = 0) {
2770
- if (t <= 0) return 0;
2771
- const omega_n = Math.sqrt(Math.max(1e-4, stiffness) / Math.max(1e-4, mass));
2772
- const zeta = damping / (2 * Math.sqrt(Math.max(1e-4, stiffness * mass)));
2773
- if (zeta < 1) {
2774
- const omega_d = omega_n * Math.sqrt(1 - zeta * zeta);
2775
- const decay = Math.exp(-zeta * omega_n * t);
2776
- const c1 = -1;
2777
- const c2 = (initialVelocity - zeta * omega_n * -1) / Math.max(1e-6, omega_d);
2778
- const displacement = decay * (c1 * Math.cos(omega_d * t) + c2 * Math.sin(omega_d * t));
2779
- return Math.min(2, Math.max(-1, 1 + displacement));
2780
- } else if (Math.abs(zeta - 1) < 1e-4) {
2781
- const decay = Math.exp(-omega_n * t);
2782
- return 1 + (-1 + (initialVelocity - omega_n) * t) * decay;
2783
- } else {
2784
- const s1 = -omega_n * (zeta - Math.sqrt(zeta * zeta - 1));
2785
- const s2 = -omega_n * (zeta + Math.sqrt(zeta * zeta - 1));
2786
- const c1 = (initialVelocity + s2) / Math.max(1e-6, s1 - s2);
2787
- const c2 = -1 - c1;
2788
- return 1 + (c1 * Math.exp(s1 * t) + c2 * Math.exp(s2 * t));
2789
- }
2790
- }
2791
- /**
2792
- * Evaluates 2D Directional Skew matrix components:
2793
- *
2794
- * S(theta, phi) = R(phi) * [ 1 tan(theta) ] * R(-phi)
2795
- * [ 0 1 ]
2796
- *
2797
- * @param skewDeg Skew angle in degrees
2798
- * @param skewAxisDeg Skew axis in degrees
2799
- * @returns 2x2 affine shear matrix components [m00, m01, m10, m11]
2800
- */
2801
- function evaluateSkewMatrix(skewDeg, skewAxisDeg = 0) {
2802
- if (skewDeg === 0) return [
2803
- 1,
2804
- 0,
2805
- 0,
2806
- 1
2807
- ];
2808
- const theta = skewDeg * Math.PI / 180;
2809
- const phi = skewAxisDeg * Math.PI / 180;
2810
- const cosPhi = Math.cos(phi);
2811
- const sinPhi = Math.sin(phi);
2812
- const tanTheta = Math.tan(theta);
2813
- return [
2814
- 1 - tanTheta * cosPhi * sinPhi,
2815
- tanTheta * cosPhi * cosPhi,
2816
- -tanTheta * sinPhi * sinPhi,
2817
- 1 + tanTheta * sinPhi * cosPhi
2818
- ];
2819
- }
2820
- /**
2821
- * Computes anchor pivot coordinates relative to glyph bounding box:
2822
- *
2823
- * @param bbox Glyph bounding box { width, height, ascender, descender }
2824
- * @param config Text anchor configuration
2825
- * @returns Pivot offset (px, py) relative to glyph quad center
2826
- */
2827
- function computeAnchorPivotOffset(bbox, config) {
2828
- let normX = config.anchorX;
2829
- let normY = config.anchorY;
2830
- switch (config.preset) {
2831
- case "center":
2832
- normX = .5;
2833
- normY = .5;
2834
- break;
2835
- case "baseline":
2836
- normX = .5;
2837
- normY = bbox.height > 0 ? bbox.ascender / bbox.height : .8;
2838
- break;
2839
- case "bottom_left":
2840
- normX = 0;
2841
- normY = 1;
2842
- break;
2843
- case "bottom_center":
2844
- normX = .5;
2845
- normY = 1;
2846
- break;
2847
- case "bottom_right":
2848
- normX = 1;
2849
- normY = 1;
2850
- break;
2851
- case "top_left":
2852
- normX = 0;
2853
- normY = 0;
2854
- break;
2855
- case "top_center":
2856
- normX = .5;
2857
- normY = 0;
2858
- break;
2859
- case "top_right":
2860
- normX = 1;
2861
- normY = 0;
2862
- break;
2863
- default:
2864
- normX = .5;
2865
- normY = .5;
2866
- break;
2867
- }
2868
- return {
2869
- px: (normX - .5) * bbox.width + config.offsetX,
2870
- py: (normY - .5) * bbox.height + config.offsetY
2871
- };
2872
- }
2873
- /**
2874
- * Computes leading displacement per line based on lineAnchor:
2875
- *
2876
- * @param lineIndex 0-based index of current line
2877
- * @param lineCount Total lines in paragraph
2878
- * @param lineSpacing Additional leading in pixels
2879
- * @param lineAnchor Pivot line anchor in [0, 1]
2880
- * @returns Y displacement in pixels
2881
- */
2882
- function computeLineLeadingDisplacement(lineIndex, lineCount, lineSpacing, lineAnchor = 0) {
2883
- if (lineSpacing === 0 || lineCount <= 1) return 0;
2884
- return (lineIndex - lineAnchor * (lineCount - 1)) * lineSpacing;
2885
- }
2886
- /**
2887
- * Evaluates an Expression Selector formula safely in a sandboxed numeric scope.
2888
- *
2889
- * @param expression Formula string (e.g. "Math.sin(time * 4 + textIndex * 0.2)")
2890
- * @param ctx Glyph evaluation context
2891
- * @returns Numeric selector weight clamped to [-1, 1]
2892
- */
2893
- function evaluateExpressionSelector(expression, ctx) {
2894
- try {
2895
- const scope = {
2896
- textIndex: ctx.charIndex,
2897
- textTotal: Math.max(1, ctx.totalChars),
2898
- wordIndex: ctx.wordIndex,
2899
- wordTotal: Math.max(1, ctx.totalWords),
2900
- lineIndex: ctx.lineIndex,
2901
- lineTotal: Math.max(1, ctx.totalLines),
2902
- time: ctx.time,
2903
- frame: ctx.frame,
2904
- fps: ctx.fps,
2905
- sin: Math.sin,
2906
- cos: Math.cos,
2907
- tan: Math.tan,
2908
- exp: Math.exp,
2909
- log: Math.log,
2910
- abs: Math.abs,
2911
- min: Math.min,
2912
- max: Math.max,
2913
- sqrt: Math.sqrt,
2914
- pow: Math.pow,
2915
- floor: Math.floor,
2916
- ceil: Math.ceil,
2917
- round: Math.round,
2918
- PI: Math.PI,
2919
- clamp: (v, lo, hi) => Math.max(lo, Math.min(hi, v)),
2920
- noise: (seed) => {
2921
- const n = Math.sin(seed * 12.9898 + ctx.frame * .1) * 43758.5453;
2922
- return (n - Math.floor(n)) * 2 - 1;
2923
- },
2924
- signals: ctx.signals ?? {}
2925
- };
2926
- const keys = Object.keys(scope);
2927
- const values = Object.values(scope);
2928
- const fn = new Function(...keys, `return (${expression});`);
2929
- const result = Number(fn(...values));
2930
- return Number.isFinite(result) ? Math.max(-1, Math.min(1, result)) : 0;
2931
- } catch {
2932
- return 0;
2933
- }
2934
- }
2935
- /**
2936
- * Evaluates 3D Volumetric Formation parametric coordinates.
2937
- */
2938
- function evaluateVolumetricFormation(glyphIndex, totalGlyphs, config) {
2939
- const n = Math.max(1, totalGlyphs);
2940
- const norm = n > 1 ? glyphIndex / (n - 1) : 0;
2941
- const totalAngleRad = config.totalAngle * Math.PI / 180;
2942
- const phi = norm * totalAngleRad;
2943
- let x = 0;
2944
- let y = 0;
2945
- let z$1$1 = 0;
2946
- let rotX = 0;
2947
- let rotY = 0;
2948
- let rotZ = 0;
2949
- let depthOpacity = 1;
2950
- switch (config.mode) {
2951
- case "cylinder": {
2952
- const theta = config.totalAngle < 360 ? (norm - .5) * totalAngleRad : phi;
2953
- if (config.axis === "y") {
2954
- x = config.radius * Math.sin(theta);
2955
- z$1$1 = config.radius * Math.cos(theta) - config.radius;
2956
- rotY = theta * 180 / Math.PI;
2957
- } else if (config.axis === "x") {
2958
- y = config.radius * Math.sin(theta);
2959
- z$1$1 = config.radius * Math.cos(theta) - config.radius;
2960
- rotX = theta * 180 / Math.PI;
2961
- } else {
2962
- x = config.radius * Math.sin(theta);
2963
- y = config.radius * Math.cos(theta);
2964
- rotZ = theta * 180 / Math.PI;
2965
- }
2966
- const facing = Math.cos(theta);
2967
- depthOpacity = Math.max(.25, (facing + 1) * .5);
2968
- break;
2969
- }
2970
- case "vortex": {
2971
- const spiralPhi = -Math.PI / 2 + phi;
2972
- const r = config.radius * (1 - norm * .35);
2973
- x = r * Math.cos(spiralPhi);
2974
- y = r * Math.sin(spiralPhi);
2975
- z$1$1 = -glyphIndex * config.pitch || 0;
2976
- const dr = -.35 * config.radius / (totalAngleRad || 1);
2977
- const dx = dr * Math.cos(spiralPhi) - r * Math.sin(spiralPhi);
2978
- const dy = dr * Math.sin(spiralPhi) + r * Math.cos(spiralPhi);
2979
- rotZ = Math.atan2(dy, dx) * 180 / Math.PI;
2980
- depthOpacity = Math.max(.65, 1 - norm * .35);
2981
- break;
2982
- }
2983
- case "helix":
2984
- if (config.axis === "x") {
2985
- const pitchX = config.pitch > 10 ? config.pitch : 28;
2986
- x = (glyphIndex - (n - 1) / 2) * pitchX;
2987
- y = config.radius * Math.sin(phi);
2988
- z$1$1 = config.radius * Math.cos(phi) - config.radius;
2989
- rotX = Math.sin(phi) * 22;
2990
- depthOpacity = .75 + .25 * ((Math.cos(phi) + 1) * .5);
2991
- } else {
2992
- const theta = (norm - .5) * totalAngleRad;
2993
- x = config.radius * Math.sin(theta);
2994
- y = (glyphIndex - (n - 1) / 2) * config.pitch;
2995
- z$1$1 = config.radius * Math.cos(theta) - config.radius;
2996
- rotY = theta * 180 / Math.PI;
2997
- const facing = Math.cos(theta);
2998
- depthOpacity = Math.max(.65, (facing + 1) * .5);
2999
- }
3000
- break;
3001
- default:
3002
- z$1$1 = 0;
3003
- break;
3004
- }
3005
- const perspective = Math.max(100, config.perspective ?? 1200);
3006
- const depthDist = perspective - z$1$1;
3007
- const scaleMult = depthDist > 1 ? perspective / depthDist : 1;
3008
- return {
3009
- x: x * scaleMult,
3010
- y: y * scaleMult,
3011
- z: z$1$1,
3012
- rotX,
3013
- rotY,
3014
- rotZ,
3015
- scaleMult: Math.max(.1, scaleMult),
3016
- depthOpacity
3017
- };
3018
- }
3019
- /**
3020
- * Evaluates infinite kinetic marquee translation and snapping.
3021
- */
3022
- function evaluateMarqueeOffset(baseX, containerWidth, contentWidth, config, elapsedSec) {
3023
- const totalSpan = (containerWidth > 0 ? Math.max(containerWidth, contentWidth) : contentWidth) + config.repeatGap;
3024
- if (totalSpan <= 0) return baseX;
3025
- let travel = config.velocity * elapsedSec;
3026
- if (config.snap?.enabled) {
3027
- const targetPos = (config.snap.stopIndex ?? 0) * (config.snap.granularity === "character" ? 40 : 120);
3028
- const decelFactor = Math.min(1, elapsedSec * 1.5);
3029
- travel = travel * (1 - decelFactor) + targetPos * decelFactor;
3030
- }
3031
- if (config.direction === "right" || config.direction === "down") travel = -travel;
3032
- if (config.loop) {
3033
- const wrapped = (baseX - travel) % totalSpan;
3034
- return wrapped < -contentWidth ? wrapped + totalSpan : wrapped;
3035
- }
3036
- return baseX - travel;
3037
- }
3038
- /**
3039
- * Samples audio FFT frequency bin and computes scale factor for Audio Spectrum Typography.
3040
- */
3041
- function sampleAudioSpectrumScale(glyphIndex, totalGlyphs, config, signals, frame, fps) {
3042
- const n = Math.max(1, totalGlyphs);
3043
- const norm = n > 1 ? glyphIndex / (n - 1) : .5;
3044
- const minFreq = Math.max(20, config.minFreqHz);
3045
- const targetFreq = minFreq * (Math.max(minFreq + 100, config.maxFreqHz) / minFreq) ** norm;
3046
- let magnitude = 0;
3047
- if (signals) {
3048
- const sig = signals[config.signalChannel];
3049
- if (typeof sig === "number") magnitude = sig;
3050
- else if (typeof sig === "function") magnitude = Number(sig(frame, fps, targetFreq)) || 0;
3051
- else if (typeof sig === "object" && sig !== null) {
3052
- const sObj = sig;
3053
- if (typeof sObj.get === "function") magnitude = Number(sObj.get({
3054
- frame,
3055
- fps,
3056
- freq: targetFreq
3057
- })) || 0;
3058
- else if (Array.isArray(sObj.samples) || ArrayBuffer.isView(sObj.samples)) {
3059
- const arr = sObj.samples;
3060
- const binIdx = Math.floor(norm * (arr.length - 1));
3061
- magnitude = Number(arr[binIdx]) || 0;
1728
+ if (node.kind === "media") {
1729
+ const src = node.inputHandleId;
1730
+ if (typeof src === "string") {
1731
+ if ((node.dataType ?? "Video") === "Image") {
1732
+ if (/\.(json|lottie)(\?.*)?$/i.test(src)) push("error", "unsupported_image_format", `'${id}' is an image layer with source '${src}', which is a Lottie vector animation. Use Layer.lottie() instead.`, id);
1733
+ else if (/\.(mp4|mov|webm|mkv)(\?.*)?$/i.test(src)) push("error", "unsupported_image_format", `'${id}' is an image layer with video source '${src}'. Use Layer.video() instead.`, id);
1734
+ else if (/\.(mp3|wav|ogg|m4a|aac)(\?.*)?$/i.test(src)) push("error", "unsupported_image_format", `'${id}' is an image layer with audio source '${src}'. Use Layer.audio() instead.`, id);
1735
+ }
3062
1736
  }
3063
1737
  }
3064
- }
3065
- const clampedMag = Math.max(0, Math.min(1, magnitude));
3066
- return config.minScale + clampedMag * (config.maxScale - config.minScale);
3067
- }
3068
- /**
3069
- * Evaluates a point on a cubic Bezier curve at parameter t in [0, 1].
3070
- */
3071
- function evaluateCubicBezier(segment, t) {
3072
- const u = 1 - t;
3073
- const tt = t * t;
3074
- const uu = u * u;
3075
- const uuu = uu * u;
3076
- const ttt = tt * t;
3077
- return {
3078
- x: uuu * segment.p0.x + 3 * uu * t * segment.p1.x + 3 * u * tt * segment.p2.x + ttt * segment.p3.x,
3079
- y: uuu * segment.p0.y + 3 * uu * t * segment.p1.y + 3 * u * tt * segment.p2.y + ttt * segment.p3.y
3080
- };
3081
- }
3082
- /**
3083
- * Evaluates the first derivative (tangent velocity vector) of a cubic Bezier curve at parameter t.
3084
- */
3085
- function evaluateCubicBezierDerivative(segment, t) {
3086
- const u = 1 - t;
3087
- return {
3088
- x: 3 * u * u * (segment.p1.x - segment.p0.x) + 6 * u * t * (segment.p2.x - segment.p1.x) + 3 * t * t * (segment.p3.x - segment.p2.x),
3089
- y: 3 * u * u * (segment.p1.y - segment.p0.y) + 6 * u * t * (segment.p2.y - segment.p1.y) + 3 * t * t * (segment.p3.y - segment.p2.y)
3090
- };
3091
- }
3092
- /**
3093
- * Generates an arc-length parameterization lookup table (LUT) for a cubic Bezier segment.
3094
- * Ensures glyphs travel with uniform speed and do not bunch up on tight curve bends.
3095
- */
3096
- function generateArcLengthLUT(segment, samples = 100) {
3097
- const lut = [{
3098
- distance: 0,
3099
- t: 0
3100
- }];
3101
- let accumulatedDist = 0;
3102
- let prevPoint = segment.p0;
3103
- for (let i = 1; i <= samples; i++) {
3104
- const t = i / samples;
3105
- const currentPoint = evaluateCubicBezier(segment, t);
3106
- const dx = currentPoint.x - prevPoint.x;
3107
- const dy = currentPoint.y - prevPoint.y;
3108
- accumulatedDist += Math.hypot(dx, dy);
3109
- lut.push({
3110
- distance: accumulatedDist,
3111
- t
3112
- });
3113
- prevPoint = currentPoint;
3114
- }
3115
- return {
3116
- lut,
3117
- totalLength: accumulatedDist
3118
- };
3119
- }
3120
- /**
3121
- * Maps a distance along the curve (in pixels) to normalized curve parameter t via binary search on the LUT.
3122
- */
3123
- function distanceToCurveParameter(lut, distance, totalLength) {
3124
- if (distance <= 0) return 0;
3125
- if (distance >= totalLength) return 1;
3126
- let low = 0;
3127
- let high = lut.length - 1;
3128
- while (low <= high) {
3129
- const mid = low + high >> 1;
3130
- if (lut[mid].distance < distance) low = mid + 1;
3131
- else high = mid - 1;
3132
- }
3133
- const index = Math.max(1, Math.min(low, lut.length - 1));
3134
- const prev = lut[index - 1];
3135
- const curr = lut[index];
3136
- const segmentDist = curr.distance - prev.distance;
3137
- if (segmentDist <= 1e-6) return prev.t;
3138
- const ratio = (distance - prev.distance) / segmentDist;
3139
- return prev.t + ratio * (curr.t - prev.t);
3140
- }
3141
- /**
3142
- * Samples position and baseline tangent orientation angle along a curve at distance `dist`.
3143
- */
3144
- function sampleCurveGeometry(segment, lut, totalLength, distance) {
3145
- const t = distanceToCurveParameter(lut, distance, totalLength);
3146
- const pos = evaluateCubicBezier(segment, t);
3147
- const deriv = evaluateCubicBezierDerivative(segment, t);
3148
- const length = Math.hypot(deriv.x, deriv.y);
3149
- const nx = length > 1e-6 ? -deriv.y / length : 0;
3150
- const ny = length > 1e-6 ? deriv.x / length : 1;
3151
- return {
3152
- position: pos,
3153
- tangentAngleDeg: Math.atan2(deriv.y, deriv.x) * 180 / Math.PI,
3154
- normal: {
3155
- x: nx,
3156
- y: ny
3157
- }
3158
- };
3159
- }
3160
- /**
3161
- * Builds a cumulative Arc-Length LUT across a chain of Cubic Bezier segments.
3162
- */
3163
- function buildPathLUT(segments, samplesPerSegment = 50) {
3164
- if (segments.length === 0) return {
3165
- totalLength: 0,
3166
- entries: [{
3167
- distance: 0,
3168
- segmentIndex: 0,
3169
- t: 0
3170
- }],
3171
- segments: []
3172
- };
3173
- const segLuts = [];
3174
- const entries = [];
3175
- let accumulatedDist = 0;
3176
- for (let segIdx = 0; segIdx < segments.length; segIdx++) {
3177
- const seg = segments[segIdx];
3178
- const { lut: segLut, totalLength: segLength } = generateArcLengthLUT(seg, samplesPerSegment);
3179
- segLuts.push({
3180
- segmentIndex: segIdx,
3181
- startDistance: accumulatedDist,
3182
- length: segLength,
3183
- lut: segLut
3184
- });
3185
- for (let i = 0; i < segLut.length; i++) entries.push({
3186
- distance: accumulatedDist + segLut[i].distance,
3187
- segmentIndex: segIdx,
3188
- t: segLut[i].t
3189
- });
3190
- accumulatedDist += segLength;
3191
- }
3192
- return {
3193
- totalLength: accumulatedDist,
3194
- entries,
3195
- segments: segLuts
3196
- };
3197
- }
3198
- /**
3199
- * Samples position, tangent angle, and normal across a chain of Cubic Bezier segments.
3200
- */
3201
- function samplePathChainGeometry(segments, chainLUT, distance) {
3202
- if (segments.length === 0) return {
3203
- position: {
3204
- x: 0,
3205
- y: 0
3206
- },
3207
- tangentAngleDeg: 0,
3208
- normal: {
3209
- x: 0,
3210
- y: 1
3211
- }
3212
- };
3213
- const totalLength = chainLUT.totalLength;
3214
- if (distance <= 0) {
3215
- const seg = segments[0];
3216
- const deriv$1 = evaluateCubicBezierDerivative(seg, 0);
3217
- const length$1 = Math.hypot(deriv$1.x, deriv$1.y);
3218
- const ux = length$1 > 1e-6 ? deriv$1.x / length$1 : 1;
3219
- const uy = length$1 > 1e-6 ? deriv$1.y / length$1 : 0;
3220
- const pos$1 = {
3221
- x: seg.p0.x + ux * distance,
3222
- y: seg.p0.y + uy * distance
3223
- };
3224
- const nx$1 = length$1 > 1e-6 ? -deriv$1.y / length$1 : 0;
3225
- const ny$1 = length$1 > 1e-6 ? deriv$1.x / length$1 : 1;
3226
- return {
3227
- position: pos$1,
3228
- tangentAngleDeg: Math.atan2(deriv$1.y, deriv$1.x) * 180 / Math.PI,
3229
- normal: {
3230
- x: nx$1,
3231
- y: ny$1
3232
- }
3233
- };
3234
- }
3235
- if (distance >= totalLength) {
3236
- const lastSeg = segments[segments.length - 1];
3237
- const deriv$1 = evaluateCubicBezierDerivative(lastSeg, 1);
3238
- const length$1 = Math.hypot(deriv$1.x, deriv$1.y);
3239
- const ux = length$1 > 1e-6 ? deriv$1.x / length$1 : 1;
3240
- const uy = length$1 > 1e-6 ? deriv$1.y / length$1 : 0;
3241
- const overflow = distance - totalLength;
3242
- const pos$1 = {
3243
- x: lastSeg.p3.x + ux * overflow,
3244
- y: lastSeg.p3.y + uy * overflow
3245
- };
3246
- const nx$1 = length$1 > 1e-6 ? -deriv$1.y / length$1 : 0;
3247
- const ny$1 = length$1 > 1e-6 ? deriv$1.x / length$1 : 1;
3248
- return {
3249
- position: pos$1,
3250
- tangentAngleDeg: Math.atan2(deriv$1.y, deriv$1.x) * 180 / Math.PI,
3251
- normal: {
3252
- x: nx$1,
3253
- y: ny$1
3254
- }
3255
- };
3256
- }
3257
- let segIdx = 0;
3258
- let t = 0;
3259
- if (chainLUT.segments && chainLUT.segments.length > 0) {
3260
- let low = 0;
3261
- let high = chainLUT.segments.length - 1;
3262
- while (low <= high) {
3263
- const mid = low + high >> 1;
3264
- const segLUT$1 = chainLUT.segments[mid];
3265
- if (distance < segLUT$1.startDistance) high = mid - 1;
3266
- else if (distance > segLUT$1.startDistance + segLUT$1.length) low = mid + 1;
3267
- else {
3268
- low = mid;
3269
- break;
1738
+ const is3D = Boolean(node.is3D) || typeof node.z === "number" && node.z !== 0;
1739
+ if (is3D || node.kind === "model3d") has3D = true;
1740
+ if (node.roughness !== void 0 || node.metallic !== void 0) pbrNodes.push(id);
1741
+ if (node.kind === "text" && backdrop && !animates(node, ["fill", "color"])) {
1742
+ const fg = solidColor(node.fill ?? node.color);
1743
+ const behind = solidColor(node.background) ?? backdrop;
1744
+ if (fg) {
1745
+ const ratio = Color.contrast(fg, behind);
1746
+ if (ratio < MIN_TEXT_CONTRAST) push("warning", "low_contrast_text", `Text '${id}' (${fg}) on ${behind} has contrast ${ratio.toFixed(2)}:1 (aim for ≥ ${MIN_TEXT_CONTRAST}; ${Color.readableOn(behind)} reads well).`, id);
3270
1747
  }
3271
1748
  }
3272
- const sIdx = Math.max(0, Math.min(low, chainLUT.segments.length - 1));
3273
- const segLUT = chainLUT.segments[sIdx];
3274
- segIdx = segLUT.segmentIndex;
3275
- const localDist = distance - segLUT.startDistance;
3276
- t = distanceToCurveParameter(segLUT.lut, localDist, segLUT.length);
3277
- } else {
3278
- let low = 0;
3279
- let high = chainLUT.entries.length - 1;
3280
- while (low <= high) {
3281
- const mid = low + high >> 1;
3282
- if (chainLUT.entries[mid].distance < distance) low = mid + 1;
3283
- else high = mid - 1;
1749
+ if (atRoot && !is3D && node.position === "absolute" && typeof node.x === "number" && typeof node.y === "number" && typeof node.width === "number" && typeof node.height === "number" && !animates(node, [
1750
+ "x",
1751
+ "y",
1752
+ "translateX",
1753
+ "translateY",
1754
+ "scale",
1755
+ "rotation"
1756
+ ])) {
1757
+ const { x, y, width, height } = node;
1758
+ if (x + width <= 0 || y + height <= 0 || x >= W || y >= H) push("warning", "offscreen_layer", `'${id}' sits entirely outside the ${W}×${H} canvas (x ${x}, y ${y}) and never moves in.`, id);
3284
1759
  }
3285
- const index = Math.max(1, Math.min(low, chainLUT.entries.length - 1));
3286
- const prev = chainLUT.entries[index - 1];
3287
- const curr = chainLUT.entries[index];
3288
- const segmentDist = curr.distance - prev.distance;
3289
- const ratio = segmentDist > 1e-6 ? (distance - prev.distance) / segmentDist : 0;
3290
- segIdx = curr.segmentIndex;
3291
- t = prev.segmentIndex === curr.segmentIndex ? prev.t + ratio * (curr.t - prev.t) : curr.t;
3292
- }
3293
- const segment = segments[segIdx] ?? segments[0];
3294
- const pos = evaluateCubicBezier(segment, t);
3295
- const deriv = evaluateCubicBezierDerivative(segment, t);
3296
- const length = Math.hypot(deriv.x, deriv.y);
3297
- const nx = length > 1e-6 ? -deriv.y / length : 0;
3298
- const ny = length > 1e-6 ? deriv.x / length : 1;
3299
- return {
3300
- position: pos,
3301
- tangentAngleDeg: Math.atan2(deriv.y, deriv.x) * 180 / Math.PI,
3302
- normal: {
3303
- x: nx,
3304
- y: ny
1760
+ for (const t of tracksOf(node)) {
1761
+ const kfs = t.keyframes ?? [];
1762
+ if ((!t.source || t.source.type === "keyframe") && kfs.length >= 2 && kfs.every((k) => JSON.stringify(k.value) === JSON.stringify(kfs[0].value))) push("info", "static_track", `'${id}' animates \`${t.prop}\` but every keyframe holds ${JSON.stringify(kfs[0].value)}.`, id);
3305
1763
  }
1764
+ const ownBackdrop = solidColor(node.background) ?? backdrop;
1765
+ const children = node.children;
1766
+ const fullFrame = node.x === 0 && node.y === 0 && node.width === W && node.height === H;
1767
+ visitLevel(children ?? [], ownBackdrop, atRoot && fullFrame);
3306
1768
  };
3307
- }
3308
- /**
3309
- * Converts an ellipse arc into cubic Bezier segments (up to 90 degrees per segment).
3310
- */
3311
- function ellipseToCubicBeziers(cx, cy, rx, ry, startAngleDeg = 0, endAngleDeg = 360) {
3312
- const startRad = startAngleDeg * Math.PI / 180;
3313
- const totalSweep = endAngleDeg * Math.PI / 180 - startRad;
3314
- const numSegments = Math.max(1, Math.ceil(Math.abs(totalSweep) / (Math.PI / 2)));
3315
- const sweepStep = totalSweep / numSegments;
3316
- const segments = [];
3317
- for (let i = 0; i < numSegments; i++) {
3318
- const a0 = startRad + i * sweepStep;
3319
- const a1 = a0 + sweepStep;
3320
- const halfSweep = sweepStep / 2;
3321
- const k = 4 / 3 * Math.tan(halfSweep / 2);
3322
- const cos0 = Math.cos(a0);
3323
- const sin0 = Math.sin(a0);
3324
- const cos1 = Math.cos(a1);
3325
- const sin1 = Math.sin(a1);
3326
- const p0 = {
3327
- x: cx + rx * cos0,
3328
- y: cy + ry * sin0
3329
- };
3330
- const p1 = {
3331
- x: p0.x - k * rx * sin0,
3332
- y: p0.y + k * ry * cos0
3333
- };
3334
- const p3 = {
3335
- x: cx + rx * cos1,
3336
- y: cy + ry * sin1
3337
- };
3338
- const p2 = {
3339
- x: p3.x + k * rx * sin1,
3340
- y: p3.y - k * ry * cos1
3341
- };
3342
- segments.push({
3343
- p0,
3344
- p1,
3345
- p2,
3346
- p3
3347
- });
3348
- }
3349
- return segments;
3350
- }
3351
- /**
3352
- * Converts a sinusoidal wave into cubic Bezier segments per half-cycle.
3353
- */
3354
- function waveToCubicBeziers(startX, startY, length, amplitude, frequency, phaseDeg = 0) {
3355
- const phaseRad = phaseDeg * Math.PI / 180;
3356
- const totalCycles = frequency < .1 && frequency * length >= .25 ? frequency * length : Math.max(.5, frequency);
3357
- const halfCycles = Math.max(1, Math.round(totalCycles * 2));
3358
- const dx = length / halfCycles;
3359
- const segments = [];
3360
- for (let i = 0; i < halfCycles; i++) {
3361
- const t0 = i / halfCycles * (2 * Math.PI * totalCycles) + phaseRad;
3362
- const t1 = (i + 1) / halfCycles * (2 * Math.PI * totalCycles) + phaseRad;
3363
- const x0 = startX + i * dx;
3364
- const x3 = startX + (i + 1) * dx;
3365
- const y0 = startY + amplitude * Math.sin(t0);
3366
- const y3 = startY + amplitude * Math.sin(t1);
3367
- const slope0 = amplitude * Math.cos(t0) * (Math.PI / 3);
3368
- const slope1 = amplitude * Math.cos(t1) * (Math.PI / 3);
3369
- const p0 = {
3370
- x: x0,
3371
- y: y0
3372
- };
3373
- const p1 = {
3374
- x: x0 + dx / 3,
3375
- y: y0 + slope0
3376
- };
3377
- const p2 = {
3378
- x: x3 - dx / 3,
3379
- y: y3 - slope1
3380
- };
3381
- const p3 = {
3382
- x: x3,
3383
- y: y3
3384
- };
3385
- segments.push({
3386
- p0,
3387
- p1,
3388
- p2,
3389
- p3
3390
- });
3391
- }
3392
- return segments;
3393
- }
3394
- /**
3395
- * An SVG elliptical arc (endpoint form, SVG 1.1 F.6.5) as cubic Bezier
3396
- * segments of at most 90° each.
3397
- */
3398
- function svgArcToCubicBeziers(x1, y1, rxIn, ryIn, rotationDeg, largeArc, sweep, x2, y2) {
3399
- if (x1 === x2 && y1 === y2) return [];
3400
- let rx = Math.abs(rxIn);
3401
- let ry = Math.abs(ryIn);
3402
- if (rx === 0 || ry === 0) return [{
3403
- p0: {
3404
- x: x1,
3405
- y: y1
3406
- },
3407
- p1: {
3408
- x: x1 + (x2 - x1) / 3,
3409
- y: y1 + (y2 - y1) / 3
3410
- },
3411
- p2: {
3412
- x: x1 + 2 * (x2 - x1) / 3,
3413
- y: y1 + 2 * (y2 - y1) / 3
3414
- },
3415
- p3: {
3416
- x: x2,
3417
- y: y2
1769
+ const visitLevel = (nodes, backdrop, atRoot) => {
1770
+ let known = backdrop;
1771
+ for (const n of byZ(nodes)) {
1772
+ visit(n, known, atRoot);
1773
+ if (paints(n)) known = null;
3418
1774
  }
3419
- }];
3420
- const phi = rotationDeg * Math.PI / 180;
3421
- const cosPhi = Math.cos(phi);
3422
- const sinPhi = Math.sin(phi);
3423
- const dx = (x1 - x2) / 2;
3424
- const dy = (y1 - y2) / 2;
3425
- const x1p = cosPhi * dx + sinPhi * dy;
3426
- const y1p = -sinPhi * dx + cosPhi * dy;
3427
- const lambda = x1p * x1p / (rx * rx) + y1p * y1p / (ry * ry);
3428
- if (lambda > 1) {
3429
- rx *= Math.sqrt(lambda);
3430
- ry *= Math.sqrt(lambda);
3431
- }
3432
- const num = rx * rx * ry * ry - rx * rx * y1p * y1p - ry * ry * x1p * x1p;
3433
- const den = rx * rx * y1p * y1p + ry * ry * x1p * x1p;
3434
- const coef = (largeArc !== sweep ? 1 : -1) * Math.sqrt(Math.max(0, num / den));
3435
- const cxp = coef * rx * y1p / ry;
3436
- const cyp = -coef * ry * x1p / rx;
3437
- const cx = cosPhi * cxp - sinPhi * cyp + (x1 + x2) / 2;
3438
- const cy = sinPhi * cxp + cosPhi * cyp + (y1 + y2) / 2;
3439
- const angle = (ux, uy, vx, vy) => Math.atan2(ux * vy - uy * vx, ux * vx + uy * vy);
3440
- const theta1 = angle(1, 0, (x1p - cxp) / rx, (y1p - cyp) / ry);
3441
- let delta = angle((x1p - cxp) / rx, (y1p - cyp) / ry, (-x1p - cxp) / rx, (-y1p - cyp) / ry);
3442
- if (!sweep && delta > 0) delta -= 2 * Math.PI;
3443
- if (sweep && delta < 0) delta += 2 * Math.PI;
3444
- const n = Math.max(1, Math.ceil(Math.abs(delta) / (Math.PI / 2)));
3445
- const step = delta / n;
3446
- const k = 4 / 3 * Math.tan(step / 4);
3447
- const point = (a) => ({
3448
- x: cx + rx * Math.cos(a) * cosPhi - ry * Math.sin(a) * sinPhi,
3449
- y: cy + rx * Math.cos(a) * sinPhi + ry * Math.sin(a) * cosPhi
3450
- });
3451
- const tangent = (a) => ({
3452
- x: -rx * Math.sin(a) * cosPhi - ry * Math.cos(a) * sinPhi,
3453
- y: -rx * Math.sin(a) * sinPhi + ry * Math.cos(a) * cosPhi
3454
- });
3455
- const segments = [];
3456
- for (let s = 0; s < n; s++) {
3457
- const a0 = theta1 + s * step;
3458
- const a1 = a0 + step;
3459
- const p0 = point(a0);
3460
- const p3 = point(a1);
3461
- const t0 = tangent(a0);
3462
- const t1 = tangent(a1);
3463
- segments.push({
3464
- p0,
3465
- p1: {
3466
- x: p0.x + k * t0.x,
3467
- y: p0.y + k * t0.y
3468
- },
3469
- p2: {
3470
- x: p3.x - k * t1.x,
3471
- y: p3.y - k * t1.y
3472
- },
3473
- p3
3474
- });
3475
- }
3476
- segments[segments.length - 1].p3 = {
3477
- x: x2,
3478
- y: y2
3479
- };
3480
- return segments;
3481
- }
3482
- /**
3483
- * Converts SVG path data string into a chain of Cubic Bezier segments.
3484
- */
3485
- function parseSvgPathToCubicBeziers(d) {
3486
- const segments = [];
3487
- const tokens = d.match(/[a-df-z]|[-+]?(?:\d*\.\d+|\d+)(?:[eE][-+]?\d+)?/gi);
3488
- if (!tokens || tokens.length === 0) return segments;
3489
- let currentX = 0;
3490
- let currentY = 0;
3491
- let startX = 0;
3492
- let startY = 0;
3493
- let lastControlX = 0;
3494
- let lastControlY = 0;
3495
- let lastCommand = "";
3496
- let i = 0;
3497
- const nextNum = () => {
3498
- if (i >= tokens.length) return 0;
3499
- return Number.parseFloat(tokens[i++]);
3500
1775
  };
3501
- while (i < tokens.length) {
3502
- const token = tokens[i++];
3503
- const isCommand = /^[a-df-z]$/i.test(token);
3504
- const cmd = isCommand ? token : lastCommand;
3505
- if (!isCommand) i--;
3506
- switch (cmd) {
3507
- case "M":
3508
- currentX = nextNum();
3509
- currentY = nextNum();
3510
- startX = currentX;
3511
- startY = currentY;
3512
- lastCommand = "L";
3513
- break;
3514
- case "m":
3515
- currentX += nextNum();
3516
- currentY += nextNum();
3517
- startX = currentX;
3518
- startY = currentY;
3519
- lastCommand = "l";
3520
- break;
3521
- case "L": {
3522
- const x = nextNum();
3523
- const y = nextNum();
3524
- segments.push({
3525
- p0: {
3526
- x: currentX,
3527
- y: currentY
3528
- },
3529
- p1: {
3530
- x: currentX + (x - currentX) / 3,
3531
- y: currentY + (y - currentY) / 3
3532
- },
3533
- p2: {
3534
- x: currentX + 2 * (x - currentX) / 3,
3535
- y: currentY + 2 * (y - currentY) / 3
3536
- },
3537
- p3: {
3538
- x,
3539
- y
3540
- }
3541
- });
3542
- currentX = x;
3543
- currentY = y;
3544
- lastCommand = "L";
3545
- break;
3546
- }
3547
- case "l": {
3548
- const dx = nextNum();
3549
- const dy = nextNum();
3550
- const x = currentX + dx;
3551
- const y = currentY + dy;
3552
- segments.push({
3553
- p0: {
3554
- x: currentX,
3555
- y: currentY
3556
- },
3557
- p1: {
3558
- x: currentX + dx / 3,
3559
- y: currentY + dy / 3
3560
- },
3561
- p2: {
3562
- x: currentX + 2 * dx / 3,
3563
- y: currentY + 2 * dy / 3
3564
- },
3565
- p3: {
3566
- x,
3567
- y
3568
- }
3569
- });
3570
- currentX = x;
3571
- currentY = y;
3572
- lastCommand = "l";
3573
- break;
3574
- }
3575
- case "H": {
3576
- const x = nextNum();
3577
- segments.push({
3578
- p0: {
3579
- x: currentX,
3580
- y: currentY
3581
- },
3582
- p1: {
3583
- x: currentX + (x - currentX) / 3,
3584
- y: currentY
3585
- },
3586
- p2: {
3587
- x: currentX + 2 * (x - currentX) / 3,
3588
- y: currentY
3589
- },
3590
- p3: {
3591
- x,
3592
- y: currentY
3593
- }
3594
- });
3595
- currentX = x;
3596
- lastCommand = "H";
3597
- break;
3598
- }
3599
- case "h": {
3600
- const dx = nextNum();
3601
- const x = currentX + dx;
3602
- segments.push({
3603
- p0: {
3604
- x: currentX,
3605
- y: currentY
3606
- },
3607
- p1: {
3608
- x: currentX + dx / 3,
3609
- y: currentY
3610
- },
3611
- p2: {
3612
- x: currentX + 2 * dx / 3,
3613
- y: currentY
3614
- },
3615
- p3: {
3616
- x,
3617
- y: currentY
3618
- }
3619
- });
3620
- currentX = x;
3621
- lastCommand = "h";
3622
- break;
3623
- }
3624
- case "V": {
3625
- const y = nextNum();
3626
- segments.push({
3627
- p0: {
3628
- x: currentX,
3629
- y: currentY
3630
- },
3631
- p1: {
3632
- x: currentX,
3633
- y: currentY + (y - currentY) / 3
3634
- },
3635
- p2: {
3636
- x: currentX,
3637
- y: currentY + 2 * (y - currentY) / 3
3638
- },
3639
- p3: {
3640
- x: currentX,
3641
- y
3642
- }
3643
- });
3644
- currentY = y;
3645
- lastCommand = "V";
3646
- break;
3647
- }
3648
- case "v": {
3649
- const dy = nextNum();
3650
- const y = currentY + dy;
3651
- segments.push({
3652
- p0: {
3653
- x: currentX,
3654
- y: currentY
3655
- },
3656
- p1: {
3657
- x: currentX,
3658
- y: currentY + dy / 3
3659
- },
3660
- p2: {
3661
- x: currentX,
3662
- y: currentY + 2 * dy / 3
3663
- },
3664
- p3: {
3665
- x: currentX,
3666
- y
3667
- }
3668
- });
3669
- currentY = y;
3670
- lastCommand = "v";
3671
- break;
3672
- }
3673
- case "C": {
3674
- const x1 = nextNum();
3675
- const y1 = nextNum();
3676
- const x2 = nextNum();
3677
- const y2 = nextNum();
3678
- const x = nextNum();
3679
- const y = nextNum();
3680
- segments.push({
3681
- p0: {
3682
- x: currentX,
3683
- y: currentY
3684
- },
3685
- p1: {
3686
- x: x1,
3687
- y: y1
3688
- },
3689
- p2: {
3690
- x: x2,
3691
- y: y2
3692
- },
3693
- p3: {
3694
- x,
3695
- y
3696
- }
3697
- });
3698
- lastControlX = x2;
3699
- lastControlY = y2;
3700
- currentX = x;
3701
- currentY = y;
3702
- lastCommand = "C";
3703
- break;
3704
- }
3705
- case "c": {
3706
- const dx1 = nextNum();
3707
- const dy1 = nextNum();
3708
- const dx2 = nextNum();
3709
- const dy2 = nextNum();
3710
- const dx = nextNum();
3711
- const dy = nextNum();
3712
- const x1 = currentX + dx1;
3713
- const y1 = currentY + dy1;
3714
- const x2 = currentX + dx2;
3715
- const y2 = currentY + dy2;
3716
- const x = currentX + dx;
3717
- const y = currentY + dy;
3718
- segments.push({
3719
- p0: {
3720
- x: currentX,
3721
- y: currentY
3722
- },
3723
- p1: {
3724
- x: x1,
3725
- y: y1
3726
- },
3727
- p2: {
3728
- x: x2,
3729
- y: y2
3730
- },
3731
- p3: {
3732
- x,
3733
- y
3734
- }
3735
- });
3736
- lastControlX = x2;
3737
- lastControlY = y2;
3738
- currentX = x;
3739
- currentY = y;
3740
- lastCommand = "c";
3741
- break;
3742
- }
3743
- case "S":
3744
- case "s": {
3745
- const isRel = cmd === "s";
3746
- const dx2 = nextNum();
3747
- const dy2 = nextNum();
3748
- const dx = nextNum();
3749
- const dy = nextNum();
3750
- const x2 = isRel ? currentX + dx2 : dx2;
3751
- const y2 = isRel ? currentY + dy2 : dy2;
3752
- const x = isRel ? currentX + dx : dx;
3753
- const y = isRel ? currentY + dy : dy;
3754
- let x1 = currentX;
3755
- let y1 = currentY;
3756
- if (/^[cs]$/i.test(lastCommand)) {
3757
- x1 = 2 * currentX - lastControlX;
3758
- y1 = 2 * currentY - lastControlY;
3759
- }
3760
- segments.push({
3761
- p0: {
3762
- x: currentX,
3763
- y: currentY
3764
- },
3765
- p1: {
3766
- x: x1,
3767
- y: y1
3768
- },
3769
- p2: {
3770
- x: x2,
3771
- y: y2
3772
- },
3773
- p3: {
3774
- x,
3775
- y
3776
- }
3777
- });
3778
- lastControlX = x2;
3779
- lastControlY = y2;
3780
- currentX = x;
3781
- currentY = y;
3782
- lastCommand = cmd;
3783
- break;
3784
- }
3785
- case "Q":
3786
- case "q": {
3787
- const isRel = cmd === "q";
3788
- const qx = nextNum();
3789
- const qy = nextNum();
3790
- const x = nextNum();
3791
- const y = nextNum();
3792
- const cx1 = isRel ? currentX + qx : qx;
3793
- const cy1 = isRel ? currentY + qy : qy;
3794
- const ex = isRel ? currentX + x : x;
3795
- const ey = isRel ? currentY + y : y;
3796
- const p1x = currentX + 2 / 3 * (cx1 - currentX);
3797
- const p1y = currentY + 2 / 3 * (cy1 - currentY);
3798
- const p2x = ex + 2 / 3 * (cx1 - ex);
3799
- const p2y = ey + 2 / 3 * (cy1 - ey);
3800
- segments.push({
3801
- p0: {
3802
- x: currentX,
3803
- y: currentY
3804
- },
3805
- p1: {
3806
- x: p1x,
3807
- y: p1y
3808
- },
3809
- p2: {
3810
- x: p2x,
3811
- y: p2y
3812
- },
3813
- p3: {
3814
- x: ex,
3815
- y: ey
3816
- }
3817
- });
3818
- lastControlX = cx1;
3819
- lastControlY = cy1;
3820
- currentX = ex;
3821
- currentY = ey;
3822
- lastCommand = cmd;
3823
- break;
3824
- }
3825
- case "A":
3826
- case "a": {
3827
- const rx = nextNum();
3828
- const ry = nextNum();
3829
- const rotation = nextNum();
3830
- const largeArc = nextNum() !== 0;
3831
- const sweep = nextNum() !== 0;
3832
- let x = nextNum();
3833
- let y = nextNum();
3834
- if (cmd === "a") {
3835
- x += currentX;
3836
- y += currentY;
3837
- }
3838
- segments.push(...svgArcToCubicBeziers(currentX, currentY, rx, ry, rotation, largeArc, sweep, x, y));
3839
- currentX = x;
3840
- currentY = y;
3841
- lastControlX = x;
3842
- lastControlY = y;
3843
- lastCommand = cmd;
3844
- break;
3845
- }
3846
- case "Z":
3847
- case "z":
3848
- if (currentX !== startX || currentY !== startY) {
3849
- segments.push({
3850
- p0: {
3851
- x: currentX,
3852
- y: currentY
3853
- },
3854
- p1: {
3855
- x: currentX + (startX - currentX) / 3,
3856
- y: currentY + (startY - currentY) / 3
3857
- },
3858
- p2: {
3859
- x: currentX + 2 * (startX - currentX) / 3,
3860
- y: currentY + 2 * (startY - currentY) / 3
3861
- },
3862
- p3: {
3863
- x: startX,
3864
- y: startY
3865
- }
3866
- });
3867
- currentX = startX;
3868
- currentY = startY;
3869
- }
3870
- lastCommand = cmd;
3871
- break;
3872
- default: break;
3873
- }
3874
- }
3875
- return segments;
3876
- }
3877
- /**
3878
- * Universal path source converter to Cubic Bezier segments.
3879
- */
3880
- function generatePathSegments(source) {
3881
- switch (source.type) {
3882
- case "bezier": return source.segments;
3883
- case "svg": return parseSvgPathToCubicBeziers(source.d);
3884
- case "ellipse": return ellipseToCubicBeziers(source.cx, source.cy, source.rx, source.ry, source.startAngleDeg ?? 0, source.endAngleDeg ?? 360);
3885
- case "wave": return waveToCubicBeziers(source.startX, source.startY, source.length, source.amplitude, source.frequency, source.phaseDeg ?? 0);
3886
- }
3887
- }
3888
- /**
3889
- * Computes After Effects Range Selector weight for a single glyph index.
3890
- *
3891
- * @param index Normalized position of the glyph in the string (0.0 to 1.0)
3892
- * @param start Start boundary (0.0 to 1.0)
3893
- * @param end End boundary (0.0 to 1.0)
3894
- * @param offset Window shift (-1.0 to 1.0)
3895
- * @param shape Falloff curve
3896
- * @param easeHigh Non-linear easing for high values
3897
- * @param easeLow Non-linear easing for low values
3898
- * @returns Weight in [0.0, 1.0]
3899
- */
3900
- function computeRangeSelectorWeight(index, start, end, offset, shape, easeHigh = 0, easeLow = 0) {
3901
- const effStart = start + offset;
3902
- const effEnd = end + offset;
3903
- if (effEnd <= effStart) return 0;
3904
- const relativePos = (index - effStart) / (effEnd - effStart);
3905
- let baseWeight = 0;
3906
- switch (shape) {
3907
- case "square":
3908
- baseWeight = relativePos >= 0 && relativePos <= 1 ? 1 : 0;
3909
- break;
3910
- case "ramp_up":
3911
- baseWeight = Math.max(0, Math.min(1, relativePos));
3912
- break;
3913
- case "ramp_down":
3914
- baseWeight = 1 - Math.max(0, Math.min(1, relativePos));
3915
- break;
3916
- case "triangle":
3917
- if (relativePos < 0 || relativePos > 1) baseWeight = 0;
3918
- else if (relativePos < .5) baseWeight = relativePos * 2;
3919
- else baseWeight = (1 - relativePos) * 2;
3920
- break;
3921
- case "round":
3922
- if (relativePos < 0 || relativePos > 1) baseWeight = 0;
3923
- else baseWeight = .5 - .5 * Math.cos(relativePos * 2 * Math.PI);
3924
- break;
3925
- case "smooth":
3926
- if (relativePos <= 0) baseWeight = 0;
3927
- else if (relativePos >= 1) baseWeight = 1;
3928
- else baseWeight = relativePos * relativePos * (3 - 2 * relativePos);
3929
- break;
3930
- }
3931
- if (baseWeight > 0 && baseWeight < 1) {
3932
- if (easeHigh !== 0 && baseWeight > .5) baseWeight = .5 + .5 * ((baseWeight - .5) * 2) ** (easeHigh > 0 ? 1 + easeHigh * 3 : 1 / (1 - easeHigh * 3));
3933
- if (easeLow !== 0 && baseWeight <= .5) baseWeight = .5 * (baseWeight * 2) ** (easeLow > 0 ? 1 + easeLow * 3 : 1 / (1 - easeLow * 3));
3934
- }
3935
- return Math.max(0, Math.min(1, baseWeight));
3936
- }
3937
- /**
3938
- * 1D Gradient deterministic hash noise for Wiggly Selectors.
3939
- */
3940
- function deterministicWigglyNoise(seed, glyphIndex, phase, correlation) {
3941
- const coord = (glyphIndex * (1 - correlation) + correlation) * 12.9898 + phase + seed * 78.233;
3942
- const raw = Math.sin(coord) * 43758.5453;
3943
- return (raw - Math.floor(raw)) * 2 - 1;
1776
+ const rootBackdrop = solidColor(config.backgroundColor) ?? null;
1777
+ visitLevel(config.layout, rootBackdrop, true);
1778
+ if (hasEnvironment && ambientLights.length > 0) push("info", "ambient_with_environment", `The environment already fills shadows with light; ambient light ${ambientLights.join(", ")} adds flat light on top (remove it, or lower it, if the scene looks washed out).`);
1779
+ if (shadowLights.length > 1) push("info", "multiple_shadow_lights", `${shadowLights.length} lights cast shadows (${shadowLights.join(", ")}); only the first one does.`);
1780
+ if (has3D && pbrNodes.length > 0 && !hasEnvironment) push("info", "pbr_without_environment", `roughness / metallic are set (${pbrNodes.slice(0, 3).join(", ")}${pbrNodes.length > 3 ? ", …" : ""}) but the scene has no Layer.environment(): add one for physically based shading, reflections and tone mapping.`);
1781
+ return out;
3944
1782
  }
3945
- /**
3946
- * Deterministic pseudo-random number generator for seeded order shuffling.
3947
- */
3948
- function getShuffledOrder(count, seed) {
3949
- let s = seed;
3950
- const nextRand = () => {
3951
- s = (s * 9301 + 49297) % 233280;
3952
- return s / 233280;
1783
+ const GEOMETRY = [
1784
+ "x",
1785
+ "y",
1786
+ "width",
1787
+ "height"
1788
+ ];
1789
+ function hoistOne(owner) {
1790
+ const matte = owner.matte;
1791
+ const { matte: _drop, ...rest } = owner;
1792
+ const self = { ...rest };
1793
+ if (Array.isArray(self.children)) self.children = hoistMattes(self.children);
1794
+ if (!matte?.node) return [self];
1795
+ const src = matte.node;
1796
+ const id = src.id ?? `${String(owner.id)}__matte`;
1797
+ const node = {
1798
+ position: "absolute",
1799
+ ...src,
1800
+ id,
1801
+ matteOf: String(owner.id),
1802
+ matteMode: matte.mode ?? "alpha"
3953
1803
  };
3954
- const arr = Array.from({ length: count }, (_, i) => i);
3955
- for (let i = arr.length - 1; i > 0; i--) {
3956
- const j = Math.floor(nextRand() * (i + 1));
3957
- const temp = arr[i];
3958
- arr[i] = arr[j];
3959
- arr[j] = temp;
3960
- }
3961
- return arr;
3962
- }
3963
- /**
3964
- * Combines consecutive selector weights using After Effects Selector Mode logic.
3965
- */
3966
- function evaluateSelectorCombination(prevWeight, currWeight, mode) {
3967
- switch (mode) {
3968
- case "add": return Math.max(0, Math.min(1, prevWeight + currWeight));
3969
- case "subtract": return Math.max(0, Math.min(1, prevWeight - currWeight));
3970
- case "intersect": return prevWeight * currWeight;
3971
- case "min": return Math.min(prevWeight, currWeight);
3972
- case "max": return Math.max(prevWeight, currWeight);
3973
- case "difference": return Math.abs(prevWeight - currWeight);
1804
+ if (GEOMETRY.every((k) => src[k] === void 0)) {
1805
+ for (const k of GEOMETRY) if (typeof owner[k] === "number") node[k] = owner[k];
3974
1806
  }
1807
+ node.startFrame = (typeof owner.startFrame === "number" ? owner.startFrame : 0) + (typeof src.startFrame === "number" ? src.startFrame : 0);
1808
+ if (src.durationFrames === void 0 && owner.durationFrames !== void 0) node.durationFrames = owner.durationFrames;
1809
+ if (Array.isArray(node.children)) node.children = hoistMattes(node.children);
1810
+ self.matteId = id;
1811
+ return [self, node];
3975
1812
  }
3976
- const SCRAMBLE_POOLS = {
3977
- ascii: "!@#$%^&*()_+{}[]:;<>,.?",
3978
- alphanumeric: "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
3979
- matrix: "010101<>[]{}+=*~#%&!?/\\:;|X0123456789",
3980
- binary: "01",
3981
- hex: "0123456789ABCDEF"
3982
- };
3983
- function getScramblePool(charset, customCharset) {
3984
- if (charset === "custom" && customCharset && customCharset.length > 0) return customCharset;
3985
- return SCRAMBLE_POOLS[charset] ?? SCRAMBLE_POOLS.alphanumeric;
3986
- }
3987
- /**
3988
- * Evaluates typewriter visible character count and scramble state for frame `currentFrame`.
3989
- */
3990
- function evaluateTypewriterState(fullText, currentFrame, startFrame, durationFrames, cadence = {
3991
- mode: "human",
3992
- jitter: .35,
3993
- commaPauseMultiplier: 3,
3994
- sentencePauseMultiplier: 5.5,
3995
- paragraphPauseMultiplier: 7
3996
- }, scramble = {
3997
- enabled: false,
3998
- charset: "alphanumeric",
3999
- scrambleFramesPerChar: 8,
4000
- highlightProbability: .25
4001
- }, blinkFrequency = 2, granularity = "character", progressOverride) {
4002
- if (progressOverride === void 0 && currentFrame < startFrame) return {
4003
- visibleChars: 0,
4004
- currentDisplayString: "",
4005
- isCursorVisible: false
4006
- };
4007
- const progress = progressOverride !== void 0 ? Math.max(0, Math.min(1, progressOverride)) : Math.min(1, (currentFrame - startFrame) / Math.max(1, durationFrames));
4008
- const elapsed = progressOverride !== void 0 ? progress * durationFrames : currentFrame - startFrame;
4009
- const totalChars = fullText.length;
4010
- let visibleCount = Math.floor(progress * totalChars);
4011
- if (granularity === "word") {
4012
- const tokens = fullText.split(/(\s+)/);
4013
- const wordIndices = [];
4014
- tokens.forEach((t, i) => {
4015
- if (t.trim().length > 0) wordIndices.push(i);
4016
- });
4017
- const visibleWords = Math.min(wordIndices.length, Math.floor(progress * (wordIndices.length + 1)));
4018
- if (visibleWords <= 0) visibleCount = 0;
4019
- else {
4020
- const lastIdx = wordIndices[Math.min(wordIndices.length - 1, visibleWords - 1)];
4021
- visibleCount = tokens.slice(0, lastIdx + 1).join("").length;
4022
- }
4023
- } else if (granularity === "line") {
4024
- const lines = fullText.split("\n");
4025
- const visibleLines = Math.min(lines.length, Math.floor(progress * (lines.length + 1)));
4026
- visibleCount = lines.slice(0, visibleLines).join("\n").length;
4027
- } else if (cadence.mode === "human" && progress < 1) {
4028
- let simulatedCharIndex = 0;
4029
- let simulatedElapsed = 0;
4030
- const baseFramesPerChar = durationFrames / Math.max(1, totalChars);
4031
- for (let i = 0; i < totalChars; i++) {
4032
- const char = fullText[i];
4033
- let multiplier = 1;
4034
- const commaMult = cadence.commaPauseMultiplier ?? 3;
4035
- const sentenceMult = cadence.sentencePauseMultiplier ?? 5.5;
4036
- const paraMult = cadence.paragraphPauseMultiplier ?? 7;
4037
- const jitter = cadence.jitter ?? .35;
4038
- if (char === "," || char === ";") multiplier = commaMult;
4039
- else if (char === "." || char === "!" || char === "?") multiplier = sentenceMult;
4040
- else if (char === "\n") multiplier = paraMult;
4041
- const jitterVal = 1 + Math.sin(i * 17.3 + 42) * .5 * jitter;
4042
- const charDuration = baseFramesPerChar * multiplier * jitterVal;
4043
- simulatedElapsed += charDuration;
4044
- if (simulatedElapsed <= elapsed) simulatedCharIndex = i + 1;
4045
- else break;
4046
- }
4047
- visibleCount = Math.min(totalChars, simulatedCharIndex);
4048
- }
4049
- let displayStr = fullText.slice(0, visibleCount);
4050
- if (scramble.enabled && visibleCount < totalChars && visibleCount > 0) {
4051
- const pool = getScramblePool(scramble.charset, scramble.customCharset);
4052
- const trailCount = Math.min(visibleCount, Math.max(1, scramble.scrambleFramesPerChar > 4 ? 3 : 2));
4053
- let scrambledTail = "";
4054
- for (let t = 0; t < trailCount; t++) {
4055
- const idx = Math.floor(Math.abs(Math.sin(currentFrame * 7 + t * 13)) * pool.length) % pool.length;
4056
- scrambledTail += pool[idx];
4057
- }
4058
- displayStr = displayStr.slice(0, displayStr.length - trailCount) + scrambledTail;
4059
- }
4060
- let isCursorVisible = true;
4061
- if (blinkFrequency > 0) {
4062
- const halfPeriodFrames = Math.max(1, Math.round(30 / (2 * blinkFrequency)));
4063
- isCursorVisible = Math.floor(elapsed / halfPeriodFrames) % 2 === 0;
4064
- }
4065
- return {
4066
- visibleChars: visibleCount,
4067
- currentDisplayString: displayStr,
4068
- isCursorVisible
4069
- };
1813
+ /** Returns the tree with every `matte` turned into a sibling matte layer. */
1814
+ function hoistMattes(nodes) {
1815
+ return nodes.flatMap((n) => hoistOne(n));
4070
1816
  }
4071
1817
  /** number px | "auto" (intrinsic) | "fit" (shrink-wrap) | "fill" (parent extent). */
4072
1818
  const SizeSpecSchema = z.union([
@@ -4847,6 +2593,11 @@ const TextFields = {
4847
2593
  "center",
4848
2594
  "end"
4849
2595
  ]).optional(),
2596
+ direction: z.enum([
2597
+ "ltr",
2598
+ "rtl",
2599
+ "auto"
2600
+ ]).optional(),
4850
2601
  verticalAlign: z.enum([
4851
2602
  "top",
4852
2603
  "middle",
@@ -4891,6 +2642,7 @@ const MediaNodeSchema = z.object({
4891
2642
  "fill",
4892
2643
  "none"
4893
2644
  ]).default("contain"),
2645
+ dpr: z.number().min(1).max(4).optional(),
4894
2646
  borderRadius: z.number().min(0).optional(),
4895
2647
  borderColor: ColorSchema.optional(),
4896
2648
  borderWidth: z.number().min(0).optional(),
@@ -4913,6 +2665,11 @@ const MediaNodeSchema = z.object({
4913
2665
  "center",
4914
2666
  "end"
4915
2667
  ]).optional(),
2668
+ direction: z.enum([
2669
+ "ltr",
2670
+ "rtl",
2671
+ "auto"
2672
+ ]).optional(),
4916
2673
  verticalAlign: z.enum([
4917
2674
  "top",
4918
2675
  "middle",
@@ -5272,11 +3029,12 @@ function applyStaggerToChildren(children, staggerFrames, direction = "forward",
5272
3029
  function nodeToVirtualMedia(node, resolveMedia, fps, inheritedOffset = 0, compDurationMs, inheritedDurationFrames) {
5273
3030
  let children = [];
5274
3031
  const sourceRef = node.src ?? node.inputHandleId;
5275
- const isDirectMediaSource = (s) => typeof s === "string" && (s.startsWith("http://") || s.startsWith("https://") || s.startsWith("file://") || s.startsWith("/") || s.startsWith("./") || s.startsWith("blob:") || s.startsWith("data:") || /\.(png|jpe?g|webp|gif|svg|mp4|webm|mov|mkv|mp3|wav|ogg|m4a|srt|vtt)$/i.test(s));
3032
+ const isDirectMediaSource = (s) => typeof s === "string" && (s.startsWith("http://") || s.startsWith("https://") || s.startsWith("file://") || s.startsWith("/") || s.startsWith("./") || s.startsWith("blob:") || s.startsWith("data:") || /\.(png|jpe?g|webp|gif|svg|mp4|webm|mov|mkv|mp3|wav|ogg|m4a|srt|vtt|json|lottie)$/i.test(s));
5276
3033
  let media;
5277
3034
  if (node.kind === "media") {
5278
3035
  if (resolveMedia) media = resolveMedia(node.inputHandleId);
5279
3036
  if (!media && sourceRef && (isDirectMediaSource(sourceRef) || node.src)) media = createVirtualMedia(sourceRef, node.dataType ?? "Video");
3037
+ if (!media && !resolveMedia && sourceRef && (sourceRef.includes(".") || sourceRef.includes("/"))) console.warn(`[Compositor] Media layer '${node.id ?? "?"}' source '${sourceRef}' could not be resolved.`);
5280
3038
  if (media && node.crop) {
5281
3039
  const cropRaw = node.crop;
5282
3040
  const cropOp = typeof cropRaw.toOperation === "function" ? cropRaw.toOperation() : cropRaw;
@@ -5442,5 +3200,5 @@ function collectNodeOps(nodes) {
5442
3200
  }
5443
3201
 
5444
3202
  //#endregion
5445
- export { TextAnimatorSchema as $, mergeAnimationTracks as $t, LightTypeSchema as A, computeRangeSelectorWeight as At, SceneTransitionTypeSchema as B, evaluateSelectorCombination as Bt, FlexNodeSchema as C, collectNodeOps as Ct, LayerAnimation as D, computeLayout as Dt, KineticMarqueeConfigSchema as E, computeCarrierContinuity as Et, MediaNodeSchema as F, evaluateAnimationAtFrame as Ft, Sequence as G, evaluateVolumetricFormation as Gt, SelectorModeSchema as H, evaluateSpringProgress as Ht, Model3DNodeSchema as I, evaluateCubicBezier as It, Spatial3DPropertiesSchema as J, getScramblePool as Jt, ShapeNodeSchema as K, generateArcLengthLUT as Kt, ParticleDissolveConfigSchema as L, evaluateCubicBezierDerivative as Lt, LongShadowConfigSchema as M, deterministicWigglyNoise as Mt, MaterialTypeSchema as N, distanceToCurveParameter as Nt, LayoutNodeSchema as O, computeLayoutSync as Ot, MatteModeSchema as P, ellipseToCubicBeziers as Pt, TextAnimatorBuilder as Q, lintComposition as Qt, Scene as R, evaluateExpressionSelector as Rt, ExtendedGlyphPropertiesSchema as S, calculateSequenceTimeline as St, GlyphAnchorPointSchema as T, computeAnchorPivotOffset as Tt, SelectorShapeSchema as U, evaluateTrackAtFrame as Ut, SelectorBasedOnSchema as V, evaluateSkewMatrix as Vt, SelectorUnitsSchema as W, evaluateTypewriterState as Wt, TextAnchorConfigSchema as X, hoistMattes as Xt, SpringPhysicsSchema as Y, getShuffledOrder as Yt, TextAnimator as Z, initLayout as Zt, DynamicStrokePropertiesSchema as _, Vec2Schema as _t, AnchorPresetSchema as a, TextPathSourceSchema as at, EnvironmentPresetSchema as b, applyStaggerToChildren as bt, BloomConfigSchema as c, TextSelectorSchema as ct, CameraNodeSchema as d, TextSpanSchema as dt, parseSvgPathToCubicBeziers as en, TextCursorConfigSchema as et, CarrierHandoffConfigSchema as f, TextWigglySelectorSchema as ft, CubicBezierSegmentSchema as g, VariableFontAxesSchema as gt, CompositorProgramSchema as h, TypingCadenceSchema as ht, AnchorGroupingSchema as i, waveToCubicBeziers as in, TextPathOptionsSchema as it, LineSpacingDynamicsSchema as j, computeStaggerDelay as jt, LightNodeSchema as k, computeLineLeadingDisplacement as kt, BoxNodeSchema as l, TextSignalSelectorSchema as lt, ColorStopSchema as m, TypewriterAnimatorSchema as mt, AdvancedTextAnimatorBuilder as n, sampleCurveGeometry as nn, TextNodeSchema as nt, AnimatableGlyphPropsSchema as o, TextRangeSelectorSchema as ot, ChromaticGlitchConfigSchema as p, ToneMappingSchema as pt, SkewPropertiesSchema as q, generatePathSegments as qt, AdvancedTextAnimatorSchema as r, samplePathChainGeometry as rn, TextPathBuilder as rt, AudioSpectrumTypographySchema as s, TextScrambleConfigSchema as st, AETextAnimatorSchema as t, sampleAudioSpectrumScale as tn, TextCursorStyleSchema as tt, CameraAnimation as u, TextSpanMarkSchema as ut, EnhancedTextNodeSchema as v, VolumetricFormationConfigSchema as vt, GlyphAnchorGroupingSchema as w, compositorToProgram as wt, ExpressionSelectorSchema as x, buildPathLUT as xt, EnvironmentFogSchema as y, VolumetricFormationModeSchema as yt, SceneDefinitionSchema as z, evaluateMarqueeOffset as zt };
5446
- //# sourceMappingURL=program-BmNKgzja.mjs.map
3203
+ export { applyStaggerToChildren as A, hoistMattes as B, ShapeNodeSchema as C, TextSpanMarkSchema as D, TextNodeSchema as E, computeLayout as F, lintComposition as H, computeLayoutSync as I, computeStaggerDelay as L, collectNodeOps as M, compositorToProgram as N, TextSpanSchema as O, computeCarrierContinuity as P, evaluateAnimationAtFrame as R, Sequence as S, TextAnimatorSchema as T, mergeAnimationTracks as U, initLayout as V, MediaNodeSchema as _, CarrierHandoffConfigSchema as a, SceneDefinitionSchema as b, EnvironmentFogSchema as c, LayerAnimation as d, LayoutNodeSchema as f, MatteModeSchema as g, MaterialTypeSchema as h, CameraNodeSchema as i, calculateSequenceTimeline as j, ToneMappingSchema as k, EnvironmentPresetSchema as l, LightTypeSchema as m, BoxNodeSchema as n, ColorStopSchema as o, LightNodeSchema as p, CameraAnimation as r, CompositorProgramSchema as s, BloomConfigSchema as t, FlexNodeSchema as u, Model3DNodeSchema as v, TextAnimator as w, SceneTransitionTypeSchema as x, Scene as y, evaluateTrackAtFrame as z };
3204
+ //# sourceMappingURL=program-BqFVw5Mu.mjs.map