framefields 2.2.0 → 2.3.1
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 +11 -2
- package/dist/audio/index.d.mts +4 -4
- package/dist/audio/index.mjs +10 -10
- package/dist/{audio-BvYmTu5T.d.mts → audio-BNnEclHU.d.mts} +3 -3
- package/dist/{audio-BvYmTu5T.d.mts.map → audio-BNnEclHU.d.mts.map} +1 -1
- package/dist/{audio-DMUr01vS.mjs → audio-CS104aUj.mjs} +3 -3
- package/dist/{audio-DMUr01vS.mjs.map → audio-CS104aUj.mjs.map} +1 -1
- package/dist/{dist-CT___nEU.mjs → dist-BOdxAhOT.mjs} +7 -5
- package/dist/dist-BOdxAhOT.mjs.map +1 -0
- package/dist/{dist-cjxDXQdx.mjs → dist-jU289ehm.mjs} +209 -31
- package/dist/{dist-cjxDXQdx.mjs.map → dist-jU289ehm.mjs.map} +1 -1
- package/dist/effects/index.d.mts +5 -5
- package/dist/effects/index.mjs +36 -36
- package/dist/{effects-C06-AOge.mjs → effects-BzOlVD-w.mjs} +532 -4
- package/dist/effects-BzOlVD-w.mjs.map +1 -0
- package/dist/fonts/index.d.mts +1 -1
- package/dist/fonts/index.mjs +2 -2
- package/dist/{fonts-C0UuLQvr.mjs → fonts-BhlV_3Qt.mjs} +2 -2
- package/dist/{fonts-C0UuLQvr.mjs.map → fonts-BhlV_3Qt.mjs.map} +1 -1
- package/dist/{gpu-Du7GpVFW.mjs → gpu-BA1Wz_mS.mjs} +2 -2
- package/dist/{gpu-Du7GpVFW.mjs.map → gpu-BA1Wz_mS.mjs.map} +1 -1
- package/dist/{index-B-oUlLoO.d.mts → index-AdrZIWT0.d.mts} +27 -2
- package/dist/index-AdrZIWT0.d.mts.map +1 -0
- package/dist/{index-BcA8rep0.d.mts → index-B-55dXDu.d.mts} +1 -1
- package/dist/{index-BcA8rep0.d.mts.map → index-B-55dXDu.d.mts.map} +1 -1
- package/dist/{index-D-Iek5sq.d.mts → index-B3BwLHa6.d.mts} +3 -3
- package/dist/{index-D-Iek5sq.d.mts.map → index-B3BwLHa6.d.mts.map} +1 -1
- package/dist/{index-CwbszPDG.d.mts → index-BU51pxZO.d.mts} +956 -9
- package/dist/index-BU51pxZO.d.mts.map +1 -0
- package/dist/{index-XdQPNJnq.d.mts → index-CeRv1KC0.d.mts} +3 -3
- package/dist/{index-XdQPNJnq.d.mts.map → index-CeRv1KC0.d.mts.map} +1 -1
- package/dist/{index-DXfp_T-3.d.mts → index-Cg2ptXcs.d.mts} +2 -2
- package/dist/{index-DXfp_T-3.d.mts.map → index-Cg2ptXcs.d.mts.map} +1 -1
- package/dist/{index-CdyE1tst.d.mts → index-QmkcUL3W.d.mts} +2 -2
- package/dist/{index-CdyE1tst.d.mts.map → index-QmkcUL3W.d.mts.map} +1 -1
- package/dist/index.d.mts +1383 -11
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +3122 -83
- package/dist/index.mjs.map +1 -1
- package/dist/preview/index.d.mts +2 -2
- package/dist/preview/index.mjs +10 -10
- package/dist/{preview-M0TsUzC6.mjs → preview-BVyG76gO.mjs} +2 -2
- package/dist/{preview-M0TsUzC6.mjs.map → preview-BVyG76gO.mjs.map} +1 -1
- package/dist/preview-engine/audio.mjs +1 -1
- package/dist/preview-engine/chunk-2JKXYG6J.mjs +127 -0
- package/dist/preview-engine/chunk-7I7PKKDL.mjs +214 -0
- package/dist/preview-engine/chunk-BQY4BUMN.mjs +1 -0
- package/dist/preview-engine/{chunk-RSMO7NPN.mjs → chunk-BSOJR4JU.mjs} +1 -1
- package/dist/preview-engine/chunk-BVA5NGSH.mjs +1 -0
- package/dist/preview-engine/{chunk-ZTHWCQ2A.mjs → chunk-FNE22WGA.mjs} +1 -1
- package/dist/preview-engine/chunk-GCTVRM7J.mjs +1522 -0
- package/dist/preview-engine/chunk-KERW7QJ4.mjs +174 -0
- package/dist/preview-engine/{chunk-7B5S5D4N.mjs → chunk-TPAEN6VV.mjs} +1 -1
- package/dist/preview-engine/chunk-YQRKT47I.mjs +1 -0
- package/dist/preview-engine/crypto-W5UAWSNT.mjs +1 -0
- package/dist/preview-engine/effects.mjs +1 -1
- package/dist/preview-engine/framefields.mjs +26 -26
- package/dist/preview-engine/player.mjs +5 -5
- package/dist/preview-engine/rapier-AHBIGHEL.mjs +1 -0
- package/dist/preview-engine/rapier-JD7KNQRV.mjs +1 -0
- package/dist/preview-engine/renderers-3F5AIDEL.mjs +228 -0
- package/dist/preview-engine/renderers-6ODPWZ2R.mjs +96 -0
- package/dist/preview-engine/renderers-7NCG6BYS.mjs +94 -0
- package/dist/preview-engine/renderers-BGGRPAVV.mjs +363 -0
- package/dist/preview-engine/renderers-DN2GF3I7.mjs +82 -0
- package/dist/preview-engine/renderers-FGHOLJJK.mjs +44 -0
- package/dist/preview-engine/renderers-FK72LKQC.mjs +275 -0
- package/dist/preview-engine/renderers-FQWWAETX.mjs +203 -0
- package/dist/preview-engine/renderers-HMR2NAD7.mjs +81 -0
- package/dist/preview-engine/renderers-HUW2ZMS3.mjs +1 -0
- package/dist/preview-engine/renderers-JLFGBYN4.mjs +78 -0
- package/dist/preview-engine/renderers-LLUEOW5T.mjs +77 -0
- package/dist/preview-engine/renderers-NC64EQDE.mjs +1 -0
- package/dist/preview-engine/renderers-PVYP2ONH.mjs +76 -0
- package/dist/preview-engine/renderers-TPBPNXWH.mjs +26 -0
- package/dist/preview-engine/renderers-UJ4YVJZT.mjs +80 -0
- package/dist/preview-engine/renderers-WHBDHTRI.mjs +78 -0
- package/dist/preview-engine/renderers-WP67KK5K.mjs +89 -0
- package/dist/preview-engine/renderers-YNFKFM7D.mjs +67 -0
- package/dist/preview-engine/renderers-ZSENYGIY.mjs +84 -0
- package/dist/preview-engine/signals.mjs +1 -1
- package/dist/{program-DzknMiY0.mjs → program-CCSfHMfh.mjs} +346 -13
- package/dist/program-CCSfHMfh.mjs.map +1 -0
- package/dist/renderer/index.d.mts +2 -2
- package/dist/renderer/index.mjs +2 -2
- package/dist/renderer-1Kv7oA86.mjs +5 -0
- package/dist/{renderer-1vhaKMeg.mjs → renderer-1uLtqb74.mjs} +141 -56
- package/dist/renderer-1uLtqb74.mjs.map +1 -0
- package/dist/{renderer-BerD3T-X.mjs → renderer-4VpA7LfU.mjs} +2 -2
- package/dist/{renderer-BerD3T-X.mjs.map → renderer-4VpA7LfU.mjs.map} +1 -1
- package/dist/{renderer-BNqwn0gZ.mjs → renderer-8BM6sJUR.mjs} +2 -2
- package/dist/{renderer-BNqwn0gZ.mjs.map → renderer-8BM6sJUR.mjs.map} +1 -1
- package/dist/renderer-AVHJ33nv.mjs +5 -0
- package/dist/{renderer-0gY4IQhM.mjs → renderer-AtLlZMQ9.mjs} +2 -2
- package/dist/{renderer-0gY4IQhM.mjs.map → renderer-AtLlZMQ9.mjs.map} +1 -1
- package/dist/renderer-B8dJGf8R.mjs +6 -0
- package/dist/{renderer-57ATc_mQ.mjs → renderer-B93zd3sx.mjs} +2 -2
- package/dist/{renderer-57ATc_mQ.mjs.map → renderer-B93zd3sx.mjs.map} +1 -1
- package/dist/renderer-BARst3ZD.mjs +3 -0
- package/dist/{renderer-CJB9nU1x.mjs → renderer-BD7Lmb8h.mjs} +3 -3
- package/dist/{renderer-CJB9nU1x.mjs.map → renderer-BD7Lmb8h.mjs.map} +1 -1
- package/dist/renderer-BEA6nknY.mjs +5 -0
- package/dist/renderer-BFRI5alp.mjs +222 -0
- package/dist/renderer-BFRI5alp.mjs.map +1 -0
- package/dist/{renderer-BiwIh_w4.mjs → renderer-BG5sbTXt.mjs} +3 -3
- package/dist/{renderer-BiwIh_w4.mjs.map → renderer-BG5sbTXt.mjs.map} +1 -1
- package/dist/{renderer-DtgMsjyL.mjs → renderer-BI4OMlEx.mjs} +2 -2
- package/dist/{renderer-DtgMsjyL.mjs.map → renderer-BI4OMlEx.mjs.map} +1 -1
- package/dist/renderer-BOfi06L2.mjs +5 -0
- package/dist/renderer-BOhvtAGL.mjs +5 -0
- package/dist/renderer-BQT3GI9g.mjs +5 -0
- package/dist/{renderer-DJfFc-XW.mjs → renderer-BRwp1kV-.mjs} +3 -3
- package/dist/{renderer-DJfFc-XW.mjs.map → renderer-BRwp1kV-.mjs.map} +1 -1
- package/dist/{renderer-u8ynJtAC.mjs → renderer-BVUTOGHs.mjs} +2 -2
- package/dist/{renderer-u8ynJtAC.mjs.map → renderer-BVUTOGHs.mjs.map} +1 -1
- package/dist/renderer-BXmStgeT.mjs +5 -0
- package/dist/renderer-Bajxo7Nt.mjs +5 -0
- package/dist/{renderer-BHskWZNG.mjs → renderer-Bel1UHA5.mjs} +2 -2
- package/dist/{renderer-AF884a7T.mjs → renderer-BetA_iVd.mjs} +3 -3
- package/dist/{renderer-AF884a7T.mjs.map → renderer-BetA_iVd.mjs.map} +1 -1
- package/dist/{renderer-DpW_LxLO.mjs → renderer-BmDpyiII.mjs} +3 -3
- package/dist/{renderer-DpW_LxLO.mjs.map → renderer-BmDpyiII.mjs.map} +1 -1
- package/dist/{renderer-BteUC_7n.mjs → renderer-BonWt8jF.mjs} +3 -3
- package/dist/{renderer-BteUC_7n.mjs.map → renderer-BonWt8jF.mjs.map} +1 -1
- package/dist/{renderer-BC8XOVl5.mjs → renderer-BpEsZG3t.mjs} +3 -3
- package/dist/{renderer-BC8XOVl5.mjs.map → renderer-BpEsZG3t.mjs.map} +1 -1
- package/dist/{renderer-aArb4RwJ.mjs → renderer-BvBIHi6N.mjs} +2 -2
- package/dist/{renderer-aArb4RwJ.mjs.map → renderer-BvBIHi6N.mjs.map} +1 -1
- package/dist/{renderer-Db3JIF1K.mjs → renderer-BvvuGfZk.mjs} +3 -3
- package/dist/{renderer-Db3JIF1K.mjs.map → renderer-BvvuGfZk.mjs.map} +1 -1
- package/dist/renderer-BzRR0KMm.mjs +5 -0
- package/dist/{renderer-DEuIwr-t.mjs → renderer-Bzl0s07U.mjs} +2 -2
- package/dist/{renderer-DEuIwr-t.mjs.map → renderer-Bzl0s07U.mjs.map} +1 -1
- package/dist/renderer-C39GD6jP.mjs +331 -0
- package/dist/renderer-C39GD6jP.mjs.map +1 -0
- package/dist/renderer-C3Gjy2iE.mjs +5 -0
- package/dist/{renderer-Br6KyRO_.mjs → renderer-C3lPwajT.mjs} +3 -3
- package/dist/{renderer-Br6KyRO_.mjs.map → renderer-C3lPwajT.mjs.map} +1 -1
- package/dist/renderer-C5hQgkz-.mjs +5 -0
- package/dist/{renderer-CebB0v1y.mjs → renderer-C6cF5seJ.mjs} +2 -2
- package/dist/{renderer-CebB0v1y.mjs.map → renderer-C6cF5seJ.mjs.map} +1 -1
- package/dist/renderer-C8GZ0pCV.mjs +191 -0
- package/dist/renderer-C8GZ0pCV.mjs.map +1 -0
- package/dist/{renderer-CuVPo-wP.mjs → renderer-CFe9pZFN.mjs} +2 -2
- package/dist/{renderer-CuVPo-wP.mjs.map → renderer-CFe9pZFN.mjs.map} +1 -1
- package/dist/renderer-CLF-MiOA.mjs +5 -0
- package/dist/renderer-CLa43fCd.mjs +5 -0
- package/dist/{renderer-Bvx56GR6.mjs → renderer-CLdwOhST.mjs} +2 -2
- package/dist/{renderer-Bvx56GR6.mjs.map → renderer-CLdwOhST.mjs.map} +1 -1
- package/dist/renderer-CMK1d6w_.mjs +5 -0
- package/dist/{renderer-CursFKUf.mjs → renderer-CMdtUn5o.mjs} +2 -2
- package/dist/{renderer-CursFKUf.mjs.map → renderer-CMdtUn5o.mjs.map} +1 -1
- package/dist/{renderer-DXqIslFk.mjs → renderer-CNYfB5cC.mjs} +2 -2
- package/dist/{renderer-DXqIslFk.mjs.map → renderer-CNYfB5cC.mjs.map} +1 -1
- package/dist/renderer-CPEQOe3u.mjs +5 -0
- package/dist/{renderer-BbdZ0YHR.mjs → renderer-CWx3Kg79.mjs} +3 -3
- package/dist/{renderer-BbdZ0YHR.mjs.map → renderer-CWx3Kg79.mjs.map} +1 -1
- package/dist/{renderer-CWBHVCvA.mjs → renderer-CdOy3EBJ.mjs} +2 -2
- package/dist/{renderer-CWBHVCvA.mjs.map → renderer-CdOy3EBJ.mjs.map} +1 -1
- package/dist/{renderer-DupsdRIw.mjs → renderer-Celrh689.mjs} +3 -3
- package/dist/{renderer-DupsdRIw.mjs.map → renderer-Celrh689.mjs.map} +1 -1
- package/dist/renderer-CemfjOM9.mjs +5 -0
- package/dist/{renderer-jYxN4mHn.mjs → renderer-ChloaI6P.mjs} +3 -3
- package/dist/{renderer-jYxN4mHn.mjs.map → renderer-ChloaI6P.mjs.map} +1 -1
- package/dist/{renderer-DqdhsSwS.mjs → renderer-CiMpdh0s.mjs} +2 -2
- package/dist/{renderer-DqdhsSwS.mjs.map → renderer-CiMpdh0s.mjs.map} +1 -1
- package/dist/renderer-CkcrScs9.mjs +5 -0
- package/dist/{renderer-CMT4QcpV.mjs → renderer-Cn6VlWHZ.mjs} +3 -3
- package/dist/{renderer-CMT4QcpV.mjs.map → renderer-Cn6VlWHZ.mjs.map} +1 -1
- package/dist/renderer-CqewgazK.mjs +224 -0
- package/dist/renderer-CqewgazK.mjs.map +1 -0
- package/dist/{renderer-C6md3msE.mjs → renderer-Cu5k5D9N.mjs} +2 -2
- package/dist/{renderer-C6md3msE.mjs.map → renderer-Cu5k5D9N.mjs.map} +1 -1
- package/dist/{renderer-id8TbKBY.mjs → renderer-CuphUktB.mjs} +2 -2
- package/dist/{renderer-id8TbKBY.mjs.map → renderer-CuphUktB.mjs.map} +1 -1
- package/dist/renderer-CwrLihY6.mjs +5 -0
- package/dist/{renderer-BzDjy1_x.mjs → renderer-D1Jt-c3F.mjs} +2 -2
- package/dist/{renderer-BzDjy1_x.mjs.map → renderer-D1Jt-c3F.mjs.map} +1 -1
- package/dist/{renderer-Beg7FLt2.mjs → renderer-D1wd0FhZ.mjs} +75 -27
- package/dist/renderer-D1wd0FhZ.mjs.map +1 -0
- package/dist/{renderer-jqByPgkD.mjs → renderer-D26S5hUh.mjs} +2 -2
- package/dist/{renderer-jqByPgkD.mjs.map → renderer-D26S5hUh.mjs.map} +1 -1
- package/dist/renderer-D4S6i2MC.mjs +5 -0
- package/dist/{renderer-BmGPTWwV.mjs → renderer-D7ss6fLB.mjs} +3 -3
- package/dist/{renderer-BmGPTWwV.mjs.map → renderer-D7ss6fLB.mjs.map} +1 -1
- package/dist/renderer-DB8F0XoP.mjs +5 -0
- package/dist/{renderer-PKQNH21k.mjs → renderer-DCGLXnYW.mjs} +2 -2
- package/dist/{renderer-CrABA3lB.mjs → renderer-DCYabwlC.mjs} +2 -2
- package/dist/{renderer-CrABA3lB.mjs.map → renderer-DCYabwlC.mjs.map} +1 -1
- package/dist/renderer-DGpVLJOn.mjs +5 -0
- package/dist/renderer-DGxibeSa.mjs +5 -0
- package/dist/renderer-DJQm3bAW.mjs +5 -0
- package/dist/{renderer-DD8napek.mjs → renderer-DMZ5aLU1.mjs} +2 -2
- package/dist/{renderer-DD8napek.mjs.map → renderer-DMZ5aLU1.mjs.map} +1 -1
- package/dist/renderer-DMftVSfX.mjs +5 -0
- package/dist/renderer-DNpovOd8.mjs +5 -0
- package/dist/renderer-DO5r7ZV-.mjs +658 -0
- package/dist/renderer-DO5r7ZV-.mjs.map +1 -0
- package/dist/{renderer-DZXbgVMK.mjs → renderer-DOWekunR.mjs} +3 -3
- package/dist/{renderer-DZXbgVMK.mjs.map → renderer-DOWekunR.mjs.map} +1 -1
- package/dist/{renderer-Cce2fgpX.mjs → renderer-DPWeKe_x.mjs} +3 -3
- package/dist/{renderer-Cce2fgpX.mjs.map → renderer-DPWeKe_x.mjs.map} +1 -1
- package/dist/{renderer-CE7fwGgw.mjs → renderer-DQtk282o.mjs} +29 -8
- package/dist/renderer-DQtk282o.mjs.map +1 -0
- package/dist/renderer-DSHlvKQk.mjs +5 -0
- package/dist/renderer-DUBb7D17.mjs +219 -0
- package/dist/renderer-DUBb7D17.mjs.map +1 -0
- package/dist/renderer-DYtrdR2p.mjs +5 -0
- package/dist/{renderer-Bn2eQE-t.mjs → renderer-DaCsT-XU.mjs} +3 -3
- package/dist/{renderer-Bn2eQE-t.mjs.map → renderer-DaCsT-XU.mjs.map} +1 -1
- package/dist/{renderer-D1Cm21eq.mjs → renderer-DcAfp1Er.mjs} +2 -2
- package/dist/{renderer-D1Cm21eq.mjs.map → renderer-DcAfp1Er.mjs.map} +1 -1
- package/dist/{renderer-C8uKdelk.mjs → renderer-DdlaBsk_.mjs} +2 -2
- package/dist/{renderer-C8uKdelk.mjs.map → renderer-DdlaBsk_.mjs.map} +1 -1
- package/dist/renderer-DerDxKK3.mjs +220 -0
- package/dist/renderer-DerDxKK3.mjs.map +1 -0
- package/dist/{renderer-CeyAgJnw.mjs → renderer-DfkWYUTX.mjs} +2 -2
- package/dist/{renderer-DHGTzype.mjs → renderer-Dh-OF6aH.mjs} +2 -2
- package/dist/{renderer-DHGTzype.mjs.map → renderer-Dh-OF6aH.mjs.map} +1 -1
- package/dist/renderer-Dk-THZHp.mjs +222 -0
- package/dist/renderer-Dk-THZHp.mjs.map +1 -0
- package/dist/{renderer-BT-_EoXw.d.mts → renderer-DlESyfg7.d.mts} +2 -2
- package/dist/{renderer-BT-_EoXw.d.mts.map → renderer-DlESyfg7.d.mts.map} +1 -1
- package/dist/renderer-DpWRj6zF.mjs +203 -0
- package/dist/renderer-DpWRj6zF.mjs.map +1 -0
- package/dist/renderer-DpwlN4LH.mjs +233 -0
- package/dist/renderer-DpwlN4LH.mjs.map +1 -0
- package/dist/{renderer-DvFaC_-7.mjs → renderer-Dq4aO7az.mjs} +2 -2
- package/dist/{renderer-DvFaC_-7.mjs.map → renderer-Dq4aO7az.mjs.map} +1 -1
- package/dist/renderer-DuSImLUz.mjs +5 -0
- package/dist/{renderer-BeIUgp1r.mjs → renderer-DukD7S3w.mjs} +2 -2
- package/dist/{renderer-BeIUgp1r.mjs.map → renderer-DukD7S3w.mjs.map} +1 -1
- package/dist/{renderer-EemDpvv3.mjs → renderer-FXUCKps6.mjs} +3 -3
- package/dist/{renderer-EemDpvv3.mjs.map → renderer-FXUCKps6.mjs.map} +1 -1
- package/dist/renderer-FbyMYKXe.mjs +5 -0
- package/dist/renderer-HMl2V4iM.mjs +541 -0
- package/dist/renderer-HMl2V4iM.mjs.map +1 -0
- package/dist/renderer-LM_XIKl1.mjs +203 -0
- package/dist/renderer-LM_XIKl1.mjs.map +1 -0
- package/dist/renderer-NMFv7Auz.mjs +5 -0
- package/dist/{renderer-YbaCzPcG.mjs → renderer-O1b-oYJE.mjs} +2 -2
- package/dist/renderer-P3vpdUnb.mjs +5 -0
- package/dist/renderer-PknbdJyL.mjs +208 -0
- package/dist/renderer-PknbdJyL.mjs.map +1 -0
- package/dist/renderer-QTOm26Lg.mjs +5 -0
- package/dist/renderer-YJ3Yukou.mjs +215 -0
- package/dist/renderer-YJ3Yukou.mjs.map +1 -0
- package/dist/{renderer-p_C_T9Kn.mjs → renderer-YdLL2o6d.mjs} +2 -2
- package/dist/{renderer-p_C_T9Kn.mjs.map → renderer-YdLL2o6d.mjs.map} +1 -1
- package/dist/renderer-ahzhMa5q.mjs +5 -0
- package/dist/{renderer-D-vRKssW.mjs → renderer-c-bwxMde.mjs} +2 -2
- package/dist/{renderer-D-vRKssW.mjs.map → renderer-c-bwxMde.mjs.map} +1 -1
- package/dist/renderer-dThfTNge.mjs +5 -0
- package/dist/renderer-dUkOBfGB.mjs +308 -0
- package/dist/renderer-dUkOBfGB.mjs.map +1 -0
- package/dist/renderer-dgAS_k7B.mjs +5 -0
- package/dist/renderer-g-ui08Lh.mjs +204 -0
- package/dist/renderer-g-ui08Lh.mjs.map +1 -0
- package/dist/renderer-kSs8VtY7.mjs +223 -0
- package/dist/renderer-kSs8VtY7.mjs.map +1 -0
- package/dist/{renderer-KnCcN_Nz.mjs → renderer-pPiQwFYh.mjs} +2 -2
- package/dist/{renderer-KnCcN_Nz.mjs.map → renderer-pPiQwFYh.mjs.map} +1 -1
- package/dist/{renderer-D8thCpS7.mjs → renderer-wL-ly4fT.mjs} +3 -3
- package/dist/{renderer-D8thCpS7.mjs.map → renderer-wL-ly4fT.mjs.map} +1 -1
- package/dist/{renderers-CP8CFWDs-BA-4l6By.mjs → renderers-CP8CFWDs-CVHwMTiz.mjs} +2 -2
- package/dist/{renderers-CP8CFWDs-BA-4l6By.mjs.map → renderers-CP8CFWDs-CVHwMTiz.mjs.map} +1 -1
- package/dist/signals/index.d.mts +5 -5
- package/dist/signals/index.mjs +4 -4
- package/package.json +58 -55
- package/dist/dist-CT___nEU.mjs.map +0 -1
- package/dist/effects-C06-AOge.mjs.map +0 -1
- package/dist/index-B-oUlLoO.d.mts.map +0 -1
- package/dist/index-CwbszPDG.d.mts.map +0 -1
- package/dist/preview-engine/chunk-G4K6TLNA.mjs +0 -1
- package/dist/preview-engine/chunk-HVCAOHNI.mjs +0 -1
- package/dist/preview-engine/chunk-KBO6EX3M.mjs +0 -1448
- package/dist/preview-engine/chunk-N4LHIPHZ.mjs +0 -340
- package/dist/preview-engine/chunk-NECOKNHA.mjs +0 -174
- package/dist/preview-engine/renderers-T4JMJXWL.mjs +0 -1
- package/dist/preview-engine/renderers-VFV5QWO3.mjs +0 -1
- package/dist/preview-engine/renderers-VUL4HBX3.mjs +0 -228
- package/dist/program-DzknMiY0.mjs.map +0 -1
- package/dist/renderer--IDyGdqT.mjs +0 -5
- package/dist/renderer-17K4tjid.mjs +0 -5
- package/dist/renderer-1vhaKMeg.mjs.map +0 -1
- package/dist/renderer-Ab9Ttn_m.mjs +0 -5
- package/dist/renderer-B-roDBBo.mjs +0 -5
- package/dist/renderer-B03uwoUX.mjs +0 -5
- package/dist/renderer-B3BI_7YJ.mjs +0 -5
- package/dist/renderer-BGD4lQ74.mjs +0 -5
- package/dist/renderer-BHXhYfeC.mjs +0 -5
- package/dist/renderer-BRsTIMFa.mjs +0 -5
- package/dist/renderer-Beg7FLt2.mjs.map +0 -1
- package/dist/renderer-BjMTtYZw.mjs +0 -5
- package/dist/renderer-BoCh3Yts.mjs +0 -5
- package/dist/renderer-BqPbR8c4.mjs +0 -5
- package/dist/renderer-Bxa4SDm9.mjs +0 -3
- package/dist/renderer-C4Da2I1-.mjs +0 -5
- package/dist/renderer-C93X6dgl.mjs +0 -5
- package/dist/renderer-CE7fwGgw.mjs.map +0 -1
- package/dist/renderer-CMAwFfGx.mjs +0 -6
- package/dist/renderer-CRXeSuX2.mjs +0 -5
- package/dist/renderer-CSp6WYBN.mjs +0 -5
- package/dist/renderer-CUXX7HTL.mjs +0 -5
- package/dist/renderer-CUgThpka.mjs +0 -5
- package/dist/renderer-CeVtufiT.mjs +0 -5
- package/dist/renderer-CespkZUk.mjs +0 -5
- package/dist/renderer-D1l47xhL.mjs +0 -5
- package/dist/renderer-DDuG18J8.mjs +0 -5
- package/dist/renderer-DFhrFSMn.mjs +0 -5
- package/dist/renderer-DO48vQ7Y.mjs +0 -5
- package/dist/renderer-DTC39B_n.mjs +0 -5
- package/dist/renderer-DbyU3hNF.mjs +0 -5
- package/dist/renderer-DftVpmfu.mjs +0 -5
- package/dist/renderer-Dj5jm63K.mjs +0 -5
- package/dist/renderer-Dju57ZaF.mjs +0 -5
- package/dist/renderer-Dn8TQCw7.mjs +0 -5
- package/dist/renderer-ETF46K0D.mjs +0 -5
- package/dist/renderer-azYzWGC3.mjs +0 -5
- package/dist/renderer-dxNoRW59.mjs +0 -5
- package/dist/renderer-fdfelx_I.mjs +0 -5
- package/dist/renderer-snwEKwMw.mjs +0 -5
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["stack","color","d3Format","d3Pie","d3Arc","x","d3Stack","lo","hi","d","d3Area","d3Line","spec","size","color","line","spec","resolvedSource","analyzeVisionFrames","signal","color","CoreEffect"],"sources":["../src/ids.ts","../src/rich-text.ts","../src/chart.ts","../src/shapes3d.ts","../src/transitions.ts","../src/lighting.ts","../src/index.ts"],"sourcesContent":["/**\n * Default ids for nodes created without one. A counter per prefix rather than\n * a random suffix: the same composition script builds the same ids on every\n * run and in every render worker, so specs, caches and diffs stay stable.\n */\nconst counters = new Map<string, number>();\n\nexport function autoId(prefix: string): string {\n\tconst n = (counters.get(prefix) ?? 0) + 1;\n\tcounters.set(prefix, n);\n\treturn `${prefix}-auto-${n}`;\n}\n","import type { Signal, TextSpan, TextSpanMark } from \"@framefields/core\";\n\nexport type { TextSpan, TextSpanMark };\n\nexport type TextSpanItem =\n\t| string\n\t| number\n\t| boolean\n\t| Signal<unknown>\n\t| TextSpan\n\t| (string | TextSpan)[]\n\t| null\n\t| undefined;\n\n/**\n * Tagged template literal for authoring rich, multi-style text runs.\n *\n * Interpolates strings, numbers, reactive signals, and typed span modifiers\n * directly into a structured TextSpan[] array with zero runtime parsing.\n *\n * @example\n * rich`Scale ${bold(\"10x\", { fill: \"#6366f1\" })} faster with ${mark(\"120 FPS\", { bg: \"#10b98133\" })}`\n */\nexport function rich(\n\tstrings: TemplateStringsArray,\n\t...values: TextSpanItem[]\n): TextSpan[] {\n\tconst spans: TextSpan[] = [];\n\n\tfor (let i = 0; i < strings.length; i++) {\n\t\tconst str = strings[i];\n\t\tif (str) {\n\t\t\tspans.push({ text: str });\n\t\t}\n\n\t\tif (i < values.length) {\n\t\t\tconst val = values[i];\n\t\t\tif (val === null || val === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (Array.isArray(val)) {\n\t\t\t\tfor (const item of val) {\n\t\t\t\t\tif (typeof item === \"string\") {\n\t\t\t\t\t\tif (item) spans.push({ text: item });\n\t\t\t\t\t} else if (item && typeof item === \"object\" && \"text\" in item) {\n\t\t\t\t\t\tspans.push(item as TextSpan);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (typeof val === \"object\" && \"text\" in val) {\n\t\t\t\tspans.push(val as TextSpan);\n\t\t\t} else if (\n\t\t\t\ttypeof val === \"object\" &&\n\t\t\t\t\"get\" in val &&\n\t\t\t\ttypeof (val as { get: unknown }).get === \"function\"\n\t\t\t) {\n\t\t\t\tspans.push({ text: val as Signal<string> });\n\t\t\t} else {\n\t\t\t\tspans.push({ text: String(val) });\n\t\t\t}\n\t\t}\n\t}\n\n\treturn spans;\n}\n\nexport function span(\n\ttext: string | Signal<string>,\n\toptions: Omit<TextSpan, \"text\"> = {},\n): TextSpan {\n\treturn { text, ...options };\n}\n\nexport function bold(\n\ttext: string | Signal<string>,\n\toptions: Omit<TextSpan, \"text\"> = {},\n): TextSpan {\n\treturn { text, fontWeight: options.fontWeight ?? 700, ...options };\n}\n\nexport function italic(\n\ttext: string | Signal<string>,\n\toptions: Omit<TextSpan, \"text\"> = {},\n): TextSpan {\n\treturn { text, fontStyle: \"italic\", ...options };\n}\n\nexport function accent(\n\ttext: string | Signal<string>,\n\toptions: Omit<TextSpan, \"text\"> = {},\n): TextSpan {\n\treturn { text, fill: options.fill ?? \"#6366f1\", ...options };\n}\n\nexport function color(\n\ttext: string | Signal<string>,\n\tfill: string | Signal<string>,\n\toptions: Omit<TextSpan, \"text\" | \"fill\"> = {},\n): TextSpan {\n\treturn { text, fill, ...options };\n}\n\nexport function size(\n\ttext: string | Signal<string>,\n\tfontSize: number | Signal<number>,\n\toptions: Omit<TextSpan, \"text\" | \"fontSize\"> = {},\n): TextSpan {\n\treturn { text, fontSize, ...options };\n}\n\nexport interface MarkOptions extends Omit<TextSpan, \"text\" | \"mark\" | \"fill\"> {\n\tbg?: string | Signal<string>;\n\tfill?: string | Signal<string>;\n\tradius?: number;\n\tpaddingX?: number;\n\tpaddingY?: number;\n}\n\nexport function mark(\n\ttext: string | Signal<string>,\n\toptions: MarkOptions = {},\n): TextSpan {\n\tconst { bg, fill, radius, paddingX, paddingY, ...rest } = options;\n\treturn {\n\t\ttext,\n\t\tfill,\n\t\tmark: {\n\t\t\tbackground: bg ?? \"#6366f133\",\n\t\t\tborderRadius: radius ?? 4,\n\t\t\tpaddingX: paddingX ?? 6,\n\t\t\tpaddingY: paddingY ?? 2,\n\t\t},\n\t\t...rest,\n\t};\n}\n\nexport function sup(\n\ttext: string | Signal<string>,\n\toptions: Omit<TextSpan, \"text\"> = {},\n): TextSpan {\n\treturn {\n\t\ttext,\n\t\tbaselineShift: options.baselineShift ?? -8,\n\t\t...options,\n\t};\n}\n\nexport function sub(\n\ttext: string | Signal<string>,\n\toptions: Omit<TextSpan, \"text\"> = {},\n): TextSpan {\n\treturn {\n\t\ttext,\n\t\tbaselineShift: options.baselineShift ?? 6,\n\t\t...options,\n\t};\n}\n\nexport function code(\n\ttext: string | Signal<string>,\n\toptions: Omit<TextSpan, \"text\"> = {},\n): TextSpan {\n\treturn {\n\t\ttext,\n\t\tfontFamily: options.fontFamily ?? \"JetBrains Mono\",\n\t\tmark: options.mark ?? {\n\t\t\tbackground: \"#ffffff18\",\n\t\t\tborderRadius: 4,\n\t\t\tpaddingX: 6,\n\t\t\tpaddingY: 2,\n\t\t},\n\t\t...options,\n\t};\n}\n\n/**\n * Normalizes string, TextSpan[], or array of mixed strings/spans into plain text and spans.\n */\nexport function normalizeTextSpans(\n\tinput: string | TextSpan[] | (string | TextSpan)[],\n): { text: string; spans?: TextSpan[] } {\n\tif (typeof input === \"string\") {\n\t\treturn { text: input };\n\t}\n\n\tif (!Array.isArray(input)) {\n\t\treturn { text: String(input) };\n\t}\n\n\tconst spans: TextSpan[] = [];\n\tlet plainText = \"\";\n\n\tfor (const item of input) {\n\t\tif (typeof item === \"string\") {\n\t\t\tif (item) {\n\t\t\t\tspans.push({ text: item });\n\t\t\t\tplainText += item;\n\t\t\t}\n\t\t} else if (item && typeof item === \"object\" && \"text\" in item) {\n\t\t\tconst s = item as TextSpan;\n\t\t\tspans.push(s);\n\t\t\tconst piece =\n\t\t\t\ttypeof s.text === \"string\"\n\t\t\t\t\t? s.text\n\t\t\t\t\t: s.text &&\n\t\t\t\t\t\t\ttypeof s.text === \"object\" &&\n\t\t\t\t\t\t\t\"get\" in s.text &&\n\t\t\t\t\t\t\ttypeof (s.text as { get: () => unknown }).get === \"function\"\n\t\t\t\t\t\t? String((s.text as { get: () => unknown }).get())\n\t\t\t\t\t\t: String(s.text ?? \"\");\n\t\t\tplainText += piece;\n\t\t}\n\t}\n\n\treturn {\n\t\ttext: plainText,\n\t\tspans: spans.length > 0 ? spans : undefined,\n\t};\n}\n\n/**\n * Upfront parser for external CMS or subtitle strings containing basic tags\n * (<b>, <i>, <span>, <color>, <mark>, <accent>, <code>, <sup>, <sub>).\n *\n * Compiles string markup into clean TextSpan[] before entering the composition pipeline.\n */\nexport function parseMarkup(markup: string): TextSpan[] {\n\tif (!markup || !markup.includes(\"<\")) {\n\t\treturn [{ text: markup }];\n\t}\n\n\tconst spans: TextSpan[] = [];\n\tconst tagRegex = /<(\\/?[a-zA-Z0-9_-]+)([^>]*)>/g;\n\tlet lastIndex = 0;\n\n\tinterface StyleState {\n\t\ttag: string;\n\t\tstyle: Partial<TextSpan>;\n\t}\n\tconst stack: StyleState[] = [];\n\n\tconst getCurrentStyle = (): Partial<TextSpan> => {\n\t\tconst merged: Partial<TextSpan> = {};\n\t\tfor (const state of stack) {\n\t\t\tObject.assign(merged, state.style);\n\t\t}\n\t\treturn merged;\n\t};\n\n\tfor (;;) {\n\t\tconst match = tagRegex.exec(markup);\n\t\tif (!match) {\n\t\t\tbreak;\n\t\t}\n\t\tconst textBefore = markup.slice(lastIndex, match.index);\n\t\tif (textBefore) {\n\t\t\tspans.push({ text: textBefore, ...getCurrentStyle() });\n\t\t}\n\t\tlastIndex = match.index + match[0].length;\n\n\t\tconst tagName = match[1].toLowerCase();\n\t\tconst rawAttrs = match[2];\n\n\t\tif (tagName.startsWith(\"/\")) {\n\t\t\tconst closingTag = tagName.slice(1);\n\t\t\tfor (let i = stack.length - 1; i >= 0; i--) {\n\t\t\t\tif (stack[i].tag === closingTag) {\n\t\t\t\t\tstack.splice(i, 1);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconst attrs: Record<string, string> = {};\n\t\t\tconst attrRegex = /([a-zA-Z0-9_-]+)=[\"']([^\"']*)[\"']/g;\n\t\t\tfor (;;) {\n\t\t\t\tconst attrMatch = attrRegex.exec(rawAttrs);\n\t\t\t\tif (!attrMatch) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tattrs[attrMatch[1].toLowerCase()] = attrMatch[2];\n\t\t\t}\n\n\t\t\tconst style: Partial<TextSpan> = {};\n\n\t\t\tif (tagName === \"b\" || tagName === \"strong\") {\n\t\t\t\tstyle.fontWeight = 700;\n\t\t\t\tif (attrs.color || attrs.fill) style.fill = attrs.color ?? attrs.fill;\n\t\t\t} else if (tagName === \"i\" || tagName === \"em\") {\n\t\t\t\tstyle.fontStyle = \"italic\";\n\t\t\t\tif (attrs.color || attrs.fill) style.fill = attrs.color ?? attrs.fill;\n\t\t\t} else if (tagName === \"accent\") {\n\t\t\t\tstyle.fill = \"#6366f1\";\n\t\t\t} else if (tagName === \"color\") {\n\t\t\t\tstyle.fill = attrs.value ?? attrs.hex ?? attrs.fill;\n\t\t\t} else if (tagName === \"size\") {\n\t\t\t\tconst num = parseFloat(attrs.value ?? attrs.px ?? attrs.pt ?? \"0\");\n\t\t\t\tif (num > 0) style.fontSize = num;\n\t\t\t} else if (tagName === \"mark\") {\n\t\t\t\tstyle.mark = {\n\t\t\t\t\tbackground: attrs.bg ?? attrs.background ?? \"#6366f133\",\n\t\t\t\t\tborderRadius: attrs.radius ? parseFloat(attrs.radius) : 4,\n\t\t\t\t\tpaddingX: attrs.paddingx ? parseFloat(attrs.paddingx) : 6,\n\t\t\t\t\tpaddingY: attrs.paddingy ? parseFloat(attrs.paddingy) : 2,\n\t\t\t\t};\n\t\t\t\tif (attrs.color || attrs.fill) style.fill = attrs.color ?? attrs.fill;\n\t\t\t} else if (tagName === \"sup\") {\n\t\t\t\tstyle.baselineShift = -8;\n\t\t\t} else if (tagName === \"sub\") {\n\t\t\t\tstyle.baselineShift = 6;\n\t\t\t} else if (tagName === \"code\") {\n\t\t\t\tstyle.fontFamily = \"JetBrains Mono\";\n\t\t\t\tstyle.mark = {\n\t\t\t\t\tbackground: attrs.bg ?? \"#ffffff18\",\n\t\t\t\t\tborderRadius: 4,\n\t\t\t\t\tpaddingX: 6,\n\t\t\t\t\tpaddingY: 2,\n\t\t\t\t};\n\t\t\t} else if (tagName === \"span\") {\n\t\t\t\tif (attrs.color || attrs.fill) style.fill = attrs.color ?? attrs.fill;\n\t\t\t\tif (attrs.fontfamily) style.fontFamily = attrs.fontfamily;\n\t\t\t\tif (attrs.fontsize) style.fontSize = parseFloat(attrs.fontsize);\n\t\t\t\tif (attrs.fontweight) {\n\t\t\t\t\tconst nw = parseInt(attrs.fontweight, 10);\n\t\t\t\t\tstyle.fontWeight = Number.isNaN(nw) ? attrs.fontweight : nw;\n\t\t\t\t}\n\t\t\t\tif (attrs.fontstyle === \"italic\" || attrs.fontstyle === \"normal\") {\n\t\t\t\t\tstyle.fontStyle = attrs.fontstyle;\n\t\t\t\t}\n\t\t\t\tif (attrs.letterspacing)\n\t\t\t\t\tstyle.letterSpacing = parseFloat(attrs.letterspacing);\n\t\t\t\tif (attrs.baselineshift)\n\t\t\t\t\tstyle.baselineShift = parseFloat(attrs.baselineshift);\n\t\t\t\tif (attrs.opacity) style.opacity = parseFloat(attrs.opacity);\n\t\t\t}\n\n\t\t\tstack.push({ tag: tagName, style });\n\t\t}\n\t}\n\n\tconst remainingText = markup.slice(lastIndex);\n\tif (remainingText) {\n\t\tspans.push({ text: remainingText, ...getCurrentStyle() });\n\t}\n\n\treturn spans;\n}\n","/**\n * Charts built from ordinary layout nodes. d3 does the math (scales, ticks,\n * line/area/arc geometry, stacking); every bar, line, slice and label is a\n * regular box, shape or text node, so charts use the composition's fonts and\n * can be animated, graded and composited like any other layer.\n */\nimport {\n\ttype BoxNode,\n\tLayerAnimation,\n\ttype LayoutNode,\n} from \"@framefields/compositions/program\";\nimport { format as d3Format } from \"d3-format\";\nimport {\n\ttype ScaleBand,\n\ttype ScaleLinear,\n\ttype ScaleTime,\n\tscaleBand,\n\tscaleLinear,\n\tscaleUtc,\n} from \"d3-scale\";\nimport {\n\ttype CurveFactory,\n\tcurveLinear,\n\tcurveMonotoneX,\n\tcurveStepAfter,\n\tarc as d3Arc,\n\tarea as d3Area,\n\tline as d3Line,\n\tpie as d3Pie,\n\tstack as d3Stack,\n\tstackOffsetDiverging,\n} from \"d3-shape\";\nimport { autoId } from \"./ids.js\";\nimport { type AnimatableNode, Layer } from \"./index.js\";\n\nexport type ChartType =\n\t| \"line\"\n\t| \"area\"\n\t| \"bar\"\n\t| \"scatter\"\n\t| \"pie\"\n\t| \"donut\"\n\t| \"candlestick\";\n\nexport type ChartX = number | string | Date;\n\n/** A plain value (x is its index or `categories[i]`), an `[x, y]` pair, or `{ x, y }`. */\nexport type ChartDatum =\n\t| number\n\t| readonly [ChartX, number]\n\t| { x: ChartX; y: number };\n\nexport interface ChartCandle {\n\tx: ChartX;\n\topen: number;\n\thigh: number;\n\tlow: number;\n\tclose: number;\n}\n\n/** A pie or donut slice. */\nexport interface ChartSlice {\n\tlabel: string;\n\tvalue: number;\n\tcolor?: string;\n}\n\nexport interface ChartSeries {\n\tname?: string;\n\t/** Series type in a combined chart; defaults to the chart's `type`. */\n\ttype?: Exclude<ChartType, \"pie\" | \"donut\">;\n\tdata: readonly ChartDatum[] | readonly ChartCandle[];\n\tcolor?: string;\n\t/** Line width for line and area series. Default 3. */\n\tstrokeWidth?: number;\n\t/** Line and area interpolation. Default \"smooth\". */\n\tcurve?: \"linear\" | \"smooth\" | \"step\";\n\t/** Dot radius drawn on line points; scatter point radius. 0 hides line dots. */\n\tpointRadius?: number;\n}\n\nexport interface ChartAxisOptions {\n\t/** Show tick labels. Default true. */\n\tshow?: boolean;\n\t/** Draw grid lines across the plot. Default true for y, false for x. */\n\tgrid?: boolean;\n\tmin?: number;\n\tmax?: number;\n\t/** Approximate number of ticks. Default 5. */\n\tticks?: number;\n\t/** A d3-format specifier such as \",.0f\", \"$.2s\" or \".0%\", or a function. */\n\tformat?: string | ((value: ChartX) => string);\n}\n\nexport interface ChartAnimationOptions {\n\t/** Frame the reveal starts, relative to the chart's own start. Default 0. */\n\tstart?: number;\n\t/** Frames each element takes to animate in. Default 30. */\n\tduration?: number;\n\t/** Frames between consecutive bars, points or slices. Default spreads them over `duration`. */\n\tstagger?: number;\n\t/** Easing for bars, points and slices. Default \"power3.out\". */\n\tease?: string;\n}\n\nexport interface ChartPadding {\n\ttop?: number;\n\tright?: number;\n\tbottom?: number;\n\tleft?: number;\n}\n\nexport interface ChartOptions {\n\t/** Chart type, and the default for series without their own. Default \"line\". */\n\ttype?: ChartType;\n\twidth?: number;\n\theight?: number;\n\tseries?: readonly ChartSeries[];\n\t/** Shorthand for a single series, or the slices of a pie or donut. */\n\tdata?: readonly ChartDatum[] | readonly ChartCandle[] | readonly ChartSlice[];\n\t/** Labels for x positions when data are plain values; slice labels for pie charts. */\n\tcategories?: readonly string[];\n\t/** Stack bar and area series instead of grouping or overlapping them. */\n\tstacked?: boolean;\n\tcolors?: readonly string[];\n\txAxis?: ChartAxisOptions;\n\tyAxis?: ChartAxisOptions;\n\t/** Space around the plot for axis labels and legend. Computed when omitted. */\n\tpadding?: number | ChartPadding;\n\tfontFamily?: string;\n\t/** Axis, legend and value label size. Default 18. */\n\tfontSize?: number;\n\t/** Axis labels; when set, also the legend and value labels. */\n\ttextColor?: string;\n\tgridColor?: string;\n\tbackground?: string;\n\t/** Show the series or slice legend. Default: on for several series and for pies. */\n\tlegend?: boolean;\n\t/** Print values on bars and slices (pie values print as percentages). */\n\tvalueLabels?: boolean;\n\t/** Donut hole as a fraction of the radius. Default 0.6 for \"donut\". */\n\tinnerRadius?: number;\n\t/** Corner radius of bars and slices. Default 4. */\n\tcornerRadius?: number;\n\tupColor?: string;\n\tdownColor?: string;\n\t/** Reveal animation, or `false` for a static chart. */\n\tanimate?: false | ChartAnimationOptions;\n}\n\nexport const DEFAULT_CHART_COLORS = [\n\t\"#6366f1\",\n\t\"#22d3ee\",\n\t\"#f59e0b\",\n\t\"#ec4899\",\n\t\"#10b981\",\n\t\"#8b5cf6\",\n\t\"#f97316\",\n\t\"#3b82f6\",\n] as const;\n\ntype XScale =\n\t| ScaleBand<string>\n\t| ScaleLinear<number, number>\n\t| ScaleTime<number, number>;\n\ninterface Timing {\n\tenabled: boolean;\n\tstart: number;\n\tduration: number;\n\tstagger: number;\n\tease: string;\n}\n\ninterface Point {\n\tx: ChartX;\n\ty: number;\n}\n\ninterface Rect {\n\tx: number;\n\ty: number;\n\twidth: number;\n\theight: number;\n}\n\nconst isCandle = (d: unknown): d is ChartCandle =>\n\ttypeof d === \"object\" && d !== null && \"open\" in d && \"close\" in d;\n\nconst isSlice = (d: unknown): d is ChartSlice =>\n\ttypeof d === \"object\" && d !== null && \"label\" in d && \"value\" in d;\n\nfunction curveOf(curve: ChartSeries[\"curve\"]): CurveFactory {\n\tif (curve === \"linear\") return curveLinear;\n\tif (curve === \"step\") return curveStepAfter;\n\treturn curveMonotoneX;\n}\n\nfunction withAlpha(color: string, alpha: number): string {\n\tconst hex = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(color.trim());\n\tif (!hex) return color;\n\tlet h = hex[1];\n\tif (h.length === 3) h = [...h].map((c) => c + c).join(\"\");\n\tconst n = parseInt(h, 16);\n\treturn `rgba(${(n >> 16) & 255}, ${(n >> 8) & 255}, ${n & 255}, ${alpha})`;\n}\n\nfunction fmt(\n\taxis: ChartAxisOptions | undefined,\n): ((v: ChartX) => string) | null {\n\tif (!axis?.format) return null;\n\tif (typeof axis.format === \"function\") return axis.format;\n\tconst f = d3Format(axis.format);\n\treturn (v) => (typeof v === \"number\" ? f(v) : String(v));\n}\n\nfunction round(v: number): number {\n\treturn Math.round(v * 100) / 100;\n}\n\nfunction fadeIn(t: Timing, delay = 0, duration = t.duration): LayerAnimation {\n\treturn LayerAnimation.create().fromTo(\"opacity\", 0, 1, {\n\t\tstart: t.start + delay,\n\t\tend: t.start + delay + Math.max(1, duration),\n\t\tease: \"power2.out\",\n\t});\n}\n\n/** Builds the chart as a box of absolutely positioned child nodes. */\nexport function buildChart(\n\toptions: ChartOptions,\n\tprops: Partial<BoxNode>,\n\tdefaultFontFamily: string,\n): AnimatableNode<BoxNode> {\n\tconst id = props.id ?? autoId(\"chart\");\n\tconst width =\n\t\toptions.width ?? (typeof props.width === \"number\" ? props.width : 960);\n\tconst height =\n\t\toptions.height ?? (typeof props.height === \"number\" ? props.height : 540);\n\tconst type = options.type ?? \"line\";\n\tconst fontSize = options.fontSize ?? 18;\n\tconst fontFamily = options.fontFamily ?? defaultFontFamily;\n\tconst textColor = options.textColor ?? \"#94a3b8\";\n\t// Legend and value labels read a little stronger than axis labels; with a custom\n\t// textColor (e.g. dark text on a light background) they use it as is.\n\tconst strongText = options.textColor ?? \"#e2e8f0\";\n\tconst gridColor = options.gridColor ?? \"rgba(148, 163, 184, 0.18)\";\n\tconst colors = options.colors?.length ? options.colors : DEFAULT_CHART_COLORS;\n\tconst radius = options.cornerRadius ?? 4;\n\n\tconst anim = options.animate === false ? undefined : (options.animate ?? {});\n\tconst timing: Timing = {\n\t\tenabled: anim !== undefined,\n\t\tstart: anim?.start ?? 0,\n\t\tduration: anim?.duration ?? 30,\n\t\tstagger: anim?.stagger ?? -1,\n\t\tease: anim?.ease ?? \"power3.out\",\n\t};\n\n\tconst children: LayoutNode[] = [];\n\tconst label = (\n\t\ttext: string,\n\t\trect: Rect,\n\t\talign: \"start\" | \"center\" | \"end\",\n\t\textra: { delay?: number; color?: string; weight?: number } = {},\n\t\tkey = \"\",\n\t) => {\n\t\tconst node = Layer.text(text, {\n\t\t\tid: `${id}-label-${key || children.length}`,\n\t\t\tposition: \"absolute\",\n\t\t\tx: round(rect.x),\n\t\t\ty: round(rect.y),\n\t\t\twidth: round(rect.width),\n\t\t\theight: round(rect.height),\n\t\t\tfontFamily,\n\t\t\tfontSize,\n\t\t\tfontWeight: extra.weight ?? 500,\n\t\t\tfill: extra.color ?? textColor,\n\t\t\talign,\n\t\t\tverticalAlign: \"middle\",\n\t\t});\n\t\tif (timing.enabled) node.animate(fadeIn(timing, extra.delay ?? 0));\n\t\tchildren.push(node);\n\t};\n\n\tconst lineHeight = Math.ceil(fontSize * 1.4);\n\n\tif (type === \"pie\" || type === \"donut\") {\n\t\tbuildPie();\n\t} else {\n\t\tbuildCartesian();\n\t}\n\n\t// Staggers and fractional durations land between frames; the program schema\n\t// wants whole-frame keyframes.\n\tfor (const child of children) snapKeyframes(child);\n\n\treturn Layer.box({\n\t\tbackground: options.background ?? \"transparent\",\n\t\t...props,\n\t\tid,\n\t\twidth,\n\t\theight,\n\t\tchildren,\n\t});\n\n\t// ── pie & donut ─────────────────────────────────────────────────────\n\n\tfunction buildPie(): void {\n\t\tconst slices = collectSlices();\n\t\tconst total = slices.reduce((s, d) => s + Math.max(0, d.value), 0);\n\t\tconst showLegend = options.legend ?? true;\n\t\tconst pad = resolvePadding({\n\t\t\ttop: 16,\n\t\t\tright: showLegend ? legendColumnWidth(slices.map((s) => s.label)) : 16,\n\t\t\tbottom: 16,\n\t\t\tleft: 16,\n\t\t});\n\t\tconst plot = plotRect(pad);\n\t\tconst r = Math.max(1, Math.min(plot.width, plot.height) / 2);\n\t\tconst inner = r * (options.innerRadius ?? (type === \"donut\" ? 0.6 : 0));\n\t\tconst cx = plot.x + plot.width / 2;\n\t\tconst cy = plot.y + plot.height / 2;\n\t\tconst m = 4;\n\t\tconst arcs = d3Pie<ChartSlice>()\n\t\t\t.sort(null)\n\t\t\t.value((d) => Math.max(0, d.value))\n\t\t\t.padAngle(slices.length > 1 ? 0.012 : 0)(slices);\n\t\tconst arcGen = d3Arc<(typeof arcs)[number]>()\n\t\t\t.innerRadius(inner)\n\t\t\t.outerRadius(r)\n\t\t\t.cornerRadius(Math.min(radius, (r - inner) / 2));\n\t\tconst step = staggerStep(arcs.length);\n\n\t\tarcs.forEach((a, i) => {\n\t\t\tconst d = arcGen(a);\n\t\t\tif (!d) return;\n\t\t\tconst color = slices[i].color ?? colors[i % colors.length];\n\t\t\tconst node = Layer.shape(\"path\", {\n\t\t\t\tid: `${id}-slice-${i}`,\n\t\t\t\tposition: \"absolute\",\n\t\t\t\tx: round(cx - r - m),\n\t\t\t\ty: round(cy - r - m),\n\t\t\t\twidth: round(2 * (r + m)),\n\t\t\t\theight: round(2 * (r + m)),\n\t\t\t\td: translatePath(d, r + m, r + m),\n\t\t\t\tfillColor: color,\n\t\t\t\tanchorX: 0.5,\n\t\t\t\tanchorY: 0.5,\n\t\t\t});\n\t\t\tif (timing.enabled) {\n\t\t\t\tconst s = timing.start + i * step;\n\t\t\t\tnode.animate(\n\t\t\t\t\tLayerAnimation.create()\n\t\t\t\t\t\t.fromTo(\"opacity\", 0, 1, {\n\t\t\t\t\t\t\tstart: s,\n\t\t\t\t\t\t\tend: s + timing.duration * 0.5,\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.fromTo(\"scale\", 0.85, 1, {\n\t\t\t\t\t\t\tstart: s,\n\t\t\t\t\t\t\tend: s + timing.duration,\n\t\t\t\t\t\t\tease: timing.ease,\n\t\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tchildren.push(node);\n\n\t\t\tif (options.valueLabels && total > 0 && a.value > 0) {\n\t\t\t\tconst [lx, ly] = d3Arc<(typeof arcs)[number]>()\n\t\t\t\t\t.innerRadius(inner || r * 0.55)\n\t\t\t\t\t.outerRadius(r)\n\t\t\t\t\t.centroid(a);\n\t\t\t\tconst pct = `${Math.round((a.value / total) * 100)}%`;\n\t\t\t\tlabel(\n\t\t\t\t\tpct,\n\t\t\t\t\t{\n\t\t\t\t\t\tx: cx + lx - 60,\n\t\t\t\t\t\ty: cy + ly - lineHeight / 2,\n\t\t\t\t\t\twidth: 120,\n\t\t\t\t\t\theight: lineHeight,\n\t\t\t\t\t},\n\t\t\t\t\t\"center\",\n\t\t\t\t\t{\n\t\t\t\t\t\tdelay: i * step + timing.duration * 0.5,\n\t\t\t\t\t\tcolor: \"#ffffff\",\n\t\t\t\t\t\tweight: 700,\n\t\t\t\t\t},\n\t\t\t\t\t`value-${i}`,\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\tif (showLegend) {\n\t\t\tlegendColumn(\n\t\t\t\tslices.map((s, i) => ({\n\t\t\t\t\tname: s.label,\n\t\t\t\t\tcolor: s.color ?? colors[i % colors.length],\n\t\t\t\t})),\n\t\t\t\t{ x: plot.x + plot.width + 24, y: plot.y, height: plot.height },\n\t\t\t);\n\t\t}\n\t}\n\n\tfunction collectSlices(): ChartSlice[] {\n\t\tconst raw = (options.data ??\n\t\t\toptions.series?.[0]?.data ??\n\t\t\t[]) as readonly unknown[];\n\t\treturn raw.map((d, i) => {\n\t\t\tif (isSlice(d)) return d;\n\t\t\tconst value =\n\t\t\t\ttypeof d === \"number\"\n\t\t\t\t\t? d\n\t\t\t\t\t: Array.isArray(d)\n\t\t\t\t\t\t? Number(d[1])\n\t\t\t\t\t\t: Number((d as Point).y);\n\t\t\tconst name =\n\t\t\t\toptions.categories?.[i] ??\n\t\t\t\t(Array.isArray(d)\n\t\t\t\t\t? String(d[0])\n\t\t\t\t\t: typeof d === \"object\" && d\n\t\t\t\t\t\t? String((d as Point).x)\n\t\t\t\t\t\t: `${i + 1}`);\n\t\t\treturn { label: name, value };\n\t\t});\n\t}\n\n\t// ── cartesian: line, area, bar, scatter, candlestick ───────────────\n\n\tfunction buildCartesian(): void {\n\t\tconst series: ChartSeries[] = options.series?.length\n\t\t\t? [...options.series]\n\t\t\t: options.data\n\t\t\t\t? [{ data: options.data as ChartSeries[\"data\"] }]\n\t\t\t\t: [];\n\t\tif (series.length === 0) return;\n\n\t\tconst typeOf = (s: ChartSeries) =>\n\t\t\ts.type ?? (type as ChartSeries[\"type\"]) ?? \"line\";\n\t\tconst colorOf = (s: ChartSeries, i: number) =>\n\t\t\ts.color ?? colors[i % colors.length];\n\n\t\t// Normalise every series to points (candles keep their OHLC values).\n\t\tconst points: Point[][] = series.map((s) =>\n\t\t\t(s.data as readonly unknown[]).map((d, i) => {\n\t\t\t\tif (isCandle(d)) return { x: d.x, y: d.close };\n\t\t\t\tif (typeof d === \"number\")\n\t\t\t\t\treturn { x: options.categories?.[i] ?? i, y: d };\n\t\t\t\tif (Array.isArray(d)) return { x: d[0] as ChartX, y: Number(d[1]) };\n\t\t\t\treturn { x: (d as Point).x, y: Number((d as Point).y) };\n\t\t\t}),\n\t\t);\n\n\t\tconst anyBand = series.some(\n\t\t\t(s) => typeOf(s) === \"bar\" || typeOf(s) === \"candlestick\",\n\t\t);\n\t\tconst allX = points.flat().map((p) => p.x);\n\t\tconst xKind: \"band\" | \"time\" | \"linear\" =\n\t\t\tanyBand || allX.some((x) => typeof x === \"string\")\n\t\t\t\t? \"band\"\n\t\t\t\t: allX.some((x) => x instanceof Date)\n\t\t\t\t\t? \"time\"\n\t\t\t\t\t: \"linear\";\n\n\t\t// Stacking for bars and areas.\n\t\tconst stackable = (s: ChartSeries) =>\n\t\t\ttypeOf(s) === \"bar\" || typeOf(s) === \"area\";\n\t\tconst stacked = !!options.stacked;\n\t\tconst categories = xKind === \"band\" ? [...new Set(allX.map(String))] : [];\n\t\tconst stackRanges = new Map<number, [number, number][]>();\n\t\tif (stacked) {\n\t\t\tconst keys = series.map((_, i) => i).filter((i) => stackable(series[i]));\n\t\t\tconst rows = categories.length\n\t\t\t\t? categories\n\t\t\t\t: [...new Set(allX.map((x) => +x))].sort((a, b) => a - b).map(String);\n\t\t\tconst table = rows.map((key) => {\n\t\t\t\tconst row: Record<string, number> = {};\n\t\t\t\tfor (const i of keys) {\n\t\t\t\t\tconst p = points[i].find(\n\t\t\t\t\t\t(pt) => String(xKind === \"band\" ? pt.x : +pt.x) === key,\n\t\t\t\t\t);\n\t\t\t\t\trow[i] = p?.y ?? 0;\n\t\t\t\t}\n\t\t\t\treturn row;\n\t\t\t});\n\t\t\tconst layers = d3Stack<Record<string, number>>()\n\t\t\t\t.keys(keys.map(String))\n\t\t\t\t.offset(stackOffsetDiverging)(table);\n\t\t\tlayers.forEach((layer) => {\n\t\t\t\tconst i = Number(layer.key);\n\t\t\t\tstackRanges.set(\n\t\t\t\t\ti,\n\t\t\t\t\tpoints[i].map((p) => {\n\t\t\t\t\t\tconst idx = rows.indexOf(String(xKind === \"band\" ? p.x : +p.x));\n\t\t\t\t\t\treturn [layer[idx][0], layer[idx][1]];\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\n\t\t// y domain\n\t\tconst yValues: number[] = [0];\n\t\tseries.forEach((s, i) => {\n\t\t\tconst range = stackRanges.get(i);\n\t\t\tif (typeOf(s) === \"candlestick\") {\n\t\t\t\tfor (const c of s.data as readonly ChartCandle[])\n\t\t\t\t\tyValues.push(c.high, c.low);\n\t\t\t} else if (range) {\n\t\t\t\tfor (const [a, b] of range) yValues.push(a, b);\n\t\t\t} else {\n\t\t\t\tfor (const p of points[i]) yValues.push(p.y);\n\t\t\t}\n\t\t});\n\t\tif (\n\t\t\tseries.every(\n\t\t\t\t(s) =>\n\t\t\t\t\ttypeOf(s) === \"candlestick\" ||\n\t\t\t\t\ttypeOf(s) === \"scatter\" ||\n\t\t\t\t\ttypeOf(s) === \"line\",\n\t\t\t)\n\t\t) {\n\t\t\t// Line, scatter and price charts don't have to include zero.\n\t\t\tyValues.shift();\n\t\t}\n\n\t\tconst yAxis = options.yAxis ?? {};\n\t\tconst xAxis = options.xAxis ?? {};\n\t\tconst yTickCount = yAxis.ticks ?? 5;\n\t\tlet lo = yAxis.min ?? Math.min(...yValues);\n\t\tlet hi = yAxis.max ?? Math.max(...yValues);\n\t\tif (!Number.isFinite(lo) || !Number.isFinite(hi)) [lo, hi] = [0, 1];\n\t\tif (lo === hi) [lo, hi] = [lo - 1, hi + 1];\n\t\tconst y = scaleLinear().domain([lo, hi]);\n\t\tif (yAxis.min === undefined || yAxis.max === undefined) y.nice(yTickCount);\n\t\tconst yFormat =\n\t\t\tfmt(yAxis) ?? ((v: ChartX) => y.tickFormat(yTickCount)(v as number));\n\t\tconst yTicks = y.ticks(yTickCount);\n\n\t\tconst legendItems = series.map((s, i) => ({\n\t\t\tname: s.name ?? `Series ${i + 1}`,\n\t\t\tcolor: colorOf(s, i),\n\t\t}));\n\t\tconst showLegend = options.legend ?? series.length > 1;\n\t\tconst showY = yAxis.show !== false;\n\t\tconst showX = xAxis.show !== false;\n\t\tconst yLabelWidth = showY\n\t\t\t? Math.max(...yTicks.map((t) => yFormat(t).length)) * fontSize * 0.7 + 20\n\t\t\t: 0;\n\t\tconst pad = resolvePadding({\n\t\t\ttop: (showLegend ? lineHeight + 20 : 0) + Math.ceil(lineHeight / 2),\n\t\t\tright: 20,\n\t\t\tbottom: showX ? lineHeight + 14 : 12,\n\t\t\tleft: Math.max(16, Math.ceil(yLabelWidth)),\n\t\t});\n\t\tconst plot = plotRect(pad);\n\t\t// Room for value labels above positive bars and below negative ones.\n\t\tconst labelRoom = lineHeight + 6;\n\t\tconst barValues = options.valueLabels\n\t\t\t? series.flatMap((s, i) =>\n\t\t\t\t\ttypeOf(s) === \"bar\" ? points[i].map((p) => p.y) : [],\n\t\t\t\t)\n\t\t\t: [];\n\t\tconst topInset = barValues.some((v) => v > 0) ? labelRoom : 0;\n\t\tconst bottomInset = barValues.some((v) => v < 0) ? labelRoom : 0;\n\t\ty.range([plot.height - bottomInset, topInset]);\n\n\t\tlet x: XScale;\n\t\tif (xKind === \"band\") {\n\t\t\tx = scaleBand<string>()\n\t\t\t\t.domain(categories)\n\t\t\t\t.range([0, plot.width])\n\t\t\t\t.paddingInner(anyBand ? 0.28 : 0)\n\t\t\t\t.paddingOuter(anyBand ? 0.14 : 0.5);\n\t\t} else if (xKind === \"time\") {\n\t\t\tconst xs = allX.map((v) => +new Date(v as Date));\n\t\t\tx = scaleUtc()\n\t\t\t\t.domain([Math.min(...xs), Math.max(...xs)])\n\t\t\t\t.range([0, plot.width]);\n\t\t} else {\n\t\t\tconst xs = allX.map(Number);\n\t\t\tx = scaleLinear()\n\t\t\t\t.domain([xAxis.min ?? Math.min(...xs), xAxis.max ?? Math.max(...xs)])\n\t\t\t\t.range([0, plot.width]);\n\t\t}\n\t\tconst xPos = (v: ChartX): number => {\n\t\t\tif (xKind === \"band\") {\n\t\t\t\tconst b = x as ScaleBand<string>;\n\t\t\t\treturn (b(String(v)) ?? 0) + b.bandwidth() / 2;\n\t\t\t}\n\t\t\tif (xKind === \"time\")\n\t\t\t\treturn (x as ScaleTime<number, number>)(new Date(v as Date));\n\t\t\treturn (x as ScaleLinear<number, number>)(Number(v));\n\t\t};\n\n\t\t// Grid and y labels.\n\t\tconst gridDelay = 0;\n\t\tif (yAxis.grid !== false) {\n\t\t\tyTicks.forEach((t, i) => {\n\t\t\t\tconst node = Layer.box({\n\t\t\t\t\tid: `${id}-ygrid-${i}`,\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tx: plot.x,\n\t\t\t\t\ty: round(plot.y + y(t) - 0.5),\n\t\t\t\t\twidth: plot.width,\n\t\t\t\t\theight: 1,\n\t\t\t\t\tbackground: gridColor,\n\t\t\t\t});\n\t\t\t\tif (timing.enabled)\n\t\t\t\t\tnode.animate(fadeIn(timing, gridDelay, timing.duration / 2));\n\t\t\t\tchildren.push(node);\n\t\t\t});\n\t\t}\n\t\tif (showY) {\n\t\t\tyTicks.forEach((t, i) => {\n\t\t\t\tlabel(\n\t\t\t\t\tyFormat(t),\n\t\t\t\t\t{\n\t\t\t\t\t\tx: 0,\n\t\t\t\t\t\ty: plot.y + y(t) - lineHeight / 2,\n\t\t\t\t\t\twidth: plot.x - 12,\n\t\t\t\t\t\theight: lineHeight,\n\t\t\t\t\t},\n\t\t\t\t\t\"end\",\n\t\t\t\t\t{},\n\t\t\t\t\t`y-${i}`,\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\n\t\t// x labels (and optional vertical grid).\n\t\tconst xTicks: { pos: number; text: string }[] = [];\n\t\tconst xFormat = fmt(xAxis);\n\t\tif (xKind === \"band\") {\n\t\t\tconst b = x as ScaleBand<string>;\n\t\t\tconst every = Math.max(\n\t\t\t\t1,\n\t\t\t\tMath.ceil(\n\t\t\t\t\tcategories.length /\n\t\t\t\t\t\tMath.max(1, Math.floor(plot.width / (fontSize * 4))),\n\t\t\t\t),\n\t\t\t);\n\t\t\tcategories.forEach((c, i) => {\n\t\t\t\tif (i % every === 0)\n\t\t\t\t\txTicks.push({\n\t\t\t\t\t\tpos: (b(c) ?? 0) + b.bandwidth() / 2,\n\t\t\t\t\t\ttext: xFormat ? xFormat(c) : c,\n\t\t\t\t\t});\n\t\t\t});\n\t\t} else {\n\t\t\tconst s = x as ScaleLinear<number, number>;\n\t\t\tconst count =\n\t\t\t\txAxis.ticks ?? Math.max(2, Math.floor(plot.width / (fontSize * 6)));\n\t\t\tconst tf = s.tickFormat(count);\n\t\t\tfor (const t of s.ticks(count)) {\n\t\t\t\txTicks.push({\n\t\t\t\t\tpos: s(t),\n\t\t\t\t\ttext: xFormat ? xFormat(xKind === \"time\" ? new Date(t) : t) : tf(t),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tif (xAxis.grid) {\n\t\t\txTicks.forEach((t, i) => {\n\t\t\t\tconst node = Layer.box({\n\t\t\t\t\tid: `${id}-xgrid-${i}`,\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tx: round(plot.x + t.pos - 0.5),\n\t\t\t\t\ty: plot.y,\n\t\t\t\t\twidth: 1,\n\t\t\t\t\theight: plot.height,\n\t\t\t\t\tbackground: gridColor,\n\t\t\t\t});\n\t\t\t\tif (timing.enabled)\n\t\t\t\t\tnode.animate(fadeIn(timing, gridDelay, timing.duration / 2));\n\t\t\t\tchildren.push(node);\n\t\t\t});\n\t\t}\n\t\tif (showX) {\n\t\t\tconst slot = Math.max(\n\t\t\t\tfontSize * 3,\n\t\t\t\tplot.width / Math.max(1, xTicks.length),\n\t\t\t);\n\t\t\txTicks.forEach((t, i) => {\n\t\t\t\tlabel(\n\t\t\t\t\tt.text,\n\t\t\t\t\t{\n\t\t\t\t\t\tx: plot.x + t.pos - slot / 2,\n\t\t\t\t\t\ty: plot.y + plot.height + 10,\n\t\t\t\t\t\twidth: slot,\n\t\t\t\t\t\theight: lineHeight,\n\t\t\t\t\t},\n\t\t\t\t\t\"center\",\n\t\t\t\t\t{},\n\t\t\t\t\t`x-${i}`,\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\n\t\t// Baseline at zero when it is inside the domain.\n\t\tconst [y0, y1] = y.domain();\n\t\tif (y0 <= 0 && y1 >= 0 && anyBand) {\n\t\t\tconst node = Layer.box({\n\t\t\t\tid: `${id}-zero`,\n\t\t\t\tposition: \"absolute\",\n\t\t\t\tx: plot.x,\n\t\t\t\ty: round(plot.y + y(0) - 1),\n\t\t\t\twidth: plot.width,\n\t\t\t\theight: 2,\n\t\t\t\tbackground: withAlpha(\"#94a3b8\", 0.45),\n\t\t\t});\n\t\t\tif (timing.enabled) node.animate(fadeIn(timing, 0, timing.duration / 2));\n\t\t\tchildren.push(node);\n\t\t}\n\n\t\t// Series. Bars first so lines draw on top.\n\t\tconst barSeries = series\n\t\t\t.map((_, i) => i)\n\t\t\t.filter((i) => typeOf(series[i]) === \"bar\");\n\t\tconst order = [\n\t\t\t...barSeries,\n\t\t\t...series\n\t\t\t\t.map((_, i) => i)\n\t\t\t\t.filter((i) => typeOf(series[i]) === \"candlestick\"),\n\t\t\t...series.map((_, i) => i).filter((i) => typeOf(series[i]) === \"area\"),\n\t\t\t...series.map((_, i) => i).filter((i) => typeOf(series[i]) === \"line\"),\n\t\t\t...series.map((_, i) => i).filter((i) => typeOf(series[i]) === \"scatter\"),\n\t\t];\n\n\t\tconst band = xKind === \"band\" ? (x as ScaleBand<string>) : null;\n\t\tconst bandStep = band ? staggerStep(categories.length) : 0;\n\t\tconst categoryIndex = (v: ChartX) =>\n\t\t\tband ? categories.indexOf(String(v)) : 0;\n\n\t\torder.forEach((si, rank) => {\n\t\t\tconst s = series[si];\n\t\t\tconst color = colorOf(s, si);\n\t\t\tconst kind = typeOf(s);\n\t\t\tconst pts = points[si];\n\t\t\tconst range = stackRanges.get(si);\n\n\t\t\tif (kind === \"bar\" && band) {\n\t\t\t\tconst groupSize = stacked ? 1 : barSeries.length;\n\t\t\t\tconst groupIdx = stacked ? 0 : barSeries.indexOf(si);\n\t\t\t\tconst bw = band.bandwidth() / groupSize;\n\t\t\t\tconst gap = groupSize > 1 ? Math.min(4, bw * 0.12) : 0;\n\t\t\t\tpts.forEach((p, i) => {\n\t\t\t\t\tconst [lo, hi] = range ? range[i] : [0, p.y];\n\t\t\t\t\tconst top = plot.y + y(Math.max(lo, hi));\n\t\t\t\t\tconst bottom = plot.y + y(Math.min(lo, hi));\n\t\t\t\t\tconst h = Math.max(0, bottom - top);\n\t\t\t\t\tconst bx =\n\t\t\t\t\t\tplot.x + (band(String(p.x)) ?? 0) + groupIdx * bw + gap / 2;\n\t\t\t\t\tconst grows = p.y >= 0 ? \"up\" : \"down\";\n\t\t\t\t\tconst node = Layer.box({\n\t\t\t\t\t\tid: `${id}-bar-${si}-${i}`,\n\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\tx: round(bx),\n\t\t\t\t\t\ty: round(top),\n\t\t\t\t\t\twidth: round(Math.max(1, bw - gap)),\n\t\t\t\t\t\theight: round(h),\n\t\t\t\t\t\tbackground: color,\n\t\t\t\t\t\tborderRadius: Math.min(radius, (bw - gap) / 2, h / 2),\n\t\t\t\t\t});\n\t\t\t\t\tconst delay =\n\t\t\t\t\t\tcategoryIndex(p.x) * bandStep +\n\t\t\t\t\t\t(stacked ? barSeries.indexOf(si) * timing.duration * 0.6 : 0);\n\t\t\t\t\tif (timing.enabled) {\n\t\t\t\t\t\tconst st = timing.start + delay;\n\t\t\t\t\t\tconst end = st + timing.duration;\n\t\t\t\t\t\tconst a = LayerAnimation.create().fromTo(\"height\", 0, round(h), {\n\t\t\t\t\t\t\tstart: st,\n\t\t\t\t\t\t\tend,\n\t\t\t\t\t\t\tease: timing.ease,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (grows === \"up\") {\n\t\t\t\t\t\t\ta.fromTo(\"y\", round(top + h), round(top), {\n\t\t\t\t\t\t\t\tstart: st,\n\t\t\t\t\t\t\t\tend,\n\t\t\t\t\t\t\t\tease: timing.ease,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnode.animate(a);\n\t\t\t\t\t}\n\t\t\t\t\tchildren.push(node);\n\t\t\t\t\tif (options.valueLabels) {\n\t\t\t\t\t\tconst text = yFormat(p.y);\n\t\t\t\t\t\tconst ly = grows === \"up\" ? top - lineHeight - 4 : top + h + 4;\n\t\t\t\t\t\tlabel(\n\t\t\t\t\t\t\ttext,\n\t\t\t\t\t\t\t{ x: bx - 30, y: ly, width: bw - gap + 60, height: lineHeight },\n\t\t\t\t\t\t\t\"center\",\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdelay: delay + timing.duration * 0.6,\n\t\t\t\t\t\t\t\tcolor: strongText,\n\t\t\t\t\t\t\t\tweight: 600,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t`value-${si}-${i}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (kind === \"candlestick\" && band) {\n\t\t\t\tconst up = options.upColor ?? \"#22c55e\";\n\t\t\t\tconst down = options.downColor ?? \"#ef4444\";\n\t\t\t\tconst bw = band.bandwidth();\n\t\t\t\t(s.data as readonly ChartCandle[]).forEach((c, i) => {\n\t\t\t\t\tconst col = c.close >= c.open ? up : down;\n\t\t\t\t\tconst cxp = plot.x + (band(String(c.x)) ?? 0) + bw / 2;\n\t\t\t\t\tconst delay = categoryIndex(c.x) * bandStep;\n\t\t\t\t\tconst parts: [string, Rect][] = [\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\"wick\",\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tx: cxp - Math.max(1, bw * 0.06),\n\t\t\t\t\t\t\t\ty: plot.y + y(c.high),\n\t\t\t\t\t\t\t\twidth: Math.max(2, bw * 0.12),\n\t\t\t\t\t\t\t\theight: Math.max(1, y(c.low) - y(c.high)),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\"body\",\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tx: cxp - bw / 2,\n\t\t\t\t\t\t\t\ty: plot.y + y(Math.max(c.open, c.close)),\n\t\t\t\t\t\t\t\twidth: bw,\n\t\t\t\t\t\t\t\theight: Math.max(2, Math.abs(y(c.open) - y(c.close))),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t];\n\t\t\t\t\tfor (const [part, r] of parts) {\n\t\t\t\t\t\tconst node = Layer.box({\n\t\t\t\t\t\t\tid: `${id}-candle-${si}-${i}-${part}`,\n\t\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t\tx: round(r.x),\n\t\t\t\t\t\t\ty: round(r.y),\n\t\t\t\t\t\t\twidth: round(r.width),\n\t\t\t\t\t\t\theight: round(r.height),\n\t\t\t\t\t\t\tbackground: col,\n\t\t\t\t\t\t\tborderRadius:\n\t\t\t\t\t\t\t\tpart === \"body\" ? Math.min(radius / 2, r.width / 2) : 0,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (timing.enabled) {\n\t\t\t\t\t\t\tconst st = timing.start + delay;\n\t\t\t\t\t\t\tconst mid = r.y + r.height / 2;\n\t\t\t\t\t\t\tnode.animate(\n\t\t\t\t\t\t\t\tLayerAnimation.create()\n\t\t\t\t\t\t\t\t\t.fromTo(\"height\", 0, round(r.height), {\n\t\t\t\t\t\t\t\t\t\tstart: st,\n\t\t\t\t\t\t\t\t\t\tend: st + timing.duration,\n\t\t\t\t\t\t\t\t\t\tease: timing.ease,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t.fromTo(\"y\", round(mid), round(r.y), {\n\t\t\t\t\t\t\t\t\t\tstart: st,\n\t\t\t\t\t\t\t\t\t\tend: st + timing.duration,\n\t\t\t\t\t\t\t\t\t\tease: timing.ease,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tchildren.push(node);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (kind === \"line\" || kind === \"area\") {\n\t\t\t\tconst sw = s.strokeWidth ?? 3;\n\t\t\t\tconst m = Math.ceil(sw * 2 + (s.pointRadius ?? 0) + 2);\n\t\t\t\tconst xy = pts.map((p, i) => ({\n\t\t\t\t\tx: xPos(p.x) + m,\n\t\t\t\t\ttop: (range ? y(range[i][1]) : y(p.y)) + m,\n\t\t\t\t\tbase:\n\t\t\t\t\t\t(range\n\t\t\t\t\t\t\t? y(range[i][0])\n\t\t\t\t\t\t\t: y(Math.max(y.domain()[0], Math.min(0, y.domain()[1])))) + m,\n\t\t\t\t}));\n\t\t\t\tconst curve = curveOf(s.curve);\n\t\t\t\tconst frame: Rect = {\n\t\t\t\t\tx: plot.x - m,\n\t\t\t\t\ty: plot.y - m,\n\t\t\t\t\twidth: plot.width + 2 * m,\n\t\t\t\t\theight: plot.height + 2 * m,\n\t\t\t\t};\n\t\t\t\tconst delay = rank * (timing.duration / 3);\n\n\t\t\t\tif (kind === \"area\") {\n\t\t\t\t\tconst d = d3Area<(typeof xy)[number]>()\n\t\t\t\t\t\t.x((p) => p.x)\n\t\t\t\t\t\t.y0((p) => p.base)\n\t\t\t\t\t\t.y1((p) => p.top)\n\t\t\t\t\t\t.curve(curve)(xy);\n\t\t\t\t\tif (d) {\n\t\t\t\t\t\tconst node = Layer.shape(\"path\", {\n\t\t\t\t\t\t\tid: `${id}-area-${si}`,\n\t\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t\t...roundRect(frame),\n\t\t\t\t\t\t\td: roundPath(d),\n\t\t\t\t\t\t\tfillType: \"linear\",\n\t\t\t\t\t\t\tfillColor: withAlpha(color, 0.45),\n\t\t\t\t\t\t\tgradientEndColor: withAlpha(color, 0.02),\n\t\t\t\t\t\t\tgradientAngle: 90,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (timing.enabled)\n\t\t\t\t\t\t\tnode.animate(\n\t\t\t\t\t\t\t\tfadeIn(timing, delay + timing.duration * 0.4, timing.duration),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\tchildren.push(node);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst d = d3Line<(typeof xy)[number]>()\n\t\t\t\t\t.x((p) => p.x)\n\t\t\t\t\t.y((p) => p.top)\n\t\t\t\t\t.curve(curve)(xy);\n\t\t\t\tif (d && sw > 0) {\n\t\t\t\t\tconst node = Layer.shape(\"path\", {\n\t\t\t\t\t\tid: `${id}-line-${si}`,\n\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t...roundRect(frame),\n\t\t\t\t\t\td: roundPath(d),\n\t\t\t\t\t\tfillType: \"none\",\n\t\t\t\t\t\tstrokeColor: color,\n\t\t\t\t\t\tstrokeWidth: sw,\n\t\t\t\t\t\tstrokeLineCap: \"round\",\n\t\t\t\t\t\tstrokeLineJoin: \"round\",\n\t\t\t\t\t});\n\t\t\t\t\tif (timing.enabled) {\n\t\t\t\t\t\tnode.animate(\n\t\t\t\t\t\t\tLayerAnimation.create().fromTo(\"trimEnd\", 0, 1, {\n\t\t\t\t\t\t\t\tstart: timing.start + delay,\n\t\t\t\t\t\t\t\tend: timing.start + delay + timing.duration * 1.5,\n\t\t\t\t\t\t\t\tease: \"power2.inOut\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tchildren.push(node);\n\t\t\t\t}\n\n\t\t\t\tif ((s.pointRadius ?? 0) > 0) {\n\t\t\t\t\tdots(\n\t\t\t\t\t\tsi,\n\t\t\t\t\t\tpts,\n\t\t\t\t\t\tcolor,\n\t\t\t\t\t\ts.pointRadius ?? 0,\n\t\t\t\t\t\tdelay + timing.duration * 0.5,\n\t\t\t\t\t\trange,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (kind === \"scatter\") {\n\t\t\t\tdots(\n\t\t\t\t\tsi,\n\t\t\t\t\tpts,\n\t\t\t\t\tcolor,\n\t\t\t\t\ts.pointRadius ?? 6,\n\t\t\t\t\trank * (timing.duration / 3),\n\t\t\t\t\trange,\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\tif (showLegend) legendRow(legendItems);\n\n\t\tfunction dots(\n\t\t\tsi: number,\n\t\t\tpts: Point[],\n\t\t\tcolor: string,\n\t\t\tr: number,\n\t\t\tbaseDelay: number,\n\t\t\trange: [number, number][] | undefined,\n\t\t): void {\n\t\t\tconst step = staggerStep(pts.length);\n\t\t\tpts.forEach((p, i) => {\n\t\t\t\tconst py = range ? y(range[i][1]) : y(p.y);\n\t\t\t\tconst node = Layer.shape(\"circle\", {\n\t\t\t\t\tid: `${id}-point-${si}-${i}`,\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tx: round(plot.x + xPos(p.x) - r),\n\t\t\t\t\ty: round(plot.y + py - r),\n\t\t\t\t\twidth: round(r * 2),\n\t\t\t\t\theight: round(r * 2),\n\t\t\t\t\tfillColor: color,\n\t\t\t\t\tanchorX: 0.5,\n\t\t\t\t\tanchorY: 0.5,\n\t\t\t\t});\n\t\t\t\tif (timing.enabled) {\n\t\t\t\t\tconst st = timing.start + baseDelay + i * step;\n\t\t\t\t\tnode.animate(\n\t\t\t\t\t\tLayerAnimation.create()\n\t\t\t\t\t\t\t.fromTo(\"scale\", 0, 1, {\n\t\t\t\t\t\t\t\tstart: st,\n\t\t\t\t\t\t\t\tend: st + timing.duration * 0.6,\n\t\t\t\t\t\t\t\tease: \"back.out(2)\",\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.fromTo(\"opacity\", 0, 1, { start: st, end: st + 6 }),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tchildren.push(node);\n\t\t\t});\n\t\t}\n\t}\n\n\t// ── shared helpers ──────────────────────────────────────────────────\n\n\tfunction staggerStep(count: number): number {\n\t\tif (!timing.enabled || count <= 1) return 0;\n\t\tif (timing.stagger >= 0) return timing.stagger;\n\t\treturn Math.min(4, timing.duration / count);\n\t}\n\n\tfunction resolvePadding(\n\t\tauto: Required<ChartPadding>,\n\t): Required<ChartPadding> {\n\t\tconst p = options.padding;\n\t\tif (typeof p === \"number\") return { top: p, right: p, bottom: p, left: p };\n\t\treturn {\n\t\t\ttop: p?.top ?? auto.top,\n\t\t\tright: p?.right ?? auto.right,\n\t\t\tbottom: p?.bottom ?? auto.bottom,\n\t\t\tleft: p?.left ?? auto.left,\n\t\t};\n\t}\n\n\tfunction plotRect(p: Required<ChartPadding>): Rect {\n\t\treturn {\n\t\t\tx: p.left,\n\t\t\ty: p.top,\n\t\t\twidth: Math.max(1, width - p.left - p.right),\n\t\t\theight: Math.max(1, height - p.top - p.bottom),\n\t\t};\n\t}\n\n\tfunction legendColumnWidth(names: string[]): number {\n\t\tconst longest = Math.max(0, ...names.map((n) => n.length));\n\t\treturn Math.min(width * 0.4, longest * fontSize * 0.6 + fontSize + 48);\n\t}\n\n\tfunction legendColumn(\n\t\titems: { name: string; color: string }[],\n\t\tat: { x: number; y: number; height: number },\n\t): void {\n\t\tconst rowH = lineHeight + 8;\n\t\tconst top = at.y + Math.max(0, (at.height - items.length * rowH) / 2);\n\t\titems.forEach((item, i) => {\n\t\t\tlegendItem(item, at.x, top + i * rowH, i);\n\t\t});\n\t}\n\n\tfunction legendRow(items: { name: string; color: string }[]): void {\n\t\tconst widths = items.map(\n\t\t\t(it) => it.name.length * fontSize * 0.6 + fontSize + 28,\n\t\t);\n\t\tconst total = widths.reduce((a, b) => a + b, 0);\n\t\tlet cursor = Math.max(0, width - total - 20);\n\t\titems.forEach((item, i) => {\n\t\t\tlegendItem(item, cursor, 4, i);\n\t\t\tcursor += widths[i];\n\t\t});\n\t}\n\n\tfunction legendItem(\n\t\titem: { name: string; color: string },\n\t\tlx: number,\n\t\tly: number,\n\t\ti: number,\n\t): void {\n\t\tconst sw = Math.round(fontSize * 0.7);\n\t\tconst swatch = Layer.box({\n\t\t\tid: `${id}-legend-swatch-${i}`,\n\t\t\tposition: \"absolute\",\n\t\t\tx: round(lx),\n\t\t\ty: round(ly + (lineHeight - sw) / 2),\n\t\t\twidth: sw,\n\t\t\theight: sw,\n\t\t\tborderRadius: Math.round(sw / 4),\n\t\t\tbackground: item.color,\n\t\t});\n\t\tif (timing.enabled) swatch.animate(fadeIn(timing, 0, timing.duration / 2));\n\t\tchildren.push(swatch);\n\t\tlabel(\n\t\t\titem.name,\n\t\t\t{\n\t\t\t\tx: lx + sw + 8,\n\t\t\t\ty: ly,\n\t\t\t\twidth: item.name.length * fontSize * 0.6 + 12,\n\t\t\t\theight: lineHeight,\n\t\t\t},\n\t\t\t\"start\",\n\t\t\t{ color: options.textColor ?? \"#cbd5e1\" },\n\t\t\t`legend-${i}`,\n\t\t);\n\t}\n}\n\nfunction snapKeyframes(node: LayoutNode): void {\n\tfor (const track of node.animation?.tracks ?? []) {\n\t\tfor (const kf of track.keyframes ?? []) kf.frame = Math.round(kf.frame);\n\t}\n\tfor (const child of (node as { children?: LayoutNode[] }).children ?? []) {\n\t\tsnapKeyframes(child);\n\t}\n}\n\nfunction roundRect(r: Rect): Rect {\n\treturn {\n\t\tx: round(r.x),\n\t\ty: round(r.y),\n\t\twidth: round(r.width),\n\t\theight: round(r.height),\n\t};\n}\n\n/** Shortens the long float literals d3 emits. */\nfunction roundPath(d: string): string {\n\treturn d.replace(/-?\\d*\\.\\d{3,}(?:e-?\\d+)?/gi, (n) =>\n\t\tString(round(Number(n))),\n\t);\n}\n\n/** Offsets an absolute SVG path (as produced by d3-arc) by dx, dy. */\nfunction translatePath(d: string, dx: number, dy: number): string {\n\t// d3-arc emits M/L/A/Z with absolute coordinates; A has 7 params, of which\n\t// the last two are the endpoint.\n\tconst out: string[] = [];\n\tconst re = /([MLAZ])([^MLAZ]*)/gi;\n\tfor (const [, cmd, args] of d.matchAll(re)) {\n\t\tconst nums = (args.match(/-?\\d*\\.?\\d+(?:e-?\\d+)?/gi) ?? []).map(Number);\n\t\tif (cmd.toUpperCase() === \"A\") {\n\t\t\tfor (let i = 0; i + 6 < nums.length; i += 7) {\n\t\t\t\tnums[i + 5] += dx;\n\t\t\t\tnums[i + 6] += dy;\n\t\t\t}\n\t\t} else if (cmd.toUpperCase() !== \"Z\") {\n\t\t\tfor (let i = 0; i + 1 < nums.length; i += 2) {\n\t\t\t\tnums[i] += dx;\n\t\t\t\tnums[i + 1] += dy;\n\t\t\t}\n\t\t}\n\t\tout.push(cmd + nums.map(round).join(\",\"));\n\t}\n\treturn out.join(\"\");\n}\n","import type {\n\tBoxNode,\n\tLayoutNode,\n\tMaterialType,\n\tModel3DNode,\n} from \"@framefields/compositions/program\";\nimport {\n\ttype CylinderGeometryOptions,\n\tgenerateExtrudedTextGeometry,\n\tgetPrimitiveGeometry,\n\ttype Model3DData,\n\ttype PrimitiveGeometryOptions,\n\ttype RoundedBoxGeometryOptions,\n\tSlugFontCache,\n\ttype SphereGeometryOptions,\n} from \"@framefields/webgpu-renderers\";\nimport { autoId } from \"./ids.js\";\nimport { type AnimatableNode, Layer } from \"./index.js\";\n\n/** Physically based surface options every 3D builder accepts. */\nexport interface Surface3DOptions {\n\t/** Light the surface gives off: a CSS color added on top of lighting. */\n\temissive?: string;\n\t/** Emissive multiplier; above 1 glows past white and blooms. Default 1. */\n\temissiveIntensity?: number;\n\t/** Falls into a `castShadow` light's shadow map (meshes default on, flat layers off). */\n\tcastShadow?: boolean;\n}\n\nconst MATERIAL_KEYS = [\n\t\"material\",\n\t\"shininess\",\n\t\"roughness\",\n\t\"specularIntensity\",\n\t\"metallic\",\n\t\"ambientIntensity\",\n\t\"ior\",\n\t\"transmission\",\n\t\"dispersion\",\n\t\"fresnelPower\",\n\t\"envIntensity\",\n\t\"emissive\",\n\t\"emissiveIntensity\",\n\t\"castShadow\",\n] as const;\n\n/** The material and surface options that were actually given. */\nfunction materialProps(o: object): Record<string, unknown> {\n\tconst src = o as Record<string, unknown>;\n\tconst out: Record<string, unknown> = {};\n\tfor (const k of MATERIAL_KEYS) {\n\t\tif (src[k] !== undefined) out[k] = src[k];\n\t}\n\treturn out;\n}\n\nexport interface CubeFaceConfig extends Surface3DOptions {\n\tbackground?: string;\n\tborderRadius?: number;\n\tborderWidth?: number;\n\tborderColor?: string;\n\topacity?: number;\n\tmaterial?: MaterialType;\n\tshininess?: number;\n\troughness?: number;\n\tspecularIntensity?: number;\n\tmetallic?: number;\n\tambientIntensity?: number;\n\tior?: number;\n\ttransmission?: number;\n\tdispersion?: number;\n\tfresnelPower?: number;\n\tenvIntensity?: number;\n\tchildren?: LayoutNode[];\n}\n\nexport type CubeFaceInput = CubeFaceConfig | LayoutNode | string;\n\nexport interface Cube3DOptions extends Surface3DOptions {\n\tid?: string;\n\tsize: number | [number, number, number];\n\tx?: number;\n\ty?: number;\n\tz?: number;\n\trotateX?: number;\n\trotateY?: number;\n\trotateZ?: number;\n\tfaces?: {\n\t\tfront?: CubeFaceInput;\n\t\tback?: CubeFaceInput;\n\t\tleft?: CubeFaceInput;\n\t\tright?: CubeFaceInput;\n\t\ttop?: CubeFaceInput;\n\t\tbottom?: CubeFaceInput;\n\t};\n\ttwoSided?: boolean;\n\tmaterial?: MaterialType;\n\tshininess?: number;\n\troughness?: number;\n\tspecularIntensity?: number;\n\tmetallic?: number;\n\tambientIntensity?: number;\n\tior?: number;\n\ttransmission?: number;\n\tdispersion?: number;\n\tfresnelPower?: number;\n\tenvIntensity?: number;\n\topacity?: number;\n}\n\nexport interface Carousel3DOptions {\n\tid?: string;\n\tradius: number;\n\titems: LayoutNode[];\n\tx?: number;\n\ty?: number;\n\tz?: number;\n\trotateX?: number;\n\trotateY?: number;\n\trotateZ?: number;\n\tfaceInward?: boolean;\n\titemWidth?: number;\n\titemHeight?: number;\n\ttwoSided?: boolean;\n\topacity?: number;\n}\n\nexport interface Prism3DOptions {\n\tid?: string;\n\tsides: number;\n\tradius: number;\n\theight: number;\n\tx?: number;\n\ty?: number;\n\tz?: number;\n\trotateX?: number;\n\trotateY?: number;\n\trotateZ?: number;\n\tsideConfigs?: Array<CubeFaceInput>;\n\ttwoSided?: boolean;\n\tmaterial?: MaterialType;\n\tshininess?: number;\n\troughness?: number;\n\tspecularIntensity?: number;\n\tmetallic?: number;\n\tambientIntensity?: number;\n\tior?: number;\n\ttransmission?: number;\n\tdispersion?: number;\n\tfresnelPower?: number;\n\tenvIntensity?: number;\n\topacity?: number;\n}\n\nexport interface Plane3DOptions extends Surface3DOptions {\n\tid?: string;\n\twidth: number;\n\theight: number;\n\tx?: number;\n\ty?: number;\n\tz?: number;\n\trotateX?: number;\n\trotateY?: number;\n\trotateZ?: number;\n\tbackground?: string;\n\tborderRadius?: number;\n\ttwoSided?: boolean;\n\tmaterial?: MaterialType;\n\tshininess?: number;\n\troughness?: number;\n\tspecularIntensity?: number;\n\tmetallic?: number;\n\tambientIntensity?: number;\n\tior?: number;\n\ttransmission?: number;\n\tdispersion?: number;\n\tfresnelPower?: number;\n\tenvIntensity?: number;\n\topacity?: number;\n\tchildren?: LayoutNode[];\n}\n\nexport interface Grid3DOptions {\n\tid?: string;\n\twidth: number;\n\theight: number;\n\tdivisions?: number;\n\tcolor?: string;\n\t/** Line thickness in world pixels (default 2). */\n\tlineWidth?: number;\n\tx?: number;\n\ty?: number;\n\tz?: number;\n\trotateX?: number;\n\trotateY?: number;\n\trotateZ?: number;\n\topacity?: number;\n}\n\nexport interface Text3DOptions extends Surface3DOptions {\n\tid?: string;\n\ttext: string;\n\tfontSize?: number;\n\tfontFamily?: string;\n\tfontWeight?: number | string;\n\tfontStyle?: string;\n\tfill?: string;\n\tx?: number;\n\ty?: number;\n\tz?: number;\n\trotateX?: number;\n\trotateY?: number;\n\trotateZ?: number;\n\tscale?: number;\n\tscaleX?: number;\n\tscaleY?: number;\n\tscaleZ?: number;\n\talign?: \"start\" | \"center\" | \"end\" | \"left\" | \"right\";\n\t/**\n\t * Base direction: \"auto\" (default) takes it from the first strong\n\t * character, so Arabic and Hebrew read right to left. \"start\"/\"end\"\n\t * alignment follows it.\n\t */\n\tdirection?: \"ltr\" | \"rtl\" | \"auto\";\n\tverticalAlign?: \"top\" | \"middle\" | \"bottom\";\n\tletterSpacing?: number;\n\tlineHeight?: number;\n\tis3D?: boolean;\n\ttwoSided?: boolean;\n\tmaterial?: MaterialType;\n\tshininess?: number;\n\troughness?: number;\n\tspecularIntensity?: number;\n\tambientIntensity?: number;\n\tmetallic?: number;\n\tior?: number;\n\ttransmission?: number;\n\tdispersion?: number;\n\tfresnelPower?: number;\n\tenvIntensity?: number;\n\topacity?: number;\n\tbackground?: string;\n\tborderRadius?: number;\n\tpadding?: number;\n\tstroke?: string;\n\tstrokeWidth?: number;\n\textrusionDepth?: number;\n\t/** @deprecated No effect: extruded text is one solid mesh, not a stack of slices. */\n\textrusionSteps?: number;\n\t/**\n\t * Extruded text only: color of the side walls. `fill` colors the letter\n\t * faces (front and back). Defaults to `fill`.\n\t */\n\tbevelColor?: string;\n}\n\nexport interface ExtrudedText3DOptions extends Text3DOptions {\n\tdepth: number;\n\t/** @deprecated No effect: extruded text is one solid mesh, not a stack of slices. */\n\tslices?: number;\n\t/** Fixed straight segments per curve; by default curves split as finely as their on-screen size needs. */\n\tcurveSegments?: number;\n\t/** Most a flattened curve strays from the outline, in on-screen px at scale 1 (default 0.1). */\n\tcurveTolerance?: number;\n}\n\n/** Node props shared by the mesh primitives (roundedBox, sphere, cylinder). */\nexport interface Primitive3DNodeOptions extends Surface3DOptions {\n\tid?: string;\n\tx?: number;\n\ty?: number;\n\tz?: number;\n\trotateX?: number;\n\trotateY?: number;\n\trotateZ?: number;\n\tscale?: number;\n\tscaleX?: number;\n\tscaleY?: number;\n\tscaleZ?: number;\n\t/** Surface color baked into the mesh (default white). */\n\tcolor?: string;\n\t/**\n\t * Multiplies the surface color. It is the node's `color`, so animate it\n\t * with `.keys(\"color\", …)`; the baked surface `color` stays fixed.\n\t */\n\ttint?: string;\n\tmaterial?: MaterialType;\n\tshininess?: number;\n\troughness?: number;\n\tspecularIntensity?: number;\n\tambientIntensity?: number;\n\tmetallic?: number;\n\topacity?: number;\n\tstartFrame?: number;\n\tdurationFrames?: number;\n}\n\nexport type RoundedBox3DOptions = Primitive3DNodeOptions &\n\tOmit<RoundedBoxGeometryOptions, \"type\" | \"color\" | \"material\">;\nexport type Sphere3DOptions = Primitive3DNodeOptions &\n\tOmit<SphereGeometryOptions, \"type\" | \"color\" | \"material\">;\nexport type Cylinder3DOptions = Primitive3DNodeOptions &\n\tOmit<CylinderGeometryOptions, \"type\" | \"color\" | \"material\">;\n\n/** Mesh shading the geometry can bake in; layer materials (glass, …) apply on the node. */\nfunction meshShading(\n\tmaterial: MaterialType | undefined,\n): \"lit\" | \"unlit\" | \"toon\" | undefined {\n\treturn material === \"lit\" || material === \"unlit\" || material === \"toon\"\n\t\t? material\n\t\t: undefined;\n}\n\nfunction primitiveNode(\n\tprefix: string,\n\tgeometry: PrimitiveGeometryOptions,\n\to: Primitive3DNodeOptions,\n): AnimatableNode<Model3DNode> {\n\t// Only defined keys, so equal shapes share one cached mesh.\n\tconst spec = Object.fromEntries(\n\t\tObject.entries({\n\t\t\t...geometry,\n\t\t\tcolor: o.color,\n\t\t\tmaterial: meshShading(o.material),\n\t\t\tshininess: o.shininess,\n\t\t\troughness: o.roughness,\n\t\t\tmetallic: o.metallic,\n\t\t}).filter(([, v]) => v !== undefined),\n\t) as unknown as PrimitiveGeometryOptions;\n\treturn Layer.model({\n\t\tid: o.id ?? autoId(prefix),\n\t\tmodelData: getPrimitiveGeometry(spec),\n\t\t// What the compositor rebuilds the mesh from when modelData did not\n\t\t// survive (a spec sent as JSON).\n\t\tprimitive3d: spec,\n\t\tis3D: true,\n\t\tx: o.x ?? 0,\n\t\ty: o.y ?? 0,\n\t\tz: o.z ?? 0,\n\t\trotateX: o.rotateX ?? 0,\n\t\trotateY: o.rotateY ?? 0,\n\t\trotateZ: o.rotateZ ?? 0,\n\t\tscale: o.scale ?? 1,\n\t\tscaleX: o.scaleX ?? 1,\n\t\tscaleY: o.scaleY ?? 1,\n\t\tscaleZ: o.scaleZ ?? 1,\n\t\topacity: o.opacity ?? 1,\n\t\tcolor: o.tint,\n\t\tmaterial: o.material,\n\t\tshininess: o.shininess ?? 32,\n\t\troughness: o.roughness,\n\t\tspecularIntensity: o.specularIntensity ?? 0.5,\n\t\tambientIntensity: o.ambientIntensity ?? 1.0,\n\t\tmetallic: o.metallic,\n\t\t...materialProps({\n\t\t\temissive: o.emissive,\n\t\t\temissiveIntensity: o.emissiveIntensity,\n\t\t\tcastShadow: o.castShadow,\n\t\t}),\n\t\ttwoSided: false,\n\t\tstartFrame: o.startFrame,\n\t\tdurationFrames: o.durationFrames,\n\t});\n}\n\nexport type Shape3DContainer = AnimatableNode<BoxNode> & {\n\tfaces?: AnimatableNode<BoxNode>[];\n\titems?: LayoutNode[];\n\t[Symbol.iterator](): Iterator<LayoutNode>;\n};\n\n/**\n * Attaches the faces/items handles as non-enumerable properties, like\n * `animate`, so they stay out of `toSpec()` and schema validation.\n */\nfunction withParts<T extends object>(\n\tnode: T,\n\tparts: { faces?: LayoutNode[]; items?: LayoutNode[] },\n): T & Shape3DContainer {\n\tconst list = (parts.faces ?? parts.items ?? []) as LayoutNode[];\n\tfor (const [key, value] of Object.entries(parts)) {\n\t\tObject.defineProperty(node, key, {\n\t\t\tvalue,\n\t\t\tenumerable: false,\n\t\t\tconfigurable: true,\n\t\t});\n\t}\n\tObject.defineProperty(node, Symbol.iterator, {\n\t\tvalue: function* () {\n\t\t\tyield* list;\n\t\t},\n\t\tenumerable: false,\n\t\tconfigurable: true,\n\t});\n\treturn node as T & Shape3DContainer;\n}\n\n/** Largest initial scale of an extruded text node along its outline's axes. */\nfunction extrudedTextScale(options: ExtrudedText3DOptions): number {\n\tconst scale = options.scale ?? 1;\n\tconst s = Math.max(\n\t\tMath.abs(scale * (options.scaleX ?? 1)),\n\t\tMath.abs(scale * (options.scaleY ?? 1)),\n\t);\n\treturn s > 0 ? s : 1;\n}\n\nexport const Layer3D = {\n\t/**\n\t * Creates a true 3D volumetric cube with 6 textured or colored faces.\n\t * Returns a preserve-3d container that can be transformed in 3D camera space.\n\t */\n\tcube(options: Cube3DOptions): Shape3DContainer {\n\t\tconst size = options.size;\n\t\tconst [w, h, d] = typeof size === \"number\" ? [size, size, size] : size;\n\t\tconst twoSided = options.twoSided ?? true;\n\t\tconst defaultColors = {\n\t\t\tfront: \"#3b82f6\",\n\t\t\tback: \"#1d4ed8\",\n\t\t\tleft: \"#2563eb\",\n\t\t\tright: \"#1e40af\",\n\t\t\ttop: \"#60a5fa\",\n\t\t\tbottom: \"#172554\",\n\t\t};\n\n\t\tconst buildFace = (\n\t\t\tfaceId: string,\n\t\t\tinput: CubeFaceInput | undefined,\n\t\t\tdefaultColor: string,\n\t\t\tfaceW: number,\n\t\t\tfaceH: number,\n\t\t\tfaceProps: Partial<BoxNode>,\n\t\t): AnimatableNode<BoxNode> => {\n\t\t\tif (input && typeof input === \"object\" && \"kind\" in input) {\n\t\t\t\tconst node = input as AnimatableNode<BoxNode>;\n\t\t\t\tnode.position = \"absolute\";\n\t\t\t\tnode.is3D = true;\n\t\t\t\tnode.twoSided = twoSided;\n\t\t\t\tnode.material = node.material ?? options.material ?? \"lit\";\n\t\t\t\tnode.shininess = node.shininess ?? options.shininess ?? 32;\n\t\t\t\tnode.specularIntensity =\n\t\t\t\t\tnode.specularIntensity ?? options.specularIntensity ?? 0.5;\n\t\t\t\tif (options.roughness !== undefined && node.roughness === undefined) {\n\t\t\t\t\tnode.roughness = options.roughness;\n\t\t\t\t}\n\t\t\t\tif (options.metallic !== undefined && node.metallic === undefined) {\n\t\t\t\t\tnode.metallic = options.metallic;\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\toptions.ambientIntensity !== undefined &&\n\t\t\t\t\tnode.ambientIntensity === undefined\n\t\t\t\t) {\n\t\t\t\t\tnode.ambientIntensity = options.ambientIntensity;\n\t\t\t\t}\n\t\t\t\tObject.assign(node, faceProps);\n\t\t\t\treturn node;\n\t\t\t}\n\t\t\tconst cfg: CubeFaceConfig =\n\t\t\t\ttypeof input === \"string\"\n\t\t\t\t\t? { background: input }\n\t\t\t\t\t: (input ?? { background: defaultColor });\n\n\t\t\treturn Layer.box({\n\t\t\t\tid: `${options.id ?? \"cube\"}-${faceId}`,\n\t\t\t\tposition: \"absolute\",\n\t\t\t\twidth: faceW,\n\t\t\t\theight: faceH,\n\t\t\t\tis3D: true,\n\t\t\t\ttwoSided,\n\t\t\t\tmaterial: cfg.material ?? options.material ?? \"lit\",\n\t\t\t\tshininess: cfg.shininess ?? options.shininess ?? 32,\n\t\t\t\tspecularIntensity:\n\t\t\t\t\tcfg.specularIntensity ?? options.specularIntensity ?? 0.5,\n\t\t\t\troughness: cfg.roughness ?? options.roughness,\n\t\t\t\tmetallic: cfg.metallic ?? options.metallic,\n\t\t\t\tambientIntensity:\n\t\t\t\t\tcfg.ambientIntensity ?? options.ambientIntensity ?? 1.0,\n\t\t\t\t...materialProps({\n\t\t\t\t\temissive: cfg.emissive ?? options.emissive,\n\t\t\t\t\temissiveIntensity: cfg.emissiveIntensity ?? options.emissiveIntensity,\n\t\t\t\t\tcastShadow: cfg.castShadow ?? options.castShadow,\n\t\t\t\t}),\n\t\t\t\tbackground: cfg.background ?? defaultColor,\n\t\t\t\tborderRadius: cfg.borderRadius ?? 0,\n\t\t\t\tborderWidth: cfg.borderWidth,\n\t\t\t\tborderColor: cfg.borderColor,\n\t\t\t\topacity: cfg.opacity ?? 1,\n\t\t\t\tchildren: cfg.children ?? [],\n\t\t\t\t...faceProps,\n\t\t\t});\n\t\t};\n\n\t\tconst halfW = w / 2;\n\t\tconst halfH = h / 2;\n\t\tconst halfD = d / 2;\n\n\t\tconst faces: AnimatableNode<BoxNode>[] = [\n\t\t\tbuildFace(\"front\", options.faces?.front, defaultColors.front, w, h, {\n\t\t\t\tx: 0,\n\t\t\t\ty: 0,\n\t\t\t\tz: -halfD,\n\t\t\t\trotateX: 0,\n\t\t\t\trotateY: 0,\n\t\t\t\trotateZ: 0,\n\t\t\t}),\n\t\t\tbuildFace(\"back\", options.faces?.back, defaultColors.back, w, h, {\n\t\t\t\tx: 0,\n\t\t\t\ty: 0,\n\t\t\t\tz: halfD,\n\t\t\t\trotateX: 0,\n\t\t\t\trotateY: 180,\n\t\t\t\trotateZ: 0,\n\t\t\t}),\n\t\t\tbuildFace(\"left\", options.faces?.left, defaultColors.left, d, h, {\n\t\t\t\tx: -halfW,\n\t\t\t\ty: 0,\n\t\t\t\tz: 0,\n\t\t\t\trotateX: 0,\n\t\t\t\trotateY: 90,\n\t\t\t\trotateZ: 0,\n\t\t\t}),\n\t\t\tbuildFace(\"right\", options.faces?.right, defaultColors.right, d, h, {\n\t\t\t\tx: halfW,\n\t\t\t\ty: 0,\n\t\t\t\tz: 0,\n\t\t\t\trotateX: 0,\n\t\t\t\trotateY: -90,\n\t\t\t\trotateZ: 0,\n\t\t\t}),\n\t\t\tbuildFace(\"top\", options.faces?.top, defaultColors.top, w, d, {\n\t\t\t\tx: 0,\n\t\t\t\ty: -halfH,\n\t\t\t\tz: 0,\n\t\t\t\trotateX: -90,\n\t\t\t\trotateY: 0,\n\t\t\t\trotateZ: 0,\n\t\t\t}),\n\t\t\tbuildFace(\"bottom\", options.faces?.bottom, defaultColors.bottom, w, d, {\n\t\t\t\tx: 0,\n\t\t\t\ty: halfH,\n\t\t\t\tz: 0,\n\t\t\t\trotateX: 90,\n\t\t\t\trotateY: 0,\n\t\t\t\trotateZ: 0,\n\t\t\t}),\n\t\t];\n\n\t\tconst container = Layer.box({\n\t\t\tid: options.id ?? autoId(\"cube\"),\n\t\t\tposition: \"absolute\",\n\t\t\tx: options.x ?? 0,\n\t\t\ty: options.y ?? 0,\n\t\t\tz: options.z ?? 0,\n\t\t\twidth: w,\n\t\t\theight: h,\n\t\t\tis3D: true,\n\t\t\ttransformStyle: \"preserve-3d\",\n\t\t\trotateX: options.rotateX ?? 0,\n\t\t\trotateY: options.rotateY ?? 0,\n\t\t\trotateZ: options.rotateZ ?? 0,\n\t\t\topacity: options.opacity ?? 1,\n\t\t\tbackground: \"transparent\",\n\t\t\tchildren: faces,\n\t\t});\n\n\t\treturn withParts(container, { faces });\n\t},\n\n\t/**\n\t * Creates a 3D cylindrical carousel of items arranged radially around a center point.\n\t */\n\tcarousel(options: Carousel3DOptions): Shape3DContainer {\n\t\tconst { items, radius, faceInward = false, twoSided = true } = options;\n\t\tconst n = items.length;\n\t\tconst angleStep = n > 0 ? 360 / n : 0;\n\n\t\tconst transformedItems = items.map((item, idx) => {\n\t\t\t// Item 0 sits nearest the default camera (-z) and the ring runs clockwise\n\t\t\t// seen from above. A face's front normal is (-sin ry, 0, -cos ry) (the\n\t\t\t// cube's convention: rotateY 90 faces -x), so the outward normal\n\t\t\t// (sin a, 0, -cos a) needs ry = -a, and inward needs 180 - a.\n\t\t\tconst angleDeg = idx * angleStep;\n\t\t\tconst rad = (angleDeg * Math.PI) / 180;\n\t\t\tconst x = radius * Math.sin(rad);\n\t\t\tconst z = -radius * Math.cos(rad);\n\t\t\tconst ry = faceInward ? 180 - angleDeg : -angleDeg;\n\n\t\t\tconst node = item as AnimatableNode<BoxNode>;\n\t\t\tnode.position = \"absolute\";\n\t\t\tnode.is3D = true;\n\t\t\tnode.twoSided = twoSided;\n\t\t\tnode.x = x;\n\t\t\tnode.y = 0;\n\t\t\tnode.z = z;\n\t\t\tnode.rotateY = ry;\n\t\t\treturn node;\n\t\t});\n\n\t\tconst container = Layer.box({\n\t\t\tid: options.id ?? autoId(\"carousel\"),\n\t\t\tposition: \"absolute\",\n\t\t\tx: options.x ?? 0,\n\t\t\ty: options.y ?? 0,\n\t\t\tz: options.z ?? 0,\n\t\t\twidth: (options.itemWidth ?? 200) as any,\n\t\t\theight: (options.itemHeight ?? 200) as any,\n\t\t\tis3D: true,\n\t\t\ttransformStyle: \"preserve-3d\",\n\t\t\trotateX: options.rotateX ?? 0,\n\t\t\trotateY: options.rotateY ?? 0,\n\t\t\trotateZ: options.rotateZ ?? 0,\n\t\t\topacity: options.opacity ?? 1,\n\t\t\tbackground: \"transparent\",\n\t\t\tchildren: transformedItems,\n\t\t});\n\n\t\treturn withParts(container, { items: transformedItems });\n\t},\n\n\t/**\n\t * Creates an N-sided regular polygonal 3D prism.\n\t */\n\tprism(options: Prism3DOptions): Shape3DContainer {\n\t\tconst { sides, radius, height, twoSided = true } = options;\n\t\tconst n = Math.max(3, sides);\n\t\tconst sideWidth = 2 * radius * Math.tan(Math.PI / n);\n\t\tconst angleStep = 360 / n;\n\t\tconst panels: AnimatableNode<BoxNode>[] = [];\n\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\tconst angleDeg = i * angleStep;\n\t\t\tconst rad = (angleDeg * Math.PI) / 180;\n\t\t\tconst x = radius * Math.sin(rad);\n\t\t\tconst z = radius * Math.cos(rad);\n\t\t\tconst cfg = options.sideConfigs?.[i];\n\t\t\tconst color =\n\t\t\t\ttypeof cfg === \"string\"\n\t\t\t\t\t? cfg\n\t\t\t\t\t: ((cfg as { background?: string } | undefined)?.background ??\n\t\t\t\t\t\t`hsl(${(i * 360) / n}, 70%, 50%)`);\n\n\t\t\tpanels.push(\n\t\t\t\tLayer.box({\n\t\t\t\t\tid: `${options.id ?? \"prism\"}-panel-${i}`,\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\twidth: sideWidth,\n\t\t\t\t\theight,\n\t\t\t\t\tis3D: true,\n\t\t\t\t\ttwoSided,\n\t\t\t\t\tx,\n\t\t\t\t\ty: 0,\n\t\t\t\t\tz,\n\t\t\t\t\trotateY: angleDeg,\n\t\t\t\t\tbackground: color,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tconst container = Layer.box({\n\t\t\tid: options.id ?? autoId(\"prism\"),\n\t\t\tposition: \"absolute\",\n\t\t\tx: options.x ?? 0,\n\t\t\ty: options.y ?? 0,\n\t\t\tz: options.z ?? 0,\n\t\t\twidth: sideWidth,\n\t\t\theight,\n\t\t\tis3D: true,\n\t\t\ttransformStyle: \"preserve-3d\",\n\t\t\trotateX: options.rotateX ?? 0,\n\t\t\trotateY: options.rotateY ?? 0,\n\t\t\trotateZ: options.rotateZ ?? 0,\n\t\t\topacity: options.opacity ?? 1,\n\t\t\tbackground: \"transparent\",\n\t\t\tchildren: panels,\n\t\t});\n\n\t\treturn withParts(container, { faces: panels });\n\t},\n\n\t/**\n\t * Creates a standalone planar 3D card/quad.\n\t */\n\tplane(options: Plane3DOptions): AnimatableNode<BoxNode> {\n\t\treturn Layer.box({\n\t\t\tid: options.id ?? autoId(\"plane\"),\n\t\t\tposition: \"absolute\",\n\t\t\twidth: options.width,\n\t\t\theight: options.height,\n\t\t\tx: options.x ?? 0,\n\t\t\ty: options.y ?? 0,\n\t\t\tz: options.z ?? 0,\n\t\t\tis3D: true,\n\t\t\ttwoSided: options.twoSided ?? true,\n\t\t\trotateX: options.rotateX ?? 0,\n\t\t\trotateY: options.rotateY ?? 0,\n\t\t\trotateZ: options.rotateZ ?? 0,\n\t\t\tbackground: options.background ?? \"#3b82f6\",\n\t\t\tborderRadius: options.borderRadius ?? 0,\n\t\t\topacity: options.opacity ?? 1,\n\t\t\t...materialProps(options),\n\t\t\tchildren: options.children ?? [],\n\t\t});\n\t},\n\n\t/**\n\t * Creates a 3D perspective ground grid: `divisions` cells per side, each\n\t * line its own unlit quad so it stays crisp at any camera distance.\n\t */\n\tgrid(options: Grid3DOptions): AnimatableNode<BoxNode> {\n\t\tconst { width, height } = options;\n\t\tconst id = options.id ?? autoId(\"grid\");\n\t\tconst divisions = Math.max(1, Math.round(options.divisions ?? 10));\n\t\tconst lineWidth = options.lineWidth ?? 2;\n\t\tconst color = options.color ?? \"rgba(59, 130, 246, 0.5)\";\n\t\tconst line = (\n\t\t\tlineId: string,\n\t\t\tx: number,\n\t\t\ty: number,\n\t\t\tw: number,\n\t\t\th: number,\n\t\t): AnimatableNode<BoxNode> =>\n\t\t\tLayer.box({\n\t\t\t\tid: `${id}-${lineId}`,\n\t\t\t\tposition: \"absolute\",\n\t\t\t\tx,\n\t\t\t\ty,\n\t\t\t\tz: 0,\n\t\t\t\twidth: w,\n\t\t\t\theight: h,\n\t\t\t\tis3D: true,\n\t\t\t\ttwoSided: true,\n\t\t\t\tmaterial: \"unlit\",\n\t\t\t\tbackground: color,\n\t\t\t});\n\t\t// Every quad is backed by a texture of its own size, so long lines are\n\t\t// split into segments that stay well inside the GPU's texture limit.\n\t\tconst MAX_SEGMENT = 4096;\n\t\tconst lines: AnimatableNode<BoxNode>[] = [];\n\t\tconst vSegments = Math.ceil(height / MAX_SEGMENT);\n\t\tconst hSegments = Math.ceil(width / MAX_SEGMENT);\n\t\tfor (let i = 0; i <= divisions; i++) {\n\t\t\tconst u = i / divisions - 0.5;\n\t\t\tfor (let k = 0; k < vSegments; k++) {\n\t\t\t\tconst len = height / vSegments;\n\t\t\t\tconst y = -height / 2 + len * (k + 0.5);\n\t\t\t\tlines.push(line(`v${i}-${k}`, u * width, y, lineWidth, len));\n\t\t\t}\n\t\t\tfor (let k = 0; k < hSegments; k++) {\n\t\t\t\tconst len = width / hSegments;\n\t\t\t\tconst x = -width / 2 + len * (k + 0.5);\n\t\t\t\tlines.push(line(`h${i}-${k}`, x, u * height, len, lineWidth));\n\t\t\t}\n\t\t}\n\t\treturn Layer.box({\n\t\t\tid,\n\t\t\tposition: \"absolute\",\n\t\t\twidth,\n\t\t\theight,\n\t\t\tx: options.x ?? 0,\n\t\t\ty: options.y ?? 0,\n\t\t\tz: options.z ?? 0,\n\t\t\tis3D: true,\n\t\t\ttransformStyle: \"preserve-3d\",\n\t\t\trotateX: options.rotateX ?? 90,\n\t\t\trotateY: options.rotateY ?? 0,\n\t\t\trotateZ: options.rotateZ ?? 0,\n\t\t\tbackground: \"transparent\",\n\t\t\topacity: options.opacity ?? 1,\n\t\t\tchildren: lines,\n\t\t});\n\t},\n\n\t/**\n\t * Creates a standalone planar 3D text node, or solid extruded 3D text when `extrusionDepth` is set.\n\t */\n\ttext(options: Text3DOptions): AnimatableNode<LayoutNode> {\n\t\tif (options.extrusionDepth && options.extrusionDepth > 0) {\n\t\t\treturn Layer3D.extrudedText({\n\t\t\t\t...options,\n\t\t\t\tdepth: options.extrusionDepth,\n\t\t\t});\n\t\t}\n\n\t\treturn Layer.text(options.text, {\n\t\t\tid: options.id ?? autoId(\"text3d\"),\n\t\t\tposition: \"absolute\",\n\t\t\tx: options.x ?? 0,\n\t\t\ty: options.y ?? 0,\n\t\t\tz: options.z ?? 0,\n\t\t\tis3D: true,\n\t\t\ttwoSided: options.twoSided ?? true,\n\t\t\trotateX: options.rotateX ?? 0,\n\t\t\trotateY: options.rotateY ?? 0,\n\t\t\trotateZ: options.rotateZ ?? 0,\n\t\t\tfontSize: options.fontSize ?? 48,\n\t\t\tfontFamily: options.fontFamily,\n\t\t\tfontWeight: options.fontWeight ?? \"bold\",\n\t\t\tfontStyle: options.fontStyle,\n\t\t\tfill: options.fill ?? \"#ffffff\",\n\t\t\talign: (options.align as any) ?? \"center\",\n\t\t\tdirection: options.direction,\n\t\t\tverticalAlign: options.verticalAlign ?? \"middle\",\n\t\t\tletterSpacing: options.letterSpacing,\n\t\t\tlineHeight: options.lineHeight,\n\t\t\tmaterial: options.material ?? \"lit\",\n\t\t\tshininess: options.shininess ?? 64,\n\t\t\troughness: options.roughness,\n\t\t\tspecularIntensity: options.specularIntensity ?? 0.8,\n\t\t\tambientIntensity: options.ambientIntensity ?? 1.0,\n\t\t\tmetallic: options.metallic,\n\t\t\t...materialProps(options),\n\t\t\topacity: options.opacity ?? 1,\n\t\t\tbackground: options.background,\n\t\t\tborderRadius: options.borderRadius,\n\t\t\tpadding: options.padding,\n\t\t\tstroke: options.stroke,\n\t\t\tstrokeWidth: options.strokeWidth,\n\t\t});\n\t},\n\n\t/**\n\t * Creates solid extruded 3D typography: `fill` colors the letter faces,\n\t * `bevelColor` the side walls; curves are tessellated to `curveTolerance`.\n\t */\n\textrudedText(options: ExtrudedText3DOptions): Shape3DContainer {\n\t\tconst { depth, text, fill = \"#ffffff\", bevelColor } = options;\n\n\t\tlet modelData: Model3DData | undefined;\n\t\t// Tolerance is in on-screen px: a node scaled up 3x needs 3x finer geometry.\n\t\tconst curveTolerance =\n\t\t\t(options.curveTolerance ?? 0.1) / extrudedTextScale(options);\n\t\tconst parsedFont =\n\t\t\t(options.fontFamily\n\t\t\t\t? SlugFontCache.getParsed(options.fontFamily)\n\t\t\t\t: null) ??\n\t\t\tSlugFontCache.getParsed(\"Inter\") ??\n\t\t\tSlugFontCache.getParsed(\"Unbounded\") ??\n\t\t\tSlugFontCache.getFirstParsed();\n\n\t\tif (parsedFont) {\n\t\t\tconst res = generateExtrudedTextGeometry({\n\t\t\t\ttext,\n\t\t\t\t// SlugFontCache holds fontkit fonts under a narrower type.\n\t\t\t\tfont: parsedFont as unknown as Parameters<\n\t\t\t\t\ttypeof generateExtrudedTextGeometry\n\t\t\t\t>[0][\"font\"],\n\t\t\t\tfontSize: options.fontSize ?? 48,\n\t\t\t\tdepth,\n\t\t\t\tfill,\n\t\t\t\tbevelColor,\n\t\t\t\tcurveSegments: options.curveSegments,\n\t\t\t\tcurveTolerance,\n\t\t\t\talign: options.align,\n\t\t\t\tdirection: options.direction,\n\t\t\t\tverticalAlign: options.verticalAlign,\n\t\t\t\tletterSpacing: options.letterSpacing,\n\t\t\t\t// The mesh's own shading only knows these; glass and the like are\n\t\t\t\t// layer materials, applied by the model node below.\n\t\t\t\tmaterial:\n\t\t\t\t\toptions.material === \"lit\" ||\n\t\t\t\t\toptions.material === \"unlit\" ||\n\t\t\t\t\toptions.material === \"toon\"\n\t\t\t\t\t\t? options.material\n\t\t\t\t\t\t: undefined,\n\t\t\t\tshininess: options.shininess,\n\t\t\t\troughness: options.roughness,\n\t\t\t\tmetallic: options.metallic,\n\t\t\t});\n\t\t\tmodelData = res.modelData;\n\t\t}\n\n\t\tconst modelNode = Layer.model({\n\t\t\tid: options.id ?? autoId(\"extruded-text\"),\n\t\t\tmodelData,\n\t\t\tis3D: true,\n\t\t\tx: options.x ?? 0,\n\t\t\ty: options.y ?? 0,\n\t\t\tz: options.z ?? 0,\n\t\t\trotateX: options.rotateX ?? 0,\n\t\t\trotateY: options.rotateY ?? 0,\n\t\t\trotateZ: options.rotateZ ?? 0,\n\t\t\tscale: options.scale ?? 1,\n\t\t\tscaleX: options.scaleX ?? 1,\n\t\t\tscaleY: options.scaleY ?? 1,\n\t\t\tscaleZ: options.scaleZ ?? 1,\n\t\t\topacity: options.opacity ?? 1,\n\t\t\tmaterial: options.material,\n\t\t\tshininess: options.shininess ?? 32,\n\t\t\troughness: options.roughness,\n\t\t\tspecularIntensity: options.specularIntensity ?? 0.8,\n\t\t\tambientIntensity: options.ambientIntensity ?? 1.0,\n\t\t\tmetallic: options.metallic,\n\t\t\t...materialProps(options),\n\t\t\ttwoSided: options.twoSided ?? true,\n\t\t\t// What the compositor rebuilds the mesh from when modelData did not\n\t\t\t// survive (a spec sent as JSON): the same tolerance as here.\n\t\t\ttext3dOptions: { ...options, curveTolerance },\n\t\t});\n\n\t\treturn withParts(modelNode, {\n\t\t\tfaces: [modelNode],\n\t\t\titems: [modelNode],\n\t\t}) as unknown as Shape3DContainer;\n\t},\n\n\t/**\n\t * A solid box with rounded edges and corners, as one smooth-shaded mesh:\n\t * cards, buttons, device bodies. `taper` below 1 narrows the top (-y)\n\t * face, the shape of a keycap. Equal shapes share one GPU buffer.\n\t */\n\troundedBox(options: RoundedBox3DOptions): AnimatableNode<Model3DNode> {\n\t\treturn primitiveNode(\n\t\t\t\"rounded-box\",\n\t\t\t{\n\t\t\t\ttype: \"roundedBox\",\n\t\t\t\twidth: options.width,\n\t\t\t\theight: options.height,\n\t\t\t\tdepth: options.depth,\n\t\t\t\tradius: options.radius,\n\t\t\t\tsegments: options.segments,\n\t\t\t\ttaper: options.taper,\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t},\n\n\t/** A UV sphere mesh. */\n\tsphere(options: Sphere3DOptions): AnimatableNode<Model3DNode> {\n\t\treturn primitiveNode(\n\t\t\t\"sphere\",\n\t\t\t{ type: \"sphere\", radius: options.radius, segments: options.segments },\n\t\t\toptions,\n\t\t);\n\t},\n\n\t/** A capped cylinder, or a cone/frustum with different top and bottom radii. */\n\tcylinder(options: Cylinder3DOptions): AnimatableNode<Model3DNode> {\n\t\treturn primitiveNode(\n\t\t\t\"cylinder\",\n\t\t\t{\n\t\t\t\ttype: \"cylinder\",\n\t\t\t\tradius: options.radius,\n\t\t\t\tradiusTop: options.radiusTop,\n\t\t\t\tradiusBottom: options.radiusBottom,\n\t\t\t\theight: options.height,\n\t\t\t\tsegments: options.segments,\n\t\t\t\topenEnded: options.openEnded,\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t},\n\n\t/**\n\t * Creates a 3D model node rendered natively with WebGPU mesh shaders.\n\t */\n\tmodel(options: Partial<Model3DNode> = {}): AnimatableNode<Model3DNode> {\n\t\treturn Layer.model(options);\n\t},\n\n\t/**\n\t * Convenience helper to create a 3D Wavefront OBJ model node.\n\t */\n\tobj(\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> {\n\t\treturn Layer.obj(src, options);\n\t},\n\n\t/**\n\t * Convenience helper to create a 3D Autodesk FBX model node with skeletal animation support.\n\t */\n\tfbx(\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> {\n\t\treturn Layer.fbx(src, options);\n\t},\n\n\t/**\n\t * Convenience helper to create a 3D glTF 2.0 model node.\n\t */\n\tgltf(\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> {\n\t\treturn Layer.gltf(src, options);\n\t},\n\n\t/**\n\t * Convenience helper to create a 3D GLB binary container model node.\n\t */\n\tglb(\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> {\n\t\treturn Layer.glb(src, options);\n\t},\n\n\t/**\n\t * Convenience helper to create a 3D STL CAD / 3D printing model node.\n\t */\n\tstl(\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> {\n\t\treturn Layer.stl(src, options);\n\t},\n\n\t/**\n\t * Convenience helper to create a 3D Stanford PLY scan model node.\n\t */\n\tply(\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> {\n\t\treturn Layer.ply(src, options);\n\t},\n\n\t/**\n\t * Convenience helper to create a 3D MagicaVoxel VOX model node.\n\t */\n\tvox(\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> {\n\t\treturn Layer.vox(src, options);\n\t},\n\n\t/**\n\t * Convenience helper to create a 3D Studio (3DS) binary model node.\n\t */\n\tthreeDS(\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> {\n\t\treturn Layer.threeDS(src, options);\n\t},\n\n\t/**\n\t * Convenience helper to create a 3D Object File Format (OFF) model node.\n\t */\n\toff(\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> {\n\t\treturn Layer.off(src, options);\n\t},\n};\n","/**\n * Scene sequencing with transitions. `Layer.sequence` lays scenes end to end\n * and overlaps neighbours by each transition's length; the transition itself\n * is plain keyframes (and, for wipes and irises, a track matte) merged into\n * the scenes, so it renders like anything else and stays editable.\n */\nimport {\n\ttype AnimationTrack,\n\ttype BoxNode,\n\tLayerAnimation,\n\ttype LayoutNode,\n} from \"@framefields/compositions/program\";\nimport { autoId } from \"./ids.js\";\nimport { type AnimatableNode, Layer } from \"./index.js\";\n\nexport type TransitionDirection = \"left\" | \"right\" | \"up\" | \"down\";\n\n/** What a transition needs to know to animate two scenes. */\ninterface TransitionContext {\n\t/** Scene size (px). */\n\twidth: number;\n\theight: number;\n\t/** Overlap length in frames. */\n\tframes: number;\n\t/** Outgoing scene: local frame where the overlap starts, and its rest position. */\n\toutStart: number;\n\toutRest: { x: number; y: number };\n\t/** Incoming scene rest position (the overlap starts at its local frame 0). */\n\tinRest: { x: number; y: number };\n}\n\ninterface TransitionParts {\n\toutgoing?: LayerAnimation;\n\tincoming?: LayerAnimation;\n\t/** A matte revealing the incoming scene (laid out like the scene, keyed from its start). */\n\tincomingMatte?: LayoutNode;\n\t/** Static props set on both scenes (e.g. motion blur for a whip). */\n\tsceneProps?: Record<string, unknown>;\n}\n\nexport interface TransitionSpec {\n\treadonly kind: string;\n\t/** Overlap between the two scenes, in frames (0 = hard cut). */\n\treadonly frames: number;\n\t/** @internal */\n\tbuild(ctx: TransitionContext): TransitionParts;\n}\n\nconst offsetFor = (dir: TransitionDirection, w: number, h: number) => {\n\tswitch (dir) {\n\t\tcase \"left\":\n\t\t\treturn { dx: -w, dy: 0 };\n\t\tcase \"right\":\n\t\t\treturn { dx: w, dy: 0 };\n\t\tcase \"up\":\n\t\t\treturn { dx: 0, dy: -h };\n\t\tdefault:\n\t\t\treturn { dx: 0, dy: h };\n\t}\n};\n\nfunction spec(\n\tkind: string,\n\tframes: number,\n\tbuild: (ctx: TransitionContext) => TransitionParts,\n): TransitionSpec {\n\treturn { kind, frames: Math.max(0, Math.round(frames)), build };\n}\n\n/**\n * Scene-to-scene transitions for `Layer.sequence`. `frames` is how long the\n * two scenes overlap; `ease` shapes the move (default \"power3.inOut\").\n */\nexport const Transition = {\n\t/** Instant cut. */\n\tcut: (): TransitionSpec => spec(\"cut\", 0, () => ({})),\n\n\t/** The incoming scene fades in over the outgoing one. */\n\tcrossfade: (frames = 15, ease = \"sine.inOut\"): TransitionSpec =>\n\t\tspec(\"crossfade\", frames, (c) => ({\n\t\t\tincoming: LayerAnimation.keys(\"opacity\", [\n\t\t\t\t[0, 0],\n\t\t\t\t[c.frames, 1, ease],\n\t\t\t]),\n\t\t})),\n\n\t/** Out to the background, then in: a dip to the composition's background color. */\n\tfadeThrough: (frames = 20, ease = \"sine.inOut\"): TransitionSpec =>\n\t\tspec(\"fadeThrough\", frames, (c) => {\n\t\t\tconst half = Math.max(1, Math.floor(c.frames / 2));\n\t\t\treturn {\n\t\t\t\toutgoing: LayerAnimation.keys(\"opacity\", [\n\t\t\t\t\t[c.outStart, 1],\n\t\t\t\t\t[c.outStart + half, 0, ease],\n\t\t\t\t]),\n\t\t\t\tincoming: LayerAnimation.keys(\"opacity\", [\n\t\t\t\t\t[0, 0],\n\t\t\t\t\t[half, 0],\n\t\t\t\t\t[c.frames, 1, ease],\n\t\t\t\t]),\n\t\t\t};\n\t\t}),\n\n\t/** Both scenes move together: the new one pushes the old one out toward `direction`. */\n\tpush: (\n\t\tdirection: TransitionDirection = \"left\",\n\t\tframes = 18,\n\t\tease = \"power3.inOut\",\n\t): TransitionSpec =>\n\t\tspec(\"push\", frames, (c) => {\n\t\t\tconst { dx, dy } = offsetFor(direction, c.width, c.height);\n\t\t\tconst out = LayerAnimation.create();\n\t\t\tconst inc = LayerAnimation.create();\n\t\t\tif (dx !== 0) {\n\t\t\t\tout.keys(\"x\", [\n\t\t\t\t\t[c.outStart, c.outRest.x],\n\t\t\t\t\t[c.outStart + c.frames, c.outRest.x + dx, ease],\n\t\t\t\t]);\n\t\t\t\tinc.keys(\"x\", [\n\t\t\t\t\t[0, c.inRest.x - dx],\n\t\t\t\t\t[c.frames, c.inRest.x, ease],\n\t\t\t\t]);\n\t\t\t} else {\n\t\t\t\tout.keys(\"y\", [\n\t\t\t\t\t[c.outStart, c.outRest.y],\n\t\t\t\t\t[c.outStart + c.frames, c.outRest.y + dy, ease],\n\t\t\t\t]);\n\t\t\t\tinc.keys(\"y\", [\n\t\t\t\t\t[0, c.inRest.y - dy],\n\t\t\t\t\t[c.frames, c.inRest.y, ease],\n\t\t\t\t]);\n\t\t\t}\n\t\t\treturn { outgoing: out, incoming: inc };\n\t\t}),\n\n\t/** The new scene slides in over the old one, which stays put and dims slightly. */\n\tslide: (\n\t\tdirection: TransitionDirection = \"left\",\n\t\tframes = 18,\n\t\tease = \"power3.out\",\n\t): TransitionSpec =>\n\t\tspec(\"slide\", frames, (c) => {\n\t\t\tconst { dx, dy } = offsetFor(direction, c.width, c.height);\n\t\t\tconst prop = dx !== 0 ? \"x\" : \"y\";\n\t\t\tconst rest = dx !== 0 ? c.inRest.x : c.inRest.y;\n\t\t\treturn {\n\t\t\t\toutgoing: LayerAnimation.keys(\"opacity\", [\n\t\t\t\t\t[c.outStart, 1],\n\t\t\t\t\t[c.outStart + c.frames, 0.6, ease],\n\t\t\t\t]),\n\t\t\t\tincoming: LayerAnimation.keys(prop, [\n\t\t\t\t\t[0, rest - (dx || dy)],\n\t\t\t\t\t[c.frames, rest, ease],\n\t\t\t\t]),\n\t\t\t};\n\t\t}),\n\n\t/** Old scene grows and fades, new one settles in from slightly small. */\n\tzoom: (frames = 18, ease = \"power2.inOut\"): TransitionSpec =>\n\t\tspec(\"zoom\", frames, (c) => ({\n\t\t\toutgoing: LayerAnimation.create()\n\t\t\t\t.keys(\"scale\", [\n\t\t\t\t\t[c.outStart, 1],\n\t\t\t\t\t[c.outStart + c.frames, 1.25, ease],\n\t\t\t\t])\n\t\t\t\t.keys(\"opacity\", [\n\t\t\t\t\t[c.outStart, 1],\n\t\t\t\t\t[c.outStart + c.frames, 0, ease],\n\t\t\t\t]),\n\t\t\tincoming: LayerAnimation.create()\n\t\t\t\t.keys(\"scale\", [\n\t\t\t\t\t[0, 0.85],\n\t\t\t\t\t[c.frames, 1, ease],\n\t\t\t\t])\n\t\t\t\t.keys(\"opacity\", [\n\t\t\t\t\t[0, 0],\n\t\t\t\t\t[c.frames, 1, ease],\n\t\t\t\t]),\n\t\t})),\n\n\t/** A fast, motion-blurred push: the camera whips to the next scene. */\n\twhip: (\n\t\tdirection: TransitionDirection = \"left\",\n\t\tframes = 10,\n\t): TransitionSpec => {\n\t\tconst push = Transition.push(direction, frames, \"expo.inOut\");\n\t\treturn spec(\"whip\", frames, (c) => ({\n\t\t\t...push.build(c),\n\t\t\tsceneProps: { motionBlurShutter: 360 },\n\t\t}));\n\t},\n\n\t/** A hard edge sweeps across, revealing the new scene. */\n\twipe: (\n\t\tdirection: TransitionDirection = \"left\",\n\t\tframes = 18,\n\t\tease = \"power2.inOut\",\n\t): TransitionSpec =>\n\t\tspec(\"wipe\", frames, (c) => {\n\t\t\t// `direction` is where the edge travels: \"left\" reveals from the right.\n\t\t\tconst { dx, dy } = offsetFor(direction, c.width, c.height);\n\t\t\tconst prop = dx !== 0 ? \"x\" : \"y\";\n\t\t\tconst rest = dx !== 0 ? c.inRest.x : c.inRest.y;\n\t\t\treturn {\n\t\t\t\tincomingMatte: Layer.box({\n\t\t\t\t\tid: autoId(\"wipe-matte\"),\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tx: c.inRest.x,\n\t\t\t\t\ty: c.inRest.y,\n\t\t\t\t\twidth: c.width,\n\t\t\t\t\theight: c.height,\n\t\t\t\t\tbackground: \"#ffffff\",\n\t\t\t\t}).animate(\n\t\t\t\t\tLayerAnimation.keys(prop, [\n\t\t\t\t\t\t[0, rest - (dx || dy)],\n\t\t\t\t\t\t[c.frames, rest, ease],\n\t\t\t\t\t]),\n\t\t\t\t),\n\t\t\t};\n\t\t}),\n\n\t/** A circle opens from the center (or `at`, as fractions of the frame) to reveal the new scene. */\n\tiris: (\n\t\tframes = 20,\n\t\toptions: { at?: [number, number]; ease?: string } = {},\n\t): TransitionSpec =>\n\t\tspec(\"iris\", frames, (c) => {\n\t\t\tconst [fx, fy] = options.at ?? [0.5, 0.5];\n\t\t\tconst cx = c.inRest.x + fx * c.width;\n\t\t\tconst cy = c.inRest.y + fy * c.height;\n\t\t\t// Big enough to cover the farthest corner.\n\t\t\tconst r = Math.hypot(\n\t\t\t\tMath.max(fx, 1 - fx) * c.width,\n\t\t\t\tMath.max(fy, 1 - fy) * c.height,\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tincomingMatte: Layer.shape(\"circle\", {\n\t\t\t\t\tid: autoId(\"iris-matte\"),\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tx: cx - r,\n\t\t\t\t\ty: cy - r,\n\t\t\t\t\twidth: r * 2,\n\t\t\t\t\theight: r * 2,\n\t\t\t\t\tfillColor: \"#ffffff\",\n\t\t\t\t}).animate(\n\t\t\t\t\tLayerAnimation.keys(\"scale\", [\n\t\t\t\t\t\t[0, 0],\n\t\t\t\t\t\t[c.frames, 1, options.ease ?? \"power2.inOut\"],\n\t\t\t\t\t]),\n\t\t\t\t),\n\t\t\t};\n\t\t}),\n};\n\nexport interface SequenceEntry {\n\t/** A full-frame layer (usually a box holding the scene). */\n\tscene: AnimatableNode<LayoutNode> | LayoutNode;\n\t/** Frames this scene is on screen, transitions included. */\n\tduration: number;\n\t/** How this scene arrives from the previous one (default: cut). */\n\ttransition?: TransitionSpec;\n}\n\nexport interface SceneSequenceOptions {\n\tid?: string;\n\t/** Scene size used by moving transitions (default: each scene's own width/height, else 1920×1080). */\n\twidth?: number;\n\theight?: number;\n\t/** First frame of the whole sequence. Default 0. */\n\tstartFrame?: number;\n}\n\nexport type SequenceNode = AnimatableNode<BoxNode> & {\n\t/** Total length in frames: put it in the composition's duration. */\n\treadonly totalFrames: number;\n\t/** Where each scene starts (composition frames, relative to the sequence). */\n\treadonly sceneStarts: readonly number[];\n};\n\nfunction sizeOf(node: LayoutNode, axis: \"width\" | \"height\", fallback: number) {\n\tconst v = (node as unknown as Record<string, unknown>)[axis];\n\treturn typeof v === \"number\" ? v : fallback;\n}\n\n/**\n * Scenes back to back, each overlapping the previous one by its transition.\n * Scene timing is set for you (`startFrame` / `durationFrames`), so every\n * scene keys its own animation from its local frame 0.\n */\nexport function sequence(\n\tentries: SequenceEntry[],\n\toptions: SceneSequenceOptions = {},\n): SequenceNode {\n\tconst scenes: LayoutNode[] = [];\n\tconst starts: number[] = [];\n\tlet cursor = 0;\n\tentries.forEach((entry, i) => {\n\t\tconst t = i === 0 ? undefined : entry.transition;\n\t\tconst overlap = Math.min(t?.frames ?? 0, entries[i - 1]?.duration ?? 0);\n\t\tconst start = Math.max(0, cursor - overlap);\n\t\tconst duration = Math.max(1, Math.round(entry.duration));\n\t\tstarts.push(start);\n\t\tconst node = entry.scene as LayoutNode & Record<string, unknown>;\n\t\t// Scenes stack in one frame rather than flowing one under the other.\n\t\tif (node.position === undefined || node.position === \"relative\") {\n\t\t\tnode.position = \"absolute\";\n\t\t\tnode.x ??= 0;\n\t\t\tnode.y ??= 0;\n\t\t}\n\t\tnode.startFrame = start;\n\t\tnode.durationFrames = duration;\n\t\tscenes.push(node);\n\t\tcursor = start + duration;\n\t});\n\n\tentries.forEach((entry, i) => {\n\t\tif (i === 0 || !entry.transition || entry.transition.frames === 0) return;\n\t\tconst prev = scenes[i - 1] as LayoutNode & Record<string, unknown>;\n\t\tconst cur = scenes[i] as LayoutNode & Record<string, unknown>;\n\t\tconst frames = Math.min(entry.transition.frames, entries[i - 1].duration);\n\t\tconst width = options.width ?? sizeOf(cur, \"width\", 1920);\n\t\tconst height = options.height ?? sizeOf(cur, \"height\", 1080);\n\t\tconst parts = entry.transition.build({\n\t\t\twidth,\n\t\t\theight,\n\t\t\tframes,\n\t\t\toutStart: entries[i - 1].duration - frames,\n\t\t\toutRest: {\n\t\t\t\tx: typeof prev.x === \"number\" ? prev.x : 0,\n\t\t\t\ty: typeof prev.y === \"number\" ? prev.y : 0,\n\t\t\t},\n\t\t\tinRest: {\n\t\t\t\tx: typeof cur.x === \"number\" ? cur.x : 0,\n\t\t\t\ty: typeof cur.y === \"number\" ? cur.y : 0,\n\t\t\t},\n\t\t});\n\t\tconst merge = (\n\t\t\tnode: LayoutNode & Record<string, unknown>,\n\t\t\tanim?: LayerAnimation,\n\t\t) => {\n\t\t\tif (!anim) return;\n\t\t\tconst existing =\n\t\t\t\t(node.animation as { tracks?: AnimationTrack[] } | undefined)?.tracks ??\n\t\t\t\t[];\n\t\t\tnode.animation = LayerAnimation.merge(\n\t\t\t\t{ tracks: existing },\n\t\t\t\tanim,\n\t\t\t).toSpec();\n\t\t};\n\t\tmerge(prev, parts.outgoing);\n\t\tmerge(cur, parts.incoming);\n\t\tif (parts.sceneProps) {\n\t\t\tObject.assign(prev, parts.sceneProps);\n\t\t\tObject.assign(cur, parts.sceneProps);\n\t\t}\n\t\tif (parts.incomingMatte) {\n\t\t\tcur.matte = { node: parts.incomingMatte, mode: \"alpha\" };\n\t\t}\n\t});\n\n\tconst root = Layer.box({\n\t\tid: options.id ?? autoId(\"sequence\"),\n\t\tposition: \"absolute\",\n\t\tx: 0,\n\t\ty: 0,\n\t\twidth:\n\t\t\toptions.width ?? sizeOf(scenes[0] ?? ({} as LayoutNode), \"width\", 1920),\n\t\theight:\n\t\t\toptions.height ?? sizeOf(scenes[0] ?? ({} as LayoutNode), \"height\", 1080),\n\t\tstartFrame: options.startFrame ?? 0,\n\t\tdurationFrames: Math.max(1, cursor),\n\t\tchildren: scenes,\n\t});\n\tObject.defineProperty(root, \"totalFrames\", {\n\t\tvalue: cursor,\n\t\tenumerable: false,\n\t});\n\tObject.defineProperty(root, \"sceneStarts\", {\n\t\tvalue: starts,\n\t\tenumerable: false,\n\t});\n\treturn root as SequenceNode;\n}\n","import type {\n\tEnvironmentPreset,\n\tLightNode,\n\tToneMapping,\n} from \"@framefields/compositions/program\";\nimport { autoId } from \"./ids.js\";\nimport {\n\ttype AnimatableNode,\n\ttype EnvironmentOptions,\n\tLight,\n} from \"./index.js\";\n\nexport interface LightingRigOptions {\n\t/** What the lights aim at (world px). Default: the canvas center at z 0. */\n\ttarget?: [number, number, number];\n\t/** How far the lights sit from the target. Default 1600. */\n\tdistance?: number;\n\t/** Turns the whole rig (lights and environment) around the vertical axis, degrees. */\n\trotation?: number;\n\t/** Scales every light. Default 1. */\n\tintensity?: number;\n\t/** Exposure in stops. Default 0. */\n\texposure?: number;\n\ttoneMapping?: ToneMapping;\n\t/** Key light casts a soft shadow. Default true. */\n\tshadows?: boolean;\n\t/** Shadow edge blur in texels. Default 3. */\n\tshadowSoftness?: number;\n\t/** Fog fading into the background, e.g. `{ color: BG, start: 2500, end: 6000 }`. */\n\tfog?: EnvironmentOptions[\"fog\"];\n\t/** Glow around emissive surfaces and highlights: `true` or settings. */\n\tbloom?: EnvironmentOptions[\"bloom\"];\n\t/** Prefix for the rig's node ids. */\n\tid?: string;\n}\n\ninterface RigSpec {\n\tenvironment: EnvironmentPreset;\n\tenvIntensity: number;\n\t/** Light directions relative to the target, before `rotation`; y is down. */\n\tkey: { dir: [number, number, number]; color: string; intensity: number };\n\trim?: { dir: [number, number, number]; color: string; intensity: number };\n\tfill?: { dir: [number, number, number]; color: string; intensity: number };\n}\n\nconst RIGS = {\n\t/** Product photography: soft overhead key with a shadow, cool rim, studio reflections. */\n\tstudio: {\n\t\tenvironment: \"studio\",\n\t\tenvIntensity: 1,\n\t\tkey: { dir: [-0.55, -1, -0.7], color: \"#fff6ec\", intensity: 1.1 },\n\t\trim: { dir: [0.9, -0.5, 0.9], color: \"#dbe8ff\", intensity: 0.9 },\n\t},\n\t/** Bright, airy, low contrast: lifestyle and UI-on-device shots. */\n\tsoft: {\n\t\tenvironment: \"soft\",\n\t\tenvIntensity: 1,\n\t\tkey: { dir: [-0.4, -1, -0.8], color: \"#ffffff\", intensity: 1.0 },\n\t},\n\t/** Low warm sun, long shadows, cool sky fill. */\n\tsunset: {\n\t\tenvironment: \"sunset\",\n\t\tenvIntensity: 0.9,\n\t\tkey: { dir: [-1, -0.35, -0.3], color: \"#ffb27a\", intensity: 2.2 },\n\t\tfill: { dir: [0.8, -0.6, -0.4], color: \"#7f9cff\", intensity: 0.35 },\n\t},\n\t/** Moody: dark world, hard key, strong rim. Pair with emissive accents. */\n\tdramatic: {\n\t\tenvironment: \"night\",\n\t\tenvIntensity: 0.8,\n\t\tkey: { dir: [-0.8, -1, -0.35], color: \"#ffffff\", intensity: 2.4 },\n\t\trim: { dir: [0.7, -0.4, 1], color: \"#8fb4ff\", intensity: 1.8 },\n\t},\n} satisfies Record<string, RigSpec>;\n\nexport type LightingRig = keyof typeof RIGS;\n\nfunction rotateY(\n\t[x, y, z]: [number, number, number],\n\tdegrees: number,\n): [number, number, number] {\n\tconst r = (degrees * Math.PI) / 180;\n\tconst c = Math.cos(r);\n\tconst s = Math.sin(r);\n\treturn [c * x + s * z, y, -s * x + c * z];\n}\n\nfunction aim(\n\tdir: [number, number, number],\n\ttarget: [number, number, number],\n\tdistance: number,\n\trotation: number,\n): Pick<LightNode, \"x\" | \"y\" | \"z\" | \"targetX\" | \"targetY\" | \"targetZ\"> {\n\tconst [dx, dy, dz] = rotateY(dir, rotation);\n\tconst len = Math.hypot(dx, dy, dz) || 1;\n\treturn {\n\t\tx: target[0] + (dx / len) * distance,\n\t\ty: target[1] + (dy / len) * distance,\n\t\tz: target[2] + (dz / len) * distance,\n\t\ttargetX: target[0],\n\t\ttargetY: target[1],\n\t\ttargetZ: target[2],\n\t};\n}\n\nfunction rig(\n\tname: LightingRig,\n\toptions: LightingRigOptions,\n): AnimatableNode<LightNode>[] {\n\tconst spec: RigSpec = RIGS[name];\n\tconst target = options.target ?? [960, 540, 0];\n\tconst distance = options.distance ?? 1600;\n\tconst rotation = options.rotation ?? 0;\n\tconst k = options.intensity ?? 1;\n\tconst id = options.id ?? autoId(`lighting-${name}`);\n\tconst nodes: AnimatableNode<LightNode>[] = [\n\t\tLight.environment(spec.environment, {\n\t\t\tid: `${id}-environment`,\n\t\t\tintensity: spec.envIntensity * k,\n\t\t\trotation,\n\t\t\texposure: options.exposure,\n\t\t\ttoneMapping: options.toneMapping,\n\t\t\tfog: options.fog,\n\t\t\tbloom: options.bloom,\n\t\t}),\n\t\tLight.directional({\n\t\t\tid: `${id}-key`,\n\t\t\tcolor: spec.key.color,\n\t\t\tintensity: spec.key.intensity * k,\n\t\t\t...aim(spec.key.dir, target, distance, rotation),\n\t\t\tcastShadow: options.shadows ?? true,\n\t\t\tshadowSoftness: options.shadowSoftness ?? 3,\n\t\t}),\n\t];\n\tfor (const [part, light] of [\n\t\t[\"rim\", spec.rim],\n\t\t[\"fill\", spec.fill],\n\t] as const) {\n\t\tif (!light) continue;\n\t\tnodes.push(\n\t\t\tLight.directional({\n\t\t\t\tid: `${id}-${part}`,\n\t\t\t\tcolor: light.color,\n\t\t\t\tintensity: light.intensity * k,\n\t\t\t\t...aim(light.dir, target, distance, rotation),\n\t\t\t}),\n\t\t);\n\t}\n\treturn nodes;\n}\n\n/**\n * Ready-made lighting: an environment (physical shading, tone mapping) plus\n * placed key / rim / fill lights, the key casting a soft shadow. Add the\n * returned nodes to the composition: `comp.add(Lighting.studio({ target }))`.\n *\n * Tweak from there rather than starting from zero: `intensity`, `exposure`,\n * `rotation` (turns the rig), `shadowSoftness`, `fog`.\n */\nexport const Lighting = {\n\tstudio: (options: LightingRigOptions = {}) => rig(\"studio\", options),\n\tsoft: (options: LightingRigOptions = {}) => rig(\"soft\", options),\n\tsunset: (options: LightingRigOptions = {}) => rig(\"sunset\", options),\n\tdramatic: (options: LightingRigOptions = {}) => rig(\"dramatic\", options),\n};\n","export {\n\tAudioSignal,\n\ttype AudioSignalOptions,\n\tcomputed,\n\tcosineSignal,\n\ttype ExtractedAudioSignalsBundle,\n\ttype FrameSignal,\n\tSignal,\n\ttype SignalContext,\n\ttype SignalValue,\n\ttype SineSignalOptions,\n\tsignal,\n\tsignalBuilder,\n\tsignalRegistry,\n\tsineSignal,\n} from \"./signals/index.js\";\n\nimport {\n\tFontManager,\n\ttype MeasuredGlyph,\n\ttype MeasureTextOptions,\n\ttype RegisteredFont,\n\ttype RegisterFontOptions,\n\ttype TextMetrics,\n} from \"./fonts/index.js\";\nimport { autoId } from \"./ids.js\";\nimport { normalizeTextSpans, type TextSpan } from \"./rich-text.js\";\n\nexport {\n\tencodeStereoWav,\n\tmixAudioTracks,\n\tmixSfxInto,\n\ttype RenderedSfx,\n\trenderSfx,\n\ttype SfxRenderContext,\n\ttype SfxTrigger,\n\tsoftLimit,\n} from \"./audio/index.js\";\nexport {\n\taccent,\n\tbold,\n\tcode,\n\tcolor,\n\titalic,\n\ttype MarkOptions,\n\tmark,\n\tnormalizeTextSpans,\n\tparseMarkup,\n\trich,\n\tsize,\n\tspan,\n\tsub,\n\tsup,\n\ttype TextSpan,\n\ttype TextSpanItem,\n\ttype TextSpanMark,\n} from \"./rich-text.js\";\nexport {\n\tFontManager,\n\ttype MeasuredGlyph,\n\ttype MeasureTextOptions,\n\ttype RegisteredFont,\n\ttype RegisterFontOptions,\n\ttype TextMetrics,\n};\n\nexport {\n\tCannyComputePipeline,\n\ttype CannyOptions,\n\ttype ControlNetConditioningOutputs,\n\tControlNetMultiplexer,\n\ttype DeflickerOptions,\n\tDepthNormalsComputePipeline,\n\ttype DepthNormalsOptions,\n\ttype NormalRelightingOptions,\n\tOpticalFlowComputePipeline,\n\ttype OpticalFlowOptions,\n\tTemporalDeflickerPipeline,\n\ttype TensorDimensions,\n\ttype TensorFormat,\n\ttype TensorNode,\n\tTensorPipeline,\n\ttype TensorPipelineConfig,\n\ttype TensorSource,\n\ttype TensorViewExport,\n} from \"@framefields/tensor-webgpu\";\nexport {\n\tCOCO_CLASSES,\n\tCOCO17_BONES,\n\tCOCO17_KEYPOINT_NAMES,\n\tCOCO17_KEYPOINTS,\n\ttype DetectedObject,\n\ttype InstanceMask,\n\ttype Landmark3D,\n\ttype LandmarkCoordinateSignals,\n\ttype MaskTrackSignals,\n\ttype NormalizedLandmarkList,\n\ttype ObjectAnchorName,\n\ttype ObjectAnchorsSignals,\n\ttype ObjectBoundingBox,\n\ttype ObjectBoundingBoxSignals,\n\ttype ObjectCollectionSignals,\n\ttype ObjectKinematicsSignals,\n\ttype ObjectTrackSignals,\n\ttype PersonMatte,\n\ttype PinToLandmarkOptions,\n\ttype PinToObjectOptions,\n\ttype PoseLandmarkSignals,\n\ttype PoseResult,\n\tPoseSkeletonRenderer,\n\tpinNodeToLandmark,\n\tpinNodeToObject,\n\ttype SegmentationResult,\n\tSegmentationTexturePool,\n\tSpatialLandmarkTransformer,\n\tTemporalObjectTracker,\n\ttype TrackedObject,\n\tVisionBundle,\n\ttype VisionConfig,\n\tVisionNode,\n\tVisionRunner,\n\ttype VisionTask,\n\ttype VisionVariant,\n} from \"@framefields/vision\";\n\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport {\n\ttype AnimationTrack,\n\ttype BoxNode,\n\ttype CameraNode,\n\ttype CompositorProgramConfig,\n\ttype CompositorToProgramOptions,\n\tcompositorToProgram,\n\ttype EnvironmentPreset,\n\ttype FlexNode,\n\tLayerAnimation,\n\ttype LayoutNode,\n\ttype LightNode,\n\tlintComposition,\n\ttype MatteMode,\n\ttype MediaNode,\n\ttype Model3DNode,\n\tmergeAnimationTracks,\n\ttype ShapeNode,\n\ttype TextNode,\n} from \"@framefields/compositions/program\";\nimport {\n\tappendOperation,\n\tEffect as CoreEffect,\n\tcreateVirtualMedia,\n\ttype DataType,\n\ttype FrameContext,\n\ttype MediaMetadata,\n\ttype MediaOperation,\n\ttype MediaSourceInput,\n\ttype MeshAudioDeformConfig,\n\tProgrammaticSignal,\n\ttype RenderDiagnostic,\n\ttype Signal,\n\ttype VirtualMediaData,\n} from \"@framefields/core\";\nimport {\n\tanalyzeSequence as analyzeVisionFrames,\n\ttype LandmarkCoordinateSignals,\n\ttype MaskTrackSignals,\n\ttype ObjectTrackSignals,\n\ttype PinToLandmarkOptions,\n\ttype PinToObjectOptions,\n\tpinNodeToLandmark,\n\tpinNodeToObject,\n\ttype VisionAnalysisReport,\n\tVisionBundle,\n\tVisionNode,\n\tVisionRunner,\n\ttype VisionTask,\n} from \"@framefields/vision\";\n\nexport {\n\tanalyzeSequence,\n\ttype VisionAnalysisReport,\n} from \"@framefields/vision\";\n\nimport {\n\ttype DeflickerOptions,\n\ttype NormalRelightingOptions,\n\tTensorPipeline,\n} from \"@framefields/tensor-webgpu\";\nimport { inputStore, mediaDecoderCache } from \"@framefields/webgpu-renderers\";\nimport { buildChart, type ChartOptions } from \"./chart.js\";\nimport {\n\tApplyLUT,\n\ttype ApplyLUTProps,\n\tBlur,\n\ttype BlurProps,\n\tColorBalance,\n\ttype ColorBalanceProps,\n\tColorKey,\n\ttype ColorKeyProps,\n\tCrop,\n\ttype CropProps,\n\tCurves,\n\ttype CurvesProps,\n\tCustomEffect,\n\ttype DeflickerProps,\n\tDepthOfField,\n\ttype DepthOfFieldProps,\n\teffectFactories,\n\tFilmGrain,\n\ttype FilmGrainProps,\n\tGradientMap,\n\ttype GradientMapProps,\n\tHalftoneScreen,\n\ttype HalftoneScreenProps,\n\tHighPass,\n\ttype HighPassProps,\n\tLevels,\n\ttype LevelsProps,\n\tModulate,\n\ttype ModulateProps,\n\tMotionBlur,\n\ttype MotionBlurProps,\n\tPBRGlass,\n\ttype PBRGlassProps,\n\tRelight3D,\n\ttype Relight3DProps,\n\tSelectiveColor,\n\ttype SelectiveColorProps,\n\tShadowsHighlights,\n\ttype ShadowsHighlightsProps,\n\tSSAO,\n\ttype SSAOProps,\n\tTemporalDeflicker,\n\tTileOffset,\n\ttype TileOffsetProps,\n\tUnsharpMask,\n\ttype UnsharpMaskProps,\n\tVignette,\n\ttype VignetteProps,\n\tVision,\n\ttype VisionProps,\n} from \"./effects/index.js\";\nimport {\n\ttype FrameGridOptions,\n\tHeadlessMediaRenderer,\n\ttype RenderProgress,\n\trenderFrameGrid,\n\ttype VideoQaOptions,\n\ttype VideoQaReport,\n} from \"./renderer/index.js\";\nimport {\n\ttype Carousel3DOptions,\n\ttype Cube3DOptions,\n\tLayer3D,\n\ttype Plane3DOptions,\n\ttype Prism3DOptions,\n} from \"./shapes3d.js\";\nimport {\n\ttype SceneSequenceOptions,\n\ttype SequenceEntry,\n\ttype SequenceNode,\n\tsequence,\n} from \"./transitions.js\";\n\nexport interface SectionOptions {\n\treadonly id?: string;\n\treadonly position?: \"absolute\" | \"relative\";\n\treadonly source?: string | MediaNode;\n\treadonly effects?: unknown[];\n\treadonly padding?: number;\n\treadonly borderRadius?: number;\n\treadonly borderColor?: string;\n\treadonly borderWidth?: number;\n\treadonly opacity?: number | unknown;\n\treadonly blendMode?: string;\n\treadonly fit?: \"cover\" | \"contain\";\n\treadonly width?: number | unknown;\n\treadonly height?: number | unknown;\n\treadonly x?: number | unknown;\n\treadonly y?: number | unknown;\n\treadonly hideWhenLost?: boolean;\n\treadonly smoothFrames?: number;\n\treadonly children?: LayoutNode[];\n\treadonly [key: string]: unknown;\n}\n\nexport type SectionNode = AnimatableNode<BoxNode> & {\n\treadonly innerMedia: AnimatableNode<MediaNode>;\n\t// Any effect, whatever its config shape (Blur, FilmGrain, …).\n\treadonly effects: Effect<object>[];\n\taddEffect(effect: Effect<object>): SectionNode;\n\twithEffect(effect: Effect<object>): SectionNode;\n\twithEffects(effects: Effect<object>[]): SectionNode;\n};\n\nexport type TrackedRegionOptions = SectionOptions;\n\n/** Editing helpers attached to every tracked object (see decorateTrackSignals). */\nexport interface TrackEditing {\n\t/** A section of the source that follows this track */\n\tsection(\n\t\tsourceOrOptions?: string | MediaNode | SectionOptions,\n\t\toptions?: SectionOptions,\n\t): SectionNode;\n\t/** A blur confined to this track's region */\n\tblurEffect(options?: Partial<BlurProps>): Blur;\n\t/** The tracked region of `source`, cut out as a section */\n\tisolate(\n\t\tsource: string | MediaNode,\n\t\toptions?: TrackedRegionOptions,\n\t): SectionNode;\n}\n\n/** A tracked object with its editing helpers, as vision hands it out. */\nexport type EditableObjectTrack = ObjectTrackSignals & TrackEditing;\n\nfunction decorateTrackSignals<T extends ObjectTrackSignals>(\n\ttrack: T,\n\tsource?: string | MediaNode,\n): T {\n\tif (!track) return track;\n\tif (source && !track.source) {\n\t\tObject.defineProperty(track, \"source\", {\n\t\t\tvalue: source,\n\t\t\tenumerable: true,\n\t\t\twritable: true,\n\t\t\tconfigurable: true,\n\t\t});\n\t}\n\tif (typeof track.section !== \"function\") {\n\t\tObject.defineProperty(track, \"section\", {\n\t\t\tvalue: (\n\t\t\t\tsourceOrOptions?: string | MediaNode | SectionOptions,\n\t\t\t\toptions?: SectionOptions,\n\t\t\t) => {\n\t\t\t\tif (\n\t\t\t\t\ttypeof sourceOrOptions === \"object\" &&\n\t\t\t\t\tsourceOrOptions !== null &&\n\t\t\t\t\t!(\"kind\" in sourceOrOptions) &&\n\t\t\t\t\t!(\"inputHandleId\" in sourceOrOptions) &&\n\t\t\t\t\t!(\"src\" in sourceOrOptions)\n\t\t\t\t) {\n\t\t\t\t\tconst resolvedSource =\n\t\t\t\t\t\t(sourceOrOptions as SectionOptions).source ??\n\t\t\t\t\t\t(track.source as string | MediaNode | undefined) ??\n\t\t\t\t\t\tsource;\n\t\t\t\t\treturn Layer.section(\n\t\t\t\t\t\tresolvedSource as string | MediaNode,\n\t\t\t\t\t\ttrack,\n\t\t\t\t\t\tsourceOrOptions as SectionOptions,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst resolvedSource =\n\t\t\t\t\tsourceOrOptions ??\n\t\t\t\t\t(track.source as string | MediaNode | undefined) ??\n\t\t\t\t\tsource;\n\t\t\t\treturn Layer.section(\n\t\t\t\t\tresolvedSource as string | MediaNode,\n\t\t\t\t\ttrack,\n\t\t\t\t\toptions,\n\t\t\t\t);\n\t\t\t},\n\t\t\tenumerable: false,\n\t\t\twritable: true,\n\t\t\tconfigurable: true,\n\t\t});\n\t}\n\tif (typeof track.blurEffect !== \"function\") {\n\t\tObject.defineProperty(track, \"blurEffect\", {\n\t\t\tvalue: (options?: Partial<BlurProps>) => new Blur({ track, ...options }),\n\t\t\tenumerable: false,\n\t\t\twritable: true,\n\t\t\tconfigurable: true,\n\t\t});\n\t}\n\tif (typeof track.isolate !== \"function\") {\n\t\tObject.defineProperty(track, \"isolate\", {\n\t\t\tvalue: (sourceArg: string | MediaNode, options?: TrackedRegionOptions) =>\n\t\t\t\tLayer.section(sourceArg, track, options),\n\t\t\tenumerable: false,\n\t\t\twritable: true,\n\t\t\tconfigurable: true,\n\t\t});\n\t}\n\treturn track;\n}\n\nconst origVisionAttach = VisionNode.attach;\nVisionNode.attach = function (\n\tsource: Parameters<typeof origVisionAttach>[0],\n\tconfig?: Parameters<typeof origVisionAttach>[1],\n\tbundleOptions?: Parameters<typeof origVisionAttach>[2],\n): ReturnType<typeof origVisionAttach> {\n\tconst bundle = origVisionAttach.call(this, source, config, bundleOptions);\n\tif (bundle?.objects) {\n\t\tconst src = source as string | MediaNode;\n\t\tconst origGet = bundle.objects.get.bind(bundle.objects);\n\t\tbundle.objects.get = (id: number) => decorateTrackSignals(origGet(id), src);\n\n\t\tconst origByCategory = bundle.objects.byCategory.bind(bundle.objects);\n\t\tbundle.objects.byCategory = (cat: string, rank?: number) =>\n\t\t\tdecorateTrackSignals(origByCategory(cat, rank), src);\n\n\t\tif (bundle.objects.primary) {\n\t\t\tdecorateTrackSignals(bundle.objects.primary, src);\n\t\t}\n\t}\n\treturn bundle;\n};\n\nexport {\n\ttype AdvancedTextAnimator,\n\tAdvancedTextAnimatorBuilder,\n\tAdvancedTextAnimatorSchema,\n\t// Text Animations & After Effects Parity\n\ttype AETextAnimator,\n\tAETextAnimatorSchema,\n\ttype AnchorGrouping,\n\tAnchorGroupingSchema,\n\ttype AnchorPreset,\n\tAnchorPresetSchema,\n\ttype AnimatableGlyphProps,\n\tAnimatableGlyphPropsSchema,\n\ttype AnimatableProp,\n\ttype AnimationTrack,\n\ttype ArcLengthLUTEntry,\n\ttype AudioSpectrumTypography,\n\tAudioSpectrumTypographySchema,\n\tapplyStaggerToChildren,\n\ttype BlockNode,\n\ttype BloomConfig,\n\tBloomConfigSchema,\n\ttype BoxNode,\n\tBoxNodeSchema,\n\tbuildPathLUT,\n\tCameraAnimation,\n\ttype CameraDoF,\n\ttype CameraLens,\n\ttype CameraNode,\n\tCameraNodeSchema,\n\ttype CameraShake,\n\ttype CarrierHandoffConfig,\n\tCarrierHandoffConfigSchema,\n\ttype CarrierState,\n\ttype ChromaticGlitchConfig,\n\tChromaticGlitchConfigSchema,\n\ttype ColorSignalOptions,\n\ttype ColorStop,\n\tColorStopSchema,\n\ttype CompositorProgramConfig,\n\tCompositorProgramSchema,\n\ttype CompositorToProgramOptions,\n\ttype CubicBezierSegment,\n\tCubicBezierSegmentSchema,\n\tcalculateSequenceTimeline,\n\tcollectNodeOps,\n\tcompositorToProgram,\n\tcomputeAnchorPivotOffset,\n\tcomputeCarrierContinuity,\n\tcomputeLayout,\n\tcomputeLayoutSync,\n\tcomputeLineLeadingDisplacement,\n\tcomputeRangeSelectorWeight,\n\tcomputeStaggerDelay,\n\ttype DynamicStrokeProperties,\n\tDynamicStrokePropertiesSchema,\n\tdeterministicWigglyNoise,\n\tdistanceToCurveParameter,\n\ttype EaseRef,\n\ttype EnhancedTextNode,\n\tEnhancedTextNodeSchema,\n\ttype EnvironmentFog,\n\tEnvironmentFogSchema,\n\ttype EnvironmentPreset,\n\tEnvironmentPresetSchema,\n\ttype ExpressionEvaluationContext,\n\ttype ExpressionSelector,\n\tExpressionSelectorSchema,\n\ttype ExtendedGlyphProperties,\n\tExtendedGlyphPropertiesSchema,\n\tellipseToCubicBeziers,\n\tevaluateAnimationAtFrame,\n\tevaluateCubicBezier,\n\tevaluateCubicBezierDerivative,\n\tevaluateExpressionSelector,\n\tevaluateMarqueeOffset,\n\tevaluateSelectorCombination,\n\tevaluateSkewMatrix,\n\tevaluateSpringProgress,\n\tevaluateTrackAtFrame,\n\tevaluateTypewriterState,\n\tevaluateVolumetricFormation,\n\ttype FlexNode,\n\tFlexNodeSchema,\n\ttype FromToOptions,\n\ttype GlyphAnchorGrouping,\n\tGlyphAnchorGroupingSchema,\n\ttype GlyphAnchorPoint,\n\tGlyphAnchorPointSchema,\n\tgenerateArcLengthLUT,\n\tgeneratePathSegments,\n\tgetScramblePool,\n\tgetShuffledOrder,\n\thoistMattes,\n\ttype Keyframe,\n\ttype KeyframeTuple,\n\ttype KineticMarqueeConfig,\n\tKineticMarqueeConfigSchema,\n\tLayerAnimation,\n\ttype LayoutNode,\n\tLayoutNodeSchema,\n\ttype LightNode,\n\tLightNodeSchema,\n\ttype LightType,\n\tLightTypeSchema,\n\ttype LineSpacingDynamics,\n\tLineSpacingDynamicsSchema,\n\ttype LongShadowConfig,\n\tLongShadowConfigSchema,\n\tlintComposition,\n\ttype MaterialType,\n\tMaterialTypeSchema,\n\ttype MatteMode,\n\tMatteModeSchema,\n\ttype MediaNode,\n\tMediaNodeSchema,\n\ttype Model3DNode,\n\tModel3DNodeSchema,\n\tmergeAnimationTracks,\n\ttype ParticleDissolveConfig,\n\tParticleDissolveConfigSchema,\n\ttype PathChainLUT,\n\ttype PathChainLUTEntry,\n\tparseSvgPathToCubicBeziers,\n\tScene,\n\ttype SceneDefinition,\n\tSceneDefinitionSchema,\n\ttype SceneOptions,\n\ttype SceneTransitionType,\n\tSceneTransitionTypeSchema,\n\ttype SelectorBasedOn,\n\tSelectorBasedOnSchema,\n\ttype SelectorMode,\n\tSelectorModeSchema,\n\ttype SelectorShape,\n\tSelectorShapeSchema,\n\ttype SelectorUnits,\n\tSelectorUnitsSchema,\n\tSequence,\n\ttype SequenceOptions,\n\ttype SequenceTimelineResult,\n\ttype ShapeNode,\n\tShapeNodeSchema,\n\ttype SignalTrackOptions,\n\ttype SkewProperties,\n\tSkewPropertiesSchema,\n\ttype Spatial3DProperties,\n\tSpatial3DPropertiesSchema,\n\ttype SpringOptions,\n\ttype SpringPhysics,\n\tSpringPhysicsSchema,\n\tsampleAudioSpectrumScale,\n\tsampleCurveGeometry,\n\tsamplePathChainGeometry,\n\ttype TextAnchorConfig,\n\tTextAnchorConfigSchema,\n\tTextAnimator,\n\tTextAnimatorBuilder,\n\tTextAnimatorSchema,\n\ttype TextCursorConfig,\n\tTextCursorConfigSchema,\n\ttype TextCursorStyle,\n\tTextCursorStyleSchema,\n\ttype TextNode,\n\tTextNodeSchema,\n\tTextPathBuilder,\n\ttype TextPathOptions,\n\tTextPathOptionsSchema,\n\ttype TextPathSource,\n\tTextPathSourceSchema,\n\ttype TextRangeSelector,\n\tTextRangeSelectorSchema,\n\ttype TextScrambleConfig,\n\tTextScrambleConfigSchema,\n\ttype TextSelector,\n\tTextSelectorSchema,\n\ttype TextSignalSelector,\n\tTextSignalSelectorSchema,\n\tTextSpanMarkSchema,\n\tTextSpanSchema,\n\ttype TextWigglySelector,\n\tTextWigglySelectorSchema,\n\ttype ToneMapping,\n\tToneMappingSchema,\n\ttype TrackSource,\n\ttype TypewriterAnimator,\n\tTypewriterAnimatorSchema,\n\ttype TypingCadence,\n\tTypingCadenceSchema,\n\ttype VariableFontAxes,\n\tVariableFontAxesSchema,\n\ttype Vec2,\n\tVec2Schema,\n\ttype VolumetricFormationConfig,\n\tVolumetricFormationConfigSchema,\n\ttype VolumetricFormationMode,\n\tVolumetricFormationModeSchema,\n\ttype WiggleOptions,\n\twaveToCubicBeziers,\n} from \"@framefields/compositions/program\";\nexport * from \"@framefields/core\";\nexport * from \"@framefields/renderers\";\nexport {\n\ttype AnimationClip3D,\n\ttype AudioLatentData,\n\tAudioLatentEngine,\n\tAudioLatentTrackCache,\n\tAudioMeshDeformPipeline,\n\ttype BlendMode,\n\ttype Bone3D,\n\tCamera3D,\n\tEffectPipeline,\n\tensureDevice,\n\tGlassPipeline,\n\ttype GPULightData,\n\tinputStore,\n\tLight3D,\n\ttype Light3DOptions,\n\ttype LoadModelOptions,\n\tloadFBX,\n\tloadModel3D,\n\tloadOBJ,\n\tlutStore,\n\ttype Material3D,\n\ttype Mesh3DData,\n\ttype Model3DData,\n\tMotionBlurPipeline,\n\ttype NodeAnimationTrack3D,\n\tPath3D,\n\tparseFBX,\n\tparseMTL,\n\tparseOBJ,\n\ttype RenderContextValue,\n\tRenderer2D,\n\tRenderer3D,\n\tShadowPipeline,\n\ttype Skeleton3D,\n\tSlugFontCache,\n\tSlugPipeline,\n\tSSAOPipeline,\n\tshaderStore,\n\ttextureCache,\n} from \"@framefields/webgpu-renderers\";\nexport {\n\ttype ChartAnimationOptions,\n\ttype ChartAxisOptions,\n\ttype ChartCandle,\n\ttype ChartDatum,\n\ttype ChartOptions,\n\ttype ChartPadding,\n\ttype ChartSeries,\n\ttype ChartSlice,\n\ttype ChartType,\n\ttype ChartX,\n\tDEFAULT_CHART_COLORS,\n} from \"./chart.js\";\nexport {\n\tApplyLUT,\n\ttype ApplyLUTProps,\n\tAudioCompressor,\n\ttype AudioCompressorProps,\n\tAudioDelay,\n\ttype AudioDelayProps,\n\tAudioFade,\n\ttype AudioFadeProps,\n\tAudioNoiseGate,\n\ttype AudioNoiseGateProps,\n\tAudioParametricEq,\n\ttype AudioParametricEqProps,\n\tAudioReverb,\n\ttype AudioReverbProps,\n\tAudioSignalExtractor,\n\ttype AudioSignalExtractorProps,\n\tBlur,\n\ttype BlurProps,\n\tCameraParallax3D,\n\ttype CameraParallax3DProps,\n\tChannelMerger,\n\ttype ChannelMergerProps,\n\tChannelSplitter,\n\ttype ChannelSplitterProps,\n\tColorBalance,\n\ttype ColorBalanceProps,\n\tColorKey,\n\ttype ColorKeyProps,\n\tCornerPin,\n\ttype CornerPinProps,\n\tCrop,\n\ttype CropProps,\n\tCurves,\n\ttype CurvesChannelPoint,\n\ttype CurvesProps,\n\tCustomEffect,\n\ttype DeflickerProps,\n\tDepthOfField,\n\ttype DepthOfFieldProps,\n\tDisplacementMap,\n\ttype DisplacementMapProps,\n\tExtractLUT,\n\ttype ExtractLUTProps,\n\teffectFactories,\n\teffectMeta,\n\tFilmGrain,\n\ttype FilmGrainProps,\n\tFlip,\n\ttype FlipProps,\n\tGradientMap,\n\ttype GradientMapProps,\n\ttype GradientMapStop,\n\ttype HalftoneDotShape,\n\ttype HalftoneMode,\n\tHalftoneScreen,\n\ttype HalftoneScreenProps,\n\tHighPass,\n\ttype HighPassProps,\n\tKenBurns,\n\ttype KenBurnsProps,\n\tLayerStyle,\n\ttype LayerStyleProps,\n\ttype LevelChannel,\n\tLevels,\n\ttype LevelsProps,\n\tLiquify,\n\ttype LiquifyProps,\n\tMaskMath,\n\ttype MaskMathProps,\n\tMeshWarp,\n\ttype MeshWarpProps,\n\tModulate,\n\ttype ModulateProps,\n\tMotionBlur,\n\ttype MotionBlurProps,\n\tNoiseGenerator,\n\ttype NoiseGeneratorProps,\n\tPaint,\n\ttype PaintProps,\n\tPatchHeal,\n\ttype PatchHealProps,\n\tPBRGlass,\n\ttype PBRGlassProps,\n\tProceduralVFX,\n\ttype ProceduralVFXProps,\n\tRefineEdge,\n\ttype RefineEdgeProps,\n\tRefractionCaustics3D,\n\ttype RefractionCaustics3DProps,\n\tRelight3D,\n\ttype Relight3DProps,\n\tResizerScaler,\n\ttype ResizerScalerProps,\n\tRotate,\n\ttype RotateProps,\n\tSelectiveColor,\n\ttype SelectiveColorAdjustment,\n\ttype SelectiveColorProps,\n\tShadowsHighlights,\n\ttype ShadowsHighlightsProps,\n\tSSAO,\n\ttype SSAOProps,\n\tStereoPanning,\n\ttype StereoPanningProps,\n\tTemporalDeflicker,\n\tTileOffset,\n\ttype TileOffsetEdgeMode,\n\ttype TileOffsetProps,\n\tUnsharpMask,\n\ttype UnsharpMaskProps,\n\tVignette,\n\ttype VignetteProps,\n\tVision,\n\ttype VisionProps,\n} from \"./effects/index.js\";\nexport {\n\tLighting,\n\ttype LightingRig,\n\ttype LightingRigOptions,\n} from \"./lighting.js\";\nexport {\n\ttype Carousel3DOptions,\n\ttype Cube3DOptions,\n\ttype CubeFaceConfig,\n\ttype CubeFaceInput,\n\ttype Cylinder3DOptions,\n\ttype ExtrudedText3DOptions,\n\ttype Grid3DOptions,\n\tLayer3D,\n\ttype Plane3DOptions,\n\ttype Primitive3DNodeOptions,\n\ttype Prism3DOptions,\n\ttype RoundedBox3DOptions,\n\ttype Shape3DContainer,\n\ttype Sphere3DOptions,\n\ttype Surface3DOptions,\n\ttype Text3DOptions,\n} from \"./shapes3d.js\";\nexport {\n\ttype SceneSequenceOptions,\n\ttype SequenceEntry,\n\ttype SequenceNode,\n\tTransition,\n\ttype TransitionDirection,\n\ttype TransitionSpec,\n} from \"./transitions.js\";\n\nexport interface CompositionOptions {\n\twidth: number;\n\theight: number;\n\tfps?: number;\n\tdurationMs?: number;\n\tdurationFrames?: number;\n\tbackgroundColor?: string;\n\tfonts?: string[];\n\tsignals?: Record<string, unknown>;\n\t/**\n\t * Smooth the edges of 3D meshes (extruded text, models) with 4x MSAA.\n\t * Default true; set false to save ~60-125 MB of GPU memory at 1080p.\n\t */\n\tantialias3d?: boolean;\n}\n\n/**\n * Fluent builder for single clips and chained visual/audio effect pipelines.\n */\nexport class Media {\n\tpublic readonly virtualMedia: VirtualMediaData;\n\n\tconstructor(source: MediaSourceInput, type: DataType = \"Video\") {\n\t\tthis.virtualMedia = createVirtualMedia(source, type);\n\t}\n\n\tstatic video(source: MediaSourceInput, meta?: Partial<MediaMetadata>): Media {\n\t\tconst m = new Media(source, \"Video\");\n\t\tif (meta) Object.assign(m.virtualMedia.metadata, meta);\n\t\treturn m;\n\t}\n\n\tstatic image(source: MediaSourceInput, meta?: Partial<MediaMetadata>): Media {\n\t\tconst m = new Media(source, \"Image\");\n\t\tif (meta) Object.assign(m.virtualMedia.metadata, meta);\n\t\treturn m;\n\t}\n\n\tstatic lottie(\n\t\tsource: MediaSourceInput,\n\t\tmeta?: Partial<MediaMetadata>,\n\t): Media {\n\t\tconst m = new Media(source, \"Lottie\");\n\t\tif (meta) Object.assign(m.virtualMedia.metadata, meta);\n\t\treturn m;\n\t}\n\n\tstatic audio(source: MediaSourceInput, meta?: Partial<MediaMetadata>): Media {\n\t\tconst m = new Media(source, \"Audio\");\n\t\tif (meta) Object.assign(m.virtualMedia.metadata, meta);\n\t\treturn m;\n\t}\n\n\t/**\n\t * Appends any Effect instance or shader operation onto the current media AST.\n\t */\n\tpublic apply<TProps extends object>(effect: Effect<TProps>): Media;\n\tpublic apply<\n\t\tTConfig extends Record<string, unknown> = Record<string, unknown>,\n\t>(op: string, config?: TConfig): Media;\n\tpublic apply(\n\t\teffectOrOp: Effect<object> | string,\n\t\tconfig: Record<string, unknown> = {},\n\t): Media {\n\t\tlet opPayload: Record<string, unknown>;\n\t\tif (\n\t\t\teffectOrOp instanceof Effect ||\n\t\t\t(typeof effectOrOp === \"object\" &&\n\t\t\t\teffectOrOp !== null &&\n\t\t\t\t\"op\" in effectOrOp)\n\t\t) {\n\t\t\topPayload = (effectOrOp as Effect<object>).toOperation();\n\t\t} else {\n\t\t\topPayload = {\n\t\t\t\top: effectOrOp,\n\t\t\t\t...config,\n\t\t\t};\n\t\t}\n\n\t\tconst nextVM = appendOperation(this.virtualMedia, {\n\t\t\t...opPayload,\n\t\t\tdataType: this.virtualMedia.operation.dataType,\n\t\t} as MediaOperation);\n\t\treturn new Media(nextVM);\n\t}\n\n\t/**\n\t * Returns the underlying VirtualMediaData AST node ready for rendering.\n\t */\n\tpublic toVirtualMedia(): VirtualMediaData {\n\t\treturn this.virtualMedia;\n\t}\n\n\t/**\n\t * Renders a single frame from this media pipeline to a PNG Buffer.\n\t * Can render either by timestamp in milliseconds (`atMs`) or by frame index (`frame`).\n\t */\n\tpublic async renderFrame(\n\t\toptions: {\n\t\t\tatMs?: number;\n\t\t\tframe?: number;\n\t\t\tfps?: number;\n\t\t\trenderer?: HeadlessMediaRenderer;\n\t\t} = {},\n\t): Promise<Buffer> {\n\t\tconst renderer = options.renderer ?? new HeadlessMediaRenderer();\n\t\treturn renderer.renderFrame(this.virtualMedia, options);\n\t}\n\n\tget fps(): number | undefined {\n\t\treturn this.virtualMedia.metadata?.fps ?? undefined;\n\t}\n\n\tget durationMs(): number | undefined {\n\t\treturn this.virtualMedia.metadata?.durationMs ?? undefined;\n\t}\n\n\tget width(): number | undefined {\n\t\treturn this.virtualMedia.metadata?.width ?? undefined;\n\t}\n\n\tget height(): number | undefined {\n\t\treturn this.virtualMedia.metadata?.height ?? undefined;\n\t}\n\n\t/**\n\t * Renders an image grid of sequential frames across a given frame or millisecond range.\n\t * Ideal for automated visual inspection of animation motion, easing curves, and layout stability.\n\t */\n\tpublic async renderFrameGrid(\n\t\toptions: FrameGridOptions = {},\n\t): Promise<Buffer> {\n\t\treturn renderFrameGrid(this, options);\n\t}\n\n\t/**\n\t * Renders this media pipeline into an MP4/WebM video file with audio.\n\t */\n\tpublic async renderVideo(\n\t\toutputPathOrOptions: string | RenderVideoOptions = {},\n\t\toptions: RenderVideoOptions = {},\n\t): Promise<RenderVideoResult> {\n\t\tconst opts =\n\t\t\ttypeof outputPathOrOptions === \"string\"\n\t\t\t\t? { ...options, outputPath: outputPathOrOptions }\n\t\t\t\t: outputPathOrOptions;\n\t\tconst renderer = opts.renderer ?? new HeadlessMediaRenderer();\n\t\tconst result = await renderer.renderVideo(this.virtualMedia, opts);\n\t\treturn deliverToOutputPath(result, opts.outputPath);\n\t}\n}\n\n/**\n * Copies a rendered temp file to `outputPath` and drops the temp, so the\n * returned `filePath` is where the video actually lives.\n */\nasync function deliverToOutputPath(\n\tresult: RenderVideoResult,\n\toutputPath: string | undefined,\n): Promise<RenderVideoResult> {\n\tif (!outputPath) return result;\n\tconst target = path.resolve(outputPath);\n\tawait fs.mkdir(path.dirname(target), { recursive: true });\n\tawait fs.copyFile(result.filePath, target);\n\tawait result.cleanup();\n\treturn { ...result, filePath: target, cleanup: async () => {} };\n}\n\nexport interface RenderVideoOptions {\n\tcodec?: string;\n\taudioCodec?: string;\n\tquality?: string;\n\tconcurrency?: number;\n\t/**\n\t * Depth of the DMA staging ring used to overlap GPU rendering with hardware\n\t * encoding (default 2, clamped 2–8). A deeper ring hides more encoder\n\t * latency at the cost of VRAM (~8.3MB/slot at 1080p RGBA). Also settable\n\t * via `FRAMEFIELDS_RING_CAPACITY`.\n\t */\n\tringCapacity?: number;\n\toutputPath?: string;\n\trenderer?: HeadlessMediaRenderer;\n\t/**\n\t * Check the output while it renders and return the findings as `qa`:\n\t * dropped, black or frozen frames, loudness (LUFS), clipping, silence and\n\t * document warnings such as truncated animations. `true` uses defaults;\n\t * pass thresholds (e.g. `{ targetLufs: -14 }`) to tighten them.\n\t */\n\tqa?: boolean | VideoQaOptions;\n\t/**\n\t * Stops the render between frames. The promise rejects with\n\t * `signal.reason` and no file is left behind.\n\t */\n\tsignal?: AbortSignal;\n\t/** Called as frames finish (`phase: \"render\"`), then once for the audio mix. */\n\tonProgress?: (progress: RenderProgress) => void;\n}\n\nexport interface RenderVideoResult {\n\tfilePath: string;\n\tcleanup: () => Promise<void>;\n\t/** Present when rendered with `qa`; print it with `formatQaReport` */\n\tqa?: VideoQaReport;\n}\n\nexport interface SubjectSandwichOptions {\n\treadonly source: string | MediaNode;\n\treadonly subject?: MaskTrackSignals | ObjectTrackSignals;\n\treadonly behind: readonly LayoutNode[];\n\treadonly feather?: number;\n\treadonly fit?: \"cover\" | \"contain\" | \"fill\";\n\treadonly variant?: VisionProps[\"variant\"];\n\treadonly confidence?: number;\n\treadonly keyBackground?: boolean;\n\treadonly backgroundKeyThreshold?: number;\n\treadonly muted?: boolean;\n\treadonly volume?: number;\n}\n\nexport interface SmartFramingOptions {\n\treadonly source: string | MediaNode;\n\treadonly targetAspect?: number;\n\treadonly sourceAspect?: number;\n\treadonly target: ObjectTrackSignals | MaskTrackSignals;\n\treadonly damping?: number;\n\treadonly leadHeadroom?: number;\n\treadonly fit?: \"cover\" | \"contain\" | \"fill\";\n\treadonly variant?: VisionProps[\"variant\"];\n\treadonly muted?: boolean;\n\treadonly volume?: number;\n}\n\nexport interface SubjectOutlineOptions {\n\treadonly source?: string | MediaNode;\n\treadonly color?: string;\n\treadonly width?: number;\n\treadonly blur?: number;\n\treadonly pulseSignal?: ProgrammaticSignal | Signal<number>;\n\treadonly muted?: boolean;\n\treadonly volume?: number;\n}\n\n/**\n * High-level programmatic builder for multi-layer Framefields compositions.\n */\nexport class Composition {\n\tpublic width: number;\n\tpublic height: number;\n\tpublic fps: number;\n\tpublic durationMs?: number;\n\tpublic backgroundColor: string;\n\tpublic antialias3d?: boolean;\n\tpublic fonts: string[];\n\tpublic children: LayoutNode[] = [];\n\tpublic audioTracks: MediaNode[] = [];\n\tpublic signals: Record<string, unknown> = {};\n\tprivate _frameHooks: Array<(ctx: FrameContext) => void> = [];\n\tprivate _visionConfig?: VisionProps;\n\tprivate _visionBundle?: VisionBundle;\n\tprivate _effects: unknown[] = [];\n\n\t/**\n\t * Applies a whole-composition post-processing effect or vision pipeline.\n\t */\n\tpublic apply(effect: unknown): this {\n\t\tif (effect instanceof Vision) {\n\t\t\tthis.withVision(effect);\n\t\t\treturn this;\n\t\t}\n\t\tthis._effects.push(effect);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Runs vision on the whole composition — the rendered frame (composition, blur, crop,\n\t * anything upstream) is the inference input. Models are LAZY: nothing downloads until\n\t * the first frame actually runs a task.\n\t * Returns the reactive VisionBundle (objects / masks / pose / classes signals).\n\t */\n\tpublic withVision(config: VisionProps | Vision = {}): VisionBundle {\n\t\tthis._visionBundle ??= new VisionBundle({\n\t\t\twidth: this.width,\n\t\t\theight: this.height,\n\t\t\tfps: this.fps,\n\t\t});\n\t\tconst rawConfig =\n\t\t\tconfig instanceof Vision ? (config.config as VisionProps) : config;\n\t\tthis._visionConfig = {\n\t\t\t...rawConfig,\n\t\t\tvisionBundle: this._visionBundle,\n\t\t};\n\t\treturn this._visionBundle;\n\t}\n\n\t/**\n\t * One-shot, ffmpeg-free vision analysis of a media source.\n\t *\n\t * Decodes frames through the same mediabunny pipeline the renderer uses, runs the requested\n\t * tasks lazily (only those models download), temporally tracks detections, and returns a\n\t * zod-serializable report. The decoder is released and the runner closed on completion.\n\t */\n\tpublic async analyzeVisionSequence(\n\t\tsource: string,\n\t\toptions: {\n\t\t\ttasks?: readonly VisionTask[];\n\t\t\tcategories?: readonly string[];\n\t\t\tfps?: number;\n\t\t\ttotalFrames?: number;\n\t\t\tpathStride?: number;\n\t\t\tincludeMasks?: boolean;\n\t\t\tmodelsDir?: string;\n\t\t\tbaseUrl?: string;\n\t\t\tconfidence?: number;\n\t\t\tvariant?: VisionProps[\"variant\"];\n\t\t\t/** Tracker box-association IoU. Default 0.25. */\n\t\t\tiouThreshold?: number;\n\t\t} = {},\n\t): Promise<VisionAnalysisReport> {\n\t\tconst fps = options.fps ?? this.fps;\n\t\tconst durationMs = this.durationMs ?? (await this.computeDuration());\n\t\tconst totalFrames =\n\t\t\toptions.totalFrames ?? Math.max(1, Math.round((durationMs / 1000) * fps));\n\n\t\tconst runner = VisionRunner.create({\n\t\t\tmodelsDir: options.modelsDir,\n\t\t\tbaseUrl: options.baseUrl,\n\t\t\t...(options.confidence !== undefined\n\t\t\t\t? { confidence: options.confidence }\n\t\t\t\t: {}),\n\t\t\t...(options.variant !== undefined ? { variant: options.variant } : {}),\n\t\t});\n\n\t\tconst decoder = mediaDecoderCache.getVideo(source, true);\n\t\tasync function* frameSource(): AsyncGenerator<{\n\t\t\tdata: Uint8Array;\n\t\t\twidth: number;\n\t\t\theight: number;\n\t\t}> {\n\t\t\tfor (let i = 0; i < totalFrames; i++) {\n\t\t\t\tconst frame = await decoder.getFrame(i / fps);\n\t\t\t\tif (frame?.buffer && frame.width > 0 && frame.height > 0) {\n\t\t\t\t\tyield {\n\t\t\t\t\t\tdata: frame.buffer,\n\t\t\t\t\t\twidth: frame.width,\n\t\t\t\t\t\theight: frame.height,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\treturn await analyzeVisionFrames(frameSource(), {\n\t\t\t\trunner,\n\t\t\t\tsource,\n\t\t\t\tfps,\n\t\t\t\t...(options.tasks !== undefined ? { tasks: options.tasks } : {}),\n\t\t\t\t...(options.categories !== undefined\n\t\t\t\t\t? { categories: options.categories }\n\t\t\t\t\t: {}),\n\t\t\t\t...(options.pathStride !== undefined\n\t\t\t\t\t? { pathStride: options.pathStride }\n\t\t\t\t\t: {}),\n\t\t\t\t...(options.includeMasks !== undefined\n\t\t\t\t\t? { includeMasks: options.includeMasks }\n\t\t\t\t\t: {}),\n\t\t\t\t...(options.iouThreshold !== undefined\n\t\t\t\t\t? { iouThreshold: options.iouThreshold }\n\t\t\t\t\t: {}),\n\t\t\t});\n\t\t} finally {\n\t\t\trunner.close();\n\t\t\tdecoder.destroy();\n\t\t}\n\t}\n\n\t/**\n\t * Game-engine per-frame lifecycle hook for the composition.\n\t * Invoked before rendering each frame so scripts or agents can mutate properties and signals.\n\t */\n\tpublic onRequestFrame(callback: (ctx: FrameContext) => void): this {\n\t\tthis._frameHooks.push(callback);\n\t\treturn this;\n\t}\n\n\tpublic notifyFrame(ctx: FrameContext): void {\n\t\tfor (const hook of this._frameHooks) {\n\t\t\thook(ctx);\n\t\t}\n\t}\n\n\tconstructor(options: CompositionOptions) {\n\t\tthis.width = options.width;\n\t\tthis.height = options.height;\n\t\tthis.fps = options.fps ?? 60;\n\t\tthis.durationMs =\n\t\t\toptions.durationMs ??\n\t\t\t(options.durationFrames !== undefined\n\t\t\t\t? (options.durationFrames / this.fps) * 1000\n\t\t\t\t: undefined);\n\t\tthis.backgroundColor = options.backgroundColor ?? \"#000000\";\n\t\tthis.antialias3d = options.antialias3d;\n\t\tthis.fonts = options.fonts ?? [];\n\t\tthis.signals = options.signals ?? {};\n\t}\n\n\tpublic static create(options: CompositionOptions): Composition {\n\t\treturn new Composition(options);\n\t}\n\n\tpublic addSignal(name: string, signal: unknown): this {\n\t\tthis.signals[name] = signal;\n\t\treturn this;\n\t}\n\n\tpublic add(\n\t\tlayerOrFirst:\n\t\t\t| LayoutNode\n\t\t\t| LayoutNode[]\n\t\t\t| TensorPipeline\n\t\t\t| VisionNode\n\t\t\t| { node: unknown },\n\t\t...rest: Array<\n\t\t\t| LayoutNode\n\t\t\t| LayoutNode[]\n\t\t\t| TensorPipeline\n\t\t\t| VisionNode\n\t\t\t| { node: unknown }\n\t\t\t| LayerAnimation\n\t\t\t| { tracks: AnimationTrack[] }\n\t\t>\n\t): this {\n\t\tif (layerOrFirst instanceof TensorPipeline) {\n\t\t\tthis.children.push(layerOrFirst.toNode() as unknown as LayoutNode);\n\t\t} else if (layerOrFirst instanceof VisionNode) {\n\t\t\tthis.children.push(layerOrFirst.toNode() as unknown as LayoutNode);\n\t\t} else if (\n\t\t\tlayerOrFirst &&\n\t\t\ttypeof layerOrFirst === \"object\" &&\n\t\t\t\"node\" in layerOrFirst\n\t\t) {\n\t\t\tthis.add(\n\t\t\t\t(\n\t\t\t\t\tlayerOrFirst as {\n\t\t\t\t\t\tnode: LayoutNode | TensorPipeline | { node: unknown };\n\t\t\t\t\t}\n\t\t\t\t).node as LayoutNode,\n\t\t\t\t...rest,\n\t\t\t);\n\t\t\treturn this;\n\t\t} else if (Array.isArray(layerOrFirst)) {\n\t\t\tfor (const l of layerOrFirst) {\n\t\t\t\tthis.add(l);\n\t\t\t}\n\t\t} else {\n\t\t\tconst targetNode = layerOrFirst as LayoutNode;\n\t\t\tconst animCandidate = rest[0];\n\t\t\tif (\n\t\t\t\tanimCandidate &&\n\t\t\t\t!(animCandidate instanceof TensorPipeline) &&\n\t\t\t\t!Array.isArray(animCandidate) &&\n\t\t\t\t(animCandidate instanceof LayerAnimation || \"tracks\" in animCandidate)\n\t\t\t) {\n\t\t\t\ttargetNode.animation =\n\t\t\t\t\tanimCandidate instanceof LayerAnimation\n\t\t\t\t\t\t? animCandidate.toSpec()\n\t\t\t\t\t\t: animCandidate;\n\t\t\t\tthis.children.push(targetNode);\n\t\t\t\treturn this;\n\t\t\t}\n\t\t\tthis.children.push(targetNode);\n\t\t}\n\n\t\tfor (const item of rest) {\n\t\t\tif (item && !(item instanceof LayerAnimation) && !(\"tracks\" in item)) {\n\t\t\t\tthis.add(\n\t\t\t\t\titem as\n\t\t\t\t\t\t| LayoutNode\n\t\t\t\t\t\t| LayoutNode[]\n\t\t\t\t\t\t| TensorPipeline\n\t\t\t\t\t\t| { node: unknown },\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tpublic addAudio(track: MediaNode): this {\n\t\tthis.audioTracks.push(track);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Turnkey \"Text Behind Subject\" (\"Sandwich\") Primitive.\n\t * Lowers into:\n\t * 1. Bottom Layer: Full background video plate\n\t * 2. Middle Layer: User-supplied `behind` nodes\n\t * 3. Top Layer: Subject cutout video with continuous matte alpha registered at identical coordinates\n\t */\n\tpublic addSubjectSandwich(options: SubjectSandwichOptions): this {\n\t\tconst src =\n\t\t\ttypeof options.source === \"string\"\n\t\t\t\t? options.source\n\t\t\t\t: (options.source.inputHandleId ?? \"\");\n\t\tconst fit = options.fit ?? \"cover\";\n\t\tconst feather = options.feather ?? 4;\n\t\tconst featherVal = feather > 1 ? feather / 100 : feather;\n\t\tconst variant = options.variant ?? \"s\";\n\n\t\t// 1. Bottom Layer: Full background video plate\n\t\tconst bottomPlate = Layer.video(src, {\n\t\t\twidth: this.width,\n\t\t\theight: this.height,\n\t\t\tposition: \"absolute\",\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\tfit,\n\t\t\tmuted: options.muted ?? false,\n\t\t\tvolume: options.muted ? 0 : (options.volume ?? 1),\n\t\t});\n\t\tthis.add(bottomPlate);\n\n\t\t// 2. Middle Layer: User-supplied `behind` nodes\n\t\tfor (const node of options.behind) {\n\t\t\tthis.add(node);\n\t\t}\n\n\t\t// 3. Top Layer: Subject cutout video with continuous matte alpha registered at identical coordinates\n\t\tconst topPlate = Layer.video(src, {\n\t\t\twidth: this.width,\n\t\t\theight: this.height,\n\t\t\tposition: \"absolute\",\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\tfit,\n\t\t\tmuted: true,\n\t\t\tvolume: 0,\n\t\t}).withVision({\n\t\t\tmode: \"matte\",\n\t\t\tenableSegmentation: true,\n\t\t\tvariant,\n\t\t\tconfidence: options.confidence ?? 0.25,\n\t\t\tfeatherRadius: featherVal,\n\t\t\tkeyBackground: options.keyBackground ?? true,\n\t\t\tbackgroundKeyThreshold: options.backgroundKeyThreshold,\n\t\t});\n\t\tthis.add(topPlate);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Dynamic Smart Re-Framing (16:9 → 9:16 Auto-Crop).\n\t * Automatically transforms landscape footage into vertical shorts/reels by framing the\n\t * tracked subject with smooth camera physics and lead headroom.\n\t */\n\tpublic addSmartFraming(options: SmartFramingOptions): this {\n\t\tconst src =\n\t\t\ttypeof options.source === \"string\"\n\t\t\t\t? options.source\n\t\t\t\t: (options.source.inputHandleId ?? \"\");\n\t\tconst damping = Math.max(0, Math.min(0.99, options.damping ?? 0.8));\n\t\tconst headroom = options.leadHeadroom ?? 0.18;\n\t\tconst compW = this.width;\n\t\tconst compH = this.height;\n\n\t\tconst sourceAspect = options.sourceAspect ?? 16 / 9;\n\t\tconst compAspect = compW / compH;\n\n\t\t// Calculate canvas coverage dimensions to avoid black bars during pan\n\t\tconst plateWidth =\n\t\t\tcompAspect < sourceAspect ? Math.round(compH * sourceAspect) : compW;\n\t\tconst plateHeight =\n\t\t\tcompAspect < sourceAspect ? compH : Math.round(compW / sourceAspect);\n\n\t\tconst minOffsetX = compW - plateWidth; // <= 0\n\t\tconst minOffsetY = compH - plateHeight; // <= 0\n\n\t\tconst targetObj = options.target as unknown as {\n\t\t\tcenter?: {\n\t\t\t\tx?: ProgrammaticSignal;\n\t\t\t\ty?: ProgrammaticSignal;\n\t\t\t\tscreenX?: ProgrammaticSignal;\n\t\t\t\tscreenY?: ProgrammaticSignal;\n\t\t\t};\n\t\t\tbounds?: {\n\t\t\t\tx?: ProgrammaticSignal;\n\t\t\t\ty?: ProgrammaticSignal;\n\t\t\t\twidth?: ProgrammaticSignal;\n\t\t\t\theight?: ProgrammaticSignal;\n\t\t\t\tcenterX?: ProgrammaticSignal;\n\t\t\t\tcenterY?: ProgrammaticSignal;\n\t\t\t};\n\t\t};\n\n\t\tconst rawOffsetX = new ProgrammaticSignal(\n\t\t\t(ctx) => {\n\t\t\t\tif (minOffsetX >= 0) return 0;\n\t\t\t\tconst normX = targetObj.center?.x\n\t\t\t\t\t? targetObj.center.x.get(ctx)\n\t\t\t\t\t: targetObj.bounds?.centerX\n\t\t\t\t\t\t? targetObj.bounds.centerX.get(ctx) / compW\n\t\t\t\t\t\t: targetObj.center?.screenX\n\t\t\t\t\t\t\t? targetObj.center.screenX.get(ctx) / compW\n\t\t\t\t\t\t\t: 0.5;\n\t\t\t\tconst clampedNormX = Math.max(0, Math.min(1, normX));\n\t\t\t\tconst targetPx = clampedNormX * plateWidth;\n\t\t\t\tconst desired = compW / 2 - targetPx;\n\t\t\t\treturn Math.max(minOffsetX, Math.min(0, desired));\n\t\t\t},\n\t\t\t{ fps: this.fps, label: \"smart_framing_pan_x\" },\n\t\t);\n\n\t\tconst rawOffsetY = new ProgrammaticSignal(\n\t\t\t(ctx) => {\n\t\t\t\tif (minOffsetY >= 0) return 0;\n\t\t\t\tconst normY = targetObj.center?.y\n\t\t\t\t\t? targetObj.center.y.get(ctx)\n\t\t\t\t\t: targetObj.bounds?.centerY\n\t\t\t\t\t\t? targetObj.bounds.centerY.get(ctx) / compH\n\t\t\t\t\t\t: targetObj.center?.screenY\n\t\t\t\t\t\t\t? targetObj.center.screenY.get(ctx) / compH\n\t\t\t\t\t\t\t: 0.5;\n\t\t\t\tconst clampedNormY = Math.max(0, Math.min(1, normY));\n\t\t\t\tconst targetPy = clampedNormY * plateHeight;\n\t\t\t\tconst desired = compH * headroom - targetPy;\n\t\t\t\treturn Math.max(minOffsetY, Math.min(0, desired));\n\t\t\t},\n\t\t\t{ fps: this.fps, label: \"smart_framing_pan_y\" },\n\t\t);\n\n\t\t// Damped camera smoothing\n\t\tconst smoothOffsetX = new ProgrammaticSignal(\n\t\t\t(ctx) => {\n\t\t\t\tconst targetFrame = ctx.frame;\n\t\t\t\tif (targetFrame <= 0) return rawOffsetX.get(ctx);\n\t\t\t\tlet filtered = rawOffsetX.get({ ...ctx, frame: 0, time: 0 });\n\t\t\t\tconst alpha = 1.0 - damping;\n\t\t\t\tfor (let f = 1; f <= targetFrame; f++) {\n\t\t\t\t\tconst val = rawOffsetX.get({ ...ctx, frame: f, time: f / ctx.fps });\n\t\t\t\t\tfiltered = filtered + alpha * (val - filtered);\n\t\t\t\t}\n\t\t\t\treturn filtered;\n\t\t\t},\n\t\t\t{ fps: this.fps, label: \"smart_framing_smooth_x\" },\n\t\t);\n\n\t\tconst smoothOffsetY = new ProgrammaticSignal(\n\t\t\t(ctx) => {\n\t\t\t\tconst targetFrame = ctx.frame;\n\t\t\t\tif (targetFrame <= 0) return rawOffsetY.get(ctx);\n\t\t\t\tlet filtered = rawOffsetY.get({ ...ctx, frame: 0, time: 0 });\n\t\t\t\tconst alpha = 1.0 - damping;\n\t\t\t\tfor (let f = 1; f <= targetFrame; f++) {\n\t\t\t\t\tconst val = rawOffsetY.get({ ...ctx, frame: f, time: f / ctx.fps });\n\t\t\t\t\tfiltered = filtered + alpha * (val - filtered);\n\t\t\t\t}\n\t\t\t\treturn filtered;\n\t\t\t},\n\t\t\t{ fps: this.fps, label: \"smart_framing_smooth_y\" },\n\t\t);\n\n\t\tconst container = Layer.box({\n\t\t\twidth: compW,\n\t\t\theight: compH,\n\t\t\toverflow: \"hidden\",\n\t\t\tposition: \"relative\",\n\t\t});\n\n\t\tconst videoPlate = Layer.video(src, {\n\t\t\twidth: plateWidth,\n\t\t\theight: plateHeight,\n\t\t\tposition: \"absolute\",\n\t\t\tx: smoothOffsetX as unknown as number,\n\t\t\ty: smoothOffsetY as unknown as number,\n\t\t\tfit: options.fit ?? \"cover\",\n\t\t\tmuted: options.muted ?? false,\n\t\t\tvolume: options.muted ? 0 : (options.volume ?? 1),\n\t\t});\n\n\t\tif (!container.children) {\n\t\t\tcontainer.children = [];\n\t\t}\n\t\tcontainer.children.push(videoPlate);\n\t\tthis.add(container);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Subject Contour Glow & Neon Outline.\n\t * Strokes the silhouette boundary with a stylized bloom/glow and optional audio-reactive pulse.\n\t */\n\tpublic addSubjectOutline(\n\t\t_subject: MaskTrackSignals | ObjectTrackSignals,\n\t\toptions: SubjectOutlineOptions = {},\n\t): this {\n\t\tconst blur = options.blur ?? 12;\n\t\tconst compW = this.width;\n\t\tconst compH = this.height;\n\n\t\tconst pulse = options.pulseSignal;\n\t\tconst baseOpacity = pulse\n\t\t\t? new ProgrammaticSignal(\n\t\t\t\t\t(ctx) => Math.max(0, Math.min(1, Number(pulse.get(ctx)) || 0)),\n\t\t\t\t\t{ fps: this.fps, label: \"outline_pulse\" },\n\t\t\t\t)\n\t\t\t: 1.0;\n\n\t\tconst src =\n\t\t\ttypeof options.source === \"string\"\n\t\t\t\t? options.source\n\t\t\t\t: (options.source?.inputHandleId ?? \"\");\n\n\t\tconst outlineLayer = Layer.box({\n\t\t\twidth: compW,\n\t\t\theight: compH,\n\t\t\tposition: \"absolute\",\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\topacity: baseOpacity as unknown as number,\n\t\t});\n\n\t\tif (src) {\n\t\t\tconst maskVideo = Layer.video(src, {\n\t\t\t\twidth: compW,\n\t\t\t\theight: compH,\n\t\t\t\tposition: \"absolute\",\n\t\t\t\tx: 0,\n\t\t\t\ty: 0,\n\t\t\t\tfit: \"cover\",\n\t\t\t\tmuted: true,\n\t\t\t\tvolume: 0,\n\t\t\t}).withVision({\n\t\t\t\tmode: \"mask\",\n\t\t\t\tenableSegmentation: true,\n\t\t\t});\n\t\t\tif (!outlineLayer.children) {\n\t\t\t\toutlineLayer.children = [];\n\t\t\t}\n\t\t\toutlineLayer.children.push(maskVideo);\n\t\t}\n\n\t\toutlineLayer.apply(\n\t\t\tnew Blur({\n\t\t\t\tstrength: blur,\n\t\t\t\tblurType: \"Gaussian\",\n\t\t\t}),\n\t\t);\n\n\t\tthis.add(outlineLayer);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Creates an isolated, styled section of the composition or underlying source plate.\n\t * Any WebGPU effects (Blur, FilmGrain, Curves, Vignette, etc.) can be applied to this section.\n\t */\n\tpublic section(\n\t\tsourceOrTargetOrOptions?:\n\t\t\t| string\n\t\t\t| MediaNode\n\t\t\t| ObjectTrackSignals\n\t\t\t| SectionOptions,\n\t\ttargetOrOptions?: ObjectTrackSignals | SectionOptions,\n\t\toptions?: SectionOptions,\n\t): SectionNode {\n\t\tlet source: string | MediaNode | undefined;\n\t\tlet target: ObjectTrackSignals | undefined;\n\t\tlet opts: SectionOptions = {};\n\n\t\tconst isFirstTrack =\n\t\t\tsourceOrTargetOrOptions !== null &&\n\t\t\ttypeof sourceOrTargetOrOptions === \"object\" &&\n\t\t\t\"bounds\" in sourceOrTargetOrOptions;\n\n\t\tconst isFirstMedia =\n\t\t\ttypeof sourceOrTargetOrOptions === \"string\" ||\n\t\t\t(sourceOrTargetOrOptions !== null &&\n\t\t\t\ttypeof sourceOrTargetOrOptions === \"object\" &&\n\t\t\t\t(\"kind\" in sourceOrTargetOrOptions ||\n\t\t\t\t\t\"src\" in sourceOrTargetOrOptions ||\n\t\t\t\t\t\"inputHandleId\" in sourceOrTargetOrOptions));\n\n\t\tif (\n\t\t\tisFirstMedia &&\n\t\t\ttargetOrOptions &&\n\t\t\ttypeof targetOrOptions === \"object\" &&\n\t\t\t\"bounds\" in targetOrOptions\n\t\t) {\n\t\t\tsource = sourceOrTargetOrOptions as string | MediaNode;\n\t\t\ttarget = targetOrOptions as ObjectTrackSignals;\n\t\t\topts = options ?? {};\n\t\t} else if (isFirstMedia && targetOrOptions) {\n\t\t\tsource = sourceOrTargetOrOptions as string | MediaNode;\n\t\t\topts = targetOrOptions as SectionOptions;\n\t\t} else if (isFirstTrack) {\n\t\t\ttarget = sourceOrTargetOrOptions as ObjectTrackSignals;\n\t\t\topts = (targetOrOptions as SectionOptions) ?? {};\n\t\t\tsource = opts.source ?? (target.source as string | MediaNode | undefined);\n\t\t} else if (\n\t\t\tsourceOrTargetOrOptions &&\n\t\t\ttypeof sourceOrTargetOrOptions === \"object\"\n\t\t) {\n\t\t\topts = sourceOrTargetOrOptions as SectionOptions;\n\t\t\tsource = opts.source;\n\t\t}\n\n\t\tif (!source) {\n\t\t\tconst mediaChild = this.children.find(\n\t\t\t\t(c) =>\n\t\t\t\t\tc.kind === \"media\" &&\n\t\t\t\t\t(c.dataType === \"Video\" || c.dataType === \"Image\"),\n\t\t\t) as MediaNode | undefined;\n\t\t\tif (mediaChild) {\n\t\t\t\tsource = mediaChild;\n\t\t\t}\n\t\t}\n\n\t\treturn Layer.section(source ?? \"\", target ?? opts, {\n\t\t\tcompositionWidth: this.width,\n\t\t\tcompositionHeight: this.height,\n\t\t\t...opts,\n\t\t});\n\t}\n\n\t/**\n\t * Creates a section and immediately adds it to the composition layout tree.\n\t */\n\tpublic addSection(\n\t\tsourceOrTargetOrOptions?:\n\t\t\t| string\n\t\t\t| MediaNode\n\t\t\t| ObjectTrackSignals\n\t\t\t| SectionOptions,\n\t\ttargetOrOptions?: ObjectTrackSignals | SectionOptions,\n\t\toptions?: SectionOptions,\n\t): SectionNode {\n\t\tconst node = this.section(\n\t\t\tsourceOrTargetOrOptions,\n\t\t\ttargetOrOptions,\n\t\t\toptions,\n\t\t);\n\t\tthis.add(node);\n\t\treturn node;\n\t}\n\n\t/**\n\t * Dynamically calculates composition duration from the longest media or animation layer.\n\t */\n\tpublic async computeDuration(): Promise<number> {\n\t\tif (this.durationMs !== undefined) return this.durationMs;\n\t\tlet maxDurationMs = 0;\n\t\tconst mediaSources: string[] = [];\n\n\t\tfor (const node of [...this.children, ...this.audioTracks]) {\n\t\t\tif (node.kind === \"media\") {\n\t\t\t\tconst src = node.inputHandleId;\n\t\t\t\tif (\n\t\t\t\t\ttypeof src === \"string\" &&\n\t\t\t\t\t(node.dataType === \"Video\" || node.dataType === \"Audio\")\n\t\t\t\t) {\n\t\t\t\t\tmediaSources.push(src);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (typeof node.durationFrames === \"number\") {\n\t\t\t\tconst start = typeof node.startFrame === \"number\" ? node.startFrame : 0;\n\t\t\t\tconst durMs = ((start + node.durationFrames) / this.fps) * 1000;\n\t\t\t\tif (durMs > maxDurationMs) maxDurationMs = durMs;\n\t\t\t}\n\t\t}\n\n\t\tfor (const src of mediaSources) {\n\t\t\ttry {\n\t\t\t\tconst input = await inputStore.acquire(src);\n\t\t\t\tconst sec = await input.computeDuration();\n\t\t\t\tif (Number.isFinite(sec) && sec > 0) {\n\t\t\t\t\tconst ms = Math.round(sec * 1000);\n\t\t\t\t\tif (ms > maxDurationMs) maxDurationMs = ms;\n\t\t\t\t}\n\t\t\t} catch (_) {}\n\t\t}\n\n\t\treturn maxDurationMs > 0 ? maxDurationMs : 5000;\n\t}\n\n\tpublic async registerFont(\n\t\toptionsOrFamilyOrSource: RegisterFontOptions | string,\n\t\tsource?: string | Uint8Array,\n\t): Promise<this> {\n\t\tconst reg = await FontManager.register(optionsOrFamilyOrSource, source);\n\t\tif (reg.filePath && !this.fonts.includes(reg.filePath)) {\n\t\t\tthis.fonts.push(reg.filePath);\n\t\t}\n\t\treturn this;\n\t}\n\n\t/** Sets the color emoji font; see {@link FontManager.registerEmojiFont}. */\n\tpublic async registerEmojiFont(source: string | Uint8Array): Promise<this> {\n\t\tawait FontManager.registerEmojiFont(source);\n\t\treturn this;\n\t}\n\n\tpublic toSpec(): CompositorProgramConfig {\n\t\tconst layoutItems: LayoutNode[] = [...this.children, ...this.audioTracks];\n\t\tconst registeredPaths = FontManager.getRegisteredFontPaths();\n\t\tconst mergedFonts = Array.from(\n\t\t\tnew Set([...this.fonts, ...registeredPaths]),\n\t\t);\n\t\treturn {\n\t\t\twidth: this.width,\n\t\t\theight: this.height,\n\t\t\tfps: this.fps,\n\t\t\tmode: \"Video\",\n\t\t\tbackgroundColor: this.backgroundColor,\n\t\t\t...(this.antialias3d !== undefined && { antialias3d: this.antialias3d }),\n\t\t\tlayout: layoutItems,\n\t\t\tfonts: mergedFonts,\n\t\t\tsignals: this.signals,\n\t\t\t...(this._effects.length > 0 && { effects: this._effects }),\n\t\t\t...(this._visionConfig && { vision: this._visionConfig }),\n\t\t\t...(this._frameHooks.length > 0 && {\n\t\t\t\tonRequestFrame: (ctx: FrameContext) => this.notifyFrame(ctx),\n\t\t\t}),\n\t\t} as unknown as CompositorProgramConfig;\n\t}\n\n\t/**\n\t * Compiles the composition into a VirtualMediaData AST ready for WebGPU rendering.\n\t */\n\tpublic toVirtualMedia(\n\t\toptions: Partial<CompositorToProgramOptions> = {},\n\t): VirtualMediaData {\n\t\treturn compositorToProgram(this.toSpec(), {\n\t\t\tisVideoMode: true,\n\t\t\tfps: this.fps,\n\t\t\tdurationMs: options.durationMs ?? this.durationMs,\n\t\t\tsignals: options.signals ?? this.signals,\n\t\t\t...(this._effects.length > 0 && { effects: this._effects }),\n\t\t\t...(this._visionConfig && { vision: this._visionConfig }),\n\t\t\t...options,\n\t\t});\n\t}\n\n\t/**\n\t * Compiles the composition into a VirtualMediaData AST with dynamically resolved duration.\n\t */\n\tpublic async toVirtualMediaAsync(\n\t\toptions: Partial<CompositorToProgramOptions> = {},\n\t): Promise<VirtualMediaData> {\n\t\tconst durationMs =\n\t\t\toptions.durationMs ?? this.durationMs ?? (await this.computeDuration());\n\t\tthis.durationMs = durationMs;\n\t\treturn compositorToProgram(this.toSpec(), {\n\t\t\tisVideoMode: true,\n\t\t\tfps: this.fps,\n\t\t\tdurationMs,\n\t\t\tsignals: options.signals ?? this.signals,\n\t\t\t...(this._effects.length > 0 && { effects: this._effects }),\n\t\t\t...(this._visionConfig && { vision: this._visionConfig }),\n\t\t\t...options,\n\t\t});\n\t}\n\n\t/**\n\t * Renders a single frame from the composition to a PNG Buffer.\n\t * Can render either by timestamp in milliseconds (`atMs`) or by frame index (`frame`).\n\t */\n\tpublic async renderFrame(\n\t\toptions: {\n\t\t\tatMs?: number;\n\t\t\tframe?: number;\n\t\t\trenderer?: HeadlessMediaRenderer;\n\t\t} = {},\n\t): Promise<Buffer> {\n\t\tif (this._frameHooks.length > 0) {\n\t\t\tconst targetFrame =\n\t\t\t\toptions.frame ??\n\t\t\t\t(options.atMs !== undefined\n\t\t\t\t\t? Math.round((options.atMs / 1000) * this.fps)\n\t\t\t\t\t: 0);\n\t\t\tthis.notifyFrame({\n\t\t\t\tframe: targetFrame,\n\t\t\t\tfps: this.fps,\n\t\t\t\ttime: this.fps > 0 ? targetFrame / this.fps : 0,\n\t\t\t\tduration: (this.durationMs ?? 0) / 1000,\n\t\t\t\tdurationMs: this.durationMs ?? 0,\n\t\t\t\tprogress:\n\t\t\t\t\tthis.durationMs && this.durationMs > 0\n\t\t\t\t\t\t? Math.max(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tMath.min(\n\t\t\t\t\t\t\t\t\t1,\n\t\t\t\t\t\t\t\t\t((targetFrame / this.fps) * 1000) / this.durationMs,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: 0,\n\t\t\t\tdeltaTime: this.fps > 0 ? 1 / this.fps : 0,\n\t\t\t});\n\t\t}\n\t\tconst renderer = options.renderer ?? new HeadlessMediaRenderer();\n\t\treturn renderer.renderFrame(this.toVirtualMedia(), {\n\t\t\tfps: this.fps,\n\t\t\t...options,\n\t\t});\n\t}\n\n\t/**\n\t * Renders an image grid of sequential frames across a given frame or millisecond range.\n\t * Ideal for automated visual inspection of animation motion, easing curves, and layout stability.\n\t */\n\tpublic async renderFrameGrid(\n\t\toptions: FrameGridOptions = {},\n\t): Promise<Buffer> {\n\t\treturn renderFrameGrid(this, options);\n\t}\n\n\t/**\n\t * Renders this composition into an MP4/WebM video file with audio.\n\t */\n\tpublic async renderVideo(\n\t\toutputPathOrOptions: string | RenderVideoOptions = {},\n\t\toptions: RenderVideoOptions = {},\n\t): Promise<RenderVideoResult> {\n\t\tconst opts =\n\t\t\ttypeof outputPathOrOptions === \"string\"\n\t\t\t\t? { ...options, outputPath: outputPathOrOptions }\n\t\t\t\t: outputPathOrOptions;\n\t\tconst renderer = opts.renderer ?? new HeadlessMediaRenderer();\n\t\tconst result = await renderer.renderVideo(this.toVirtualMedia(), opts);\n\t\tif (result.qa) {\n\t\t\t// Fold the document checks into the output checks.\n\t\t\tconst lint = this.lint();\n\t\t\tconst issues = [\n\t\t\t\t...result.qa.issues,\n\t\t\t\t...lint.map((d) => ({\n\t\t\t\t\tseverity: d.severity,\n\t\t\t\t\tcode: d.code,\n\t\t\t\t\tmessage: d.message,\n\t\t\t\t\t...(d.layerId !== undefined && { layerId: d.layerId }),\n\t\t\t\t})),\n\t\t\t];\n\t\t\tresult.qa = {\n\t\t\t\t...result.qa,\n\t\t\t\tissues,\n\t\t\t\t// Lint warnings advise; only a lint error fails the render.\n\t\t\t\tpassed: result.qa.passed && !lint.some((d) => d.severity === \"error\"),\n\t\t\t};\n\t\t}\n\t\treturn deliverToOutputPath(result, opts.outputPath);\n\t}\n\n\t/**\n\t * Checks the document for things that render without error but not as\n\t * intended: unreadable colors or gradients (drawn transparent),\n\t * low-contrast text, layers parked off-canvas, shadows on lights that\n\t * cannot cast them, physical materials without an environment, tracks that\n\t * never change. `renderVideo({ qa })` includes these automatically.\n\t */\n\tpublic lint(): RenderDiagnostic[] {\n\t\treturn lintComposition(this.toSpec());\n\t}\n}\n\n/**\n * Layer helpers for constructing composition nodes with clean URL/path strings.\n */\n\nexport type AnimatableNode<T extends LayoutNode> = T & {\n\tglass?: Record<string, unknown>;\n\taudioDeform?: MeshAudioDeformConfig | Record<string, unknown>;\n\tcrop?: CropProps | Crop;\n\tvision?: Vision;\n\trelighting?: NormalRelightingOptions;\n\tdeflicker?: DeflickerOptions;\n\teffects?: unknown[];\n\tblurRegions?: unknown[];\n\t[key: string]: unknown;\n\tanimate(\n\t\t...anim: (\n\t\t\t| LayerAnimation\n\t\t\t| { tracks: AnimationTrack[] }\n\t\t\t| LayerAnimation[]\n\t\t)[]\n\t): AnimatableNode<T>;\n\tpinToLandmark(\n\t\ttarget:\n\t\t\t| LandmarkCoordinateSignals\n\t\t\t| {\n\t\t\t\t\tx: number;\n\t\t\t\t\ty: number;\n\t\t\t\t\tz?: number;\n\t\t\t\t\tscreenX?: number;\n\t\t\t\t\tscreenY?: number;\n\t\t\t },\n\t\toptions?: PinToLandmarkOptions,\n\t): AnimatableNode<T>;\n\tpinToObject(\n\t\ttarget:\n\t\t\t| ObjectTrackSignals\n\t\t\t| LandmarkCoordinateSignals\n\t\t\t| {\n\t\t\t\t\tx: number;\n\t\t\t\t\ty: number;\n\t\t\t\t\tz?: number;\n\t\t\t\t\tscreenX?: number;\n\t\t\t\t\tscreenY?: number;\n\t\t\t },\n\t\toptions?: PinToObjectOptions,\n\t): AnimatableNode<T>;\n\t/**\n\t * Track matte: `matte` (any layer) masks this one by its alpha or\n\t * brightness. It is laid out like a sibling (same parent) and timed with\n\t * this node; with no x/y/width/height it covers this node's box. Animate\n\t * the matte for wipes and reveals: text through a sliding box, video\n\t * inside type, an iris circle.\n\t */\n\twithMatte(matte: LayoutNode, mode?: MatteMode): AnimatableNode<T>;\n\t/** Alias of {@link withMatte}. */\n\twithMask(mask: LayoutNode, mode?: MatteMode): AnimatableNode<T>;\n\twithPbrGlass(options?: Record<string, unknown>): AnimatableNode<T>;\n\tdeformWithAudio(\n\t\tconfig?: MeshAudioDeformConfig | Record<string, unknown>,\n\t): AnimatableNode<T>;\n\twithCrop(cropConfig: CropProps | Crop): AnimatableNode<T>;\n\t/** Runs vision on this node's rendered output (see `Vision` for options and modes). */\n\twithVision(config?: VisionProps | Vision): AnimatableNode<T>;\n\twithRelighting(options?: NormalRelightingOptions): AnimatableNode<T>;\n\trelight(options?: NormalRelightingOptions): AnimatableNode<T>;\n\twithDeflicker(options?: DeflickerOptions): AnimatableNode<T>;\n\tapply(effect: unknown): AnimatableNode<T>;\n\twithEffect(effect: unknown): AnimatableNode<T>;\n\twithEffects(effects: unknown[]): AnimatableNode<T>;\n\tblurRegion(\n\t\ttrackTarget: ObjectTrackSignals,\n\t\toptions?: Partial<BlurProps>,\n\t): AnimatableNode<T>;\n\twithBlurRegion(\n\t\ttrackTarget: ObjectTrackSignals,\n\t\toptions?: Partial<BlurProps>,\n\t): AnimatableNode<T>;\n};\n\nfunction withAnimation<T extends LayoutNode>(node: T): AnimatableNode<T> {\n\tconst target = node as AnimatableNode<T>;\n\tObject.defineProperty(target, \"animate\", {\n\t\tvalue: (\n\t\t\t...anims: (\n\t\t\t\t| LayerAnimation\n\t\t\t\t| { tracks: AnimationTrack[] }\n\t\t\t\t| LayerAnimation[]\n\t\t\t)[]\n\t\t) => {\n\t\t\t// Every call layers onto what is already there: keyframe tracks on\n\t\t\t// the same prop merge (a later key wins on a shared frame).\n\t\t\tconst incoming = anims\n\t\t\t\t.flat()\n\t\t\t\t.flatMap((a) =>\n\t\t\t\t\ta instanceof LayerAnimation\n\t\t\t\t\t\t? a.tracks\n\t\t\t\t\t\t: ((a as { tracks?: AnimationTrack[] }).tracks ?? []),\n\t\t\t\t);\n\t\t\tconst existing =\n\t\t\t\t(target.animation as { tracks?: AnimationTrack[] } | undefined)\n\t\t\t\t\t?.tracks ?? [];\n\t\t\ttarget.animation = {\n\t\t\t\ttracks: mergeAnimationTracks([...existing, ...incoming]),\n\t\t\t};\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"pinToLandmark\", {\n\t\tvalue: (\n\t\t\tlandmarkTarget:\n\t\t\t\t| LandmarkCoordinateSignals\n\t\t\t\t| {\n\t\t\t\t\t\tx: number;\n\t\t\t\t\t\ty: number;\n\t\t\t\t\t\tz?: number;\n\t\t\t\t\t\tscreenX?: number;\n\t\t\t\t\t\tscreenY?: number;\n\t\t\t\t },\n\t\t\toptions?: PinToLandmarkOptions,\n\t\t) => {\n\t\t\tpinNodeToLandmark(\n\t\t\t\ttarget as unknown as { x?: unknown; y?: unknown; z?: unknown },\n\t\t\t\tlandmarkTarget,\n\t\t\t\toptions,\n\t\t\t);\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"pinToObject\", {\n\t\tvalue: (\n\t\t\tobjectTarget:\n\t\t\t\t| ObjectTrackSignals\n\t\t\t\t| LandmarkCoordinateSignals\n\t\t\t\t| {\n\t\t\t\t\t\tx: number;\n\t\t\t\t\t\ty: number;\n\t\t\t\t\t\tz?: number;\n\t\t\t\t\t\tscreenX?: number;\n\t\t\t\t\t\tscreenY?: number;\n\t\t\t\t },\n\t\t\toptions?: PinToObjectOptions,\n\t\t) => {\n\t\t\tpinNodeToObject(\n\t\t\t\ttarget as unknown as {\n\t\t\t\t\tx?: unknown;\n\t\t\t\t\ty?: unknown;\n\t\t\t\t\tz?: unknown;\n\t\t\t\t\twidth?: unknown;\n\t\t\t\t\theight?: unknown;\n\t\t\t\t\topacity?: unknown;\n\t\t\t\t},\n\t\t\t\tobjectTarget,\n\t\t\t\toptions,\n\t\t\t);\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tconst withMatte = (matte: LayoutNode, mode?: MatteMode) => {\n\t\ttarget.matte = { node: matte, ...(mode && { mode }) };\n\t\treturn target;\n\t};\n\tfor (const name of [\"withMatte\", \"withMask\"]) {\n\t\tObject.defineProperty(target, name, {\n\t\t\tvalue: withMatte,\n\t\t\tenumerable: false,\n\t\t\twritable: true,\n\t\t\tconfigurable: true,\n\t\t});\n\t}\n\n\tObject.defineProperty(target, \"withPbrGlass\", {\n\t\tvalue: (options?: Record<string, unknown>) => {\n\t\t\ttarget.glass = options ?? {};\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"deformWithAudio\", {\n\t\tvalue: (config?: MeshAudioDeformConfig | Record<string, unknown>) => {\n\t\t\ttarget.audioDeform = config ?? {};\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"withCrop\", {\n\t\tvalue: (cropConfig: CropProps | Crop) => {\n\t\t\ttarget.crop =\n\t\t\t\tcropConfig instanceof Crop ? cropConfig : new Crop(cropConfig);\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"withVision\", {\n\t\tvalue: (config?: VisionProps | Vision) => {\n\t\t\ttarget.vision = config instanceof Vision ? config : new Vision(config);\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"withRelighting\", {\n\t\tvalue: (options?: NormalRelightingOptions) => {\n\t\t\ttarget.relighting = options ?? {};\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"relight\", {\n\t\tvalue: (options?: NormalRelightingOptions) => {\n\t\t\ttarget.relighting = options ?? {};\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"withDeflicker\", {\n\t\tvalue: (options?: DeflickerOptions) => {\n\t\t\ttarget.deflicker = options ?? {};\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"apply\", {\n\t\tvalue: (effect: unknown) => {\n\t\t\tif (!target.effects) {\n\t\t\t\ttarget.effects = [];\n\t\t\t}\n\t\t\ttarget.effects.push(effect);\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"withEffect\", {\n\t\tvalue: (effect: unknown) => {\n\t\t\tif (!target.effects) {\n\t\t\t\ttarget.effects = [];\n\t\t\t}\n\t\t\ttarget.effects.push(effect);\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"withEffects\", {\n\t\tvalue: (effects: unknown[]) => {\n\t\t\tif (!target.effects) {\n\t\t\t\ttarget.effects = [];\n\t\t\t}\n\t\t\ttarget.effects.push(...effects);\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"section\", {\n\t\tvalue: (\n\t\t\ttargetOrOptions: ObjectTrackSignals | SectionOptions = {},\n\t\t\toptions?: SectionOptions,\n\t\t) => {\n\t\t\tif (\n\t\t\t\ttargetOrOptions !== null &&\n\t\t\t\ttypeof targetOrOptions === \"object\" &&\n\t\t\t\t\"bounds\" in targetOrOptions\n\t\t\t) {\n\t\t\t\treturn Layer.section(\n\t\t\t\t\ttarget as MediaNode,\n\t\t\t\t\ttargetOrOptions as ObjectTrackSignals,\n\t\t\t\t\toptions,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn Layer.section(\n\t\t\t\ttarget as MediaNode,\n\t\t\t\ttargetOrOptions as SectionOptions,\n\t\t\t);\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"blurRegion\", {\n\t\tvalue: (trackTarget: ObjectTrackSignals, options?: Partial<BlurProps>) => {\n\t\t\tconst blur = new Blur({\n\t\t\t\ttrack: trackTarget,\n\t\t\t\tstrength: options?.strength ?? 25,\n\t\t\t\tshape: options?.shape ?? \"ellipse\",\n\t\t\t\t...options,\n\t\t\t});\n\t\t\tif (!target.effects) {\n\t\t\t\ttarget.effects = [];\n\t\t\t}\n\t\t\ttarget.effects.push(blur);\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"withBlurRegion\", {\n\t\tvalue: (trackTarget: ObjectTrackSignals, options?: Partial<BlurProps>) => {\n\t\t\treturn (\n\t\t\t\ttarget as {\n\t\t\t\t\tblurRegion: (\n\t\t\t\t\t\tt: ObjectTrackSignals,\n\t\t\t\t\t\to?: Partial<BlurProps>,\n\t\t\t\t\t) => unknown;\n\t\t\t\t}\n\t\t\t).blurRegion(trackTarget, options);\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\treturn target;\n}\n\nexport const Layer = {\n\tvideo: (\n\t\tsrc: string,\n\t\toptions: Partial<MediaNode> = {},\n\t): AnimatableNode<MediaNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"video\"),\n\t\t\tkind: \"media\",\n\t\t\tinputHandleId: src,\n\t\t\tdataType: \"Video\",\n\t\t\tfit: options.fit ?? \"cover\",\n\t\t\t...options,\n\t\t}),\n\timage: (\n\t\tsrc: string,\n\t\toptions: Partial<MediaNode> = {},\n\t): AnimatableNode<MediaNode> => {\n\t\tif (typeof src === \"string\") {\n\t\t\tif (\n\t\t\t\t/\\.(json|lottie)(\\?.*)?$/i.test(src) ||\n\t\t\t\tsrc.startsWith(\"data:application/json\")\n\t\t\t) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[Layer.image] '${src}' is a Lottie vector animation, not a static image. Use Layer.lottie('${src}', options) instead.`,\n\t\t\t\t);\n\t\t\t} else if (/\\.(mp4|mov|webm|mkv)(\\?.*)?$/i.test(src)) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[Layer.image] '${src}' is a video file, not a static image. Use Layer.video('${src}', options) instead.`,\n\t\t\t\t);\n\t\t\t} else if (/\\.(mp3|wav|ogg|m4a|aac)(\\?.*)?$/i.test(src)) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[Layer.image] '${src}' is an audio file, not a static image. Use Layer.audio('${src}', options) instead.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\treturn withAnimation({\n\t\t\tid: options.id ?? autoId(\"img\"),\n\t\t\tkind: \"media\",\n\t\t\tinputHandleId: src,\n\t\t\tdataType: \"Image\",\n\t\t\tfit: options.fit ?? \"cover\",\n\t\t\t...options,\n\t\t});\n\t},\n\tsvg: (\n\t\tsrc: string,\n\t\toptions: Partial<MediaNode> = {},\n\t): AnimatableNode<MediaNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"svg\"),\n\t\t\tkind: \"media\",\n\t\t\tinputHandleId: src,\n\t\t\tdataType: \"SVG\",\n\t\t\tfit: options.fit ?? \"contain\",\n\t\t\t...options,\n\t\t}),\n\tlottie: (\n\t\tsrc: string,\n\t\toptions: Partial<MediaNode> = {},\n\t): AnimatableNode<MediaNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"lottie\"),\n\t\t\tkind: \"media\",\n\t\t\tinputHandleId: src,\n\t\t\tdataType: \"Lottie\",\n\t\t\tfit: options.fit ?? \"contain\",\n\t\t\t...options,\n\t\t}),\n\taudio: (\n\t\tsrc: string,\n\t\toptions: Partial<MediaNode> = {},\n\t): AnimatableNode<MediaNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"audio\"),\n\t\t\tkind: \"media\",\n\t\t\tinputHandleId: src,\n\t\t\tdataType: \"Audio\",\n\t\t\tvolume: options.volume ?? 1,\n\t\t\t...options,\n\t\t}),\n\ttext: (\n\t\tcontentOrOptions:\n\t\t\t| string\n\t\t\t| TextSpan[]\n\t\t\t| (string | TextSpan)[]\n\t\t\t| Partial<TextNode>,\n\t\tmaybeOptions: Partial<TextNode> = {},\n\t): AnimatableNode<TextNode> => {\n\t\tconst isArray = Array.isArray(contentOrOptions);\n\t\tconst isObj =\n\t\t\t!isArray &&\n\t\t\ttypeof contentOrOptions === \"object\" &&\n\t\t\tcontentOrOptions !== null;\n\t\tconst options = isObj\n\t\t\t? (contentOrOptions as Partial<TextNode>)\n\t\t\t: maybeOptions;\n\n\t\tlet textContent = \"\";\n\t\tlet spans: TextSpan[] | undefined = options.spans;\n\n\t\tif (isArray) {\n\t\t\tconst normalized = normalizeTextSpans(\n\t\t\t\tcontentOrOptions as (string | TextSpan)[],\n\t\t\t);\n\t\t\ttextContent = normalized.text;\n\t\t\tspans = normalized.spans;\n\t\t} else if (isObj) {\n\t\t\tif (options.spans && !options.text) {\n\t\t\t\tconst normalized = normalizeTextSpans(options.spans);\n\t\t\t\ttextContent = normalized.text;\n\t\t\t} else {\n\t\t\t\ttextContent = (options.text as string) ?? \"\";\n\t\t\t}\n\t\t} else {\n\t\t\ttextContent =\n\t\t\t\ttypeof contentOrOptions === \"string\"\n\t\t\t\t\t? contentOrOptions\n\t\t\t\t\t: String(contentOrOptions ?? \"\");\n\t\t}\n\n\t\treturn withAnimation({\n\t\t\tid: options.id ?? autoId(\"text\"),\n\t\t\tkind: \"text\",\n\t\t\tfontFamily:\n\t\t\t\toptions.fontFamily ?? FontManager.getAll()[0]?.family ?? \"Inter\",\n\t\t\tfontSize: options.fontSize ?? 48,\n\t\t\tfill: options.fill ?? \"#ffffff\",\n\t\t\t...options,\n\t\t\ttext: options.text ?? textContent,\n\t\t\tspans: options.spans ?? spans,\n\t\t});\n\t},\n\tcaption: (\n\t\tsrc: string,\n\t\toptions: Partial<MediaNode> = {},\n\t): AnimatableNode<MediaNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"caption\"),\n\t\t\tkind: \"media\",\n\t\t\tinputHandleId: src,\n\t\t\tdataType: options.dataType ?? \"Caption\",\n\t\t\tfontFamily:\n\t\t\t\toptions.fontFamily ?? FontManager.getAll()[0]?.family ?? \"Inter\",\n\t\t\tfontSize: options.fontSize ?? 48,\n\t\t\tfill: options.fill ?? \"#ffffff\",\n\t\t\t...options,\n\t\t}),\n\tshape: (\n\t\tshapeType:\n\t\t\t| \"rect\"\n\t\t\t| \"circle\"\n\t\t\t| \"ellipse\"\n\t\t\t| \"polygon\"\n\t\t\t| \"star\"\n\t\t\t| \"arrow\"\n\t\t\t| \"path\" = \"rect\",\n\t\toptions: Partial<ShapeNode> & {\n\t\t\t/** Alias of `fillColor`: a color or a CSS gradient string. */\n\t\t\tfill?: string;\n\t\t} = {},\n\t): AnimatableNode<ShapeNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"shape\"),\n\t\t\tkind: \"shape\",\n\t\t\tshapeType: options.shapeType ?? shapeType,\n\t\t\t...options,\n\t\t\t// `fill` and `fillColor` are the same thing; either may hold a\n\t\t\t// color or a CSS gradient.\n\t\t\tfillColor: options.fillColor ?? options.fill ?? \"#3b82f6\",\n\t\t}),\n\tflex: (options: Partial<FlexNode> = {}): AnimatableNode<FlexNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"flex\"),\n\t\t\tkind: \"flex\",\n\t\t\tdir: options.dir ?? \"column\",\n\t\t\tchildren: options.children ?? [],\n\t\t\t...options,\n\t\t}),\n\tbox: (options: Partial<BoxNode> = {}): AnimatableNode<BoxNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"box\"),\n\t\t\tkind: \"box\",\n\t\t\tbackground: options.background ?? \"transparent\",\n\t\t\tchildren: options.children ?? [],\n\t\t\t...options,\n\t\t}),\n\tsection: (\n\t\tsource: string | MediaNode | Composition,\n\t\ttargetOrOptions: ObjectTrackSignals | SectionOptions = {},\n\t\toptions: SectionOptions = {},\n\t): SectionNode => {\n\t\tlet realSource: string | MediaNode = source as string | MediaNode;\n\t\tif (\n\t\t\tsource &&\n\t\t\ttypeof source === \"object\" &&\n\t\t\t\"toSpec\" in source &&\n\t\t\t\"children\" in source\n\t\t) {\n\t\t\tconst compMedia = (\n\t\t\t\t((source as Composition).children || []) as LayoutNode[]\n\t\t\t).find(\n\t\t\t\t(c) =>\n\t\t\t\t\tc.kind === \"media\" &&\n\t\t\t\t\t(c.dataType === \"Video\" || c.dataType === \"Image\"),\n\t\t\t) as MediaNode | undefined;\n\t\t\tif (compMedia) {\n\t\t\t\trealSource = compMedia;\n\t\t\t}\n\t\t}\n\n\t\tconst isTracked =\n\t\t\ttargetOrOptions !== null &&\n\t\t\ttypeof targetOrOptions === \"object\" &&\n\t\t\t\"bounds\" in targetOrOptions;\n\t\tconst opts: SectionOptions = isTracked\n\t\t\t? options\n\t\t\t: (targetOrOptions as SectionOptions);\n\t\tconst target = isTracked\n\t\t\t? (targetOrOptions as ObjectTrackSignals)\n\t\t\t: undefined;\n\n\t\tconst padding = opts.padding ?? 0;\n\t\tconst src =\n\t\t\ttypeof realSource === \"string\"\n\t\t\t\t? realSource\n\t\t\t\t: (realSource?.inputHandleId ??\n\t\t\t\t\t(realSource as { src?: string })?.src ??\n\t\t\t\t\t\"\");\n\t\tconst dataType =\n\t\t\ttypeof realSource === \"object\" && realSource?.dataType\n\t\t\t\t? realSource.dataType\n\t\t\t\t: \"Video\";\n\t\tconst compW =\n\t\t\t(opts.compositionWidth as number) ??\n\t\t\t(opts.compWidth as number) ??\n\t\t\t(isTracked ? (opts.width as number) : undefined) ??\n\t\t\t1920;\n\t\tconst compH =\n\t\t\t(opts.compositionHeight as number) ??\n\t\t\t(opts.compHeight as number) ??\n\t\t\t(isTracked ? (opts.height as number) : undefined) ??\n\t\t\t1080;\n\n\t\tconst effList: Effect[] = Array.isArray(opts.effects)\n\t\t\t? ([...opts.effects] as Effect[])\n\t\t\t: opts.effects\n\t\t\t\t? [opts.effects as Effect]\n\t\t\t\t: [];\n\n\t\tconst innerX = target\n\t\t\t? target.bounds.screenX.multiply(-1).add(padding)\n\t\t\t: typeof opts.x === \"number\"\n\t\t\t\t? -opts.x\n\t\t\t\t: opts.x &&\n\t\t\t\t\t\ttypeof (opts.x as { multiply?: unknown }).multiply === \"function\"\n\t\t\t\t\t? (opts.x as { multiply: (n: number) => unknown }).multiply(-1)\n\t\t\t\t\t: 0;\n\n\t\tconst innerY = target\n\t\t\t? target.bounds.screenY.multiply(-1).add(padding)\n\t\t\t: typeof opts.y === \"number\"\n\t\t\t\t? -opts.y\n\t\t\t\t: opts.y &&\n\t\t\t\t\t\ttypeof (opts.y as { multiply?: unknown }).multiply === \"function\"\n\t\t\t\t\t? (opts.y as { multiply: (n: number) => unknown }).multiply(-1)\n\t\t\t\t\t: 0;\n\n\t\tconst innerMedia = (\n\t\t\tdataType === \"Image\"\n\t\t\t\t? Layer.image(src, {\n\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\twidth: compW,\n\t\t\t\t\t\theight: compH,\n\t\t\t\t\t\tfit: opts.fit ?? \"cover\",\n\t\t\t\t\t\tx: innerX as number,\n\t\t\t\t\t\ty: innerY as number,\n\t\t\t\t\t})\n\t\t\t\t: Layer.video(src, {\n\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\twidth: compW,\n\t\t\t\t\t\theight: compH,\n\t\t\t\t\t\tfit: opts.fit ?? \"cover\",\n\t\t\t\t\t\tx: innerX as number,\n\t\t\t\t\t\ty: innerY as number,\n\t\t\t\t\t})\n\t\t).withEffects(effList);\n\n\t\tconst boxWidth = target\n\t\t\t? target.bounds.screenWidth.add(padding * 2)\n\t\t\t: opts.width !== undefined\n\t\t\t\t? opts.width\n\t\t\t\t: compW;\n\n\t\tconst boxHeight = target\n\t\t\t? target.bounds.screenHeight.add(padding * 2)\n\t\t\t: opts.height !== undefined\n\t\t\t\t? opts.height\n\t\t\t\t: compH;\n\n\t\tconst boxChildren = [innerMedia, ...(opts.children ?? [])];\n\n\t\tconst boxId =\n\t\t\topts.id ??\n\t\t\t(target ? autoId(`section-track-${target.trackId}`) : autoId(\"section\"));\n\n\t\tlet box = Layer.box({\n\t\t\tid: boxId,\n\t\t\tposition: (opts.position as \"absolute\" | \"relative\") ?? \"absolute\",\n\t\t\twidth: boxWidth as number,\n\t\t\theight: boxHeight as number,\n\t\t\tx: target ? undefined : (opts.x as number),\n\t\t\ty: target ? undefined : (opts.y as number),\n\t\t\tborderRadius: opts.borderRadius ?? 0,\n\t\t\tborderColor: opts.borderColor,\n\t\t\tborderWidth: opts.borderWidth,\n\t\t\topacity: (opts.opacity as number) ?? 1,\n\t\t\toverflow: \"hidden\",\n\t\t\tchildren: boxChildren,\n\t\t});\n\n\t\tif (target) {\n\t\t\tbox = box.pinToObject(target, {\n\t\t\t\tanchor: \"topLeft\",\n\t\t\t\toffsetX: -padding,\n\t\t\t\toffsetY: -padding,\n\t\t\t\thideWhenLost: opts.hideWhenLost ?? true,\n\t\t\t\tsmoothFrames: opts.smoothFrames,\n\t\t\t});\n\t\t}\n\n\t\tconst sectionNode = box as SectionNode;\n\t\tObject.defineProperty(sectionNode, \"innerMedia\", {\n\t\t\tvalue: innerMedia,\n\t\t\tenumerable: true,\n\t\t\twritable: false,\n\t\t});\n\t\tObject.defineProperty(sectionNode, \"effects\", {\n\t\t\tget: () => effList,\n\t\t\tenumerable: true,\n\t\t});\n\t\tObject.defineProperty(sectionNode, \"addEffect\", {\n\t\t\tvalue: (effect: Effect) => {\n\t\t\t\teffList.push(effect);\n\t\t\t\tinnerMedia.effects = effList;\n\t\t\t\treturn sectionNode;\n\t\t\t},\n\t\t\tenumerable: true,\n\t\t\twritable: false,\n\t\t});\n\t\tObject.defineProperty(sectionNode, \"withEffect\", {\n\t\t\tvalue: (effect: Effect) => sectionNode.addEffect(effect),\n\t\t\tenumerable: true,\n\t\t\twritable: false,\n\t\t});\n\t\tObject.defineProperty(sectionNode, \"withEffects\", {\n\t\t\tvalue: (effects: Effect[]) => {\n\t\t\t\tfor (const eff of effects) {\n\t\t\t\t\tsectionNode.addEffect(eff);\n\t\t\t\t}\n\t\t\t\treturn sectionNode;\n\t\t\t},\n\t\t\tenumerable: true,\n\t\t\twritable: false,\n\t\t});\n\n\t\treturn sectionNode;\n\t},\n\ttrackedRegion: (\n\t\tsource: string | MediaNode,\n\t\ttarget: ObjectTrackSignals,\n\t\toptions: TrackedRegionOptions = {},\n\t): SectionNode => {\n\t\treturn Layer.section(source, target, options);\n\t},\n\tblurTrackedRegion: (\n\t\tsource: string | MediaNode,\n\t\ttarget: ObjectTrackSignals,\n\t\toptions: Partial<BlurProps> & {\n\t\t\tborderRadius?: number;\n\t\t\tpadding?: number;\n\t\t\tborderColor?: string;\n\t\t\tborderWidth?: number;\n\t\t} = {},\n\t): SectionNode => {\n\t\t// Section styling is not a Blur prop; keep it out of the effect config.\n\t\tconst { padding, borderRadius, borderColor, borderWidth, ...blurOptions } =\n\t\t\toptions;\n\t\treturn Layer.section(source, target, {\n\t\t\tpadding: padding ?? 8,\n\t\t\tborderRadius: borderRadius ?? 12,\n\t\t\tborderColor,\n\t\t\tborderWidth,\n\t\t\teffects: [\n\t\t\t\tnew Blur({\n\t\t\t\t\tstrength: blurOptions.strength ?? 25,\n\t\t\t\t\tblurType: blurOptions.blurType ?? \"Gaussian\",\n\t\t\t\t\t...blurOptions,\n\t\t\t\t}),\n\t\t\t],\n\t\t});\n\t},\n\t/**\n\t * A line, area, bar, scatter, candlestick, pie or donut chart. Returns a box\n\t * of ordinary nodes (bars are boxes, lines and slices are path shapes,\n\t * labels are text), so it positions, animates and composites like any layer.\n\t * `props` applies to that box: position, id, timing, effects.\n\t */\n\tchart: (\n\t\toptions: ChartOptions,\n\t\tprops: Partial<BoxNode> = {},\n\t): AnimatableNode<BoxNode> =>\n\t\tbuildChart(options, props, FontManager.getAll()[0]?.family ?? \"Inter\"),\n\tcamera: (options: Partial<CameraNode> = {}): AnimatableNode<CameraNode> =>\n\t\twithAnimation<CameraNode>({\n\t\t\tid: options.id ?? autoId(\"camera\"),\n\t\t\tkind: \"camera\",\n\t\t\tmode: options.mode ?? \"lookAt\",\n\t\t\tpitch: options.pitch ?? 0,\n\t\t\tyaw: options.yaw ?? 0,\n\t\t\troll: options.roll ?? 0,\n\t\t\t...options,\n\t\t}),\n\tlight: (options: Partial<LightNode> = {}): AnimatableNode<LightNode> =>\n\t\twithAnimation<LightNode>({\n\t\t\tid: options.id ?? autoId(\"light\"),\n\t\t\tkind: \"light\",\n\t\t\tlightType: options.lightType ?? \"point\",\n\t\t\tcolor: options.color ?? \"#ffffff\",\n\t\t\tintensity: options.intensity ?? 1.0,\n\t\t\t...options,\n\t\t}),\n\tambientLight: (\n\t\tcolor: string = \"#ffffff\",\n\t\tintensity: number = 0.5,\n\t\toptions: Partial<LightNode> = {},\n\t): AnimatableNode<LightNode> => Light.ambient(color, intensity, options),\n\t/**\n\t * Scenes back to back with transitions between them; see `Transition`.\n\t * `comp.add(Layer.sequence([{ scene: hero(), duration: 90 },\n\t * { scene: next(), duration: 120, transition: Transition.push(\"left\") }]))`.\n\t * The result's `totalFrames` is the sequence length.\n\t */\n\tsequence: (\n\t\tentries: SequenceEntry[],\n\t\toptions?: SceneSequenceOptions,\n\t): SequenceNode => sequence(entries, options),\n\t/** See {@link Light.environment}: `Layer.environment(\"studio\", { exposure: 0.3 })`. */\n\tenvironment: (\n\t\tpresetOrOptions: EnvironmentPreset | EnvironmentOptions = \"studio\",\n\t\toptions: EnvironmentOptions = {},\n\t): AnimatableNode<LightNode> => Light.environment(presetOrOptions, options),\n\tdirectionalLight: (\n\t\toptions: Partial<LightNode> = {},\n\t): AnimatableNode<LightNode> => Light.directional(options),\n\tpointLight: (options: Partial<LightNode> = {}): AnimatableNode<LightNode> =>\n\t\tLight.point(options),\n\tspotLight: (options: Partial<LightNode> = {}): AnimatableNode<LightNode> =>\n\t\tLight.spot(options),\n\tcube: (options: Cube3DOptions): AnimatableNode<BoxNode> =>\n\t\tLayer3D.cube(options),\n\tcarousel3d: (options: Carousel3DOptions): AnimatableNode<BoxNode> =>\n\t\tLayer3D.carousel(options),\n\tplane3d: (options: Plane3DOptions): AnimatableNode<BoxNode> =>\n\t\tLayer3D.plane(options),\n\tprism3d: (options: Prism3DOptions): AnimatableNode<BoxNode> =>\n\t\tLayer3D.prism(options),\n\tmodel: (options: Partial<Model3DNode> = {}): AnimatableNode<Model3DNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"model3d\"),\n\t\t\tkind: \"model3d\",\n\t\t\tis3D: options.is3D ?? true,\n\t\t\tmodelFormat: options.modelFormat ?? \"auto\",\n\t\t\tloop: options.loop ?? true,\n\t\t\tscale: options.scale ?? 1.0,\n\t\t\tscaleX: options.scaleX ?? 1.0,\n\t\t\tscaleY: options.scaleY ?? 1.0,\n\t\t\tscaleZ: options.scaleZ ?? 1.0,\n\t\t\topacity: options.opacity ?? 1.0,\n\t\t\t// material and twoSided stay unset unless given: the model's own\n\t\t\t// materials (toon, single-sided, …) decide, falling back to lit.\n\t\t\t...options,\n\t\t}),\n\tobj: (\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> =>\n\t\tLayer.model({\n\t\t\tsrc,\n\t\t\tmodelFormat: \"obj\",\n\t\t\t...options,\n\t\t}),\n\tfbx: (\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> =>\n\t\tLayer.model({\n\t\t\tsrc,\n\t\t\tmodelFormat: \"fbx\",\n\t\t\t...options,\n\t\t}),\n\tgltf: (\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> =>\n\t\tLayer.model({\n\t\t\tsrc,\n\t\t\tmodelFormat: \"gltf\",\n\t\t\t...options,\n\t\t}),\n\tglb: (\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> =>\n\t\tLayer.model({\n\t\t\tsrc,\n\t\t\tmodelFormat: \"glb\",\n\t\t\t...options,\n\t\t}),\n\tstl: (\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> =>\n\t\tLayer.model({\n\t\t\tsrc,\n\t\t\tmodelFormat: \"stl\",\n\t\t\t...options,\n\t\t}),\n\tply: (\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> =>\n\t\tLayer.model({\n\t\t\tsrc,\n\t\t\tmodelFormat: \"ply\",\n\t\t\t...options,\n\t\t}),\n\tvox: (\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> =>\n\t\tLayer.model({\n\t\t\tsrc,\n\t\t\tmodelFormat: \"vox\",\n\t\t\t...options,\n\t\t}),\n\tthreeDS: (\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> =>\n\t\tLayer.model({\n\t\t\tsrc,\n\t\t\tmodelFormat: \"3ds\",\n\t\t\t...options,\n\t\t}),\n\toff: (\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> =>\n\t\tLayer.model({\n\t\t\tsrc,\n\t\t\tmodelFormat: \"off\",\n\t\t\t...options,\n\t\t}),\n};\n\n/** World settings for `Layer.environment` (see `LightNode` for every field). */\nexport type EnvironmentOptions = Partial<\n\tPick<\n\t\tLightNode,\n\t\t| \"id\"\n\t\t| \"preset\"\n\t\t| \"top\"\n\t\t| \"horizon\"\n\t\t| \"bottom\"\n\t\t| \"intensity\"\n\t\t| \"softboxes\"\n\t\t| \"rotation\"\n\t\t| \"exposure\"\n\t\t| \"toneMapping\"\n\t\t| \"fog\"\n\t\t| \"bloom\"\n\t\t| \"startFrame\"\n\t\t| \"durationFrames\"\n\t>\n>;\n\nexport const Light = {\n\t/**\n\t * The scene's world: a procedural studio environment that lights and\n\t * reflects off every surface, plus exposure, tone mapping and fog. Adding\n\t * one switches the scene to physically based shading (GGX, real\n\t * `roughness` / `metallic`, `emissive` that blooms past white).\n\t */\n\tenvironment: (\n\t\tpresetOrOptions: EnvironmentPreset | EnvironmentOptions = \"studio\",\n\t\toptions: EnvironmentOptions = {},\n\t): AnimatableNode<LightNode> => {\n\t\tconst opts =\n\t\t\ttypeof presetOrOptions === \"string\"\n\t\t\t\t? { preset: presetOrOptions, ...options }\n\t\t\t\t: { ...presetOrOptions, ...options };\n\t\treturn withAnimation({\n\t\t\tkind: \"light\",\n\t\t\tlightType: \"environment\",\n\t\t\tpreset: \"studio\",\n\t\t\tintensity: 1,\n\t\t\t...opts,\n\t\t\tid: opts.id ?? autoId(\"environment\"),\n\t\t});\n\t},\n\tambient: (\n\t\tcolor: string = \"#ffffff\",\n\t\tintensity: number = 0.5,\n\t\toptions: Partial<LightNode> = {},\n\t): AnimatableNode<LightNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"light-ambient\"),\n\t\t\tkind: \"light\",\n\t\t\tlightType: \"ambient\",\n\t\t\tcolor,\n\t\t\tintensity,\n\t\t\t...options,\n\t\t}),\n\tdirectional: (options: Partial<LightNode> = {}): AnimatableNode<LightNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"light-directional\"),\n\t\t\tkind: \"light\",\n\t\t\tlightType: \"directional\",\n\t\t\tcolor: options.color ?? \"#ffffff\",\n\t\t\tintensity: options.intensity ?? 1.0,\n\t\t\tx: options.x ?? 0,\n\t\t\ty: options.y ?? -1000,\n\t\t\tz: options.z ?? -1000,\n\t\t\ttargetX: options.targetX ?? 0,\n\t\t\ttargetY: options.targetY ?? 0,\n\t\t\ttargetZ: options.targetZ ?? 0,\n\t\t\t...options,\n\t\t}),\n\tpoint: (options: Partial<LightNode> = {}): AnimatableNode<LightNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"light-point\"),\n\t\t\tkind: \"light\",\n\t\t\tlightType: \"point\",\n\t\t\tcolor: options.color ?? \"#ffffff\",\n\t\t\tintensity: options.intensity ?? 1.0,\n\t\t\tx: options.x ?? 0,\n\t\t\ty: options.y ?? 0,\n\t\t\tz: options.z ?? -500,\n\t\t\tradius: options.radius ?? 1000,\n\t\t\tdecay: options.decay ?? 1.0,\n\t\t\t...options,\n\t\t}),\n\tspot: (options: Partial<LightNode> = {}): AnimatableNode<LightNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"light-spot\"),\n\t\t\tkind: \"light\",\n\t\t\tlightType: \"spot\",\n\t\t\tcolor: options.color ?? \"#ffffff\",\n\t\t\tintensity: options.intensity ?? 1.0,\n\t\t\tx: options.x ?? 0,\n\t\t\ty: options.y ?? -500,\n\t\t\tz: options.z ?? -1000,\n\t\t\ttargetX: options.targetX ?? 0,\n\t\t\ttargetY: options.targetY ?? 0,\n\t\t\ttargetZ: options.targetZ ?? 0,\n\t\t\tangle: options.angle ?? 45,\n\t\t\tpenumbra: options.penumbra ?? 0.2,\n\t\t\tradius: options.radius ?? 2000,\n\t\t\tdecay: options.decay ?? 1.0,\n\t\t\t...options,\n\t\t}),\n};\n\nexport {\n\ttype PreviewCloseReason,\n\ttype PreviewOptions,\n\ttype PreviewSession,\n\ttype PreviewSource,\n\tstartPreview,\n} from \"./preview/index.js\";\nexport {\n\ttype AudioQaStats,\n\tcomputeGridLayout,\n\tdescribeGpu,\n\ttype FrameGridOptions,\n\ttype FrameGridRenderable,\n\ttype FrameSamplePoint,\n\tformatQaReport,\n\ttype GpuAdapterDescription,\n\tHeadlessMediaRenderer,\n\tHeadlessWebGPURenderer,\n\ttype QaIssue,\n\ttype QaSegment,\n\ttype RenderProgress,\n\trenderFrameGrid,\n\trenderSemaphore,\n\tresetRenderCaches,\n\tresolveSamplePoints,\n\ttype VideoQaOptions,\n\ttype VideoQaReport,\n\ttype VideoQaStats,\n} from \"./renderer/index.js\";\n\nexport function section(\n\tsource: string | MediaNode | Composition,\n\ttargetOrOptions: ObjectTrackSignals | SectionOptions = {},\n\toptions: SectionOptions = {},\n): SectionNode {\n\treturn Layer.section(source, targetOrOptions, options);\n}\n\nexport function blurRegion(\n\tsourceOrLayer: string | AnimatableNode<MediaNode>,\n\ttarget: ObjectTrackSignals,\n\toptions: Partial<BlurProps> & {\n\t\tborderRadius?: number;\n\t\tpadding?: number;\n\t\tborderColor?: string;\n\t\tborderWidth?: number;\n\t} = {},\n): AnimatableNode<MediaNode> | AnimatableNode<BoxNode> {\n\tif (typeof sourceOrLayer === \"object\" && \"blurRegion\" in sourceOrLayer) {\n\t\treturn (sourceOrLayer as AnimatableNode<MediaNode>).blurRegion(\n\t\t\ttarget,\n\t\t\toptions,\n\t\t);\n\t}\n\treturn Layer.blurTrackedRegion(sourceOrLayer as string, target, options);\n}\n\nexport function editTrackedRegion(\n\tsource: string | MediaNode,\n\ttarget: ObjectTrackSignals,\n\toptions: TrackedRegionOptions = {},\n): SectionNode {\n\treturn Layer.section(source, target, options);\n}\n\nexport const Effect = Object.assign(CoreEffect, effectFactories, {\n\tblur: (config?: BlurProps) => new Blur(config),\n\tvignette: (config?: VignetteProps) => new Vignette(config),\n\tcolorBalance: (config?: ColorBalanceProps) => new ColorBalance(config),\n\tcolorKey: (config?: ColorKeyProps) => new ColorKey(config),\n\tlevels: (config?: LevelsProps) => new Levels(config),\n\tfilmGrain: (config?: FilmGrainProps) => new FilmGrain(config),\n\tcurves: (config?: CurvesProps) => new Curves(config),\n\tselectiveColor: (config?: SelectiveColorProps) => new SelectiveColor(config),\n\tgradientMap: (config?: GradientMapProps) => new GradientMap(config),\n\tshadowsHighlights: (config?: ShadowsHighlightsProps) =>\n\t\tnew ShadowsHighlights(config),\n\tapplyLut: (config?: ApplyLUTProps) => new ApplyLUT(config),\n\tunsharpMask: (config?: UnsharpMaskProps) => new UnsharpMask(config),\n\thighPass: (config?: HighPassProps) => new HighPass(config),\n\thalftoneScreen: (config?: HalftoneScreenProps) => new HalftoneScreen(config),\n\ttileOffset: (config?: TileOffsetProps) => new TileOffset(config),\n\tmotionBlur: (config?: MotionBlurProps) => new MotionBlur(config),\n\tssao: (config?: SSAOProps) => new SSAO(config),\n\tpbrGlass: (config?: PBRGlassProps) => new PBRGlass(config),\n\tdepthOfField: (config?: DepthOfFieldProps) => new DepthOfField(config),\n\tcrop: (config?: CropProps) => new Crop(config),\n\tvision: (config?: VisionProps) => new Vision(config),\n\trelight3d: (config?: Relight3DProps) => new Relight3D(config),\n\tmodulate: (config?: ModulateProps) => new Modulate(config),\n\tdeflicker: (config?: DeflickerProps) => new TemporalDeflicker(config),\n\tcustom: (op: string, config: Record<string, unknown> = {}) =>\n\t\tnew CustomEffect(op, config),\n});\n\nexport type Effect<TConfig extends object = Record<string, unknown>> =\n\tCoreEffect<TConfig>;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["stack","num","color","d3Format","d3Pie","d3Arc","x","d3Stack","range","lo","hi","d","d3Area","d3Line","fs","path","size","stack","anim","Effect","spec","size","color","line","spec","R","spec","spec","scaleShape","num","dist","spec","h","size","resolvedSource","analyzeVisionFrames","signal","color","CoreEffect"],"sources":["../src/ids.ts","../src/rich-text.ts","../src/chart.ts","../src/clip-vision.ts","../src/physics/core.ts","../src/particles.ts","../src/shapes3d.ts","../src/transitions.ts","../src/lighting.ts","../src/physics/backend.ts","../src/physics/world2d.ts","../src/physics/world3d.ts","../src/physics/index.ts","../src/styles.ts","../src/index.ts"],"sourcesContent":["/**\n * Default ids for nodes created without one. A counter per prefix rather than\n * a random suffix: the same composition script builds the same ids on every\n * run and in every render worker, so specs, caches and diffs stay stable.\n */\nconst counters = new Map<string, number>();\n\nexport function autoId(prefix: string): string {\n\tconst n = (counters.get(prefix) ?? 0) + 1;\n\tcounters.set(prefix, n);\n\treturn `${prefix}-auto-${n}`;\n}\n","import type { Signal, TextSpan, TextSpanMark } from \"@framefields/core\";\n\nexport type { TextSpan, TextSpanMark };\n\nexport type TextSpanItem =\n\t| string\n\t| number\n\t| boolean\n\t| Signal<unknown>\n\t| TextSpan\n\t| (string | TextSpan)[]\n\t| null\n\t| undefined;\n\n/**\n * Tagged template literal for authoring rich, multi-style text runs.\n *\n * Interpolates strings, numbers, reactive signals, and typed span modifiers\n * directly into a structured TextSpan[] array with zero runtime parsing.\n *\n * @example\n * rich`Scale ${bold(\"10x\", { fill: \"#6366f1\" })} faster with ${mark(\"120 FPS\", { bg: \"#10b98133\" })}`\n */\nexport function rich(\n\tstrings: TemplateStringsArray,\n\t...values: TextSpanItem[]\n): TextSpan[] {\n\tconst spans: TextSpan[] = [];\n\n\tfor (let i = 0; i < strings.length; i++) {\n\t\tconst str = strings[i];\n\t\tif (str) {\n\t\t\tspans.push({ text: str });\n\t\t}\n\n\t\tif (i < values.length) {\n\t\t\tconst val = values[i];\n\t\t\tif (val === null || val === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (Array.isArray(val)) {\n\t\t\t\tfor (const item of val) {\n\t\t\t\t\tif (typeof item === \"string\") {\n\t\t\t\t\t\tif (item) spans.push({ text: item });\n\t\t\t\t\t} else if (item && typeof item === \"object\" && \"text\" in item) {\n\t\t\t\t\t\tspans.push(item as TextSpan);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (typeof val === \"object\" && \"text\" in val) {\n\t\t\t\tspans.push(val as TextSpan);\n\t\t\t} else if (\n\t\t\t\ttypeof val === \"object\" &&\n\t\t\t\t\"get\" in val &&\n\t\t\t\ttypeof (val as { get: unknown }).get === \"function\"\n\t\t\t) {\n\t\t\t\tspans.push({ text: val as Signal<string> });\n\t\t\t} else {\n\t\t\t\tspans.push({ text: String(val) });\n\t\t\t}\n\t\t}\n\t}\n\n\treturn spans;\n}\n\nexport function span(\n\ttext: string | Signal<string>,\n\toptions: Omit<TextSpan, \"text\"> = {},\n): TextSpan {\n\treturn { text, ...options };\n}\n\nexport function bold(\n\ttext: string | Signal<string>,\n\toptions: Omit<TextSpan, \"text\"> = {},\n): TextSpan {\n\treturn { text, fontWeight: options.fontWeight ?? 700, ...options };\n}\n\nexport function italic(\n\ttext: string | Signal<string>,\n\toptions: Omit<TextSpan, \"text\"> = {},\n): TextSpan {\n\treturn { text, fontStyle: \"italic\", ...options };\n}\n\nexport function accent(\n\ttext: string | Signal<string>,\n\toptions: Omit<TextSpan, \"text\"> = {},\n): TextSpan {\n\treturn { text, fill: options.fill ?? \"#6366f1\", ...options };\n}\n\nexport function color(\n\ttext: string | Signal<string>,\n\tfill: string | Signal<string>,\n\toptions: Omit<TextSpan, \"text\" | \"fill\"> = {},\n): TextSpan {\n\treturn { text, fill, ...options };\n}\n\nexport function size(\n\ttext: string | Signal<string>,\n\tfontSize: number | Signal<number>,\n\toptions: Omit<TextSpan, \"text\" | \"fontSize\"> = {},\n): TextSpan {\n\treturn { text, fontSize, ...options };\n}\n\nexport interface MarkOptions extends Omit<TextSpan, \"text\" | \"mark\" | \"fill\"> {\n\tbg?: string | Signal<string>;\n\tfill?: string | Signal<string>;\n\tradius?: number;\n\tpaddingX?: number;\n\tpaddingY?: number;\n}\n\nexport function mark(\n\ttext: string | Signal<string>,\n\toptions: MarkOptions = {},\n): TextSpan {\n\tconst { bg, fill, radius, paddingX, paddingY, ...rest } = options;\n\treturn {\n\t\ttext,\n\t\tfill,\n\t\tmark: {\n\t\t\tbackground: bg ?? \"#6366f133\",\n\t\t\tborderRadius: radius ?? 4,\n\t\t\tpaddingX: paddingX ?? 6,\n\t\t\tpaddingY: paddingY ?? 2,\n\t\t},\n\t\t...rest,\n\t};\n}\n\nexport function sup(\n\ttext: string | Signal<string>,\n\toptions: Omit<TextSpan, \"text\"> = {},\n): TextSpan {\n\treturn {\n\t\ttext,\n\t\tbaselineShift: options.baselineShift ?? -8,\n\t\t...options,\n\t};\n}\n\nexport function sub(\n\ttext: string | Signal<string>,\n\toptions: Omit<TextSpan, \"text\"> = {},\n): TextSpan {\n\treturn {\n\t\ttext,\n\t\tbaselineShift: options.baselineShift ?? 6,\n\t\t...options,\n\t};\n}\n\nexport function code(\n\ttext: string | Signal<string>,\n\toptions: Omit<TextSpan, \"text\"> = {},\n): TextSpan {\n\treturn {\n\t\ttext,\n\t\tfontFamily: options.fontFamily ?? \"JetBrains Mono\",\n\t\tmark: options.mark ?? {\n\t\t\tbackground: \"#ffffff18\",\n\t\t\tborderRadius: 4,\n\t\t\tpaddingX: 6,\n\t\t\tpaddingY: 2,\n\t\t},\n\t\t...options,\n\t};\n}\n\n/**\n * Normalizes string, TextSpan[], or array of mixed strings/spans into plain text and spans.\n */\nexport function normalizeTextSpans(\n\tinput: string | TextSpan[] | (string | TextSpan)[],\n): { text: string; spans?: TextSpan[] } {\n\tif (typeof input === \"string\") {\n\t\treturn { text: input };\n\t}\n\n\tif (!Array.isArray(input)) {\n\t\treturn { text: String(input) };\n\t}\n\n\tconst spans: TextSpan[] = [];\n\tlet plainText = \"\";\n\n\tfor (const item of input) {\n\t\tif (typeof item === \"string\") {\n\t\t\tif (item) {\n\t\t\t\tspans.push({ text: item });\n\t\t\t\tplainText += item;\n\t\t\t}\n\t\t} else if (item && typeof item === \"object\" && \"text\" in item) {\n\t\t\tconst s = item as TextSpan;\n\t\t\tspans.push(s);\n\t\t\tconst piece =\n\t\t\t\ttypeof s.text === \"string\"\n\t\t\t\t\t? s.text\n\t\t\t\t\t: s.text &&\n\t\t\t\t\t\t\ttypeof s.text === \"object\" &&\n\t\t\t\t\t\t\t\"get\" in s.text &&\n\t\t\t\t\t\t\ttypeof (s.text as { get: () => unknown }).get === \"function\"\n\t\t\t\t\t\t? String((s.text as { get: () => unknown }).get())\n\t\t\t\t\t\t: String(s.text ?? \"\");\n\t\t\tplainText += piece;\n\t\t}\n\t}\n\n\treturn {\n\t\ttext: plainText,\n\t\tspans: spans.length > 0 ? spans : undefined,\n\t};\n}\n\n/**\n * Upfront parser for external CMS or subtitle strings containing basic tags\n * (<b>, <i>, <span>, <color>, <mark>, <accent>, <code>, <sup>, <sub>).\n *\n * Compiles string markup into clean TextSpan[] before entering the composition pipeline.\n */\nexport function parseMarkup(markup: string): TextSpan[] {\n\tif (!markup || !markup.includes(\"<\")) {\n\t\treturn [{ text: markup }];\n\t}\n\n\tconst spans: TextSpan[] = [];\n\tconst tagRegex = /<(\\/?[a-zA-Z0-9_-]+)([^>]*)>/g;\n\tlet lastIndex = 0;\n\n\tinterface StyleState {\n\t\ttag: string;\n\t\tstyle: Partial<TextSpan>;\n\t}\n\tconst stack: StyleState[] = [];\n\n\tconst getCurrentStyle = (): Partial<TextSpan> => {\n\t\tconst merged: Partial<TextSpan> = {};\n\t\tfor (const state of stack) {\n\t\t\tObject.assign(merged, state.style);\n\t\t}\n\t\treturn merged;\n\t};\n\n\tfor (;;) {\n\t\tconst match = tagRegex.exec(markup);\n\t\tif (!match) {\n\t\t\tbreak;\n\t\t}\n\t\tconst textBefore = markup.slice(lastIndex, match.index);\n\t\tif (textBefore) {\n\t\t\tspans.push({ text: textBefore, ...getCurrentStyle() });\n\t\t}\n\t\tlastIndex = match.index + match[0].length;\n\n\t\tconst tagName = match[1].toLowerCase();\n\t\tconst rawAttrs = match[2];\n\n\t\tif (tagName.startsWith(\"/\")) {\n\t\t\tconst closingTag = tagName.slice(1);\n\t\t\tfor (let i = stack.length - 1; i >= 0; i--) {\n\t\t\t\tif (stack[i].tag === closingTag) {\n\t\t\t\t\tstack.splice(i, 1);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconst attrs: Record<string, string> = {};\n\t\t\tconst attrRegex = /([a-zA-Z0-9_-]+)=[\"']([^\"']*)[\"']/g;\n\t\t\tfor (;;) {\n\t\t\t\tconst attrMatch = attrRegex.exec(rawAttrs);\n\t\t\t\tif (!attrMatch) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tattrs[attrMatch[1].toLowerCase()] = attrMatch[2];\n\t\t\t}\n\n\t\t\tconst style: Partial<TextSpan> = {};\n\n\t\t\tif (tagName === \"b\" || tagName === \"strong\") {\n\t\t\t\tstyle.fontWeight = 700;\n\t\t\t\tif (attrs.color || attrs.fill) style.fill = attrs.color ?? attrs.fill;\n\t\t\t} else if (tagName === \"i\" || tagName === \"em\") {\n\t\t\t\tstyle.fontStyle = \"italic\";\n\t\t\t\tif (attrs.color || attrs.fill) style.fill = attrs.color ?? attrs.fill;\n\t\t\t} else if (tagName === \"accent\") {\n\t\t\t\tstyle.fill = \"#6366f1\";\n\t\t\t} else if (tagName === \"color\") {\n\t\t\t\tstyle.fill = attrs.value ?? attrs.hex ?? attrs.fill;\n\t\t\t} else if (tagName === \"size\") {\n\t\t\t\tconst num = parseFloat(attrs.value ?? attrs.px ?? attrs.pt ?? \"0\");\n\t\t\t\tif (num > 0) style.fontSize = num;\n\t\t\t} else if (tagName === \"mark\") {\n\t\t\t\tstyle.mark = {\n\t\t\t\t\tbackground: attrs.bg ?? attrs.background ?? \"#6366f133\",\n\t\t\t\t\tborderRadius: attrs.radius ? parseFloat(attrs.radius) : 4,\n\t\t\t\t\tpaddingX: attrs.paddingx ? parseFloat(attrs.paddingx) : 6,\n\t\t\t\t\tpaddingY: attrs.paddingy ? parseFloat(attrs.paddingy) : 2,\n\t\t\t\t};\n\t\t\t\tif (attrs.color || attrs.fill) style.fill = attrs.color ?? attrs.fill;\n\t\t\t} else if (tagName === \"sup\") {\n\t\t\t\tstyle.baselineShift = -8;\n\t\t\t} else if (tagName === \"sub\") {\n\t\t\t\tstyle.baselineShift = 6;\n\t\t\t} else if (tagName === \"code\") {\n\t\t\t\tstyle.fontFamily = \"JetBrains Mono\";\n\t\t\t\tstyle.mark = {\n\t\t\t\t\tbackground: attrs.bg ?? \"#ffffff18\",\n\t\t\t\t\tborderRadius: 4,\n\t\t\t\t\tpaddingX: 6,\n\t\t\t\t\tpaddingY: 2,\n\t\t\t\t};\n\t\t\t} else if (tagName === \"span\") {\n\t\t\t\tif (attrs.color || attrs.fill) style.fill = attrs.color ?? attrs.fill;\n\t\t\t\tif (attrs.fontfamily) style.fontFamily = attrs.fontfamily;\n\t\t\t\tif (attrs.fontsize) style.fontSize = parseFloat(attrs.fontsize);\n\t\t\t\tif (attrs.fontweight) {\n\t\t\t\t\tconst nw = parseInt(attrs.fontweight, 10);\n\t\t\t\t\tstyle.fontWeight = Number.isNaN(nw) ? attrs.fontweight : nw;\n\t\t\t\t}\n\t\t\t\tif (attrs.fontstyle === \"italic\" || attrs.fontstyle === \"normal\") {\n\t\t\t\t\tstyle.fontStyle = attrs.fontstyle;\n\t\t\t\t}\n\t\t\t\tif (attrs.letterspacing)\n\t\t\t\t\tstyle.letterSpacing = parseFloat(attrs.letterspacing);\n\t\t\t\tif (attrs.baselineshift)\n\t\t\t\t\tstyle.baselineShift = parseFloat(attrs.baselineshift);\n\t\t\t\tif (attrs.opacity) style.opacity = parseFloat(attrs.opacity);\n\t\t\t}\n\n\t\t\tstack.push({ tag: tagName, style });\n\t\t}\n\t}\n\n\tconst remainingText = markup.slice(lastIndex);\n\tif (remainingText) {\n\t\tspans.push({ text: remainingText, ...getCurrentStyle() });\n\t}\n\n\treturn spans;\n}\n","/**\n * Charts built from ordinary layout nodes. d3 does the math (scales, ticks,\n * line/area/arc geometry, stacking); every bar, line, slice and label is a\n * regular box, shape or text node, so charts use the composition's fonts and\n * can be animated, graded and composited like any other layer.\n */\nimport {\n\ttype BoxNode,\n\tLayerAnimation,\n\ttype LayoutNode,\n} from \"@framefields/compositions/program\";\nimport { format as d3Format } from \"d3-format\";\nimport {\n\ttype ScaleBand,\n\ttype ScaleLinear,\n\ttype ScaleTime,\n\tscaleBand,\n\tscaleLinear,\n\tscaleUtc,\n} from \"d3-scale\";\nimport {\n\ttype CurveFactory,\n\tcurveLinear,\n\tcurveMonotoneX,\n\tcurveStepAfter,\n\tarc as d3Arc,\n\tarea as d3Area,\n\tline as d3Line,\n\tpie as d3Pie,\n\tstack as d3Stack,\n\tstackOffsetDiverging,\n} from \"d3-shape\";\nimport { autoId } from \"./ids.js\";\nimport { type AnimatableNode, Layer } from \"./index.js\";\n\nexport type ChartType =\n\t| \"line\"\n\t| \"area\"\n\t| \"bar\"\n\t| \"scatter\"\n\t| \"pie\"\n\t| \"donut\"\n\t| \"candlestick\";\n\nexport type ChartX = number | string | Date;\n\n/** A plain value (x is its index or `categories[i]`), an `[x, y]` pair, or `{ x, y }`. */\nexport type ChartDatum =\n\t| number\n\t| readonly [ChartX, number]\n\t| { x: ChartX; y: number };\n\nexport interface ChartCandle {\n\tx: ChartX;\n\topen: number;\n\thigh: number;\n\tlow: number;\n\tclose: number;\n}\n\n/** A pie or donut slice. */\nexport interface ChartSlice {\n\tlabel: string;\n\tvalue: number;\n\tcolor?: string;\n}\n\nexport interface ChartSeries {\n\tname?: string;\n\t/** Series type in a combined chart; defaults to the chart's `type`. */\n\ttype?: Exclude<ChartType, \"pie\" | \"donut\">;\n\tdata: readonly ChartDatum[] | readonly ChartCandle[];\n\tcolor?: string;\n\t/** Line width for line and area series. Default 3. */\n\tstrokeWidth?: number;\n\t/** Line and area interpolation. Default \"smooth\". */\n\tcurve?: \"linear\" | \"smooth\" | \"step\";\n\t/** Dot radius drawn on line points; scatter point radius. 0 hides line dots. */\n\tpointRadius?: number;\n}\n\nexport interface ChartAxisOptions {\n\t/** Show tick labels. Default true. */\n\tshow?: boolean;\n\t/** Draw grid lines across the plot. Default true for y, false for x. */\n\tgrid?: boolean;\n\tmin?: number;\n\tmax?: number;\n\t/** Approximate number of ticks. Default 5. */\n\tticks?: number;\n\t/** A d3-format specifier such as \",.0f\", \"$.2s\" or \".0%\", or a function. */\n\tformat?: string | ((value: ChartX) => string);\n}\n\nexport interface ChartAnimationOptions {\n\t/** Frame the reveal starts, relative to the chart's own start. Default 0. */\n\tstart?: number;\n\t/** Frames each element takes to animate in. Default 30. */\n\tduration?: number;\n\t/** Frames between consecutive bars, points or slices. Default spreads them over `duration`. */\n\tstagger?: number;\n\t/** Easing for bars, points and slices. Default \"power3.out\". */\n\tease?: string;\n}\n\nexport interface ChartPadding {\n\ttop?: number;\n\tright?: number;\n\tbottom?: number;\n\tleft?: number;\n}\n\nexport interface ChartOptions {\n\t/** Chart type, and the default for series without their own. Default \"line\". */\n\ttype?: ChartType;\n\twidth?: number;\n\theight?: number;\n\tseries?: readonly ChartSeries[];\n\t/** Shorthand for a single series, or the slices of a pie or donut. */\n\tdata?: readonly ChartDatum[] | readonly ChartCandle[] | readonly ChartSlice[];\n\t/** Labels for x positions when data are plain values; slice labels for pie charts. */\n\tcategories?: readonly string[];\n\t/** Stack bar and area series instead of grouping or overlapping them. */\n\tstacked?: boolean;\n\tcolors?: readonly string[];\n\txAxis?: ChartAxisOptions;\n\tyAxis?: ChartAxisOptions;\n\t/** Space around the plot for axis labels and legend. Computed when omitted. */\n\tpadding?: number | ChartPadding;\n\tfontFamily?: string;\n\t/** Axis, legend and value label size. Default 18. */\n\tfontSize?: number;\n\t/** Axis labels; when set, also the legend and value labels. */\n\ttextColor?: string;\n\tgridColor?: string;\n\tbackground?: string;\n\t/** Show the series or slice legend. Default: on for several series and for pies. */\n\tlegend?: boolean;\n\t/** Print values on bars and slices (pie values print as percentages). */\n\tvalueLabels?: boolean;\n\t/** Donut hole as a fraction of the radius. Default 0.6 for \"donut\". */\n\tinnerRadius?: number;\n\t/** Corner radius of bars and slices. Default 4. */\n\tcornerRadius?: number;\n\tupColor?: string;\n\tdownColor?: string;\n\t/** Reveal animation, or `false` for a static chart. */\n\tanimate?: false | ChartAnimationOptions;\n}\n\nexport const DEFAULT_CHART_COLORS = [\n\t\"#6366f1\",\n\t\"#22d3ee\",\n\t\"#f59e0b\",\n\t\"#ec4899\",\n\t\"#10b981\",\n\t\"#8b5cf6\",\n\t\"#f97316\",\n\t\"#3b82f6\",\n] as const;\n\ntype XScale =\n\t| ScaleBand<string>\n\t| ScaleLinear<number, number>\n\t| ScaleTime<number, number>;\n\ninterface Timing {\n\tenabled: boolean;\n\tstart: number;\n\tduration: number;\n\tstagger: number;\n\tease: string;\n}\n\ninterface Point {\n\tx: ChartX;\n\ty: number;\n}\n\ninterface Rect {\n\tx: number;\n\ty: number;\n\twidth: number;\n\theight: number;\n}\n\nconst isCandle = (d: unknown): d is ChartCandle =>\n\ttypeof d === \"object\" && d !== null && \"open\" in d && \"close\" in d;\n\nconst isSlice = (d: unknown): d is ChartSlice =>\n\ttypeof d === \"object\" && d !== null && \"label\" in d && \"value\" in d;\n\nfunction curveOf(curve: ChartSeries[\"curve\"]): CurveFactory {\n\tif (curve === \"linear\") return curveLinear;\n\tif (curve === \"step\") return curveStepAfter;\n\treturn curveMonotoneX;\n}\n\nfunction withAlpha(color: string, alpha: number): string {\n\tconst hex = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(color.trim());\n\tif (!hex) return color;\n\tlet h = hex[1];\n\tif (h.length === 3) h = [...h].map((c) => c + c).join(\"\");\n\tconst n = parseInt(h, 16);\n\treturn `rgba(${(n >> 16) & 255}, ${(n >> 8) & 255}, ${n & 255}, ${alpha})`;\n}\n\nfunction fmt(\n\taxis: ChartAxisOptions | undefined,\n): ((v: ChartX) => string) | null {\n\tif (!axis?.format) return null;\n\tif (typeof axis.format === \"function\") return axis.format;\n\tconst f = d3Format(axis.format);\n\treturn (v) => (typeof v === \"number\" ? f(v) : String(v));\n}\n\nfunction round(v: number): number {\n\treturn Math.round(v * 100) / 100;\n}\n\nfunction fadeIn(t: Timing, delay = 0, duration = t.duration): LayerAnimation {\n\treturn LayerAnimation.create().fromTo(\"opacity\", 0, 1, {\n\t\tstart: t.start + delay,\n\t\tend: t.start + delay + Math.max(1, duration),\n\t\tease: \"power2.out\",\n\t});\n}\n\n/** Builds the chart as a box of absolutely positioned child nodes. */\nexport function buildChart(\n\toptions: ChartOptions,\n\tprops: Partial<BoxNode>,\n\tdefaultFontFamily: string,\n): AnimatableNode<BoxNode> {\n\tconst id = props.id ?? autoId(\"chart\");\n\tconst width =\n\t\toptions.width ?? (typeof props.width === \"number\" ? props.width : 960);\n\tconst height =\n\t\toptions.height ?? (typeof props.height === \"number\" ? props.height : 540);\n\tconst type = options.type ?? \"line\";\n\tconst fontSize = options.fontSize ?? 18;\n\tconst fontFamily = options.fontFamily ?? defaultFontFamily;\n\tconst textColor = options.textColor ?? \"#94a3b8\";\n\t// Legend and value labels read a little stronger than axis labels; with a custom\n\t// textColor (e.g. dark text on a light background) they use it as is.\n\tconst strongText = options.textColor ?? \"#e2e8f0\";\n\tconst gridColor = options.gridColor ?? \"rgba(148, 163, 184, 0.18)\";\n\tconst colors = options.colors?.length ? options.colors : DEFAULT_CHART_COLORS;\n\tconst radius = options.cornerRadius ?? 4;\n\n\tconst anim = options.animate === false ? undefined : (options.animate ?? {});\n\tconst timing: Timing = {\n\t\tenabled: anim !== undefined,\n\t\tstart: anim?.start ?? 0,\n\t\tduration: anim?.duration ?? 30,\n\t\tstagger: anim?.stagger ?? -1,\n\t\tease: anim?.ease ?? \"power3.out\",\n\t};\n\n\tconst children: LayoutNode[] = [];\n\tconst label = (\n\t\ttext: string,\n\t\trect: Rect,\n\t\talign: \"start\" | \"center\" | \"end\",\n\t\textra: { delay?: number; color?: string; weight?: number } = {},\n\t\tkey = \"\",\n\t) => {\n\t\tconst node = Layer.text(text, {\n\t\t\tid: `${id}-label-${key || children.length}`,\n\t\t\tposition: \"absolute\",\n\t\t\tx: round(rect.x),\n\t\t\ty: round(rect.y),\n\t\t\twidth: round(rect.width),\n\t\t\theight: round(rect.height),\n\t\t\tfontFamily,\n\t\t\tfontSize,\n\t\t\tfontWeight: extra.weight ?? 500,\n\t\t\tfill: extra.color ?? textColor,\n\t\t\talign,\n\t\t\tverticalAlign: \"middle\",\n\t\t});\n\t\tif (timing.enabled) node.animate(fadeIn(timing, extra.delay ?? 0));\n\t\tchildren.push(node);\n\t};\n\n\tconst lineHeight = Math.ceil(fontSize * 1.4);\n\n\tif (type === \"pie\" || type === \"donut\") {\n\t\tbuildPie();\n\t} else {\n\t\tbuildCartesian();\n\t}\n\n\t// Staggers and fractional durations land between frames; the program schema\n\t// wants whole-frame keyframes.\n\tfor (const child of children) snapKeyframes(child);\n\n\treturn Layer.box({\n\t\tbackground: options.background ?? \"transparent\",\n\t\t...props,\n\t\tid,\n\t\twidth,\n\t\theight,\n\t\tchildren,\n\t});\n\n\t// ── pie & donut ─────────────────────────────────────────────────────\n\n\tfunction buildPie(): void {\n\t\tconst slices = collectSlices();\n\t\tconst total = slices.reduce((s, d) => s + Math.max(0, d.value), 0);\n\t\tconst showLegend = options.legend ?? true;\n\t\tconst pad = resolvePadding({\n\t\t\ttop: 16,\n\t\t\tright: showLegend ? legendColumnWidth(slices.map((s) => s.label)) : 16,\n\t\t\tbottom: 16,\n\t\t\tleft: 16,\n\t\t});\n\t\tconst plot = plotRect(pad);\n\t\tconst r = Math.max(1, Math.min(plot.width, plot.height) / 2);\n\t\tconst inner = r * (options.innerRadius ?? (type === \"donut\" ? 0.6 : 0));\n\t\tconst cx = plot.x + plot.width / 2;\n\t\tconst cy = plot.y + plot.height / 2;\n\t\tconst m = 4;\n\t\tconst arcs = d3Pie<ChartSlice>()\n\t\t\t.sort(null)\n\t\t\t.value((d) => Math.max(0, d.value))\n\t\t\t.padAngle(slices.length > 1 ? 0.012 : 0)(slices);\n\t\tconst arcGen = d3Arc<(typeof arcs)[number]>()\n\t\t\t.innerRadius(inner)\n\t\t\t.outerRadius(r)\n\t\t\t.cornerRadius(Math.min(radius, (r - inner) / 2));\n\t\tconst step = staggerStep(arcs.length);\n\n\t\tarcs.forEach((a, i) => {\n\t\t\tconst d = arcGen(a);\n\t\t\tif (!d) return;\n\t\t\tconst color = slices[i].color ?? colors[i % colors.length];\n\t\t\tconst node = Layer.shape(\"path\", {\n\t\t\t\tid: `${id}-slice-${i}`,\n\t\t\t\tposition: \"absolute\",\n\t\t\t\tx: round(cx - r - m),\n\t\t\t\ty: round(cy - r - m),\n\t\t\t\twidth: round(2 * (r + m)),\n\t\t\t\theight: round(2 * (r + m)),\n\t\t\t\td: translatePath(d, r + m, r + m),\n\t\t\t\tfillColor: color,\n\t\t\t\tanchorX: 0.5,\n\t\t\t\tanchorY: 0.5,\n\t\t\t});\n\t\t\tif (timing.enabled) {\n\t\t\t\tconst s = timing.start + i * step;\n\t\t\t\tnode.animate(\n\t\t\t\t\tLayerAnimation.create()\n\t\t\t\t\t\t.fromTo(\"opacity\", 0, 1, {\n\t\t\t\t\t\t\tstart: s,\n\t\t\t\t\t\t\tend: s + timing.duration * 0.5,\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.fromTo(\"scale\", 0.85, 1, {\n\t\t\t\t\t\t\tstart: s,\n\t\t\t\t\t\t\tend: s + timing.duration,\n\t\t\t\t\t\t\tease: timing.ease,\n\t\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tchildren.push(node);\n\n\t\t\tif (options.valueLabels && total > 0 && a.value > 0) {\n\t\t\t\tconst [lx, ly] = d3Arc<(typeof arcs)[number]>()\n\t\t\t\t\t.innerRadius(inner || r * 0.55)\n\t\t\t\t\t.outerRadius(r)\n\t\t\t\t\t.centroid(a);\n\t\t\t\tconst pct = `${Math.round((a.value / total) * 100)}%`;\n\t\t\t\tlabel(\n\t\t\t\t\tpct,\n\t\t\t\t\t{\n\t\t\t\t\t\tx: cx + lx - 60,\n\t\t\t\t\t\ty: cy + ly - lineHeight / 2,\n\t\t\t\t\t\twidth: 120,\n\t\t\t\t\t\theight: lineHeight,\n\t\t\t\t\t},\n\t\t\t\t\t\"center\",\n\t\t\t\t\t{\n\t\t\t\t\t\tdelay: i * step + timing.duration * 0.5,\n\t\t\t\t\t\tcolor: \"#ffffff\",\n\t\t\t\t\t\tweight: 700,\n\t\t\t\t\t},\n\t\t\t\t\t`value-${i}`,\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\tif (showLegend) {\n\t\t\tlegendColumn(\n\t\t\t\tslices.map((s, i) => ({\n\t\t\t\t\tname: s.label,\n\t\t\t\t\tcolor: s.color ?? colors[i % colors.length],\n\t\t\t\t})),\n\t\t\t\t{ x: plot.x + plot.width + 24, y: plot.y, height: plot.height },\n\t\t\t);\n\t\t}\n\t}\n\n\tfunction collectSlices(): ChartSlice[] {\n\t\tconst raw = (options.data ??\n\t\t\toptions.series?.[0]?.data ??\n\t\t\t[]) as readonly unknown[];\n\t\treturn raw.map((d, i) => {\n\t\t\tif (isSlice(d)) return d;\n\t\t\tconst value =\n\t\t\t\ttypeof d === \"number\"\n\t\t\t\t\t? d\n\t\t\t\t\t: Array.isArray(d)\n\t\t\t\t\t\t? Number(d[1])\n\t\t\t\t\t\t: Number((d as Point).y);\n\t\t\tconst name =\n\t\t\t\toptions.categories?.[i] ??\n\t\t\t\t(Array.isArray(d)\n\t\t\t\t\t? String(d[0])\n\t\t\t\t\t: typeof d === \"object\" && d\n\t\t\t\t\t\t? String((d as Point).x)\n\t\t\t\t\t\t: `${i + 1}`);\n\t\t\treturn { label: name, value };\n\t\t});\n\t}\n\n\t// ── cartesian: line, area, bar, scatter, candlestick ───────────────\n\n\tfunction buildCartesian(): void {\n\t\tconst series: ChartSeries[] = options.series?.length\n\t\t\t? [...options.series]\n\t\t\t: options.data\n\t\t\t\t? [{ data: options.data as ChartSeries[\"data\"] }]\n\t\t\t\t: [];\n\t\tif (series.length === 0) return;\n\n\t\tconst typeOf = (s: ChartSeries) =>\n\t\t\ts.type ?? (type as ChartSeries[\"type\"]) ?? \"line\";\n\t\tconst colorOf = (s: ChartSeries, i: number) =>\n\t\t\ts.color ?? colors[i % colors.length];\n\n\t\t// Normalise every series to points (candles keep their OHLC values).\n\t\tconst points: Point[][] = series.map((s) =>\n\t\t\t(s.data as readonly unknown[]).map((d, i) => {\n\t\t\t\tif (isCandle(d)) return { x: d.x, y: d.close };\n\t\t\t\tif (typeof d === \"number\")\n\t\t\t\t\treturn { x: options.categories?.[i] ?? i, y: d };\n\t\t\t\tif (Array.isArray(d)) return { x: d[0] as ChartX, y: Number(d[1]) };\n\t\t\t\treturn { x: (d as Point).x, y: Number((d as Point).y) };\n\t\t\t}),\n\t\t);\n\n\t\tconst anyBand = series.some(\n\t\t\t(s) => typeOf(s) === \"bar\" || typeOf(s) === \"candlestick\",\n\t\t);\n\t\tconst allX = points.flat().map((p) => p.x);\n\t\tconst xKind: \"band\" | \"time\" | \"linear\" =\n\t\t\tanyBand || allX.some((x) => typeof x === \"string\")\n\t\t\t\t? \"band\"\n\t\t\t\t: allX.some((x) => x instanceof Date)\n\t\t\t\t\t? \"time\"\n\t\t\t\t\t: \"linear\";\n\n\t\t// Stacking for bars and areas.\n\t\tconst stackable = (s: ChartSeries) =>\n\t\t\ttypeOf(s) === \"bar\" || typeOf(s) === \"area\";\n\t\tconst stacked = !!options.stacked;\n\t\tconst categories = xKind === \"band\" ? [...new Set(allX.map(String))] : [];\n\t\tconst stackRanges = new Map<number, [number, number][]>();\n\t\tif (stacked) {\n\t\t\tconst keys = series.map((_, i) => i).filter((i) => stackable(series[i]));\n\t\t\tconst rows = categories.length\n\t\t\t\t? categories\n\t\t\t\t: [...new Set(allX.map((x) => +x))].sort((a, b) => a - b).map(String);\n\t\t\tconst table = rows.map((key) => {\n\t\t\t\tconst row: Record<string, number> = {};\n\t\t\t\tfor (const i of keys) {\n\t\t\t\t\tconst p = points[i].find(\n\t\t\t\t\t\t(pt) => String(xKind === \"band\" ? pt.x : +pt.x) === key,\n\t\t\t\t\t);\n\t\t\t\t\trow[i] = p?.y ?? 0;\n\t\t\t\t}\n\t\t\t\treturn row;\n\t\t\t});\n\t\t\tconst layers = d3Stack<Record<string, number>>()\n\t\t\t\t.keys(keys.map(String))\n\t\t\t\t.offset(stackOffsetDiverging)(table);\n\t\t\tlayers.forEach((layer) => {\n\t\t\t\tconst i = Number(layer.key);\n\t\t\t\tstackRanges.set(\n\t\t\t\t\ti,\n\t\t\t\t\tpoints[i].map((p) => {\n\t\t\t\t\t\tconst idx = rows.indexOf(String(xKind === \"band\" ? p.x : +p.x));\n\t\t\t\t\t\treturn [layer[idx][0], layer[idx][1]];\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\n\t\t// y domain\n\t\tconst yValues: number[] = [0];\n\t\tseries.forEach((s, i) => {\n\t\t\tconst range = stackRanges.get(i);\n\t\t\tif (typeOf(s) === \"candlestick\") {\n\t\t\t\tfor (const c of s.data as readonly ChartCandle[])\n\t\t\t\t\tyValues.push(c.high, c.low);\n\t\t\t} else if (range) {\n\t\t\t\tfor (const [a, b] of range) yValues.push(a, b);\n\t\t\t} else {\n\t\t\t\tfor (const p of points[i]) yValues.push(p.y);\n\t\t\t}\n\t\t});\n\t\tif (\n\t\t\tseries.every(\n\t\t\t\t(s) =>\n\t\t\t\t\ttypeOf(s) === \"candlestick\" ||\n\t\t\t\t\ttypeOf(s) === \"scatter\" ||\n\t\t\t\t\ttypeOf(s) === \"line\",\n\t\t\t)\n\t\t) {\n\t\t\t// Line, scatter and price charts don't have to include zero.\n\t\t\tyValues.shift();\n\t\t}\n\n\t\tconst yAxis = options.yAxis ?? {};\n\t\tconst xAxis = options.xAxis ?? {};\n\t\tconst yTickCount = yAxis.ticks ?? 5;\n\t\tlet lo = yAxis.min ?? Math.min(...yValues);\n\t\tlet hi = yAxis.max ?? Math.max(...yValues);\n\t\tif (!Number.isFinite(lo) || !Number.isFinite(hi)) [lo, hi] = [0, 1];\n\t\tif (lo === hi) [lo, hi] = [lo - 1, hi + 1];\n\t\tconst y = scaleLinear().domain([lo, hi]);\n\t\tif (yAxis.min === undefined || yAxis.max === undefined) y.nice(yTickCount);\n\t\tconst yFormat =\n\t\t\tfmt(yAxis) ?? ((v: ChartX) => y.tickFormat(yTickCount)(v as number));\n\t\tconst yTicks = y.ticks(yTickCount);\n\n\t\tconst legendItems = series.map((s, i) => ({\n\t\t\tname: s.name ?? `Series ${i + 1}`,\n\t\t\tcolor: colorOf(s, i),\n\t\t}));\n\t\tconst showLegend = options.legend ?? series.length > 1;\n\t\tconst showY = yAxis.show !== false;\n\t\tconst showX = xAxis.show !== false;\n\t\tconst yLabelWidth = showY\n\t\t\t? Math.max(...yTicks.map((t) => yFormat(t).length)) * fontSize * 0.7 + 20\n\t\t\t: 0;\n\t\tconst pad = resolvePadding({\n\t\t\ttop: (showLegend ? lineHeight + 20 : 0) + Math.ceil(lineHeight / 2),\n\t\t\tright: 20,\n\t\t\tbottom: showX ? lineHeight + 14 : 12,\n\t\t\tleft: Math.max(16, Math.ceil(yLabelWidth)),\n\t\t});\n\t\tconst plot = plotRect(pad);\n\t\t// Room for value labels above positive bars and below negative ones.\n\t\tconst labelRoom = lineHeight + 6;\n\t\tconst barValues = options.valueLabels\n\t\t\t? series.flatMap((s, i) =>\n\t\t\t\t\ttypeOf(s) === \"bar\" ? points[i].map((p) => p.y) : [],\n\t\t\t\t)\n\t\t\t: [];\n\t\tconst topInset = barValues.some((v) => v > 0) ? labelRoom : 0;\n\t\tconst bottomInset = barValues.some((v) => v < 0) ? labelRoom : 0;\n\t\ty.range([plot.height - bottomInset, topInset]);\n\n\t\tlet x: XScale;\n\t\tif (xKind === \"band\") {\n\t\t\tx = scaleBand<string>()\n\t\t\t\t.domain(categories)\n\t\t\t\t.range([0, plot.width])\n\t\t\t\t.paddingInner(anyBand ? 0.28 : 0)\n\t\t\t\t.paddingOuter(anyBand ? 0.14 : 0.5);\n\t\t} else if (xKind === \"time\") {\n\t\t\tconst xs = allX.map((v) => +new Date(v as Date));\n\t\t\tx = scaleUtc()\n\t\t\t\t.domain([Math.min(...xs), Math.max(...xs)])\n\t\t\t\t.range([0, plot.width]);\n\t\t} else {\n\t\t\tconst xs = allX.map(Number);\n\t\t\tx = scaleLinear()\n\t\t\t\t.domain([xAxis.min ?? Math.min(...xs), xAxis.max ?? Math.max(...xs)])\n\t\t\t\t.range([0, plot.width]);\n\t\t}\n\t\tconst xPos = (v: ChartX): number => {\n\t\t\tif (xKind === \"band\") {\n\t\t\t\tconst b = x as ScaleBand<string>;\n\t\t\t\treturn (b(String(v)) ?? 0) + b.bandwidth() / 2;\n\t\t\t}\n\t\t\tif (xKind === \"time\")\n\t\t\t\treturn (x as ScaleTime<number, number>)(new Date(v as Date));\n\t\t\treturn (x as ScaleLinear<number, number>)(Number(v));\n\t\t};\n\n\t\t// Grid and y labels.\n\t\tconst gridDelay = 0;\n\t\tif (yAxis.grid !== false) {\n\t\t\tyTicks.forEach((t, i) => {\n\t\t\t\tconst node = Layer.box({\n\t\t\t\t\tid: `${id}-ygrid-${i}`,\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tx: plot.x,\n\t\t\t\t\ty: round(plot.y + y(t) - 0.5),\n\t\t\t\t\twidth: plot.width,\n\t\t\t\t\theight: 1,\n\t\t\t\t\tbackground: gridColor,\n\t\t\t\t});\n\t\t\t\tif (timing.enabled)\n\t\t\t\t\tnode.animate(fadeIn(timing, gridDelay, timing.duration / 2));\n\t\t\t\tchildren.push(node);\n\t\t\t});\n\t\t}\n\t\tif (showY) {\n\t\t\tyTicks.forEach((t, i) => {\n\t\t\t\tlabel(\n\t\t\t\t\tyFormat(t),\n\t\t\t\t\t{\n\t\t\t\t\t\tx: 0,\n\t\t\t\t\t\ty: plot.y + y(t) - lineHeight / 2,\n\t\t\t\t\t\twidth: plot.x - 12,\n\t\t\t\t\t\theight: lineHeight,\n\t\t\t\t\t},\n\t\t\t\t\t\"end\",\n\t\t\t\t\t{},\n\t\t\t\t\t`y-${i}`,\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\n\t\t// x labels (and optional vertical grid).\n\t\tconst xTicks: { pos: number; text: string }[] = [];\n\t\tconst xFormat = fmt(xAxis);\n\t\tif (xKind === \"band\") {\n\t\t\tconst b = x as ScaleBand<string>;\n\t\t\tconst every = Math.max(\n\t\t\t\t1,\n\t\t\t\tMath.ceil(\n\t\t\t\t\tcategories.length /\n\t\t\t\t\t\tMath.max(1, Math.floor(plot.width / (fontSize * 4))),\n\t\t\t\t),\n\t\t\t);\n\t\t\tcategories.forEach((c, i) => {\n\t\t\t\tif (i % every === 0)\n\t\t\t\t\txTicks.push({\n\t\t\t\t\t\tpos: (b(c) ?? 0) + b.bandwidth() / 2,\n\t\t\t\t\t\ttext: xFormat ? xFormat(c) : c,\n\t\t\t\t\t});\n\t\t\t});\n\t\t} else {\n\t\t\tconst s = x as ScaleLinear<number, number>;\n\t\t\tconst count =\n\t\t\t\txAxis.ticks ?? Math.max(2, Math.floor(plot.width / (fontSize * 6)));\n\t\t\tconst tf = s.tickFormat(count);\n\t\t\tfor (const t of s.ticks(count)) {\n\t\t\t\txTicks.push({\n\t\t\t\t\tpos: s(t),\n\t\t\t\t\ttext: xFormat ? xFormat(xKind === \"time\" ? new Date(t) : t) : tf(t),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tif (xAxis.grid) {\n\t\t\txTicks.forEach((t, i) => {\n\t\t\t\tconst node = Layer.box({\n\t\t\t\t\tid: `${id}-xgrid-${i}`,\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tx: round(plot.x + t.pos - 0.5),\n\t\t\t\t\ty: plot.y,\n\t\t\t\t\twidth: 1,\n\t\t\t\t\theight: plot.height,\n\t\t\t\t\tbackground: gridColor,\n\t\t\t\t});\n\t\t\t\tif (timing.enabled)\n\t\t\t\t\tnode.animate(fadeIn(timing, gridDelay, timing.duration / 2));\n\t\t\t\tchildren.push(node);\n\t\t\t});\n\t\t}\n\t\tif (showX) {\n\t\t\tconst slot = Math.max(\n\t\t\t\tfontSize * 3,\n\t\t\t\tplot.width / Math.max(1, xTicks.length),\n\t\t\t);\n\t\t\txTicks.forEach((t, i) => {\n\t\t\t\tlabel(\n\t\t\t\t\tt.text,\n\t\t\t\t\t{\n\t\t\t\t\t\tx: plot.x + t.pos - slot / 2,\n\t\t\t\t\t\ty: plot.y + plot.height + 10,\n\t\t\t\t\t\twidth: slot,\n\t\t\t\t\t\theight: lineHeight,\n\t\t\t\t\t},\n\t\t\t\t\t\"center\",\n\t\t\t\t\t{},\n\t\t\t\t\t`x-${i}`,\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\n\t\t// Baseline at zero when it is inside the domain.\n\t\tconst [y0, y1] = y.domain();\n\t\tif (y0 <= 0 && y1 >= 0 && anyBand) {\n\t\t\tconst node = Layer.box({\n\t\t\t\tid: `${id}-zero`,\n\t\t\t\tposition: \"absolute\",\n\t\t\t\tx: plot.x,\n\t\t\t\ty: round(plot.y + y(0) - 1),\n\t\t\t\twidth: plot.width,\n\t\t\t\theight: 2,\n\t\t\t\tbackground: withAlpha(\"#94a3b8\", 0.45),\n\t\t\t});\n\t\t\tif (timing.enabled) node.animate(fadeIn(timing, 0, timing.duration / 2));\n\t\t\tchildren.push(node);\n\t\t}\n\n\t\t// Series. Bars first so lines draw on top.\n\t\tconst barSeries = series\n\t\t\t.map((_, i) => i)\n\t\t\t.filter((i) => typeOf(series[i]) === \"bar\");\n\t\tconst order = [\n\t\t\t...barSeries,\n\t\t\t...series\n\t\t\t\t.map((_, i) => i)\n\t\t\t\t.filter((i) => typeOf(series[i]) === \"candlestick\"),\n\t\t\t...series.map((_, i) => i).filter((i) => typeOf(series[i]) === \"area\"),\n\t\t\t...series.map((_, i) => i).filter((i) => typeOf(series[i]) === \"line\"),\n\t\t\t...series.map((_, i) => i).filter((i) => typeOf(series[i]) === \"scatter\"),\n\t\t];\n\n\t\tconst band = xKind === \"band\" ? (x as ScaleBand<string>) : null;\n\t\tconst bandStep = band ? staggerStep(categories.length) : 0;\n\t\tconst categoryIndex = (v: ChartX) =>\n\t\t\tband ? categories.indexOf(String(v)) : 0;\n\n\t\torder.forEach((si, rank) => {\n\t\t\tconst s = series[si];\n\t\t\tconst color = colorOf(s, si);\n\t\t\tconst kind = typeOf(s);\n\t\t\tconst pts = points[si];\n\t\t\tconst range = stackRanges.get(si);\n\n\t\t\tif (kind === \"bar\" && band) {\n\t\t\t\tconst groupSize = stacked ? 1 : barSeries.length;\n\t\t\t\tconst groupIdx = stacked ? 0 : barSeries.indexOf(si);\n\t\t\t\tconst bw = band.bandwidth() / groupSize;\n\t\t\t\tconst gap = groupSize > 1 ? Math.min(4, bw * 0.12) : 0;\n\t\t\t\tpts.forEach((p, i) => {\n\t\t\t\t\tconst [lo, hi] = range ? range[i] : [0, p.y];\n\t\t\t\t\tconst top = plot.y + y(Math.max(lo, hi));\n\t\t\t\t\tconst bottom = plot.y + y(Math.min(lo, hi));\n\t\t\t\t\tconst h = Math.max(0, bottom - top);\n\t\t\t\t\tconst bx =\n\t\t\t\t\t\tplot.x + (band(String(p.x)) ?? 0) + groupIdx * bw + gap / 2;\n\t\t\t\t\tconst grows = p.y >= 0 ? \"up\" : \"down\";\n\t\t\t\t\tconst node = Layer.box({\n\t\t\t\t\t\tid: `${id}-bar-${si}-${i}`,\n\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\tx: round(bx),\n\t\t\t\t\t\ty: round(top),\n\t\t\t\t\t\twidth: round(Math.max(1, bw - gap)),\n\t\t\t\t\t\theight: round(h),\n\t\t\t\t\t\tbackground: color,\n\t\t\t\t\t\tborderRadius: Math.min(radius, (bw - gap) / 2, h / 2),\n\t\t\t\t\t});\n\t\t\t\t\tconst delay =\n\t\t\t\t\t\tcategoryIndex(p.x) * bandStep +\n\t\t\t\t\t\t(stacked ? barSeries.indexOf(si) * timing.duration * 0.6 : 0);\n\t\t\t\t\tif (timing.enabled) {\n\t\t\t\t\t\tconst st = timing.start + delay;\n\t\t\t\t\t\tconst end = st + timing.duration;\n\t\t\t\t\t\tconst a = LayerAnimation.create().fromTo(\"height\", 0, round(h), {\n\t\t\t\t\t\t\tstart: st,\n\t\t\t\t\t\t\tend,\n\t\t\t\t\t\t\tease: timing.ease,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (grows === \"up\") {\n\t\t\t\t\t\t\ta.fromTo(\"y\", round(top + h), round(top), {\n\t\t\t\t\t\t\t\tstart: st,\n\t\t\t\t\t\t\t\tend,\n\t\t\t\t\t\t\t\tease: timing.ease,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnode.animate(a);\n\t\t\t\t\t}\n\t\t\t\t\tchildren.push(node);\n\t\t\t\t\tif (options.valueLabels) {\n\t\t\t\t\t\tconst text = yFormat(p.y);\n\t\t\t\t\t\tconst ly = grows === \"up\" ? top - lineHeight - 4 : top + h + 4;\n\t\t\t\t\t\tlabel(\n\t\t\t\t\t\t\ttext,\n\t\t\t\t\t\t\t{ x: bx - 30, y: ly, width: bw - gap + 60, height: lineHeight },\n\t\t\t\t\t\t\t\"center\",\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdelay: delay + timing.duration * 0.6,\n\t\t\t\t\t\t\t\tcolor: strongText,\n\t\t\t\t\t\t\t\tweight: 600,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t`value-${si}-${i}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (kind === \"candlestick\" && band) {\n\t\t\t\tconst up = options.upColor ?? \"#22c55e\";\n\t\t\t\tconst down = options.downColor ?? \"#ef4444\";\n\t\t\t\tconst bw = band.bandwidth();\n\t\t\t\t(s.data as readonly ChartCandle[]).forEach((c, i) => {\n\t\t\t\t\tconst col = c.close >= c.open ? up : down;\n\t\t\t\t\tconst cxp = plot.x + (band(String(c.x)) ?? 0) + bw / 2;\n\t\t\t\t\tconst delay = categoryIndex(c.x) * bandStep;\n\t\t\t\t\tconst parts: [string, Rect][] = [\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\"wick\",\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tx: cxp - Math.max(1, bw * 0.06),\n\t\t\t\t\t\t\t\ty: plot.y + y(c.high),\n\t\t\t\t\t\t\t\twidth: Math.max(2, bw * 0.12),\n\t\t\t\t\t\t\t\theight: Math.max(1, y(c.low) - y(c.high)),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\"body\",\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tx: cxp - bw / 2,\n\t\t\t\t\t\t\t\ty: plot.y + y(Math.max(c.open, c.close)),\n\t\t\t\t\t\t\t\twidth: bw,\n\t\t\t\t\t\t\t\theight: Math.max(2, Math.abs(y(c.open) - y(c.close))),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t];\n\t\t\t\t\tfor (const [part, r] of parts) {\n\t\t\t\t\t\tconst node = Layer.box({\n\t\t\t\t\t\t\tid: `${id}-candle-${si}-${i}-${part}`,\n\t\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t\tx: round(r.x),\n\t\t\t\t\t\t\ty: round(r.y),\n\t\t\t\t\t\t\twidth: round(r.width),\n\t\t\t\t\t\t\theight: round(r.height),\n\t\t\t\t\t\t\tbackground: col,\n\t\t\t\t\t\t\tborderRadius:\n\t\t\t\t\t\t\t\tpart === \"body\" ? Math.min(radius / 2, r.width / 2) : 0,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (timing.enabled) {\n\t\t\t\t\t\t\tconst st = timing.start + delay;\n\t\t\t\t\t\t\tconst mid = r.y + r.height / 2;\n\t\t\t\t\t\t\tnode.animate(\n\t\t\t\t\t\t\t\tLayerAnimation.create()\n\t\t\t\t\t\t\t\t\t.fromTo(\"height\", 0, round(r.height), {\n\t\t\t\t\t\t\t\t\t\tstart: st,\n\t\t\t\t\t\t\t\t\t\tend: st + timing.duration,\n\t\t\t\t\t\t\t\t\t\tease: timing.ease,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t.fromTo(\"y\", round(mid), round(r.y), {\n\t\t\t\t\t\t\t\t\t\tstart: st,\n\t\t\t\t\t\t\t\t\t\tend: st + timing.duration,\n\t\t\t\t\t\t\t\t\t\tease: timing.ease,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tchildren.push(node);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (kind === \"line\" || kind === \"area\") {\n\t\t\t\tconst sw = s.strokeWidth ?? 3;\n\t\t\t\tconst m = Math.ceil(sw * 2 + (s.pointRadius ?? 0) + 2);\n\t\t\t\tconst xy = pts.map((p, i) => ({\n\t\t\t\t\tx: xPos(p.x) + m,\n\t\t\t\t\ttop: (range ? y(range[i][1]) : y(p.y)) + m,\n\t\t\t\t\tbase:\n\t\t\t\t\t\t(range\n\t\t\t\t\t\t\t? y(range[i][0])\n\t\t\t\t\t\t\t: y(Math.max(y.domain()[0], Math.min(0, y.domain()[1])))) + m,\n\t\t\t\t}));\n\t\t\t\tconst curve = curveOf(s.curve);\n\t\t\t\tconst frame: Rect = {\n\t\t\t\t\tx: plot.x - m,\n\t\t\t\t\ty: plot.y - m,\n\t\t\t\t\twidth: plot.width + 2 * m,\n\t\t\t\t\theight: plot.height + 2 * m,\n\t\t\t\t};\n\t\t\t\tconst delay = rank * (timing.duration / 3);\n\n\t\t\t\tif (kind === \"area\") {\n\t\t\t\t\tconst d = d3Area<(typeof xy)[number]>()\n\t\t\t\t\t\t.x((p) => p.x)\n\t\t\t\t\t\t.y0((p) => p.base)\n\t\t\t\t\t\t.y1((p) => p.top)\n\t\t\t\t\t\t.curve(curve)(xy);\n\t\t\t\t\tif (d) {\n\t\t\t\t\t\tconst node = Layer.shape(\"path\", {\n\t\t\t\t\t\t\tid: `${id}-area-${si}`,\n\t\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t\t...roundRect(frame),\n\t\t\t\t\t\t\td: roundPath(d),\n\t\t\t\t\t\t\tfillType: \"linear\",\n\t\t\t\t\t\t\tfillColor: withAlpha(color, 0.45),\n\t\t\t\t\t\t\tgradientEndColor: withAlpha(color, 0.02),\n\t\t\t\t\t\t\tgradientAngle: 90,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (timing.enabled)\n\t\t\t\t\t\t\tnode.animate(\n\t\t\t\t\t\t\t\tfadeIn(timing, delay + timing.duration * 0.4, timing.duration),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\tchildren.push(node);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst d = d3Line<(typeof xy)[number]>()\n\t\t\t\t\t.x((p) => p.x)\n\t\t\t\t\t.y((p) => p.top)\n\t\t\t\t\t.curve(curve)(xy);\n\t\t\t\tif (d && sw > 0) {\n\t\t\t\t\tconst node = Layer.shape(\"path\", {\n\t\t\t\t\t\tid: `${id}-line-${si}`,\n\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t...roundRect(frame),\n\t\t\t\t\t\td: roundPath(d),\n\t\t\t\t\t\tfillType: \"none\",\n\t\t\t\t\t\tstrokeColor: color,\n\t\t\t\t\t\tstrokeWidth: sw,\n\t\t\t\t\t\tstrokeLineCap: \"round\",\n\t\t\t\t\t\tstrokeLineJoin: \"round\",\n\t\t\t\t\t});\n\t\t\t\t\tif (timing.enabled) {\n\t\t\t\t\t\tnode.animate(\n\t\t\t\t\t\t\tLayerAnimation.create().fromTo(\"trimEnd\", 0, 1, {\n\t\t\t\t\t\t\t\tstart: timing.start + delay,\n\t\t\t\t\t\t\t\tend: timing.start + delay + timing.duration * 1.5,\n\t\t\t\t\t\t\t\tease: \"power2.inOut\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tchildren.push(node);\n\t\t\t\t}\n\n\t\t\t\tif ((s.pointRadius ?? 0) > 0) {\n\t\t\t\t\tdots(\n\t\t\t\t\t\tsi,\n\t\t\t\t\t\tpts,\n\t\t\t\t\t\tcolor,\n\t\t\t\t\t\ts.pointRadius ?? 0,\n\t\t\t\t\t\tdelay + timing.duration * 0.5,\n\t\t\t\t\t\trange,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (kind === \"scatter\") {\n\t\t\t\tdots(\n\t\t\t\t\tsi,\n\t\t\t\t\tpts,\n\t\t\t\t\tcolor,\n\t\t\t\t\ts.pointRadius ?? 6,\n\t\t\t\t\trank * (timing.duration / 3),\n\t\t\t\t\trange,\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\tif (showLegend) legendRow(legendItems);\n\n\t\tfunction dots(\n\t\t\tsi: number,\n\t\t\tpts: Point[],\n\t\t\tcolor: string,\n\t\t\tr: number,\n\t\t\tbaseDelay: number,\n\t\t\trange: [number, number][] | undefined,\n\t\t): void {\n\t\t\tconst step = staggerStep(pts.length);\n\t\t\tpts.forEach((p, i) => {\n\t\t\t\tconst py = range ? y(range[i][1]) : y(p.y);\n\t\t\t\tconst node = Layer.shape(\"circle\", {\n\t\t\t\t\tid: `${id}-point-${si}-${i}`,\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tx: round(plot.x + xPos(p.x) - r),\n\t\t\t\t\ty: round(plot.y + py - r),\n\t\t\t\t\twidth: round(r * 2),\n\t\t\t\t\theight: round(r * 2),\n\t\t\t\t\tfillColor: color,\n\t\t\t\t\tanchorX: 0.5,\n\t\t\t\t\tanchorY: 0.5,\n\t\t\t\t});\n\t\t\t\tif (timing.enabled) {\n\t\t\t\t\tconst st = timing.start + baseDelay + i * step;\n\t\t\t\t\tnode.animate(\n\t\t\t\t\t\tLayerAnimation.create()\n\t\t\t\t\t\t\t.fromTo(\"scale\", 0, 1, {\n\t\t\t\t\t\t\t\tstart: st,\n\t\t\t\t\t\t\t\tend: st + timing.duration * 0.6,\n\t\t\t\t\t\t\t\tease: \"back.out(2)\",\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.fromTo(\"opacity\", 0, 1, { start: st, end: st + 6 }),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tchildren.push(node);\n\t\t\t});\n\t\t}\n\t}\n\n\t// ── shared helpers ──────────────────────────────────────────────────\n\n\tfunction staggerStep(count: number): number {\n\t\tif (!timing.enabled || count <= 1) return 0;\n\t\tif (timing.stagger >= 0) return timing.stagger;\n\t\treturn Math.min(4, timing.duration / count);\n\t}\n\n\tfunction resolvePadding(\n\t\tauto: Required<ChartPadding>,\n\t): Required<ChartPadding> {\n\t\tconst p = options.padding;\n\t\tif (typeof p === \"number\") return { top: p, right: p, bottom: p, left: p };\n\t\treturn {\n\t\t\ttop: p?.top ?? auto.top,\n\t\t\tright: p?.right ?? auto.right,\n\t\t\tbottom: p?.bottom ?? auto.bottom,\n\t\t\tleft: p?.left ?? auto.left,\n\t\t};\n\t}\n\n\tfunction plotRect(p: Required<ChartPadding>): Rect {\n\t\treturn {\n\t\t\tx: p.left,\n\t\t\ty: p.top,\n\t\t\twidth: Math.max(1, width - p.left - p.right),\n\t\t\theight: Math.max(1, height - p.top - p.bottom),\n\t\t};\n\t}\n\n\tfunction legendColumnWidth(names: string[]): number {\n\t\tconst longest = Math.max(0, ...names.map((n) => n.length));\n\t\treturn Math.min(width * 0.4, longest * fontSize * 0.6 + fontSize + 48);\n\t}\n\n\tfunction legendColumn(\n\t\titems: { name: string; color: string }[],\n\t\tat: { x: number; y: number; height: number },\n\t): void {\n\t\tconst rowH = lineHeight + 8;\n\t\tconst top = at.y + Math.max(0, (at.height - items.length * rowH) / 2);\n\t\titems.forEach((item, i) => {\n\t\t\tlegendItem(item, at.x, top + i * rowH, i);\n\t\t});\n\t}\n\n\tfunction legendRow(items: { name: string; color: string }[]): void {\n\t\tconst widths = items.map(\n\t\t\t(it) => it.name.length * fontSize * 0.6 + fontSize + 28,\n\t\t);\n\t\tconst total = widths.reduce((a, b) => a + b, 0);\n\t\tlet cursor = Math.max(0, width - total - 20);\n\t\titems.forEach((item, i) => {\n\t\t\tlegendItem(item, cursor, 4, i);\n\t\t\tcursor += widths[i];\n\t\t});\n\t}\n\n\tfunction legendItem(\n\t\titem: { name: string; color: string },\n\t\tlx: number,\n\t\tly: number,\n\t\ti: number,\n\t): void {\n\t\tconst sw = Math.round(fontSize * 0.7);\n\t\tconst swatch = Layer.box({\n\t\t\tid: `${id}-legend-swatch-${i}`,\n\t\t\tposition: \"absolute\",\n\t\t\tx: round(lx),\n\t\t\ty: round(ly + (lineHeight - sw) / 2),\n\t\t\twidth: sw,\n\t\t\theight: sw,\n\t\t\tborderRadius: Math.round(sw / 4),\n\t\t\tbackground: item.color,\n\t\t});\n\t\tif (timing.enabled) swatch.animate(fadeIn(timing, 0, timing.duration / 2));\n\t\tchildren.push(swatch);\n\t\tlabel(\n\t\t\titem.name,\n\t\t\t{\n\t\t\t\tx: lx + sw + 8,\n\t\t\t\ty: ly,\n\t\t\t\twidth: item.name.length * fontSize * 0.6 + 12,\n\t\t\t\theight: lineHeight,\n\t\t\t},\n\t\t\t\"start\",\n\t\t\t{ color: options.textColor ?? \"#cbd5e1\" },\n\t\t\t`legend-${i}`,\n\t\t);\n\t}\n}\n\nfunction snapKeyframes(node: LayoutNode): void {\n\tfor (const track of node.animation?.tracks ?? []) {\n\t\tfor (const kf of track.keyframes ?? []) kf.frame = Math.round(kf.frame);\n\t}\n\tfor (const child of (node as { children?: LayoutNode[] }).children ?? []) {\n\t\tsnapKeyframes(child);\n\t}\n}\n\nfunction roundRect(r: Rect): Rect {\n\treturn {\n\t\tx: round(r.x),\n\t\ty: round(r.y),\n\t\twidth: round(r.width),\n\t\theight: round(r.height),\n\t};\n}\n\n/** Shortens the long float literals d3 emits. */\nfunction roundPath(d: string): string {\n\treturn d.replace(/-?\\d*\\.\\d{3,}(?:e-?\\d+)?/gi, (n) =>\n\t\tString(round(Number(n))),\n\t);\n}\n\n/** Offsets an absolute SVG path (as produced by d3-arc) by dx, dy. */\nfunction translatePath(d: string, dx: number, dy: number): string {\n\t// d3-arc emits M/L/A/Z with absolute coordinates; A has 7 params, of which\n\t// the last two are the endpoint.\n\tconst out: string[] = [];\n\tconst re = /([MLAZ])([^MLAZ]*)/gi;\n\tfor (const [, cmd, args] of d.matchAll(re)) {\n\t\tconst nums = (args.match(/-?\\d*\\.?\\d+(?:e-?\\d+)?/gi) ?? []).map(Number);\n\t\tif (cmd.toUpperCase() === \"A\") {\n\t\t\tfor (let i = 0; i + 6 < nums.length; i += 7) {\n\t\t\t\tnums[i + 5] += dx;\n\t\t\t\tnums[i + 6] += dy;\n\t\t\t}\n\t\t} else if (cmd.toUpperCase() !== \"Z\") {\n\t\t\tfor (let i = 0; i + 1 < nums.length; i += 2) {\n\t\t\t\tnums[i] += dx;\n\t\t\t\tnums[i + 1] += dy;\n\t\t\t}\n\t\t}\n\t\tout.push(cmd + nums.map(round).join(\",\"));\n\t}\n\treturn out.join(\"\");\n}\n","import { type FrameSignal, Signal } from \"@framefields/core\";\nimport {\n\ttype ClipSubjectSource,\n\tCOCO17_KEYPOINT_NAMES,\n\ttype InstanceMask,\n\tmergeSubjectMask,\n\tVisionRunner,\n} from \"@framefields/vision\";\nimport { mediaDecoderCache } from \"@framefields/webgpu-renderers\";\nimport type { VisionProps } from \"./effects/index.js\";\n\nexport type PoseKeypointName = (typeof COCO17_KEYPOINT_NAMES)[number];\n\nexport interface ClipVisionOptions {\n\t/** Composition frame the clip's first frame plays on (default 0). */\n\tstartFrame?: number;\n\t/** Seconds trimmed off the clip's start, as on its media layer (default 0). */\n\ttrimStartSec?: number;\n\t/** Analysis frame rate (default: the composition's). */\n\tfps?: number;\n\t/** Track 17 COCO keypoints (default true). */\n\tpose?: boolean;\n\t/** Track the person's silhouette, dress and held things included (default true). */\n\tmask?: boolean;\n\t/** Silhouette cell size in source pixels (default 8: a 1920×1080 clip gives a 240×135 grid). */\n\tmaskCell?: number;\n\t/** Keypoints are averaged over ±`smoothing` frames, weighted by confidence (default 2; 0 = raw). */\n\tsmoothing?: number;\n\tvariant?: VisionProps[\"variant\"];\n\tconfidence?: number;\n\tmodelsDir?: string;\n\tbaseUrl?: string;\n\t/**\n\t * Node: where results persist between runs. Default\n\t * `$FRAMEFIELDS_VISION_CACHE_DIR` or `~/.cache/framefields/vision`;\n\t * `false` keeps them in memory only. Browsers always keep them in memory.\n\t */\n\tcacheDir?: string | false;\n}\n\n/** Where the clip sits in the composition, like a media layer's box and `fit`. */\nexport interface PersonPlacement {\n\tx?: number;\n\ty?: number;\n\twidth: number;\n\theight: number;\n\tfit?: \"cover\" | \"contain\" | \"fill\";\n}\n\ninterface FrameResult {\n\t/** 17 × [x, y, visibility], source px; null when no person was found. */\n\tkp: Float32Array | null;\n\t/** cellW × cellH, 0–255; null when no person was found. */\n\tmask: Uint8Array | null;\n}\n\n/** A frame's merged subject at source resolution, run-length encoded. */\ninterface SubjectResult {\n\tcategory: string;\n\tarea: number;\n\t/** (value, run length) pairs over the source-sized 0–255 mask. */\n\tvalues: Uint8Array;\n\tlengths: Uint32Array;\n}\n\ninterface Transform {\n\tsx: number;\n\tsy: number;\n\tox: number;\n\toy: number;\n}\n\n/** Frames looked back over to bridge a gap where the person is lost. */\nconst HOLD = 24;\n\nconst CACHE_VERSION = 1;\n\n/**\n * Vision results for one clip, computed per frame on demand and shared by\n * everything that reads the clip: physics, layout, signals. Unlike the\n * render-time `withVision`, which analyses a layer's previous rendered frame,\n * this analyses the clip's own frames, so a result exists before its frame\n * renders. The composition analyses what each frame needs just before\n * drawing it (and a live physics world before stepping), so preview and\n * export fill the cache as they play; nothing has to be analysed up front.\n *\n * Results depend only on the clip and settings, so they persist on disk in\n * Node: a second run, or a render after a preview, reuses them. A matte-mode\n * `withVision` layer of the same clip reuses them too (`keepSubjects`).\n */\nexport class ClipVision implements ClipSubjectSource {\n\treadonly source: string;\n\treadonly fps: number;\n\treadonly startFrame: number;\n\treadonly trimStartSec: number;\n\treadonly smoothing: number;\n\t/** @internal */\n\treadonly options: ClipVisionOptions;\n\tprivate readonly results = new Map<number, FrameResult>();\n\tprivate sourceWidth = 0;\n\tprivate sourceHeight = 0;\n\tprivate cellW = 0;\n\tprivate cellH = 0;\n\tprivate readonly cell: number;\n\tprivate queue: Promise<void> = Promise.resolve();\n\tprivate runner?: VisionRunner;\n\tprivate cacheLoaded?: Promise<void>;\n\tprivate unsaved = 0;\n\tprivate unsavedSubjects = 0;\n\tprivate readonly blurred = new Map<number, Float32Array | null>();\n\tprivate readonly smoothed = new Map<string, [number, number, number]>();\n\tprivate personView?: PersonTrack;\n\t/** Full-resolution subject masks for render-time mattes (see `keepSubjects`). */\n\tprivate readonly subjects = new Map<number, SubjectResult | null>();\n\tprivate wantSubjects = false;\n\tprivate subjectsLoaded?: Promise<void>;\n\n\t/** @internal Use `comp.vision(source, options)`. */\n\tconstructor(source: string, fps: number, options: ClipVisionOptions = {}) {\n\t\tthis.source = source;\n\t\tthis.options = options;\n\t\tthis.fps = options.fps ?? fps;\n\t\tthis.startFrame = Math.round(options.startFrame ?? 0);\n\t\tthis.trimStartSec = options.trimStartSec ?? 0;\n\t\tthis.smoothing = Math.max(0, Math.round(options.smoothing ?? 2));\n\t\tthis.cell = Math.max(1, Math.round(options.maskCell ?? 8));\n\t}\n\n\t/** The tracked person in source pixels; `.place()` maps it into the composition. */\n\tget person(): PersonTrack {\n\t\tthis.personView ??= new PersonTrack(this);\n\t\treturn this.personView;\n\t}\n\n\t/**\n\t * Analyses what reading composition frame `frame` needs (it and a few\n\t * neighbours for smoothing). Pass a second frame to analyse a whole range.\n\t * Calls queue, so the clip is decoded once, in order.\n\t */\n\tready(frame: number, toFrame: number = frame): Promise<void> {\n\t\tconst [from, to] = this.window(frame, toFrame);\n\t\tthis.queue = this.queue.then(() => this.compute(from, to));\n\t\treturn this.queue;\n\t}\n\n\t/** True when composition frame `frame` can be read synchronously. */\n\tisReady(frame: number): boolean {\n\t\tconst [from, to] = this.window(frame, frame);\n\t\tfor (let c = from; c <= to; c++) if (!this.results.has(c)) return false;\n\t\treturn true;\n\t}\n\n\t/**\n\t * @internal Also keep each frame's full-resolution subject mask, merged\n\t * like the Vision effect's matte, so a matte layer of this clip reuses it\n\t * instead of segmenting the frame again (framefields links them).\n\t */\n\tkeepSubjects(): void {\n\t\tthis.wantSubjects = true;\n\t}\n\n\t/**\n\t * @internal The subject at a source frame of the clip (`frame` at `fps`),\n\t * for a render-time matte: undefined until that frame is analysed with\n\t * subjects kept, null when it holds no subject.\n\t */\n\tsubject(frame: number, fps: number): InstanceMask | null | undefined {\n\t\tconst c = (frame * this.fps) / fps;\n\t\tif (Math.abs(c - Math.round(c)) > 1e-6) return undefined;\n\t\tconst s = this.subjects.get(Math.round(c));\n\t\tif (s === undefined) return s;\n\t\tif (s === null || !this.sourceWidth) return null;\n\t\tconst width = this.sourceWidth;\n\t\tconst height = this.sourceHeight;\n\t\treturn {\n\t\t\tcategory: s.category,\n\t\t\tmask: decodeRuns(s, width * height),\n\t\t\twidth,\n\t\t\theight,\n\t\t\tarea: s.area,\n\t\t\tcoverage: s.area / (width * height),\n\t\t\tdetectionIndex: -1,\n\t\t};\n\t}\n\n\t/** Composition frame → clip frame (fractional). */\n\tclipFrame(frame: number): number {\n\t\treturn frame - this.startFrame + this.trimStartSec * this.fps;\n\t}\n\n\tprivate window(frame: number, toFrame: number): [number, number] {\n\t\tconst a = Math.floor(this.clipFrame(Math.min(frame, toFrame)));\n\t\tconst b = Math.ceil(this.clipFrame(Math.max(frame, toFrame)));\n\t\treturn [\n\t\t\tMath.max(0, a - HOLD - this.smoothing),\n\t\t\tMath.max(0, b + this.smoothing),\n\t\t];\n\t}\n\n\tprivate analysed(c: number): boolean {\n\t\treturn this.results.has(c) && (!this.wantSubjects || this.subjects.has(c));\n\t}\n\n\tprivate async compute(from: number, to: number): Promise<void> {\n\t\tthis.cacheLoaded ??= this.loadCache();\n\t\tawait this.cacheLoaded;\n\t\tif (this.wantSubjects) {\n\t\t\tthis.subjectsLoaded ??= this.loadSubjects();\n\t\t\tawait this.subjectsLoaded;\n\t\t}\n\t\tlet missing = false;\n\t\tfor (let c = from; c <= to; c++) if (!this.analysed(c)) missing = true;\n\t\tif (!missing) return;\n\n\t\tconst wantPose = this.options.pose ?? true;\n\t\tconst wantMask = this.options.mask ?? true;\n\t\tthis.runner ??= VisionRunner.create({\n\t\t\tmodelsDir: this.options.modelsDir,\n\t\t\tbaseUrl: this.options.baseUrl,\n\t\t\t...(this.options.confidence !== undefined && {\n\t\t\t\tconfidence: this.options.confidence,\n\t\t\t}),\n\t\t\t...(this.options.variant !== undefined && {\n\t\t\t\tvariant: this.options.variant,\n\t\t\t}),\n\t\t});\n\t\tconst decoder = mediaDecoderCache.getVideo(\n\t\t\tthis.source,\n\t\t\ttrue,\n\t\t\t\"clip-vision\",\n\t\t);\n\t\tfor (let c = from; c <= to; c++) {\n\t\t\tif (this.analysed(c)) continue;\n\t\t\tconst image = await decodedPixels(await decoder.getFrame(c / this.fps));\n\t\t\tif (!image) {\n\t\t\t\tthis.results.set(c, { kp: null, mask: null });\n\t\t\t\tif (this.wantSubjects) this.subjects.set(c, null);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!this.sourceWidth) this.setSize(image.width, image.height);\n\t\t\t// Analysed before without subjects: only segment it again.\n\t\t\tconst known = this.results.get(c);\n\t\t\tlet kp: Float32Array | null = known?.kp ?? null;\n\t\t\tlet mask: Uint8Array | null = known?.mask ?? null;\n\t\t\tif (wantPose && !known) {\n\t\t\t\tconst person = (await this.runner.pose(image)).people[0];\n\t\t\t\tif (person) {\n\t\t\t\t\tkp = new Float32Array(51);\n\t\t\t\t\tfor (const [k, p] of person.keypoints.entries()) {\n\t\t\t\t\t\tkp.set([p.x, p.y, p.visibility], k * 3);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst seg =\n\t\t\t\t(wantMask && !known) || this.wantSubjects\n\t\t\t\t\t? await this.runner.segment(image)\n\t\t\t\t\t: undefined;\n\t\t\tif (seg && this.wantSubjects) {\n\t\t\t\tconst subject = mergeSubjectMask(seg.masks);\n\t\t\t\tthis.subjects.set(\n\t\t\t\t\tc,\n\t\t\t\t\tsubject\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tcategory: subject.category,\n\t\t\t\t\t\t\t\tarea: subject.area,\n\t\t\t\t\t\t\t\t...encodeRuns(subject.mask),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: null,\n\t\t\t\t);\n\t\t\t\tthis.unsavedSubjects++;\n\t\t\t}\n\t\t\tif (seg && wantMask && !known) {\n\t\t\t\tconst silhouette = personSilhouette(seg);\n\t\t\t\tif (silhouette) {\n\t\t\t\t\tmask = new Uint8Array(this.cellW * this.cellH);\n\t\t\t\t\tdownsampleMean(\n\t\t\t\t\t\tsilhouette,\n\t\t\t\t\t\timage.width,\n\t\t\t\t\t\timage.height,\n\t\t\t\t\t\tthis.cell,\n\t\t\t\t\t\tmask,\n\t\t\t\t\t\tthis.cellW,\n\t\t\t\t\t\tthis.cellH,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.results.set(c, { kp, mask });\n\t\t\tif (!known) this.unsaved++;\n\t\t\tif (this.unsaved >= 24) await this.saveCache();\n\t\t\tif (this.unsavedSubjects >= 24) await this.saveSubjects();\n\t\t}\n\t\tif (this.unsaved > 0) await this.saveCache();\n\t\tif (this.unsavedSubjects > 0) await this.saveSubjects();\n\t}\n\n\tprivate setSize(width: number, height: number): void {\n\t\tthis.sourceWidth = width;\n\t\tthis.sourceHeight = height;\n\t\tthis.cellW = Math.ceil(width / this.cell);\n\t\tthis.cellH = Math.ceil(height / this.cell);\n\t}\n\n\t/** @internal */\n\tsize(): { width: number; height: number } {\n\t\treturn { width: this.sourceWidth, height: this.sourceHeight };\n\t}\n\n\t/** @internal Raw result for a clip frame, or throws when it was never analysed. */\n\tresult(c: number): FrameResult | undefined {\n\t\treturn this.results.get(Math.max(0, c));\n\t}\n\n\t/** @internal Confidence-weighted keypoint over the smoothing window, in source px. */\n\tkeypoint(k: number, c: number): [number, number, number] {\n\t\tc = Math.max(0, c);\n\t\tconst key = `${k}:${c}`;\n\t\tconst hit = this.smoothed.get(key);\n\t\tif (hit) return hit;\n\t\tconst avg = (center: number): [number, number, number] | null => {\n\t\t\tlet sx = 0;\n\t\t\tlet sy = 0;\n\t\t\tlet sv = 0;\n\t\t\tlet sw = 0;\n\t\t\tfor (let g = center - this.smoothing; g <= center + this.smoothing; g++) {\n\t\t\t\tconst r = this.mustHave(g < 0 ? 0 : g);\n\t\t\t\tif (!r.kp) continue;\n\t\t\t\tconst v = r.kp[k * 3 + 2];\n\t\t\t\tconst w = (this.smoothing + 1 - Math.abs(g - center)) * v * v;\n\t\t\t\tsx += r.kp[k * 3] * w;\n\t\t\t\tsy += r.kp[k * 3 + 1] * w;\n\t\t\t\tsv += v * w;\n\t\t\t\tsw += w;\n\t\t\t}\n\t\t\treturn sw > 1e-6 ? [sx / sw, sy / sw, sv / sw] : null;\n\t\t};\n\t\tlet out: [number, number, number] | null = null;\n\t\t// Lost? Hold the last place the person was seen (within HOLD frames).\n\t\tfor (let d = 0; d <= HOLD && !out; d++) if (c - d >= 0) out = avg(c - d);\n\t\tout ??= [this.sourceWidth / 2, this.sourceHeight / 2, 0];\n\t\tthis.smoothed.set(key, out);\n\t\treturn out;\n\t}\n\n\t/** @internal Softened silhouette grid for a clip frame (null: no person). */\n\tblurredMask(c: number): Float32Array | null {\n\t\tc = Math.max(0, c);\n\t\tif (this.blurred.has(c)) return this.blurred.get(c) ?? null;\n\t\tconst r = this.mustHave(c);\n\t\tconst grid = r.mask ? boxBlur(r.mask, this.cellW, this.cellH, 2) : null;\n\t\tthis.blurred.set(c, grid);\n\t\treturn grid;\n\t}\n\n\t/** @internal */\n\tgrid(): { cell: number; width: number; height: number } {\n\t\treturn { cell: this.cell, width: this.cellW, height: this.cellH };\n\t}\n\n\tprivate mustHave(c: number): FrameResult {\n\t\tconst r = this.results.get(c);\n\t\tif (r) return r;\n\t\tthrow new Error(\n\t\t\t`ClipVision \"${this.source}\": frame ${c} is not analysed yet. ` +\n\t\t\t\t\"Read it while rendering (the composition prepares each frame), in a live physics world, \" +\n\t\t\t\t`or after \\`await clip.ready(frame)\\`.`,\n\t\t);\n\t}\n\n\t// ── Persistence (Node) ────────────────────────────────────────────────\n\n\tprivate cacheFile?: string | null;\n\n\tprivate async cachePath(): Promise<string | null> {\n\t\tif (this.cacheFile !== undefined) return this.cacheFile;\n\t\tthis.cacheFile = null;\n\t\tif (\n\t\t\tthis.options.cacheDir === false ||\n\t\t\ttypeof process === \"undefined\" ||\n\t\t\t!process.versions?.node\n\t\t) {\n\t\t\treturn null;\n\t\t}\n\t\ttry {\n\t\t\tconst [fs, path, os, crypto] = await Promise.all([\n\t\t\t\timport(\"node:fs\"),\n\t\t\t\timport(\"node:path\"),\n\t\t\t\timport(\"node:os\"),\n\t\t\t\timport(\"node:crypto\"),\n\t\t\t]);\n\t\t\tconst stat = fs.statSync(this.source);\n\t\t\tconst dir =\n\t\t\t\tthis.options.cacheDir ??\n\t\t\t\tprocess.env.FRAMEFIELDS_VISION_CACHE_DIR ??\n\t\t\t\tpath.join(os.homedir(), \".cache\", \"framefields\", \"vision\");\n\t\t\tconst o = this.options;\n\t\t\tconst key = JSON.stringify([\n\t\t\t\tCACHE_VERSION,\n\t\t\t\tpath.resolve(this.source),\n\t\t\t\tstat.size,\n\t\t\t\tstat.mtimeMs,\n\t\t\t\tthis.fps,\n\t\t\t\to.pose ?? true,\n\t\t\t\to.mask ?? true,\n\t\t\t\tthis.cell,\n\t\t\t\to.variant ?? \"s\",\n\t\t\t\to.confidence ?? null,\n\t\t\t]);\n\t\t\tconst hash = crypto\n\t\t\t\t.createHash(\"sha256\")\n\t\t\t\t.update(key)\n\t\t\t\t.digest(\"hex\")\n\t\t\t\t.slice(0, 24);\n\t\t\tfs.mkdirSync(dir, { recursive: true });\n\t\t\tthis.cacheFile = path.join(\n\t\t\t\tdir,\n\t\t\t\t`${path.basename(this.source)}.${hash}.json`,\n\t\t\t);\n\t\t} catch {\n\t\t\tthis.cacheFile = null; // remote URL or unreadable: memory only\n\t\t}\n\t\treturn this.cacheFile;\n\t}\n\n\tprivate async loadCache(): Promise<void> {\n\t\tconst file = await this.cachePath();\n\t\tif (!file) return;\n\t\ttry {\n\t\t\tconst fs = await import(\"node:fs\");\n\t\t\tif (!fs.existsSync(file)) return;\n\t\t\tconst json = JSON.parse(fs.readFileSync(file, \"utf8\")) as {\n\t\t\t\twidth: number;\n\t\t\t\theight: number;\n\t\t\t\tcell: number;\n\t\t\t\tframes: Record<string, { kp: number[] | null; mask: string | null }>;\n\t\t\t};\n\t\t\tif (json.cell !== this.cell) return;\n\t\t\tthis.setSize(json.width, json.height);\n\t\t\tfor (const [c, r] of Object.entries(json.frames)) {\n\t\t\t\tthis.results.set(Number(c), {\n\t\t\t\t\tkp: r.kp ? Float32Array.from(r.kp) : null,\n\t\t\t\t\tmask: r.mask ? new Uint8Array(Buffer.from(r.mask, \"base64\")) : null,\n\t\t\t\t});\n\t\t\t}\n\t\t} catch {\n\t\t\t// A damaged cache is recomputed.\n\t\t}\n\t}\n\n\tprivate async saveCache(): Promise<void> {\n\t\tthis.unsaved = 0;\n\t\tconst file = await this.cachePath();\n\t\tif (!file || !this.sourceWidth) return;\n\t\tconst frames: Record<string, { kp: number[] | null; mask: string | null }> =\n\t\t\t{};\n\t\tfor (const [c, r] of this.results) {\n\t\t\tframes[c] = {\n\t\t\t\tkp: r.kp ? Array.from(r.kp, (v) => Math.round(v * 100) / 100) : null,\n\t\t\t\tmask: r.mask ? Buffer.from(r.mask).toString(\"base64\") : null,\n\t\t\t};\n\t\t}\n\t\tconst fs = await import(\"node:fs\");\n\t\tconst tmp = `${file}.${process.pid}.tmp`;\n\t\tfs.writeFileSync(\n\t\t\ttmp,\n\t\t\tJSON.stringify({\n\t\t\t\twidth: this.sourceWidth,\n\t\t\t\theight: this.sourceHeight,\n\t\t\t\tcell: this.cell,\n\t\t\t\tframes,\n\t\t\t}),\n\t\t);\n\t\tfs.renameSync(tmp, file);\n\t}\n\n\t/** Subjects live beside the results: large, and only matte layers read them. */\n\tprivate async subjectsPath(): Promise<string | null> {\n\t\tconst file = await this.cachePath();\n\t\treturn file ? file.replace(/\\.json$/, \".subjects.json\") : null;\n\t}\n\n\tprivate async loadSubjects(): Promise<void> {\n\t\tconst file = await this.subjectsPath();\n\t\tif (!file) return;\n\t\ttry {\n\t\t\tconst fs = await import(\"node:fs\");\n\t\t\tif (!fs.existsSync(file)) return;\n\t\t\tconst json = JSON.parse(fs.readFileSync(file, \"utf8\")) as {\n\t\t\t\twidth: number;\n\t\t\t\theight: number;\n\t\t\t\tframes: Record<\n\t\t\t\t\tstring,\n\t\t\t\t\t{\n\t\t\t\t\t\tcategory: string;\n\t\t\t\t\t\tarea: number;\n\t\t\t\t\t\tvalues: string;\n\t\t\t\t\t\tlengths: string;\n\t\t\t\t\t} | null\n\t\t\t\t>;\n\t\t\t};\n\t\t\tif (this.sourceWidth && json.width !== this.sourceWidth) return;\n\t\t\tif (!this.sourceWidth) this.setSize(json.width, json.height);\n\t\t\tfor (const [c, s] of Object.entries(json.frames)) {\n\t\t\t\tconst lengths = Buffer.from(s?.lengths ?? \"\", \"base64\");\n\t\t\t\tthis.subjects.set(\n\t\t\t\t\tNumber(c),\n\t\t\t\t\ts && {\n\t\t\t\t\t\tcategory: s.category,\n\t\t\t\t\t\tarea: s.area,\n\t\t\t\t\t\tvalues: new Uint8Array(Buffer.from(s.values, \"base64\")),\n\t\t\t\t\t\tlengths: new Uint32Array(\n\t\t\t\t\t\t\tlengths.buffer.slice(\n\t\t\t\t\t\t\t\tlengths.byteOffset,\n\t\t\t\t\t\t\t\tlengths.byteOffset + lengths.byteLength,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t} catch {\n\t\t\t// A damaged cache is recomputed.\n\t\t}\n\t}\n\n\tprivate async saveSubjects(): Promise<void> {\n\t\tthis.unsavedSubjects = 0;\n\t\tconst file = await this.subjectsPath();\n\t\tif (!file || !this.sourceWidth) return;\n\t\tconst frames: Record<\n\t\t\tstring,\n\t\t\t{ category: string; area: number; values: string; lengths: string } | null\n\t\t> = {};\n\t\tfor (const [c, s] of this.subjects) {\n\t\t\tframes[c] = s && {\n\t\t\t\tcategory: s.category,\n\t\t\t\tarea: s.area,\n\t\t\t\tvalues: Buffer.from(s.values).toString(\"base64\"),\n\t\t\t\tlengths: Buffer.from(\n\t\t\t\t\ts.lengths.buffer,\n\t\t\t\t\ts.lengths.byteOffset,\n\t\t\t\t\ts.lengths.byteLength,\n\t\t\t\t).toString(\"base64\"),\n\t\t\t};\n\t\t}\n\t\tconst fs = await import(\"node:fs\");\n\t\tconst tmp = `${file}.${process.pid}.tmp`;\n\t\tfs.writeFileSync(\n\t\t\ttmp,\n\t\t\tJSON.stringify({\n\t\t\t\twidth: this.sourceWidth,\n\t\t\t\theight: this.sourceHeight,\n\t\t\t\tframes,\n\t\t\t}),\n\t\t);\n\t\tfs.renameSync(tmp, file);\n\t}\n}\n\n/**\n * The person in a {@link ClipVision}: pose keypoints and silhouette at any\n * composition frame, in source pixels or, after `place()`, composition\n * pixels. Reads are synchronous; the frame must be analysed (it is while\n * rendering, inside a live physics world, or after `await clip.ready(frame)`).\n */\nexport class PersonTrack {\n\t/** @internal */\n\tconstructor(\n\t\treadonly clip: ClipVision,\n\t\tprivate readonly t?: Transform,\n\t\tprivate readonly placement?: PersonPlacement,\n\t) {}\n\n\t/** The same person in composition pixels for a clip laid out at `placement`. */\n\tplace(placement: PersonPlacement): PersonTrack {\n\t\treturn new PersonTrack(this.clip, undefined, placement);\n\t}\n\n\tprivate transform(): Transform {\n\t\tif (this.t) return this.t;\n\t\tconst p = this.placement;\n\t\tconst { width: sw, height: sh } = this.clip.size();\n\t\tif (!p || !sw) return { sx: 1, sy: 1, ox: 0, oy: 0 };\n\t\tlet sx = p.width / sw;\n\t\tlet sy = p.height / sh;\n\t\tif (p.fit !== \"fill\") {\n\t\t\tconst s = p.fit === \"contain\" ? Math.min(sx, sy) : Math.max(sx, sy);\n\t\t\tsx = s;\n\t\t\tsy = s;\n\t\t}\n\t\treturn {\n\t\t\tsx,\n\t\t\tsy,\n\t\t\tox: (p.x ?? 0) + (p.width - sw * sx) / 2,\n\t\t\toy: (p.y ?? 0) + (p.height - sh * sy) / 2,\n\t\t};\n\t}\n\n\t/** A keypoint at a composition frame (fractional frames interpolate). */\n\tpoint(\n\t\tname: PoseKeypointName,\n\t\tframe: number,\n\t): { x: number; y: number; visibility: number } {\n\t\tconst k = keypointIndex(name);\n\t\tconst c = this.clip.clipFrame(frame);\n\t\tconst c0 = Math.floor(c);\n\t\tconst u = c - c0;\n\t\tconst a = this.clip.keypoint(k, c0);\n\t\tconst b = u > 0 ? this.clip.keypoint(k, c0 + 1) : a;\n\t\tconst t = this.transform();\n\t\treturn {\n\t\t\tx: (a[0] + (b[0] - a[0]) * u) * t.sx + t.ox,\n\t\t\ty: (a[1] + (b[1] - a[1]) * u) * t.sy + t.oy,\n\t\t\tvisibility: a[2] + (b[2] - a[2]) * u,\n\t\t};\n\t}\n\n\t/** Signals for a keypoint, for `.signal(\"x\", …)`; read while rendering. */\n\tsignals(name: PoseKeypointName): {\n\t\tx: FrameSignal<number>;\n\t\ty: FrameSignal<number>;\n\t\tvisibility: FrameSignal<number>;\n\t} {\n\t\tconst read = (axis: \"x\" | \"y\" | \"visibility\") =>\n\t\t\tSignal.builder({\n\t\t\t\ttype: \"custom\",\n\t\t\t\tfn: (ctx) => this.point(name, ctx.frame)[axis],\n\t\t\t}) as FrameSignal<number>;\n\t\treturn { x: read(\"x\"), y: read(\"y\"), visibility: read(\"visibility\") };\n\t}\n\n\t/**\n\t * @internal The softened silhouette grid at a composition frame and how\n\t * placed px map onto it (`cell = (px − origin) / scale − 0.5`), for GPU\n\t * consumers such as particles. Null when no person was found.\n\t */\n\tsilhouetteGrid(frame: number): {\n\t\tdata: Float32Array;\n\t\twidth: number;\n\t\theight: number;\n\t\toriginX: number;\n\t\toriginY: number;\n\t\tscaleX: number;\n\t\tscaleY: number;\n\t} | null {\n\t\tconst grid = this.clip.blurredMask(Math.round(this.clip.clipFrame(frame)));\n\t\tif (!grid) return null;\n\t\tconst { cell, width, height } = this.clip.grid();\n\t\tconst t = this.transform();\n\t\treturn {\n\t\t\tdata: grid,\n\t\t\twidth,\n\t\t\theight,\n\t\t\toriginX: t.ox,\n\t\t\toriginY: t.oy,\n\t\t\tscaleX: cell * t.sx,\n\t\t\tscaleY: cell * t.sy,\n\t\t};\n\t}\n\n\t/**\n\t * The silhouette near a point at a composition frame: `alpha` 0–1 (softened\n\t * over a few cells; inside > 0.5) and its gradient `gx`, `gy` per px,\n\t * pointing into the body. Push things out with `-gradient`.\n\t */\n\tsample(\n\t\tframe: number,\n\t\tx: number,\n\t\ty: number,\n\t): { alpha: number; gx: number; gy: number } {\n\t\tconst grid = this.clip.blurredMask(Math.round(this.clip.clipFrame(frame)));\n\t\tif (!grid) return { alpha: 0, gx: 0, gy: 0 };\n\t\tconst { cell, width: w, height: h } = this.clip.grid();\n\t\tconst t = this.transform();\n\t\tconst cx = (x - t.ox) / t.sx / cell - 0.5;\n\t\tconst cy = (y - t.oy) / t.sy / cell - 0.5;\n\t\tconst read = (gx: number, gy: number) =>\n\t\t\tgx < 0 || gy < 0 || gx >= w || gy >= h ? 0 : grid[gy * w + gx];\n\t\tconst bil = (px: number, py: number) => {\n\t\t\tconst x0 = Math.floor(px);\n\t\t\tconst y0 = Math.floor(py);\n\t\t\tconst ux = px - x0;\n\t\t\tconst uy = py - y0;\n\t\t\tconst a = read(x0, y0) + (read(x0 + 1, y0) - read(x0, y0)) * ux;\n\t\t\tconst b =\n\t\t\t\tread(x0, y0 + 1) + (read(x0 + 1, y0 + 1) - read(x0, y0 + 1)) * ux;\n\t\t\treturn a + (b - a) * uy;\n\t\t};\n\t\treturn {\n\t\t\talpha: bil(cx, cy),\n\t\t\tgx: (bil(cx + 1, cy) - bil(cx - 1, cy)) / (2 * cell * t.sx),\n\t\t\tgy: (bil(cx, cy + 1) - bil(cx, cy - 1)) / (2 * cell * t.sy),\n\t\t};\n\t}\n}\n\nfunction keypointIndex(name: PoseKeypointName): number {\n\tconst i = COCO17_KEYPOINT_NAMES.indexOf(name);\n\tif (i < 0) {\n\t\tthrow new Error(\n\t\t\t`Unknown keypoint \"${name}\". Use one of ${COCO17_KEYPOINT_NAMES.join(\", \")}.`,\n\t\t);\n\t}\n\treturn i;\n}\n\n/** RGBA pixels of a decoded frame (headless buffer, or a canvas in the browser). */\nasync function decodedPixels(\n\tframe: {\n\t\twidth: number;\n\t\theight: number;\n\t\tbuffer?: Uint8Array;\n\t\tcanvas?: unknown;\n\t} | null,\n): Promise<{\n\tdata: Uint8Array | Uint8ClampedArray;\n\twidth: number;\n\theight: number;\n} | null> {\n\tif (!frame || frame.width <= 0) return null;\n\tif (frame.buffer)\n\t\treturn { data: frame.buffer, width: frame.width, height: frame.height };\n\tconst canvas = frame.canvas as\n\t\t| {\n\t\t\t\tgetContext(type: \"2d\"): {\n\t\t\t\t\tgetImageData(\n\t\t\t\t\t\tx: number,\n\t\t\t\t\t\ty: number,\n\t\t\t\t\t\tw: number,\n\t\t\t\t\t\th: number,\n\t\t\t\t\t): { data: Uint8ClampedArray };\n\t\t\t\t} | null;\n\t\t }\n\t\t| undefined;\n\tconst ctx = canvas?.getContext(\"2d\");\n\tif (!ctx) return null;\n\treturn {\n\t\tdata: ctx.getImageData(0, 0, frame.width, frame.height).data,\n\t\twidth: frame.width,\n\t\theight: frame.height,\n\t};\n}\n\ntype Segmentation = Awaited<ReturnType<VisionRunner[\"segment\"]>>;\n\n/**\n * The largest person's mask, plus instances that overlap it and are no more\n * than twice its size (a flowing dress often comes back as \"kite\").\n */\nfunction personSilhouette(seg: Segmentation): Uint8Array | undefined {\n\tconst people = seg.masks.filter((m) => m.category === \"person\");\n\tif (people.length === 0) return undefined;\n\tconst person = people.reduce((a, b) => (b.area > a.area ? b : a));\n\tconst box = seg.detections[person.detectionIndex]?.boundingBox;\n\tconst out = new Uint8Array(person.mask);\n\tif (!box) return out;\n\tfor (const m of seg.masks) {\n\t\tif (m === person || m.area > person.area * 2) continue;\n\t\tconst b = seg.detections[m.detectionIndex]?.boundingBox;\n\t\tif (!b) continue;\n\t\tconst ix = Math.max(\n\t\t\t0,\n\t\t\tMath.min(box.originX + box.width, b.originX + b.width) -\n\t\t\t\tMath.max(box.originX, b.originX),\n\t\t);\n\t\tconst iy = Math.max(\n\t\t\t0,\n\t\t\tMath.min(box.originY + box.height, b.originY + b.height) -\n\t\t\t\tMath.max(box.originY, b.originY),\n\t\t);\n\t\tif (ix * iy < 0.3 * b.width * b.height) continue;\n\t\tfor (let i = 0; i < out.length; i++)\n\t\t\tif (m.mask[i] > out[i]) out[i] = m.mask[i];\n\t}\n\treturn out;\n}\n\nfunction downsampleMean(\n\tsrc: Uint8Array,\n\tw: number,\n\th: number,\n\tcell: number,\n\tdst: Uint8Array,\n\tmw: number,\n\tmh: number,\n): void {\n\tfor (let my = 0; my < mh; my++) {\n\t\tfor (let mx = 0; mx < mw; mx++) {\n\t\t\tlet sum = 0;\n\t\t\tlet n = 0;\n\t\t\tfor (let y = my * cell; y < Math.min(h, (my + 1) * cell); y++) {\n\t\t\t\tfor (let x = mx * cell; x < Math.min(w, (mx + 1) * cell); x++) {\n\t\t\t\t\tsum += src[y * w + x];\n\t\t\t\t\tn++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tdst[my * mw + mx] = n ? Math.round(sum / n) : 0;\n\t\t}\n\t}\n}\n\n/** A mask as (value, run length) pairs: long flat runs with soft edges. */\nfunction encodeRuns(mask: Uint8Array): {\n\tvalues: Uint8Array;\n\tlengths: Uint32Array;\n} {\n\tlet runs = 0;\n\tfor (let i = 1; i <= mask.length; i++)\n\t\tif (i === mask.length || mask[i] !== mask[i - 1]) runs++;\n\tconst values = new Uint8Array(runs);\n\tconst lengths = new Uint32Array(runs);\n\tlet r = 0;\n\tlet start = 0;\n\tfor (let i = 1; i <= mask.length; i++) {\n\t\tif (i === mask.length || mask[i] !== mask[start]) {\n\t\t\tvalues[r] = mask[start];\n\t\t\tlengths[r++] = i - start;\n\t\t\tstart = i;\n\t\t}\n\t}\n\treturn { values, lengths };\n}\n\nfunction decodeRuns(\n\truns: { values: Uint8Array; lengths: Uint32Array },\n\tsize: number,\n): Uint8Array {\n\tconst out = new Uint8Array(size);\n\tlet at = 0;\n\tfor (let r = 0; r < runs.values.length; r++) {\n\t\tconst end = Math.min(size, at + runs.lengths[r]);\n\t\tif (runs.values[r] !== 0) out.fill(runs.values[r], at, end);\n\t\tat = end;\n\t}\n\treturn out;\n}\n\n/** Separable box blur to 0–1, so gradients reach a little past the edge. */\nfunction boxBlur(\n\tsrc: Uint8Array,\n\tw: number,\n\th: number,\n\tr: number,\n): Float32Array {\n\tconst tmp = new Float32Array(w * h);\n\tconst dst = new Float32Array(w * h);\n\tfor (let y = 0; y < h; y++) {\n\t\tfor (let x = 0; x < w; x++) {\n\t\t\tlet s = 0;\n\t\t\tlet n = 0;\n\t\t\tfor (let k = -r; k <= r; k++) {\n\t\t\t\tconst xx = x + k;\n\t\t\t\tif (xx >= 0 && xx < w) {\n\t\t\t\t\ts += src[y * w + xx];\n\t\t\t\t\tn++;\n\t\t\t\t}\n\t\t\t}\n\t\t\ttmp[y * w + x] = s / n / 255;\n\t\t}\n\t}\n\tfor (let y = 0; y < h; y++) {\n\t\tfor (let x = 0; x < w; x++) {\n\t\t\tlet s = 0;\n\t\t\tlet n = 0;\n\t\t\tfor (let k = -r; k <= r; k++) {\n\t\t\t\tconst yy = y + k;\n\t\t\t\tif (yy >= 0 && yy < h) {\n\t\t\t\t\ts += tmp[yy * w + x];\n\t\t\t\t\tn++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tdst[y * w + x] = s / n;\n\t\t}\n\t}\n\treturn dst;\n}\n\ntype SeedFrame = {\n\tkp: number[] | null;\n\tmask: Uint8Array | null;\n\t/** Source-sized subject mask for render-time mattes; null = no subject. */\n\tsubject?: Uint8Array | null;\n};\n\n/** @internal Test hook: a clip whose results are given instead of computed. */\nexport function clipVisionFromResults(\n\tfps: number,\n\tsize: { width: number; height: number; cell: number },\n\tframes: SeedFrame[],\n\toptions: ClipVisionOptions = {},\n): ClipVision {\n\tconst clip = new ClipVision(\"memory\", fps, {\n\t\t...options,\n\t\tmaskCell: size.cell,\n\t\tcacheDir: false,\n\t});\n\treturn seedClipVision(clip, size, frames);\n}\n\n/** @internal Test hook: gives a clip's per-frame results instead of computing them. */\nexport function seedClipVision(\n\tclip: ClipVision,\n\tsize: { width: number; height: number },\n\tframes: SeedFrame[],\n): ClipVision {\n\tconst c = clip as unknown as {\n\t\tsetSize(w: number, h: number): void;\n\t\tresults: Map<number, FrameResult>;\n\t\tsubjects: Map<number, SubjectResult | null>;\n\t};\n\tc.setSize(size.width, size.height);\n\tframes.forEach((f, i) => {\n\t\tc.results.set(i, {\n\t\t\tkp: f.kp ? Float32Array.from(f.kp) : null,\n\t\t\tmask: f.mask,\n\t\t});\n\t\tif (f.subject === undefined) return;\n\t\tlet area = 0;\n\t\tfor (const v of f.subject ?? []) area += v;\n\t\tc.subjects.set(\n\t\t\ti,\n\t\t\tf.subject && {\n\t\t\t\tcategory: \"person\",\n\t\t\t\tarea: Math.round(area / 255),\n\t\t\t\t...encodeRuns(f.subject),\n\t\t\t},\n\t\t);\n\t});\n\treturn clip;\n}\n","import {\n\ttype AnimatableProp,\n\ttype KeyframeTuple,\n\tLayerAnimation,\n} from \"@framefields/compositions/program\";\nimport { type FrameContext, type FrameSignal, Signal } from \"@framefields/core\";\nimport type { SimBody, SimWorld } from \"./backend.js\";\n\n/**\n * A value read every simulated frame: a number, a signal (sampled at the\n * composition frame, like `.signal()` tracks), or `(frame) => value` where\n * `frame` is the composition frame.\n */\nexport type PhysicsDriver =\n\t| number\n\t| ((frame: number) => number)\n\t| { get(ctx?: FrameContext): number };\n\nexport interface PhysicsWorldOptions {\n\t/** Composition frame rate. */\n\tfps: number;\n\t/** How many frames to simulate. Signals hold the last frame afterwards. */\n\tframes: number;\n\t/**\n\t * Composition frame the simulation's frame 0 lands on (default 0). Set it\n\t * to a scene's start so a world inside that scene starts with it.\n\t */\n\tstartFrame?: number;\n\t/** Pixels per physics meter (default 100). Only changes how stiff and heavy things feel. */\n\tpixelsPerMeter?: number;\n\t/** Solver steps per frame (default 4). Raise for fast, thin or stacked bodies. */\n\tsubsteps?: number;\n\t/** Frames an impact envelope takes to fall to ~37% (default 8). */\n\timpactDecay?: number;\n\t/** Velocity change, px/s, that reads as impact 1 (default 1500). */\n\timpactReference?: number;\n}\n\nexport interface BodyCommonOptions {\n\t/** `\"dynamic\"` (default) falls and collides; `\"fixed\"` never moves; `\"kinematic\"` follows `follow` and pushes others. */\n\ttype?: \"dynamic\" | \"fixed\" | \"kinematic\";\n\t/** Bounciness, 0–1 (default 0.3). */\n\trestitution?: number;\n\t/** Default 0.6. */\n\tfriction?: number;\n\t/** Mass per area/volume (default 1). Heavier bodies push lighter ones. */\n\tdensity?: number;\n\t/** Velocity damping per second (default 0). */\n\tlinearDamping?: number;\n\t/** Spin damping per second (default 0). */\n\tangularDamping?: number;\n\t/** Multiplies world gravity for this body (default 1; 0 floats). */\n\tgravityScale?: number;\n\t/** Never rotates. */\n\tlockRotation?: boolean;\n\t/** Continuous collision detection for very fast bodies (default false). */\n\tccd?: boolean;\n\t/** Collides with nothing; still moves, still reports contacts (triggers). */\n\tsensor?: boolean;\n\t/** Simulation frame the body wakes up; it holds its place before (default 0). */\n\tstartFrame?: number;\n\t/**\n\t * How the result reaches the layer: `\"signals\"` (default) binds the\n\t * body's signals, `\"keyframes\"` writes plain keyframes, `\"none\"` leaves\n\t * the layer alone (read the signals yourself).\n\t */\n\toutput?: \"signals\" | \"keyframes\" | \"none\";\n}\n\n/** What `world.live()` needs from a composition. */\nexport interface LiveHost {\n\tonPrepareFrame(\n\t\tcallback: (ctx: { frame: number }) => Promise<void> | void,\n\t): unknown;\n\tprepareVision?(frame: number): Promise<void>;\n}\n\ninterface Stepper<B, V, R> {\n\t/** Last simulated frame, relative to the world's start. */\n\tcurrent: number;\n\tfreed: boolean;\n\tbySim: Map<SimBody<V, R>, B>;\n\tkinematicFrom: Map<B, { position: V; rotation: R }>;\n\t/** Impact envelope level per body after `current`. */\n\tlevel: Map<B, number>;\n}\n\nexport interface PhysicsCollision<B> {\n\t/** Composition frame of first contact. */\n\tframe: number;\n\t/** The other body. */\n\twith: B;\n\t/** Velocity change of the harder-hit body, px/s. */\n\tspeed: number;\n}\n\nexport interface PhysicsBakeOptions {\n\t/** Largest error a dropped keyframe may leave, px (default 0.25). Degrees use a fifth of it. */\n\ttolerance?: number;\n}\n\nconst CHANNEL_TOLERANCE_SCALE: Record<string, number> = {\n\trotation: 0.2,\n\trotateX: 0.2,\n\trotateY: 0.2,\n\trotateZ: 0.2,\n};\n\nexport function sampleDriver(\n\tdriver: PhysicsDriver,\n\tframe: number,\n\tfps: number,\n): number {\n\tif (typeof driver === \"number\") return driver;\n\tif (typeof driver === \"function\") return driver(frame);\n\tconst time = frame / fps;\n\treturn driver.get({\n\t\tframe,\n\t\tfps,\n\t\ttime,\n\t\tduration: 0,\n\t\tdurationMs: 0,\n\t\tprogress: 0,\n\t\tdeltaTime: 1 / fps,\n\t});\n}\n\n/** Shortest-path angle continuation so rotation never jumps by 360. */\nexport function unwrapDegrees(previous: number, next: number): number {\n\tlet d = next - previous;\n\td -= Math.round(d / 360) * 360;\n\treturn previous + d;\n}\n\n/**\n * Ramer–Douglas–Peucker over one channel: the fewest linear keyframes that\n * stay within `tolerance` of every simulated frame.\n */\nexport function simplifyKeys(\n\tvalues: ArrayLike<number>,\n\ttolerance: number,\n): KeyframeTuple[] {\n\tconst n = values.length;\n\tif (n === 0) return [];\n\tconst keep = new Uint8Array(n);\n\tkeep[0] = 1;\n\tkeep[n - 1] = 1;\n\tconst stack: Array<[number, number]> = [[0, n - 1]];\n\twhile (stack.length > 0) {\n\t\tconst [a, b] = stack.pop() as [number, number];\n\t\tlet worst = -1;\n\t\tlet worstErr = tolerance;\n\t\tfor (let i = a + 1; i < b; i++) {\n\t\t\tconst t = (i - a) / (b - a);\n\t\t\tconst lerp = values[a] + (values[b] - values[a]) * t;\n\t\t\tconst err = Math.abs(values[i] - lerp);\n\t\t\tif (err > worstErr) {\n\t\t\t\tworstErr = err;\n\t\t\t\tworst = i;\n\t\t\t}\n\t\t}\n\t\tif (worst >= 0) {\n\t\t\tkeep[worst] = 1;\n\t\t\tstack.push([a, worst], [worst, b]);\n\t\t}\n\t}\n\tconst keys: KeyframeTuple[] = [];\n\tfor (let i = 0; i < n; i++) {\n\t\tif (keep[i]) keys.push([i, round4(values[i]), \"none\"]);\n\t}\n\t// A constant channel needs a single key.\n\tif (keys.length === 2 && keys[0][1] === keys[1][1]) keys.pop();\n\treturn keys;\n}\n\nfunction round4(v: number): number {\n\treturn Math.round(v * 1e4) / 1e4;\n}\n\n/**\n * Per-frame recordings of one body, indexed by composition frame. Arrays are\n * filled when the world simulates; reading a signal before that simulates.\n */\nexport class Recording {\n\treadonly channels = new Map<string, Float32Array>();\n\tprivate readonly signals = new Map<string, FrameSignal<number>>();\n\n\tconstructor(\n\t\treadonly length: number,\n\t\tprivate readonly fps: number,\n\t\tprivate readonly ensure: () => void,\n\t) {}\n\n\tchannel(name: string): Float32Array {\n\t\tlet arr = this.channels.get(name);\n\t\tif (!arr) {\n\t\t\tarr = new Float32Array(this.length);\n\t\t\tthis.channels.set(name, arr);\n\t\t}\n\t\treturn arr;\n\t}\n\n\t/**\n\t * A per-frame signal over a channel. Creating it does nothing; the first\n\t * value read runs the simulation (offline worlds), so signals can be bound\n\t * while bodies are still being added.\n\t */\n\tsignal(name: string): FrameSignal<number> {\n\t\tlet sig = this.signals.get(name);\n\t\tif (!sig) {\n\t\t\tconst arr = this.channel(name);\n\t\t\tconst fps = this.fps;\n\t\t\tsig = Signal.builder({\n\t\t\t\ttype: \"custom\",\n\t\t\t\tfn: (ctx: { frame: number; fps?: number }) => {\n\t\t\t\t\tthis.ensure();\n\t\t\t\t\tconst f =\n\t\t\t\t\t\tctx.fps && ctx.fps !== fps\n\t\t\t\t\t\t\t? (ctx.frame / ctx.fps) * fps\n\t\t\t\t\t\t\t: ctx.frame;\n\t\t\t\t\tconst i = Math.max(0, Math.min(arr.length - 1, Math.round(f)));\n\t\t\t\t\treturn arr[i];\n\t\t\t\t},\n\t\t\t}) as unknown as FrameSignal<number>;\n\t\t\tthis.signals.set(name, sig);\n\t\t}\n\t\treturn sig;\n\t}\n}\n\n/** What the shared stepping loop needs from a 2D or 3D body. */\nexport interface CoreBody<V extends number[], R> {\n\treadonly sim: SimBody<V, R>;\n\treadonly type: \"dynamic\" | \"fixed\" | \"kinematic\";\n\treadonly startFrame: number;\n\treadonly gravityScale: number;\n\t/** Unset: signals, or keyframes under `bakeKeyframes()`. */\n\treadonly output?: \"signals\" | \"keyframes\" | \"none\";\n\treadonly recording: Recording;\n\treadonly collisions: PhysicsCollision<unknown>[];\n\treadonly layer?: Record<string, unknown>;\n\t/** Kinematic pose (backend units) at a composition frame, if it follows drivers. */\n\tkinematicTarget?(frame: number): { position: V; rotation: R } | undefined;\n\t/** Writes the body's state for one composition frame into its recording. */\n\trecord(index: number, previousIndex: number): void;\n\t/** Props bound to the layer, with the recording channel each one reads. */\n\tboundChannels(): Array<[AnimatableProp, string]>;\n}\n\ninterface ForceEntry<V> {\n\tbody: CoreBody<number[], unknown>;\n\taccel: (frame: number) => V;\n}\n\ninterface ImpulseEntry<V> {\n\tbody: CoreBody<number[], unknown>;\n\tframe: number;\n\tdv: V;\n}\n\n/**\n * Stepping, recording, impacts and output shared by `PhysicsWorld2D` and\n * `PhysicsWorld3D`. V is a vector in backend units (meters).\n */\nexport abstract class WorldCore<\n\tV extends number[],\n\tR,\n\tB extends CoreBody<V, R>,\n> {\n\treadonly fps: number;\n\treadonly frames: number;\n\treadonly startFrame: number;\n\treadonly pixelsPerMeter: number;\n\tprotected readonly substeps: number;\n\tprotected readonly impactDecay: number;\n\tprotected readonly impactReference: number;\n\tprotected readonly bodies: B[] = [];\n\tprotected readonly forces: ForceEntry<V>[] = [];\n\tprotected readonly impulses: ImpulseEntry<V>[] = [];\n\tprotected readonly fields: Array<{\n\t\ttargets?: Set<B>;\n\t\taccel: (body: B, frame: number) => V | null | undefined;\n\t}> = [];\n\tprivate readonly worldRecording: Recording;\n\tprivate readonly allCollisions: Array<PhysicsCollision<B> & { body: B }> = [];\n\t/** No more bodies, joints or forces: the world has started (or finished). */\n\tprivate locked = false;\n\tprivate liveMode = false;\n\tprivate stepper?: Stepper<B, V, R>;\n\tprivate chain: Promise<void> = Promise.resolve();\n\n\tprotected constructor(\n\t\tprotected readonly sim: SimWorld<V, SimBody<V, R>, unknown>,\n\t\tprotected readonly gravity: V,\n\t\toptions: PhysicsWorldOptions,\n\t) {\n\t\tif (!(options.fps > 0)) throw new Error(\"Physics: `fps` must be > 0.\");\n\t\tif (!(options.frames >= 1) || !Number.isInteger(options.frames)) {\n\t\t\tthrow new Error(\"Physics: `frames` must be a positive integer.\");\n\t\t}\n\t\tthis.fps = options.fps;\n\t\tthis.frames = options.frames;\n\t\tthis.startFrame = Math.max(0, Math.round(options.startFrame ?? 0));\n\t\tthis.pixelsPerMeter = options.pixelsPerMeter ?? 100;\n\t\tthis.substeps = Math.max(1, Math.round(options.substeps ?? 4));\n\t\tthis.impactDecay = Math.max(0.5, options.impactDecay ?? 8);\n\t\tthis.impactReference = options.impactReference ?? 1500;\n\t\tthis.worldRecording = this.newRecording();\n\t}\n\n\t/** First contacts so far (all of them once simulated), in frame order. */\n\tget collisions(): ReadonlyArray<PhysicsCollision<B> & { body: B }> {\n\t\tthis.ensureSimulated();\n\t\treturn this.allCollisions;\n\t}\n\n\t/** Loudest impact envelope of any body each frame: camera shake, flashes, hit sounds. */\n\tget impact(): FrameSignal<number> {\n\t\treturn this.worldRecording.signal(\"impact\");\n\t}\n\n\t/** Runs the whole simulation now (once) and binds every body's layer per its `output`. */\n\tsimulate(): this {\n\t\tif (this.liveMode)\n\t\t\tthrow new Error(\n\t\t\t\t\"Physics: this world is live; it steps as frames render.\",\n\t\t\t);\n\t\tthis.ensureSimulated();\n\t\treturn this;\n\t}\n\n\t/** Like {@link simulate}, but writes keyframes for every body whose `output` was left at its default. */\n\tbakeKeyframes(options: PhysicsBakeOptions = {}): this {\n\t\tif (this.locked) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Physics: bakeKeyframes() must come before simulate(), live() or reading any body signal.\",\n\t\t\t);\n\t\t}\n\t\tthis.bakeDefault = options;\n\t\tthis.ensureSimulated();\n\t\treturn this;\n\t}\n\n\t/**\n\t * Steps the world as the composition renders instead of all at once: before\n\t * each frame draws, the world advances to it, after the composition's\n\t * vision clips (`comp.vision`) and any `inputs` have that frame ready. Use\n\t * it when bodies follow a performer, so nothing is analysed up front and a\n\t * preview starts at once. Frames already simulated are kept, so scrubbing\n\t * back costs nothing; jumping ahead simulates the frames in between.\n\t * Signals only; `bakeKeyframes()` needs the whole run up front.\n\t */\n\tlive(\n\t\tcomp: LiveHost,\n\t\toptions: {\n\t\t\tinputs?: ReadonlyArray<{ ready(frame: number): Promise<void> }>;\n\t\t} = {},\n\t): this {\n\t\tif (this.locked) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Physics: live() must come before simulate() or reading any body signal.\",\n\t\t\t);\n\t\t}\n\t\tthis.locked = true;\n\t\tthis.liveMode = true;\n\t\tconst prepare = async (frame: number) => {\n\t\t\tawait comp.prepareVision?.(frame);\n\t\t\tfor (const input of options.inputs ?? []) await input.ready(frame);\n\t\t};\n\t\tthis.prepareInputs = prepare;\n\t\tfor (const body of this.bodies) this.bind(body);\n\t\tcomp.onPrepareFrame((ctx) => this.advanceTo(ctx.frame));\n\t\treturn this;\n\t}\n\n\t/**\n\t * Live worlds: simulates up to composition frame `frame` (no-op when it\n\t * already has). Calls queue, so frames are stepped once, in order.\n\t */\n\tadvanceTo(frame: number): Promise<void> {\n\t\tthis.chain = this.chain.then(async () => {\n\t\t\tconst target = Math.min(\n\t\t\t\tthis.frames - 1,\n\t\t\t\tMath.round(frame) - this.startFrame,\n\t\t\t);\n\t\t\tif (!this.stepper) {\n\t\t\t\tawait this.prepareInputs?.(this.startFrame);\n\t\t\t\tthis.stepper = this.begin();\n\t\t\t}\n\t\t\tconst st = this.stepper;\n\t\t\twhile (st.current < target) {\n\t\t\t\tconst next = st.current + 1;\n\t\t\t\tawait this.prepareInputs?.(this.startFrame + next);\n\t\t\t\tthis.stepFrame(st, next);\n\t\t\t}\n\t\t\tif (st.current === this.frames - 1 && !st.freed) {\n\t\t\t\tst.freed = true;\n\t\t\t\tthis.sim.free();\n\t\t\t}\n\t\t});\n\t\treturn this.chain;\n\t}\n\n\tprivate prepareInputs?: (frame: number) => Promise<void>;\n\tprivate bakeDefault?: PhysicsBakeOptions;\n\n\tprotected newRecording(): Recording {\n\t\treturn new Recording(this.startFrame + this.frames, this.fps, () =>\n\t\t\tthis.ensureSimulated(),\n\t\t);\n\t}\n\n\tprotected assertOpen(): void {\n\t\tif (this.locked) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Physics: the world has already started; add every body, joint and force before simulate(), live() or reading signals.\",\n\t\t\t);\n\t\t}\n\t}\n\n\tprotected addBody(body: B): B {\n\t\tthis.assertOpen();\n\t\tthis.bodies.push(body);\n\t\treturn body;\n\t}\n\n\tprotected addForce(body: B, accel: (frame: number) => V): void {\n\t\tthis.assertOpen();\n\t\tthis.forces.push({\n\t\t\tbody: body as unknown as CoreBody<number[], unknown>,\n\t\t\taccel,\n\t\t});\n\t}\n\n\tprotected addField(\n\t\taccel: (body: B, frame: number) => V | null | undefined,\n\t\ttargets?: readonly B[],\n\t): void {\n\t\tthis.assertOpen();\n\t\tthis.fields.push({ accel, ...(targets && { targets: new Set(targets) }) });\n\t}\n\n\tprotected addImpulse(body: B, frame: number, dv: V): void {\n\t\tthis.assertOpen();\n\t\tthis.impulses.push({\n\t\t\tbody: body as unknown as CoreBody<number[], unknown>,\n\t\t\tframe: Math.round(frame),\n\t\t\tdv,\n\t\t});\n\t}\n\n\tprotected ensureSimulated(): void {\n\t\tif (this.locked) return;\n\t\tthis.locked = true;\n\t\tconst st = this.begin();\n\t\tfor (let f = 1; f < this.frames; f++) this.stepFrame(st, f);\n\t\tst.freed = true;\n\t\tthis.sim.free();\n\t\tfor (const body of this.bodies) this.bind(body);\n\t}\n\n\t/** Records frame 0 and sets every channel to it, so frames not simulated yet hold the start pose. */\n\tprivate begin(): Stepper<B, V, R> {\n\t\tconst { startFrame } = this;\n\t\tconst bodies = this.bodies;\n\t\tconst bySim = new Map<SimBody<V, R>, B>();\n\t\tfor (const b of bodies) bySim.set(b.sim, b);\n\t\tfor (const b of bodies) if (b.startFrame > 0) b.sim.setEnabled(false);\n\t\tconst kinematicFrom = new Map<B, { position: V; rotation: R }>();\n\t\tfor (const b of bodies) {\n\t\t\tb.record(startFrame, -1);\n\t\t\tb.recording.channel(\"impact\");\n\t\t\tconst t = b.kinematicTarget?.(startFrame);\n\t\t\tif (t) kinematicFrom.set(b, t);\n\t\t}\n\t\tthis.worldRecording.channel(\"impact\");\n\t\tfor (const rec of [\n\t\t\t...bodies.map((b) => b.recording),\n\t\t\tthis.worldRecording,\n\t\t]) {\n\t\t\tfor (const arr of rec.channels.values()) arr.fill(arr[startFrame]);\n\t\t}\n\t\treturn {\n\t\t\tcurrent: 0,\n\t\t\tfreed: false,\n\t\t\tbySim,\n\t\t\tkinematicFrom,\n\t\t\tlevel: new Map(bodies.map((b) => [b, 0])),\n\t\t};\n\t}\n\n\tprivate stepFrame(st: Stepper<B, V, R>, f: number): void {\n\t\tconst { fps, startFrame, substeps } = this;\n\t\tconst dt = 1 / (fps * substeps);\n\t\tconst bodies = this.bodies;\n\t\tconst frame = startFrame + f;\n\t\tconst dims = this.gravity.length;\n\t\tconst prevVel = new Map<B, number[]>();\n\t\tfor (const b of bodies) {\n\t\t\t// A body sits at its start pose on its start frame and moves after.\n\t\t\tif (b.startFrame > 0 && f === b.startFrame + 1) b.sim.setEnabled(true);\n\t\t\tprevVel.set(b, b.sim.velocity() as number[]);\n\t\t}\n\t\tconst isActive = (b: B) => b.type === \"dynamic\" && f > b.startFrame;\n\t\t// Velocity each body is expected to gain this frame from gravity,\n\t\t// forces, fields and impulses: anything beyond it came from a contact.\n\t\tconst expected = new Map<B, number[]>();\n\t\tfor (const b of bodies) {\n\t\t\texpected.set(\n\t\t\t\tb,\n\t\t\t\tthis.gravity.map((g) => (isActive(b) ? (g * b.gravityScale) / fps : 0)),\n\t\t\t);\n\t\t}\n\t\tfor (const imp of this.impulses) {\n\t\t\tif (imp.frame !== f) continue;\n\t\t\tconst body = imp.body as unknown as B;\n\t\t\tif (!isActive(body)) continue;\n\t\t\tconst m = body.sim.mass();\n\t\t\tbody.sim.applyImpulse(imp.dv.map((v) => v * m) as V);\n\t\t\tconst e = expected.get(body) as number[];\n\t\t\tfor (let i = 0; i < dims; i++) e[i] += imp.dv[i];\n\t\t}\n\t\tconst frameForces = this.forces\n\t\t\t.filter((fe) => isActive(fe.body as unknown as B))\n\t\t\t.map((fe) => {\n\t\t\t\tconst body = fe.body as unknown as B;\n\t\t\t\tconst a = fe.accel(frame);\n\t\t\t\tconst e = expected.get(body) as number[];\n\t\t\t\tfor (let i = 0; i < dims; i++) e[i] += a[i] / fps;\n\t\t\t\treturn { body, a };\n\t\t\t});\n\t\tconst kinematicTo = new Map<B, { position: V; rotation: R }>();\n\t\tfor (const b of bodies) {\n\t\t\tconst t = b.kinematicTarget?.(frame);\n\t\t\tif (t) kinematicTo.set(b, t);\n\t\t}\n\n\t\tconst started = new Set<string>();\n\t\tconst pairs: Array<[B, B]> = [];\n\t\tfor (let s = 1; s <= substeps; s++) {\n\t\t\tfor (const { body, a } of frameForces) {\n\t\t\t\tconst m = body.sim.mass();\n\t\t\t\tbody.sim.applyImpulse(a.map((v) => v * m * dt) as V);\n\t\t\t}\n\t\t\tfor (const field of this.fields) {\n\t\t\t\tfor (const b of bodies) {\n\t\t\t\t\tif (!isActive(b) || (field.targets && !field.targets.has(b)))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tconst a = field.accel(b, frame);\n\t\t\t\t\tif (!a) continue;\n\t\t\t\t\tconst m = b.sim.mass();\n\t\t\t\t\tb.sim.applyImpulse(a.map((v) => v * m * dt) as V);\n\t\t\t\t\tconst e = expected.get(b) as number[];\n\t\t\t\t\tfor (let i = 0; i < dims; i++) e[i] += a[i] * dt;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const [b, to] of kinematicTo) {\n\t\t\t\tconst from = st.kinematicFrom.get(b) ?? to;\n\t\t\t\tconst k = s / substeps;\n\t\t\t\tb.sim.setKinematicTarget(\n\t\t\t\t\tlerpVec(from.position, to.position, k),\n\t\t\t\t\tthis.lerpRotation(from.rotation, to.rotation, k),\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.sim.step(dt);\n\t\t\tfor (const [sa, sb] of this.sim.drainCollisionStarts()) {\n\t\t\t\tconst a = st.bySim.get(sa);\n\t\t\t\tconst b = st.bySim.get(sb);\n\t\t\t\tif (!a || !b) continue;\n\t\t\t\tconst key = `${bodies.indexOf(a)}:${bodies.indexOf(b)}`;\n\t\t\t\tif (started.has(key)) continue;\n\t\t\t\tstarted.add(key);\n\t\t\t\tpairs.push([a, b]);\n\t\t\t}\n\t\t}\n\t\tst.kinematicFrom = kinematicTo;\n\n\t\tfor (const b of bodies) b.record(frame, frame - 1);\n\n\t\tconst raw = new Map<B, number>();\n\t\tif (pairs.length > 0) {\n\t\t\tconst ppm = this.pixelsPerMeter;\n\t\t\tconst hit = (b: B): number => {\n\t\t\t\tif (b.type !== \"dynamic\") return 0;\n\t\t\t\tconst v = b.sim.velocity() as number[];\n\t\t\t\tconst v0 = prevVel.get(b) as number[];\n\t\t\t\tconst e = expected.get(b) as number[];\n\t\t\t\tlet sq = 0;\n\t\t\t\tfor (let i = 0; i < dims; i++) {\n\t\t\t\t\tconst d = v[i] - (v0[i] + e[i]);\n\t\t\t\t\tsq += d * d;\n\t\t\t\t}\n\t\t\t\treturn Math.sqrt(sq) * ppm;\n\t\t\t};\n\t\t\tfor (const [a, b] of pairs) {\n\t\t\t\tconst speed = Math.max(hit(a), hit(b));\n\t\t\t\tfor (const [self, other] of [\n\t\t\t\t\t[a, b],\n\t\t\t\t\t[b, a],\n\t\t\t\t] as const) {\n\t\t\t\t\traw.set(self, Math.max(raw.get(self) ?? 0, speed));\n\t\t\t\t\tconst c = { frame, with: other, speed };\n\t\t\t\t\tself.collisions.push(c as never);\n\t\t\t\t\tif (self === a) this.allCollisions.push({ ...c, body: a });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Impact envelopes: instant attack, exponential release.\n\t\tconst decay = Math.exp(-1 / this.impactDecay);\n\t\tlet loudest = 0;\n\t\tfor (const b of bodies) {\n\t\t\tconst level = Math.max(\n\t\t\t\t(raw.get(b) ?? 0) / this.impactReference,\n\t\t\t\t(st.level.get(b) ?? 0) * decay,\n\t\t\t);\n\t\t\tst.level.set(b, level);\n\t\t\tb.recording.channel(\"impact\")[frame] = level;\n\t\t\tif (level > loudest) loudest = level;\n\t\t}\n\t\tthis.worldRecording.channel(\"impact\")[frame] = loudest;\n\t\tst.current = f;\n\t}\n\n\tprotected abstract lerpRotation(a: R, b: R, t: number): R;\n\n\tprivate bind(body: B): void {\n\t\tconst layer = body.layer as\n\t\t\t| { animate?: (...a: LayerAnimation[]) => unknown }\n\t\t\t| undefined;\n\t\tconst output = body.output ?? (this.bakeDefault ? \"keyframes\" : \"signals\");\n\t\tif (typeof layer?.animate !== \"function\" || output === \"none\") return;\n\t\tif (body.type === \"fixed\") return;\n\t\tconst channels = body.boundChannels();\n\t\tif (output === \"keyframes\" && this.liveMode) {\n\t\t\tthrow new Error(\n\t\t\t\t'Physics: live worlds bind signals; drop `output: \"keyframes\"` or use simulate().',\n\t\t\t);\n\t\t}\n\t\tif (output === \"signals\") {\n\t\t\tconst anim = LayerAnimation.create();\n\t\t\tfor (const [prop, channel] of channels) {\n\t\t\t\tanim.signal(prop, body.recording.signal(channel));\n\t\t\t}\n\t\t\tlayer.animate(anim);\n\t\t\treturn;\n\t\t}\n\t\tconst tolerance = this.bakeDefault?.tolerance ?? 0.25;\n\t\tconst anim = LayerAnimation.create();\n\t\tfor (const [prop, channel] of channels) {\n\t\t\tconst arr = body.recording.channel(channel);\n\t\t\tconst local = arr.subarray(this.startFrame);\n\t\t\tconst scale = CHANNEL_TOLERANCE_SCALE[prop] ?? 1;\n\t\t\tanim.keys(prop, simplifyKeys(local, tolerance * scale));\n\t\t}\n\t\tlayer.animate(anim);\n\t}\n}\n\nfunction lerpVec<V extends number[]>(a: V, b: V, t: number): V {\n\treturn a.map((v, i) => v + (b[i] - v) * t) as V;\n}\n","import { Effect } from \"@framefields/core\";\nimport type {\n\tEmitterShape,\n\tParticleBlend,\n\tParticleBounds,\n\tParticleFrame,\n\tParticleProgram,\n\tParticleShape,\n\tParticleStatic,\n} from \"@framefields/node-particles\";\nimport { parseColor } from \"@framefields/webgpu-renderers\";\nimport type { PersonTrack } from \"./clip-vision.js\";\nimport { type PhysicsDriver, sampleDriver } from \"./physics/core.js\";\n\nexport type { EmitterShape, ParticleBlend, ParticleBounds, ParticleShape };\n\ntype Range = number | [number, number];\n\nexport interface ParticlesOptions {\n\t/** Particle layer box in composition px (the particles' own space; default the whole canvas). */\n\tx?: number;\n\ty?: number;\n\twidth: number;\n\theight: number;\n\tid?: string;\n\tstartFrame?: number;\n\tdurationFrames?: number;\n\tzIndex?: number;\n\t/** Most particles alive at once (default 20000). Costs GPU memory, not time when idle. */\n\tmax?: number;\n\tseed?: number;\n\temitter?: {\n\t\t/** `\"rect\"` (default, the whole layer), `\"point\"`, `\"line\"`, `\"circle\"` (area) or `\"ring\"` (edge). Layer px. */\n\t\tshape?: EmitterShape;\n\t\t/** Emitter position (layer px). A driver moves it: `(f) => person.point(\"rightWrist\", f).x` paints with light. */\n\t\tx?: PhysicsDriver;\n\t\ty?: PhysicsDriver;\n\t\twidth?: number;\n\t\theight?: number;\n\t\tradius?: number;\n\t\t/** Aim away from the emitter's center instead of along `direction`. */\n\t\tradial?: boolean;\n\t\t/** Particles per second (default 1000); a driver for bursts of activity. */\n\t\trate?: PhysicsDriver;\n\t\t/** Extra particles at given layer frames. */\n\t\tbursts?: Array<{ frame: number; count: number }>;\n\t};\n\t/** Seconds each particle lives (default [2, 4]). */\n\tlifetime?: Range;\n\t/** Launch speed, px/s (default [40, 160]). */\n\tspeed?: Range;\n\t/** Launch direction, degrees (0 = right, -90 = up; default -90). */\n\tdirection?: number;\n\t/** Spread around `direction`, degrees (default 360). */\n\tspread?: number;\n\t/** px/s². A single driver pulls down. */\n\tgravity?: PhysicsDriver | [PhysicsDriver, PhysicsDriver];\n\t/** Velocity damping per second (default 0.4). Higher reads as thicker air or liquid. */\n\tdrag?: PhysicsDriver;\n\t/** Swirling, divergence-free flow (curl noise): smoke, ink, flow fields. */\n\tnoise?: { strength?: PhysicsDriver; scale?: number; speed?: number };\n\t/** Points that pull (positive) or push (negative), px/s² at the center, falling off over `radius`. Layer px. Up to 8. */\n\tattractors?: Array<{\n\t\tx: PhysicsDriver;\n\t\ty: PhysicsDriver;\n\t\tstrength: PhysicsDriver;\n\t\tradius?: number;\n\t}>;\n\t/**\n\t * A performer pushes particles out of their silhouette, harder where it\n\t * is sweeping in: `person` from `comp.vision(clip).person.place(…)`.\n\t */\n\tpush?: {\n\t\tperson: PersonTrack;\n\t\tstrength?: PhysicsDriver;\n\t\tsweep?: PhysicsDriver;\n\t};\n\t/** What happens at the layer's edges: `\"none\"` (default), `\"kill\"`, `\"bounce\"`, `\"wrap\"`. */\n\tbounds?: ParticleBounds;\n\t/** A floor line in layer px that particles bounce on. */\n\tfloor?: number;\n\t/** Bounciness at the floor and bounced edges (default 0.3). */\n\tbounce?: number;\n\t/** px at birth → death (default [6, 0]). */\n\tsize?: Range;\n\t/** Random size variation, 0–1 (default 0.5). */\n\tsizeJitter?: number;\n\t/** Fractions of life to fade in and out (default [0.1, 0.3]). */\n\tfade?: [number, number];\n\t/** `\"circle\"` (default), `\"soft\"` (glow), `\"square\"`, `\"spark\"` (streaks along motion). */\n\tshape?: ParticleShape;\n\t/** Spark length per px/s (default 0.04). */\n\tstretch?: number;\n\t/** `\"normal\"` (default), `\"add\"` (glows build up), `\"screen\"`. */\n\tblend?: ParticleBlend;\n\t/** One color, or up to 8 spread over each particle's life (default white). */\n\tcolor?: string | string[];\n\t/** Color by speed instead of age: the px/s that reaches the last color. */\n\tcolorBySpeed?: number;\n\topacity?: number;\n\t/** Solver steps per frame (default 2). */\n\tsubsteps?: number;\n\t/** Seconds simulated before the first frame, so it starts already full. */\n\tprewarm?: number;\n}\n\nconst range = (\n\tr: Range | undefined,\n\tfallback: [number, number],\n): [number, number] =>\n\tr === undefined ? fallback : typeof r === \"number\" ? [r, r] : r;\n\n/**\n * A GPU particle system: tens of thousands of particles simulated in a\n * compute shader and drawn in one call. Used through `Layer.particles()`.\n * It steps as the composition renders (snapshots make scrubbing back\n * cheap), and its drivers are read every frame.\n */\nexport class Particles\n\textends Effect<Record<string, never>>\n\timplements ParticleProgram\n{\n\tpublic readonly op = \"Particles\";\n\treadonly particleStatic: ParticleStatic;\n\tparticleState?: unknown;\n\tprivate readonly options: ParticlesOptions;\n\n\tconstructor(options: ParticlesOptions) {\n\t\tsuper({});\n\t\tthis.options = options;\n\t\tconst e = options.emitter ?? {};\n\t\tconst staticPos = (d: PhysicsDriver | undefined) =>\n\t\t\ttypeof d === \"number\" ? d : undefined;\n\t\tconst width = options.width;\n\t\tconst height = options.height;\n\t\tconst colors = (\n\t\t\tArray.isArray(options.color)\n\t\t\t\t? options.color\n\t\t\t\t: [options.color ?? \"#ffffff\"]\n\t\t).map((c): [number, number, number, number] => {\n\t\t\tconst p = parseColor(c);\n\t\t\treturn [p.r, p.g, p.b, p.a];\n\t\t});\n\t\tthis.particleStatic = {\n\t\t\tmax: Math.max(1, Math.round(options.max ?? 20000)),\n\t\t\tseed: Math.round(options.seed ?? 1) >>> 0,\n\t\t\tlayer: { x: options.x ?? 0, y: options.y ?? 0, width, height },\n\t\t\temitter: {\n\t\t\t\tshape: e.shape ?? \"rect\",\n\t\t\t\tx:\n\t\t\t\t\tstaticPos(e.x) ??\n\t\t\t\t\t(e.shape === \"circle\" || e.shape === \"ring\" || e.shape === \"point\"\n\t\t\t\t\t\t? width / 2\n\t\t\t\t\t\t: 0),\n\t\t\t\ty:\n\t\t\t\t\tstaticPos(e.y) ??\n\t\t\t\t\t(e.shape === \"circle\" || e.shape === \"ring\" || e.shape === \"point\"\n\t\t\t\t\t\t? height / 2\n\t\t\t\t\t\t: 0),\n\t\t\t\twidth: e.width ?? width,\n\t\t\t\theight: e.height ?? (e.shape === \"line\" ? 0 : height),\n\t\t\t\tradius: e.radius ?? Math.min(width, height) / 4,\n\t\t\t\tradial: e.radial ?? false,\n\t\t\t},\n\t\t\tlifetime: range(options.lifetime, [2, 4]),\n\t\t\tspeed: range(options.speed, [40, 160]),\n\t\t\tdirection: options.direction ?? -90,\n\t\t\tspread: options.spread ?? 360,\n\t\t\tbounds: options.bounds ?? \"none\",\n\t\t\tfloor: options.floor ?? null,\n\t\t\tbounce: options.bounce ?? 0.3,\n\t\t\tsize: range(options.size, [6, 0]),\n\t\t\tsizeJitter: options.sizeJitter ?? 0.5,\n\t\t\tfade: options.fade ?? [0.1, 0.3],\n\t\t\tshape: options.shape ?? \"circle\",\n\t\t\tstretch: options.stretch ?? 0.04,\n\t\t\tblend: options.blend ?? \"normal\",\n\t\t\tcolors: colors.slice(0, 8),\n\t\t\tcolorBySpeed: options.colorBySpeed ?? null,\n\t\t\topacity: options.opacity ?? 1,\n\t\t\tsubsteps: options.substeps ?? 2,\n\t\t\tprewarm: options.prewarm ?? 0,\n\t\t};\n\t}\n\n\tparticleFrame(frame: number, fps: number): ParticleFrame {\n\t\tconst o = this.options;\n\t\tconst read = (d: PhysicsDriver | undefined, fallback: number) =>\n\t\t\td === undefined ? fallback : sampleDriver(d, frame, fps);\n\t\tconst layerFrame = frame - (o.startFrame ?? 0);\n\t\tconst burst = (o.emitter?.bursts ?? [])\n\t\t\t.filter((b) => Math.round(b.frame) === layerFrame)\n\t\t\t.reduce((n, b) => n + b.count, 0);\n\t\tconst g = o.gravity;\n\t\tconst gravity: [number, number] = Array.isArray(g)\n\t\t\t? [read(g[0], 0), read(g[1], 0)]\n\t\t\t: [0, read(g, 0)];\n\t\tlet push: ParticleFrame[\"push\"] = null;\n\t\tif (o.push) {\n\t\t\tpush = {\n\t\t\t\tstrength: read(o.push.strength, 6000),\n\t\t\t\tsweep: read(o.push.sweep, 60000),\n\t\t\t\tmask: o.push.person.silhouetteGrid(frame),\n\t\t\t\tprevious: o.push.person.silhouetteGrid(Math.max(0, frame - 1)),\n\t\t\t};\n\t\t}\n\t\tconst ex = o.emitter?.x;\n\t\tconst ey = o.emitter?.y;\n\t\tconst moving =\n\t\t\t(ex !== undefined && typeof ex !== \"number\") ||\n\t\t\t(ey !== undefined && typeof ey !== \"number\");\n\t\tconst at = (f: number) => ({\n\t\t\tx:\n\t\t\t\tex === undefined\n\t\t\t\t\t? this.particleStatic.emitter.x\n\t\t\t\t\t: sampleDriver(ex, f, fps),\n\t\t\ty:\n\t\t\t\tey === undefined\n\t\t\t\t\t? this.particleStatic.emitter.y\n\t\t\t\t\t: sampleDriver(ey, f, fps),\n\t\t});\n\t\tlet emitter: ParticleFrame[\"emitter\"];\n\t\tif (moving) {\n\t\t\tconst now = at(frame);\n\t\t\tconst before = at(Math.max(0, frame - 1));\n\t\t\temitter = {\n\t\t\t\tx: now.x,\n\t\t\t\ty: now.y,\n\t\t\t\tpreviousX: before.x,\n\t\t\t\tpreviousY: before.y,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\t...(emitter && { emitter }),\n\t\t\trate: read(o.emitter?.rate, 1000),\n\t\t\tburst,\n\t\t\tgravity,\n\t\t\tdrag: read(o.drag, 0.4),\n\t\t\tnoise: {\n\t\t\t\tstrength: read(o.noise?.strength, 0),\n\t\t\t\tscale: o.noise?.scale ?? 300,\n\t\t\t\tspeed: o.noise?.speed ?? 0.3,\n\t\t\t},\n\t\t\tattractors: (o.attractors ?? []).map((a) => ({\n\t\t\t\tx: read(a.x, 0),\n\t\t\t\ty: read(a.y, 0),\n\t\t\t\tstrength: read(a.strength, 0),\n\t\t\t\tradius: a.radius ?? 200,\n\t\t\t})),\n\t\t\tpush,\n\t\t};\n\t}\n}\n","import type {\n\tBoxNode,\n\tLayoutNode,\n\tMaterialType,\n\tModel3DNode,\n} from \"@framefields/compositions/program\";\nimport {\n\ttype CylinderGeometryOptions,\n\tgenerateExtrudedTextGeometry,\n\tgetPrimitiveGeometry,\n\ttype Model3DData,\n\ttype PrimitiveGeometryOptions,\n\ttype RoundedBoxGeometryOptions,\n\tSlugFontCache,\n\ttype SphereGeometryOptions,\n} from \"@framefields/webgpu-renderers\";\nimport { autoId } from \"./ids.js\";\nimport { type AnimatableNode, Layer } from \"./index.js\";\n\n/** Physically based surface options every 3D builder accepts. */\nexport interface Surface3DOptions {\n\t/** Light the surface gives off: a CSS color added on top of lighting. */\n\temissive?: string;\n\t/** Emissive multiplier; above 1 glows past white and blooms. Default 1. */\n\temissiveIntensity?: number;\n\t/** Falls into a `castShadow` light's shadow map (meshes default on, flat layers off). */\n\tcastShadow?: boolean;\n}\n\nconst MATERIAL_KEYS = [\n\t\"material\",\n\t\"shininess\",\n\t\"roughness\",\n\t\"specularIntensity\",\n\t\"metallic\",\n\t\"ambientIntensity\",\n\t\"ior\",\n\t\"transmission\",\n\t\"dispersion\",\n\t\"fresnelPower\",\n\t\"envIntensity\",\n\t\"emissive\",\n\t\"emissiveIntensity\",\n\t\"castShadow\",\n] as const;\n\n/** The material and surface options that were actually given. */\nfunction materialProps(o: object): Record<string, unknown> {\n\tconst src = o as Record<string, unknown>;\n\tconst out: Record<string, unknown> = {};\n\tfor (const k of MATERIAL_KEYS) {\n\t\tif (src[k] !== undefined) out[k] = src[k];\n\t}\n\treturn out;\n}\n\nexport interface CubeFaceConfig extends Surface3DOptions {\n\tbackground?: string;\n\tborderRadius?: number;\n\tborderWidth?: number;\n\tborderColor?: string;\n\topacity?: number;\n\tmaterial?: MaterialType;\n\tshininess?: number;\n\troughness?: number;\n\tspecularIntensity?: number;\n\tmetallic?: number;\n\tambientIntensity?: number;\n\tior?: number;\n\ttransmission?: number;\n\tdispersion?: number;\n\tfresnelPower?: number;\n\tenvIntensity?: number;\n\tchildren?: LayoutNode[];\n}\n\nexport type CubeFaceInput = CubeFaceConfig | LayoutNode | string;\n\nexport interface Cube3DOptions extends Surface3DOptions {\n\tid?: string;\n\tsize: number | [number, number, number];\n\tx?: number;\n\ty?: number;\n\tz?: number;\n\trotateX?: number;\n\trotateY?: number;\n\trotateZ?: number;\n\tfaces?: {\n\t\tfront?: CubeFaceInput;\n\t\tback?: CubeFaceInput;\n\t\tleft?: CubeFaceInput;\n\t\tright?: CubeFaceInput;\n\t\ttop?: CubeFaceInput;\n\t\tbottom?: CubeFaceInput;\n\t};\n\ttwoSided?: boolean;\n\tmaterial?: MaterialType;\n\tshininess?: number;\n\troughness?: number;\n\tspecularIntensity?: number;\n\tmetallic?: number;\n\tambientIntensity?: number;\n\tior?: number;\n\ttransmission?: number;\n\tdispersion?: number;\n\tfresnelPower?: number;\n\tenvIntensity?: number;\n\topacity?: number;\n}\n\nexport interface Carousel3DOptions {\n\tid?: string;\n\tradius: number;\n\titems: LayoutNode[];\n\tx?: number;\n\ty?: number;\n\tz?: number;\n\trotateX?: number;\n\trotateY?: number;\n\trotateZ?: number;\n\tfaceInward?: boolean;\n\titemWidth?: number;\n\titemHeight?: number;\n\ttwoSided?: boolean;\n\topacity?: number;\n}\n\nexport interface Prism3DOptions {\n\tid?: string;\n\tsides: number;\n\tradius: number;\n\theight: number;\n\tx?: number;\n\ty?: number;\n\tz?: number;\n\trotateX?: number;\n\trotateY?: number;\n\trotateZ?: number;\n\tsideConfigs?: Array<CubeFaceInput>;\n\ttwoSided?: boolean;\n\tmaterial?: MaterialType;\n\tshininess?: number;\n\troughness?: number;\n\tspecularIntensity?: number;\n\tmetallic?: number;\n\tambientIntensity?: number;\n\tior?: number;\n\ttransmission?: number;\n\tdispersion?: number;\n\tfresnelPower?: number;\n\tenvIntensity?: number;\n\topacity?: number;\n}\n\nexport interface Plane3DOptions extends Surface3DOptions {\n\tid?: string;\n\twidth: number;\n\theight: number;\n\tx?: number;\n\ty?: number;\n\tz?: number;\n\trotateX?: number;\n\trotateY?: number;\n\trotateZ?: number;\n\tbackground?: string;\n\tborderRadius?: number;\n\ttwoSided?: boolean;\n\tmaterial?: MaterialType;\n\tshininess?: number;\n\troughness?: number;\n\tspecularIntensity?: number;\n\tmetallic?: number;\n\tambientIntensity?: number;\n\tior?: number;\n\ttransmission?: number;\n\tdispersion?: number;\n\tfresnelPower?: number;\n\tenvIntensity?: number;\n\topacity?: number;\n\tchildren?: LayoutNode[];\n}\n\nexport interface Grid3DOptions {\n\tid?: string;\n\twidth: number;\n\theight: number;\n\tdivisions?: number;\n\tcolor?: string;\n\t/** Line thickness in world pixels (default 2). */\n\tlineWidth?: number;\n\tx?: number;\n\ty?: number;\n\tz?: number;\n\trotateX?: number;\n\trotateY?: number;\n\trotateZ?: number;\n\topacity?: number;\n}\n\nexport interface Text3DOptions extends Surface3DOptions {\n\tid?: string;\n\ttext: string;\n\tfontSize?: number;\n\tfontFamily?: string;\n\tfontWeight?: number | string;\n\tfontStyle?: string;\n\tfill?: string;\n\tx?: number;\n\ty?: number;\n\tz?: number;\n\trotateX?: number;\n\trotateY?: number;\n\trotateZ?: number;\n\tscale?: number;\n\tscaleX?: number;\n\tscaleY?: number;\n\tscaleZ?: number;\n\talign?: \"start\" | \"center\" | \"end\" | \"left\" | \"right\";\n\t/**\n\t * Base direction: \"auto\" (default) takes it from the first strong\n\t * character, so Arabic and Hebrew read right to left. \"start\"/\"end\"\n\t * alignment follows it.\n\t */\n\tdirection?: \"ltr\" | \"rtl\" | \"auto\";\n\tverticalAlign?: \"top\" | \"middle\" | \"bottom\";\n\tletterSpacing?: number;\n\tlineHeight?: number;\n\tis3D?: boolean;\n\ttwoSided?: boolean;\n\tmaterial?: MaterialType;\n\tshininess?: number;\n\troughness?: number;\n\tspecularIntensity?: number;\n\tambientIntensity?: number;\n\tmetallic?: number;\n\tior?: number;\n\ttransmission?: number;\n\tdispersion?: number;\n\tfresnelPower?: number;\n\tenvIntensity?: number;\n\topacity?: number;\n\tbackground?: string;\n\tborderRadius?: number;\n\tpadding?: number;\n\tstroke?: string;\n\tstrokeWidth?: number;\n\textrusionDepth?: number;\n\t/** @deprecated No effect: extruded text is one solid mesh, not a stack of slices. */\n\textrusionSteps?: number;\n\t/**\n\t * Extruded text only: color of the side walls. `fill` colors the letter\n\t * faces (front and back). Defaults to `fill`.\n\t */\n\tbevelColor?: string;\n}\n\nexport interface ExtrudedText3DOptions extends Text3DOptions {\n\tdepth: number;\n\t/** @deprecated No effect: extruded text is one solid mesh, not a stack of slices. */\n\tslices?: number;\n\t/** Fixed straight segments per curve; by default curves split as finely as their on-screen size needs. */\n\tcurveSegments?: number;\n\t/** Most a flattened curve strays from the outline, in on-screen px at scale 1 (default 0.1). */\n\tcurveTolerance?: number;\n}\n\n/** Node props shared by the mesh primitives (roundedBox, sphere, cylinder). */\nexport interface Primitive3DNodeOptions extends Surface3DOptions {\n\tid?: string;\n\tx?: number;\n\ty?: number;\n\tz?: number;\n\trotateX?: number;\n\trotateY?: number;\n\trotateZ?: number;\n\tscale?: number;\n\tscaleX?: number;\n\tscaleY?: number;\n\tscaleZ?: number;\n\t/** Surface color baked into the mesh (default white). */\n\tcolor?: string;\n\t/**\n\t * Multiplies the surface color. It is the node's `color`, so animate it\n\t * with `.keys(\"color\", …)`; the baked surface `color` stays fixed.\n\t */\n\ttint?: string;\n\tmaterial?: MaterialType;\n\tshininess?: number;\n\troughness?: number;\n\tspecularIntensity?: number;\n\tambientIntensity?: number;\n\tmetallic?: number;\n\topacity?: number;\n\tstartFrame?: number;\n\tdurationFrames?: number;\n}\n\nexport type RoundedBox3DOptions = Primitive3DNodeOptions &\n\tOmit<RoundedBoxGeometryOptions, \"type\" | \"color\" | \"material\">;\nexport type Sphere3DOptions = Primitive3DNodeOptions &\n\tOmit<SphereGeometryOptions, \"type\" | \"color\" | \"material\">;\nexport type Cylinder3DOptions = Primitive3DNodeOptions &\n\tOmit<CylinderGeometryOptions, \"type\" | \"color\" | \"material\">;\n\n/** Mesh shading the geometry can bake in; layer materials (glass, …) apply on the node. */\nfunction meshShading(\n\tmaterial: MaterialType | undefined,\n): \"lit\" | \"unlit\" | \"toon\" | undefined {\n\treturn material === \"lit\" || material === \"unlit\" || material === \"toon\"\n\t\t? material\n\t\t: undefined;\n}\n\nfunction primitiveNode(\n\tprefix: string,\n\tgeometry: PrimitiveGeometryOptions,\n\to: Primitive3DNodeOptions,\n): AnimatableNode<Model3DNode> {\n\t// Only defined keys, so equal shapes share one cached mesh.\n\tconst spec = Object.fromEntries(\n\t\tObject.entries({\n\t\t\t...geometry,\n\t\t\tcolor: o.color,\n\t\t\tmaterial: meshShading(o.material),\n\t\t\tshininess: o.shininess,\n\t\t\troughness: o.roughness,\n\t\t\tmetallic: o.metallic,\n\t\t}).filter(([, v]) => v !== undefined),\n\t) as unknown as PrimitiveGeometryOptions;\n\treturn Layer.model({\n\t\tid: o.id ?? autoId(prefix),\n\t\tmodelData: getPrimitiveGeometry(spec),\n\t\t// What the compositor rebuilds the mesh from when modelData did not\n\t\t// survive (a spec sent as JSON).\n\t\tprimitive3d: spec,\n\t\tis3D: true,\n\t\tx: o.x ?? 0,\n\t\ty: o.y ?? 0,\n\t\tz: o.z ?? 0,\n\t\trotateX: o.rotateX ?? 0,\n\t\trotateY: o.rotateY ?? 0,\n\t\trotateZ: o.rotateZ ?? 0,\n\t\tscale: o.scale ?? 1,\n\t\tscaleX: o.scaleX ?? 1,\n\t\tscaleY: o.scaleY ?? 1,\n\t\tscaleZ: o.scaleZ ?? 1,\n\t\topacity: o.opacity ?? 1,\n\t\tcolor: o.tint,\n\t\tmaterial: o.material,\n\t\tshininess: o.shininess ?? 32,\n\t\troughness: o.roughness,\n\t\tspecularIntensity: o.specularIntensity ?? 0.5,\n\t\tambientIntensity: o.ambientIntensity ?? 1.0,\n\t\tmetallic: o.metallic,\n\t\t...materialProps({\n\t\t\temissive: o.emissive,\n\t\t\temissiveIntensity: o.emissiveIntensity,\n\t\t\tcastShadow: o.castShadow,\n\t\t}),\n\t\ttwoSided: false,\n\t\tstartFrame: o.startFrame,\n\t\tdurationFrames: o.durationFrames,\n\t});\n}\n\nexport type Shape3DContainer = AnimatableNode<BoxNode> & {\n\tfaces?: AnimatableNode<BoxNode>[];\n\titems?: LayoutNode[];\n\t[Symbol.iterator](): Iterator<LayoutNode>;\n};\n\n/**\n * Attaches the faces/items handles as non-enumerable properties, like\n * `animate`, so they stay out of `toSpec()` and schema validation.\n */\nfunction withParts<T extends object>(\n\tnode: T,\n\tparts: { faces?: LayoutNode[]; items?: LayoutNode[] },\n): T & Shape3DContainer {\n\tconst list = (parts.faces ?? parts.items ?? []) as LayoutNode[];\n\tfor (const [key, value] of Object.entries(parts)) {\n\t\tObject.defineProperty(node, key, {\n\t\t\tvalue,\n\t\t\tenumerable: false,\n\t\t\tconfigurable: true,\n\t\t});\n\t}\n\tObject.defineProperty(node, Symbol.iterator, {\n\t\tvalue: function* () {\n\t\t\tyield* list;\n\t\t},\n\t\tenumerable: false,\n\t\tconfigurable: true,\n\t});\n\treturn node as T & Shape3DContainer;\n}\n\n/** Largest initial scale of an extruded text node along its outline's axes. */\nfunction extrudedTextScale(options: ExtrudedText3DOptions): number {\n\tconst scale = options.scale ?? 1;\n\tconst s = Math.max(\n\t\tMath.abs(scale * (options.scaleX ?? 1)),\n\t\tMath.abs(scale * (options.scaleY ?? 1)),\n\t);\n\treturn s > 0 ? s : 1;\n}\n\nexport const Layer3D = {\n\t/**\n\t * Creates a true 3D volumetric cube with 6 textured or colored faces.\n\t * Returns a preserve-3d container that can be transformed in 3D camera space.\n\t */\n\tcube(options: Cube3DOptions): Shape3DContainer {\n\t\tconst size = options.size;\n\t\tconst [w, h, d] = typeof size === \"number\" ? [size, size, size] : size;\n\t\tconst twoSided = options.twoSided ?? true;\n\t\tconst defaultColors = {\n\t\t\tfront: \"#3b82f6\",\n\t\t\tback: \"#1d4ed8\",\n\t\t\tleft: \"#2563eb\",\n\t\t\tright: \"#1e40af\",\n\t\t\ttop: \"#60a5fa\",\n\t\t\tbottom: \"#172554\",\n\t\t};\n\n\t\tconst buildFace = (\n\t\t\tfaceId: string,\n\t\t\tinput: CubeFaceInput | undefined,\n\t\t\tdefaultColor: string,\n\t\t\tfaceW: number,\n\t\t\tfaceH: number,\n\t\t\tfaceProps: Partial<BoxNode>,\n\t\t): AnimatableNode<BoxNode> => {\n\t\t\tif (input && typeof input === \"object\" && \"kind\" in input) {\n\t\t\t\tconst node = input as AnimatableNode<BoxNode>;\n\t\t\t\tnode.position = \"absolute\";\n\t\t\t\tnode.is3D = true;\n\t\t\t\tnode.twoSided = twoSided;\n\t\t\t\tnode.material = node.material ?? options.material ?? \"lit\";\n\t\t\t\tnode.shininess = node.shininess ?? options.shininess ?? 32;\n\t\t\t\tnode.specularIntensity =\n\t\t\t\t\tnode.specularIntensity ?? options.specularIntensity ?? 0.5;\n\t\t\t\tif (options.roughness !== undefined && node.roughness === undefined) {\n\t\t\t\t\tnode.roughness = options.roughness;\n\t\t\t\t}\n\t\t\t\tif (options.metallic !== undefined && node.metallic === undefined) {\n\t\t\t\t\tnode.metallic = options.metallic;\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\toptions.ambientIntensity !== undefined &&\n\t\t\t\t\tnode.ambientIntensity === undefined\n\t\t\t\t) {\n\t\t\t\t\tnode.ambientIntensity = options.ambientIntensity;\n\t\t\t\t}\n\t\t\t\tObject.assign(node, faceProps);\n\t\t\t\treturn node;\n\t\t\t}\n\t\t\tconst cfg: CubeFaceConfig =\n\t\t\t\ttypeof input === \"string\"\n\t\t\t\t\t? { background: input }\n\t\t\t\t\t: (input ?? { background: defaultColor });\n\n\t\t\treturn Layer.box({\n\t\t\t\tid: `${options.id ?? \"cube\"}-${faceId}`,\n\t\t\t\tposition: \"absolute\",\n\t\t\t\twidth: faceW,\n\t\t\t\theight: faceH,\n\t\t\t\tis3D: true,\n\t\t\t\ttwoSided,\n\t\t\t\tmaterial: cfg.material ?? options.material ?? \"lit\",\n\t\t\t\tshininess: cfg.shininess ?? options.shininess ?? 32,\n\t\t\t\tspecularIntensity:\n\t\t\t\t\tcfg.specularIntensity ?? options.specularIntensity ?? 0.5,\n\t\t\t\troughness: cfg.roughness ?? options.roughness,\n\t\t\t\tmetallic: cfg.metallic ?? options.metallic,\n\t\t\t\tambientIntensity:\n\t\t\t\t\tcfg.ambientIntensity ?? options.ambientIntensity ?? 1.0,\n\t\t\t\t...materialProps({\n\t\t\t\t\temissive: cfg.emissive ?? options.emissive,\n\t\t\t\t\temissiveIntensity: cfg.emissiveIntensity ?? options.emissiveIntensity,\n\t\t\t\t\tcastShadow: cfg.castShadow ?? options.castShadow,\n\t\t\t\t}),\n\t\t\t\tbackground: cfg.background ?? defaultColor,\n\t\t\t\tborderRadius: cfg.borderRadius ?? 0,\n\t\t\t\tborderWidth: cfg.borderWidth,\n\t\t\t\tborderColor: cfg.borderColor,\n\t\t\t\topacity: cfg.opacity ?? 1,\n\t\t\t\tchildren: cfg.children ?? [],\n\t\t\t\t...faceProps,\n\t\t\t});\n\t\t};\n\n\t\tconst halfW = w / 2;\n\t\tconst halfH = h / 2;\n\t\tconst halfD = d / 2;\n\n\t\tconst faces: AnimatableNode<BoxNode>[] = [\n\t\t\tbuildFace(\"front\", options.faces?.front, defaultColors.front, w, h, {\n\t\t\t\tx: 0,\n\t\t\t\ty: 0,\n\t\t\t\tz: -halfD,\n\t\t\t\trotateX: 0,\n\t\t\t\trotateY: 0,\n\t\t\t\trotateZ: 0,\n\t\t\t}),\n\t\t\tbuildFace(\"back\", options.faces?.back, defaultColors.back, w, h, {\n\t\t\t\tx: 0,\n\t\t\t\ty: 0,\n\t\t\t\tz: halfD,\n\t\t\t\trotateX: 0,\n\t\t\t\trotateY: 180,\n\t\t\t\trotateZ: 0,\n\t\t\t}),\n\t\t\tbuildFace(\"left\", options.faces?.left, defaultColors.left, d, h, {\n\t\t\t\tx: -halfW,\n\t\t\t\ty: 0,\n\t\t\t\tz: 0,\n\t\t\t\trotateX: 0,\n\t\t\t\trotateY: 90,\n\t\t\t\trotateZ: 0,\n\t\t\t}),\n\t\t\tbuildFace(\"right\", options.faces?.right, defaultColors.right, d, h, {\n\t\t\t\tx: halfW,\n\t\t\t\ty: 0,\n\t\t\t\tz: 0,\n\t\t\t\trotateX: 0,\n\t\t\t\trotateY: -90,\n\t\t\t\trotateZ: 0,\n\t\t\t}),\n\t\t\tbuildFace(\"top\", options.faces?.top, defaultColors.top, w, d, {\n\t\t\t\tx: 0,\n\t\t\t\ty: -halfH,\n\t\t\t\tz: 0,\n\t\t\t\trotateX: -90,\n\t\t\t\trotateY: 0,\n\t\t\t\trotateZ: 0,\n\t\t\t}),\n\t\t\tbuildFace(\"bottom\", options.faces?.bottom, defaultColors.bottom, w, d, {\n\t\t\t\tx: 0,\n\t\t\t\ty: halfH,\n\t\t\t\tz: 0,\n\t\t\t\trotateX: 90,\n\t\t\t\trotateY: 0,\n\t\t\t\trotateZ: 0,\n\t\t\t}),\n\t\t];\n\n\t\tconst container = Layer.box({\n\t\t\tid: options.id ?? autoId(\"cube\"),\n\t\t\tposition: \"absolute\",\n\t\t\tx: options.x ?? 0,\n\t\t\ty: options.y ?? 0,\n\t\t\tz: options.z ?? 0,\n\t\t\twidth: w,\n\t\t\theight: h,\n\t\t\tis3D: true,\n\t\t\ttransformStyle: \"preserve-3d\",\n\t\t\trotateX: options.rotateX ?? 0,\n\t\t\trotateY: options.rotateY ?? 0,\n\t\t\trotateZ: options.rotateZ ?? 0,\n\t\t\topacity: options.opacity ?? 1,\n\t\t\tbackground: \"transparent\",\n\t\t\tchildren: faces,\n\t\t});\n\n\t\treturn withParts(container, { faces });\n\t},\n\n\t/**\n\t * Creates a 3D cylindrical carousel of items arranged radially around a center point.\n\t */\n\tcarousel(options: Carousel3DOptions): Shape3DContainer {\n\t\tconst { items, radius, faceInward = false, twoSided = true } = options;\n\t\tconst n = items.length;\n\t\tconst angleStep = n > 0 ? 360 / n : 0;\n\n\t\tconst transformedItems = items.map((item, idx) => {\n\t\t\t// Item 0 sits nearest the default camera (-z) and the ring runs clockwise\n\t\t\t// seen from above. A face's front normal is (-sin ry, 0, -cos ry) (the\n\t\t\t// cube's convention: rotateY 90 faces -x), so the outward normal\n\t\t\t// (sin a, 0, -cos a) needs ry = -a, and inward needs 180 - a.\n\t\t\tconst angleDeg = idx * angleStep;\n\t\t\tconst rad = (angleDeg * Math.PI) / 180;\n\t\t\tconst x = radius * Math.sin(rad);\n\t\t\tconst z = -radius * Math.cos(rad);\n\t\t\tconst ry = faceInward ? 180 - angleDeg : -angleDeg;\n\n\t\t\tconst node = item as AnimatableNode<BoxNode>;\n\t\t\tnode.position = \"absolute\";\n\t\t\tnode.is3D = true;\n\t\t\tnode.twoSided = twoSided;\n\t\t\tnode.x = x;\n\t\t\tnode.y = 0;\n\t\t\tnode.z = z;\n\t\t\tnode.rotateY = ry;\n\t\t\treturn node;\n\t\t});\n\n\t\tconst container = Layer.box({\n\t\t\tid: options.id ?? autoId(\"carousel\"),\n\t\t\tposition: \"absolute\",\n\t\t\tx: options.x ?? 0,\n\t\t\ty: options.y ?? 0,\n\t\t\tz: options.z ?? 0,\n\t\t\twidth: (options.itemWidth ?? 200) as any,\n\t\t\theight: (options.itemHeight ?? 200) as any,\n\t\t\tis3D: true,\n\t\t\ttransformStyle: \"preserve-3d\",\n\t\t\trotateX: options.rotateX ?? 0,\n\t\t\trotateY: options.rotateY ?? 0,\n\t\t\trotateZ: options.rotateZ ?? 0,\n\t\t\topacity: options.opacity ?? 1,\n\t\t\tbackground: \"transparent\",\n\t\t\tchildren: transformedItems,\n\t\t});\n\n\t\treturn withParts(container, { items: transformedItems });\n\t},\n\n\t/**\n\t * Creates an N-sided regular polygonal 3D prism.\n\t */\n\tprism(options: Prism3DOptions): Shape3DContainer {\n\t\tconst { sides, radius, height, twoSided = true } = options;\n\t\tconst n = Math.max(3, sides);\n\t\tconst sideWidth = 2 * radius * Math.tan(Math.PI / n);\n\t\tconst angleStep = 360 / n;\n\t\tconst panels: AnimatableNode<BoxNode>[] = [];\n\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\tconst angleDeg = i * angleStep;\n\t\t\tconst rad = (angleDeg * Math.PI) / 180;\n\t\t\tconst x = radius * Math.sin(rad);\n\t\t\tconst z = radius * Math.cos(rad);\n\t\t\tconst cfg = options.sideConfigs?.[i];\n\t\t\tconst color =\n\t\t\t\ttypeof cfg === \"string\"\n\t\t\t\t\t? cfg\n\t\t\t\t\t: ((cfg as { background?: string } | undefined)?.background ??\n\t\t\t\t\t\t`hsl(${(i * 360) / n}, 70%, 50%)`);\n\n\t\t\tpanels.push(\n\t\t\t\tLayer.box({\n\t\t\t\t\tid: `${options.id ?? \"prism\"}-panel-${i}`,\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\twidth: sideWidth,\n\t\t\t\t\theight,\n\t\t\t\t\tis3D: true,\n\t\t\t\t\ttwoSided,\n\t\t\t\t\tx,\n\t\t\t\t\ty: 0,\n\t\t\t\t\tz,\n\t\t\t\t\trotateY: angleDeg,\n\t\t\t\t\tbackground: color,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tconst container = Layer.box({\n\t\t\tid: options.id ?? autoId(\"prism\"),\n\t\t\tposition: \"absolute\",\n\t\t\tx: options.x ?? 0,\n\t\t\ty: options.y ?? 0,\n\t\t\tz: options.z ?? 0,\n\t\t\twidth: sideWidth,\n\t\t\theight,\n\t\t\tis3D: true,\n\t\t\ttransformStyle: \"preserve-3d\",\n\t\t\trotateX: options.rotateX ?? 0,\n\t\t\trotateY: options.rotateY ?? 0,\n\t\t\trotateZ: options.rotateZ ?? 0,\n\t\t\topacity: options.opacity ?? 1,\n\t\t\tbackground: \"transparent\",\n\t\t\tchildren: panels,\n\t\t});\n\n\t\treturn withParts(container, { faces: panels });\n\t},\n\n\t/**\n\t * Creates a standalone planar 3D card/quad.\n\t */\n\tplane(options: Plane3DOptions): AnimatableNode<BoxNode> {\n\t\treturn Layer.box({\n\t\t\tid: options.id ?? autoId(\"plane\"),\n\t\t\tposition: \"absolute\",\n\t\t\twidth: options.width,\n\t\t\theight: options.height,\n\t\t\tx: options.x ?? 0,\n\t\t\ty: options.y ?? 0,\n\t\t\tz: options.z ?? 0,\n\t\t\tis3D: true,\n\t\t\ttwoSided: options.twoSided ?? true,\n\t\t\trotateX: options.rotateX ?? 0,\n\t\t\trotateY: options.rotateY ?? 0,\n\t\t\trotateZ: options.rotateZ ?? 0,\n\t\t\tbackground: options.background ?? \"#3b82f6\",\n\t\t\tborderRadius: options.borderRadius ?? 0,\n\t\t\topacity: options.opacity ?? 1,\n\t\t\t...materialProps(options),\n\t\t\tchildren: options.children ?? [],\n\t\t});\n\t},\n\n\t/**\n\t * Creates a 3D perspective ground grid: `divisions` cells per side, each\n\t * line its own unlit quad so it stays crisp at any camera distance.\n\t */\n\tgrid(options: Grid3DOptions): AnimatableNode<BoxNode> {\n\t\tconst { width, height } = options;\n\t\tconst id = options.id ?? autoId(\"grid\");\n\t\tconst divisions = Math.max(1, Math.round(options.divisions ?? 10));\n\t\tconst lineWidth = options.lineWidth ?? 2;\n\t\tconst color = options.color ?? \"rgba(59, 130, 246, 0.5)\";\n\t\tconst line = (\n\t\t\tlineId: string,\n\t\t\tx: number,\n\t\t\ty: number,\n\t\t\tw: number,\n\t\t\th: number,\n\t\t): AnimatableNode<BoxNode> =>\n\t\t\tLayer.box({\n\t\t\t\tid: `${id}-${lineId}`,\n\t\t\t\tposition: \"absolute\",\n\t\t\t\tx,\n\t\t\t\ty,\n\t\t\t\tz: 0,\n\t\t\t\twidth: w,\n\t\t\t\theight: h,\n\t\t\t\tis3D: true,\n\t\t\t\ttwoSided: true,\n\t\t\t\tmaterial: \"unlit\",\n\t\t\t\tbackground: color,\n\t\t\t});\n\t\t// Every quad is backed by a texture of its own size, so long lines are\n\t\t// split into segments that stay well inside the GPU's texture limit.\n\t\tconst MAX_SEGMENT = 4096;\n\t\tconst lines: AnimatableNode<BoxNode>[] = [];\n\t\tconst vSegments = Math.ceil(height / MAX_SEGMENT);\n\t\tconst hSegments = Math.ceil(width / MAX_SEGMENT);\n\t\tfor (let i = 0; i <= divisions; i++) {\n\t\t\tconst u = i / divisions - 0.5;\n\t\t\tfor (let k = 0; k < vSegments; k++) {\n\t\t\t\tconst len = height / vSegments;\n\t\t\t\tconst y = -height / 2 + len * (k + 0.5);\n\t\t\t\tlines.push(line(`v${i}-${k}`, u * width, y, lineWidth, len));\n\t\t\t}\n\t\t\tfor (let k = 0; k < hSegments; k++) {\n\t\t\t\tconst len = width / hSegments;\n\t\t\t\tconst x = -width / 2 + len * (k + 0.5);\n\t\t\t\tlines.push(line(`h${i}-${k}`, x, u * height, len, lineWidth));\n\t\t\t}\n\t\t}\n\t\treturn Layer.box({\n\t\t\tid,\n\t\t\tposition: \"absolute\",\n\t\t\twidth,\n\t\t\theight,\n\t\t\tx: options.x ?? 0,\n\t\t\ty: options.y ?? 0,\n\t\t\tz: options.z ?? 0,\n\t\t\tis3D: true,\n\t\t\ttransformStyle: \"preserve-3d\",\n\t\t\trotateX: options.rotateX ?? 90,\n\t\t\trotateY: options.rotateY ?? 0,\n\t\t\trotateZ: options.rotateZ ?? 0,\n\t\t\tbackground: \"transparent\",\n\t\t\topacity: options.opacity ?? 1,\n\t\t\tchildren: lines,\n\t\t});\n\t},\n\n\t/**\n\t * Creates a standalone planar 3D text node, or solid extruded 3D text when `extrusionDepth` is set.\n\t */\n\ttext(options: Text3DOptions): AnimatableNode<LayoutNode> {\n\t\tif (options.extrusionDepth && options.extrusionDepth > 0) {\n\t\t\treturn Layer3D.extrudedText({\n\t\t\t\t...options,\n\t\t\t\tdepth: options.extrusionDepth,\n\t\t\t});\n\t\t}\n\n\t\treturn Layer.text(options.text, {\n\t\t\tid: options.id ?? autoId(\"text3d\"),\n\t\t\tposition: \"absolute\",\n\t\t\tx: options.x ?? 0,\n\t\t\ty: options.y ?? 0,\n\t\t\tz: options.z ?? 0,\n\t\t\tis3D: true,\n\t\t\ttwoSided: options.twoSided ?? true,\n\t\t\trotateX: options.rotateX ?? 0,\n\t\t\trotateY: options.rotateY ?? 0,\n\t\t\trotateZ: options.rotateZ ?? 0,\n\t\t\tfontSize: options.fontSize ?? 48,\n\t\t\tfontFamily: options.fontFamily,\n\t\t\tfontWeight: options.fontWeight ?? \"bold\",\n\t\t\tfontStyle: options.fontStyle,\n\t\t\tfill: options.fill ?? \"#ffffff\",\n\t\t\talign: (options.align as any) ?? \"center\",\n\t\t\tdirection: options.direction,\n\t\t\tverticalAlign: options.verticalAlign ?? \"middle\",\n\t\t\tletterSpacing: options.letterSpacing,\n\t\t\tlineHeight: options.lineHeight,\n\t\t\tmaterial: options.material ?? \"lit\",\n\t\t\tshininess: options.shininess ?? 64,\n\t\t\troughness: options.roughness,\n\t\t\tspecularIntensity: options.specularIntensity ?? 0.8,\n\t\t\tambientIntensity: options.ambientIntensity ?? 1.0,\n\t\t\tmetallic: options.metallic,\n\t\t\t...materialProps(options),\n\t\t\topacity: options.opacity ?? 1,\n\t\t\tbackground: options.background,\n\t\t\tborderRadius: options.borderRadius,\n\t\t\tpadding: options.padding,\n\t\t\tstroke: options.stroke,\n\t\t\tstrokeWidth: options.strokeWidth,\n\t\t});\n\t},\n\n\t/**\n\t * Creates solid extruded 3D typography: `fill` colors the letter faces,\n\t * `bevelColor` the side walls; curves are tessellated to `curveTolerance`.\n\t */\n\textrudedText(options: ExtrudedText3DOptions): Shape3DContainer {\n\t\tconst { depth, text, fill = \"#ffffff\", bevelColor } = options;\n\n\t\tlet modelData: Model3DData | undefined;\n\t\t// Tolerance is in on-screen px: a node scaled up 3x needs 3x finer geometry.\n\t\tconst curveTolerance =\n\t\t\t(options.curveTolerance ?? 0.1) / extrudedTextScale(options);\n\t\tconst parsedFont =\n\t\t\t(options.fontFamily\n\t\t\t\t? SlugFontCache.getParsed(options.fontFamily)\n\t\t\t\t: null) ??\n\t\t\tSlugFontCache.getParsed(\"Inter\") ??\n\t\t\tSlugFontCache.getParsed(\"Unbounded\") ??\n\t\t\tSlugFontCache.getFirstParsed();\n\n\t\tif (parsedFont) {\n\t\t\tconst res = generateExtrudedTextGeometry({\n\t\t\t\ttext,\n\t\t\t\t// SlugFontCache holds fontkit fonts under a narrower type.\n\t\t\t\tfont: parsedFont as unknown as Parameters<\n\t\t\t\t\ttypeof generateExtrudedTextGeometry\n\t\t\t\t>[0][\"font\"],\n\t\t\t\tfontSize: options.fontSize ?? 48,\n\t\t\t\tdepth,\n\t\t\t\tfill,\n\t\t\t\tbevelColor,\n\t\t\t\tcurveSegments: options.curveSegments,\n\t\t\t\tcurveTolerance,\n\t\t\t\talign: options.align,\n\t\t\t\tdirection: options.direction,\n\t\t\t\tverticalAlign: options.verticalAlign,\n\t\t\t\tletterSpacing: options.letterSpacing,\n\t\t\t\t// The mesh's own shading only knows these; glass and the like are\n\t\t\t\t// layer materials, applied by the model node below.\n\t\t\t\tmaterial:\n\t\t\t\t\toptions.material === \"lit\" ||\n\t\t\t\t\toptions.material === \"unlit\" ||\n\t\t\t\t\toptions.material === \"toon\"\n\t\t\t\t\t\t? options.material\n\t\t\t\t\t\t: undefined,\n\t\t\t\tshininess: options.shininess,\n\t\t\t\troughness: options.roughness,\n\t\t\t\tmetallic: options.metallic,\n\t\t\t});\n\t\t\tmodelData = res.modelData;\n\t\t}\n\n\t\tconst modelNode = Layer.model({\n\t\t\tid: options.id ?? autoId(\"extruded-text\"),\n\t\t\tmodelData,\n\t\t\tis3D: true,\n\t\t\tx: options.x ?? 0,\n\t\t\ty: options.y ?? 0,\n\t\t\tz: options.z ?? 0,\n\t\t\trotateX: options.rotateX ?? 0,\n\t\t\trotateY: options.rotateY ?? 0,\n\t\t\trotateZ: options.rotateZ ?? 0,\n\t\t\tscale: options.scale ?? 1,\n\t\t\tscaleX: options.scaleX ?? 1,\n\t\t\tscaleY: options.scaleY ?? 1,\n\t\t\tscaleZ: options.scaleZ ?? 1,\n\t\t\topacity: options.opacity ?? 1,\n\t\t\tmaterial: options.material,\n\t\t\tshininess: options.shininess ?? 32,\n\t\t\troughness: options.roughness,\n\t\t\tspecularIntensity: options.specularIntensity ?? 0.8,\n\t\t\tambientIntensity: options.ambientIntensity ?? 1.0,\n\t\t\tmetallic: options.metallic,\n\t\t\t...materialProps(options),\n\t\t\ttwoSided: options.twoSided ?? true,\n\t\t\t// What the compositor rebuilds the mesh from when modelData did not\n\t\t\t// survive (a spec sent as JSON): the same tolerance as here.\n\t\t\ttext3dOptions: { ...options, curveTolerance },\n\t\t});\n\n\t\treturn withParts(modelNode, {\n\t\t\tfaces: [modelNode],\n\t\t\titems: [modelNode],\n\t\t}) as unknown as Shape3DContainer;\n\t},\n\n\t/**\n\t * A solid box with rounded edges and corners, as one smooth-shaded mesh:\n\t * cards, buttons, device bodies. `taper` below 1 narrows the top (-y)\n\t * face, the shape of a keycap. Equal shapes share one GPU buffer.\n\t */\n\troundedBox(options: RoundedBox3DOptions): AnimatableNode<Model3DNode> {\n\t\treturn primitiveNode(\n\t\t\t\"rounded-box\",\n\t\t\t{\n\t\t\t\ttype: \"roundedBox\",\n\t\t\t\twidth: options.width,\n\t\t\t\theight: options.height,\n\t\t\t\tdepth: options.depth,\n\t\t\t\tradius: options.radius,\n\t\t\t\tsegments: options.segments,\n\t\t\t\ttaper: options.taper,\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t},\n\n\t/** A UV sphere mesh. */\n\tsphere(options: Sphere3DOptions): AnimatableNode<Model3DNode> {\n\t\treturn primitiveNode(\n\t\t\t\"sphere\",\n\t\t\t{ type: \"sphere\", radius: options.radius, segments: options.segments },\n\t\t\toptions,\n\t\t);\n\t},\n\n\t/** A capped cylinder, or a cone/frustum with different top and bottom radii. */\n\tcylinder(options: Cylinder3DOptions): AnimatableNode<Model3DNode> {\n\t\treturn primitiveNode(\n\t\t\t\"cylinder\",\n\t\t\t{\n\t\t\t\ttype: \"cylinder\",\n\t\t\t\tradius: options.radius,\n\t\t\t\tradiusTop: options.radiusTop,\n\t\t\t\tradiusBottom: options.radiusBottom,\n\t\t\t\theight: options.height,\n\t\t\t\tsegments: options.segments,\n\t\t\t\topenEnded: options.openEnded,\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t},\n\n\t/**\n\t * Creates a 3D model node rendered natively with WebGPU mesh shaders.\n\t */\n\tmodel(options: Partial<Model3DNode> = {}): AnimatableNode<Model3DNode> {\n\t\treturn Layer.model(options);\n\t},\n\n\t/**\n\t * Convenience helper to create a 3D Wavefront OBJ model node.\n\t */\n\tobj(\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> {\n\t\treturn Layer.obj(src, options);\n\t},\n\n\t/**\n\t * Convenience helper to create a 3D Autodesk FBX model node with skeletal animation support.\n\t */\n\tfbx(\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> {\n\t\treturn Layer.fbx(src, options);\n\t},\n\n\t/**\n\t * Convenience helper to create a 3D glTF 2.0 model node.\n\t */\n\tgltf(\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> {\n\t\treturn Layer.gltf(src, options);\n\t},\n\n\t/**\n\t * Convenience helper to create a 3D GLB binary container model node.\n\t */\n\tglb(\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> {\n\t\treturn Layer.glb(src, options);\n\t},\n\n\t/**\n\t * Convenience helper to create a 3D STL CAD / 3D printing model node.\n\t */\n\tstl(\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> {\n\t\treturn Layer.stl(src, options);\n\t},\n\n\t/**\n\t * Convenience helper to create a 3D Stanford PLY scan model node.\n\t */\n\tply(\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> {\n\t\treturn Layer.ply(src, options);\n\t},\n\n\t/**\n\t * Convenience helper to create a 3D MagicaVoxel VOX model node.\n\t */\n\tvox(\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> {\n\t\treturn Layer.vox(src, options);\n\t},\n\n\t/**\n\t * Convenience helper to create a 3D Studio (3DS) binary model node.\n\t */\n\tthreeDS(\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> {\n\t\treturn Layer.threeDS(src, options);\n\t},\n\n\t/**\n\t * Convenience helper to create a 3D Object File Format (OFF) model node.\n\t */\n\toff(\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> {\n\t\treturn Layer.off(src, options);\n\t},\n};\n","/**\n * Scene sequencing with transitions. `Layer.sequence` lays scenes end to end\n * and overlaps neighbours by each transition's length; the transition itself\n * is plain keyframes (and, for wipes and irises, a track matte) merged into\n * the scenes, so it renders like anything else and stays editable.\n */\nimport {\n\ttype AnimationTrack,\n\ttype BoxNode,\n\tLayerAnimation,\n\ttype LayoutNode,\n} from \"@framefields/compositions/program\";\nimport { autoId } from \"./ids.js\";\nimport { type AnimatableNode, Layer } from \"./index.js\";\n\nexport type TransitionDirection = \"left\" | \"right\" | \"up\" | \"down\";\n\n/** What a transition needs to know to animate two scenes. */\ninterface TransitionContext {\n\t/** Scene size (px). */\n\twidth: number;\n\theight: number;\n\t/** Overlap length in frames. */\n\tframes: number;\n\t/** Outgoing scene: local frame where the overlap starts, and its rest position. */\n\toutStart: number;\n\toutRest: { x: number; y: number };\n\t/** Incoming scene rest position (the overlap starts at its local frame 0). */\n\tinRest: { x: number; y: number };\n}\n\ninterface TransitionParts {\n\toutgoing?: LayerAnimation;\n\tincoming?: LayerAnimation;\n\t/** A matte revealing the incoming scene (laid out like the scene, keyed from its start). */\n\tincomingMatte?: LayoutNode;\n\t/** Static props set on both scenes (e.g. motion blur for a whip). */\n\tsceneProps?: Record<string, unknown>;\n}\n\nexport interface TransitionSpec {\n\treadonly kind: string;\n\t/** Overlap between the two scenes, in frames (0 = hard cut). */\n\treadonly frames: number;\n\t/** @internal */\n\tbuild(ctx: TransitionContext): TransitionParts;\n}\n\nconst offsetFor = (dir: TransitionDirection, w: number, h: number) => {\n\tswitch (dir) {\n\t\tcase \"left\":\n\t\t\treturn { dx: -w, dy: 0 };\n\t\tcase \"right\":\n\t\t\treturn { dx: w, dy: 0 };\n\t\tcase \"up\":\n\t\t\treturn { dx: 0, dy: -h };\n\t\tdefault:\n\t\t\treturn { dx: 0, dy: h };\n\t}\n};\n\nfunction spec(\n\tkind: string,\n\tframes: number,\n\tbuild: (ctx: TransitionContext) => TransitionParts,\n): TransitionSpec {\n\treturn { kind, frames: Math.max(0, Math.round(frames)), build };\n}\n\n/**\n * Scene-to-scene transitions for `Layer.sequence`. `frames` is how long the\n * two scenes overlap; `ease` shapes the move (default \"power3.inOut\").\n */\nexport const Transition = {\n\t/** Instant cut. */\n\tcut: (): TransitionSpec => spec(\"cut\", 0, () => ({})),\n\n\t/** The incoming scene fades in over the outgoing one. */\n\tcrossfade: (frames = 15, ease = \"sine.inOut\"): TransitionSpec =>\n\t\tspec(\"crossfade\", frames, (c) => ({\n\t\t\tincoming: LayerAnimation.keys(\"opacity\", [\n\t\t\t\t[0, 0],\n\t\t\t\t[c.frames, 1, ease],\n\t\t\t]),\n\t\t})),\n\n\t/** Out to the background, then in: a dip to the composition's background color. */\n\tfadeThrough: (frames = 20, ease = \"sine.inOut\"): TransitionSpec =>\n\t\tspec(\"fadeThrough\", frames, (c) => {\n\t\t\tconst half = Math.max(1, Math.floor(c.frames / 2));\n\t\t\treturn {\n\t\t\t\toutgoing: LayerAnimation.keys(\"opacity\", [\n\t\t\t\t\t[c.outStart, 1],\n\t\t\t\t\t[c.outStart + half, 0, ease],\n\t\t\t\t]),\n\t\t\t\tincoming: LayerAnimation.keys(\"opacity\", [\n\t\t\t\t\t[0, 0],\n\t\t\t\t\t[half, 0],\n\t\t\t\t\t[c.frames, 1, ease],\n\t\t\t\t]),\n\t\t\t};\n\t\t}),\n\n\t/** Both scenes move together: the new one pushes the old one out toward `direction`. */\n\tpush: (\n\t\tdirection: TransitionDirection = \"left\",\n\t\tframes = 18,\n\t\tease = \"power3.inOut\",\n\t): TransitionSpec =>\n\t\tspec(\"push\", frames, (c) => {\n\t\t\tconst { dx, dy } = offsetFor(direction, c.width, c.height);\n\t\t\tconst out = LayerAnimation.create();\n\t\t\tconst inc = LayerAnimation.create();\n\t\t\tif (dx !== 0) {\n\t\t\t\tout.keys(\"x\", [\n\t\t\t\t\t[c.outStart, c.outRest.x],\n\t\t\t\t\t[c.outStart + c.frames, c.outRest.x + dx, ease],\n\t\t\t\t]);\n\t\t\t\tinc.keys(\"x\", [\n\t\t\t\t\t[0, c.inRest.x - dx],\n\t\t\t\t\t[c.frames, c.inRest.x, ease],\n\t\t\t\t]);\n\t\t\t} else {\n\t\t\t\tout.keys(\"y\", [\n\t\t\t\t\t[c.outStart, c.outRest.y],\n\t\t\t\t\t[c.outStart + c.frames, c.outRest.y + dy, ease],\n\t\t\t\t]);\n\t\t\t\tinc.keys(\"y\", [\n\t\t\t\t\t[0, c.inRest.y - dy],\n\t\t\t\t\t[c.frames, c.inRest.y, ease],\n\t\t\t\t]);\n\t\t\t}\n\t\t\treturn { outgoing: out, incoming: inc };\n\t\t}),\n\n\t/** The new scene slides in over the old one, which stays put and dims slightly. */\n\tslide: (\n\t\tdirection: TransitionDirection = \"left\",\n\t\tframes = 18,\n\t\tease = \"power3.out\",\n\t): TransitionSpec =>\n\t\tspec(\"slide\", frames, (c) => {\n\t\t\tconst { dx, dy } = offsetFor(direction, c.width, c.height);\n\t\t\tconst prop = dx !== 0 ? \"x\" : \"y\";\n\t\t\tconst rest = dx !== 0 ? c.inRest.x : c.inRest.y;\n\t\t\treturn {\n\t\t\t\toutgoing: LayerAnimation.keys(\"opacity\", [\n\t\t\t\t\t[c.outStart, 1],\n\t\t\t\t\t[c.outStart + c.frames, 0.6, ease],\n\t\t\t\t]),\n\t\t\t\tincoming: LayerAnimation.keys(prop, [\n\t\t\t\t\t[0, rest - (dx || dy)],\n\t\t\t\t\t[c.frames, rest, ease],\n\t\t\t\t]),\n\t\t\t};\n\t\t}),\n\n\t/** Old scene grows and fades, new one settles in from slightly small. */\n\tzoom: (frames = 18, ease = \"power2.inOut\"): TransitionSpec =>\n\t\tspec(\"zoom\", frames, (c) => ({\n\t\t\toutgoing: LayerAnimation.create()\n\t\t\t\t.keys(\"scale\", [\n\t\t\t\t\t[c.outStart, 1],\n\t\t\t\t\t[c.outStart + c.frames, 1.25, ease],\n\t\t\t\t])\n\t\t\t\t.keys(\"opacity\", [\n\t\t\t\t\t[c.outStart, 1],\n\t\t\t\t\t[c.outStart + c.frames, 0, ease],\n\t\t\t\t]),\n\t\t\tincoming: LayerAnimation.create()\n\t\t\t\t.keys(\"scale\", [\n\t\t\t\t\t[0, 0.85],\n\t\t\t\t\t[c.frames, 1, ease],\n\t\t\t\t])\n\t\t\t\t.keys(\"opacity\", [\n\t\t\t\t\t[0, 0],\n\t\t\t\t\t[c.frames, 1, ease],\n\t\t\t\t]),\n\t\t})),\n\n\t/** A fast, motion-blurred push: the camera whips to the next scene. */\n\twhip: (\n\t\tdirection: TransitionDirection = \"left\",\n\t\tframes = 10,\n\t): TransitionSpec => {\n\t\tconst push = Transition.push(direction, frames, \"expo.inOut\");\n\t\treturn spec(\"whip\", frames, (c) => ({\n\t\t\t...push.build(c),\n\t\t\tsceneProps: { motionBlurShutter: 360 },\n\t\t}));\n\t},\n\n\t/** A hard edge sweeps across, revealing the new scene. */\n\twipe: (\n\t\tdirection: TransitionDirection = \"left\",\n\t\tframes = 18,\n\t\tease = \"power2.inOut\",\n\t): TransitionSpec =>\n\t\tspec(\"wipe\", frames, (c) => {\n\t\t\t// `direction` is where the edge travels: \"left\" reveals from the right.\n\t\t\tconst { dx, dy } = offsetFor(direction, c.width, c.height);\n\t\t\tconst prop = dx !== 0 ? \"x\" : \"y\";\n\t\t\tconst rest = dx !== 0 ? c.inRest.x : c.inRest.y;\n\t\t\treturn {\n\t\t\t\tincomingMatte: Layer.box({\n\t\t\t\t\tid: autoId(\"wipe-matte\"),\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tx: c.inRest.x,\n\t\t\t\t\ty: c.inRest.y,\n\t\t\t\t\twidth: c.width,\n\t\t\t\t\theight: c.height,\n\t\t\t\t\tbackground: \"#ffffff\",\n\t\t\t\t}).animate(\n\t\t\t\t\tLayerAnimation.keys(prop, [\n\t\t\t\t\t\t[0, rest - (dx || dy)],\n\t\t\t\t\t\t[c.frames, rest, ease],\n\t\t\t\t\t]),\n\t\t\t\t),\n\t\t\t};\n\t\t}),\n\n\t/** A circle opens from the center (or `at`, as fractions of the frame) to reveal the new scene. */\n\tiris: (\n\t\tframes = 20,\n\t\toptions: { at?: [number, number]; ease?: string } = {},\n\t): TransitionSpec =>\n\t\tspec(\"iris\", frames, (c) => {\n\t\t\tconst [fx, fy] = options.at ?? [0.5, 0.5];\n\t\t\tconst cx = c.inRest.x + fx * c.width;\n\t\t\tconst cy = c.inRest.y + fy * c.height;\n\t\t\t// Big enough to cover the farthest corner.\n\t\t\tconst r = Math.hypot(\n\t\t\t\tMath.max(fx, 1 - fx) * c.width,\n\t\t\t\tMath.max(fy, 1 - fy) * c.height,\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tincomingMatte: Layer.shape(\"circle\", {\n\t\t\t\t\tid: autoId(\"iris-matte\"),\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tx: cx - r,\n\t\t\t\t\ty: cy - r,\n\t\t\t\t\twidth: r * 2,\n\t\t\t\t\theight: r * 2,\n\t\t\t\t\tfillColor: \"#ffffff\",\n\t\t\t\t}).animate(\n\t\t\t\t\tLayerAnimation.keys(\"scale\", [\n\t\t\t\t\t\t[0, 0],\n\t\t\t\t\t\t[c.frames, 1, options.ease ?? \"power2.inOut\"],\n\t\t\t\t\t]),\n\t\t\t\t),\n\t\t\t};\n\t\t}),\n};\n\nexport interface SequenceEntry {\n\t/** A full-frame layer (usually a box holding the scene). */\n\tscene: AnimatableNode<LayoutNode> | LayoutNode;\n\t/** Frames this scene is on screen, transitions included. */\n\tduration: number;\n\t/** How this scene arrives from the previous one (default: cut). */\n\ttransition?: TransitionSpec;\n}\n\nexport interface SceneSequenceOptions {\n\tid?: string;\n\t/** Scene size used by moving transitions (default: each scene's own width/height, else 1920×1080). */\n\twidth?: number;\n\theight?: number;\n\t/** First frame of the whole sequence. Default 0. */\n\tstartFrame?: number;\n}\n\nexport type SequenceNode = AnimatableNode<BoxNode> & {\n\t/** Total length in frames: put it in the composition's duration. */\n\treadonly totalFrames: number;\n\t/** Where each scene starts (composition frames, relative to the sequence). */\n\treadonly sceneStarts: readonly number[];\n};\n\nfunction sizeOf(node: LayoutNode, axis: \"width\" | \"height\", fallback: number) {\n\tconst v = (node as unknown as Record<string, unknown>)[axis];\n\treturn typeof v === \"number\" ? v : fallback;\n}\n\n/**\n * Scenes back to back, each overlapping the previous one by its transition.\n * Scene timing is set for you (`startFrame` / `durationFrames`), so every\n * scene keys its own animation from its local frame 0.\n */\nexport function sequence(\n\tentries: SequenceEntry[],\n\toptions: SceneSequenceOptions = {},\n): SequenceNode {\n\tconst scenes: LayoutNode[] = [];\n\tconst starts: number[] = [];\n\tlet cursor = 0;\n\tentries.forEach((entry, i) => {\n\t\tconst t = i === 0 ? undefined : entry.transition;\n\t\tconst overlap = Math.min(t?.frames ?? 0, entries[i - 1]?.duration ?? 0);\n\t\tconst start = Math.max(0, cursor - overlap);\n\t\tconst duration = Math.max(1, Math.round(entry.duration));\n\t\tstarts.push(start);\n\t\tconst node = entry.scene as LayoutNode & Record<string, unknown>;\n\t\t// Scenes stack in one frame rather than flowing one under the other.\n\t\tif (node.position === undefined || node.position === \"relative\") {\n\t\t\tnode.position = \"absolute\";\n\t\t\tnode.x ??= 0;\n\t\t\tnode.y ??= 0;\n\t\t}\n\t\tnode.startFrame = start;\n\t\tnode.durationFrames = duration;\n\t\tscenes.push(node);\n\t\tcursor = start + duration;\n\t});\n\n\tentries.forEach((entry, i) => {\n\t\tif (i === 0 || !entry.transition || entry.transition.frames === 0) return;\n\t\tconst prev = scenes[i - 1] as LayoutNode & Record<string, unknown>;\n\t\tconst cur = scenes[i] as LayoutNode & Record<string, unknown>;\n\t\tconst frames = Math.min(entry.transition.frames, entries[i - 1].duration);\n\t\tconst width = options.width ?? sizeOf(cur, \"width\", 1920);\n\t\tconst height = options.height ?? sizeOf(cur, \"height\", 1080);\n\t\tconst parts = entry.transition.build({\n\t\t\twidth,\n\t\t\theight,\n\t\t\tframes,\n\t\t\toutStart: entries[i - 1].duration - frames,\n\t\t\toutRest: {\n\t\t\t\tx: typeof prev.x === \"number\" ? prev.x : 0,\n\t\t\t\ty: typeof prev.y === \"number\" ? prev.y : 0,\n\t\t\t},\n\t\t\tinRest: {\n\t\t\t\tx: typeof cur.x === \"number\" ? cur.x : 0,\n\t\t\t\ty: typeof cur.y === \"number\" ? cur.y : 0,\n\t\t\t},\n\t\t});\n\t\tconst merge = (\n\t\t\tnode: LayoutNode & Record<string, unknown>,\n\t\t\tanim?: LayerAnimation,\n\t\t) => {\n\t\t\tif (!anim) return;\n\t\t\tconst existing =\n\t\t\t\t(node.animation as { tracks?: AnimationTrack[] } | undefined)?.tracks ??\n\t\t\t\t[];\n\t\t\tnode.animation = LayerAnimation.merge(\n\t\t\t\t{ tracks: existing },\n\t\t\t\tanim,\n\t\t\t).toSpec();\n\t\t};\n\t\tmerge(prev, parts.outgoing);\n\t\tmerge(cur, parts.incoming);\n\t\tif (parts.sceneProps) {\n\t\t\tObject.assign(prev, parts.sceneProps);\n\t\t\tObject.assign(cur, parts.sceneProps);\n\t\t}\n\t\tif (parts.incomingMatte) {\n\t\t\tcur.matte = { node: parts.incomingMatte, mode: \"alpha\" };\n\t\t}\n\t});\n\n\tconst root = Layer.box({\n\t\tid: options.id ?? autoId(\"sequence\"),\n\t\tposition: \"absolute\",\n\t\tx: 0,\n\t\ty: 0,\n\t\twidth:\n\t\t\toptions.width ?? sizeOf(scenes[0] ?? ({} as LayoutNode), \"width\", 1920),\n\t\theight:\n\t\t\toptions.height ?? sizeOf(scenes[0] ?? ({} as LayoutNode), \"height\", 1080),\n\t\tstartFrame: options.startFrame ?? 0,\n\t\tdurationFrames: Math.max(1, cursor),\n\t\tchildren: scenes,\n\t});\n\tObject.defineProperty(root, \"totalFrames\", {\n\t\tvalue: cursor,\n\t\tenumerable: false,\n\t});\n\tObject.defineProperty(root, \"sceneStarts\", {\n\t\tvalue: starts,\n\t\tenumerable: false,\n\t});\n\treturn root as SequenceNode;\n}\n","import type {\n\tEnvironmentPreset,\n\tLightNode,\n\tToneMapping,\n} from \"@framefields/compositions/program\";\nimport { autoId } from \"./ids.js\";\nimport {\n\ttype AnimatableNode,\n\ttype EnvironmentOptions,\n\tLight,\n} from \"./index.js\";\n\nexport interface LightingRigOptions {\n\t/** What the lights aim at (world px). Default: the canvas center at z 0. */\n\ttarget?: [number, number, number];\n\t/** How far the lights sit from the target. Default 1600. */\n\tdistance?: number;\n\t/** Turns the whole rig (lights and environment) around the vertical axis, degrees. */\n\trotation?: number;\n\t/** Scales every light. Default 1. */\n\tintensity?: number;\n\t/** Exposure in stops. Default 0. */\n\texposure?: number;\n\ttoneMapping?: ToneMapping;\n\t/** Key light casts a soft shadow. Default true. */\n\tshadows?: boolean;\n\t/** Shadow edge blur in texels. Default 3. */\n\tshadowSoftness?: number;\n\t/** Fog fading into the background, e.g. `{ color: BG, start: 2500, end: 6000 }`. */\n\tfog?: EnvironmentOptions[\"fog\"];\n\t/** Glow around emissive surfaces and highlights: `true` or settings. */\n\tbloom?: EnvironmentOptions[\"bloom\"];\n\t/** Prefix for the rig's node ids. */\n\tid?: string;\n}\n\ninterface RigSpec {\n\tenvironment: EnvironmentPreset;\n\tenvIntensity: number;\n\t/** Light directions relative to the target, before `rotation`; y is down. */\n\tkey: { dir: [number, number, number]; color: string; intensity: number };\n\trim?: { dir: [number, number, number]; color: string; intensity: number };\n\tfill?: { dir: [number, number, number]; color: string; intensity: number };\n}\n\nconst RIGS = {\n\t/** Product photography: soft overhead key with a shadow, cool rim, studio reflections. */\n\tstudio: {\n\t\tenvironment: \"studio\",\n\t\tenvIntensity: 1,\n\t\tkey: { dir: [-0.55, -1, -0.7], color: \"#fff6ec\", intensity: 1.1 },\n\t\trim: { dir: [0.9, -0.5, 0.9], color: \"#dbe8ff\", intensity: 0.9 },\n\t},\n\t/** Bright, airy, low contrast: lifestyle and UI-on-device shots. */\n\tsoft: {\n\t\tenvironment: \"soft\",\n\t\tenvIntensity: 1,\n\t\tkey: { dir: [-0.4, -1, -0.8], color: \"#ffffff\", intensity: 1.0 },\n\t},\n\t/** Low warm sun, long shadows, cool sky fill. */\n\tsunset: {\n\t\tenvironment: \"sunset\",\n\t\tenvIntensity: 0.9,\n\t\tkey: { dir: [-1, -0.35, -0.3], color: \"#ffb27a\", intensity: 2.2 },\n\t\tfill: { dir: [0.8, -0.6, -0.4], color: \"#7f9cff\", intensity: 0.35 },\n\t},\n\t/** Moody: dark world, hard key, strong rim. Pair with emissive accents. */\n\tdramatic: {\n\t\tenvironment: \"night\",\n\t\tenvIntensity: 0.8,\n\t\tkey: { dir: [-0.8, -1, -0.35], color: \"#ffffff\", intensity: 2.4 },\n\t\trim: { dir: [0.7, -0.4, 1], color: \"#8fb4ff\", intensity: 1.8 },\n\t},\n} satisfies Record<string, RigSpec>;\n\nexport type LightingRig = keyof typeof RIGS;\n\nfunction rotateY(\n\t[x, y, z]: [number, number, number],\n\tdegrees: number,\n): [number, number, number] {\n\tconst r = (degrees * Math.PI) / 180;\n\tconst c = Math.cos(r);\n\tconst s = Math.sin(r);\n\treturn [c * x + s * z, y, -s * x + c * z];\n}\n\nfunction aim(\n\tdir: [number, number, number],\n\ttarget: [number, number, number],\n\tdistance: number,\n\trotation: number,\n): Pick<LightNode, \"x\" | \"y\" | \"z\" | \"targetX\" | \"targetY\" | \"targetZ\"> {\n\tconst [dx, dy, dz] = rotateY(dir, rotation);\n\tconst len = Math.hypot(dx, dy, dz) || 1;\n\treturn {\n\t\tx: target[0] + (dx / len) * distance,\n\t\ty: target[1] + (dy / len) * distance,\n\t\tz: target[2] + (dz / len) * distance,\n\t\ttargetX: target[0],\n\t\ttargetY: target[1],\n\t\ttargetZ: target[2],\n\t};\n}\n\nfunction rig(\n\tname: LightingRig,\n\toptions: LightingRigOptions,\n): AnimatableNode<LightNode>[] {\n\tconst spec: RigSpec = RIGS[name];\n\tconst target = options.target ?? [960, 540, 0];\n\tconst distance = options.distance ?? 1600;\n\tconst rotation = options.rotation ?? 0;\n\tconst k = options.intensity ?? 1;\n\tconst id = options.id ?? autoId(`lighting-${name}`);\n\tconst nodes: AnimatableNode<LightNode>[] = [\n\t\tLight.environment(spec.environment, {\n\t\t\tid: `${id}-environment`,\n\t\t\tintensity: spec.envIntensity * k,\n\t\t\trotation,\n\t\t\texposure: options.exposure,\n\t\t\ttoneMapping: options.toneMapping,\n\t\t\tfog: options.fog,\n\t\t\tbloom: options.bloom,\n\t\t}),\n\t\tLight.directional({\n\t\t\tid: `${id}-key`,\n\t\t\tcolor: spec.key.color,\n\t\t\tintensity: spec.key.intensity * k,\n\t\t\t...aim(spec.key.dir, target, distance, rotation),\n\t\t\tcastShadow: options.shadows ?? true,\n\t\t\tshadowSoftness: options.shadowSoftness ?? 3,\n\t\t}),\n\t];\n\tfor (const [part, light] of [\n\t\t[\"rim\", spec.rim],\n\t\t[\"fill\", spec.fill],\n\t] as const) {\n\t\tif (!light) continue;\n\t\tnodes.push(\n\t\t\tLight.directional({\n\t\t\t\tid: `${id}-${part}`,\n\t\t\t\tcolor: light.color,\n\t\t\t\tintensity: light.intensity * k,\n\t\t\t\t...aim(light.dir, target, distance, rotation),\n\t\t\t}),\n\t\t);\n\t}\n\treturn nodes;\n}\n\n/**\n * Ready-made lighting: an environment (physical shading, tone mapping) plus\n * placed key / rim / fill lights, the key casting a soft shadow. Add the\n * returned nodes to the composition: `comp.add(Lighting.studio({ target }))`.\n *\n * Tweak from there rather than starting from zero: `intensity`, `exposure`,\n * `rotation` (turns the rig), `shadowSoftness`, `fog`.\n */\nexport const Lighting = {\n\tstudio: (options: LightingRigOptions = {}) => rig(\"studio\", options),\n\tsoft: (options: LightingRigOptions = {}) => rig(\"soft\", options),\n\tsunset: (options: LightingRigOptions = {}) => rig(\"sunset\", options),\n\tdramatic: (options: LightingRigOptions = {}) => rig(\"dramatic\", options),\n};\n","/**\n * The simulation backend the physics worlds drive. Worlds talk to this\n * engine-neutral surface only, so another solver can be dropped in later;\n * Rapier (deterministic builds, identical results on every platform) is the\n * one shipped. Units here are SI: meters, radians, seconds, y down.\n */\nimport type RAPIER2D from \"@dimforge/rapier2d-deterministic-compat\";\nimport type RAPIER3D from \"@dimforge/rapier3d-deterministic-compat\";\n\nexport type Vec2 = [number, number];\nexport type Vec3 = [number, number, number];\n/** Quaternion as [x, y, z, w]. */\nexport type Quat = [number, number, number, number];\n\nexport type BodyType = \"dynamic\" | \"fixed\" | \"kinematic\";\n\ninterface MaterialSpec {\n\tdensity: number;\n\tfriction: number;\n\trestitution: number;\n}\n\nexport type Shape2D =\n\t| { kind: \"box\"; hx: number; hy: number; radius?: number }\n\t| { kind: \"ball\"; radius: number }\n\t/** Flat [x0, y0, x1, y1, …] around the body origin. */\n\t| { kind: \"hull\"; points: number[] };\n\nexport type Shape3D =\n\t| { kind: \"box\"; hx: number; hy: number; hz: number; radius?: number }\n\t| { kind: \"ball\"; radius: number }\n\t/** Axis along y. */\n\t| { kind: \"cylinder\"; halfHeight: number; radius: number }\n\t/** Flat [x0, y0, z0, …] around the body origin. */\n\t| { kind: \"hull\"; points: number[] };\n\ninterface BodySpecBase extends MaterialSpec {\n\ttype: BodyType;\n\tlinearDamping: number;\n\tangularDamping: number;\n\tgravityScale: number;\n\tlockRotation: boolean;\n\tccd: boolean;\n\tenabled: boolean;\n\t/** Touches nothing (joint anchors). */\n\tsensor?: boolean;\n}\n\nexport interface BodySpec2D extends BodySpecBase {\n\tposition: Vec2;\n\tangle: number;\n\tvelocity: Vec2;\n\tangularVelocity: number;\n\tshape: Shape2D;\n}\n\nexport interface BodySpec3D extends BodySpecBase {\n\t/** Per-axis rotation, when only some axes are locked: [x, y, z] allowed. */\n\tenabledRotations?: [boolean, boolean, boolean];\n\tposition: Vec3;\n\trotation: Quat;\n\tvelocity: Vec3;\n\tangularVelocity: Vec3;\n\tshape: Shape3D;\n}\n\nexport type JointSpec<V> =\n\t| { type: \"revolute\"; anchorA: V; anchorB: V; axis?: Vec3 }\n\t| { type: \"spherical\"; anchorA: V; anchorB: V }\n\t| { type: \"fixed\"; anchorA: V; anchorB: V }\n\t| { type: \"rope\"; anchorA: V; anchorB: V; length: number }\n\t| {\n\t\t\ttype: \"spring\";\n\t\t\tanchorA: V;\n\t\t\tanchorB: V;\n\t\t\trestLength: number;\n\t\t\tstiffness: number;\n\t\t\tdamping: number;\n\t };\n\nexport interface SimBody<V, R> {\n\tposition(): V;\n\trotation(): R;\n\tvelocity(): V;\n\t/** 2D: rad/s; 3D: rad/s per axis. */\n\tangularVelocity(): R extends number ? number : Vec3;\n\tsleeping(): boolean;\n\tmass(): number;\n\tsetEnabled(enabled: boolean): void;\n\tapplyImpulse(impulse: V): void;\n\tsetKinematicTarget(position: V, rotation: R): void;\n}\n\nexport type SimBody2D = SimBody<Vec2, number>;\nexport type SimBody3D = SimBody<Vec3, Quat>;\n\nexport interface SimWorld<V, B, S> {\n\taddBody(spec: S): B;\n\taddJoint(a: B, b: B, spec: JointSpec<V>): void;\n\tstep(dt: number): void;\n\t/** Pairs that started touching during the last step. */\n\tdrainCollisionStarts(): Array<[B, B]>;\n\tfree(): void;\n}\n\nexport type SimWorld2D = SimWorld<Vec2, SimBody2D, BodySpec2D>;\nexport type SimWorld3D = SimWorld<Vec3, SimBody3D, BodySpec3D>;\n\nexport interface PhysicsBackend {\n\tcreateWorld2D(gravity: Vec2): SimWorld2D;\n\tcreateWorld3D(gravity: Vec3): SimWorld3D;\n}\n\n// ---------------------------------------------------------------------------\n// Rapier\n// ---------------------------------------------------------------------------\n\ntype Rapier2D = typeof RAPIER2D;\ntype Rapier3D = typeof RAPIER3D;\n\n// Literal specifiers: the preview's browser bundle splits each engine into a\n// chunk loaded on first use; Node keeps them as external optional packages.\nconst RAPIER_2D = \"@dimforge/rapier2d-deterministic-compat\";\nconst RAPIER_3D = \"@dimforge/rapier3d-deterministic-compat\";\n\nasync function loadRapier<T>(\n\tspecifier: string,\n\tload: () => Promise<unknown>,\n): Promise<T> {\n\tlet mod: { default?: T } & T;\n\ttry {\n\t\tmod = (await load()) as { default?: T } & T;\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Physics needs the optional dependency \"${specifier}\". Install it with \\`npm i ${specifier}\\`.`,\n\t\t\t{ cause: error },\n\t\t);\n\t}\n\tconst rapier = (mod.default ?? mod) as T & { init(): Promise<void> };\n\tawait rapier.init();\n\treturn rapier;\n}\n\nlet rapier2d: Promise<Rapier2D> | undefined;\nlet rapier3d: Promise<Rapier3D> | undefined;\n\n/** Loads and initializes Rapier once per process; 2D and 3D are separate modules. */\nexport async function rapierBackend(dims: 2 | 3): Promise<PhysicsBackend> {\n\tif (dims === 2) {\n\t\trapier2d ??= loadRapier<Rapier2D>(\n\t\t\tRAPIER_2D,\n\t\t\t() => import(\"@dimforge/rapier2d-deterministic-compat\"),\n\t\t);\n\t\tconst R = await rapier2d;\n\t\treturn {\n\t\t\tcreateWorld2D: (gravity) => new RapierWorld2D(R, gravity),\n\t\t\tcreateWorld3D: () => {\n\t\t\t\tthrow new Error(\"This backend was loaded for 2D.\");\n\t\t\t},\n\t\t};\n\t}\n\trapier3d ??= loadRapier<Rapier3D>(\n\t\tRAPIER_3D,\n\t\t() => import(\"@dimforge/rapier3d-deterministic-compat\"),\n\t);\n\tconst R = await rapier3d;\n\treturn {\n\t\tcreateWorld2D: () => {\n\t\t\tthrow new Error(\"This backend was loaded for 3D.\");\n\t\t},\n\t\tcreateWorld3D: (gravity) => new RapierWorld3D(R, gravity),\n\t};\n}\n\nclass RapierWorld2D implements SimWorld2D {\n\tprivate readonly world: RAPIER2D.World;\n\tprivate readonly events: RAPIER2D.EventQueue;\n\tprivate readonly byCollider = new Map<number, SimBody2D>();\n\tprivate readonly started: Array<[SimBody2D, SimBody2D]> = [];\n\n\tconstructor(\n\t\tprivate readonly R: Rapier2D,\n\t\tgravity: Vec2,\n\t) {\n\t\tthis.world = new R.World({ x: gravity[0], y: gravity[1] });\n\t\tthis.events = new R.EventQueue(true);\n\t}\n\n\taddBody(spec: BodySpec2D): SimBody2D {\n\t\tconst R = this.R;\n\t\tconst desc = bodyDesc(R, spec.type)\n\t\t\t.setTranslation(spec.position[0], spec.position[1])\n\t\t\t.setRotation(spec.angle)\n\t\t\t.setLinvel(spec.velocity[0], spec.velocity[1])\n\t\t\t.setAngvel(spec.angularVelocity)\n\t\t\t.setLinearDamping(spec.linearDamping)\n\t\t\t.setAngularDamping(spec.angularDamping)\n\t\t\t.setGravityScale(spec.gravityScale)\n\t\t\t.setCcdEnabled(spec.ccd)\n\t\t\t.setEnabled(spec.enabled);\n\t\tif (spec.lockRotation) desc.lockRotations();\n\t\tconst body = this.world.createRigidBody(desc);\n\t\tconst collider = this.world.createCollider(\n\t\t\tshapeDesc2D(R, spec.shape)\n\t\t\t\t.setDensity(spec.density)\n\t\t\t\t.setFriction(spec.friction)\n\t\t\t\t.setRestitution(spec.restitution)\n\t\t\t\t.setActiveEvents(R.ActiveEvents.COLLISION_EVENTS)\n\t\t\t\t.setSensor(spec.sensor ?? false),\n\t\t\tbody,\n\t\t);\n\t\tconst sim: SimBody2D & { raw: RAPIER2D.RigidBody } = {\n\t\t\traw: body,\n\t\t\tposition: () => {\n\t\t\t\tconst t = body.translation();\n\t\t\t\treturn [t.x, t.y];\n\t\t\t},\n\t\t\trotation: () => body.rotation(),\n\t\t\tvelocity: () => {\n\t\t\t\tconst v = body.linvel();\n\t\t\t\treturn [v.x, v.y];\n\t\t\t},\n\t\t\tangularVelocity: () => body.angvel(),\n\t\t\tsleeping: () => body.isSleeping(),\n\t\t\tmass: () => body.mass(),\n\t\t\tsetEnabled: (on) => body.setEnabled(on),\n\t\t\tapplyImpulse: ([x, y]) => body.applyImpulse({ x, y }, true),\n\t\t\tsetKinematicTarget: ([x, y], angle) => {\n\t\t\t\tbody.setNextKinematicTranslation({ x, y });\n\t\t\t\tbody.setNextKinematicRotation(angle);\n\t\t\t},\n\t\t};\n\t\tthis.byCollider.set(collider.handle, sim);\n\t\treturn sim;\n\t}\n\n\taddJoint(a: SimBody2D, b: SimBody2D, spec: JointSpec<Vec2>): void {\n\t\tconst R = this.R;\n\t\tconst a1 = { x: spec.anchorA[0], y: spec.anchorA[1] };\n\t\tconst a2 = { x: spec.anchorB[0], y: spec.anchorB[1] };\n\t\tlet data: RAPIER2D.JointData;\n\t\tswitch (spec.type) {\n\t\t\tcase \"revolute\":\n\t\t\tcase \"spherical\":\n\t\t\t\tdata = R.JointData.revolute(a1, a2);\n\t\t\t\tbreak;\n\t\t\tcase \"fixed\":\n\t\t\t\tdata = R.JointData.fixed(a1, 0, a2, 0);\n\t\t\t\tbreak;\n\t\t\tcase \"rope\":\n\t\t\t\tdata = R.JointData.rope(spec.length, a1, a2);\n\t\t\t\tbreak;\n\t\t\tcase \"spring\":\n\t\t\t\tdata = R.JointData.spring(\n\t\t\t\t\tspec.restLength,\n\t\t\t\t\tspec.stiffness,\n\t\t\t\t\tspec.damping,\n\t\t\t\t\ta1,\n\t\t\t\t\ta2,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t}\n\t\t// Jointed bodies pass through each other where they meet.\n\t\tthis.world\n\t\t\t.createImpulseJoint(data, rawBody(a), rawBody(b), true)\n\t\t\t.setContactsEnabled(false);\n\t}\n\n\tstep(dt: number): void {\n\t\tthis.world.timestep = dt;\n\t\tthis.world.step(this.events);\n\t\tthis.events.drainCollisionEvents((h1, h2, started) => {\n\t\t\tif (!started) return;\n\t\t\tconst a = this.byCollider.get(h1);\n\t\t\tconst b = this.byCollider.get(h2);\n\t\t\tif (a && b) this.started.push([a, b]);\n\t\t});\n\t}\n\n\tdrainCollisionStarts(): Array<[SimBody2D, SimBody2D]> {\n\t\treturn this.started.splice(0);\n\t}\n\n\tfree(): void {\n\t\tthis.events.free();\n\t\tthis.world.free();\n\t}\n}\n\nclass RapierWorld3D implements SimWorld3D {\n\tprivate readonly world: RAPIER3D.World;\n\tprivate readonly events: RAPIER3D.EventQueue;\n\tprivate readonly byCollider = new Map<number, SimBody3D>();\n\tprivate readonly started: Array<[SimBody3D, SimBody3D]> = [];\n\n\tconstructor(\n\t\tprivate readonly R: Rapier3D,\n\t\tgravity: Vec3,\n\t) {\n\t\tthis.world = new R.World({ x: gravity[0], y: gravity[1], z: gravity[2] });\n\t\tthis.events = new R.EventQueue(true);\n\t}\n\n\taddBody(spec: BodySpec3D): SimBody3D {\n\t\tconst R = this.R;\n\t\tconst [qx, qy, qz, qw] = spec.rotation;\n\t\tconst desc = bodyDesc(R, spec.type)\n\t\t\t.setTranslation(spec.position[0], spec.position[1], spec.position[2])\n\t\t\t.setRotation({ x: qx, y: qy, z: qz, w: qw })\n\t\t\t.setLinvel(spec.velocity[0], spec.velocity[1], spec.velocity[2])\n\t\t\t// Locked axes start still too (Rapier keeps an initial spin otherwise).\n\t\t\t.setAngvel(\n\t\t\t\tvec3(\n\t\t\t\t\tspec.lockRotation\n\t\t\t\t\t\t? [0, 0, 0]\n\t\t\t\t\t\t: (spec.angularVelocity.map((w, i) =>\n\t\t\t\t\t\t\t\tspec.enabledRotations && !spec.enabledRotations[i] ? 0 : w,\n\t\t\t\t\t\t\t) as Vec3),\n\t\t\t\t),\n\t\t\t)\n\t\t\t.setLinearDamping(spec.linearDamping)\n\t\t\t.setAngularDamping(spec.angularDamping)\n\t\t\t.setGravityScale(spec.gravityScale)\n\t\t\t.setCcdEnabled(spec.ccd)\n\t\t\t.setEnabled(spec.enabled);\n\t\tif (spec.lockRotation) desc.lockRotations();\n\t\telse if (spec.enabledRotations)\n\t\t\tdesc.enabledRotations(...spec.enabledRotations);\n\t\tconst body = this.world.createRigidBody(desc);\n\t\tconst shape = shapeDesc3D(R, spec.shape);\n\t\tconst collider = this.world.createCollider(\n\t\t\tshape\n\t\t\t\t.setDensity(spec.density)\n\t\t\t\t.setFriction(spec.friction)\n\t\t\t\t.setRestitution(spec.restitution)\n\t\t\t\t.setActiveEvents(R.ActiveEvents.COLLISION_EVENTS)\n\t\t\t\t.setSensor(spec.sensor ?? false),\n\t\t\tbody,\n\t\t);\n\t\tconst sim: SimBody3D & { raw: RAPIER3D.RigidBody } = {\n\t\t\traw: body,\n\t\t\tposition: () => {\n\t\t\t\tconst t = body.translation();\n\t\t\t\treturn [t.x, t.y, t.z];\n\t\t\t},\n\t\t\trotation: () => {\n\t\t\t\tconst q = body.rotation();\n\t\t\t\treturn [q.x, q.y, q.z, q.w];\n\t\t\t},\n\t\t\tvelocity: () => {\n\t\t\t\tconst v = body.linvel();\n\t\t\t\treturn [v.x, v.y, v.z];\n\t\t\t},\n\t\t\tangularVelocity: () => {\n\t\t\t\tconst w = body.angvel();\n\t\t\t\treturn [w.x, w.y, w.z];\n\t\t\t},\n\t\t\tsleeping: () => body.isSleeping(),\n\t\t\tmass: () => body.mass(),\n\t\t\tsetEnabled: (on) => body.setEnabled(on),\n\t\t\tapplyImpulse: (v) => body.applyImpulse(vec3(v), true),\n\t\t\tsetKinematicTarget: (p, [x, y, z, w]) => {\n\t\t\t\tbody.setNextKinematicTranslation(vec3(p));\n\t\t\t\tbody.setNextKinematicRotation({ x, y, z, w });\n\t\t\t},\n\t\t};\n\t\tthis.byCollider.set(collider.handle, sim);\n\t\treturn sim;\n\t}\n\n\taddJoint(a: SimBody3D, b: SimBody3D, spec: JointSpec<Vec3>): void {\n\t\tconst R = this.R;\n\t\tconst a1 = vec3(spec.anchorA);\n\t\tconst a2 = vec3(spec.anchorB);\n\t\tlet data: RAPIER3D.JointData;\n\t\tswitch (spec.type) {\n\t\t\tcase \"revolute\":\n\t\t\t\tdata = R.JointData.revolute(a1, a2, vec3(spec.axis ?? [0, 0, 1]));\n\t\t\t\tbreak;\n\t\t\tcase \"spherical\":\n\t\t\t\tdata = R.JointData.spherical(a1, a2);\n\t\t\t\tbreak;\n\t\t\tcase \"fixed\": {\n\t\t\t\tconst identity = { x: 0, y: 0, z: 0, w: 1 };\n\t\t\t\tdata = R.JointData.fixed(a1, identity, a2, identity);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"rope\":\n\t\t\t\tdata = R.JointData.rope(spec.length, a1, a2);\n\t\t\t\tbreak;\n\t\t\tcase \"spring\":\n\t\t\t\tdata = R.JointData.spring(\n\t\t\t\t\tspec.restLength,\n\t\t\t\t\tspec.stiffness,\n\t\t\t\t\tspec.damping,\n\t\t\t\t\ta1,\n\t\t\t\t\ta2,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t}\n\t\t// Jointed bodies pass through each other where they meet.\n\t\tthis.world\n\t\t\t.createImpulseJoint(data, rawBody(a), rawBody(b), true)\n\t\t\t.setContactsEnabled(false);\n\t}\n\n\tstep(dt: number): void {\n\t\tthis.world.timestep = dt;\n\t\tthis.world.step(this.events);\n\t\tthis.events.drainCollisionEvents((h1, h2, started) => {\n\t\t\tif (!started) return;\n\t\t\tconst a = this.byCollider.get(h1);\n\t\t\tconst b = this.byCollider.get(h2);\n\t\t\tif (a && b) this.started.push([a, b]);\n\t\t});\n\t}\n\n\tdrainCollisionStarts(): Array<[SimBody3D, SimBody3D]> {\n\t\treturn this.started.splice(0);\n\t}\n\n\tfree(): void {\n\t\tthis.events.free();\n\t\tthis.world.free();\n\t}\n}\n\nfunction vec3([x, y, z]: Vec3): { x: number; y: number; z: number } {\n\treturn { x, y, z };\n}\n\nfunction rawBody<T>(body: unknown): T {\n\treturn (body as { raw: T }).raw;\n}\n\nfunction bodyDesc<R extends Rapier2D | Rapier3D>(\n\tR: R,\n\ttype: BodyType,\n): ReturnType<R[\"RigidBodyDesc\"][\"dynamic\"]> {\n\tconst D = R.RigidBodyDesc;\n\tconst desc =\n\t\ttype === \"fixed\"\n\t\t\t? D.fixed()\n\t\t\t: type === \"kinematic\"\n\t\t\t\t? D.kinematicPositionBased()\n\t\t\t\t: D.dynamic();\n\treturn desc as ReturnType<R[\"RigidBodyDesc\"][\"dynamic\"]>;\n}\n\nfunction shapeDesc2D(R: Rapier2D, shape: Shape2D): RAPIER2D.ColliderDesc {\n\tswitch (shape.kind) {\n\t\tcase \"ball\":\n\t\t\treturn R.ColliderDesc.ball(shape.radius);\n\t\tcase \"box\": {\n\t\t\t// The rounded border wraps a core box; keep the core solid (a flat core has no mass).\n\t\t\tconst r = Math.min(shape.radius ?? 0, shape.hx / 2, shape.hy / 2);\n\t\t\treturn r > 0\n\t\t\t\t? R.ColliderDesc.roundCuboid(shape.hx - r, shape.hy - r, r)\n\t\t\t\t: R.ColliderDesc.cuboid(shape.hx, shape.hy);\n\t\t}\n\t\tcase \"hull\": {\n\t\t\tconst desc = R.ColliderDesc.convexHull(new Float32Array(shape.points));\n\t\t\tif (!desc)\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Physics: could not build a convex hull for this shape.\",\n\t\t\t\t);\n\t\t\treturn desc;\n\t\t}\n\t}\n}\n\nfunction shapeDesc3D(R: Rapier3D, shape: Shape3D): RAPIER3D.ColliderDesc {\n\tswitch (shape.kind) {\n\t\tcase \"ball\":\n\t\t\treturn R.ColliderDesc.ball(shape.radius);\n\t\tcase \"box\": {\n\t\t\t// The rounded border wraps a core box; keep the core solid (a flat core has no mass).\n\t\t\tconst r = Math.min(\n\t\t\t\tshape.radius ?? 0,\n\t\t\t\tshape.hx / 2,\n\t\t\t\tshape.hy / 2,\n\t\t\t\tshape.hz / 2,\n\t\t\t);\n\t\t\treturn r > 0\n\t\t\t\t? R.ColliderDesc.roundCuboid(\n\t\t\t\t\t\tshape.hx - r,\n\t\t\t\t\t\tshape.hy - r,\n\t\t\t\t\t\tshape.hz - r,\n\t\t\t\t\t\tr,\n\t\t\t\t\t)\n\t\t\t\t: R.ColliderDesc.cuboid(shape.hx, shape.hy, shape.hz);\n\t\t}\n\t\tcase \"cylinder\":\n\t\t\treturn R.ColliderDesc.cylinder(shape.halfHeight, shape.radius);\n\t\tcase \"hull\": {\n\t\t\tconst desc = R.ColliderDesc.convexHull(new Float32Array(shape.points));\n\t\t\tif (!desc)\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Physics: could not build a convex hull for this shape.\",\n\t\t\t\t);\n\t\t\treturn desc;\n\t\t}\n\t}\n}\n","import type {\n\tAnimatableProp,\n\tLayoutNode,\n} from \"@framefields/compositions/program\";\nimport type { FrameSignal } from \"@framefields/core\";\nimport {\n\tbuildShapeSvgPath,\n\tparseSvgPathToSegments,\n\ttype ShapeGeometryConfig,\n} from \"@framefields/webgpu-renderers\";\nimport { FontManager } from \"../fonts/manager.js\";\nimport type {\n\tBodySpec2D,\n\tPhysicsBackend,\n\tShape2D,\n\tSimBody2D,\n\tSimWorld2D,\n\tVec2,\n} from \"./backend.js\";\nimport {\n\ttype BodyCommonOptions,\n\ttype CoreBody,\n\ttype PhysicsCollision,\n\ttype PhysicsDriver,\n\ttype PhysicsWorldOptions,\n\ttype Recording,\n\tsampleDriver,\n\tunwrapDegrees,\n\tWorldCore,\n} from \"./core.js\";\n\nexport interface World2DOptions extends PhysicsWorldOptions {\n\t/** px/s², y down. A number pulls straight down. Default 2400. */\n\tgravity?: number | [number, number];\n}\n\n/** A plain rectangle for bodies with no layer (invisible obstacles, funnels). */\nexport interface PhysicsRect {\n\tx: number;\n\ty: number;\n\twidth: number;\n\theight: number;\n\trotation?: number;\n\tborderRadius?: number;\n}\n\nexport interface Body2DOptions extends BodyCommonOptions {\n\t/**\n\t * Collider: `\"auto\"` (default) reads the layer — circles stay circles,\n\t * rounded boxes keep their radius, polygons/stars/paths use their convex\n\t * hull. Force `\"box\"`, `\"circle\"` or `\"hull\"` (the shape's outline).\n\t */\n\tshape?: \"auto\" | \"box\" | \"circle\" | \"hull\";\n\t/** Collider size override `[width, height]`, px. Text layers are measured when they have no size. */\n\tsize?: [number, number];\n\t/** px/s. */\n\tvelocity?: [number, number];\n\t/** Degrees per second, clockwise. */\n\tangularVelocity?: number;\n\t/**\n\t * Kinematic bodies: where the layer is each frame, as its own `x` / `y`\n\t * (top-left) and `rotation` (degrees). Missing ones keep the start pose.\n\t */\n\tfollow?: { x?: PhysicsDriver; y?: PhysicsDriver; rotation?: PhysicsDriver };\n}\n\ntype LayerLike = Record<string, unknown> & {\n\tkind?: string;\n\tanimate?: (...a: unknown[]) => unknown;\n};\n\n/**\n * A simulated body. Its signals hold one value per composition frame; bind\n * them to any prop or effect uniform (`.signal(\"opacity\", body.impact)`).\n * Reading a signal runs the simulation if it has not run yet.\n */\nexport class PhysicsBody2D implements CoreBody<Vec2, number> {\n\treadonly collisions: PhysicsCollision<PhysicsBody2D>[] = [];\n\t/** @internal */ readonly recording: Recording;\n\t/** @internal */ readonly sim: SimBody2D;\n\n\t/** @internal */\n\tconstructor(\n\t\t/** @internal */ readonly world: PhysicsWorld2D,\n\t\tsim: SimBody2D,\n\t\treadonly type: \"dynamic\" | \"fixed\" | \"kinematic\",\n\t\treadonly layer: LayerLike | undefined,\n\t\t/** Layer box size (unscaled), scale and pivot, to turn the center back into x/y. */\n\t\tprivate readonly frame: {\n\t\t\twidth: number;\n\t\t\theight: number;\n\t\t\tscale: number;\n\t\t\tanchorX: number;\n\t\t\tanchorY: number;\n\t\t\trotation: number;\n\t\t},\n\t\tprivate readonly options: Body2DOptions,\n\t\trecording: Recording,\n\t) {\n\t\tthis.sim = sim;\n\t\tthis.recording = recording;\n\t}\n\n\tget startFrame(): number {\n\t\treturn Math.max(0, Math.round(this.options.startFrame ?? 0));\n\t}\n\tget gravityScale(): number {\n\t\treturn this.options.gravityScale ?? 1;\n\t}\n\tget output(): Body2DOptions[\"output\"] {\n\t\treturn this.options.output;\n\t}\n\n\t/** The layer's `x` (top-left) every frame. */\n\tget x(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"x\");\n\t}\n\t/** The layer's `y` (top-left) every frame. */\n\tget y(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"y\");\n\t}\n\t/** Degrees, clockwise, continuous (no jump at 360). */\n\tget rotation(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"rotation\");\n\t}\n\t/** Body center, px. */\n\tget centerX(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"centerX\");\n\t}\n\tget centerY(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"centerY\");\n\t}\n\t/** px/s. */\n\tget vx(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"vx\");\n\t}\n\tget vy(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"vy\");\n\t}\n\t/** px/s. */\n\tget speed(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"speed\");\n\t}\n\t/** Degrees per second. */\n\tget angularVelocity(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"angularVelocity\");\n\t}\n\t/**\n\t * Hit envelope: jumps on each new contact (1 ≈ a 1500 px/s velocity\n\t * change, see `impactReference`) and decays over `impactDecay` frames.\n\t */\n\tget impact(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"impact\");\n\t}\n\t/** 1 while the body is at rest, else 0. */\n\tget sleeping(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"sleeping\");\n\t}\n\n\t/** @internal */\n\tkinematicTarget(\n\t\tframe: number,\n\t): { position: Vec2; rotation: number } | undefined {\n\t\tconst follow = this.options.follow;\n\t\tif (this.type !== \"kinematic\" || !follow) return undefined;\n\t\tconst f = this.frame;\n\t\tconst fps = this.world.fps;\n\t\tconst x =\n\t\t\tfollow.x === undefined ? undefined : sampleDriver(follow.x, frame, fps);\n\t\tconst y =\n\t\t\tfollow.y === undefined ? undefined : sampleDriver(follow.y, frame, fps);\n\t\tconst rotation =\n\t\t\tfollow.rotation === undefined\n\t\t\t\t? f.rotation\n\t\t\t\t: sampleDriver(follow.rotation, frame, fps);\n\t\tconst start = this.initialLayerXY();\n\t\tconst center = layerToCenter(x ?? start[0], y ?? start[1], rotation, f);\n\t\tconst ppm = this.world.pixelsPerMeter;\n\t\treturn {\n\t\t\tposition: [center[0] / ppm, center[1] / ppm],\n\t\t\trotation: (rotation * Math.PI) / 180,\n\t\t};\n\t}\n\n\tprivate initialLayerXY(): Vec2 {\n\t\tconst l = this.layer;\n\t\treturn [Number(l?.x ?? 0), Number(l?.y ?? 0)];\n\t}\n\n\t/** @internal */\n\trecord(index: number, previous: number): void {\n\t\tconst ppm = this.world.pixelsPerMeter;\n\t\tconst [mx, my] = this.sim.position();\n\t\tconst cx = mx * ppm;\n\t\tconst cy = my * ppm;\n\t\tconst rec = this.recording;\n\t\tconst rotation = rec.channel(\"rotation\");\n\t\tconst deg = (this.sim.rotation() * 180) / Math.PI;\n\t\trotation[index] =\n\t\t\tprevious < 0\n\t\t\t\t? unwrapDegrees(this.frame.rotation, deg)\n\t\t\t\t: unwrapDegrees(rotation[previous], deg);\n\t\tconst [x, y] = centerToLayer(cx, cy, rotation[index], this.frame);\n\t\trec.channel(\"x\")[index] = x;\n\t\trec.channel(\"y\")[index] = y;\n\t\trec.channel(\"centerX\")[index] = cx;\n\t\trec.channel(\"centerY\")[index] = cy;\n\t\tconst [vx, vy] = this.sim.velocity();\n\t\trec.channel(\"vx\")[index] = vx * ppm;\n\t\trec.channel(\"vy\")[index] = vy * ppm;\n\t\trec.channel(\"speed\")[index] = Math.hypot(vx, vy) * ppm;\n\t\trec.channel(\"angularVelocity\")[index] =\n\t\t\t(this.sim.angularVelocity() * 180) / Math.PI;\n\t\trec.channel(\"sleeping\")[index] = this.sim.sleeping() ? 1 : 0;\n\t}\n\n\t/** @internal */\n\tboundChannels(): Array<[AnimatableProp, string]> {\n\t\tconst out: Array<[AnimatableProp, string]> = [\n\t\t\t[\"x\", \"x\"],\n\t\t\t[\"y\", \"y\"],\n\t\t];\n\t\tif (!this.options.lockRotation) out.push([\"rotation\", \"rotation\"]);\n\t\treturn out;\n\t}\n\n\t/** @internal World-space point (px) → this body's local frame (meters), at the start pose. */\n\tlocalAnchor(point: Vec2 | undefined): Vec2 {\n\t\tif (!point) return [0, 0];\n\t\tconst ppm = this.world.pixelsPerMeter;\n\t\tconst [px, py] = this.sim.position();\n\t\tconst a = -this.sim.rotation();\n\t\tconst dx = point[0] / ppm - px;\n\t\tconst dy = point[1] / ppm - py;\n\t\treturn [\n\t\t\tdx * Math.cos(a) - dy * Math.sin(a),\n\t\t\tdx * Math.sin(a) + dy * Math.cos(a),\n\t\t];\n\t}\n\n\t/** @internal Start-pose center in px. */\n\tcenter(): Vec2 {\n\t\tconst ppm = this.world.pixelsPerMeter;\n\t\tconst [x, y] = this.sim.position();\n\t\treturn [x * ppm, y * ppm];\n\t}\n}\n\n/** What a {@link PhysicsWorld2D.field} sees for one body. */\nexport interface FieldSample2D {\n\t/** Body center, px. */\n\tx: number;\n\ty: number;\n\t/** px/s. */\n\tvx: number;\n\tvy: number;\n\t/** Composition frame. */\n\tframe: number;\n\tbody: PhysicsBody2D;\n}\n\nexport interface PhysicsSpringOptions {\n\t/** Rest length, px (default: the distance at the start). */\n\tlength?: number;\n\t/** Oscillations per second (default 2). Higher is stiffer. */\n\tfrequency?: number;\n\t/** 0 bounces forever, 1 settles without overshoot (default 0.2). */\n\tdampingRatio?: number;\n\t/** Attachment point on body A, world px at the start (default its center). */\n\tanchorA?: [number, number];\n\t/** Attachment point on body B (or the world point), world px. */\n\tanchorB?: [number, number];\n}\n\nexport interface PhysicsRopeOptions {\n\t/** Maximum length, px (default: the distance at the start). */\n\tlength?: number;\n\tanchorA?: [number, number];\n\tanchorB?: [number, number];\n}\n\nexport interface PhysicsGroundOptions {\n\t/** Top edge of the ground, px. */\n\ty: number;\n\tfriction?: number;\n\trestitution?: number;\n}\n\nexport interface PhysicsWallsOptions {\n\tx?: number;\n\ty?: number;\n\twidth: number;\n\theight: number;\n\t/** Close the top too (default false: things can fall in). */\n\tceiling?: boolean;\n\t/** Wall thickness outside the box, px (default 400). */\n\tthickness?: number;\n\tfriction?: number;\n\trestitution?: number;\n}\n\n/**\n * A deterministic 2D rigid-body world (Rapier) in layer pixels. Build it,\n * add bodies from layers, then `simulate()`: each body's layer is bound to\n * its simulated `x` / `y` / `rotation`, and every body exposes signals\n * (`impact`, `speed`, …) for driving anything else. The simulation runs\n * once while the composition is built, so frames render in any order and\n * identically on every machine.\n */\nexport class PhysicsWorld2D extends WorldCore<Vec2, number, PhysicsBody2D> {\n\t/** @internal */\n\tconstructor(backend: PhysicsBackend, options: World2DOptions) {\n\t\tconst ppm = options.pixelsPerMeter ?? 100;\n\t\tconst g = options.gravity ?? 2400;\n\t\tconst gravity: Vec2 =\n\t\t\ttypeof g === \"number\" ? [0, g / ppm] : [g[0] / ppm, g[1] / ppm];\n\t\tconst sim = backend.createWorld2D(gravity);\n\t\tsuper(sim as never, gravity, options);\n\t}\n\n\t/**\n\t * Adds a body for a layer (absolutely positioned: `x`, `y`, and a size)\n\t * or for a plain rectangle. The layer's current pose is the start pose.\n\t */\n\tbody(\n\t\ttarget: LayoutNode | PhysicsRect,\n\t\toptions: Body2DOptions = {},\n\t): PhysicsBody2D {\n\t\tthis.assertOpen();\n\t\tconst isLayer = typeof (target as unknown as LayerLike).kind === \"string\";\n\t\tconst layer = isLayer ? (target as unknown as LayerLike) : undefined;\n\t\tconst geom = layerGeometry(target as unknown as LayerLike, options);\n\t\tconst ppm = this.pixelsPerMeter;\n\t\tconst type = options.type ?? \"dynamic\";\n\t\tconst [cx, cy] = layerToCenter(geom.x, geom.y, geom.rotation, geom);\n\t\tconst v = options.velocity ?? [0, 0];\n\t\tconst spec: BodySpec2D = {\n\t\t\ttype,\n\t\t\tposition: [cx / ppm, cy / ppm],\n\t\t\tangle: (geom.rotation * Math.PI) / 180,\n\t\t\tvelocity: [v[0] / ppm, v[1] / ppm],\n\t\t\tangularVelocity: ((options.angularVelocity ?? 0) * Math.PI) / 180,\n\t\t\tlinearDamping: options.linearDamping ?? 0,\n\t\t\tangularDamping: options.angularDamping ?? 0,\n\t\t\tgravityScale: options.gravityScale ?? 1,\n\t\t\tlockRotation: options.lockRotation ?? false,\n\t\t\tccd: options.ccd ?? false,\n\t\t\tenabled: true,\n\t\t\tsensor: options.sensor ?? false,\n\t\t\tdensity: options.density ?? 1,\n\t\t\tfriction: options.friction ?? 0.6,\n\t\t\trestitution: options.restitution ?? 0.3,\n\t\t\tshape: scaleShape(geom.shape, 1 / ppm),\n\t\t};\n\t\tconst simBody = (this.sim as unknown as SimWorld2D).addBody(spec);\n\t\tconst body = new PhysicsBody2D(\n\t\t\tthis,\n\t\t\tsimBody,\n\t\t\ttype,\n\t\t\tlayer,\n\t\t\tgeom,\n\t\t\toptions,\n\t\t\tthis.newRecording(),\n\t\t);\n\t\treturn this.addBody(body);\n\t}\n\n\t/** A fixed, very wide floor whose top edge sits at `y`. */\n\tground(options: PhysicsGroundOptions): PhysicsBody2D {\n\t\tconst t = 2000;\n\t\tconst w = 1e6;\n\t\treturn this.body(\n\t\t\t{ x: -w / 2, y: options.y, width: w, height: t },\n\t\t\t{\n\t\t\t\ttype: \"fixed\",\n\t\t\t\tfriction: options.friction,\n\t\t\t\trestitution: options.restitution ?? 0.2,\n\t\t\t},\n\t\t);\n\t}\n\n\t/** Fixed floor, left and right walls (and optionally a ceiling) around a box, e.g. the canvas. */\n\twalls(options: PhysicsWallsOptions): {\n\t\tfloor: PhysicsBody2D;\n\t\tleft: PhysicsBody2D;\n\t\tright: PhysicsBody2D;\n\t\tceiling?: PhysicsBody2D;\n\t} {\n\t\tconst { width: W, height: H } = options;\n\t\tconst x = options.x ?? 0;\n\t\tconst y = options.y ?? 0;\n\t\tconst t = options.thickness ?? 400;\n\t\tconst mat = {\n\t\t\ttype: \"fixed\" as const,\n\t\t\tfriction: options.friction,\n\t\t\trestitution: options.restitution ?? 0.2,\n\t\t};\n\t\tconst tall = H * 4 + t;\n\t\tconst result = {\n\t\t\tfloor: this.body(\n\t\t\t\t{ x: x - t, y: y + H, width: W + 2 * t, height: t },\n\t\t\t\tmat,\n\t\t\t),\n\t\t\tleft: this.body(\n\t\t\t\t{ x: x - t, y: y + H - tall, width: t, height: tall },\n\t\t\t\tmat,\n\t\t\t),\n\t\t\tright: this.body(\n\t\t\t\t{ x: x + W, y: y + H - tall, width: t, height: tall },\n\t\t\t\tmat,\n\t\t\t),\n\t\t\tceiling: undefined as PhysicsBody2D | undefined,\n\t\t};\n\t\tif (options.ceiling) {\n\t\t\tresult.ceiling = this.body(\n\t\t\t\t{ x: x - t, y: y - t, width: W + 2 * t, height: t },\n\t\t\t\tmat,\n\t\t\t);\n\t\t}\n\t\treturn result;\n\t}\n\n\t/** Pins a body to the world at a point (default its center); it can still swing around it. */\n\tpin(body: PhysicsBody2D, at?: [number, number]): this {\n\t\tconst point = at ?? body.center();\n\t\tconst anchor = this.anchorBody(point);\n\t\tthis.joint(body, anchor, {\n\t\t\ttype: \"revolute\",\n\t\t\tanchorA: body.localAnchor(point),\n\t\t\tanchorB: [0, 0],\n\t\t});\n\t\treturn this;\n\t}\n\n\t/** Joins two bodies at a world point so they swing around it (a hinge). */\n\thinge(a: PhysicsBody2D, b: PhysicsBody2D, at: [number, number]): this {\n\t\tthis.joint(a, b, {\n\t\t\ttype: \"revolute\",\n\t\t\tanchorA: a.localAnchor(at),\n\t\t\tanchorB: b.localAnchor(at),\n\t\t});\n\t\treturn this;\n\t}\n\n\t/** Glues two bodies together rigidly. */\n\tweld(a: PhysicsBody2D, b: PhysicsBody2D): this {\n\t\tconst at = a.center();\n\t\tthis.joint(a, b, {\n\t\t\ttype: \"fixed\",\n\t\t\tanchorA: [0, 0],\n\t\t\tanchorB: b.localAnchor(at),\n\t\t});\n\t\treturn this;\n\t}\n\n\t/** A damped spring between two bodies, or from a body to a world point. */\n\tspring(\n\t\ta: PhysicsBody2D,\n\t\tb: PhysicsBody2D | [number, number],\n\t\toptions: PhysicsSpringOptions = {},\n\t): this {\n\t\tconst { other, pa, pb } = this.endpoints(\n\t\t\ta,\n\t\t\tb,\n\t\t\toptions.anchorA,\n\t\t\toptions.anchorB,\n\t\t);\n\t\tconst ppm = this.pixelsPerMeter;\n\t\tconst length =\n\t\t\t(options.length ?? Math.hypot(pb[0] - pa[0], pb[1] - pa[1])) / ppm;\n\t\tconst mass = effectiveMass(a, other);\n\t\tconst w = 2 * Math.PI * (options.frequency ?? 2);\n\t\tthis.joint(a, other, {\n\t\t\ttype: \"spring\",\n\t\t\tanchorA: a.localAnchor(pa),\n\t\t\tanchorB: other.localAnchor(pb),\n\t\t\trestLength: length,\n\t\t\tstiffness: mass * w * w,\n\t\t\tdamping: 2 * (options.dampingRatio ?? 0.2) * mass * w,\n\t\t});\n\t\treturn this;\n\t}\n\n\t/** A rope: never longer than `length`, slack when closer. */\n\trope(\n\t\ta: PhysicsBody2D,\n\t\tb: PhysicsBody2D | [number, number],\n\t\toptions: PhysicsRopeOptions = {},\n\t): this {\n\t\tconst { other, pa, pb } = this.endpoints(\n\t\t\ta,\n\t\t\tb,\n\t\t\toptions.anchorA,\n\t\t\toptions.anchorB,\n\t\t);\n\t\tconst length = options.length ?? Math.hypot(pb[0] - pa[0], pb[1] - pa[1]);\n\t\tthis.joint(a, other, {\n\t\t\ttype: \"rope\",\n\t\t\tanchorA: a.localAnchor(pa),\n\t\t\tanchorB: other.localAnchor(pb),\n\t\t\tlength: length / this.pixelsPerMeter,\n\t\t});\n\t\treturn this;\n\t}\n\n\t/** A steady push, px/s² (mass-independent): wind, magnets, audio. Drivers are read every frame. */\n\tforce(\n\t\tbody: PhysicsBody2D,\n\t\taccel: { x?: PhysicsDriver; y?: PhysicsDriver },\n\t): this {\n\t\tconst ppm = this.pixelsPerMeter;\n\t\tthis.addForce(body, (frame) => [\n\t\t\taccel.x === undefined ? 0 : sampleDriver(accel.x, frame, this.fps) / ppm,\n\t\t\taccel.y === undefined ? 0 : sampleDriver(accel.y, frame, this.fps) / ppm,\n\t\t]);\n\t\treturn this;\n\t}\n\n\t/**\n\t * A force field: called for every awake dynamic body (or just `bodies`)\n\t * each solver step with its center and velocity in px, px/s; returns an\n\t * acceleration `[ax, ay]` px/s² (or nothing). Wind, vortices, magnets,\n\t * flow fields, a dancer's silhouette pushing particles.\n\t */\n\tfield(\n\t\taccel: (sample: FieldSample2D) => [number, number] | null | undefined,\n\t\toptions: { bodies?: readonly PhysicsBody2D[] } = {},\n\t): this {\n\t\tconst ppm = this.pixelsPerMeter;\n\t\tthis.addField((body, frame) => {\n\t\t\tconst [x, y] = body.sim.position();\n\t\t\tconst [vx, vy] = body.sim.velocity();\n\t\t\tconst a = accel({\n\t\t\t\tx: x * ppm,\n\t\t\t\ty: y * ppm,\n\t\t\t\tvx: vx * ppm,\n\t\t\t\tvy: vy * ppm,\n\t\t\t\tframe,\n\t\t\t\tbody,\n\t\t\t});\n\t\t\treturn a ? [a[0] / ppm, a[1] / ppm] : null;\n\t\t}, options.bodies);\n\t\treturn this;\n\t}\n\n\t/** An instant kick at a simulation frame: adds `[vx, vy]` px/s to the body's velocity. */\n\timpulse(\n\t\tbody: PhysicsBody2D,\n\t\tframe: number,\n\t\tvelocity: [number, number],\n\t): this {\n\t\tconst ppm = this.pixelsPerMeter;\n\t\tthis.addImpulse(body, frame, [velocity[0] / ppm, velocity[1] / ppm]);\n\t\treturn this;\n\t}\n\n\tprotected lerpRotation(a: number, b: number, t: number): number {\n\t\treturn a + (b - a) * t;\n\t}\n\n\tprivate joint(\n\t\ta: PhysicsBody2D,\n\t\tb: PhysicsBody2D,\n\t\tspec: Parameters<SimWorld2D[\"addJoint\"]>[2],\n\t): void {\n\t\tthis.assertOpen();\n\t\t(this.sim as unknown as SimWorld2D).addJoint(a.sim, b.sim, spec);\n\t}\n\n\tprivate anchorBody(point: [number, number]): PhysicsBody2D {\n\t\treturn this.body(\n\t\t\t{ x: point[0] - 0.5, y: point[1] - 0.5, width: 1, height: 1 },\n\t\t\t{ type: \"fixed\", output: \"none\", sensor: true },\n\t\t);\n\t}\n\n\tprivate endpoints(\n\t\ta: PhysicsBody2D,\n\t\tb: PhysicsBody2D | [number, number],\n\t\tanchorA?: [number, number],\n\t\tanchorB?: [number, number],\n\t): { other: PhysicsBody2D; pa: Vec2; pb: Vec2 } {\n\t\tconst pa = anchorA ?? a.center();\n\t\tif (Array.isArray(b)) {\n\t\t\tconst pb = anchorB ?? b;\n\t\t\treturn { other: this.anchorBody(pb), pa, pb };\n\t\t}\n\t\treturn { other: b, pa, pb: anchorB ?? b.center() };\n\t}\n}\n\nfunction effectiveMass(a: PhysicsBody2D, b: PhysicsBody2D): number {\n\tconst ma = a.type === \"dynamic\" ? a.sim.mass() : 0;\n\tconst mb = b.type === \"dynamic\" ? b.sim.mass() : 0;\n\tif (ma > 0 && mb > 0) return (ma * mb) / (ma + mb);\n\treturn Math.max(ma, mb, 1e-3);\n}\n\ninterface LayerGeometry {\n\tx: number;\n\ty: number;\n\twidth: number;\n\theight: number;\n\tscale: number;\n\tanchorX: number;\n\tanchorY: number;\n\trotation: number;\n\t/** Collider in px, around the box center, already scaled. */\n\tshape: Shape2D;\n}\n\nfunction num(v: unknown, fallback: number): number {\n\treturn typeof v === \"number\" && Number.isFinite(v) ? v : fallback;\n}\n\nfunction layerGeometry(\n\tlayer: LayerLike,\n\toptions: Body2DOptions,\n): LayerGeometry {\n\tconst id = typeof layer.id === \"string\" ? ` \"${layer.id}\"` : \"\";\n\tif (typeof layer.x !== \"number\" || typeof layer.y !== \"number\") {\n\t\tthrow new Error(\n\t\t\t`Physics: layer${id} needs numeric \\`x\\` and \\`y\\` (absolute position) to become a body.`,\n\t\t);\n\t}\n\tlet width =\n\t\toptions.size?.[0] ??\n\t\t(typeof layer.width === \"number\" ? layer.width : undefined);\n\tlet height =\n\t\toptions.size?.[1] ??\n\t\t(typeof layer.height === \"number\" ? layer.height : undefined);\n\tif ((width === undefined || height === undefined) && layer.kind === \"text\") {\n\t\tconst m = FontManager.measure(String(layer.text ?? \"\"), {\n\t\t\tfontFamily: String(layer.fontFamily ?? \"Inter\"),\n\t\t\tfontSize: num(layer.fontSize, 48),\n\t\t\tfontWeight: layer.fontWeight as never,\n\t\t\tletterSpacing: num(layer.letterSpacing, 0),\n\t\t\tlineHeight:\n\t\t\t\ttypeof layer.lineHeight === \"number\" ? layer.lineHeight : undefined,\n\t\t});\n\t\twidth ??= m.width;\n\t\theight ??= m.height;\n\t}\n\tif (\n\t\twidth === undefined ||\n\t\theight === undefined ||\n\t\twidth <= 0 ||\n\t\theight <= 0\n\t) {\n\t\tthrow new Error(\n\t\t\t`Physics: layer${id} needs a numeric \\`width\\` and \\`height\\` (or the \\`size\\` option) to become a body.`,\n\t\t);\n\t}\n\tconst scale = num(layer.scale, 1);\n\tconst geom = {\n\t\tx: layer.x,\n\t\ty: layer.y,\n\t\twidth,\n\t\theight,\n\t\tscale,\n\t\tanchorX: num(layer.anchorX, 0.5),\n\t\tanchorY: num(layer.anchorY, 0.5),\n\t\trotation: num(layer.rotation, 0),\n\t};\n\treturn {\n\t\t...geom,\n\t\tshape: scaleShape(\n\t\t\tcolliderShape(layer, width, height, options.shape ?? \"auto\"),\n\t\t\tscale,\n\t\t),\n\t};\n}\n\nfunction colliderShape(\n\tlayer: LayerLike,\n\tw: number,\n\th: number,\n\tmode: NonNullable<Body2DOptions[\"shape\"]>,\n): Shape2D {\n\tconst isShape = layer.kind === \"shape\";\n\tconst shapeType = isShape ? String(layer.shapeType ?? \"rect\") : \"rect\";\n\tconst radius = num(layer.borderRadius, num(layer.cornerRadius, 0));\n\tconst box: Shape2D = { kind: \"box\", hx: w / 2, hy: h / 2, radius };\n\tif (mode === \"box\") return box;\n\tif (mode === \"circle\" || (mode === \"auto\" && shapeType === \"circle\")) {\n\t\treturn { kind: \"ball\", radius: Math.min(w, h) / 2 };\n\t}\n\tif (mode === \"auto\" && shapeType === \"rect\") return box;\n\tif (mode === \"hull\" || mode === \"auto\") {\n\t\tconst points = outlinePoints(layer, shapeType, w, h);\n\t\treturn points.length >= 6 ? { kind: \"hull\", points } : box;\n\t}\n\treturn box;\n}\n\n/** The shape's outline as flat points around the box center, px. */\nfunction outlinePoints(\n\tlayer: LayerLike,\n\tshapeType: string,\n\tw: number,\n\th: number,\n): number[] {\n\tconst d =\n\t\tshapeType === \"path\"\n\t\t\t? String(layer.d ?? \"\")\n\t\t\t: buildShapeSvgPath({\n\t\t\t\t\tshapeType: shapeType as ShapeGeometryConfig[\"shapeType\"],\n\t\t\t\t\twidth: w,\n\t\t\t\t\theight: h,\n\t\t\t\t\tcornerRadius: num(layer.cornerRadius, num(layer.borderRadius, 0)),\n\t\t\t\t\tpolygonSides: layer.polygonSides as number | undefined,\n\t\t\t\t\tstarPoints: layer.starPoints as number | undefined,\n\t\t\t\t\tstarInnerRadiusRatio: layer.starInnerRadiusRatio as\n\t\t\t\t\t\t| number\n\t\t\t\t\t\t| undefined,\n\t\t\t\t\tarrowHeadWidth: layer.arrowHeadWidth as number | undefined,\n\t\t\t\t\tarrowHeadLength: layer.arrowHeadLength as number | undefined,\n\t\t\t\t\tarrowShaftWidth: layer.arrowShaftWidth as number | undefined,\n\t\t\t\t});\n\tconst out: number[] = [];\n\tfor (const seg of parseSvgPathToSegments(d)) {\n\t\tout.push(\n\t\t\tseg.p0.x - w / 2,\n\t\t\tseg.p0.y - h / 2,\n\t\t\tseg.p1.x - w / 2,\n\t\t\tseg.p1.y - h / 2,\n\t\t);\n\t}\n\treturn out;\n}\n\nfunction scaleShape(shape: Shape2D, s: number): Shape2D {\n\tswitch (shape.kind) {\n\t\tcase \"ball\":\n\t\t\treturn { kind: \"ball\", radius: shape.radius * s };\n\t\tcase \"box\":\n\t\t\treturn {\n\t\t\t\tkind: \"box\",\n\t\t\t\thx: shape.hx * s,\n\t\t\t\thy: shape.hy * s,\n\t\t\t\tradius: (shape.radius ?? 0) * s,\n\t\t\t};\n\t\tcase \"hull\":\n\t\t\treturn { kind: \"hull\", points: shape.points.map((v) => v * s) };\n\t}\n}\n\ninterface PivotFrame {\n\twidth: number;\n\theight: number;\n\tscale: number;\n\tanchorX: number;\n\tanchorY: number;\n}\n\n/**\n * Layers rotate and scale around their pivot (`anchorX/Y` of the unscaled\n * box); bodies rotate around their center. These convert between the two.\n */\nfunction pivotOffset(rotationDeg: number, f: PivotFrame): Vec2 {\n\tconst a = (rotationDeg * Math.PI) / 180;\n\tconst dx = (0.5 - f.anchorX) * f.width * f.scale;\n\tconst dy = (0.5 - f.anchorY) * f.height * f.scale;\n\treturn [\n\t\tdx * Math.cos(a) - dy * Math.sin(a),\n\t\tdx * Math.sin(a) + dy * Math.cos(a),\n\t];\n}\n\nfunction layerToCenter(\n\tx: number,\n\ty: number,\n\trotationDeg: number,\n\tf: PivotFrame,\n): Vec2 {\n\tconst [ox, oy] = pivotOffset(rotationDeg, f);\n\treturn [x + f.anchorX * f.width + ox, y + f.anchorY * f.height + oy];\n}\n\nfunction centerToLayer(\n\tcx: number,\n\tcy: number,\n\trotationDeg: number,\n\tf: PivotFrame,\n): Vec2 {\n\tconst [ox, oy] = pivotOffset(rotationDeg, f);\n\treturn [cx - ox - f.anchorX * f.width, cy - oy - f.anchorY * f.height];\n}\n","import type {\n\tAnimatableProp,\n\tLayoutNode,\n} from \"@framefields/compositions/program\";\nimport type { FrameSignal } from \"@framefields/core\";\nimport type {\n\tBodySpec3D,\n\tPhysicsBackend,\n\tQuat,\n\tShape3D,\n\tSimBody3D,\n\tSimWorld3D,\n\tVec3,\n} from \"./backend.js\";\nimport {\n\ttype BodyCommonOptions,\n\ttype CoreBody,\n\ttype PhysicsCollision,\n\ttype PhysicsDriver,\n\ttype PhysicsWorldOptions,\n\ttype Recording,\n\tsampleDriver,\n\tunwrapDegrees,\n\tWorldCore,\n} from \"./core.js\";\n\nexport interface World3DOptions extends PhysicsWorldOptions {\n\t/** px/s², y down. A number pulls straight down. Default 2400. */\n\tgravity?: number | [number, number, number];\n}\n\n/** A plain box for bodies with no layer (invisible obstacles). Centered on x/y/z like Layer3D. */\nexport interface PhysicsBox3D {\n\tx: number;\n\ty: number;\n\tz: number;\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\trotateX?: number;\n\trotateY?: number;\n\trotateZ?: number;\n}\n\nexport interface Body3DOptions extends Omit<BodyCommonOptions, \"lockRotation\"> {\n\t/**\n\t * Never rotates (`true`), or only around some axes: `{ x: true, y: true }`\n\t * keeps a card facing the camera while it still spins in the picture plane.\n\t */\n\tlockRotation?: boolean | { x?: boolean; y?: boolean; z?: boolean };\n\t/**\n\t * Collider: `\"auto\"` (default) reads the Layer3D primitive (box, sphere,\n\t * cylinder) and falls back to the mesh's convex hull for models and\n\t * tapered or uneven shapes. Force `\"box\"`, `\"sphere\"`, `\"cylinder\"` or `\"hull\"`.\n\t */\n\tshape?: \"auto\" | \"box\" | \"sphere\" | \"cylinder\" | \"hull\";\n\t/** Collider size override `[width, height, depth]`, px (before the layer's scale). */\n\tsize?: [number, number, number];\n\t/** px/s. */\n\tvelocity?: [number, number, number];\n\t/** Degrees per second around x, y, z. */\n\tangularVelocity?: [number, number, number];\n\t/** Kinematic bodies: the layer's `x` / `y` / `z` and `rotateX/Y/Z` each frame. */\n\tfollow?: {\n\t\tx?: PhysicsDriver;\n\t\ty?: PhysicsDriver;\n\t\tz?: PhysicsDriver;\n\t\trotateX?: PhysicsDriver;\n\t\trotateY?: PhysicsDriver;\n\t\trotateZ?: PhysicsDriver;\n\t};\n}\n\ntype LayerLike = Record<string, unknown> & { kind?: string };\n\nconst DEG = Math.PI / 180;\n\n/** Quaternion of the renderer's Euler order: R = Rz · Ry · Rx (degrees). */\nexport function quatFromEuler(rx: number, ry: number, rz: number): Quat {\n\tconst half = (d: number) => (d * DEG) / 2;\n\tconst qx: Quat = [Math.sin(half(rx)), 0, 0, Math.cos(half(rx))];\n\tconst qy: Quat = [0, Math.sin(half(ry)), 0, Math.cos(half(ry))];\n\tconst qz: Quat = [0, 0, Math.sin(half(rz)), Math.cos(half(rz))];\n\treturn quatMul(quatMul(qz, qy), qx);\n}\n\nfunction quatMul(a: Quat, b: Quat): Quat {\n\tconst [ax, ay, az, aw] = a;\n\tconst [bx, by, bz, bw] = b;\n\treturn [\n\t\taw * bx + ax * bw + ay * bz - az * by,\n\t\taw * by - ax * bz + ay * bw + az * bx,\n\t\taw * bz + ax * by - ay * bx + az * bw,\n\t\taw * bw - ax * bx - ay * by - az * bz,\n\t];\n}\n\n/**\n * Euler angles (degrees, R = Rz · Ry · Rx) for a quaternion, choosing of the\n * two equivalent solutions the one closest to `previous` and unwrapping each\n * angle, so rotations stay continuous frame to frame.\n */\nexport function eulerFromQuat(q: Quat, previous?: Vec3): Vec3 {\n\tconst [x, y, z, w] = q;\n\tconst r00 = 1 - 2 * (y * y + z * z);\n\tconst r10 = 2 * (x * y + w * z);\n\tconst r20 = 2 * (x * z - w * y);\n\tconst r21 = 2 * (y * z + w * x);\n\tconst r22 = 1 - 2 * (x * x + y * y);\n\tconst r01 = 2 * (x * y - w * z);\n\tconst r11 = 1 - 2 * (x * x + z * z);\n\tconst sy = Math.max(-1, Math.min(1, -r20));\n\tlet a: Vec3;\n\tif (Math.abs(sy) > 0.999999) {\n\t\t// Gimbal lock: only x - z (or x + z) is defined; keep x where it was.\n\t\tconst ay = Math.asin(sy);\n\t\tconst keepX = previous ? previous[0] * DEG : 0;\n\t\tconst az = Math.atan2(-r01, r11) + (sy > 0 ? keepX : -keepX);\n\t\ta = [keepX, ay, az];\n\t} else {\n\t\ta = [Math.atan2(r21, r22), Math.asin(sy), Math.atan2(r10, r00)];\n\t}\n\tconst first: Vec3 = [a[0] / DEG, a[1] / DEG, a[2] / DEG];\n\tif (!previous) return first;\n\tconst second: Vec3 = [first[0] + 180, 180 - first[1], first[2] + 180];\n\tconst unwrap = (c: Vec3): Vec3 => [\n\t\tunwrapDegrees(previous[0], c[0]),\n\t\tunwrapDegrees(previous[1], c[1]),\n\t\tunwrapDegrees(previous[2], c[2]),\n\t];\n\tconst p = unwrap(first);\n\tconst s = unwrap(second);\n\tconst dist = (c: Vec3) =>\n\t\tMath.abs(c[0] - previous[0]) +\n\t\tMath.abs(c[1] - previous[1]) +\n\t\tMath.abs(c[2] - previous[2]);\n\treturn dist(p) <= dist(s) ? p : s;\n}\n\n/**\n * A simulated 3D body. Like {@link PhysicsBody2D}, its signals hold one\n * value per composition frame and reading one runs the simulation.\n */\nexport class PhysicsBody3D implements CoreBody<Vec3, Quat> {\n\treadonly collisions: PhysicsCollision<PhysicsBody3D>[] = [];\n\t/** @internal */ readonly recording: Recording;\n\t/** @internal */ readonly sim: SimBody3D;\n\n\t/** @internal */\n\tconstructor(\n\t\t/** @internal */ readonly world: PhysicsWorld3D,\n\t\tsim: SimBody3D,\n\t\treadonly type: \"dynamic\" | \"fixed\" | \"kinematic\",\n\t\treadonly layer: LayerLike | undefined,\n\t\tprivate readonly start: { position: Vec3; rotation: Vec3 },\n\t\tprivate readonly options: Body3DOptions,\n\t\trecording: Recording,\n\t) {\n\t\tthis.sim = sim;\n\t\tthis.recording = recording;\n\t}\n\n\tget startFrame(): number {\n\t\treturn Math.max(0, Math.round(this.options.startFrame ?? 0));\n\t}\n\tget gravityScale(): number {\n\t\treturn this.options.gravityScale ?? 1;\n\t}\n\tget output(): Body3DOptions[\"output\"] {\n\t\treturn this.options.output;\n\t}\n\n\t/** Center, px (what Layer3D's `x` / `y` / `z` mean). */\n\tget x(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"x\");\n\t}\n\tget y(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"y\");\n\t}\n\tget z(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"z\");\n\t}\n\t/** Degrees, continuous. */\n\tget rotateX(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"rotateX\");\n\t}\n\tget rotateY(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"rotateY\");\n\t}\n\tget rotateZ(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"rotateZ\");\n\t}\n\t/** px/s. */\n\tget vx(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"vx\");\n\t}\n\tget vy(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"vy\");\n\t}\n\tget vz(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"vz\");\n\t}\n\tget speed(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"speed\");\n\t}\n\t/** Hit envelope, as on 2D bodies. */\n\tget impact(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"impact\");\n\t}\n\t/** 1 while the body is at rest, else 0. */\n\tget sleeping(): FrameSignal<number> {\n\t\treturn this.recording.signal(\"sleeping\");\n\t}\n\n\t/** @internal */\n\tkinematicTarget(\n\t\tframe: number,\n\t): { position: Vec3; rotation: Quat } | undefined {\n\t\tconst follow = this.options.follow;\n\t\tif (this.type !== \"kinematic\" || !follow) return undefined;\n\t\tconst fps = this.world.fps;\n\t\tconst read = (d: PhysicsDriver | undefined, fallback: number) =>\n\t\t\td === undefined ? fallback : sampleDriver(d, frame, fps);\n\t\tconst p = this.start.position;\n\t\tconst r = this.start.rotation;\n\t\tconst ppm = this.world.pixelsPerMeter;\n\t\treturn {\n\t\t\tposition: [\n\t\t\t\tread(follow.x, p[0]) / ppm,\n\t\t\t\tread(follow.y, p[1]) / ppm,\n\t\t\t\tread(follow.z, p[2]) / ppm,\n\t\t\t],\n\t\t\trotation: quatFromEuler(\n\t\t\t\tread(follow.rotateX, r[0]),\n\t\t\t\tread(follow.rotateY, r[1]),\n\t\t\t\tread(follow.rotateZ, r[2]),\n\t\t\t),\n\t\t};\n\t}\n\n\t/** @internal */\n\trecord(index: number, previous: number): void {\n\t\tconst ppm = this.world.pixelsPerMeter;\n\t\tconst rec = this.recording;\n\t\tconst [x, y, z] = this.sim.position();\n\t\trec.channel(\"x\")[index] = x * ppm;\n\t\trec.channel(\"y\")[index] = y * ppm;\n\t\trec.channel(\"z\")[index] = z * ppm;\n\t\tconst rx = rec.channel(\"rotateX\");\n\t\tconst ry = rec.channel(\"rotateY\");\n\t\tconst rz = rec.channel(\"rotateZ\");\n\t\tconst prev: Vec3 =\n\t\t\tprevious < 0\n\t\t\t\t? this.start.rotation\n\t\t\t\t: [rx[previous], ry[previous], rz[previous]];\n\t\tconst e = eulerFromQuat(this.sim.rotation(), prev);\n\t\trx[index] = e[0];\n\t\try[index] = e[1];\n\t\trz[index] = e[2];\n\t\tconst [vx, vy, vz] = this.sim.velocity();\n\t\trec.channel(\"vx\")[index] = vx * ppm;\n\t\trec.channel(\"vy\")[index] = vy * ppm;\n\t\trec.channel(\"vz\")[index] = vz * ppm;\n\t\trec.channel(\"speed\")[index] = Math.hypot(vx, vy, vz) * ppm;\n\t\trec.channel(\"sleeping\")[index] = this.sim.sleeping() ? 1 : 0;\n\t}\n\n\t/** @internal */\n\tboundChannels(): Array<[AnimatableProp, string]> {\n\t\tconst out: Array<[AnimatableProp, string]> = [\n\t\t\t[\"x\", \"x\"],\n\t\t\t[\"y\", \"y\"],\n\t\t\t[\"z\", \"z\"],\n\t\t];\n\t\tif (this.options.lockRotation !== true) {\n\t\t\tout.push(\n\t\t\t\t[\"rotateX\", \"rotateX\"],\n\t\t\t\t[\"rotateY\", \"rotateY\"],\n\t\t\t\t[\"rotateZ\", \"rotateZ\"],\n\t\t\t);\n\t\t}\n\t\treturn out;\n\t}\n\n\t/** @internal World point (px) → local frame (meters) at the start pose. */\n\tlocalAnchor(point: Vec3 | undefined): Vec3 {\n\t\tif (!point) return [0, 0, 0];\n\t\tconst ppm = this.world.pixelsPerMeter;\n\t\tconst p = this.sim.position();\n\t\tconst [qx, qy, qz, qw] = this.sim.rotation();\n\t\tconst v: Vec3 = [\n\t\t\tpoint[0] / ppm - p[0],\n\t\t\tpoint[1] / ppm - p[1],\n\t\t\tpoint[2] / ppm - p[2],\n\t\t];\n\t\treturn rotateByQuat(v, [-qx, -qy, -qz, qw]);\n\t}\n\n\t/** @internal Start-pose center, px. */\n\tcenter(): Vec3 {\n\t\tconst ppm = this.world.pixelsPerMeter;\n\t\tconst [x, y, z] = this.sim.position();\n\t\treturn [x * ppm, y * ppm, z * ppm];\n\t}\n}\n\nfunction rotateByQuat(v: Vec3, q: Quat): Vec3 {\n\tconst r = quatMul(quatMul(q, [v[0], v[1], v[2], 0]), [\n\t\t-q[0],\n\t\t-q[1],\n\t\t-q[2],\n\t\tq[3],\n\t]);\n\treturn [r[0], r[1], r[2]];\n}\n\n/** What a {@link PhysicsWorld3D.field} sees for one body. */\nexport interface FieldSample3D {\n\tx: number;\n\ty: number;\n\tz: number;\n\tvx: number;\n\tvy: number;\n\tvz: number;\n\tframe: number;\n\tbody: PhysicsBody3D;\n}\n\nexport interface PhysicsSpring3DOptions {\n\tlength?: number;\n\tfrequency?: number;\n\tdampingRatio?: number;\n\tanchorA?: Vec3;\n\tanchorB?: Vec3;\n}\n\nexport interface PhysicsRope3DOptions {\n\tlength?: number;\n\tanchorA?: Vec3;\n\tanchorB?: Vec3;\n}\n\n/**\n * A deterministic 3D rigid-body world (Rapier) for Layer3D primitives and\n * models, in the 3D scene's pixels (y down). Same flow as 2D: add bodies,\n * `simulate()`, and each layer's `x/y/z` and `rotateX/Y/Z` follow the\n * simulation; bodies expose signals for everything else.\n */\nexport class PhysicsWorld3D extends WorldCore<Vec3, Quat, PhysicsBody3D> {\n\t/** @internal */\n\tconstructor(backend: PhysicsBackend, options: World3DOptions) {\n\t\tconst ppm = options.pixelsPerMeter ?? 100;\n\t\tconst g = options.gravity ?? 2400;\n\t\tconst gravity: Vec3 =\n\t\t\ttypeof g === \"number\"\n\t\t\t\t? [0, g / ppm, 0]\n\t\t\t\t: [g[0] / ppm, g[1] / ppm, g[2] / ppm];\n\t\tsuper(backend.createWorld3D(gravity) as never, gravity, options);\n\t}\n\n\t/** Adds a body for a Layer3D primitive or model (centered on its `x/y/z`), or a plain box. */\n\tbody(\n\t\ttarget: LayoutNode | PhysicsBox3D,\n\t\toptions: Body3DOptions = {},\n\t): PhysicsBody3D {\n\t\tthis.assertOpen();\n\t\tconst isLayer = typeof (target as unknown as LayerLike).kind === \"string\";\n\t\tconst layer = isLayer ? (target as unknown as LayerLike) : undefined;\n\t\tconst t = target as unknown as LayerLike;\n\t\tconst position: Vec3 = [num(t.x, 0), num(t.y, 0), num(t.z, 0)];\n\t\tconst rotation: Vec3 = [\n\t\t\tnum(t.rotateX, 0),\n\t\t\tnum(t.rotateY, 0),\n\t\t\tnum(t.rotateZ, 0),\n\t\t];\n\t\tconst ppm = this.pixelsPerMeter;\n\t\tconst type = options.type ?? \"dynamic\";\n\t\tconst v = options.velocity ?? [0, 0, 0];\n\t\tconst w = options.angularVelocity ?? [0, 0, 0];\n\t\tconst spec: BodySpec3D = {\n\t\t\ttype,\n\t\t\tposition: [position[0] / ppm, position[1] / ppm, position[2] / ppm],\n\t\t\trotation: quatFromEuler(rotation[0], rotation[1], rotation[2]),\n\t\t\tvelocity: [v[0] / ppm, v[1] / ppm, v[2] / ppm],\n\t\t\tangularVelocity: [w[0] * DEG, w[1] * DEG, w[2] * DEG],\n\t\t\tlinearDamping: options.linearDamping ?? 0,\n\t\t\tangularDamping: options.angularDamping ?? 0,\n\t\t\tgravityScale: options.gravityScale ?? 1,\n\t\t\tlockRotation: options.lockRotation === true,\n\t\t\t...(typeof options.lockRotation === \"object\" && {\n\t\t\t\tenabledRotations: [\n\t\t\t\t\t!options.lockRotation.x,\n\t\t\t\t\t!options.lockRotation.y,\n\t\t\t\t\t!options.lockRotation.z,\n\t\t\t\t] as [boolean, boolean, boolean],\n\t\t\t}),\n\t\t\tccd: options.ccd ?? false,\n\t\t\tenabled: true,\n\t\t\tsensor: options.sensor ?? false,\n\t\t\tdensity: options.density ?? 1,\n\t\t\tfriction: options.friction ?? 0.6,\n\t\t\trestitution: options.restitution ?? 0.3,\n\t\t\tshape: scaleShape(colliderShape3D(t, options), 1 / ppm),\n\t\t};\n\t\tconst simBody = (this.sim as unknown as SimWorld3D).addBody(spec);\n\t\tconst body = new PhysicsBody3D(\n\t\t\tthis,\n\t\t\tsimBody,\n\t\t\ttype,\n\t\t\tlayer,\n\t\t\t{ position, rotation },\n\t\t\toptions,\n\t\t\tthis.newRecording(),\n\t\t);\n\t\treturn this.addBody(body);\n\t}\n\n\t/** A fixed, very large floor whose top face sits at `y`. */\n\tground(options: {\n\t\ty: number;\n\t\tfriction?: number;\n\t\trestitution?: number;\n\t}): PhysicsBody3D {\n\t\tconst t = 2000;\n\t\treturn this.body(\n\t\t\t{ x: 0, y: options.y + t / 2, z: 0, width: 1e6, height: t, depth: 1e6 },\n\t\t\t{\n\t\t\t\ttype: \"fixed\",\n\t\t\t\tfriction: options.friction,\n\t\t\t\trestitution: options.restitution ?? 0.2,\n\t\t\t},\n\t\t);\n\t}\n\n\t/** Fixed floor and four walls around a box centered on `x`/`z`, floor at `y + height/2`. */\n\twalls(options: {\n\t\tx?: number;\n\t\ty?: number;\n\t\tz?: number;\n\t\twidth: number;\n\t\theight: number;\n\t\tdepth: number;\n\t\tthickness?: number;\n\t\tfriction?: number;\n\t\trestitution?: number;\n\t}): PhysicsBody3D[] {\n\t\tconst { width: W, height: H, depth: D } = options;\n\t\tconst [x, y, z] = [options.x ?? 0, options.y ?? 0, options.z ?? 0];\n\t\tconst t = options.thickness ?? 400;\n\t\tconst mat = {\n\t\t\ttype: \"fixed\" as const,\n\t\t\tfriction: options.friction,\n\t\t\trestitution: options.restitution ?? 0.2,\n\t\t};\n\t\tconst tall = H * 4;\n\t\tconst wy = y + H / 2 - tall / 2;\n\t\treturn [\n\t\t\tthis.body(\n\t\t\t\t{\n\t\t\t\t\tx,\n\t\t\t\t\ty: y + H / 2 + t / 2,\n\t\t\t\t\tz,\n\t\t\t\t\twidth: W + 2 * t,\n\t\t\t\t\theight: t,\n\t\t\t\t\tdepth: D + 2 * t,\n\t\t\t\t},\n\t\t\t\tmat,\n\t\t\t),\n\t\t\tthis.body(\n\t\t\t\t{\n\t\t\t\t\tx: x - W / 2 - t / 2,\n\t\t\t\t\ty: wy,\n\t\t\t\t\tz,\n\t\t\t\t\twidth: t,\n\t\t\t\t\theight: tall,\n\t\t\t\t\tdepth: D + 2 * t,\n\t\t\t\t},\n\t\t\t\tmat,\n\t\t\t),\n\t\t\tthis.body(\n\t\t\t\t{\n\t\t\t\t\tx: x + W / 2 + t / 2,\n\t\t\t\t\ty: wy,\n\t\t\t\t\tz,\n\t\t\t\t\twidth: t,\n\t\t\t\t\theight: tall,\n\t\t\t\t\tdepth: D + 2 * t,\n\t\t\t\t},\n\t\t\t\tmat,\n\t\t\t),\n\t\t\tthis.body(\n\t\t\t\t{ x, y: wy, z: z - D / 2 - t / 2, width: W, height: tall, depth: t },\n\t\t\t\tmat,\n\t\t\t),\n\t\t\tthis.body(\n\t\t\t\t{ x, y: wy, z: z + D / 2 + t / 2, width: W, height: tall, depth: t },\n\t\t\t\tmat,\n\t\t\t),\n\t\t];\n\t}\n\n\t/** Pins a body to the world at a point (default its center); it can still turn around it. */\n\tpin(body: PhysicsBody3D, at?: Vec3): this {\n\t\tconst point = at ?? body.center();\n\t\tconst anchor = this.anchorBody(point);\n\t\tthis.joint(body, anchor, {\n\t\t\ttype: \"spherical\",\n\t\t\tanchorA: body.localAnchor(point),\n\t\t\tanchorB: [0, 0, 0],\n\t\t});\n\t\treturn this;\n\t}\n\n\t/** Joins two bodies at a world point, turning only around `axis` (default z, facing the camera). */\n\thinge(\n\t\ta: PhysicsBody3D,\n\t\tb: PhysicsBody3D,\n\t\tat: Vec3,\n\t\taxis: Vec3 = [0, 0, 1],\n\t): this {\n\t\tthis.joint(a, b, {\n\t\t\ttype: \"revolute\",\n\t\t\tanchorA: a.localAnchor(at),\n\t\t\tanchorB: b.localAnchor(at),\n\t\t\taxis,\n\t\t});\n\t\treturn this;\n\t}\n\n\t/** Glues two bodies together rigidly. */\n\tweld(a: PhysicsBody3D, b: PhysicsBody3D): this {\n\t\tthis.joint(a, b, {\n\t\t\ttype: \"fixed\",\n\t\t\tanchorA: [0, 0, 0],\n\t\t\tanchorB: b.localAnchor(a.center()),\n\t\t});\n\t\treturn this;\n\t}\n\n\tspring(\n\t\ta: PhysicsBody3D,\n\t\tb: PhysicsBody3D | Vec3,\n\t\toptions: PhysicsSpring3DOptions = {},\n\t): this {\n\t\tconst { other, pa, pb } = this.endpoints(\n\t\t\ta,\n\t\t\tb,\n\t\t\toptions.anchorA,\n\t\t\toptions.anchorB,\n\t\t);\n\t\tconst ppm = this.pixelsPerMeter;\n\t\tconst length = (options.length ?? dist(pa, pb)) / ppm;\n\t\tconst ma = a.type === \"dynamic\" ? a.sim.mass() : 0;\n\t\tconst mb = other.type === \"dynamic\" ? other.sim.mass() : 0;\n\t\tconst mass =\n\t\t\tma > 0 && mb > 0 ? (ma * mb) / (ma + mb) : Math.max(ma, mb, 1e-3);\n\t\tconst w = 2 * Math.PI * (options.frequency ?? 2);\n\t\tthis.joint(a, other, {\n\t\t\ttype: \"spring\",\n\t\t\tanchorA: a.localAnchor(pa),\n\t\t\tanchorB: other.localAnchor(pb),\n\t\t\trestLength: length,\n\t\t\tstiffness: mass * w * w,\n\t\t\tdamping: 2 * (options.dampingRatio ?? 0.2) * mass * w,\n\t\t});\n\t\treturn this;\n\t}\n\n\trope(\n\t\ta: PhysicsBody3D,\n\t\tb: PhysicsBody3D | Vec3,\n\t\toptions: PhysicsRope3DOptions = {},\n\t): this {\n\t\tconst { other, pa, pb } = this.endpoints(\n\t\t\ta,\n\t\t\tb,\n\t\t\toptions.anchorA,\n\t\t\toptions.anchorB,\n\t\t);\n\t\tthis.joint(a, other, {\n\t\t\ttype: \"rope\",\n\t\t\tanchorA: a.localAnchor(pa),\n\t\t\tanchorB: other.localAnchor(pb),\n\t\t\tlength: (options.length ?? dist(pa, pb)) / this.pixelsPerMeter,\n\t\t});\n\t\treturn this;\n\t}\n\n\t/** A steady push, px/s² (mass-independent). Drivers are read every frame. */\n\tforce(\n\t\tbody: PhysicsBody3D,\n\t\taccel: { x?: PhysicsDriver; y?: PhysicsDriver; z?: PhysicsDriver },\n\t): this {\n\t\tconst ppm = this.pixelsPerMeter;\n\t\tconst read = (d: PhysicsDriver | undefined, frame: number) =>\n\t\t\td === undefined ? 0 : sampleDriver(d, frame, this.fps) / ppm;\n\t\tthis.addForce(body, (frame) => [\n\t\t\tread(accel.x, frame),\n\t\t\tread(accel.y, frame),\n\t\t\tread(accel.z, frame),\n\t\t]);\n\t\treturn this;\n\t}\n\n\t/** A force field, as in 2D: returns `[ax, ay, az]` px/s² for a body at `x/y/z` px. */\n\tfield(\n\t\taccel: (sample: FieldSample3D) => Vec3 | null | undefined,\n\t\toptions: { bodies?: readonly PhysicsBody3D[] } = {},\n\t): this {\n\t\tconst ppm = this.pixelsPerMeter;\n\t\tthis.addField((body, frame) => {\n\t\t\tconst [x, y, z] = body.sim.position();\n\t\t\tconst [vx, vy, vz] = body.sim.velocity();\n\t\t\tconst a = accel({\n\t\t\t\tx: x * ppm,\n\t\t\t\ty: y * ppm,\n\t\t\t\tz: z * ppm,\n\t\t\t\tvx: vx * ppm,\n\t\t\t\tvy: vy * ppm,\n\t\t\t\tvz: vz * ppm,\n\t\t\t\tframe,\n\t\t\t\tbody,\n\t\t\t});\n\t\t\treturn a ? [a[0] / ppm, a[1] / ppm, a[2] / ppm] : null;\n\t\t}, options.bodies);\n\t\treturn this;\n\t}\n\n\t/** An instant kick at a simulation frame: adds `[vx, vy, vz]` px/s. */\n\timpulse(body: PhysicsBody3D, frame: number, velocity: Vec3): this {\n\t\tconst ppm = this.pixelsPerMeter;\n\t\tthis.addImpulse(body, frame, [\n\t\t\tvelocity[0] / ppm,\n\t\t\tvelocity[1] / ppm,\n\t\t\tvelocity[2] / ppm,\n\t\t]);\n\t\treturn this;\n\t}\n\n\tprotected lerpRotation(a: Quat, b: Quat, t: number): Quat {\n\t\t// Normalized lerp along the short arc; fine for per-substep steps.\n\t\tconst sign =\n\t\t\ta[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3] < 0 ? -1 : 1;\n\t\tconst q = a.map((v, i) => v + (b[i] * sign - v) * t) as Quat;\n\t\tconst len = Math.hypot(...q) || 1;\n\t\treturn q.map((v) => v / len) as Quat;\n\t}\n\n\tprivate joint(\n\t\ta: PhysicsBody3D,\n\t\tb: PhysicsBody3D,\n\t\tspec: Parameters<SimWorld3D[\"addJoint\"]>[2],\n\t): void {\n\t\tthis.assertOpen();\n\t\t(this.sim as unknown as SimWorld3D).addJoint(a.sim, b.sim, spec);\n\t}\n\n\tprivate anchorBody(point: Vec3): PhysicsBody3D {\n\t\treturn this.body(\n\t\t\t{ x: point[0], y: point[1], z: point[2], width: 1, height: 1, depth: 1 },\n\t\t\t{ type: \"fixed\", output: \"none\", sensor: true },\n\t\t);\n\t}\n\n\tprivate endpoints(\n\t\ta: PhysicsBody3D,\n\t\tb: PhysicsBody3D | Vec3,\n\t\tanchorA?: Vec3,\n\t\tanchorB?: Vec3,\n\t): { other: PhysicsBody3D; pa: Vec3; pb: Vec3 } {\n\t\tconst pa = anchorA ?? a.center();\n\t\tif (Array.isArray(b)) {\n\t\t\tconst pb = anchorB ?? b;\n\t\t\treturn { other: this.anchorBody(pb), pa, pb };\n\t\t}\n\t\treturn { other: b, pa, pb: anchorB ?? b.center() };\n\t}\n}\n\nfunction dist(a: Vec3, b: Vec3): number {\n\treturn Math.hypot(b[0] - a[0], b[1] - a[1], b[2] - a[2]);\n}\n\nfunction num(v: unknown, fallback: number): number {\n\treturn typeof v === \"number\" && Number.isFinite(v) ? v : fallback;\n}\n\ninterface PrimitiveSpec {\n\ttype?: string;\n\twidth?: number;\n\theight?: number;\n\tdepth?: number;\n\tradius?: number;\n\tradiusTop?: number;\n\tradiusBottom?: number;\n\ttaper?: number;\n}\n\n/** Collider in px around the layer's center, with the layer's scale applied. */\nfunction colliderShape3D(t: LayerLike, options: Body3DOptions): Shape3D {\n\tconst id = typeof t.id === \"string\" ? ` \"${t.id}\"` : \"\";\n\tconst s = num(t.scale, 1);\n\tconst scale: Vec3 = [\n\t\ts * num(t.scaleX, 1),\n\t\ts * num(t.scaleY, 1),\n\t\ts * num(t.scaleZ, 1),\n\t];\n\tconst uniform = scale[0] === scale[1] && scale[1] === scale[2];\n\tconst prim = (t.primitive3d ?? {}) as PrimitiveSpec;\n\tconst mode = options.shape ?? \"auto\";\n\tconst hull = (): Shape3D | undefined => {\n\t\tconst pts = meshPoints(t.modelData);\n\t\tif (!pts) return undefined;\n\t\treturn { kind: \"hull\", points: pts.map((v, i) => v * scale[i % 3]) };\n\t};\n\n\tif (options.size || mode === \"box\") {\n\t\tconst [w, h, d] = options.size ?? boxSize(t, prim) ?? [0, 0, 0];\n\t\tif (w > 0 && h > 0 && d > 0) {\n\t\t\treturn {\n\t\t\t\tkind: \"box\",\n\t\t\t\thx: (w * scale[0]) / 2,\n\t\t\t\thy: (h * scale[1]) / 2,\n\t\t\t\thz: (d * scale[2]) / 2,\n\t\t\t\tradius:\n\t\t\t\t\tprim.type === \"roundedBox\"\n\t\t\t\t\t\t? num(prim.radius, 0) * Math.min(...scale)\n\t\t\t\t\t\t: 0,\n\t\t\t};\n\t\t}\n\t}\n\tif (mode === \"hull\") {\n\t\tconst h = hull();\n\t\tif (h) return h;\n\t}\n\tconst sphere =\n\t\tmode === \"sphere\" || (mode === \"auto\" && prim.type === \"sphere\");\n\tif (sphere && (uniform || mode === \"sphere\")) {\n\t\tconst r = num(prim.radius, 0) || Math.max(...(boxSize(t, prim) ?? [0])) / 2;\n\t\tif (r > 0) return { kind: \"ball\", radius: r * Math.max(...scale) };\n\t}\n\tconst rTop = num(prim.radiusTop, num(prim.radius, 0));\n\tconst rBottom = num(prim.radiusBottom, num(prim.radius, 0));\n\tconst cylinder =\n\t\tmode === \"cylinder\" || (mode === \"auto\" && prim.type === \"cylinder\");\n\tif (cylinder && rTop === rBottom && rTop > 0 && scale[0] === scale[2]) {\n\t\treturn {\n\t\t\tkind: \"cylinder\",\n\t\t\thalfHeight: (num(prim.height, 0) * scale[1]) / 2,\n\t\t\tradius: rTop * scale[0],\n\t\t};\n\t}\n\tif (\n\t\tmode === \"auto\" &&\n\t\tprim.type === \"roundedBox\" &&\n\t\t(prim.taper ?? 1) === 1\n\t) {\n\t\tconst [w, h, d] = [\n\t\t\tnum(prim.width, 0),\n\t\t\tnum(prim.height, 0),\n\t\t\tnum(prim.depth, 0),\n\t\t];\n\t\treturn {\n\t\t\tkind: \"box\",\n\t\t\thx: (w * scale[0]) / 2,\n\t\t\thy: (h * scale[1]) / 2,\n\t\t\thz: (d * scale[2]) / 2,\n\t\t\tradius: num(prim.radius, 0) * Math.min(...scale),\n\t\t};\n\t}\n\tconst h = hull();\n\tif (h) return h;\n\tconst size = boxSize(t, prim);\n\tif (size) {\n\t\treturn {\n\t\t\tkind: \"box\",\n\t\t\thx: (size[0] * scale[0]) / 2,\n\t\t\thy: (size[1] * scale[1]) / 2,\n\t\t\thz: (size[2] * scale[2]) / 2,\n\t\t};\n\t}\n\tthrow new Error(\n\t\t`Physics: layer${id} has no mesh or size to build a 3D collider from; pass \\`size: [w, h, d]\\`.`,\n\t);\n}\n\nfunction boxSize(t: LayerLike, prim: PrimitiveSpec): Vec3 | undefined {\n\tif (prim.type === \"roundedBox\")\n\t\treturn [num(prim.width, 0), num(prim.height, 0), num(prim.depth, 0)];\n\tif (prim.type === \"sphere\") {\n\t\tconst d = num(prim.radius, 0) * 2;\n\t\treturn [d, d, d];\n\t}\n\tif (prim.type === \"cylinder\") {\n\t\tconst d =\n\t\t\tMath.max(\n\t\t\t\tnum(prim.radiusTop, num(prim.radius, 0)),\n\t\t\t\tnum(prim.radiusBottom, num(prim.radius, 0)),\n\t\t\t) * 2;\n\t\treturn [d, num(prim.height, 0), d];\n\t}\n\tif (\n\t\ttypeof t.width === \"number\" &&\n\t\ttypeof t.height === \"number\" &&\n\t\ttypeof t.depth === \"number\"\n\t) {\n\t\treturn [t.width, t.height, t.depth];\n\t}\n\treturn undefined;\n}\n\n/** Every vertex of a model, flat xyz, at most ~4k points (the hull needs no more). */\nfunction meshPoints(modelData: unknown): number[] | undefined {\n\tconst meshes = (\n\t\tmodelData as\n\t\t\t| { meshes?: Array<{ positions?: ArrayLike<number> }> }\n\t\t\t| undefined\n\t)?.meshes;\n\tif (!meshes?.length) return undefined;\n\tlet total = 0;\n\tfor (const m of meshes) total += (m.positions?.length ?? 0) / 3;\n\tif (total < 4) return undefined;\n\tconst stride = Math.max(1, Math.floor(total / 4096));\n\tconst out: number[] = [];\n\tlet i = 0;\n\tfor (const m of meshes) {\n\t\tconst p = m.positions;\n\t\tif (!p) continue;\n\t\tfor (let v = 0; v < p.length; v += 3, i++) {\n\t\t\tif (i % stride === 0) out.push(p[v], p[v + 1], p[v + 2]);\n\t\t}\n\t}\n\treturn out;\n}\n\nfunction scaleShape(shape: Shape3D, s: number): Shape3D {\n\tswitch (shape.kind) {\n\t\tcase \"ball\":\n\t\t\treturn { kind: \"ball\", radius: shape.radius * s };\n\t\tcase \"box\":\n\t\t\treturn {\n\t\t\t\tkind: \"box\",\n\t\t\t\thx: shape.hx * s,\n\t\t\t\thy: shape.hy * s,\n\t\t\t\thz: shape.hz * s,\n\t\t\t\tradius: (shape.radius ?? 0) * s,\n\t\t\t};\n\t\tcase \"cylinder\":\n\t\t\treturn {\n\t\t\t\tkind: \"cylinder\",\n\t\t\t\thalfHeight: shape.halfHeight * s,\n\t\t\t\tradius: shape.radius * s,\n\t\t\t};\n\t\tcase \"hull\":\n\t\t\treturn { kind: \"hull\", points: shape.points.map((v) => v * s) };\n\t}\n}\n","import { rapierBackend } from \"./backend.js\";\nimport { PhysicsWorld2D, type World2DOptions } from \"./world2d.js\";\nimport { PhysicsWorld3D, type World3DOptions } from \"./world3d.js\";\n\n/**\n * Rigid-body physics baked into signals. A world simulates once, while the\n * composition is built (Rapier's deterministic build, so every machine gets\n * the same motion), and replays as per-frame signals: layers follow their\n * bodies, and `impact`, `speed`, … drive any other prop or effect.\n *\n * ```ts\n * const world = await Physics.world2d({ fps: 30, frames: 150 });\n * world.walls({ width: W, height: H });\n * const card = world.body(cardLayer, { restitution: 0.4 });\n * world.simulate();\n * flash.animate(LayerAnimation.create().signal(\"opacity\", card.impact));\n * ```\n */\nexport const Physics = {\n\t/** A 2D world in layer pixels (y down). Loads the physics engine on first use. */\n\tasync world2d(options: World2DOptions): Promise<PhysicsWorld2D> {\n\t\treturn new PhysicsWorld2D(await rapierBackend(2), options);\n\t},\n\t/** A 3D world for Layer3D primitives and models, in scene pixels (y down). */\n\tasync world3d(options: World3DOptions): Promise<PhysicsWorld3D> {\n\t\treturn new PhysicsWorld3D(await rapierBackend(3), options);\n\t},\n};\n\nexport type {\n\tBodyCommonOptions,\n\tPhysicsBakeOptions,\n\tPhysicsCollision,\n\tPhysicsDriver,\n\tPhysicsWorldOptions,\n} from \"./core.js\";\nexport {\n\ttype Body2DOptions,\n\ttype FieldSample2D,\n\tPhysicsBody2D,\n\ttype PhysicsGroundOptions,\n\ttype PhysicsRect,\n\ttype PhysicsRopeOptions,\n\ttype PhysicsSpringOptions,\n\ttype PhysicsWallsOptions,\n\tPhysicsWorld2D,\n\ttype World2DOptions,\n} from \"./world2d.js\";\nexport {\n\ttype Body3DOptions,\n\ttype FieldSample3D,\n\tPhysicsBody3D,\n\ttype PhysicsBox3D,\n\ttype PhysicsRope3DOptions,\n\ttype PhysicsSpring3DOptions,\n\tPhysicsWorld3D,\n\ttype World3DOptions,\n} from \"./world3d.js\";\n","/**\n * Ready-made looks: each preset is a short stack of effects, applied with\n * `layer.withEffects(Styles.vhs())`. Presets take a few options for the\n * knobs that matter most; for anything finer, build the stack from the\n * effect classes directly.\n */\nimport type { Effect } from \"@framefields/core\";\nimport {\n\tAscii,\n\tContour,\n\tCRT,\n\tDither,\n\tFilmGrain,\n\tGradientMap,\n\tHalftoneScreen,\n\tIridescence,\n\tKaleidoscope,\n\tOpArt,\n\tPainterly,\n\tPixelate,\n\tPosterize,\n\tRGBSplit,\n\tToon,\n\tVignette,\n} from \"./effects/index.js\";\n\ntype Look = Effect<object>[];\nconst look = (...effects: unknown[]): Look => effects as Look;\n\nexport const Styles = {\n\t/** 8-bit game: PICO-8 palette, chunky pixels, light dithering. */\n\tpixelArt: (\n\t\to: { pixelSize?: number; palette?: \"pico8\" | \"c64\" | \"cga\" } = {},\n\t) =>\n\t\tlook(\n\t\t\tnew Posterize({\n\t\t\t\tpalette: o.palette ?? \"pico8\",\n\t\t\t\tpixelSize: o.pixelSize ?? 6,\n\t\t\t\tdither: 0.4,\n\t\t\t}),\n\t\t),\n\n\t/** Original Game Boy: four greens, dithered, big pixels. */\n\tgameBoy: (o: { pixelSize?: number } = {}) =>\n\t\tlook(\n\t\t\tnew Posterize({\n\t\t\t\tpalette: \"gameboy\",\n\t\t\t\tpixelSize: o.pixelSize ?? 4,\n\t\t\t\tdither: 0.6,\n\t\t\t}),\n\t\t),\n\n\t/** Teletext / Ceefax: eight flat colors in big blocks. */\n\tteletext: (o: { pixelSize?: number } = {}) =>\n\t\tlook(new Posterize({ palette: \"teletext\", pixelSize: o.pixelSize ?? 10 })),\n\n\t/** LED wall: round lit pixels with gaps. */\n\tledWall: (o: { size?: number } = {}) =>\n\t\tlook(new Pixelate({ size: o.size ?? 14, shape: \"circle\", gap: 0.18 })),\n\n\t/** Text-mode art: the clip drawn in characters. `matrix` makes it green phosphor. */\n\tascii: (o: { cellSize?: number; matrix?: boolean } = {}) =>\n\t\tlook(\n\t\t\tnew Ascii({\n\t\t\t\tcellSize: o.cellSize ?? 10,\n\t\t\t\tcolorMode: o.matrix ? \"green\" : \"source\",\n\t\t\t\tbg: o.matrix ? \"#020a04\" : \"#0b0b0b\",\n\t\t\t}),\n\t\t),\n\n\t/** 1-bit print: ordered dither in two inks. */\n\toneBit: (o: { dark?: string; light?: string; scale?: number } = {}) =>\n\t\tlook(\n\t\t\tnew Dither({\n\t\t\t\tmode: \"bayer\",\n\t\t\t\tscale: o.scale ?? 2,\n\t\t\t\tdark: o.dark ?? \"#111111\",\n\t\t\t\tlight: o.light ?? \"#f2efe6\",\n\t\t\t}),\n\t\t),\n\n\t/** Riso print: two inks on paper, ordered dither, grain. */\n\trisograph: (o: { inkA?: string; inkB?: string; paper?: string } = {}) => {\n\t\tconst a = o.inkA ?? \"#1d3fbb\";\n\t\tconst b = o.inkB ?? \"#ff5fa2\";\n\t\tconst paper = o.paper ?? \"#f4efe4\";\n\t\treturn look(\n\t\t\tnew GradientMap({\n\t\t\t\tstops: [\n\t\t\t\t\t{ position: 0, color: a },\n\t\t\t\t\t{ position: 0.55, color: b },\n\t\t\t\t\t{ position: 1, color: paper },\n\t\t\t\t],\n\t\t\t}),\n\t\t\tnew Posterize({\n\t\t\t\tpalette: \"custom\",\n\t\t\t\tcolors: [a, b, paper],\n\t\t\t\tdither: 0.8,\n\t\t\t\tpixelSize: 2,\n\t\t\t}),\n\t\t\tnew FilmGrain({ strength: 0.2 }),\n\t\t);\n\t},\n\n\t/** Cartoon / cel shading with ink outlines. */\n\tcartoon: (o: { levels?: number; ink?: string } = {}) =>\n\t\tlook(\n\t\t\tnew Toon({\n\t\t\t\tlevels: o.levels ?? 4,\n\t\t\t\tedgeColor: o.ink ?? \"#111111\",\n\t\t\t\tsaturation: 1.3,\n\t\t\t}),\n\t\t),\n\n\t/** Comic book: cel shading, ink lines and a halftone dot screen. */\n\tcomic: (o: { dotFrequency?: number } = {}) =>\n\t\tlook(\n\t\t\tnew Toon({ levels: 4, edgeWidth: 1.5, saturation: 1.4 }),\n\t\t\tnew HalftoneScreen({ frequency: o.dotFrequency ?? 70, opacity: 0.35 }),\n\t\t),\n\n\t/** Thermal camera: brightness mapped to the ironbow palette. */\n\tthermal: () =>\n\t\tlook(\n\t\t\tnew GradientMap({\n\t\t\t\tstops: [\n\t\t\t\t\t{ position: 0, color: \"#000010\" },\n\t\t\t\t\t{ position: 0.25, color: \"#3b0a7a\" },\n\t\t\t\t\t{ position: 0.5, color: \"#c4205f\" },\n\t\t\t\t\t{ position: 0.75, color: \"#ff9a1f\" },\n\t\t\t\t\t{ position: 1, color: \"#fffbe0\" },\n\t\t\t\t],\n\t\t\t}),\n\t\t),\n\n\t/** VHS tape: wobble, colour bleed, soft scanlines, grain. */\n\tvhs: (o: { tracking?: number } = {}) =>\n\t\tlook(\n\t\t\tnew CRT({\n\t\t\t\ttracking: o.tracking ?? 0.5,\n\t\t\t\tchroma: 4,\n\t\t\t\tcurvature: 0.04,\n\t\t\t\tscanlines: 0.25,\n\t\t\t\tmask: 0.05,\n\t\t\t\tnoise: 0.15,\n\t\t\t}),\n\t\t\tnew RGBSplit({ amount: 3 }),\n\t\t),\n\n\t/** An old CRT monitor: curved glass, scanlines, RGB mask. */\n\tcrt: (o: { curvature?: number } = {}) =>\n\t\tlook(\n\t\t\tnew CRT({ curvature: o.curvature ?? 0.15, scanlines: 0.5, mask: 0.35 }),\n\t\t),\n\n\t/** Glitch: hard RGB split plus tracking errors. Animate `amount` for hits. */\n\tglitch: (o: { amount?: number } = {}) =>\n\t\tlook(\n\t\t\tnew RGBSplit({ amount: o.amount ?? 18 }),\n\t\t\tnew CRT({\n\t\t\t\ttracking: 1,\n\t\t\t\tchroma: 6,\n\t\t\t\tcurvature: 0,\n\t\t\t\tscanlines: 0.1,\n\t\t\t\tmask: 0,\n\t\t\t\tvignette: 0,\n\t\t\t}),\n\t\t),\n\n\t/** Oil painting. */\n\toilPainting: (o: { brush?: number } = {}) =>\n\t\tlook(new Painterly({ style: \"oil\", radius: o.brush ?? 5 })),\n\n\t/** Watercolour: soft patches, pigment edges, paper. */\n\twatercolor: (o: { brush?: number } = {}) =>\n\t\tlook(\n\t\t\tnew Painterly({ style: \"watercolor\", radius: o.brush ?? 6, paper: 0.5 }),\n\t\t),\n\n\t/** Topographic map lines on paper. */\n\ttopographic: (o: { levels?: number; ink?: string; paper?: string } = {}) =>\n\t\tlook(\n\t\t\tnew Contour({\n\t\t\t\tlevels: o.levels ?? 16,\n\t\t\t\tfill: \"flat\",\n\t\t\t\tlineColor: o.ink ?? \"#5a3a1a\",\n\t\t\t\tfillColor: o.paper ?? \"#f3ead8\",\n\t\t\t}),\n\t\t),\n\n\t/** Kaleidoscope. Animate `rotation` on the returned effect, or pass a fixed angle. */\n\tkaleidoscope: (o: { segments?: number; rotation?: number } = {}) =>\n\t\tlook(\n\t\t\tnew Kaleidoscope({\n\t\t\t\tsegments: o.segments ?? 8,\n\t\t\t\trotation: o.rotation ?? 0,\n\t\t\t}),\n\t\t),\n\n\t/** Op art / line portrait: stripes bent by the image. */\n\topArt: (\n\t\to: {\n\t\t\tpattern?: \"stripes\" | \"rings\" | \"checker\" | \"waves\";\n\t\t\tfrequency?: number;\n\t\t} = {},\n\t) =>\n\t\tlook(\n\t\t\tnew OpArt({\n\t\t\t\tpattern: o.pattern ?? \"stripes\",\n\t\t\t\tfrequency: o.frequency ?? 60,\n\t\t\t}),\n\t\t),\n\n\t/** Holographic foil sheen. Animate `shift` to make it move. */\n\tholographic: (o: { strength?: number; shift?: number } = {}) =>\n\t\tlook(new Iridescence({ strength: o.strength ?? 0.7, shift: o.shift ?? 0 })),\n\n\t/** Black-and-white film noir: crushed tones, grain, vignette. */\n\tnoir: () =>\n\t\tlook(\n\t\t\tnew GradientMap({\n\t\t\t\tstops: [\n\t\t\t\t\t{ position: 0, color: \"#000000\" },\n\t\t\t\t\t{ position: 0.55, color: \"#8a8a8a\" },\n\t\t\t\t\t{ position: 1, color: \"#ffffff\" },\n\t\t\t\t],\n\t\t\t}),\n\t\t\tnew FilmGrain({ strength: 0.35 }),\n\t\t\tnew Vignette({ strength: 0.6 }),\n\t\t),\n\n\t/** Analog film: grain and a soft vignette. */\n\tfilm: () =>\n\t\tlook(new FilmGrain({ strength: 0.25 }), new Vignette({ strength: 0.35 })),\n};\n\nexport type StyleName = keyof typeof Styles;\n","export {\n\tAudioSignal,\n\ttype AudioSignalOptions,\n\tcomputed,\n\tcosineSignal,\n\ttype ExtractedAudioSignalsBundle,\n\ttype FrameSignal,\n\tSignal,\n\ttype SignalContext,\n\ttype SignalValue,\n\ttype SineSignalOptions,\n\tsignal,\n\tsignalBuilder,\n\tsignalRegistry,\n\tsineSignal,\n} from \"./signals/index.js\";\n\nimport {\n\tFontManager,\n\ttype MeasuredGlyph,\n\ttype MeasureTextOptions,\n\ttype RegisteredFont,\n\ttype RegisterFontOptions,\n\ttype TextMetrics,\n} from \"./fonts/index.js\";\nimport { autoId } from \"./ids.js\";\nimport { normalizeTextSpans, type TextSpan } from \"./rich-text.js\";\n\nexport {\n\tencodeStereoWav,\n\tmixAudioTracks,\n\tmixSfxInto,\n\ttype RenderedSfx,\n\trenderSfx,\n\ttype SfxRenderContext,\n\ttype SfxTrigger,\n\tsoftLimit,\n} from \"./audio/index.js\";\nexport {\n\taccent,\n\tbold,\n\tcode,\n\tcolor,\n\titalic,\n\ttype MarkOptions,\n\tmark,\n\tnormalizeTextSpans,\n\tparseMarkup,\n\trich,\n\tsize,\n\tspan,\n\tsub,\n\tsup,\n\ttype TextSpan,\n\ttype TextSpanItem,\n\ttype TextSpanMark,\n} from \"./rich-text.js\";\nexport {\n\tFontManager,\n\ttype MeasuredGlyph,\n\ttype MeasureTextOptions,\n\ttype RegisteredFont,\n\ttype RegisterFontOptions,\n\ttype TextMetrics,\n};\n\nexport {\n\tCannyComputePipeline,\n\ttype CannyOptions,\n\ttype ControlNetConditioningOutputs,\n\tControlNetMultiplexer,\n\ttype DeflickerOptions,\n\tDepthNormalsComputePipeline,\n\ttype DepthNormalsOptions,\n\ttype NormalRelightingOptions,\n\tOpticalFlowComputePipeline,\n\ttype OpticalFlowOptions,\n\tTemporalDeflickerPipeline,\n\ttype TensorDimensions,\n\ttype TensorFormat,\n\ttype TensorNode,\n\tTensorPipeline,\n\ttype TensorPipelineConfig,\n\ttype TensorSource,\n\ttype TensorViewExport,\n} from \"@framefields/tensor-webgpu\";\nexport {\n\tCOCO_CLASSES,\n\tCOCO17_BONES,\n\tCOCO17_KEYPOINT_NAMES,\n\tCOCO17_KEYPOINTS,\n\ttype DetectedObject,\n\ttype InstanceMask,\n\ttype Landmark3D,\n\ttype LandmarkCoordinateSignals,\n\ttype MaskTrackSignals,\n\ttype NormalizedLandmarkList,\n\ttype ObjectAnchorName,\n\ttype ObjectAnchorsSignals,\n\ttype ObjectBoundingBox,\n\ttype ObjectBoundingBoxSignals,\n\ttype ObjectCollectionSignals,\n\ttype ObjectKinematicsSignals,\n\ttype ObjectTrackSignals,\n\ttype PersonMatte,\n\ttype PinToLandmarkOptions,\n\ttype PinToObjectOptions,\n\ttype PoseLandmarkSignals,\n\ttype PoseResult,\n\tPoseSkeletonRenderer,\n\tpinNodeToLandmark,\n\tpinNodeToObject,\n\ttype SegmentationResult,\n\tSegmentationTexturePool,\n\tSpatialLandmarkTransformer,\n\tTemporalObjectTracker,\n\ttype TrackedObject,\n\tVisionBundle,\n\ttype VisionConfig,\n\tVisionNode,\n\tVisionRunner,\n\ttype VisionTask,\n\ttype VisionVariant,\n} from \"@framefields/vision\";\n\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport {\n\ttype AnimationTrack,\n\ttype BoxNode,\n\ttype CameraNode,\n\ttype CompositorProgramConfig,\n\ttype CompositorToProgramOptions,\n\tcompositorToProgram,\n\ttype EnvironmentPreset,\n\ttype FlexNode,\n\tLayerAnimation,\n\ttype LayoutNode,\n\ttype LightNode,\n\tlintComposition,\n\ttype MatteMode,\n\ttype MediaNode,\n\ttype Model3DNode,\n\tmergeAnimationTracks,\n\ttype ShapeNode,\n\ttype TextNode,\n} from \"@framefields/compositions/program\";\nimport {\n\tappendOperation,\n\tEffect as CoreEffect,\n\tcreateVirtualMedia,\n\ttype DataType,\n\ttype FrameContext,\n\ttype MediaMetadata,\n\ttype MediaOperation,\n\ttype MediaSourceInput,\n\ttype MeshAudioDeformConfig,\n\tProgrammaticSignal,\n\ttype RenderDiagnostic,\n\ttype Signal,\n\ttype VirtualMediaData,\n} from \"@framefields/core\";\nimport {\n\tanalyzeSequence as analyzeVisionFrames,\n\tCLIP_SUBJECT,\n\ttype LandmarkCoordinateSignals,\n\ttype MaskTrackSignals,\n\ttype ObjectTrackSignals,\n\ttype PinToLandmarkOptions,\n\ttype PinToObjectOptions,\n\tpinNodeToLandmark,\n\tpinNodeToObject,\n\ttype VisionAnalysisReport,\n\tVisionBundle,\n\tVisionNode,\n\tVisionRunner,\n\ttype VisionTask,\n} from \"@framefields/vision\";\n\nexport {\n\tanalyzeSequence,\n\ttype VisionAnalysisReport,\n} from \"@framefields/vision\";\n\nimport {\n\ttype DeflickerOptions,\n\ttype NormalRelightingOptions,\n\tTensorPipeline,\n} from \"@framefields/tensor-webgpu\";\nimport { inputStore, mediaDecoderCache } from \"@framefields/webgpu-renderers\";\nimport { buildChart, type ChartOptions } from \"./chart.js\";\nimport { ClipVision, type ClipVisionOptions } from \"./clip-vision.js\";\nimport {\n\tApplyLUT,\n\ttype ApplyLUTProps,\n\tBlur,\n\ttype BlurProps,\n\tColorBalance,\n\ttype ColorBalanceProps,\n\tColorKey,\n\ttype ColorKeyProps,\n\tCrop,\n\ttype CropProps,\n\tCurves,\n\ttype CurvesProps,\n\tCustomEffect,\n\ttype DeflickerProps,\n\tDepthOfField,\n\ttype DepthOfFieldProps,\n\teffectFactories,\n\tFilmGrain,\n\ttype FilmGrainProps,\n\tGradientMap,\n\ttype GradientMapProps,\n\tHalftoneScreen,\n\ttype HalftoneScreenProps,\n\tHighPass,\n\ttype HighPassProps,\n\tLevels,\n\ttype LevelsProps,\n\tModulate,\n\ttype ModulateProps,\n\tMotionBlur,\n\ttype MotionBlurProps,\n\tPBRGlass,\n\ttype PBRGlassProps,\n\tProceduralVFX,\n\ttype ProceduralVFXProps,\n\tRelight3D,\n\ttype Relight3DProps,\n\tSelectiveColor,\n\ttype SelectiveColorProps,\n\tShadowsHighlights,\n\ttype ShadowsHighlightsProps,\n\tSSAO,\n\ttype SSAOProps,\n\tTemporalDeflicker,\n\tTileOffset,\n\ttype TileOffsetProps,\n\tUnsharpMask,\n\ttype UnsharpMaskProps,\n\tVignette,\n\ttype VignetteProps,\n\tVision,\n\ttype VisionProps,\n} from \"./effects/index.js\";\nimport { Particles, type ParticlesOptions } from \"./particles.js\";\nimport {\n\ttype FrameGridOptions,\n\tHeadlessMediaRenderer,\n\ttype RenderProgress,\n\trenderFrameGrid,\n\ttype VideoQaOptions,\n\ttype VideoQaReport,\n} from \"./renderer/index.js\";\nimport {\n\ttype Carousel3DOptions,\n\ttype Cube3DOptions,\n\tLayer3D,\n\ttype Plane3DOptions,\n\ttype Prism3DOptions,\n} from \"./shapes3d.js\";\nimport {\n\ttype SceneSequenceOptions,\n\ttype SequenceEntry,\n\ttype SequenceNode,\n\tsequence,\n} from \"./transitions.js\";\n\nexport interface SectionOptions {\n\treadonly id?: string;\n\treadonly position?: \"absolute\" | \"relative\";\n\treadonly source?: string | MediaNode;\n\treadonly effects?: unknown[];\n\treadonly padding?: number;\n\treadonly borderRadius?: number;\n\treadonly borderColor?: string;\n\treadonly borderWidth?: number;\n\treadonly opacity?: number | unknown;\n\treadonly blendMode?: string;\n\treadonly fit?: \"cover\" | \"contain\";\n\treadonly width?: number | unknown;\n\treadonly height?: number | unknown;\n\treadonly x?: number | unknown;\n\treadonly y?: number | unknown;\n\treadonly hideWhenLost?: boolean;\n\treadonly smoothFrames?: number;\n\treadonly children?: LayoutNode[];\n\treadonly [key: string]: unknown;\n}\n\nexport type SectionNode = AnimatableNode<BoxNode> & {\n\treadonly innerMedia: AnimatableNode<MediaNode>;\n\t// Any effect, whatever its config shape (Blur, FilmGrain, …).\n\treadonly effects: Effect<object>[];\n\taddEffect(effect: Effect<object>): SectionNode;\n\twithEffect(effect: Effect<object>): SectionNode;\n\twithEffects(effects: Effect<object>[]): SectionNode;\n};\n\nexport type TrackedRegionOptions = SectionOptions;\n\n/** Editing helpers attached to every tracked object (see decorateTrackSignals). */\nexport interface TrackEditing {\n\t/** A section of the source that follows this track */\n\tsection(\n\t\tsourceOrOptions?: string | MediaNode | SectionOptions,\n\t\toptions?: SectionOptions,\n\t): SectionNode;\n\t/** A blur confined to this track's region */\n\tblurEffect(options?: Partial<BlurProps>): Blur;\n\t/** The tracked region of `source`, cut out as a section */\n\tisolate(\n\t\tsource: string | MediaNode,\n\t\toptions?: TrackedRegionOptions,\n\t): SectionNode;\n}\n\n/** A tracked object with its editing helpers, as vision hands it out. */\nexport type EditableObjectTrack = ObjectTrackSignals & TrackEditing;\n\nfunction decorateTrackSignals<T extends ObjectTrackSignals>(\n\ttrack: T,\n\tsource?: string | MediaNode,\n): T {\n\tif (!track) return track;\n\tif (source && !track.source) {\n\t\tObject.defineProperty(track, \"source\", {\n\t\t\tvalue: source,\n\t\t\tenumerable: true,\n\t\t\twritable: true,\n\t\t\tconfigurable: true,\n\t\t});\n\t}\n\tif (typeof track.section !== \"function\") {\n\t\tObject.defineProperty(track, \"section\", {\n\t\t\tvalue: (\n\t\t\t\tsourceOrOptions?: string | MediaNode | SectionOptions,\n\t\t\t\toptions?: SectionOptions,\n\t\t\t) => {\n\t\t\t\tif (\n\t\t\t\t\ttypeof sourceOrOptions === \"object\" &&\n\t\t\t\t\tsourceOrOptions !== null &&\n\t\t\t\t\t!(\"kind\" in sourceOrOptions) &&\n\t\t\t\t\t!(\"inputHandleId\" in sourceOrOptions) &&\n\t\t\t\t\t!(\"src\" in sourceOrOptions)\n\t\t\t\t) {\n\t\t\t\t\tconst resolvedSource =\n\t\t\t\t\t\t(sourceOrOptions as SectionOptions).source ??\n\t\t\t\t\t\t(track.source as string | MediaNode | undefined) ??\n\t\t\t\t\t\tsource;\n\t\t\t\t\treturn Layer.section(\n\t\t\t\t\t\tresolvedSource as string | MediaNode,\n\t\t\t\t\t\ttrack,\n\t\t\t\t\t\tsourceOrOptions as SectionOptions,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst resolvedSource =\n\t\t\t\t\tsourceOrOptions ??\n\t\t\t\t\t(track.source as string | MediaNode | undefined) ??\n\t\t\t\t\tsource;\n\t\t\t\treturn Layer.section(\n\t\t\t\t\tresolvedSource as string | MediaNode,\n\t\t\t\t\ttrack,\n\t\t\t\t\toptions,\n\t\t\t\t);\n\t\t\t},\n\t\t\tenumerable: false,\n\t\t\twritable: true,\n\t\t\tconfigurable: true,\n\t\t});\n\t}\n\tif (typeof track.blurEffect !== \"function\") {\n\t\tObject.defineProperty(track, \"blurEffect\", {\n\t\t\tvalue: (options?: Partial<BlurProps>) => new Blur({ track, ...options }),\n\t\t\tenumerable: false,\n\t\t\twritable: true,\n\t\t\tconfigurable: true,\n\t\t});\n\t}\n\tif (typeof track.isolate !== \"function\") {\n\t\tObject.defineProperty(track, \"isolate\", {\n\t\t\tvalue: (sourceArg: string | MediaNode, options?: TrackedRegionOptions) =>\n\t\t\t\tLayer.section(sourceArg, track, options),\n\t\t\tenumerable: false,\n\t\t\twritable: true,\n\t\t\tconfigurable: true,\n\t\t});\n\t}\n\treturn track;\n}\n\nconst origVisionAttach = VisionNode.attach;\nVisionNode.attach = function (\n\tsource: Parameters<typeof origVisionAttach>[0],\n\tconfig?: Parameters<typeof origVisionAttach>[1],\n\tbundleOptions?: Parameters<typeof origVisionAttach>[2],\n): ReturnType<typeof origVisionAttach> {\n\tconst bundle = origVisionAttach.call(this, source, config, bundleOptions);\n\tif (bundle?.objects) {\n\t\tconst src = source as string | MediaNode;\n\t\tconst origGet = bundle.objects.get.bind(bundle.objects);\n\t\tbundle.objects.get = (id: number) => decorateTrackSignals(origGet(id), src);\n\n\t\tconst origByCategory = bundle.objects.byCategory.bind(bundle.objects);\n\t\tbundle.objects.byCategory = (cat: string, rank?: number) =>\n\t\t\tdecorateTrackSignals(origByCategory(cat, rank), src);\n\n\t\tif (bundle.objects.primary) {\n\t\t\tdecorateTrackSignals(bundle.objects.primary, src);\n\t\t}\n\t}\n\treturn bundle;\n};\n\nexport {\n\ttype AdvancedTextAnimator,\n\tAdvancedTextAnimatorBuilder,\n\tAdvancedTextAnimatorSchema,\n\t// Text Animations & After Effects Parity\n\ttype AETextAnimator,\n\tAETextAnimatorSchema,\n\ttype AnchorGrouping,\n\tAnchorGroupingSchema,\n\ttype AnchorPreset,\n\tAnchorPresetSchema,\n\ttype AnimatableGlyphProps,\n\tAnimatableGlyphPropsSchema,\n\ttype AnimatableProp,\n\ttype AnimationTrack,\n\ttype ArcLengthLUTEntry,\n\ttype AudioSpectrumTypography,\n\tAudioSpectrumTypographySchema,\n\tapplyStaggerToChildren,\n\ttype BlockNode,\n\ttype BloomConfig,\n\tBloomConfigSchema,\n\ttype BoxNode,\n\tBoxNodeSchema,\n\tbuildPathLUT,\n\tCameraAnimation,\n\ttype CameraDoF,\n\ttype CameraLens,\n\ttype CameraNode,\n\tCameraNodeSchema,\n\ttype CameraShake,\n\ttype CarrierHandoffConfig,\n\tCarrierHandoffConfigSchema,\n\ttype CarrierState,\n\ttype ChromaticGlitchConfig,\n\tChromaticGlitchConfigSchema,\n\ttype ColorSignalOptions,\n\ttype ColorStop,\n\tColorStopSchema,\n\ttype CompositorProgramConfig,\n\tCompositorProgramSchema,\n\ttype CompositorToProgramOptions,\n\ttype CubicBezierSegment,\n\tCubicBezierSegmentSchema,\n\tcalculateSequenceTimeline,\n\tcollectNodeOps,\n\tcompositorToProgram,\n\tcomputeAnchorPivotOffset,\n\tcomputeCarrierContinuity,\n\tcomputeLayout,\n\tcomputeLayoutSync,\n\tcomputeLineLeadingDisplacement,\n\tcomputeRangeSelectorWeight,\n\tcomputeStaggerDelay,\n\ttype DynamicStrokeProperties,\n\tDynamicStrokePropertiesSchema,\n\tdeterministicWigglyNoise,\n\tdistanceToCurveParameter,\n\ttype EaseRef,\n\ttype EnhancedTextNode,\n\tEnhancedTextNodeSchema,\n\ttype EnvironmentFog,\n\tEnvironmentFogSchema,\n\ttype EnvironmentPreset,\n\tEnvironmentPresetSchema,\n\ttype ExpressionEvaluationContext,\n\ttype ExpressionSelector,\n\tExpressionSelectorSchema,\n\ttype ExtendedGlyphProperties,\n\tExtendedGlyphPropertiesSchema,\n\tellipseToCubicBeziers,\n\tevaluateAnimationAtFrame,\n\tevaluateCubicBezier,\n\tevaluateCubicBezierDerivative,\n\tevaluateExpressionSelector,\n\tevaluateMarqueeOffset,\n\tevaluateSelectorCombination,\n\tevaluateSkewMatrix,\n\tevaluateSpringProgress,\n\tevaluateTrackAtFrame,\n\tevaluateTypewriterState,\n\tevaluateVolumetricFormation,\n\ttype FlexNode,\n\tFlexNodeSchema,\n\ttype FromToOptions,\n\ttype GlyphAnchorGrouping,\n\tGlyphAnchorGroupingSchema,\n\ttype GlyphAnchorPoint,\n\tGlyphAnchorPointSchema,\n\tgenerateArcLengthLUT,\n\tgeneratePathSegments,\n\tgetScramblePool,\n\tgetShuffledOrder,\n\thoistMattes,\n\ttype Keyframe,\n\ttype KeyframeTuple,\n\ttype KineticMarqueeConfig,\n\tKineticMarqueeConfigSchema,\n\tLayerAnimation,\n\ttype LayoutNode,\n\tLayoutNodeSchema,\n\ttype LightNode,\n\tLightNodeSchema,\n\ttype LightType,\n\tLightTypeSchema,\n\ttype LineSpacingDynamics,\n\tLineSpacingDynamicsSchema,\n\ttype LongShadowConfig,\n\tLongShadowConfigSchema,\n\tlintComposition,\n\ttype MaterialType,\n\tMaterialTypeSchema,\n\ttype MatteMode,\n\tMatteModeSchema,\n\ttype MediaNode,\n\tMediaNodeSchema,\n\ttype Model3DNode,\n\tModel3DNodeSchema,\n\tmergeAnimationTracks,\n\ttype ParticleDissolveConfig,\n\tParticleDissolveConfigSchema,\n\ttype PathChainLUT,\n\ttype PathChainLUTEntry,\n\tparseSvgPathToCubicBeziers,\n\tScene,\n\ttype SceneDefinition,\n\tSceneDefinitionSchema,\n\ttype SceneOptions,\n\ttype SceneTransitionType,\n\tSceneTransitionTypeSchema,\n\ttype SelectorBasedOn,\n\tSelectorBasedOnSchema,\n\ttype SelectorMode,\n\tSelectorModeSchema,\n\ttype SelectorShape,\n\tSelectorShapeSchema,\n\ttype SelectorUnits,\n\tSelectorUnitsSchema,\n\tSequence,\n\ttype SequenceOptions,\n\ttype SequenceTimelineResult,\n\ttype ShapeNode,\n\tShapeNodeSchema,\n\ttype SignalTrackOptions,\n\ttype SkewProperties,\n\tSkewPropertiesSchema,\n\ttype Spatial3DProperties,\n\tSpatial3DPropertiesSchema,\n\ttype SpringOptions,\n\ttype SpringPhysics,\n\tSpringPhysicsSchema,\n\tsampleAudioSpectrumScale,\n\tsampleCurveGeometry,\n\tsamplePathChainGeometry,\n\ttype TextAnchorConfig,\n\tTextAnchorConfigSchema,\n\tTextAnimator,\n\tTextAnimatorBuilder,\n\tTextAnimatorSchema,\n\ttype TextCursorConfig,\n\tTextCursorConfigSchema,\n\ttype TextCursorStyle,\n\tTextCursorStyleSchema,\n\ttype TextNode,\n\tTextNodeSchema,\n\tTextPathBuilder,\n\ttype TextPathOptions,\n\tTextPathOptionsSchema,\n\ttype TextPathSource,\n\tTextPathSourceSchema,\n\ttype TextRangeSelector,\n\tTextRangeSelectorSchema,\n\ttype TextScrambleConfig,\n\tTextScrambleConfigSchema,\n\ttype TextSelector,\n\tTextSelectorSchema,\n\ttype TextSignalSelector,\n\tTextSignalSelectorSchema,\n\tTextSpanMarkSchema,\n\tTextSpanSchema,\n\ttype TextWigglySelector,\n\tTextWigglySelectorSchema,\n\ttype ToneMapping,\n\tToneMappingSchema,\n\ttype TrackSource,\n\ttype TypewriterAnimator,\n\tTypewriterAnimatorSchema,\n\ttype TypingCadence,\n\tTypingCadenceSchema,\n\ttype VariableFontAxes,\n\tVariableFontAxesSchema,\n\ttype Vec2,\n\tVec2Schema,\n\ttype VolumetricFormationConfig,\n\tVolumetricFormationConfigSchema,\n\ttype VolumetricFormationMode,\n\tVolumetricFormationModeSchema,\n\ttype WiggleOptions,\n\twaveToCubicBeziers,\n} from \"@framefields/compositions/program\";\nexport * from \"@framefields/core\";\nexport * from \"@framefields/renderers\";\nexport {\n\ttype AnimationClip3D,\n\ttype AudioLatentData,\n\tAudioLatentEngine,\n\tAudioLatentTrackCache,\n\tAudioMeshDeformPipeline,\n\ttype BlendMode,\n\ttype Bone3D,\n\tCamera3D,\n\tEffectPipeline,\n\tensureDevice,\n\tGlassPipeline,\n\ttype GPULightData,\n\tinputStore,\n\tLight3D,\n\ttype Light3DOptions,\n\ttype LoadModelOptions,\n\tloadFBX,\n\tloadModel3D,\n\tloadOBJ,\n\tlutStore,\n\ttype Material3D,\n\ttype Mesh3DData,\n\ttype Model3DData,\n\tMotionBlurPipeline,\n\ttype NodeAnimationTrack3D,\n\tPath3D,\n\tparseFBX,\n\tparseMTL,\n\tparseOBJ,\n\ttype RenderContextValue,\n\tRenderer2D,\n\tRenderer3D,\n\tShadowPipeline,\n\ttype Skeleton3D,\n\tSlugFontCache,\n\tSlugPipeline,\n\tSSAOPipeline,\n\tshaderStore,\n\ttextureCache,\n} from \"@framefields/webgpu-renderers\";\nexport {\n\ttype ChartAnimationOptions,\n\ttype ChartAxisOptions,\n\ttype ChartCandle,\n\ttype ChartDatum,\n\ttype ChartOptions,\n\ttype ChartPadding,\n\ttype ChartSeries,\n\ttype ChartSlice,\n\ttype ChartType,\n\ttype ChartX,\n\tDEFAULT_CHART_COLORS,\n} from \"./chart.js\";\nexport {\n\tClipVision,\n\ttype ClipVisionOptions,\n\ttype PersonPlacement,\n\tPersonTrack,\n\ttype PoseKeypointName,\n} from \"./clip-vision.js\";\nexport {\n\tApplyLUT,\n\ttype ApplyLUTProps,\n\tAscii,\n\ttype AsciiProps,\n\tAudioCompressor,\n\ttype AudioCompressorProps,\n\tAudioDelay,\n\ttype AudioDelayProps,\n\tAudioFade,\n\ttype AudioFadeProps,\n\tAudioNoiseGate,\n\ttype AudioNoiseGateProps,\n\tAudioParametricEq,\n\ttype AudioParametricEqProps,\n\tAudioReverb,\n\ttype AudioReverbProps,\n\tAudioSignalExtractor,\n\ttype AudioSignalExtractorProps,\n\tBlur,\n\ttype BlurProps,\n\tCameraParallax3D,\n\ttype CameraParallax3DProps,\n\tChannelMerger,\n\ttype ChannelMergerProps,\n\tChannelSplitter,\n\ttype ChannelSplitterProps,\n\tColorBalance,\n\ttype ColorBalanceProps,\n\tColorKey,\n\ttype ColorKeyProps,\n\tContour,\n\ttype ContourProps,\n\tCornerPin,\n\ttype CornerPinProps,\n\tCRT,\n\ttype CRTProps,\n\tCrop,\n\ttype CropProps,\n\tCurves,\n\ttype CurvesChannelPoint,\n\ttype CurvesProps,\n\tCustomEffect,\n\tDatamosh,\n\ttype DatamoshProps,\n\ttype DeflickerProps,\n\tDepthOfField,\n\ttype DepthOfFieldProps,\n\tDisplacementMap,\n\ttype DisplacementMapProps,\n\tDither,\n\ttype DitherProps,\n\tExtractLUT,\n\ttype ExtractLUTProps,\n\teffectFactories,\n\teffectMeta,\n\tFilmGrain,\n\ttype FilmGrainProps,\n\tFlip,\n\ttype FlipProps,\n\tGooey,\n\ttype GooeyProps,\n\tGradientMap,\n\ttype GradientMapProps,\n\ttype GradientMapStop,\n\ttype HalftoneDotShape,\n\ttype HalftoneMode,\n\tHalftoneScreen,\n\ttype HalftoneScreenProps,\n\tHighPass,\n\ttype HighPassProps,\n\tIridescence,\n\ttype IridescenceProps,\n\tKaleidoscope,\n\ttype KaleidoscopeProps,\n\tKenBurns,\n\ttype KenBurnsProps,\n\tLayerStyle,\n\ttype LayerStyleProps,\n\ttype LevelChannel,\n\tLevels,\n\ttype LevelsProps,\n\tLiquify,\n\ttype LiquifyProps,\n\tMaskMath,\n\ttype MaskMathProps,\n\tMeshWarp,\n\ttype MeshWarpProps,\n\tModulate,\n\ttype ModulateProps,\n\tMotionBlur,\n\ttype MotionBlurProps,\n\tNoiseGenerator,\n\ttype NoiseGeneratorProps,\n\tOpArt,\n\ttype OpArtProps,\n\tPaint,\n\tPainterly,\n\ttype PainterlyProps,\n\ttype PaintProps,\n\tPatchHeal,\n\ttype PatchHealProps,\n\tPBRGlass,\n\ttype PBRGlassProps,\n\tPixelate,\n\ttype PixelateProps,\n\tPosterize,\n\ttype PosterizeProps,\n\tProceduralVFX,\n\ttype ProceduralVFXProps,\n\tRefineEdge,\n\ttype RefineEdgeProps,\n\tRefractionCaustics3D,\n\ttype RefractionCaustics3DProps,\n\tRelight3D,\n\ttype Relight3DProps,\n\tResizerScaler,\n\ttype ResizerScalerProps,\n\tRGBSplit,\n\ttype RGBSplitProps,\n\tRotate,\n\ttype RotateProps,\n\tSelectiveColor,\n\ttype SelectiveColorAdjustment,\n\ttype SelectiveColorProps,\n\tShadowsHighlights,\n\ttype ShadowsHighlightsProps,\n\tSSAO,\n\ttype SSAOProps,\n\tStereoPanning,\n\ttype StereoPanningProps,\n\tTemporalDeflicker,\n\tTileOffset,\n\ttype TileOffsetEdgeMode,\n\ttype TileOffsetProps,\n\tToon,\n\ttype ToonProps,\n\tTrails,\n\ttype TrailsProps,\n\tUnsharpMask,\n\ttype UnsharpMaskProps,\n\tVignette,\n\ttype VignetteProps,\n\tVision,\n\ttype VisionProps,\n} from \"./effects/index.js\";\nexport {\n\tLighting,\n\ttype LightingRig,\n\ttype LightingRigOptions,\n} from \"./lighting.js\";\nexport {\n\ttype EmitterShape,\n\ttype ParticleBlend,\n\ttype ParticleBounds,\n\ttype ParticleShape,\n\tParticles,\n\ttype ParticlesOptions,\n} from \"./particles.js\";\nexport {\n\ttype Body2DOptions,\n\ttype Body3DOptions,\n\ttype BodyCommonOptions,\n\ttype FieldSample2D,\n\ttype FieldSample3D,\n\tPhysics,\n\ttype PhysicsBakeOptions,\n\tPhysicsBody2D,\n\tPhysicsBody3D,\n\ttype PhysicsBox3D,\n\ttype PhysicsCollision,\n\ttype PhysicsDriver,\n\ttype PhysicsGroundOptions,\n\ttype PhysicsRect,\n\ttype PhysicsRope3DOptions,\n\ttype PhysicsRopeOptions,\n\ttype PhysicsSpring3DOptions,\n\ttype PhysicsSpringOptions,\n\ttype PhysicsWallsOptions,\n\tPhysicsWorld2D,\n\tPhysicsWorld3D,\n\ttype PhysicsWorldOptions,\n\ttype World2DOptions,\n\ttype World3DOptions,\n} from \"./physics/index.js\";\nexport {\n\ttype Carousel3DOptions,\n\ttype Cube3DOptions,\n\ttype CubeFaceConfig,\n\ttype CubeFaceInput,\n\ttype Cylinder3DOptions,\n\ttype ExtrudedText3DOptions,\n\ttype Grid3DOptions,\n\tLayer3D,\n\ttype Plane3DOptions,\n\ttype Primitive3DNodeOptions,\n\ttype Prism3DOptions,\n\ttype RoundedBox3DOptions,\n\ttype Shape3DContainer,\n\ttype Sphere3DOptions,\n\ttype Surface3DOptions,\n\ttype Text3DOptions,\n} from \"./shapes3d.js\";\nexport { type StyleName, Styles } from \"./styles.js\";\nexport {\n\ttype SceneSequenceOptions,\n\ttype SequenceEntry,\n\ttype SequenceNode,\n\tTransition,\n\ttype TransitionDirection,\n\ttype TransitionSpec,\n} from \"./transitions.js\";\n\nexport interface CompositionOptions {\n\twidth: number;\n\theight: number;\n\tfps?: number;\n\tdurationMs?: number;\n\tdurationFrames?: number;\n\tbackgroundColor?: string;\n\tfonts?: string[];\n\tsignals?: Record<string, unknown>;\n\t/**\n\t * Smooth the edges of 3D meshes (extruded text, models) with 4x MSAA.\n\t * Default true; set false to save ~60-125 MB of GPU memory at 1080p.\n\t */\n\tantialias3d?: boolean;\n}\n\n/**\n * Fluent builder for single clips and chained visual/audio effect pipelines.\n */\nexport class Media {\n\tpublic readonly virtualMedia: VirtualMediaData;\n\n\tconstructor(source: MediaSourceInput, type: DataType = \"Video\") {\n\t\tthis.virtualMedia = createVirtualMedia(source, type);\n\t}\n\n\tstatic video(source: MediaSourceInput, meta?: Partial<MediaMetadata>): Media {\n\t\tconst m = new Media(source, \"Video\");\n\t\tif (meta) Object.assign(m.virtualMedia.metadata, meta);\n\t\treturn m;\n\t}\n\n\tstatic image(source: MediaSourceInput, meta?: Partial<MediaMetadata>): Media {\n\t\tconst m = new Media(source, \"Image\");\n\t\tif (meta) Object.assign(m.virtualMedia.metadata, meta);\n\t\treturn m;\n\t}\n\n\tstatic lottie(\n\t\tsource: MediaSourceInput,\n\t\tmeta?: Partial<MediaMetadata>,\n\t): Media {\n\t\tconst m = new Media(source, \"Lottie\");\n\t\tif (meta) Object.assign(m.virtualMedia.metadata, meta);\n\t\treturn m;\n\t}\n\n\tstatic audio(source: MediaSourceInput, meta?: Partial<MediaMetadata>): Media {\n\t\tconst m = new Media(source, \"Audio\");\n\t\tif (meta) Object.assign(m.virtualMedia.metadata, meta);\n\t\treturn m;\n\t}\n\n\t/**\n\t * Appends any Effect instance or shader operation onto the current media AST.\n\t */\n\tpublic apply<TProps extends object>(effect: Effect<TProps>): Media;\n\tpublic apply<\n\t\tTConfig extends Record<string, unknown> = Record<string, unknown>,\n\t>(op: string, config?: TConfig): Media;\n\tpublic apply(\n\t\teffectOrOp: Effect<object> | string,\n\t\tconfig: Record<string, unknown> = {},\n\t): Media {\n\t\tlet opPayload: Record<string, unknown>;\n\t\tif (\n\t\t\teffectOrOp instanceof Effect ||\n\t\t\t(typeof effectOrOp === \"object\" &&\n\t\t\t\teffectOrOp !== null &&\n\t\t\t\t\"op\" in effectOrOp)\n\t\t) {\n\t\t\topPayload = (effectOrOp as Effect<object>).toOperation();\n\t\t} else {\n\t\t\topPayload = {\n\t\t\t\top: effectOrOp,\n\t\t\t\t...config,\n\t\t\t};\n\t\t}\n\n\t\tconst nextVM = appendOperation(this.virtualMedia, {\n\t\t\t...opPayload,\n\t\t\tdataType: this.virtualMedia.operation.dataType,\n\t\t} as MediaOperation);\n\t\treturn new Media(nextVM);\n\t}\n\n\t/**\n\t * Returns the underlying VirtualMediaData AST node ready for rendering.\n\t */\n\tpublic toVirtualMedia(): VirtualMediaData {\n\t\treturn this.virtualMedia;\n\t}\n\n\t/**\n\t * Renders a single frame from this media pipeline to a PNG Buffer.\n\t * Can render either by timestamp in milliseconds (`atMs`) or by frame index (`frame`).\n\t */\n\tpublic async renderFrame(\n\t\toptions: {\n\t\t\tatMs?: number;\n\t\t\tframe?: number;\n\t\t\tfps?: number;\n\t\t\trenderer?: HeadlessMediaRenderer;\n\t\t} = {},\n\t): Promise<Buffer> {\n\t\tconst renderer = options.renderer ?? new HeadlessMediaRenderer();\n\t\treturn renderer.renderFrame(this.virtualMedia, options);\n\t}\n\n\tget fps(): number | undefined {\n\t\treturn this.virtualMedia.metadata?.fps ?? undefined;\n\t}\n\n\tget durationMs(): number | undefined {\n\t\treturn this.virtualMedia.metadata?.durationMs ?? undefined;\n\t}\n\n\tget width(): number | undefined {\n\t\treturn this.virtualMedia.metadata?.width ?? undefined;\n\t}\n\n\tget height(): number | undefined {\n\t\treturn this.virtualMedia.metadata?.height ?? undefined;\n\t}\n\n\t/**\n\t * Renders an image grid of sequential frames across a given frame or millisecond range.\n\t * Ideal for automated visual inspection of animation motion, easing curves, and layout stability.\n\t */\n\tpublic async renderFrameGrid(\n\t\toptions: FrameGridOptions = {},\n\t): Promise<Buffer> {\n\t\treturn renderFrameGrid(this, options);\n\t}\n\n\t/**\n\t * Renders this media pipeline into an MP4/WebM video file with audio.\n\t */\n\tpublic async renderVideo(\n\t\toutputPathOrOptions: string | RenderVideoOptions = {},\n\t\toptions: RenderVideoOptions = {},\n\t): Promise<RenderVideoResult> {\n\t\tconst opts =\n\t\t\ttypeof outputPathOrOptions === \"string\"\n\t\t\t\t? { ...options, outputPath: outputPathOrOptions }\n\t\t\t\t: outputPathOrOptions;\n\t\tconst renderer = opts.renderer ?? new HeadlessMediaRenderer();\n\t\tconst result = await renderer.renderVideo(this.virtualMedia, opts);\n\t\treturn deliverToOutputPath(result, opts.outputPath);\n\t}\n}\n\n/**\n * Copies a rendered temp file to `outputPath` and drops the temp, so the\n * returned `filePath` is where the video actually lives.\n */\nasync function deliverToOutputPath(\n\tresult: RenderVideoResult,\n\toutputPath: string | undefined,\n): Promise<RenderVideoResult> {\n\tif (!outputPath) return result;\n\tconst target = path.resolve(outputPath);\n\tawait fs.mkdir(path.dirname(target), { recursive: true });\n\tawait fs.copyFile(result.filePath, target);\n\tawait result.cleanup();\n\treturn { ...result, filePath: target, cleanup: async () => {} };\n}\n\nexport interface RenderVideoOptions {\n\tcodec?: string;\n\taudioCodec?: string;\n\tquality?: string;\n\tconcurrency?: number;\n\t/**\n\t * Depth of the DMA staging ring used to overlap GPU rendering with hardware\n\t * encoding (default 2, clamped 2–8). A deeper ring hides more encoder\n\t * latency at the cost of VRAM (~8.3MB/slot at 1080p RGBA). Also settable\n\t * via `FRAMEFIELDS_RING_CAPACITY`.\n\t */\n\tringCapacity?: number;\n\toutputPath?: string;\n\trenderer?: HeadlessMediaRenderer;\n\t/**\n\t * Check the output while it renders and return the findings as `qa`:\n\t * dropped, black or frozen frames, loudness (LUFS), clipping, silence and\n\t * document warnings such as truncated animations. `true` uses defaults;\n\t * pass thresholds (e.g. `{ targetLufs: -14 }`) to tighten them.\n\t */\n\tqa?: boolean | VideoQaOptions;\n\t/**\n\t * Stops the render between frames. The promise rejects with\n\t * `signal.reason` and no file is left behind.\n\t */\n\tsignal?: AbortSignal;\n\t/** Called as frames finish (`phase: \"render\"`), then once for the audio mix. */\n\tonProgress?: (progress: RenderProgress) => void;\n}\n\nexport interface RenderVideoResult {\n\tfilePath: string;\n\tcleanup: () => Promise<void>;\n\t/** Present when rendered with `qa`; print it with `formatQaReport` */\n\tqa?: VideoQaReport;\n}\n\nexport interface SubjectSandwichOptions {\n\treadonly source: string | MediaNode;\n\treadonly subject?: MaskTrackSignals | ObjectTrackSignals;\n\treadonly behind: readonly LayoutNode[];\n\treadonly feather?: number;\n\treadonly fit?: \"cover\" | \"contain\" | \"fill\";\n\treadonly variant?: VisionProps[\"variant\"];\n\treadonly confidence?: number;\n\treadonly keyBackground?: boolean;\n\treadonly backgroundKeyThreshold?: number;\n\treadonly muted?: boolean;\n\treadonly volume?: number;\n}\n\nexport interface SmartFramingOptions {\n\treadonly source: string | MediaNode;\n\treadonly targetAspect?: number;\n\treadonly sourceAspect?: number;\n\treadonly target: ObjectTrackSignals | MaskTrackSignals;\n\treadonly damping?: number;\n\treadonly leadHeadroom?: number;\n\treadonly fit?: \"cover\" | \"contain\" | \"fill\";\n\treadonly variant?: VisionProps[\"variant\"];\n\treadonly muted?: boolean;\n\treadonly volume?: number;\n}\n\nexport interface SubjectOutlineOptions {\n\treadonly source?: string | MediaNode;\n\treadonly color?: string;\n\treadonly width?: number;\n\treadonly blur?: number;\n\treadonly pulseSignal?: ProgrammaticSignal | Signal<number>;\n\treadonly muted?: boolean;\n\treadonly volume?: number;\n}\n\n/**\n * High-level programmatic builder for multi-layer Framefields compositions.\n */\nexport class Composition {\n\tpublic width: number;\n\tpublic height: number;\n\tpublic fps: number;\n\tpublic durationMs?: number;\n\tpublic backgroundColor: string;\n\tpublic antialias3d?: boolean;\n\tpublic fonts: string[];\n\tpublic children: LayoutNode[] = [];\n\tpublic audioTracks: MediaNode[] = [];\n\tpublic signals: Record<string, unknown> = {};\n\tprivate _frameHooks: Array<(ctx: FrameContext) => void> = [];\n\tprivate _prepareHooks: Array<(ctx: FrameContext) => Promise<void> | void> =\n\t\t[];\n\tprivate readonly _clipVision = new Map<string, ClipVision>();\n\tprivate _visionConfig?: VisionProps;\n\tprivate _visionBundle?: VisionBundle;\n\tprivate _effects: unknown[] = [];\n\n\t/**\n\t * Applies a whole-composition post-processing effect or vision pipeline.\n\t */\n\tpublic apply(effect: unknown): this {\n\t\tif (effect instanceof Vision) {\n\t\t\tthis.withVision(effect);\n\t\t\treturn this;\n\t\t}\n\t\tthis._effects.push(effect);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Runs vision on the whole composition — the rendered frame (composition, blur, crop,\n\t * anything upstream) is the inference input. Models are LAZY: nothing downloads until\n\t * the first frame actually runs a task.\n\t * Returns the reactive VisionBundle (objects / masks / pose / classes signals).\n\t */\n\tpublic withVision(config: VisionProps | Vision = {}): VisionBundle {\n\t\tthis._visionBundle ??= new VisionBundle({\n\t\t\twidth: this.width,\n\t\t\theight: this.height,\n\t\t\tfps: this.fps,\n\t\t});\n\t\tconst rawConfig =\n\t\t\tconfig instanceof Vision ? (config.config as VisionProps) : config;\n\t\tthis._visionConfig = {\n\t\t\t...rawConfig,\n\t\t\tvisionBundle: this._visionBundle,\n\t\t};\n\t\treturn this._visionBundle;\n\t}\n\n\t/**\n\t * Vision for a clip, analysed per frame on demand and shared by everything\n\t * that reads it (see {@link ClipVision}): `comp.vision(\"dancer.mp4\").person`\n\t * gives pose keypoints and a silhouette at any frame. Each frame is\n\t * analysed just before it renders, so nothing runs up front. Results\n\t * persist on disk in Node. The same clip and options return one instance.\n\t */\n\tpublic vision(source: string, options: ClipVisionOptions = {}): ClipVision {\n\t\tconst key = `${source}\\u0000${JSON.stringify(options)}`;\n\t\tlet clip = this._clipVision.get(key);\n\t\tif (!clip) {\n\t\t\tclip = new ClipVision(source, this.fps, options);\n\t\t\tthis._clipVision.set(key, clip);\n\t\t}\n\t\treturn clip;\n\t}\n\n\t/**\n\t * @internal Analyses every `comp.vision` clip up to a composition frame\n\t * (frames already analysed are skipped), so consumers that step frame by\n\t * frame — physics, particles — always find every frame before it.\n\t */\n\tpublic async prepareVision(frame: number): Promise<void> {\n\t\tthis.linkClipMattes();\n\t\tawait Promise.all(\n\t\t\t[...this._clipVision.values()].map((clip) => clip.ready(0, frame)),\n\t\t);\n\t}\n\n\t/**\n\t * Points matte-family `withVision` layers at the `comp.vision` clip they\n\t * show, so the cutout reuses that clip's per-frame subject instead of\n\t * segmenting the frame again during render. Only layers whose settings\n\t * would give the same subject are linked; the rest keep their own pass.\n\t */\n\tprivate linkClipMattes(): void {\n\t\tif (this._clipVision.size === 0) return;\n\t\tconst walk = (node: unknown): void => {\n\t\t\tif (!node || typeof node !== \"object\") return;\n\t\t\tconst n = node as {\n\t\t\t\tkind?: string;\n\t\t\t\tdataType?: string;\n\t\t\t\tinputHandleId?: unknown;\n\t\t\t\tvision?: unknown;\n\t\t\t\tchildren?: unknown;\n\t\t\t};\n\t\t\tif (\n\t\t\t\tn.kind === \"media\" &&\n\t\t\t\tn.dataType === \"Video\" &&\n\t\t\t\ttypeof n.inputHandleId === \"string\" &&\n\t\t\t\tn.vision instanceof Vision &&\n\t\t\t\t!(CLIP_SUBJECT in n.vision)\n\t\t\t) {\n\t\t\t\tconst clip = this.clipForMatte(n.inputHandleId, n.vision);\n\t\t\t\tif (clip) {\n\t\t\t\t\tclip.keepSubjects();\n\t\t\t\t\tObject.defineProperty(n.vision, CLIP_SUBJECT, {\n\t\t\t\t\t\tvalue: clip,\n\t\t\t\t\t\tenumerable: false,\n\t\t\t\t\t\tconfigurable: true,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (Array.isArray(n.children)) for (const c of n.children) walk(c);\n\t\t};\n\t\tfor (const child of this.children) walk(child);\n\t}\n\n\tprivate clipForMatte(source: string, v: Vision): ClipVision | undefined {\n\t\tconst mode = v.mode ?? \"passthrough\";\n\t\tif (mode !== \"matte\" && mode !== \"mask\" && mode !== \"crop\") return;\n\t\t// Anything that changes the subject, or needs results the clip lacks.\n\t\tif (\n\t\t\tv.matteSource === \"selfie\" ||\n\t\t\tv.keyBackground === true ||\n\t\t\tv.classes !== undefined ||\n\t\t\tv.enablePose === true ||\n\t\t\tv.enableMatte === true ||\n\t\t\tv.visionBundle !== undefined ||\n\t\t\t(v.maskThreshold ?? 0.5) !== 0.5 ||\n\t\t\tv.featherRadius !== undefined\n\t\t) {\n\t\t\treturn;\n\t\t}\n\t\tfor (const clip of this._clipVision.values()) {\n\t\t\tconst o = clip.options;\n\t\t\tif (\n\t\t\t\tclip.source === source &&\n\t\t\t\t(o.variant ?? \"s\") === (v.variant ?? \"s\") &&\n\t\t\t\t(o.confidence ?? 0.3) === (v.confidence ?? 0.3)\n\t\t\t) {\n\t\t\t\treturn clip;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * One-shot, ffmpeg-free vision analysis of a media source.\n\t *\n\t * Decodes frames through the same mediabunny pipeline the renderer uses, runs the requested\n\t * tasks lazily (only those models download), temporally tracks detections, and returns a\n\t * zod-serializable report. The decoder is released and the runner closed on completion.\n\t */\n\tpublic async analyzeVisionSequence(\n\t\tsource: string,\n\t\toptions: {\n\t\t\ttasks?: readonly VisionTask[];\n\t\t\tcategories?: readonly string[];\n\t\t\tfps?: number;\n\t\t\ttotalFrames?: number;\n\t\t\tpathStride?: number;\n\t\t\tincludeMasks?: boolean;\n\t\t\tmodelsDir?: string;\n\t\t\tbaseUrl?: string;\n\t\t\tconfidence?: number;\n\t\t\tvariant?: VisionProps[\"variant\"];\n\t\t\t/** Tracker box-association IoU. Default 0.25. */\n\t\t\tiouThreshold?: number;\n\t\t} = {},\n\t): Promise<VisionAnalysisReport> {\n\t\tconst fps = options.fps ?? this.fps;\n\t\tconst durationMs = this.durationMs ?? (await this.computeDuration());\n\t\tconst totalFrames =\n\t\t\toptions.totalFrames ?? Math.max(1, Math.round((durationMs / 1000) * fps));\n\n\t\tconst runner = VisionRunner.create({\n\t\t\tmodelsDir: options.modelsDir,\n\t\t\tbaseUrl: options.baseUrl,\n\t\t\t...(options.confidence !== undefined\n\t\t\t\t? { confidence: options.confidence }\n\t\t\t\t: {}),\n\t\t\t...(options.variant !== undefined ? { variant: options.variant } : {}),\n\t\t});\n\n\t\tconst decoder = mediaDecoderCache.getVideo(source, true);\n\t\tasync function* frameSource(): AsyncGenerator<{\n\t\t\tdata: Uint8Array;\n\t\t\twidth: number;\n\t\t\theight: number;\n\t\t}> {\n\t\t\tfor (let i = 0; i < totalFrames; i++) {\n\t\t\t\tconst frame = await decoder.getFrame(i / fps);\n\t\t\t\tif (frame?.buffer && frame.width > 0 && frame.height > 0) {\n\t\t\t\t\tyield {\n\t\t\t\t\t\tdata: frame.buffer,\n\t\t\t\t\t\twidth: frame.width,\n\t\t\t\t\t\theight: frame.height,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\treturn await analyzeVisionFrames(frameSource(), {\n\t\t\t\trunner,\n\t\t\t\tsource,\n\t\t\t\tfps,\n\t\t\t\t...(options.tasks !== undefined ? { tasks: options.tasks } : {}),\n\t\t\t\t...(options.categories !== undefined\n\t\t\t\t\t? { categories: options.categories }\n\t\t\t\t\t: {}),\n\t\t\t\t...(options.pathStride !== undefined\n\t\t\t\t\t? { pathStride: options.pathStride }\n\t\t\t\t\t: {}),\n\t\t\t\t...(options.includeMasks !== undefined\n\t\t\t\t\t? { includeMasks: options.includeMasks }\n\t\t\t\t\t: {}),\n\t\t\t\t...(options.iouThreshold !== undefined\n\t\t\t\t\t? { iouThreshold: options.iouThreshold }\n\t\t\t\t\t: {}),\n\t\t\t});\n\t\t} finally {\n\t\t\trunner.close();\n\t\t\tdecoder.destroy();\n\t\t}\n\t}\n\n\t/**\n\t * Game-engine per-frame lifecycle hook for the composition.\n\t * Invoked before rendering each frame so scripts or agents can mutate properties and signals.\n\t */\n\tpublic onRequestFrame(callback: (ctx: FrameContext) => void): this {\n\t\tthis._frameHooks.push(callback);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Async work a frame needs before it is evaluated (vision, a live physics\n\t * world). Every render path awaits these, in order, before drawing the\n\t * frame; they may run more than once per frame, so keep them idempotent.\n\t */\n\tpublic onPrepareFrame(\n\t\tcallback: (ctx: FrameContext) => Promise<void> | void,\n\t): this {\n\t\tthis._prepareHooks.push(callback);\n\t\treturn this;\n\t}\n\n\tpublic notifyFrame(ctx: FrameContext): Promise<void> | undefined {\n\t\tfor (const hook of this._frameHooks) {\n\t\t\thook(ctx);\n\t\t}\n\t\tif (this._clipVision.size === 0 && this._prepareHooks.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn (async () => {\n\t\t\tawait this.prepareVision(ctx.frame);\n\t\t\tfor (const hook of this._prepareHooks) await hook(ctx);\n\t\t})();\n\t}\n\n\tprivate hasFrameHooks(): boolean {\n\t\treturn (\n\t\t\tthis._frameHooks.length > 0 ||\n\t\t\tthis._prepareHooks.length > 0 ||\n\t\t\tthis._clipVision.size > 0\n\t\t);\n\t}\n\n\tconstructor(options: CompositionOptions) {\n\t\tthis.width = options.width;\n\t\tthis.height = options.height;\n\t\tthis.fps = options.fps ?? 60;\n\t\tthis.durationMs =\n\t\t\toptions.durationMs ??\n\t\t\t(options.durationFrames !== undefined\n\t\t\t\t? (options.durationFrames / this.fps) * 1000\n\t\t\t\t: undefined);\n\t\tthis.backgroundColor = options.backgroundColor ?? \"#000000\";\n\t\tthis.antialias3d = options.antialias3d;\n\t\tthis.fonts = options.fonts ?? [];\n\t\tthis.signals = options.signals ?? {};\n\t}\n\n\tpublic static create(options: CompositionOptions): Composition {\n\t\treturn new Composition(options);\n\t}\n\n\tpublic addSignal(name: string, signal: unknown): this {\n\t\tthis.signals[name] = signal;\n\t\treturn this;\n\t}\n\n\tpublic add(\n\t\tlayerOrFirst:\n\t\t\t| LayoutNode\n\t\t\t| LayoutNode[]\n\t\t\t| TensorPipeline\n\t\t\t| VisionNode\n\t\t\t| { node: unknown },\n\t\t...rest: Array<\n\t\t\t| LayoutNode\n\t\t\t| LayoutNode[]\n\t\t\t| TensorPipeline\n\t\t\t| VisionNode\n\t\t\t| { node: unknown }\n\t\t\t| LayerAnimation\n\t\t\t| { tracks: AnimationTrack[] }\n\t\t>\n\t): this {\n\t\tif (layerOrFirst instanceof TensorPipeline) {\n\t\t\tthis.children.push(layerOrFirst.toNode() as unknown as LayoutNode);\n\t\t} else if (layerOrFirst instanceof VisionNode) {\n\t\t\tthis.children.push(layerOrFirst.toNode() as unknown as LayoutNode);\n\t\t} else if (\n\t\t\tlayerOrFirst &&\n\t\t\ttypeof layerOrFirst === \"object\" &&\n\t\t\t\"node\" in layerOrFirst\n\t\t) {\n\t\t\tthis.add(\n\t\t\t\t(\n\t\t\t\t\tlayerOrFirst as {\n\t\t\t\t\t\tnode: LayoutNode | TensorPipeline | { node: unknown };\n\t\t\t\t\t}\n\t\t\t\t).node as LayoutNode,\n\t\t\t\t...rest,\n\t\t\t);\n\t\t\treturn this;\n\t\t} else if (Array.isArray(layerOrFirst)) {\n\t\t\tfor (const l of layerOrFirst) {\n\t\t\t\tthis.add(l);\n\t\t\t}\n\t\t} else {\n\t\t\tconst targetNode = layerOrFirst as LayoutNode;\n\t\t\tconst animCandidate = rest[0];\n\t\t\tif (\n\t\t\t\tanimCandidate &&\n\t\t\t\t!(animCandidate instanceof TensorPipeline) &&\n\t\t\t\t!Array.isArray(animCandidate) &&\n\t\t\t\t(animCandidate instanceof LayerAnimation || \"tracks\" in animCandidate)\n\t\t\t) {\n\t\t\t\ttargetNode.animation =\n\t\t\t\t\tanimCandidate instanceof LayerAnimation\n\t\t\t\t\t\t? animCandidate.toSpec()\n\t\t\t\t\t\t: animCandidate;\n\t\t\t\tthis.children.push(targetNode);\n\t\t\t\treturn this;\n\t\t\t}\n\t\t\tthis.children.push(targetNode);\n\t\t}\n\n\t\tfor (const item of rest) {\n\t\t\tif (item && !(item instanceof LayerAnimation) && !(\"tracks\" in item)) {\n\t\t\t\tthis.add(\n\t\t\t\t\titem as\n\t\t\t\t\t\t| LayoutNode\n\t\t\t\t\t\t| LayoutNode[]\n\t\t\t\t\t\t| TensorPipeline\n\t\t\t\t\t\t| { node: unknown },\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tpublic addAudio(track: MediaNode): this {\n\t\tthis.audioTracks.push(track);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Turnkey \"Text Behind Subject\" (\"Sandwich\") Primitive.\n\t * Lowers into:\n\t * 1. Bottom Layer: Full background video plate\n\t * 2. Middle Layer: User-supplied `behind` nodes\n\t * 3. Top Layer: Subject cutout video with continuous matte alpha registered at identical coordinates\n\t */\n\tpublic addSubjectSandwich(options: SubjectSandwichOptions): this {\n\t\tconst src =\n\t\t\ttypeof options.source === \"string\"\n\t\t\t\t? options.source\n\t\t\t\t: (options.source.inputHandleId ?? \"\");\n\t\tconst fit = options.fit ?? \"cover\";\n\t\tconst feather = options.feather ?? 4;\n\t\tconst featherVal = feather > 1 ? feather / 100 : feather;\n\t\tconst variant = options.variant ?? \"s\";\n\n\t\t// 1. Bottom Layer: Full background video plate\n\t\tconst bottomPlate = Layer.video(src, {\n\t\t\twidth: this.width,\n\t\t\theight: this.height,\n\t\t\tposition: \"absolute\",\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\tfit,\n\t\t\tmuted: options.muted ?? false,\n\t\t\tvolume: options.muted ? 0 : (options.volume ?? 1),\n\t\t});\n\t\tthis.add(bottomPlate);\n\n\t\t// 2. Middle Layer: User-supplied `behind` nodes\n\t\tfor (const node of options.behind) {\n\t\t\tthis.add(node);\n\t\t}\n\n\t\t// 3. Top Layer: Subject cutout video with continuous matte alpha registered at identical coordinates\n\t\tconst topPlate = Layer.video(src, {\n\t\t\twidth: this.width,\n\t\t\theight: this.height,\n\t\t\tposition: \"absolute\",\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\tfit,\n\t\t\tmuted: true,\n\t\t\tvolume: 0,\n\t\t}).withVision({\n\t\t\tmode: \"matte\",\n\t\t\tenableSegmentation: true,\n\t\t\tvariant,\n\t\t\tconfidence: options.confidence ?? 0.25,\n\t\t\tfeatherRadius: featherVal,\n\t\t\tkeyBackground: options.keyBackground ?? true,\n\t\t\tbackgroundKeyThreshold: options.backgroundKeyThreshold,\n\t\t});\n\t\tthis.add(topPlate);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Dynamic Smart Re-Framing (16:9 → 9:16 Auto-Crop).\n\t * Automatically transforms landscape footage into vertical shorts/reels by framing the\n\t * tracked subject with smooth camera physics and lead headroom.\n\t */\n\tpublic addSmartFraming(options: SmartFramingOptions): this {\n\t\tconst src =\n\t\t\ttypeof options.source === \"string\"\n\t\t\t\t? options.source\n\t\t\t\t: (options.source.inputHandleId ?? \"\");\n\t\tconst damping = Math.max(0, Math.min(0.99, options.damping ?? 0.8));\n\t\tconst headroom = options.leadHeadroom ?? 0.18;\n\t\tconst compW = this.width;\n\t\tconst compH = this.height;\n\n\t\tconst sourceAspect = options.sourceAspect ?? 16 / 9;\n\t\tconst compAspect = compW / compH;\n\n\t\t// Calculate canvas coverage dimensions to avoid black bars during pan\n\t\tconst plateWidth =\n\t\t\tcompAspect < sourceAspect ? Math.round(compH * sourceAspect) : compW;\n\t\tconst plateHeight =\n\t\t\tcompAspect < sourceAspect ? compH : Math.round(compW / sourceAspect);\n\n\t\tconst minOffsetX = compW - plateWidth; // <= 0\n\t\tconst minOffsetY = compH - plateHeight; // <= 0\n\n\t\tconst targetObj = options.target as unknown as {\n\t\t\tcenter?: {\n\t\t\t\tx?: ProgrammaticSignal;\n\t\t\t\ty?: ProgrammaticSignal;\n\t\t\t\tscreenX?: ProgrammaticSignal;\n\t\t\t\tscreenY?: ProgrammaticSignal;\n\t\t\t};\n\t\t\tbounds?: {\n\t\t\t\tx?: ProgrammaticSignal;\n\t\t\t\ty?: ProgrammaticSignal;\n\t\t\t\twidth?: ProgrammaticSignal;\n\t\t\t\theight?: ProgrammaticSignal;\n\t\t\t\tcenterX?: ProgrammaticSignal;\n\t\t\t\tcenterY?: ProgrammaticSignal;\n\t\t\t};\n\t\t};\n\n\t\tconst rawOffsetX = new ProgrammaticSignal(\n\t\t\t(ctx) => {\n\t\t\t\tif (minOffsetX >= 0) return 0;\n\t\t\t\tconst normX = targetObj.center?.x\n\t\t\t\t\t? targetObj.center.x.get(ctx)\n\t\t\t\t\t: targetObj.bounds?.centerX\n\t\t\t\t\t\t? targetObj.bounds.centerX.get(ctx) / compW\n\t\t\t\t\t\t: targetObj.center?.screenX\n\t\t\t\t\t\t\t? targetObj.center.screenX.get(ctx) / compW\n\t\t\t\t\t\t\t: 0.5;\n\t\t\t\tconst clampedNormX = Math.max(0, Math.min(1, normX));\n\t\t\t\tconst targetPx = clampedNormX * plateWidth;\n\t\t\t\tconst desired = compW / 2 - targetPx;\n\t\t\t\treturn Math.max(minOffsetX, Math.min(0, desired));\n\t\t\t},\n\t\t\t{ fps: this.fps, label: \"smart_framing_pan_x\" },\n\t\t);\n\n\t\tconst rawOffsetY = new ProgrammaticSignal(\n\t\t\t(ctx) => {\n\t\t\t\tif (minOffsetY >= 0) return 0;\n\t\t\t\tconst normY = targetObj.center?.y\n\t\t\t\t\t? targetObj.center.y.get(ctx)\n\t\t\t\t\t: targetObj.bounds?.centerY\n\t\t\t\t\t\t? targetObj.bounds.centerY.get(ctx) / compH\n\t\t\t\t\t\t: targetObj.center?.screenY\n\t\t\t\t\t\t\t? targetObj.center.screenY.get(ctx) / compH\n\t\t\t\t\t\t\t: 0.5;\n\t\t\t\tconst clampedNormY = Math.max(0, Math.min(1, normY));\n\t\t\t\tconst targetPy = clampedNormY * plateHeight;\n\t\t\t\tconst desired = compH * headroom - targetPy;\n\t\t\t\treturn Math.max(minOffsetY, Math.min(0, desired));\n\t\t\t},\n\t\t\t{ fps: this.fps, label: \"smart_framing_pan_y\" },\n\t\t);\n\n\t\t// Damped camera smoothing\n\t\tconst smoothOffsetX = new ProgrammaticSignal(\n\t\t\t(ctx) => {\n\t\t\t\tconst targetFrame = ctx.frame;\n\t\t\t\tif (targetFrame <= 0) return rawOffsetX.get(ctx);\n\t\t\t\tlet filtered = rawOffsetX.get({ ...ctx, frame: 0, time: 0 });\n\t\t\t\tconst alpha = 1.0 - damping;\n\t\t\t\tfor (let f = 1; f <= targetFrame; f++) {\n\t\t\t\t\tconst val = rawOffsetX.get({ ...ctx, frame: f, time: f / ctx.fps });\n\t\t\t\t\tfiltered = filtered + alpha * (val - filtered);\n\t\t\t\t}\n\t\t\t\treturn filtered;\n\t\t\t},\n\t\t\t{ fps: this.fps, label: \"smart_framing_smooth_x\" },\n\t\t);\n\n\t\tconst smoothOffsetY = new ProgrammaticSignal(\n\t\t\t(ctx) => {\n\t\t\t\tconst targetFrame = ctx.frame;\n\t\t\t\tif (targetFrame <= 0) return rawOffsetY.get(ctx);\n\t\t\t\tlet filtered = rawOffsetY.get({ ...ctx, frame: 0, time: 0 });\n\t\t\t\tconst alpha = 1.0 - damping;\n\t\t\t\tfor (let f = 1; f <= targetFrame; f++) {\n\t\t\t\t\tconst val = rawOffsetY.get({ ...ctx, frame: f, time: f / ctx.fps });\n\t\t\t\t\tfiltered = filtered + alpha * (val - filtered);\n\t\t\t\t}\n\t\t\t\treturn filtered;\n\t\t\t},\n\t\t\t{ fps: this.fps, label: \"smart_framing_smooth_y\" },\n\t\t);\n\n\t\tconst container = Layer.box({\n\t\t\twidth: compW,\n\t\t\theight: compH,\n\t\t\toverflow: \"hidden\",\n\t\t\tposition: \"relative\",\n\t\t});\n\n\t\tconst videoPlate = Layer.video(src, {\n\t\t\twidth: plateWidth,\n\t\t\theight: plateHeight,\n\t\t\tposition: \"absolute\",\n\t\t\tx: smoothOffsetX as unknown as number,\n\t\t\ty: smoothOffsetY as unknown as number,\n\t\t\tfit: options.fit ?? \"cover\",\n\t\t\tmuted: options.muted ?? false,\n\t\t\tvolume: options.muted ? 0 : (options.volume ?? 1),\n\t\t});\n\n\t\tif (!container.children) {\n\t\t\tcontainer.children = [];\n\t\t}\n\t\tcontainer.children.push(videoPlate);\n\t\tthis.add(container);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Subject Contour Glow & Neon Outline.\n\t * Strokes the silhouette boundary with a stylized bloom/glow and optional audio-reactive pulse.\n\t */\n\tpublic addSubjectOutline(\n\t\t_subject: MaskTrackSignals | ObjectTrackSignals,\n\t\toptions: SubjectOutlineOptions = {},\n\t): this {\n\t\tconst blur = options.blur ?? 12;\n\t\tconst compW = this.width;\n\t\tconst compH = this.height;\n\n\t\tconst pulse = options.pulseSignal;\n\t\tconst baseOpacity = pulse\n\t\t\t? new ProgrammaticSignal(\n\t\t\t\t\t(ctx) => Math.max(0, Math.min(1, Number(pulse.get(ctx)) || 0)),\n\t\t\t\t\t{ fps: this.fps, label: \"outline_pulse\" },\n\t\t\t\t)\n\t\t\t: 1.0;\n\n\t\tconst src =\n\t\t\ttypeof options.source === \"string\"\n\t\t\t\t? options.source\n\t\t\t\t: (options.source?.inputHandleId ?? \"\");\n\n\t\tconst outlineLayer = Layer.box({\n\t\t\twidth: compW,\n\t\t\theight: compH,\n\t\t\tposition: \"absolute\",\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\topacity: baseOpacity as unknown as number,\n\t\t});\n\n\t\tif (src) {\n\t\t\tconst maskVideo = Layer.video(src, {\n\t\t\t\twidth: compW,\n\t\t\t\theight: compH,\n\t\t\t\tposition: \"absolute\",\n\t\t\t\tx: 0,\n\t\t\t\ty: 0,\n\t\t\t\tfit: \"cover\",\n\t\t\t\tmuted: true,\n\t\t\t\tvolume: 0,\n\t\t\t}).withVision({\n\t\t\t\tmode: \"mask\",\n\t\t\t\tenableSegmentation: true,\n\t\t\t});\n\t\t\tif (!outlineLayer.children) {\n\t\t\t\toutlineLayer.children = [];\n\t\t\t}\n\t\t\toutlineLayer.children.push(maskVideo);\n\t\t}\n\n\t\toutlineLayer.apply(\n\t\t\tnew Blur({\n\t\t\t\tstrength: blur,\n\t\t\t\tblurType: \"Gaussian\",\n\t\t\t}),\n\t\t);\n\n\t\tthis.add(outlineLayer);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Creates an isolated, styled section of the composition or underlying source plate.\n\t * Any WebGPU effects (Blur, FilmGrain, Curves, Vignette, etc.) can be applied to this section.\n\t */\n\tpublic section(\n\t\tsourceOrTargetOrOptions?:\n\t\t\t| string\n\t\t\t| MediaNode\n\t\t\t| ObjectTrackSignals\n\t\t\t| SectionOptions,\n\t\ttargetOrOptions?: ObjectTrackSignals | SectionOptions,\n\t\toptions?: SectionOptions,\n\t): SectionNode {\n\t\tlet source: string | MediaNode | undefined;\n\t\tlet target: ObjectTrackSignals | undefined;\n\t\tlet opts: SectionOptions = {};\n\n\t\tconst isFirstTrack =\n\t\t\tsourceOrTargetOrOptions !== null &&\n\t\t\ttypeof sourceOrTargetOrOptions === \"object\" &&\n\t\t\t\"bounds\" in sourceOrTargetOrOptions;\n\n\t\tconst isFirstMedia =\n\t\t\ttypeof sourceOrTargetOrOptions === \"string\" ||\n\t\t\t(sourceOrTargetOrOptions !== null &&\n\t\t\t\ttypeof sourceOrTargetOrOptions === \"object\" &&\n\t\t\t\t(\"kind\" in sourceOrTargetOrOptions ||\n\t\t\t\t\t\"src\" in sourceOrTargetOrOptions ||\n\t\t\t\t\t\"inputHandleId\" in sourceOrTargetOrOptions));\n\n\t\tif (\n\t\t\tisFirstMedia &&\n\t\t\ttargetOrOptions &&\n\t\t\ttypeof targetOrOptions === \"object\" &&\n\t\t\t\"bounds\" in targetOrOptions\n\t\t) {\n\t\t\tsource = sourceOrTargetOrOptions as string | MediaNode;\n\t\t\ttarget = targetOrOptions as ObjectTrackSignals;\n\t\t\topts = options ?? {};\n\t\t} else if (isFirstMedia && targetOrOptions) {\n\t\t\tsource = sourceOrTargetOrOptions as string | MediaNode;\n\t\t\topts = targetOrOptions as SectionOptions;\n\t\t} else if (isFirstTrack) {\n\t\t\ttarget = sourceOrTargetOrOptions as ObjectTrackSignals;\n\t\t\topts = (targetOrOptions as SectionOptions) ?? {};\n\t\t\tsource = opts.source ?? (target.source as string | MediaNode | undefined);\n\t\t} else if (\n\t\t\tsourceOrTargetOrOptions &&\n\t\t\ttypeof sourceOrTargetOrOptions === \"object\"\n\t\t) {\n\t\t\topts = sourceOrTargetOrOptions as SectionOptions;\n\t\t\tsource = opts.source;\n\t\t}\n\n\t\tif (!source) {\n\t\t\tconst mediaChild = this.children.find(\n\t\t\t\t(c) =>\n\t\t\t\t\tc.kind === \"media\" &&\n\t\t\t\t\t(c.dataType === \"Video\" || c.dataType === \"Image\"),\n\t\t\t) as MediaNode | undefined;\n\t\t\tif (mediaChild) {\n\t\t\t\tsource = mediaChild;\n\t\t\t}\n\t\t}\n\n\t\treturn Layer.section(source ?? \"\", target ?? opts, {\n\t\t\tcompositionWidth: this.width,\n\t\t\tcompositionHeight: this.height,\n\t\t\t...opts,\n\t\t});\n\t}\n\n\t/**\n\t * Creates a section and immediately adds it to the composition layout tree.\n\t */\n\tpublic addSection(\n\t\tsourceOrTargetOrOptions?:\n\t\t\t| string\n\t\t\t| MediaNode\n\t\t\t| ObjectTrackSignals\n\t\t\t| SectionOptions,\n\t\ttargetOrOptions?: ObjectTrackSignals | SectionOptions,\n\t\toptions?: SectionOptions,\n\t): SectionNode {\n\t\tconst node = this.section(\n\t\t\tsourceOrTargetOrOptions,\n\t\t\ttargetOrOptions,\n\t\t\toptions,\n\t\t);\n\t\tthis.add(node);\n\t\treturn node;\n\t}\n\n\t/**\n\t * Dynamically calculates composition duration from the longest media or animation layer.\n\t */\n\tpublic async computeDuration(): Promise<number> {\n\t\tif (this.durationMs !== undefined) return this.durationMs;\n\t\tlet maxDurationMs = 0;\n\t\tconst mediaSources: string[] = [];\n\n\t\tfor (const node of [...this.children, ...this.audioTracks]) {\n\t\t\tif (node.kind === \"media\") {\n\t\t\t\tconst src = node.inputHandleId;\n\t\t\t\tif (\n\t\t\t\t\ttypeof src === \"string\" &&\n\t\t\t\t\t(node.dataType === \"Video\" || node.dataType === \"Audio\")\n\t\t\t\t) {\n\t\t\t\t\tmediaSources.push(src);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (typeof node.durationFrames === \"number\") {\n\t\t\t\tconst start = typeof node.startFrame === \"number\" ? node.startFrame : 0;\n\t\t\t\tconst durMs = ((start + node.durationFrames) / this.fps) * 1000;\n\t\t\t\tif (durMs > maxDurationMs) maxDurationMs = durMs;\n\t\t\t}\n\t\t}\n\n\t\tfor (const src of mediaSources) {\n\t\t\ttry {\n\t\t\t\tconst input = await inputStore.acquire(src);\n\t\t\t\tconst sec = await input.computeDuration();\n\t\t\t\tif (Number.isFinite(sec) && sec > 0) {\n\t\t\t\t\tconst ms = Math.round(sec * 1000);\n\t\t\t\t\tif (ms > maxDurationMs) maxDurationMs = ms;\n\t\t\t\t}\n\t\t\t} catch (_) {}\n\t\t}\n\n\t\treturn maxDurationMs > 0 ? maxDurationMs : 5000;\n\t}\n\n\tpublic async registerFont(\n\t\toptionsOrFamilyOrSource: RegisterFontOptions | string,\n\t\tsource?: string | Uint8Array,\n\t): Promise<this> {\n\t\tconst reg = await FontManager.register(optionsOrFamilyOrSource, source);\n\t\tif (reg.filePath && !this.fonts.includes(reg.filePath)) {\n\t\t\tthis.fonts.push(reg.filePath);\n\t\t}\n\t\treturn this;\n\t}\n\n\t/** Sets the color emoji font; see {@link FontManager.registerEmojiFont}. */\n\tpublic async registerEmojiFont(source: string | Uint8Array): Promise<this> {\n\t\tawait FontManager.registerEmojiFont(source);\n\t\treturn this;\n\t}\n\n\tpublic toSpec(): CompositorProgramConfig {\n\t\tconst layoutItems: LayoutNode[] = [...this.children, ...this.audioTracks];\n\t\tconst registeredPaths = FontManager.getRegisteredFontPaths();\n\t\tconst mergedFonts = Array.from(\n\t\t\tnew Set([...this.fonts, ...registeredPaths]),\n\t\t);\n\t\treturn {\n\t\t\twidth: this.width,\n\t\t\theight: this.height,\n\t\t\tfps: this.fps,\n\t\t\tmode: \"Video\",\n\t\t\tbackgroundColor: this.backgroundColor,\n\t\t\t...(this.antialias3d !== undefined && { antialias3d: this.antialias3d }),\n\t\t\tlayout: layoutItems,\n\t\t\tfonts: mergedFonts,\n\t\t\tsignals: this.signals,\n\t\t\t...(this._effects.length > 0 && { effects: this._effects }),\n\t\t\t...(this._visionConfig && { vision: this._visionConfig }),\n\t\t\t...(this.hasFrameHooks() && {\n\t\t\t\tonRequestFrame: (ctx: FrameContext) => this.notifyFrame(ctx),\n\t\t\t}),\n\t\t} as unknown as CompositorProgramConfig;\n\t}\n\n\t/**\n\t * Compiles the composition into a VirtualMediaData AST ready for WebGPU rendering.\n\t */\n\tpublic toVirtualMedia(\n\t\toptions: Partial<CompositorToProgramOptions> = {},\n\t): VirtualMediaData {\n\t\treturn compositorToProgram(this.toSpec(), {\n\t\t\tisVideoMode: true,\n\t\t\tfps: this.fps,\n\t\t\tdurationMs: options.durationMs ?? this.durationMs,\n\t\t\tsignals: options.signals ?? this.signals,\n\t\t\t...(this._effects.length > 0 && { effects: this._effects }),\n\t\t\t...(this._visionConfig && { vision: this._visionConfig }),\n\t\t\t...options,\n\t\t});\n\t}\n\n\t/**\n\t * Compiles the composition into a VirtualMediaData AST with dynamically resolved duration.\n\t */\n\tpublic async toVirtualMediaAsync(\n\t\toptions: Partial<CompositorToProgramOptions> = {},\n\t): Promise<VirtualMediaData> {\n\t\tconst durationMs =\n\t\t\toptions.durationMs ?? this.durationMs ?? (await this.computeDuration());\n\t\tthis.durationMs = durationMs;\n\t\treturn compositorToProgram(this.toSpec(), {\n\t\t\tisVideoMode: true,\n\t\t\tfps: this.fps,\n\t\t\tdurationMs,\n\t\t\tsignals: options.signals ?? this.signals,\n\t\t\t...(this._effects.length > 0 && { effects: this._effects }),\n\t\t\t...(this._visionConfig && { vision: this._visionConfig }),\n\t\t\t...options,\n\t\t});\n\t}\n\n\t/**\n\t * Renders a single frame from the composition to a PNG Buffer.\n\t * Can render either by timestamp in milliseconds (`atMs`) or by frame index (`frame`).\n\t */\n\tpublic async renderFrame(\n\t\toptions: {\n\t\t\tatMs?: number;\n\t\t\tframe?: number;\n\t\t\trenderer?: HeadlessMediaRenderer;\n\t\t} = {},\n\t): Promise<Buffer> {\n\t\tif (this.hasFrameHooks()) {\n\t\t\tconst targetFrame =\n\t\t\t\toptions.frame ??\n\t\t\t\t(options.atMs !== undefined\n\t\t\t\t\t? Math.round((options.atMs / 1000) * this.fps)\n\t\t\t\t\t: 0);\n\t\t\tawait this.notifyFrame({\n\t\t\t\tframe: targetFrame,\n\t\t\t\tfps: this.fps,\n\t\t\t\ttime: this.fps > 0 ? targetFrame / this.fps : 0,\n\t\t\t\tduration: (this.durationMs ?? 0) / 1000,\n\t\t\t\tdurationMs: this.durationMs ?? 0,\n\t\t\t\tprogress:\n\t\t\t\t\tthis.durationMs && this.durationMs > 0\n\t\t\t\t\t\t? Math.max(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tMath.min(\n\t\t\t\t\t\t\t\t\t1,\n\t\t\t\t\t\t\t\t\t((targetFrame / this.fps) * 1000) / this.durationMs,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: 0,\n\t\t\t\tdeltaTime: this.fps > 0 ? 1 / this.fps : 0,\n\t\t\t});\n\t\t}\n\t\tconst renderer = options.renderer ?? new HeadlessMediaRenderer();\n\t\treturn renderer.renderFrame(this.toVirtualMedia(), {\n\t\t\tfps: this.fps,\n\t\t\t...options,\n\t\t});\n\t}\n\n\t/**\n\t * Renders an image grid of sequential frames across a given frame or millisecond range.\n\t * Ideal for automated visual inspection of animation motion, easing curves, and layout stability.\n\t */\n\tpublic async renderFrameGrid(\n\t\toptions: FrameGridOptions = {},\n\t): Promise<Buffer> {\n\t\treturn renderFrameGrid(this, options);\n\t}\n\n\t/**\n\t * Renders this composition into an MP4/WebM video file with audio.\n\t */\n\tpublic async renderVideo(\n\t\toutputPathOrOptions: string | RenderVideoOptions = {},\n\t\toptions: RenderVideoOptions = {},\n\t): Promise<RenderVideoResult> {\n\t\tconst opts =\n\t\t\ttypeof outputPathOrOptions === \"string\"\n\t\t\t\t? { ...options, outputPath: outputPathOrOptions }\n\t\t\t\t: outputPathOrOptions;\n\t\tconst renderer = opts.renderer ?? new HeadlessMediaRenderer();\n\t\tconst result = await renderer.renderVideo(this.toVirtualMedia(), opts);\n\t\tif (result.qa) {\n\t\t\t// Fold the document checks into the output checks.\n\t\t\tconst lint = this.lint();\n\t\t\tconst issues = [\n\t\t\t\t...result.qa.issues,\n\t\t\t\t...lint.map((d) => ({\n\t\t\t\t\tseverity: d.severity,\n\t\t\t\t\tcode: d.code,\n\t\t\t\t\tmessage: d.message,\n\t\t\t\t\t...(d.layerId !== undefined && { layerId: d.layerId }),\n\t\t\t\t})),\n\t\t\t];\n\t\t\tresult.qa = {\n\t\t\t\t...result.qa,\n\t\t\t\tissues,\n\t\t\t\t// Lint warnings advise; only a lint error fails the render.\n\t\t\t\tpassed: result.qa.passed && !lint.some((d) => d.severity === \"error\"),\n\t\t\t};\n\t\t}\n\t\treturn deliverToOutputPath(result, opts.outputPath);\n\t}\n\n\t/**\n\t * Checks the document for things that render without error but not as\n\t * intended: unreadable colors or gradients (drawn transparent),\n\t * low-contrast text, layers parked off-canvas, shadows on lights that\n\t * cannot cast them, physical materials without an environment, tracks that\n\t * never change. `renderVideo({ qa })` includes these automatically.\n\t */\n\tpublic lint(): RenderDiagnostic[] {\n\t\treturn lintComposition(this.toSpec());\n\t}\n}\n\n/**\n * Layer helpers for constructing composition nodes with clean URL/path strings.\n */\n\nexport type AnimatableNode<T extends LayoutNode> = T & {\n\tglass?: Record<string, unknown>;\n\taudioDeform?: MeshAudioDeformConfig | Record<string, unknown>;\n\tcrop?: CropProps | Crop;\n\tvision?: Vision;\n\trelighting?: NormalRelightingOptions;\n\tdeflicker?: DeflickerOptions;\n\teffects?: unknown[];\n\tblurRegions?: unknown[];\n\t[key: string]: unknown;\n\tanimate(\n\t\t...anim: (\n\t\t\t| LayerAnimation\n\t\t\t| { tracks: AnimationTrack[] }\n\t\t\t| LayerAnimation[]\n\t\t)[]\n\t): AnimatableNode<T>;\n\tpinToLandmark(\n\t\ttarget:\n\t\t\t| LandmarkCoordinateSignals\n\t\t\t| {\n\t\t\t\t\tx: number;\n\t\t\t\t\ty: number;\n\t\t\t\t\tz?: number;\n\t\t\t\t\tscreenX?: number;\n\t\t\t\t\tscreenY?: number;\n\t\t\t },\n\t\toptions?: PinToLandmarkOptions,\n\t): AnimatableNode<T>;\n\tpinToObject(\n\t\ttarget:\n\t\t\t| ObjectTrackSignals\n\t\t\t| LandmarkCoordinateSignals\n\t\t\t| {\n\t\t\t\t\tx: number;\n\t\t\t\t\ty: number;\n\t\t\t\t\tz?: number;\n\t\t\t\t\tscreenX?: number;\n\t\t\t\t\tscreenY?: number;\n\t\t\t },\n\t\toptions?: PinToObjectOptions,\n\t): AnimatableNode<T>;\n\t/**\n\t * Track matte: `matte` (any layer) masks this one by its alpha or\n\t * brightness. It is laid out like a sibling (same parent) and timed with\n\t * this node; with no x/y/width/height it covers this node's box. Animate\n\t * the matte for wipes and reveals: text through a sliding box, video\n\t * inside type, an iris circle.\n\t */\n\twithMatte(matte: LayoutNode, mode?: MatteMode): AnimatableNode<T>;\n\t/** Alias of {@link withMatte}. */\n\twithMask(mask: LayoutNode, mode?: MatteMode): AnimatableNode<T>;\n\twithPbrGlass(options?: Record<string, unknown>): AnimatableNode<T>;\n\tdeformWithAudio(\n\t\tconfig?: MeshAudioDeformConfig | Record<string, unknown>,\n\t): AnimatableNode<T>;\n\twithCrop(cropConfig: CropProps | Crop): AnimatableNode<T>;\n\t/** Runs vision on this node's rendered output (see `Vision` for options and modes). */\n\twithVision(config?: VisionProps | Vision): AnimatableNode<T>;\n\twithRelighting(options?: NormalRelightingOptions): AnimatableNode<T>;\n\trelight(options?: NormalRelightingOptions): AnimatableNode<T>;\n\twithDeflicker(options?: DeflickerOptions): AnimatableNode<T>;\n\tapply(effect: unknown): AnimatableNode<T>;\n\twithEffect(effect: unknown): AnimatableNode<T>;\n\twithEffects(effects: unknown[]): AnimatableNode<T>;\n\tblurRegion(\n\t\ttrackTarget: ObjectTrackSignals,\n\t\toptions?: Partial<BlurProps>,\n\t): AnimatableNode<T>;\n\twithBlurRegion(\n\t\ttrackTarget: ObjectTrackSignals,\n\t\toptions?: Partial<BlurProps>,\n\t): AnimatableNode<T>;\n};\n\nfunction withAnimation<T extends LayoutNode>(node: T): AnimatableNode<T> {\n\tconst target = node as AnimatableNode<T>;\n\tObject.defineProperty(target, \"animate\", {\n\t\tvalue: (\n\t\t\t...anims: (\n\t\t\t\t| LayerAnimation\n\t\t\t\t| { tracks: AnimationTrack[] }\n\t\t\t\t| LayerAnimation[]\n\t\t\t)[]\n\t\t) => {\n\t\t\t// Every call layers onto what is already there: keyframe tracks on\n\t\t\t// the same prop merge (a later key wins on a shared frame).\n\t\t\tconst incoming = anims\n\t\t\t\t.flat()\n\t\t\t\t.flatMap((a) =>\n\t\t\t\t\ta instanceof LayerAnimation\n\t\t\t\t\t\t? a.tracks\n\t\t\t\t\t\t: ((a as { tracks?: AnimationTrack[] }).tracks ?? []),\n\t\t\t\t);\n\t\t\tconst current = target.animation as\n\t\t\t\t| { tracks?: AnimationTrack[]; frameStep?: number }\n\t\t\t\t| undefined;\n\t\t\tconst existing = current?.tracks ?? [];\n\t\t\t// The last `.stepped()` wins; stepping applies to the whole layer.\n\t\t\tconst frameStep =\n\t\t\t\tanims\n\t\t\t\t\t.flat()\n\t\t\t\t\t.map((a) => (a as { frameStep?: number }).frameStep)\n\t\t\t\t\t.filter((n): n is number => n !== undefined)\n\t\t\t\t\t.at(-1) ?? current?.frameStep;\n\t\t\ttarget.animation = {\n\t\t\t\ttracks: mergeAnimationTracks([...existing, ...incoming]),\n\t\t\t\t...(frameStep !== undefined && frameStep > 1 && { frameStep }),\n\t\t\t};\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"pinToLandmark\", {\n\t\tvalue: (\n\t\t\tlandmarkTarget:\n\t\t\t\t| LandmarkCoordinateSignals\n\t\t\t\t| {\n\t\t\t\t\t\tx: number;\n\t\t\t\t\t\ty: number;\n\t\t\t\t\t\tz?: number;\n\t\t\t\t\t\tscreenX?: number;\n\t\t\t\t\t\tscreenY?: number;\n\t\t\t\t },\n\t\t\toptions?: PinToLandmarkOptions,\n\t\t) => {\n\t\t\tpinNodeToLandmark(\n\t\t\t\ttarget as unknown as { x?: unknown; y?: unknown; z?: unknown },\n\t\t\t\tlandmarkTarget,\n\t\t\t\toptions,\n\t\t\t);\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"pinToObject\", {\n\t\tvalue: (\n\t\t\tobjectTarget:\n\t\t\t\t| ObjectTrackSignals\n\t\t\t\t| LandmarkCoordinateSignals\n\t\t\t\t| {\n\t\t\t\t\t\tx: number;\n\t\t\t\t\t\ty: number;\n\t\t\t\t\t\tz?: number;\n\t\t\t\t\t\tscreenX?: number;\n\t\t\t\t\t\tscreenY?: number;\n\t\t\t\t },\n\t\t\toptions?: PinToObjectOptions,\n\t\t) => {\n\t\t\tpinNodeToObject(\n\t\t\t\ttarget as unknown as {\n\t\t\t\t\tx?: unknown;\n\t\t\t\t\ty?: unknown;\n\t\t\t\t\tz?: unknown;\n\t\t\t\t\twidth?: unknown;\n\t\t\t\t\theight?: unknown;\n\t\t\t\t\topacity?: unknown;\n\t\t\t\t},\n\t\t\t\tobjectTarget,\n\t\t\t\toptions,\n\t\t\t);\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tconst withMatte = (matte: LayoutNode, mode?: MatteMode) => {\n\t\ttarget.matte = { node: matte, ...(mode && { mode }) };\n\t\treturn target;\n\t};\n\tfor (const name of [\"withMatte\", \"withMask\"]) {\n\t\tObject.defineProperty(target, name, {\n\t\t\tvalue: withMatte,\n\t\t\tenumerable: false,\n\t\t\twritable: true,\n\t\t\tconfigurable: true,\n\t\t});\n\t}\n\n\tObject.defineProperty(target, \"withPbrGlass\", {\n\t\tvalue: (options?: Record<string, unknown>) => {\n\t\t\ttarget.glass = options ?? {};\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"deformWithAudio\", {\n\t\tvalue: (config?: MeshAudioDeformConfig | Record<string, unknown>) => {\n\t\t\ttarget.audioDeform = config ?? {};\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"withCrop\", {\n\t\tvalue: (cropConfig: CropProps | Crop) => {\n\t\t\ttarget.crop =\n\t\t\t\tcropConfig instanceof Crop ? cropConfig : new Crop(cropConfig);\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"withVision\", {\n\t\tvalue: (config?: VisionProps | Vision) => {\n\t\t\ttarget.vision = config instanceof Vision ? config : new Vision(config);\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"withRelighting\", {\n\t\tvalue: (options?: NormalRelightingOptions) => {\n\t\t\ttarget.relighting = options ?? {};\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"relight\", {\n\t\tvalue: (options?: NormalRelightingOptions) => {\n\t\t\ttarget.relighting = options ?? {};\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"withDeflicker\", {\n\t\tvalue: (options?: DeflickerOptions) => {\n\t\t\ttarget.deflicker = options ?? {};\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"apply\", {\n\t\tvalue: (effect: unknown) => {\n\t\t\tif (!target.effects) {\n\t\t\t\ttarget.effects = [];\n\t\t\t}\n\t\t\ttarget.effects.push(effect);\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"withEffect\", {\n\t\tvalue: (effect: unknown) => {\n\t\t\tif (!target.effects) {\n\t\t\t\ttarget.effects = [];\n\t\t\t}\n\t\t\ttarget.effects.push(effect);\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"withEffects\", {\n\t\tvalue: (effects: unknown[]) => {\n\t\t\tif (!target.effects) {\n\t\t\t\ttarget.effects = [];\n\t\t\t}\n\t\t\ttarget.effects.push(...effects);\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"section\", {\n\t\tvalue: (\n\t\t\ttargetOrOptions: ObjectTrackSignals | SectionOptions = {},\n\t\t\toptions?: SectionOptions,\n\t\t) => {\n\t\t\tif (\n\t\t\t\ttargetOrOptions !== null &&\n\t\t\t\ttypeof targetOrOptions === \"object\" &&\n\t\t\t\t\"bounds\" in targetOrOptions\n\t\t\t) {\n\t\t\t\treturn Layer.section(\n\t\t\t\t\ttarget as MediaNode,\n\t\t\t\t\ttargetOrOptions as ObjectTrackSignals,\n\t\t\t\t\toptions,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn Layer.section(\n\t\t\t\ttarget as MediaNode,\n\t\t\t\ttargetOrOptions as SectionOptions,\n\t\t\t);\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"blurRegion\", {\n\t\tvalue: (trackTarget: ObjectTrackSignals, options?: Partial<BlurProps>) => {\n\t\t\tconst blur = new Blur({\n\t\t\t\ttrack: trackTarget,\n\t\t\t\tstrength: options?.strength ?? 25,\n\t\t\t\tshape: options?.shape ?? \"ellipse\",\n\t\t\t\t...options,\n\t\t\t});\n\t\t\tif (!target.effects) {\n\t\t\t\ttarget.effects = [];\n\t\t\t}\n\t\t\ttarget.effects.push(blur);\n\t\t\treturn target;\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\tObject.defineProperty(target, \"withBlurRegion\", {\n\t\tvalue: (trackTarget: ObjectTrackSignals, options?: Partial<BlurProps>) => {\n\t\t\treturn (\n\t\t\t\ttarget as {\n\t\t\t\t\tblurRegion: (\n\t\t\t\t\t\tt: ObjectTrackSignals,\n\t\t\t\t\t\to?: Partial<BlurProps>,\n\t\t\t\t\t) => unknown;\n\t\t\t\t}\n\t\t\t).blurRegion(trackTarget, options);\n\t\t},\n\t\tenumerable: false,\n\t\twritable: true,\n\t\tconfigurable: true,\n\t});\n\n\treturn target;\n}\n\nexport const Layer = {\n\tvideo: (\n\t\tsrc: string,\n\t\toptions: Partial<MediaNode> = {},\n\t): AnimatableNode<MediaNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"video\"),\n\t\t\tkind: \"media\",\n\t\t\tinputHandleId: src,\n\t\t\tdataType: \"Video\",\n\t\t\tfit: options.fit ?? \"cover\",\n\t\t\t...options,\n\t\t}),\n\timage: (\n\t\tsrc: string,\n\t\toptions: Partial<MediaNode> = {},\n\t): AnimatableNode<MediaNode> => {\n\t\tif (typeof src === \"string\") {\n\t\t\tif (\n\t\t\t\t/\\.(json|lottie)(\\?.*)?$/i.test(src) ||\n\t\t\t\tsrc.startsWith(\"data:application/json\")\n\t\t\t) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[Layer.image] '${src}' is a Lottie vector animation, not a static image. Use Layer.lottie('${src}', options) instead.`,\n\t\t\t\t);\n\t\t\t} else if (/\\.(mp4|mov|webm|mkv)(\\?.*)?$/i.test(src)) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[Layer.image] '${src}' is a video file, not a static image. Use Layer.video('${src}', options) instead.`,\n\t\t\t\t);\n\t\t\t} else if (/\\.(mp3|wav|ogg|m4a|aac)(\\?.*)?$/i.test(src)) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[Layer.image] '${src}' is an audio file, not a static image. Use Layer.audio('${src}', options) instead.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\treturn withAnimation({\n\t\t\tid: options.id ?? autoId(\"img\"),\n\t\t\tkind: \"media\",\n\t\t\tinputHandleId: src,\n\t\t\tdataType: \"Image\",\n\t\t\tfit: options.fit ?? \"cover\",\n\t\t\t...options,\n\t\t});\n\t},\n\tsvg: (\n\t\tsrc: string,\n\t\toptions: Partial<MediaNode> = {},\n\t): AnimatableNode<MediaNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"svg\"),\n\t\t\tkind: \"media\",\n\t\t\tinputHandleId: src,\n\t\t\tdataType: \"SVG\",\n\t\t\tfit: options.fit ?? \"contain\",\n\t\t\t...options,\n\t\t}),\n\tlottie: (\n\t\tsrc: string,\n\t\toptions: Partial<MediaNode> = {},\n\t): AnimatableNode<MediaNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"lottie\"),\n\t\t\tkind: \"media\",\n\t\t\tinputHandleId: src,\n\t\t\tdataType: \"Lottie\",\n\t\t\tfit: options.fit ?? \"contain\",\n\t\t\t...options,\n\t\t}),\n\taudio: (\n\t\tsrc: string,\n\t\toptions: Partial<MediaNode> = {},\n\t): AnimatableNode<MediaNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"audio\"),\n\t\t\tkind: \"media\",\n\t\t\tinputHandleId: src,\n\t\t\tdataType: \"Audio\",\n\t\t\tvolume: options.volume ?? 1,\n\t\t\t...options,\n\t\t}),\n\ttext: (\n\t\tcontentOrOptions:\n\t\t\t| string\n\t\t\t| TextSpan[]\n\t\t\t| (string | TextSpan)[]\n\t\t\t| Partial<TextNode>,\n\t\tmaybeOptions: Partial<TextNode> = {},\n\t): AnimatableNode<TextNode> => {\n\t\tconst isArray = Array.isArray(contentOrOptions);\n\t\tconst isObj =\n\t\t\t!isArray &&\n\t\t\ttypeof contentOrOptions === \"object\" &&\n\t\t\tcontentOrOptions !== null;\n\t\tconst options = isObj\n\t\t\t? (contentOrOptions as Partial<TextNode>)\n\t\t\t: maybeOptions;\n\n\t\tlet textContent = \"\";\n\t\tlet spans: TextSpan[] | undefined = options.spans;\n\n\t\tif (isArray) {\n\t\t\tconst normalized = normalizeTextSpans(\n\t\t\t\tcontentOrOptions as (string | TextSpan)[],\n\t\t\t);\n\t\t\ttextContent = normalized.text;\n\t\t\tspans = normalized.spans;\n\t\t} else if (isObj) {\n\t\t\tif (options.spans && !options.text) {\n\t\t\t\tconst normalized = normalizeTextSpans(options.spans);\n\t\t\t\ttextContent = normalized.text;\n\t\t\t} else {\n\t\t\t\ttextContent = (options.text as string) ?? \"\";\n\t\t\t}\n\t\t} else {\n\t\t\ttextContent =\n\t\t\t\ttypeof contentOrOptions === \"string\"\n\t\t\t\t\t? contentOrOptions\n\t\t\t\t\t: String(contentOrOptions ?? \"\");\n\t\t}\n\n\t\treturn withAnimation({\n\t\t\tid: options.id ?? autoId(\"text\"),\n\t\t\tkind: \"text\",\n\t\t\tfontFamily:\n\t\t\t\toptions.fontFamily ?? FontManager.getAll()[0]?.family ?? \"Inter\",\n\t\t\tfontSize: options.fontSize ?? 48,\n\t\t\tfill: options.fill ?? \"#ffffff\",\n\t\t\t...options,\n\t\t\ttext: options.text ?? textContent,\n\t\t\tspans: options.spans ?? spans,\n\t\t});\n\t},\n\tcaption: (\n\t\tsrc: string,\n\t\toptions: Partial<MediaNode> = {},\n\t): AnimatableNode<MediaNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"caption\"),\n\t\t\tkind: \"media\",\n\t\t\tinputHandleId: src,\n\t\t\tdataType: options.dataType ?? \"Caption\",\n\t\t\tfontFamily:\n\t\t\t\toptions.fontFamily ?? FontManager.getAll()[0]?.family ?? \"Inter\",\n\t\t\tfontSize: options.fontSize ?? 48,\n\t\t\tfill: options.fill ?? \"#ffffff\",\n\t\t\t...options,\n\t\t}),\n\tshape: (\n\t\tshapeType:\n\t\t\t| \"rect\"\n\t\t\t| \"circle\"\n\t\t\t| \"ellipse\"\n\t\t\t| \"polygon\"\n\t\t\t| \"star\"\n\t\t\t| \"arrow\"\n\t\t\t| \"path\" = \"rect\",\n\t\toptions: Partial<ShapeNode> & {\n\t\t\t/** Alias of `fillColor`: a color or a CSS gradient string. */\n\t\t\tfill?: string;\n\t\t} = {},\n\t): AnimatableNode<ShapeNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"shape\"),\n\t\t\tkind: \"shape\",\n\t\t\tshapeType: options.shapeType ?? shapeType,\n\t\t\t...options,\n\t\t\t// `fill` and `fillColor` are the same thing; either may hold a\n\t\t\t// color or a CSS gradient.\n\t\t\tfillColor: options.fillColor ?? options.fill ?? \"#3b82f6\",\n\t\t}),\n\tflex: (options: Partial<FlexNode> = {}): AnimatableNode<FlexNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"flex\"),\n\t\t\tkind: \"flex\",\n\t\t\tdir: options.dir ?? \"column\",\n\t\t\tchildren: options.children ?? [],\n\t\t\t...options,\n\t\t}),\n\tbox: (options: Partial<BoxNode> = {}): AnimatableNode<BoxNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"box\"),\n\t\t\tkind: \"box\",\n\t\t\tbackground: options.background ?? \"transparent\",\n\t\t\tchildren: options.children ?? [],\n\t\t\t...options,\n\t\t}),\n\t/**\n\t * A GPU particle system as a layer: tens of thousands of particles\n\t * simulated in a compute shader and drawn in one call (see\n\t * {@link ParticlesOptions}). Positions are in the layer's own px; drivers\n\t * (rate, gravity, noise, attractors) are read every frame, and a\n\t * performer can push particles with `push: { person }`.\n\t */\n\tparticles: (options: ParticlesOptions): AnimatableNode<MediaNode> => {\n\t\tconst system = new Particles(options);\n\t\t// A media layer whose source is the particle op itself: it draws into\n\t\t// the layer's own texture, composited like any clip.\n\t\tconst source = {\n\t\t\tmetadata: { width: options.width, height: options.height },\n\t\t\toperation: { ...system.toOperation(), effect: system, dataType: \"Video\" },\n\t\t\tchildren: [],\n\t\t};\n\t\treturn withAnimation({\n\t\t\tid: options.id ?? autoId(\"particles\"),\n\t\t\tkind: \"media\",\n\t\t\tdataType: \"Video\",\n\t\t\tsrc: source,\n\t\t\tposition: \"absolute\",\n\t\t\tx: options.x ?? 0,\n\t\t\ty: options.y ?? 0,\n\t\t\twidth: options.width,\n\t\t\theight: options.height,\n\t\t\t...(options.startFrame !== undefined && {\n\t\t\t\tstartFrame: options.startFrame,\n\t\t\t}),\n\t\t\t...(options.durationFrames !== undefined && {\n\t\t\t\tdurationFrames: options.durationFrames,\n\t\t\t}),\n\t\t\t...(options.zIndex !== undefined && { zIndex: options.zIndex }),\n\t\t} as unknown as MediaNode);\n\t},\n\t/**\n\t * A procedural VFX layer (smoke, fire, rain, snow, aurora, …) drawn by\n\t * the GPU, transparent where there is no effect. Put it above or below\n\t * other layers like any clip.\n\t */\n\tvfx: (\n\t\toptions: Partial<ProceduralVFXProps> & {\n\t\t\tx?: number;\n\t\t\ty?: number;\n\t\t\twidth: number;\n\t\t\theight: number;\n\t\t\tid?: string;\n\t\t\tstartFrame?: number;\n\t\t\tdurationFrames?: number;\n\t\t\tzIndex?: number;\n\t\t},\n\t): AnimatableNode<MediaNode> => {\n\t\tconst { x, y, id, startFrame, durationFrames, zIndex, ...props } = options;\n\t\tconst vfx = new ProceduralVFX({\n\t\t\toutputType: \"Video\",\n\t\t\t...props,\n\t\t} as ProceduralVFXProps);\n\t\tconst source = {\n\t\t\tmetadata: { width: options.width, height: options.height },\n\t\t\toperation: { ...vfx.toOperation(), effect: vfx, dataType: \"Video\" },\n\t\t\tchildren: [],\n\t\t};\n\t\treturn withAnimation({\n\t\t\tid: id ?? autoId(\"vfx\"),\n\t\t\tkind: \"media\",\n\t\t\tdataType: \"Video\",\n\t\t\tsrc: source,\n\t\t\tposition: \"absolute\",\n\t\t\tx: x ?? 0,\n\t\t\ty: y ?? 0,\n\t\t\twidth: options.width,\n\t\t\theight: options.height,\n\t\t\t...(startFrame !== undefined && { startFrame }),\n\t\t\t...(durationFrames !== undefined && { durationFrames }),\n\t\t\t...(zIndex !== undefined && { zIndex }),\n\t\t} as unknown as MediaNode);\n\t},\n\tsection: (\n\t\tsource: string | MediaNode | Composition,\n\t\ttargetOrOptions: ObjectTrackSignals | SectionOptions = {},\n\t\toptions: SectionOptions = {},\n\t): SectionNode => {\n\t\tlet realSource: string | MediaNode = source as string | MediaNode;\n\t\tif (\n\t\t\tsource &&\n\t\t\ttypeof source === \"object\" &&\n\t\t\t\"toSpec\" in source &&\n\t\t\t\"children\" in source\n\t\t) {\n\t\t\tconst compMedia = (\n\t\t\t\t((source as Composition).children || []) as LayoutNode[]\n\t\t\t).find(\n\t\t\t\t(c) =>\n\t\t\t\t\tc.kind === \"media\" &&\n\t\t\t\t\t(c.dataType === \"Video\" || c.dataType === \"Image\"),\n\t\t\t) as MediaNode | undefined;\n\t\t\tif (compMedia) {\n\t\t\t\trealSource = compMedia;\n\t\t\t}\n\t\t}\n\n\t\tconst isTracked =\n\t\t\ttargetOrOptions !== null &&\n\t\t\ttypeof targetOrOptions === \"object\" &&\n\t\t\t\"bounds\" in targetOrOptions;\n\t\tconst opts: SectionOptions = isTracked\n\t\t\t? options\n\t\t\t: (targetOrOptions as SectionOptions);\n\t\tconst target = isTracked\n\t\t\t? (targetOrOptions as ObjectTrackSignals)\n\t\t\t: undefined;\n\n\t\tconst padding = opts.padding ?? 0;\n\t\tconst src =\n\t\t\ttypeof realSource === \"string\"\n\t\t\t\t? realSource\n\t\t\t\t: (realSource?.inputHandleId ??\n\t\t\t\t\t(realSource as { src?: string })?.src ??\n\t\t\t\t\t\"\");\n\t\tconst dataType =\n\t\t\ttypeof realSource === \"object\" && realSource?.dataType\n\t\t\t\t? realSource.dataType\n\t\t\t\t: \"Video\";\n\t\tconst compW =\n\t\t\t(opts.compositionWidth as number) ??\n\t\t\t(opts.compWidth as number) ??\n\t\t\t(isTracked ? (opts.width as number) : undefined) ??\n\t\t\t1920;\n\t\tconst compH =\n\t\t\t(opts.compositionHeight as number) ??\n\t\t\t(opts.compHeight as number) ??\n\t\t\t(isTracked ? (opts.height as number) : undefined) ??\n\t\t\t1080;\n\n\t\tconst effList: Effect[] = Array.isArray(opts.effects)\n\t\t\t? ([...opts.effects] as Effect[])\n\t\t\t: opts.effects\n\t\t\t\t? [opts.effects as Effect]\n\t\t\t\t: [];\n\n\t\tconst innerX = target\n\t\t\t? target.bounds.screenX.multiply(-1).add(padding)\n\t\t\t: typeof opts.x === \"number\"\n\t\t\t\t? -opts.x\n\t\t\t\t: opts.x &&\n\t\t\t\t\t\ttypeof (opts.x as { multiply?: unknown }).multiply === \"function\"\n\t\t\t\t\t? (opts.x as { multiply: (n: number) => unknown }).multiply(-1)\n\t\t\t\t\t: 0;\n\n\t\tconst innerY = target\n\t\t\t? target.bounds.screenY.multiply(-1).add(padding)\n\t\t\t: typeof opts.y === \"number\"\n\t\t\t\t? -opts.y\n\t\t\t\t: opts.y &&\n\t\t\t\t\t\ttypeof (opts.y as { multiply?: unknown }).multiply === \"function\"\n\t\t\t\t\t? (opts.y as { multiply: (n: number) => unknown }).multiply(-1)\n\t\t\t\t\t: 0;\n\n\t\tconst innerMedia = (\n\t\t\tdataType === \"Image\"\n\t\t\t\t? Layer.image(src, {\n\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\twidth: compW,\n\t\t\t\t\t\theight: compH,\n\t\t\t\t\t\tfit: opts.fit ?? \"cover\",\n\t\t\t\t\t\tx: innerX as number,\n\t\t\t\t\t\ty: innerY as number,\n\t\t\t\t\t})\n\t\t\t\t: Layer.video(src, {\n\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\twidth: compW,\n\t\t\t\t\t\theight: compH,\n\t\t\t\t\t\tfit: opts.fit ?? \"cover\",\n\t\t\t\t\t\tx: innerX as number,\n\t\t\t\t\t\ty: innerY as number,\n\t\t\t\t\t})\n\t\t).withEffects(effList);\n\n\t\tconst boxWidth = target\n\t\t\t? target.bounds.screenWidth.add(padding * 2)\n\t\t\t: opts.width !== undefined\n\t\t\t\t? opts.width\n\t\t\t\t: compW;\n\n\t\tconst boxHeight = target\n\t\t\t? target.bounds.screenHeight.add(padding * 2)\n\t\t\t: opts.height !== undefined\n\t\t\t\t? opts.height\n\t\t\t\t: compH;\n\n\t\tconst boxChildren = [innerMedia, ...(opts.children ?? [])];\n\n\t\tconst boxId =\n\t\t\topts.id ??\n\t\t\t(target ? autoId(`section-track-${target.trackId}`) : autoId(\"section\"));\n\n\t\tlet box = Layer.box({\n\t\t\tid: boxId,\n\t\t\tposition: (opts.position as \"absolute\" | \"relative\") ?? \"absolute\",\n\t\t\twidth: boxWidth as number,\n\t\t\theight: boxHeight as number,\n\t\t\tx: target ? undefined : (opts.x as number),\n\t\t\ty: target ? undefined : (opts.y as number),\n\t\t\tborderRadius: opts.borderRadius ?? 0,\n\t\t\tborderColor: opts.borderColor,\n\t\t\tborderWidth: opts.borderWidth,\n\t\t\topacity: (opts.opacity as number) ?? 1,\n\t\t\toverflow: \"hidden\",\n\t\t\tchildren: boxChildren,\n\t\t});\n\n\t\tif (target) {\n\t\t\tbox = box.pinToObject(target, {\n\t\t\t\tanchor: \"topLeft\",\n\t\t\t\toffsetX: -padding,\n\t\t\t\toffsetY: -padding,\n\t\t\t\thideWhenLost: opts.hideWhenLost ?? true,\n\t\t\t\tsmoothFrames: opts.smoothFrames,\n\t\t\t});\n\t\t}\n\n\t\tconst sectionNode = box as SectionNode;\n\t\tObject.defineProperty(sectionNode, \"innerMedia\", {\n\t\t\tvalue: innerMedia,\n\t\t\tenumerable: true,\n\t\t\twritable: false,\n\t\t});\n\t\tObject.defineProperty(sectionNode, \"effects\", {\n\t\t\tget: () => effList,\n\t\t\tenumerable: true,\n\t\t});\n\t\tObject.defineProperty(sectionNode, \"addEffect\", {\n\t\t\tvalue: (effect: Effect) => {\n\t\t\t\teffList.push(effect);\n\t\t\t\tinnerMedia.effects = effList;\n\t\t\t\treturn sectionNode;\n\t\t\t},\n\t\t\tenumerable: true,\n\t\t\twritable: false,\n\t\t});\n\t\tObject.defineProperty(sectionNode, \"withEffect\", {\n\t\t\tvalue: (effect: Effect) => sectionNode.addEffect(effect),\n\t\t\tenumerable: true,\n\t\t\twritable: false,\n\t\t});\n\t\tObject.defineProperty(sectionNode, \"withEffects\", {\n\t\t\tvalue: (effects: Effect[]) => {\n\t\t\t\tfor (const eff of effects) {\n\t\t\t\t\tsectionNode.addEffect(eff);\n\t\t\t\t}\n\t\t\t\treturn sectionNode;\n\t\t\t},\n\t\t\tenumerable: true,\n\t\t\twritable: false,\n\t\t});\n\n\t\treturn sectionNode;\n\t},\n\ttrackedRegion: (\n\t\tsource: string | MediaNode,\n\t\ttarget: ObjectTrackSignals,\n\t\toptions: TrackedRegionOptions = {},\n\t): SectionNode => {\n\t\treturn Layer.section(source, target, options);\n\t},\n\tblurTrackedRegion: (\n\t\tsource: string | MediaNode,\n\t\ttarget: ObjectTrackSignals,\n\t\toptions: Partial<BlurProps> & {\n\t\t\tborderRadius?: number;\n\t\t\tpadding?: number;\n\t\t\tborderColor?: string;\n\t\t\tborderWidth?: number;\n\t\t} = {},\n\t): SectionNode => {\n\t\t// Section styling is not a Blur prop; keep it out of the effect config.\n\t\tconst { padding, borderRadius, borderColor, borderWidth, ...blurOptions } =\n\t\t\toptions;\n\t\treturn Layer.section(source, target, {\n\t\t\tpadding: padding ?? 8,\n\t\t\tborderRadius: borderRadius ?? 12,\n\t\t\tborderColor,\n\t\t\tborderWidth,\n\t\t\teffects: [\n\t\t\t\tnew Blur({\n\t\t\t\t\tstrength: blurOptions.strength ?? 25,\n\t\t\t\t\tblurType: blurOptions.blurType ?? \"Gaussian\",\n\t\t\t\t\t...blurOptions,\n\t\t\t\t}),\n\t\t\t],\n\t\t});\n\t},\n\t/**\n\t * A line, area, bar, scatter, candlestick, pie or donut chart. Returns a box\n\t * of ordinary nodes (bars are boxes, lines and slices are path shapes,\n\t * labels are text), so it positions, animates and composites like any layer.\n\t * `props` applies to that box: position, id, timing, effects.\n\t */\n\tchart: (\n\t\toptions: ChartOptions,\n\t\tprops: Partial<BoxNode> = {},\n\t): AnimatableNode<BoxNode> =>\n\t\tbuildChart(options, props, FontManager.getAll()[0]?.family ?? \"Inter\"),\n\tcamera: (options: Partial<CameraNode> = {}): AnimatableNode<CameraNode> =>\n\t\twithAnimation<CameraNode>({\n\t\t\tid: options.id ?? autoId(\"camera\"),\n\t\t\tkind: \"camera\",\n\t\t\tmode: options.mode ?? \"lookAt\",\n\t\t\tpitch: options.pitch ?? 0,\n\t\t\tyaw: options.yaw ?? 0,\n\t\t\troll: options.roll ?? 0,\n\t\t\t...options,\n\t\t}),\n\tlight: (options: Partial<LightNode> = {}): AnimatableNode<LightNode> =>\n\t\twithAnimation<LightNode>({\n\t\t\tid: options.id ?? autoId(\"light\"),\n\t\t\tkind: \"light\",\n\t\t\tlightType: options.lightType ?? \"point\",\n\t\t\tcolor: options.color ?? \"#ffffff\",\n\t\t\tintensity: options.intensity ?? 1.0,\n\t\t\t...options,\n\t\t}),\n\tambientLight: (\n\t\tcolor: string = \"#ffffff\",\n\t\tintensity: number = 0.5,\n\t\toptions: Partial<LightNode> = {},\n\t): AnimatableNode<LightNode> => Light.ambient(color, intensity, options),\n\t/**\n\t * Scenes back to back with transitions between them; see `Transition`.\n\t * `comp.add(Layer.sequence([{ scene: hero(), duration: 90 },\n\t * { scene: next(), duration: 120, transition: Transition.push(\"left\") }]))`.\n\t * The result's `totalFrames` is the sequence length.\n\t */\n\tsequence: (\n\t\tentries: SequenceEntry[],\n\t\toptions?: SceneSequenceOptions,\n\t): SequenceNode => sequence(entries, options),\n\t/** See {@link Light.environment}: `Layer.environment(\"studio\", { exposure: 0.3 })`. */\n\tenvironment: (\n\t\tpresetOrOptions: EnvironmentPreset | EnvironmentOptions = \"studio\",\n\t\toptions: EnvironmentOptions = {},\n\t): AnimatableNode<LightNode> => Light.environment(presetOrOptions, options),\n\tdirectionalLight: (\n\t\toptions: Partial<LightNode> = {},\n\t): AnimatableNode<LightNode> => Light.directional(options),\n\tpointLight: (options: Partial<LightNode> = {}): AnimatableNode<LightNode> =>\n\t\tLight.point(options),\n\tspotLight: (options: Partial<LightNode> = {}): AnimatableNode<LightNode> =>\n\t\tLight.spot(options),\n\tcube: (options: Cube3DOptions): AnimatableNode<BoxNode> =>\n\t\tLayer3D.cube(options),\n\tcarousel3d: (options: Carousel3DOptions): AnimatableNode<BoxNode> =>\n\t\tLayer3D.carousel(options),\n\tplane3d: (options: Plane3DOptions): AnimatableNode<BoxNode> =>\n\t\tLayer3D.plane(options),\n\tprism3d: (options: Prism3DOptions): AnimatableNode<BoxNode> =>\n\t\tLayer3D.prism(options),\n\tmodel: (options: Partial<Model3DNode> = {}): AnimatableNode<Model3DNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"model3d\"),\n\t\t\tkind: \"model3d\",\n\t\t\tis3D: options.is3D ?? true,\n\t\t\tmodelFormat: options.modelFormat ?? \"auto\",\n\t\t\tloop: options.loop ?? true,\n\t\t\tscale: options.scale ?? 1.0,\n\t\t\tscaleX: options.scaleX ?? 1.0,\n\t\t\tscaleY: options.scaleY ?? 1.0,\n\t\t\tscaleZ: options.scaleZ ?? 1.0,\n\t\t\topacity: options.opacity ?? 1.0,\n\t\t\t// material and twoSided stay unset unless given: the model's own\n\t\t\t// materials (toon, single-sided, …) decide, falling back to lit.\n\t\t\t...options,\n\t\t}),\n\tobj: (\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> =>\n\t\tLayer.model({\n\t\t\tsrc,\n\t\t\tmodelFormat: \"obj\",\n\t\t\t...options,\n\t\t}),\n\tfbx: (\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> =>\n\t\tLayer.model({\n\t\t\tsrc,\n\t\t\tmodelFormat: \"fbx\",\n\t\t\t...options,\n\t\t}),\n\tgltf: (\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> =>\n\t\tLayer.model({\n\t\t\tsrc,\n\t\t\tmodelFormat: \"gltf\",\n\t\t\t...options,\n\t\t}),\n\tglb: (\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> =>\n\t\tLayer.model({\n\t\t\tsrc,\n\t\t\tmodelFormat: \"glb\",\n\t\t\t...options,\n\t\t}),\n\tstl: (\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> =>\n\t\tLayer.model({\n\t\t\tsrc,\n\t\t\tmodelFormat: \"stl\",\n\t\t\t...options,\n\t\t}),\n\tply: (\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> =>\n\t\tLayer.model({\n\t\t\tsrc,\n\t\t\tmodelFormat: \"ply\",\n\t\t\t...options,\n\t\t}),\n\tvox: (\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> =>\n\t\tLayer.model({\n\t\t\tsrc,\n\t\t\tmodelFormat: \"vox\",\n\t\t\t...options,\n\t\t}),\n\tthreeDS: (\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> =>\n\t\tLayer.model({\n\t\t\tsrc,\n\t\t\tmodelFormat: \"3ds\",\n\t\t\t...options,\n\t\t}),\n\toff: (\n\t\tsrc: string,\n\t\toptions: Partial<Model3DNode> = {},\n\t): AnimatableNode<Model3DNode> =>\n\t\tLayer.model({\n\t\t\tsrc,\n\t\t\tmodelFormat: \"off\",\n\t\t\t...options,\n\t\t}),\n};\n\n/** World settings for `Layer.environment` (see `LightNode` for every field). */\nexport type EnvironmentOptions = Partial<\n\tPick<\n\t\tLightNode,\n\t\t| \"id\"\n\t\t| \"preset\"\n\t\t| \"top\"\n\t\t| \"horizon\"\n\t\t| \"bottom\"\n\t\t| \"intensity\"\n\t\t| \"softboxes\"\n\t\t| \"rotation\"\n\t\t| \"exposure\"\n\t\t| \"toneMapping\"\n\t\t| \"fog\"\n\t\t| \"bloom\"\n\t\t| \"startFrame\"\n\t\t| \"durationFrames\"\n\t>\n>;\n\nexport const Light = {\n\t/**\n\t * The scene's world: a procedural studio environment that lights and\n\t * reflects off every surface, plus exposure, tone mapping and fog. Adding\n\t * one switches the scene to physically based shading (GGX, real\n\t * `roughness` / `metallic`, `emissive` that blooms past white).\n\t */\n\tenvironment: (\n\t\tpresetOrOptions: EnvironmentPreset | EnvironmentOptions = \"studio\",\n\t\toptions: EnvironmentOptions = {},\n\t): AnimatableNode<LightNode> => {\n\t\tconst opts =\n\t\t\ttypeof presetOrOptions === \"string\"\n\t\t\t\t? { preset: presetOrOptions, ...options }\n\t\t\t\t: { ...presetOrOptions, ...options };\n\t\treturn withAnimation({\n\t\t\tkind: \"light\",\n\t\t\tlightType: \"environment\",\n\t\t\tpreset: \"studio\",\n\t\t\tintensity: 1,\n\t\t\t...opts,\n\t\t\tid: opts.id ?? autoId(\"environment\"),\n\t\t});\n\t},\n\tambient: (\n\t\tcolor: string = \"#ffffff\",\n\t\tintensity: number = 0.5,\n\t\toptions: Partial<LightNode> = {},\n\t): AnimatableNode<LightNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"light-ambient\"),\n\t\t\tkind: \"light\",\n\t\t\tlightType: \"ambient\",\n\t\t\tcolor,\n\t\t\tintensity,\n\t\t\t...options,\n\t\t}),\n\tdirectional: (options: Partial<LightNode> = {}): AnimatableNode<LightNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"light-directional\"),\n\t\t\tkind: \"light\",\n\t\t\tlightType: \"directional\",\n\t\t\tcolor: options.color ?? \"#ffffff\",\n\t\t\tintensity: options.intensity ?? 1.0,\n\t\t\tx: options.x ?? 0,\n\t\t\ty: options.y ?? -1000,\n\t\t\tz: options.z ?? -1000,\n\t\t\ttargetX: options.targetX ?? 0,\n\t\t\ttargetY: options.targetY ?? 0,\n\t\t\ttargetZ: options.targetZ ?? 0,\n\t\t\t...options,\n\t\t}),\n\tpoint: (options: Partial<LightNode> = {}): AnimatableNode<LightNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"light-point\"),\n\t\t\tkind: \"light\",\n\t\t\tlightType: \"point\",\n\t\t\tcolor: options.color ?? \"#ffffff\",\n\t\t\tintensity: options.intensity ?? 1.0,\n\t\t\tx: options.x ?? 0,\n\t\t\ty: options.y ?? 0,\n\t\t\tz: options.z ?? -500,\n\t\t\tradius: options.radius ?? 1000,\n\t\t\tdecay: options.decay ?? 1.0,\n\t\t\t...options,\n\t\t}),\n\tspot: (options: Partial<LightNode> = {}): AnimatableNode<LightNode> =>\n\t\twithAnimation({\n\t\t\tid: options.id ?? autoId(\"light-spot\"),\n\t\t\tkind: \"light\",\n\t\t\tlightType: \"spot\",\n\t\t\tcolor: options.color ?? \"#ffffff\",\n\t\t\tintensity: options.intensity ?? 1.0,\n\t\t\tx: options.x ?? 0,\n\t\t\ty: options.y ?? -500,\n\t\t\tz: options.z ?? -1000,\n\t\t\ttargetX: options.targetX ?? 0,\n\t\t\ttargetY: options.targetY ?? 0,\n\t\t\ttargetZ: options.targetZ ?? 0,\n\t\t\tangle: options.angle ?? 45,\n\t\t\tpenumbra: options.penumbra ?? 0.2,\n\t\t\tradius: options.radius ?? 2000,\n\t\t\tdecay: options.decay ?? 1.0,\n\t\t\t...options,\n\t\t}),\n};\n\nexport {\n\ttype PreviewCloseReason,\n\ttype PreviewOptions,\n\ttype PreviewSession,\n\ttype PreviewSource,\n\tstartPreview,\n} from \"./preview/index.js\";\nexport {\n\ttype AudioQaStats,\n\tcomputeGridLayout,\n\tdescribeGpu,\n\ttype FrameGridOptions,\n\ttype FrameGridRenderable,\n\ttype FrameSamplePoint,\n\tformatQaReport,\n\ttype GpuAdapterDescription,\n\tHeadlessMediaRenderer,\n\tHeadlessWebGPURenderer,\n\ttype QaIssue,\n\ttype QaSegment,\n\ttype RenderProgress,\n\trenderFrameGrid,\n\trenderSemaphore,\n\tresetRenderCaches,\n\tresolveSamplePoints,\n\ttype VideoQaOptions,\n\ttype VideoQaReport,\n\ttype VideoQaStats,\n} from \"./renderer/index.js\";\n\nexport function section(\n\tsource: string | MediaNode | Composition,\n\ttargetOrOptions: ObjectTrackSignals | SectionOptions = {},\n\toptions: SectionOptions = {},\n): SectionNode {\n\treturn Layer.section(source, targetOrOptions, options);\n}\n\nexport function blurRegion(\n\tsourceOrLayer: string | AnimatableNode<MediaNode>,\n\ttarget: ObjectTrackSignals,\n\toptions: Partial<BlurProps> & {\n\t\tborderRadius?: number;\n\t\tpadding?: number;\n\t\tborderColor?: string;\n\t\tborderWidth?: number;\n\t} = {},\n): AnimatableNode<MediaNode> | AnimatableNode<BoxNode> {\n\tif (typeof sourceOrLayer === \"object\" && \"blurRegion\" in sourceOrLayer) {\n\t\treturn (sourceOrLayer as AnimatableNode<MediaNode>).blurRegion(\n\t\t\ttarget,\n\t\t\toptions,\n\t\t);\n\t}\n\treturn Layer.blurTrackedRegion(sourceOrLayer as string, target, options);\n}\n\nexport function editTrackedRegion(\n\tsource: string | MediaNode,\n\ttarget: ObjectTrackSignals,\n\toptions: TrackedRegionOptions = {},\n): SectionNode {\n\treturn Layer.section(source, target, options);\n}\n\nexport const Effect = Object.assign(CoreEffect, effectFactories, {\n\tblur: (config?: BlurProps) => new Blur(config),\n\tvignette: (config?: VignetteProps) => new Vignette(config),\n\tcolorBalance: (config?: ColorBalanceProps) => new ColorBalance(config),\n\tcolorKey: (config?: ColorKeyProps) => new ColorKey(config),\n\tlevels: (config?: LevelsProps) => new Levels(config),\n\tfilmGrain: (config?: FilmGrainProps) => new FilmGrain(config),\n\tcurves: (config?: CurvesProps) => new Curves(config),\n\tselectiveColor: (config?: SelectiveColorProps) => new SelectiveColor(config),\n\tgradientMap: (config?: GradientMapProps) => new GradientMap(config),\n\tshadowsHighlights: (config?: ShadowsHighlightsProps) =>\n\t\tnew ShadowsHighlights(config),\n\tapplyLut: (config?: ApplyLUTProps) => new ApplyLUT(config),\n\tunsharpMask: (config?: UnsharpMaskProps) => new UnsharpMask(config),\n\thighPass: (config?: HighPassProps) => new HighPass(config),\n\thalftoneScreen: (config?: HalftoneScreenProps) => new HalftoneScreen(config),\n\ttileOffset: (config?: TileOffsetProps) => new TileOffset(config),\n\tmotionBlur: (config?: MotionBlurProps) => new MotionBlur(config),\n\tssao: (config?: SSAOProps) => new SSAO(config),\n\tpbrGlass: (config?: PBRGlassProps) => new PBRGlass(config),\n\tdepthOfField: (config?: DepthOfFieldProps) => new DepthOfField(config),\n\tcrop: (config?: CropProps) => new Crop(config),\n\tvision: (config?: VisionProps) => new Vision(config),\n\trelight3d: (config?: Relight3DProps) => new Relight3D(config),\n\tmodulate: (config?: ModulateProps) => new Modulate(config),\n\tdeflicker: (config?: DeflickerProps) => new TemporalDeflicker(config),\n\tcustom: (op: string, config: Record<string, unknown> = {}) =>\n\t\tnew CustomEffect(op, config),\n});\n\nexport type Effect<TConfig extends object = Record<string, unknown>> =\n\tCoreEffect<TConfig>;\n"],"mappings":"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"}
|