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.
- package/README.md +22 -5
- package/dist/audio/index.d.mts +4 -4
- package/dist/audio/index.mjs +13 -12
- package/dist/{audio-BHanw8Jb.d.mts → audio-C2fLC3Tx.d.mts} +3 -3
- package/dist/{audio-BHanw8Jb.d.mts.map → audio-C2fLC3Tx.d.mts.map} +1 -1
- package/dist/{audio-TAvPwzLR.mjs → audio-DJeVoE8b.mjs} +1 -1
- package/dist/{audio-TAvPwzLR.mjs.map → audio-DJeVoE8b.mjs.map} +1 -1
- package/dist/{audio-COOMNwL5.mjs → audio-D_4SeMRK.mjs} +4 -4
- package/dist/{audio-COOMNwL5.mjs.map → audio-D_4SeMRK.mjs.map} +1 -1
- package/dist/{client-CwRhflHE.mjs → client-dVxUnmHz.mjs} +1 -1
- package/dist/{client-CwRhflHE.mjs.map → client-dVxUnmHz.mjs.map} +1 -1
- package/dist/{dist-C_hjvkdN.mjs → dist-0QGroRYZ.mjs} +1 -1
- package/dist/{dist-C_hjvkdN.mjs.map → dist-0QGroRYZ.mjs.map} +1 -1
- package/dist/{dist-BYqNNwsl.mjs → dist-BY0bIWgr.mjs} +10 -2
- package/dist/dist-BY0bIWgr.mjs.map +1 -0
- package/dist/{dist-Cxi68OuY.mjs → dist-Bun_TUvZ.mjs} +26862 -25638
- package/dist/dist-Bun_TUvZ.mjs.map +1 -0
- package/dist/{dist-BAVZdFEJ.mjs → dist-DlzqyRar.mjs} +75 -618
- package/dist/dist-DlzqyRar.mjs.map +1 -0
- package/dist/{dist-cjs-TsA8LFXC.mjs → dist-cjs-91nR6B7Z.mjs} +3 -3
- package/dist/{dist-cjs-TsA8LFXC.mjs.map → dist-cjs-91nR6B7Z.mjs.map} +1 -1
- package/dist/{dist-cjs-DJ8fcQEe.mjs → dist-cjs-BAIenEMC.mjs} +11 -11
- package/dist/{dist-cjs-DJ8fcQEe.mjs.map → dist-cjs-BAIenEMC.mjs.map} +1 -1
- package/dist/{dist-cjs-BmyyWYWv.mjs → dist-cjs-BEQhh76X.mjs} +2 -2
- package/dist/{dist-cjs-BmyyWYWv.mjs.map → dist-cjs-BEQhh76X.mjs.map} +1 -1
- package/dist/{dist-cjs--pxyGFw2.mjs → dist-cjs-BYPq7pfw.mjs} +1 -1
- package/dist/{dist-cjs--pxyGFw2.mjs.map → dist-cjs-BYPq7pfw.mjs.map} +1 -1
- package/dist/{dist-cjs--lfMLs3U.mjs → dist-cjs-BocDqSCX.mjs} +4 -4
- package/dist/{dist-cjs--lfMLs3U.mjs.map → dist-cjs-BocDqSCX.mjs.map} +1 -1
- package/dist/{dist-cjs-CsU2sZoX.mjs → dist-cjs-CWiNggTl.mjs} +4 -4
- package/dist/{dist-cjs-CsU2sZoX.mjs.map → dist-cjs-CWiNggTl.mjs.map} +1 -1
- package/dist/{dist-cjs-DjzmP0-x.mjs → dist-cjs-CwabutT6.mjs} +13 -13
- package/dist/{dist-cjs-DjzmP0-x.mjs.map → dist-cjs-CwabutT6.mjs.map} +1 -1
- package/dist/{dist-cjs-BDpO-TH_.mjs → dist-cjs-D-EE4Ahy.mjs} +1 -1
- package/dist/{dist-cjs-BDpO-TH_.mjs.map → dist-cjs-D-EE4Ahy.mjs.map} +1 -1
- package/dist/{dist-cjs-CQwmMllY.mjs → dist-cjs-DNtDUWfk.mjs} +6 -6
- package/dist/{dist-cjs-CQwmMllY.mjs.map → dist-cjs-DNtDUWfk.mjs.map} +1 -1
- package/dist/{dist-cjs-CND_ghfH.mjs → dist-cjs-DbZhsgS0.mjs} +1 -1
- package/dist/{dist-cjs-CND_ghfH.mjs.map → dist-cjs-DbZhsgS0.mjs.map} +1 -1
- package/dist/{dist-cjs-CgFzrgj8.mjs → dist-cjs-Dh7REKcN.mjs} +1 -1
- package/dist/{dist-cjs-CgFzrgj8.mjs.map → dist-cjs-Dh7REKcN.mjs.map} +1 -1
- package/dist/{dist-cjs-DT2jJlcK.mjs → dist-cjs-Dobx0Nz-.mjs} +5 -5
- package/dist/{dist-cjs-DT2jJlcK.mjs.map → dist-cjs-Dobx0Nz-.mjs.map} +1 -1
- package/dist/{dist-cjs-DzjrlfbE.mjs → dist-cjs-Du0UpNof.mjs} +14 -14
- package/dist/{dist-cjs-DzjrlfbE.mjs.map → dist-cjs-Du0UpNof.mjs.map} +1 -1
- package/dist/dist-cjs-DyHiUfsr.mjs +6 -0
- package/dist/{dist-cjs-M-8QOgS_.mjs → dist-cjs-HHMfMF5a.mjs} +2 -2
- package/dist/{dist-cjs-M-8QOgS_.mjs.map → dist-cjs-HHMfMF5a.mjs.map} +1 -1
- package/dist/{dist-cjs-BiKQozdJ.mjs → dist-cjs-UJYQzLNT.mjs} +3 -3
- package/dist/{dist-cjs-BiKQozdJ.mjs.map → dist-cjs-UJYQzLNT.mjs.map} +1 -1
- package/dist/{dist-cjs-agQl9T8M.mjs → dist-cjs-UKxm5cFR.mjs} +6 -6
- package/dist/{dist-cjs-agQl9T8M.mjs.map → dist-cjs-UKxm5cFR.mjs.map} +1 -1
- package/dist/{dist-CbG3QxDw.mjs → dist-fjKpBYkc.mjs} +12 -27
- package/dist/dist-fjKpBYkc.mjs.map +1 -0
- package/dist/effects/index.d.mts +4 -4
- package/dist/effects/index.mjs +36 -34
- package/dist/{effects-DzbjFhyA.mjs → effects-FTlu0dri.mjs} +3 -3
- package/dist/{effects-DzbjFhyA.mjs.map → effects-FTlu0dri.mjs.map} +1 -1
- package/dist/{event-streams-BaNGaLxh.mjs → event-streams-DnRe8uwT.mjs} +2 -2
- package/dist/{event-streams-BaNGaLxh.mjs.map → event-streams-DnRe8uwT.mjs.map} +1 -1
- package/dist/fonts/index.d.mts +1 -1
- package/dist/fonts/index.mjs +3 -1
- package/dist/{fonts-C0W6TgJk.mjs → fonts-UM5xaBOx.mjs} +24 -11
- package/dist/fonts-UM5xaBOx.mjs.map +1 -0
- package/dist/gpu-RkpiFGOA.mjs +215 -0
- package/dist/gpu-RkpiFGOA.mjs.map +1 -0
- package/dist/{index-CYGpSVsf.d.mts → index-CHQ39_Oe.d.mts} +2 -2
- package/dist/{index-CYGpSVsf.d.mts.map → index-CHQ39_Oe.d.mts.map} +1 -1
- package/dist/{index-CDoTrMs1.d.mts → index-CzQseCtg.d.mts} +8 -8
- package/dist/{index-CDoTrMs1.d.mts.map → index-CzQseCtg.d.mts.map} +1 -1
- package/dist/{index-DDEPvMww.d.mts → index-D67p-rHX.d.mts} +3452 -1675
- package/dist/index-D67p-rHX.d.mts.map +1 -0
- package/dist/{index-9B8CJowc.d.mts → index-DPicEt8H.d.mts} +10 -2
- package/dist/index-DPicEt8H.d.mts.map +1 -0
- package/dist/{index-DGJp1d30.d.mts → index-Db8Z3AtX.d.mts} +3 -3
- package/dist/{index-DGJp1d30.d.mts.map → index-Db8Z3AtX.d.mts.map} +1 -1
- package/dist/{index-DRZu3ezy.d.mts → index-DsOqONsj.d.mts} +3 -3
- package/dist/{index-DRZu3ezy.d.mts.map → index-DsOqONsj.d.mts.map} +1 -1
- package/dist/{index-DnWsbbuZ.d.mts → index-l03NV8JS.d.mts} +7 -2
- package/dist/index-l03NV8JS.d.mts.map +1 -0
- package/dist/index.d.mts +28 -1841
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +79 -65
- package/dist/index.mjs.map +1 -1
- package/dist/{package-XpCRbTOA.mjs → package-CudzAF-n.mjs} +1 -1
- package/dist/{package-XpCRbTOA.mjs.map → package-CudzAF-n.mjs.map} +1 -1
- package/dist/preview/index.d.mts +2 -2
- package/dist/preview/index.mjs +13 -12
- package/dist/{preview-BV2C4Fk6.mjs → preview-DwClLMlU.mjs} +3 -3
- package/dist/{preview-BV2C4Fk6.mjs.map → preview-DwClLMlU.mjs.map} +1 -1
- package/dist/preview-engine/audio.mjs +1 -1
- package/dist/preview-engine/{chunk-Y6HWYPKX.mjs → chunk-3GNP7TJH.mjs} +3 -3
- package/dist/preview-engine/{chunk-LIHUEYI5.mjs → chunk-44CQSOYE.mjs} +2 -2
- package/dist/preview-engine/{chunk-6JW37VJA.mjs → chunk-5AUB4Y3L.mjs} +3 -23
- package/dist/preview-engine/chunk-5DOD2NVY.mjs +26 -0
- package/dist/preview-engine/chunk-5FC7GOWW.mjs +474 -0
- package/dist/preview-engine/chunk-5W4AFQP7.mjs +97 -0
- package/dist/preview-engine/chunk-63SFBHEH.mjs +1 -0
- package/dist/preview-engine/chunk-7EPIRODI.mjs +91 -0
- package/dist/preview-engine/{chunk-PQD5UPHG.mjs → chunk-7G3XIOP7.mjs} +1 -1
- package/dist/preview-engine/chunk-7J2FWGVD.mjs +1 -0
- package/dist/preview-engine/chunk-AXHB4J37.mjs +147 -0
- package/dist/preview-engine/chunk-AY7UX37L.mjs +450 -0
- package/dist/preview-engine/chunk-B43Z3J7J.mjs +5 -0
- package/dist/preview-engine/chunk-BWJS6G7R.mjs +314 -0
- package/dist/preview-engine/{chunk-24DXIKXL.mjs → chunk-DIGIQ5MJ.mjs} +2 -2
- package/dist/preview-engine/{chunk-AEK5BO3J.mjs → chunk-E4RAFHZM.mjs} +1 -1
- package/dist/preview-engine/chunk-ENKKLU7B.mjs +22 -0
- package/dist/preview-engine/{chunk-XLFYM7KH.mjs → chunk-EVXWDOCL.mjs} +2 -2
- package/dist/preview-engine/{chunk-EQ4QZRXB.mjs → chunk-EYWPOCZW.mjs} +2 -2
- package/dist/preview-engine/{chunk-IYVN2QEL.mjs → chunk-FLPSWDX4.mjs} +1 -1
- package/dist/preview-engine/chunk-FU7AIAMM.mjs +88 -0
- package/dist/preview-engine/{chunk-CBM7B7EW.mjs → chunk-GMGGDADT.mjs} +1 -1
- package/dist/preview-engine/chunk-GSFN4WCH.mjs +62 -0
- package/dist/preview-engine/chunk-HE4R7EZM.mjs +121 -0
- package/dist/preview-engine/chunk-IQC2I5A5.mjs +1 -0
- package/dist/preview-engine/{chunk-RJUAM52F.mjs → chunk-IR5DNNWR.mjs} +3 -23
- package/dist/preview-engine/chunk-IUPDOATX.mjs +114 -0
- package/dist/preview-engine/{chunk-GHMCGTJ2.mjs → chunk-J2R5R7YY.mjs} +3 -23
- package/dist/preview-engine/chunk-JAJOZG5P.mjs +1 -0
- package/dist/preview-engine/chunk-JXNG2ACR.mjs +118 -0
- package/dist/preview-engine/{chunk-V6VU46ZG.mjs → chunk-L6BH5J4P.mjs} +1 -1
- package/dist/preview-engine/chunk-LGVEFPOG.mjs +3 -0
- package/dist/preview-engine/{chunk-MDDF2GCF.mjs → chunk-MLY5M7Y5.mjs} +3 -23
- package/dist/preview-engine/chunk-NPD6W3RP.mjs +1 -0
- package/dist/preview-engine/chunk-OCX5AD23.mjs +1 -0
- package/dist/preview-engine/{chunk-D3TETPLI.mjs → chunk-OG62XGCT.mjs} +1 -1
- package/dist/preview-engine/chunk-OJ2PKBXE.mjs +40 -0
- package/dist/preview-engine/chunk-OKH2VU2U.mjs +97 -0
- package/dist/preview-engine/chunk-PAQNDZQB.mjs +83 -0
- package/dist/preview-engine/chunk-PEWYB6WP.mjs +43 -0
- package/dist/preview-engine/chunk-PL4IH5V4.mjs +89 -0
- package/dist/preview-engine/chunk-PSRQA3QW.mjs +84 -0
- package/dist/preview-engine/{chunk-QYRDQMNB.mjs → chunk-PXT52LEH.mjs} +3 -23
- package/dist/preview-engine/chunk-Q22PJXFJ.mjs +69 -0
- package/dist/preview-engine/chunk-Q4Z54DQ7.mjs +1 -0
- package/dist/preview-engine/{chunk-BHFI3Y4T.mjs → chunk-QBEUICZD.mjs} +1 -1
- package/dist/preview-engine/chunk-RQLMW6MA.mjs +4 -0
- package/dist/preview-engine/chunk-RSMO7NPN.mjs +1 -0
- package/dist/preview-engine/chunk-RW2F3XLQ.mjs +90 -0
- package/dist/preview-engine/{chunk-25IW7NYO.mjs → chunk-S2CTIJSI.mjs} +1 -1
- package/dist/preview-engine/chunk-SGPRLTNF.mjs +52 -0
- package/dist/preview-engine/{chunk-Y6FEU4TV.mjs → chunk-SZW5J72T.mjs} +3 -23
- package/dist/preview-engine/{chunk-ECPP3UG6.mjs → chunk-T2FE5VOW.mjs} +3 -23
- package/dist/preview-engine/{chunk-ZSIJB76A.mjs → chunk-TS3JI3BH.mjs} +2 -2
- package/dist/preview-engine/{chunk-AMBSW6OA.mjs → chunk-U4JIFQRR.mjs} +2 -2
- package/dist/preview-engine/{chunk-BJKH76OM.mjs → chunk-VXS5SIEC.mjs} +3 -23
- package/dist/preview-engine/chunk-WFGJXCZT.mjs +53 -0
- package/dist/preview-engine/chunk-WH5Q2NFN.mjs +32 -0
- package/dist/preview-engine/{chunk-AWTH2WZO.mjs → chunk-WUKH7BD7.mjs} +1 -1
- package/dist/preview-engine/chunk-XC5WZNOY.mjs +1448 -0
- package/dist/preview-engine/chunk-YQZOGEPZ.mjs +186 -0
- package/dist/preview-engine/{chunk-6256GQFP.mjs → chunk-ZDQF3OTC.mjs} +1 -1
- package/dist/preview-engine/chunk-ZIIFTWDH.mjs +58 -0
- package/dist/preview-engine/effects.mjs +1 -1
- package/dist/preview-engine/fonts.mjs +1 -1
- package/dist/preview-engine/framefields.mjs +127 -130
- package/dist/preview-engine/player.mjs +6 -6
- package/dist/preview-engine/renderers-2H7YEUTD.mjs +1 -0
- package/dist/preview-engine/renderers-2ILG23ED.mjs +1 -0
- package/dist/preview-engine/renderers-2P6KXWEZ.mjs +1 -0
- package/dist/preview-engine/renderers-2SVWAB42.mjs +1 -0
- package/dist/preview-engine/renderers-2VN3AH45.mjs +104 -0
- package/dist/preview-engine/renderers-3RC5FDWX.mjs +1 -0
- package/dist/preview-engine/renderers-57WDL6XN.mjs +1 -0
- package/dist/preview-engine/{renderers-CAUWP4XH.mjs → renderers-6OGFUSH6.mjs} +3 -23
- package/dist/preview-engine/renderers-6WH7NZCC.mjs +1 -0
- package/dist/preview-engine/renderers-7VJN5L3Z.mjs +1 -0
- package/dist/preview-engine/renderers-A6HM64UZ.mjs +1 -0
- package/dist/preview-engine/{renderers-WLH4HRUE.mjs → renderers-A7VH3ON5.mjs} +1 -1
- package/dist/preview-engine/renderers-B7DSGUMI.mjs +1 -0
- package/dist/preview-engine/renderers-BFNJ7VCI.mjs +1 -0
- package/dist/preview-engine/renderers-BSKZXITT.mjs +35 -0
- package/dist/preview-engine/renderers-CGYIDAVV.mjs +1 -0
- package/dist/preview-engine/renderers-CRRLV7IO.mjs +1 -0
- package/dist/preview-engine/{renderers-JQHUBWLL.mjs → renderers-D6T6IPER.mjs} +3 -23
- package/dist/preview-engine/renderers-DXHJAMZR.mjs +1 -0
- package/dist/preview-engine/renderers-ECA3P4ON.mjs +1 -0
- package/dist/preview-engine/{renderers-W5CVDJVH.mjs → renderers-F55XFVMP.mjs} +1 -1
- package/dist/preview-engine/renderers-FWGMNPYB.mjs +1 -0
- package/dist/preview-engine/renderers-H46TS3IG.mjs +228 -0
- package/dist/preview-engine/renderers-HXFRTIJD.mjs +1 -0
- package/dist/preview-engine/renderers-IWQ3V6AJ.mjs +1 -0
- package/dist/preview-engine/renderers-JHFT27YU.mjs +1 -0
- package/dist/preview-engine/renderers-KZWGSKRF.mjs +1 -0
- package/dist/preview-engine/renderers-MON4QFRF.mjs +1 -0
- package/dist/preview-engine/renderers-NQXMYNSY.mjs +1 -0
- package/dist/preview-engine/renderers-NWHS7N2L.mjs +1 -0
- package/dist/preview-engine/renderers-ORAIXUL3.mjs +1 -0
- package/dist/preview-engine/renderers-OT7D3BUA.mjs +1 -0
- package/dist/preview-engine/renderers-Q4OFCMXI.mjs +1 -0
- package/dist/preview-engine/renderers-QVZVEYP5.mjs +1 -0
- package/dist/preview-engine/renderers-RJO6H4FC.mjs +1 -0
- package/dist/preview-engine/renderers-RKDPX5JU.mjs +1 -0
- package/dist/preview-engine/{renderers-2US2NIUG.mjs → renderers-RLHTNLRE.mjs} +3 -23
- package/dist/preview-engine/renderers-SBFF7JP5.mjs +1 -0
- package/dist/preview-engine/renderers-SCJ6OKTB.mjs +1 -0
- package/dist/preview-engine/renderers-T4JMJXWL.mjs +1 -0
- package/dist/preview-engine/renderers-TAWT3ZSS.mjs +1 -0
- package/dist/preview-engine/renderers-U6KY34TP.mjs +100 -0
- package/dist/preview-engine/renderers-UHTO6BQA.mjs +1 -0
- package/dist/preview-engine/renderers-UNK6I4JJ.mjs +1 -0
- package/dist/preview-engine/renderers-UPTJJE5F.mjs +1 -0
- package/dist/preview-engine/renderers-W773SBPV.mjs +1 -0
- package/dist/preview-engine/renderers-XHTMRXC5.mjs +1 -0
- package/dist/preview-engine/renderers-YECY2YFT.mjs +1 -0
- package/dist/preview-engine/renderers-YMN6QXK7.mjs +1 -0
- package/dist/preview-engine/renderers-ZANPE3OK.mjs +1 -0
- package/dist/preview-engine/renderers-ZHTX73PR.mjs +1 -0
- package/dist/preview-engine/renderers-ZJTRANIX.mjs +1 -0
- package/dist/preview-engine/signals.mjs +1 -1
- package/dist/preview-engine/skia-canvas-QBXAOGPB.mjs +1 -0
- package/dist/{program-BmNKgzja.mjs → program-BqFVw5Mu.mjs} +93 -2335
- package/dist/program-BqFVw5Mu.mjs.map +1 -0
- package/dist/renderer/index.d.mts +2 -2
- package/dist/renderer/index.mjs +3 -3
- package/dist/{renderer-CnXW28b9.mjs → renderer-2Nf9ypST.mjs} +85 -279
- package/dist/renderer-2Nf9ypST.mjs.map +1 -0
- package/dist/{renderer-BREIjsUU.mjs → renderer-2uN2cd0y.mjs} +14 -40
- package/dist/renderer-2uN2cd0y.mjs.map +1 -0
- package/dist/renderer-31jAuNzF.mjs +5 -0
- package/dist/renderer-36EI7Rsz.mjs +5 -0
- package/dist/renderer-3io-cjTt.mjs +5 -0
- package/dist/renderer-9_zWTHbg.mjs +5 -0
- package/dist/{renderer-WSGuj_V6.mjs → renderer-B12_76qk.mjs} +4 -3
- package/dist/{renderer-WSGuj_V6.mjs.map → renderer-B12_76qk.mjs.map} +1 -1
- package/dist/{renderer-bsWnRNpJ.mjs → renderer-B4oS8ZFO.mjs} +29 -98
- package/dist/renderer-B4oS8ZFO.mjs.map +1 -0
- package/dist/renderer-B6KnbfdA.mjs +5 -0
- package/dist/renderer-B7Y2bmRc.mjs +5 -0
- package/dist/renderer-BA6miaaI.mjs +5 -0
- package/dist/{renderer-Bv6q84TU.mjs → renderer-BGr_cBKV.mjs} +61 -208
- package/dist/renderer-BGr_cBKV.mjs.map +1 -0
- package/dist/renderer-BHi-Q6Z_.mjs +5 -0
- package/dist/{renderer-Bv21DbWy.mjs → renderer-BLcu9RDt.mjs} +3 -1
- package/dist/{renderer-D2XD4QYk.mjs → renderer-BO2lYmtE.mjs} +34 -147
- package/dist/renderer-BO2lYmtE.mjs.map +1 -0
- package/dist/renderer-BOlN9HeG.mjs +5 -0
- package/dist/renderer-BSitV56h.mjs +268 -0
- package/dist/renderer-BSitV56h.mjs.map +1 -0
- package/dist/renderer-BTOW-ceB.mjs +5 -0
- package/dist/{renderer-Bhdf90Zq.mjs → renderer-BYqfkwLf.mjs} +51 -163
- package/dist/renderer-BYqfkwLf.mjs.map +1 -0
- package/dist/{renderer-bZU_ndxf.mjs → renderer-BajIOuZH.mjs} +2 -2
- package/dist/{renderer-bZU_ndxf.mjs.map → renderer-BajIOuZH.mjs.map} +1 -1
- package/dist/{renderer-DirxsOjq.mjs → renderer-BgnJUx24.mjs} +80 -258
- package/dist/renderer-BgnJUx24.mjs.map +1 -0
- package/dist/renderer-BiQ0PYOp.mjs +5 -0
- package/dist/{renderer-DIgsilTw.mjs → renderer-BjTq3a0L.mjs} +5 -4
- package/dist/{renderer-DIgsilTw.mjs.map → renderer-BjTq3a0L.mjs.map} +1 -1
- package/dist/{renderer-DEJwPRkR.mjs → renderer-BkN20ZKO.mjs} +15 -51
- package/dist/renderer-BkN20ZKO.mjs.map +1 -0
- package/dist/renderer-Bla7GDyV.mjs +5 -0
- package/dist/renderer-BoYyLVKy.mjs +5 -0
- package/dist/{renderer-D7zvPHKn.mjs → renderer-BpZaHFRc.mjs} +18 -28
- package/dist/renderer-BpZaHFRc.mjs.map +1 -0
- package/dist/renderer-BqOgb7bM.mjs +5 -0
- package/dist/{renderer-cgxO2xN6.mjs → renderer-Bq_dO0LG.mjs} +10 -17
- package/dist/renderer-Bq_dO0LG.mjs.map +1 -0
- package/dist/renderer-BqeM8yTJ.mjs +5 -0
- package/dist/{renderer-dncoIVdd.mjs → renderer-BqsV75Ml.mjs} +3 -1
- package/dist/{renderer-ChdLYS-G.mjs → renderer-Bs4tz_pw.mjs} +20 -87
- package/dist/renderer-Bs4tz_pw.mjs.map +1 -0
- package/dist/{renderer-DpGc-N3G.mjs → renderer-Bsaokil3.mjs} +24 -104
- package/dist/renderer-Bsaokil3.mjs.map +1 -0
- package/dist/{renderer-CXn5HAnK.mjs → renderer-BvG1GF1c.mjs} +10 -16
- package/dist/renderer-BvG1GF1c.mjs.map +1 -0
- package/dist/{renderer-CI7sG_cv.mjs → renderer-BvpSIFkw.mjs} +83 -266
- package/dist/renderer-BvpSIFkw.mjs.map +1 -0
- package/dist/{renderer-B8UaFNqb.mjs → renderer-BwAqwTQq.mjs} +62 -209
- package/dist/renderer-BwAqwTQq.mjs.map +1 -0
- package/dist/{renderer-CzPWB0Ss.mjs → renderer-BwVfhrEx.mjs} +13 -45
- package/dist/renderer-BwVfhrEx.mjs.map +1 -0
- package/dist/renderer-BzpRe50i.mjs +5 -0
- package/dist/renderer-C0eAPwpr.mjs +5 -0
- package/dist/{renderer-CtyD_Xju.mjs → renderer-C3RfT8Gv.mjs} +59 -194
- package/dist/renderer-C3RfT8Gv.mjs.map +1 -0
- package/dist/{renderer-B1YMwl2B.mjs → renderer-C3cYDT3m.mjs} +3 -1
- package/dist/{renderer-1VuQTY1Z.mjs → renderer-CEGbqT2m.mjs} +236 -96
- package/dist/renderer-CEGbqT2m.mjs.map +1 -0
- package/dist/{renderer-DxTs4Iyi.mjs → renderer-CGldH-Zx.mjs} +40 -142
- package/dist/renderer-CGldH-Zx.mjs.map +1 -0
- package/dist/renderer-CGn8V63v.mjs +5 -0
- package/dist/{renderer-kwmlLQOO.mjs → renderer-CH9Qtpy7.mjs} +4 -4
- package/dist/{renderer-kwmlLQOO.mjs.map → renderer-CH9Qtpy7.mjs.map} +1 -1
- package/dist/{renderer-ho_jXJ0H.mjs → renderer-CLyuu_19.mjs} +23 -117
- package/dist/renderer-CLyuu_19.mjs.map +1 -0
- package/dist/renderer-CM5Syo9r.mjs +5 -0
- package/dist/{renderer-D2nCGcjv.mjs → renderer-CRIM_XRK.mjs} +3 -3
- package/dist/{renderer-D2nCGcjv.mjs.map → renderer-CRIM_XRK.mjs.map} +1 -1
- package/dist/{renderer-BTdOMMEx.d.mts → renderer-CTGe8SqQ.d.mts} +2 -2
- package/dist/{renderer-BTdOMMEx.d.mts.map → renderer-CTGe8SqQ.d.mts.map} +1 -1
- package/dist/renderer-CWCEW6Wv.mjs +5 -0
- package/dist/{renderer-Dy0utCl7.mjs → renderer-CgyOylPO.mjs} +10 -17
- package/dist/renderer-CgyOylPO.mjs.map +1 -0
- package/dist/{renderer-C_TPMHiH.mjs → renderer-CjT5Zy-J.mjs} +81 -221
- package/dist/renderer-CjT5Zy-J.mjs.map +1 -0
- package/dist/{renderer-_uvdg48N.mjs → renderer-Cjq1s3br.mjs} +24 -93
- package/dist/renderer-Cjq1s3br.mjs.map +1 -0
- package/dist/renderer-Cl70zxkP.mjs +5 -0
- package/dist/renderer-ClJjoVpB.mjs +6 -0
- package/dist/{renderer-BSaYG8aw.mjs → renderer-CpKNqciR.mjs} +3 -1
- package/dist/{renderer-Bfgd4N0O.mjs → renderer-Cwhux4VX.mjs} +9 -16
- package/dist/renderer-Cwhux4VX.mjs.map +1 -0
- package/dist/{renderer-BJ1aTkZf.mjs → renderer-D0nWLogn.mjs} +99 -282
- package/dist/renderer-D0nWLogn.mjs.map +1 -0
- package/dist/{renderer-vqkKWqa5.mjs → renderer-D1lynYuy.mjs} +23 -107
- package/dist/renderer-D1lynYuy.mjs.map +1 -0
- package/dist/{renderer-B8-kzZdP.mjs → renderer-D4sYVV-I.mjs} +41 -140
- package/dist/renderer-D4sYVV-I.mjs.map +1 -0
- package/dist/{renderer-Bc04fivZ.mjs → renderer-D5z3WDkm.mjs} +99 -287
- package/dist/renderer-D5z3WDkm.mjs.map +1 -0
- package/dist/renderer-D8C-pamu.mjs +148 -0
- package/dist/renderer-D8C-pamu.mjs.map +1 -0
- package/dist/{renderer-D_1oDOCP.mjs → renderer-DAtBnNGC.mjs} +14 -69
- package/dist/renderer-DAtBnNGC.mjs.map +1 -0
- package/dist/{renderer-DZGtBUCx.mjs → renderer-DG1NFsSV.mjs} +35 -185
- package/dist/renderer-DG1NFsSV.mjs.map +1 -0
- package/dist/{renderer-BM05sB8m.mjs → renderer-DHAErBtJ.mjs} +11 -74
- package/dist/renderer-DHAErBtJ.mjs.map +1 -0
- package/dist/{renderer-RKsXlF_0.mjs → renderer-DIDSmoFA.mjs} +73 -73
- package/dist/{renderer-RKsXlF_0.mjs.map → renderer-DIDSmoFA.mjs.map} +1 -1
- package/dist/{renderer-BDbTWSpP.mjs → renderer-DKtP7-fr.mjs} +58 -234
- package/dist/renderer-DKtP7-fr.mjs.map +1 -0
- package/dist/renderer-DLnF-V_h.mjs +5 -0
- package/dist/renderer-DN1rjmcL.mjs +5 -0
- package/dist/{renderer-CfC_aiew.mjs → renderer-DOEsFT7Q.mjs} +57 -192
- package/dist/renderer-DOEsFT7Q.mjs.map +1 -0
- package/dist/{renderer-Ctk2zzfy.mjs → renderer-DPYB6ZcB.mjs} +57 -197
- package/dist/renderer-DPYB6ZcB.mjs.map +1 -0
- package/dist/{renderer-CWTpc4ff.mjs → renderer-DRsPCkxr.mjs} +76 -210
- package/dist/renderer-DRsPCkxr.mjs.map +1 -0
- package/dist/renderer-DXTw9Oqb.mjs +5 -0
- package/dist/{renderer-CaaOKMSd.mjs → renderer-DZLJnnU2.mjs} +63 -190
- package/dist/renderer-DZLJnnU2.mjs.map +1 -0
- package/dist/{renderer-B2ieylQ3.mjs → renderer-DZrQffIP.mjs} +56 -167
- package/dist/renderer-DZrQffIP.mjs.map +1 -0
- package/dist/renderer-DbAVSBNI.mjs +5 -0
- package/dist/renderer-Dg8rD--8.mjs +5 -0
- package/dist/{renderer-DML9qpmS.mjs → renderer-DhEyjn6Q.mjs} +52 -202
- package/dist/renderer-DhEyjn6Q.mjs.map +1 -0
- package/dist/{renderer-CdciwwMI.mjs → renderer-Dmv_Aj6x.mjs} +161 -457
- package/dist/renderer-Dmv_Aj6x.mjs.map +1 -0
- package/dist/renderer-DnFxegGu.mjs +5 -0
- package/dist/renderer-DnfmelHn.mjs +5 -0
- package/dist/{renderer-BIIWCg_J.mjs → renderer-Dpj68gTn.mjs} +11 -18
- package/dist/renderer-Dpj68gTn.mjs.map +1 -0
- package/dist/renderer-DuOjzggd.mjs +5 -0
- package/dist/renderer-DuuOlYIG.mjs +3 -0
- package/dist/renderer-DvYql0Cl.mjs +5 -0
- package/dist/{renderer-BfAWZziM.mjs → renderer-DzhRNdBS.mjs} +58 -225
- package/dist/renderer-DzhRNdBS.mjs.map +1 -0
- package/dist/renderer-GSFP7v2z.mjs +3 -0
- package/dist/renderer-LfUdjgjF.mjs +5 -0
- package/dist/{renderer-Djlb4TLO.mjs → renderer-Q63y7HP_.mjs} +8 -15
- package/dist/renderer-Q63y7HP_.mjs.map +1 -0
- package/dist/renderer-SecCv3U8.mjs +5 -0
- package/dist/{renderer-BhZZEyFX.mjs → renderer-mp1NN5zk.mjs} +4 -4
- package/dist/{renderer-BhZZEyFX.mjs.map → renderer-mp1NN5zk.mjs.map} +1 -1
- package/dist/renderer-oZyoB4CT.mjs +5 -0
- package/dist/renderer-rzci_kTy.mjs +5 -0
- package/dist/{renderer-CpkiHRhh.mjs → renderer-to9DwqXK.mjs} +17 -99
- package/dist/renderer-to9DwqXK.mjs.map +1 -0
- package/dist/{renderer-CepMDQ06.mjs → renderer-v0vuUUUI.mjs} +19 -106
- package/dist/renderer-v0vuUUUI.mjs.map +1 -0
- package/dist/renderer-vLaZuZbX.mjs +5 -0
- package/dist/{renderers-CP8CFWDs-DwQTx8S7.mjs → renderers-CP8CFWDs-DlFq8jmz.mjs} +4 -4
- package/dist/{renderers-CP8CFWDs-DwQTx8S7.mjs.map → renderers-CP8CFWDs-DlFq8jmz.mjs.map} +1 -1
- package/dist/signals/index.d.mts +5 -5
- package/dist/signals/index.mjs +7 -7
- package/dist/{signals-Bv1OweKd.mjs → signals-BDkO0xcZ.mjs} +3 -3
- package/dist/{signals-Bv1OweKd.mjs.map → signals-BDkO0xcZ.mjs.map} +1 -1
- package/dist/{signin-Db08vl-g.mjs → signin-SVSXQw9i.mjs} +9 -9
- package/dist/{signin-Db08vl-g.mjs.map → signin-SVSXQw9i.mjs.map} +1 -1
- package/dist/{sso-oidc-CpLz_lIu.mjs → sso-oidc-B3Sagl43.mjs} +9 -9
- package/dist/{sso-oidc-CpLz_lIu.mjs.map → sso-oidc-B3Sagl43.mjs.map} +1 -1
- package/dist/{sts-BQefGuml.mjs → sts-CYeWec9i.mjs} +2 -2
- package/dist/{sts-Dgl0kH-t.mjs → sts-ClVtt-bV.mjs} +9 -9
- package/dist/{sts-Dgl0kH-t.mjs.map → sts-ClVtt-bV.mjs.map} +1 -1
- package/package.json +55 -55
- package/dist/dist-BAVZdFEJ.mjs.map +0 -1
- package/dist/dist-BYqNNwsl.mjs.map +0 -1
- package/dist/dist-CbG3QxDw.mjs.map +0 -1
- package/dist/dist-Cxi68OuY.mjs.map +0 -1
- package/dist/dist-cjs-3pon9kTt.mjs +0 -6
- package/dist/fonts-C0W6TgJk.mjs.map +0 -1
- package/dist/index-9B8CJowc.d.mts.map +0 -1
- package/dist/index-DDEPvMww.d.mts.map +0 -1
- package/dist/index-DnWsbbuZ.d.mts.map +0 -1
- package/dist/preview-engine/chunk-36YGYLKD.mjs +0 -58
- package/dist/preview-engine/chunk-7O24H4YT.mjs +0 -117
- package/dist/preview-engine/chunk-AUFSM5KI.mjs +0 -141
- package/dist/preview-engine/chunk-BQ65MU6H.mjs +0 -138
- package/dist/preview-engine/chunk-BWDARDO6.mjs +0 -117
- package/dist/preview-engine/chunk-DLXQDDIN.mjs +0 -46
- package/dist/preview-engine/chunk-EJGLUZMW.mjs +0 -1
- package/dist/preview-engine/chunk-FE6RSVKZ.mjs +0 -73
- package/dist/preview-engine/chunk-FGHOHCFG.mjs +0 -110
- package/dist/preview-engine/chunk-HPIULG7P.mjs +0 -111
- package/dist/preview-engine/chunk-HRIKNYPF.mjs +0 -60
- package/dist/preview-engine/chunk-IMV5SBQV.mjs +0 -1
- package/dist/preview-engine/chunk-JPXQPP6J.mjs +0 -1
- package/dist/preview-engine/chunk-K52S5DJX.mjs +0 -109
- package/dist/preview-engine/chunk-L3IEJZ5S.mjs +0 -474
- package/dist/preview-engine/chunk-M7NMFDJ3.mjs +0 -3
- package/dist/preview-engine/chunk-MJM3NFEC.mjs +0 -315
- package/dist/preview-engine/chunk-NFAGEP43.mjs +0 -1448
- package/dist/preview-engine/chunk-NRHSNPZV.mjs +0 -182
- package/dist/preview-engine/chunk-OWOSYNMF.mjs +0 -104
- package/dist/preview-engine/chunk-Q66QQI6N.mjs +0 -8
- package/dist/preview-engine/chunk-QGBSLNFI.mjs +0 -52
- package/dist/preview-engine/chunk-QM3XFEJN.mjs +0 -63
- package/dist/preview-engine/chunk-R3ZH7YF3.mjs +0 -89
- package/dist/preview-engine/chunk-R6YNSBKL.mjs +0 -108
- package/dist/preview-engine/chunk-S4CSX6K5.mjs +0 -610
- package/dist/preview-engine/chunk-SNYAHQ25.mjs +0 -186
- package/dist/preview-engine/chunk-SRT2OCQW.mjs +0 -1
- package/dist/preview-engine/chunk-SUUUYXXT.mjs +0 -1
- package/dist/preview-engine/chunk-T6COGNOW.mjs +0 -134
- package/dist/preview-engine/chunk-XFYXT76H.mjs +0 -52
- package/dist/preview-engine/chunk-XUM42I4R.mjs +0 -1
- package/dist/preview-engine/chunk-YITWSOG4.mjs +0 -103
- package/dist/preview-engine/chunk-ZDCA6NVT.mjs +0 -82
- package/dist/preview-engine/chunk-ZNGOAGAI.mjs +0 -1
- package/dist/preview-engine/renderers-27Q5X3U6.mjs +0 -1
- package/dist/preview-engine/renderers-4AHH6BHF.mjs +0 -1
- package/dist/preview-engine/renderers-5BV6JGTU.mjs +0 -248
- package/dist/preview-engine/renderers-6PRVCTYV.mjs +0 -1
- package/dist/preview-engine/renderers-76PQY2SO.mjs +0 -1
- package/dist/preview-engine/renderers-7X2W6QWX.mjs +0 -1
- package/dist/preview-engine/renderers-B52QT6MT.mjs +0 -55
- package/dist/preview-engine/renderers-BE6RVJSE.mjs +0 -1
- package/dist/preview-engine/renderers-BMM2BH56.mjs +0 -1
- package/dist/preview-engine/renderers-CHOGQHVQ.mjs +0 -1
- package/dist/preview-engine/renderers-CRKRWR2Y.mjs +0 -1
- package/dist/preview-engine/renderers-DEYDSGJX.mjs +0 -1
- package/dist/preview-engine/renderers-DZTNRCR7.mjs +0 -1
- package/dist/preview-engine/renderers-ELO3KWTK.mjs +0 -1
- package/dist/preview-engine/renderers-EOJMPPAQ.mjs +0 -1
- package/dist/preview-engine/renderers-F2KJNDWA.mjs +0 -124
- package/dist/preview-engine/renderers-FCV4COVB.mjs +0 -1
- package/dist/preview-engine/renderers-G5KQISVL.mjs +0 -1
- package/dist/preview-engine/renderers-GJSUN5HU.mjs +0 -1
- package/dist/preview-engine/renderers-GMX2ZQDG.mjs +0 -1
- package/dist/preview-engine/renderers-GXCRINGC.mjs +0 -1
- package/dist/preview-engine/renderers-IHKORHMT.mjs +0 -1
- package/dist/preview-engine/renderers-JA4SLMG3.mjs +0 -1
- package/dist/preview-engine/renderers-JLN77CFZ.mjs +0 -1
- package/dist/preview-engine/renderers-KBFW7B5F.mjs +0 -1
- package/dist/preview-engine/renderers-LJRJMFCR.mjs +0 -1
- package/dist/preview-engine/renderers-LPAPZ5QS.mjs +0 -1
- package/dist/preview-engine/renderers-NQUDQEHY.mjs +0 -1
- package/dist/preview-engine/renderers-NS3AIJVG.mjs +0 -1
- package/dist/preview-engine/renderers-NSY2SDIE.mjs +0 -1
- package/dist/preview-engine/renderers-PW4OJWHF.mjs +0 -120
- package/dist/preview-engine/renderers-PWLWOZY4.mjs +0 -1
- package/dist/preview-engine/renderers-Q3MD34JN.mjs +0 -1
- package/dist/preview-engine/renderers-RXGNA2Q7.mjs +0 -1
- package/dist/preview-engine/renderers-TVTQ2R74.mjs +0 -1
- package/dist/preview-engine/renderers-VTTGFO55.mjs +0 -1
- package/dist/preview-engine/renderers-W3VVM5HB.mjs +0 -1
- package/dist/preview-engine/renderers-WG7QBD4D.mjs +0 -1
- package/dist/preview-engine/renderers-WLLJFZTF.mjs +0 -1
- package/dist/preview-engine/renderers-WN4SYFCU.mjs +0 -1
- package/dist/preview-engine/renderers-WSMLLSWX.mjs +0 -1
- package/dist/preview-engine/renderers-XFBSGTHU.mjs +0 -1
- package/dist/preview-engine/renderers-XFC6ZPO5.mjs +0 -1
- package/dist/preview-engine/renderers-XUHRY3XH.mjs +0 -1
- package/dist/preview-engine/renderers-YAOB5XU6.mjs +0 -1
- package/dist/preview-engine/renderers-YTB4FOHT.mjs +0 -1
- package/dist/preview-engine/renderers-ZIMBODX6.mjs +0 -1
- package/dist/program-BmNKgzja.mjs.map +0 -1
- package/dist/renderer-1VuQTY1Z.mjs.map +0 -1
- package/dist/renderer-6oMSare3.mjs +0 -3
- package/dist/renderer-B1ComPb2.mjs +0 -3
- package/dist/renderer-B2XzjK0z.mjs +0 -3
- package/dist/renderer-B2ieylQ3.mjs.map +0 -1
- package/dist/renderer-B8-kzZdP.mjs.map +0 -1
- package/dist/renderer-B8UaFNqb.mjs.map +0 -1
- package/dist/renderer-BDbTWSpP.mjs.map +0 -1
- package/dist/renderer-BIIWCg_J.mjs.map +0 -1
- package/dist/renderer-BJ1aTkZf.mjs.map +0 -1
- package/dist/renderer-BM05sB8m.mjs.map +0 -1
- package/dist/renderer-BQ5Bz5D0.mjs +0 -3
- package/dist/renderer-BREIjsUU.mjs.map +0 -1
- package/dist/renderer-BTu2EVhF.mjs +0 -3
- package/dist/renderer-BZcn_iBl.mjs +0 -3
- package/dist/renderer-Bc04fivZ.mjs.map +0 -1
- package/dist/renderer-BfAWZziM.mjs.map +0 -1
- package/dist/renderer-BfJSUjPN.mjs +0 -3
- package/dist/renderer-Bfgd4N0O.mjs.map +0 -1
- package/dist/renderer-Bhdf90Zq.mjs.map +0 -1
- package/dist/renderer-Bp6sDMa6.mjs +0 -3
- package/dist/renderer-Bt7_sb_Y.mjs +0 -3
- package/dist/renderer-Bv6q84TU.mjs.map +0 -1
- package/dist/renderer-C-H680_l.mjs +0 -3
- package/dist/renderer-C606ZPUn.mjs +0 -3
- package/dist/renderer-C9jyKn1i.mjs +0 -3
- package/dist/renderer-CDLrNgfo.mjs +0 -3
- package/dist/renderer-CERfcxgv.mjs +0 -3
- package/dist/renderer-CG5PzNkv.mjs +0 -3
- package/dist/renderer-CI7sG_cv.mjs.map +0 -1
- package/dist/renderer-CPoIMVdk.mjs +0 -3
- package/dist/renderer-CQdVj2JS.mjs +0 -3
- package/dist/renderer-CQiTodg9.mjs +0 -337
- package/dist/renderer-CQiTodg9.mjs.map +0 -1
- package/dist/renderer-CWTpc4ff.mjs.map +0 -1
- package/dist/renderer-CXn5HAnK.mjs.map +0 -1
- package/dist/renderer-CZgB5st8.mjs +0 -3
- package/dist/renderer-C_TPMHiH.mjs.map +0 -1
- package/dist/renderer-Ca7L1EOp.mjs +0 -3
- package/dist/renderer-CaaOKMSd.mjs.map +0 -1
- package/dist/renderer-CdciwwMI.mjs.map +0 -1
- package/dist/renderer-CepMDQ06.mjs.map +0 -1
- package/dist/renderer-CfC_aiew.mjs.map +0 -1
- package/dist/renderer-ChdLYS-G.mjs.map +0 -1
- package/dist/renderer-CkykdR_D.mjs +0 -3
- package/dist/renderer-Cl6GkeHx.mjs +0 -3
- package/dist/renderer-ClcjrFyo.mjs +0 -3
- package/dist/renderer-CnXW28b9.mjs.map +0 -1
- package/dist/renderer-CpkiHRhh.mjs.map +0 -1
- package/dist/renderer-CtVkU_GA.mjs +0 -44
- package/dist/renderer-CtVkU_GA.mjs.map +0 -1
- package/dist/renderer-Ctk2zzfy.mjs.map +0 -1
- package/dist/renderer-CtyD_Xju.mjs.map +0 -1
- package/dist/renderer-CySUP_wk.mjs +0 -3
- package/dist/renderer-CzPWB0Ss.mjs.map +0 -1
- package/dist/renderer-D2XD4QYk.mjs.map +0 -1
- package/dist/renderer-D2l_Odyg.mjs +0 -3
- package/dist/renderer-D7zvPHKn.mjs.map +0 -1
- package/dist/renderer-D9NnIx7o.mjs +0 -3
- package/dist/renderer-DCPCYySt.mjs +0 -3
- package/dist/renderer-DEJwPRkR.mjs.map +0 -1
- package/dist/renderer-DIkpJEOZ.mjs +0 -3
- package/dist/renderer-DML9qpmS.mjs.map +0 -1
- package/dist/renderer-DNSXPkf_.mjs +0 -3
- package/dist/renderer-DP-CvZ_Z.mjs +0 -3
- package/dist/renderer-DZGtBUCx.mjs.map +0 -1
- package/dist/renderer-D_1oDOCP.mjs.map +0 -1
- package/dist/renderer-DeXb8R6h.mjs +0 -3
- package/dist/renderer-DezO-ZaP.mjs +0 -4
- package/dist/renderer-DhXe04fC.mjs +0 -3
- package/dist/renderer-DirxsOjq.mjs.map +0 -1
- package/dist/renderer-Djlb4TLO.mjs.map +0 -1
- package/dist/renderer-DnH3SI7w.mjs +0 -3
- package/dist/renderer-DpGc-N3G.mjs.map +0 -1
- package/dist/renderer-Dpw4oi33.mjs +0 -3
- package/dist/renderer-DxTs4Iyi.mjs.map +0 -1
- package/dist/renderer-Dy0utCl7.mjs.map +0 -1
- package/dist/renderer-Md-ytU0v.mjs +0 -3
- package/dist/renderer-U-bhWO9Q.mjs +0 -3
- package/dist/renderer-_uvdg48N.mjs.map +0 -1
- package/dist/renderer-bsWnRNpJ.mjs.map +0 -1
- package/dist/renderer-cgxO2xN6.mjs.map +0 -1
- package/dist/renderer-d5-F_48R.mjs +0 -3
- package/dist/renderer-ho_jXJ0H.mjs.map +0 -1
- package/dist/renderer-vqkKWqa5.mjs.map +0 -1
- package/dist/renderer-zA5okHds.mjs +0 -3
- /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-
|
|
2
|
-
import { t as ColorSchema } from "./dist-
|
|
3
|
-
import {
|
|
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
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
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
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
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
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
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
|
|
3286
|
-
|
|
3287
|
-
|
|
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
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
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
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
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
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
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
|
-
|
|
3955
|
-
|
|
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
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
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 {
|
|
5446
|
-
//# sourceMappingURL=program-
|
|
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
|