framefields 2.0.9 → 2.0.11
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 +17 -6
- package/dist/audio/index.d.mts +4 -4
- package/dist/audio/index.mjs +10 -10
- package/dist/{audio-BxA0sL9z.d.mts → audio-BHanw8Jb.d.mts} +3 -3
- package/dist/{audio-BxA0sL9z.d.mts.map → audio-BHanw8Jb.d.mts.map} +1 -1
- package/dist/{audio-Dev4NGPa.mjs → audio-COOMNwL5.mjs} +4 -4
- package/dist/{audio-Dev4NGPa.mjs.map → audio-COOMNwL5.mjs.map} +1 -1
- package/dist/{dist-CoSg-CWr.mjs → dist-BAVZdFEJ.mjs} +3 -3
- package/dist/{dist-CoSg-CWr.mjs.map → dist-BAVZdFEJ.mjs.map} +1 -1
- package/dist/{dist-DzUJmIHt.mjs → dist-BYqNNwsl.mjs} +2 -2
- package/dist/{dist-DzUJmIHt.mjs.map → dist-BYqNNwsl.mjs.map} +1 -1
- package/dist/{dist-B9Afsv83.mjs → dist-CbG3QxDw.mjs} +651 -2
- package/dist/dist-CbG3QxDw.mjs.map +1 -0
- package/dist/{dist-DgfykO99.mjs → dist-Cxi68OuY.mjs} +5347 -3286
- package/dist/dist-Cxi68OuY.mjs.map +1 -0
- package/dist/effects/index.d.mts +4 -4
- package/dist/effects/index.mjs +25 -25
- package/dist/{effects-hxRwxjyC.mjs → effects-DzbjFhyA.mjs} +3 -3
- package/dist/{effects-hxRwxjyC.mjs.map → effects-DzbjFhyA.mjs.map} +1 -1
- package/dist/fonts/index.d.mts +2 -2
- package/dist/fonts/index.mjs +1 -1
- package/dist/{fonts-BznIea-I.mjs → fonts-C0W6TgJk.mjs} +52 -5
- package/dist/fonts-C0W6TgJk.mjs.map +1 -0
- package/dist/{index-J9CIK_nu.d.mts → index-9B8CJowc.d.mts} +2 -2
- package/dist/{index-J9CIK_nu.d.mts.map → index-9B8CJowc.d.mts.map} +1 -1
- package/dist/{index-CvDVpaKn.d.mts → index-CDoTrMs1.d.mts} +4 -4
- package/dist/{index-CvDVpaKn.d.mts.map → index-CDoTrMs1.d.mts.map} +1 -1
- package/dist/{index-BXNNJVs8.d.mts → index-CYGpSVsf.d.mts} +2 -2
- package/dist/{index-BXNNJVs8.d.mts.map → index-CYGpSVsf.d.mts.map} +1 -1
- package/dist/{index-D1zaOwEU.d.mts → index-DDEPvMww.d.mts} +520 -71
- package/dist/index-DDEPvMww.d.mts.map +1 -0
- package/dist/{index-oodg5k9K.d.mts → index-DGJp1d30.d.mts} +3 -3
- package/dist/{index-oodg5k9K.d.mts.map → index-DGJp1d30.d.mts.map} +1 -1
- package/dist/{index-fo4E7A6C.d.mts → index-DRZu3ezy.d.mts} +3 -3
- package/dist/{index-fo4E7A6C.d.mts.map → index-DRZu3ezy.d.mts.map} +1 -1
- package/dist/{index-CQcdKyxF.d.mts → index-DnWsbbuZ.d.mts} +54 -2
- package/dist/index-DnWsbbuZ.d.mts.map +1 -0
- package/dist/index.d.mts +398 -18
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +633 -57
- 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-DZTbEON9.mjs → preview-BV2C4Fk6.mjs} +2 -2
- package/dist/{preview-DZTbEON9.mjs.map → preview-BV2C4Fk6.mjs.map} +1 -1
- package/dist/preview-engine/{chunk-VVLM6LZ3.mjs → chunk-6256GQFP.mjs} +1 -1
- package/dist/preview-engine/{chunk-VWLR2AZR.mjs → chunk-AEK5BO3J.mjs} +1 -1
- package/dist/preview-engine/{chunk-YG35X5R5.mjs → chunk-AWTH2WZO.mjs} +1 -1
- package/dist/preview-engine/{chunk-7DIAFPQP.mjs → chunk-ECPP3UG6.mjs} +1 -1
- package/dist/preview-engine/{chunk-5JD65JSJ.mjs → chunk-FGHOHCFG.mjs} +1 -1
- package/dist/preview-engine/chunk-IMV5SBQV.mjs +1 -0
- package/dist/preview-engine/chunk-IQKIHFNZ.mjs +1 -0
- package/dist/preview-engine/chunk-L3IEJZ5S.mjs +474 -0
- package/dist/preview-engine/chunk-M7NMFDJ3.mjs +3 -0
- package/dist/preview-engine/chunk-MJM3NFEC.mjs +315 -0
- package/dist/preview-engine/chunk-NFAGEP43.mjs +1448 -0
- package/dist/preview-engine/{chunk-5PPSCISJ.mjs → chunk-Q66QQI6N.mjs} +1 -1
- package/dist/preview-engine/{chunk-JAOXXYXG.mjs → chunk-QYRDQMNB.mjs} +1 -1
- package/dist/preview-engine/{chunk-XCYFPA34.mjs → chunk-RJUAM52F.mjs} +1 -1
- package/dist/preview-engine/chunk-VRGREB3V.mjs +1 -0
- package/dist/preview-engine/{chunk-AW7HNZKR.mjs → chunk-Y6HWYPKX.mjs} +1 -1
- package/dist/preview-engine/effects.mjs +1 -1
- package/dist/preview-engine/fonts.mjs +1 -1
- package/dist/preview-engine/framefields.mjs +27 -27
- package/dist/preview-engine/player.mjs +1 -1
- package/dist/preview-engine/renderers-5BV6JGTU.mjs +248 -0
- package/dist/preview-engine/renderers-7X2W6QWX.mjs +1 -0
- package/dist/preview-engine/renderers-EOJMPPAQ.mjs +1 -0
- package/dist/preview-engine/renderers-G5KQISVL.mjs +1 -0
- package/dist/preview-engine/renderers-GMX2ZQDG.mjs +1 -0
- package/dist/preview-engine/renderers-TVTQ2R74.mjs +1 -0
- package/dist/preview-engine/renderers-ZIMBODX6.mjs +1 -0
- package/dist/{program-C797QMRL.mjs → program-BmNKgzja.mjs} +281 -23
- package/dist/program-BmNKgzja.mjs.map +1 -0
- package/dist/renderer/index.d.mts +2 -2
- package/dist/renderer/index.mjs +2 -2
- package/dist/{renderer-D-4Yh-RK.mjs → renderer-1VuQTY1Z.mjs} +2 -2
- package/dist/{renderer-D-4Yh-RK.mjs.map → renderer-1VuQTY1Z.mjs.map} +1 -1
- package/dist/renderer-6oMSare3.mjs +3 -0
- package/dist/renderer-B1ComPb2.mjs +3 -0
- package/dist/{renderer-DgSO5OO0.mjs → renderer-B1YMwl2B.mjs} +1 -1
- package/dist/{renderer-9QCHY8Kh.mjs → renderer-B2ieylQ3.mjs} +2 -2
- package/dist/{renderer-9QCHY8Kh.mjs.map → renderer-B2ieylQ3.mjs.map} +1 -1
- package/dist/{renderer-CuqhAB4i.mjs → renderer-B8-kzZdP.mjs} +2 -2
- package/dist/{renderer-CuqhAB4i.mjs.map → renderer-B8-kzZdP.mjs.map} +1 -1
- package/dist/{renderer-Dn8v2o9L.mjs → renderer-B8UaFNqb.mjs} +3 -3
- package/dist/{renderer-Dn8v2o9L.mjs.map → renderer-B8UaFNqb.mjs.map} +1 -1
- package/dist/{renderer-DPpgBTlK.mjs → renderer-BDbTWSpP.mjs} +3 -3
- package/dist/{renderer-DPpgBTlK.mjs.map → renderer-BDbTWSpP.mjs.map} +1 -1
- package/dist/{renderer-CrVAvP92.mjs → renderer-BIIWCg_J.mjs} +3 -3
- package/dist/{renderer-CrVAvP92.mjs.map → renderer-BIIWCg_J.mjs.map} +1 -1
- package/dist/{renderer-5jfDUKd4.mjs → renderer-BJ1aTkZf.mjs} +3 -3
- package/dist/{renderer-5jfDUKd4.mjs.map → renderer-BJ1aTkZf.mjs.map} +1 -1
- package/dist/renderer-BQ5Bz5D0.mjs +3 -0
- package/dist/{renderer-D6Gi_h4K.mjs → renderer-BSaYG8aw.mjs} +1 -1
- package/dist/{renderer-2NQWaZd7.d.mts → renderer-BTdOMMEx.d.mts} +2 -2
- package/dist/{renderer-2NQWaZd7.d.mts.map → renderer-BTdOMMEx.d.mts.map} +1 -1
- package/dist/renderer-BZcn_iBl.mjs +3 -0
- package/dist/{renderer-DnF3aXPX.mjs → renderer-Bc04fivZ.mjs} +3 -3
- package/dist/{renderer-DnF3aXPX.mjs.map → renderer-Bc04fivZ.mjs.map} +1 -1
- package/dist/{renderer-B1UeU7lX.mjs → renderer-BfAWZziM.mjs} +193 -12
- package/dist/renderer-BfAWZziM.mjs.map +1 -0
- package/dist/{renderer-CKJb_Lky.mjs → renderer-Bfgd4N0O.mjs} +3 -3
- package/dist/{renderer-CKJb_Lky.mjs.map → renderer-Bfgd4N0O.mjs.map} +1 -1
- package/dist/{renderer-b6sZN90h.mjs → renderer-BhZZEyFX.mjs} +2 -2
- package/dist/{renderer-b6sZN90h.mjs.map → renderer-BhZZEyFX.mjs.map} +1 -1
- package/dist/{renderer-C-PfbkPu.mjs → renderer-Bhdf90Zq.mjs} +2 -2
- package/dist/{renderer-C-PfbkPu.mjs.map → renderer-Bhdf90Zq.mjs.map} +1 -1
- package/dist/renderer-Bp6sDMa6.mjs +3 -0
- package/dist/renderer-Bt7_sb_Y.mjs +3 -0
- package/dist/{renderer-CB8hMQgm.mjs → renderer-Bv21DbWy.mjs} +1 -1
- package/dist/{renderer-gT0ADXMW.mjs → renderer-Bv6q84TU.mjs} +2 -2
- package/dist/{renderer-gT0ADXMW.mjs.map → renderer-Bv6q84TU.mjs.map} +1 -1
- package/dist/renderer-C606ZPUn.mjs +3 -0
- package/dist/renderer-C9jyKn1i.mjs +3 -0
- package/dist/renderer-CERfcxgv.mjs +3 -0
- package/dist/renderer-CG5PzNkv.mjs +3 -0
- package/dist/{renderer-CpUbDJAV.mjs → renderer-CI7sG_cv.mjs} +2 -2
- package/dist/{renderer-CpUbDJAV.mjs.map → renderer-CI7sG_cv.mjs.map} +1 -1
- package/dist/renderer-CPoIMVdk.mjs +3 -0
- package/dist/{renderer-B4ecTNR7.mjs → renderer-CWTpc4ff.mjs} +2 -2
- package/dist/{renderer-B4ecTNR7.mjs.map → renderer-CWTpc4ff.mjs.map} +1 -1
- package/dist/{renderer-D3uNI10l.mjs → renderer-CXn5HAnK.mjs} +3 -3
- package/dist/{renderer-D3uNI10l.mjs.map → renderer-CXn5HAnK.mjs.map} +1 -1
- package/dist/{renderer-DCK73tcD.mjs → renderer-C_TPMHiH.mjs} +2 -2
- package/dist/{renderer-DCK73tcD.mjs.map → renderer-C_TPMHiH.mjs.map} +1 -1
- package/dist/renderer-Ca7L1EOp.mjs +3 -0
- package/dist/{renderer-6PqlYQjC.mjs → renderer-CaaOKMSd.mjs} +2 -2
- package/dist/{renderer-6PqlYQjC.mjs.map → renderer-CaaOKMSd.mjs.map} +1 -1
- package/dist/{renderer-DX38J6mK.mjs → renderer-CdciwwMI.mjs} +3 -3
- package/dist/{renderer-DX38J6mK.mjs.map → renderer-CdciwwMI.mjs.map} +1 -1
- package/dist/{renderer-DRpE3ZW4.mjs → renderer-CfC_aiew.mjs} +3 -3
- package/dist/{renderer-DRpE3ZW4.mjs.map → renderer-CfC_aiew.mjs.map} +1 -1
- package/dist/{renderer-BE4Ns0nw.mjs → renderer-ChdLYS-G.mjs} +3 -3
- package/dist/{renderer-BE4Ns0nw.mjs.map → renderer-ChdLYS-G.mjs.map} +1 -1
- package/dist/renderer-Cl6GkeHx.mjs +3 -0
- package/dist/renderer-ClcjrFyo.mjs +3 -0
- package/dist/{renderer-B8gTyU3w.mjs → renderer-CnXW28b9.mjs} +2 -2
- package/dist/{renderer-B8gTyU3w.mjs.map → renderer-CnXW28b9.mjs.map} +1 -1
- package/dist/{renderer-C2gnWTQZ.mjs → renderer-Ctk2zzfy.mjs} +3 -3
- package/dist/{renderer-C2gnWTQZ.mjs.map → renderer-Ctk2zzfy.mjs.map} +1 -1
- package/dist/{renderer-EmG34sT2.mjs → renderer-CtyD_Xju.mjs} +2 -2
- package/dist/{renderer-EmG34sT2.mjs.map → renderer-CtyD_Xju.mjs.map} +1 -1
- package/dist/renderer-CySUP_wk.mjs +3 -0
- package/dist/renderer-D2l_Odyg.mjs +3 -0
- package/dist/{renderer-CckJJHbM.mjs → renderer-D2nCGcjv.mjs} +2 -2
- package/dist/{renderer-CckJJHbM.mjs.map → renderer-D2nCGcjv.mjs.map} +1 -1
- package/dist/renderer-DCPCYySt.mjs +3 -0
- package/dist/{renderer-BgqjWI7K.mjs → renderer-DIgsilTw.mjs} +3 -3
- package/dist/{renderer-BgqjWI7K.mjs.map → renderer-DIgsilTw.mjs.map} +1 -1
- package/dist/renderer-DIkpJEOZ.mjs +3 -0
- package/dist/{renderer-CxQ5v4fJ.mjs → renderer-DML9qpmS.mjs} +2 -2
- package/dist/{renderer-CxQ5v4fJ.mjs.map → renderer-DML9qpmS.mjs.map} +1 -1
- package/dist/renderer-DNSXPkf_.mjs +3 -0
- package/dist/renderer-DP-CvZ_Z.mjs +3 -0
- package/dist/renderer-DeXb8R6h.mjs +3 -0
- package/dist/renderer-DezO-ZaP.mjs +4 -0
- package/dist/renderer-DhXe04fC.mjs +3 -0
- package/dist/{renderer-BwmZUkvd.mjs → renderer-DirxsOjq.mjs} +2 -2
- package/dist/{renderer-BwmZUkvd.mjs.map → renderer-DirxsOjq.mjs.map} +1 -1
- package/dist/{renderer-BcPpcKDI.mjs → renderer-Djlb4TLO.mjs} +3 -3
- package/dist/{renderer-BcPpcKDI.mjs.map → renderer-Djlb4TLO.mjs.map} +1 -1
- package/dist/renderer-DnH3SI7w.mjs +3 -0
- package/dist/{renderer-xp_J0ln7.mjs → renderer-DpGc-N3G.mjs} +3 -3
- package/dist/{renderer-xp_J0ln7.mjs.map → renderer-DpGc-N3G.mjs.map} +1 -1
- package/dist/renderer-Dpw4oi33.mjs +3 -0
- package/dist/{renderer-DAFyJ4dv.mjs → renderer-DxTs4Iyi.mjs} +2 -2
- package/dist/{renderer-DAFyJ4dv.mjs.map → renderer-DxTs4Iyi.mjs.map} +1 -1
- package/dist/{renderer-BXaK02qA.mjs → renderer-Dy0utCl7.mjs} +3 -3
- package/dist/{renderer-BXaK02qA.mjs.map → renderer-Dy0utCl7.mjs.map} +1 -1
- package/dist/renderer-Md-ytU0v.mjs +3 -0
- package/dist/{renderer-BTYncYDf.mjs → renderer-RKsXlF_0.mjs} +43 -43
- package/dist/{renderer-BTYncYDf.mjs.map → renderer-RKsXlF_0.mjs.map} +1 -1
- package/dist/renderer-U-bhWO9Q.mjs +3 -0
- package/dist/{renderer-CV8diddR.mjs → renderer-WSGuj_V6.mjs} +2 -2
- package/dist/{renderer-CV8diddR.mjs.map → renderer-WSGuj_V6.mjs.map} +1 -1
- package/dist/{renderer-_bygZSKk.mjs → renderer-bsWnRNpJ.mjs} +2 -2
- package/dist/{renderer-_bygZSKk.mjs.map → renderer-bsWnRNpJ.mjs.map} +1 -1
- package/dist/{renderer-lq4n1hSS.mjs → renderer-cgxO2xN6.mjs} +3 -3
- package/dist/{renderer-lq4n1hSS.mjs.map → renderer-cgxO2xN6.mjs.map} +1 -1
- package/dist/{renderer-zvtpCnqy.mjs → renderer-dncoIVdd.mjs} +1 -1
- package/dist/{renderer-BpJgfBQ8.mjs → renderer-kwmlLQOO.mjs} +3 -3
- package/dist/{renderer-BpJgfBQ8.mjs.map → renderer-kwmlLQOO.mjs.map} +1 -1
- package/dist/{renderer--vY6O19V.mjs → renderer-vqkKWqa5.mjs} +2 -2
- package/dist/{renderer--vY6O19V.mjs.map → renderer-vqkKWqa5.mjs.map} +1 -1
- package/dist/renderer-zA5okHds.mjs +3 -0
- package/dist/{renderers-CP8CFWDs-Ciap7y_j.mjs → renderers-CP8CFWDs-DwQTx8S7.mjs} +3 -3
- package/dist/{renderers-CP8CFWDs-Ciap7y_j.mjs.map → renderers-CP8CFWDs-DwQTx8S7.mjs.map} +1 -1
- package/dist/signals/index.d.mts +5 -5
- package/dist/signals/index.mjs +6 -6
- package/dist/{signals-CsxqD2AA.mjs → signals-Bv1OweKd.mjs} +3 -3
- package/dist/{signals-CsxqD2AA.mjs.map → signals-Bv1OweKd.mjs.map} +1 -1
- package/package.json +55 -55
- package/dist/dist-B9Afsv83.mjs.map +0 -1
- package/dist/dist-DgfykO99.mjs.map +0 -1
- package/dist/fonts-BznIea-I.mjs.map +0 -1
- package/dist/index-CQcdKyxF.d.mts.map +0 -1
- package/dist/index-D1zaOwEU.d.mts.map +0 -1
- package/dist/preview-engine/chunk-BUWK5RJ4.mjs +0 -997
- package/dist/preview-engine/chunk-CNSHAFEA.mjs +0 -1
- package/dist/preview-engine/chunk-OF75EHTX.mjs +0 -418
- package/dist/preview-engine/chunk-UC7CSW2A.mjs +0 -1
- package/dist/preview-engine/chunk-WQ7BFSKF.mjs +0 -3
- package/dist/preview-engine/chunk-ZJFAGIOM.mjs +0 -315
- package/dist/preview-engine/renderers-32PIFHPS.mjs +0 -1
- package/dist/preview-engine/renderers-3Y3EMRDJ.mjs +0 -1
- package/dist/preview-engine/renderers-CHJWUJVI.mjs +0 -1
- package/dist/preview-engine/renderers-CI2GXWLP.mjs +0 -1
- package/dist/preview-engine/renderers-EE2GFG7J.mjs +0 -1
- package/dist/preview-engine/renderers-LTNTQLWE.mjs +0 -248
- package/dist/preview-engine/renderers-UGZUPONY.mjs +0 -1
- package/dist/program-C797QMRL.mjs.map +0 -1
- package/dist/renderer-3uTfN95I.mjs +0 -3
- package/dist/renderer-B1UeU7lX.mjs.map +0 -1
- package/dist/renderer-B5GslTP-.mjs +0 -3
- package/dist/renderer-BUIWeIKQ.mjs +0 -3
- package/dist/renderer-B_LfC88A.mjs +0 -3
- package/dist/renderer-B_zmicsE.mjs +0 -3
- package/dist/renderer-BtNxtXkR.mjs +0 -3
- package/dist/renderer-C-sZSHtf.mjs +0 -3
- package/dist/renderer-C1zifktw.mjs +0 -3
- package/dist/renderer-CCt2XTSM.mjs +0 -3
- package/dist/renderer-CL3evUmF.mjs +0 -3
- package/dist/renderer-CMXcaArD.mjs +0 -3
- package/dist/renderer-CW9D5zCP.mjs +0 -3
- package/dist/renderer-CjY77sB_.mjs +0 -3
- package/dist/renderer-D1R7vBUl.mjs +0 -3
- package/dist/renderer-D5yawxtJ.mjs +0 -3
- package/dist/renderer-DC8jr1Ay.mjs +0 -3
- package/dist/renderer-DCv-Abvn.mjs +0 -4
- package/dist/renderer-DPLFhzaV.mjs +0 -3
- package/dist/renderer-DVsF2FDr.mjs +0 -3
- package/dist/renderer-DetDm3ep.mjs +0 -3
- package/dist/renderer-DhMhJh_G.mjs +0 -3
- package/dist/renderer-DhQld4Qt.mjs +0 -3
- package/dist/renderer-Dn3rc3ah.mjs +0 -3
- package/dist/renderer-Dw9LxE2f.mjs +0 -3
- package/dist/renderer-HvrQZw5E.mjs +0 -3
- package/dist/renderer-QdJE56ts.mjs +0 -3
- package/dist/renderer-euGyUN2O.mjs +0 -3
- package/dist/renderer-p3SmBFP9.mjs +0 -3
|
@@ -1725,6 +1725,655 @@ function computeVideoCropRenderProps(virtualMedia) {
|
|
|
1725
1725
|
cropTranslatePercentageY: -(totalOffsetY / sourceH) * 100
|
|
1726
1726
|
};
|
|
1727
1727
|
}
|
|
1728
|
+
const NAMED = {
|
|
1729
|
+
transparent: "#00000000",
|
|
1730
|
+
black: "#000000",
|
|
1731
|
+
white: "#ffffff",
|
|
1732
|
+
red: "#ff0000",
|
|
1733
|
+
green: "#008000",
|
|
1734
|
+
lime: "#00ff00",
|
|
1735
|
+
blue: "#0000ff",
|
|
1736
|
+
yellow: "#ffff00",
|
|
1737
|
+
cyan: "#00ffff",
|
|
1738
|
+
aqua: "#00ffff",
|
|
1739
|
+
magenta: "#ff00ff",
|
|
1740
|
+
fuchsia: "#ff00ff",
|
|
1741
|
+
orange: "#ffa500",
|
|
1742
|
+
purple: "#800080",
|
|
1743
|
+
pink: "#ffc0cb",
|
|
1744
|
+
gray: "#808080",
|
|
1745
|
+
grey: "#808080",
|
|
1746
|
+
silver: "#c0c0c0",
|
|
1747
|
+
maroon: "#800000",
|
|
1748
|
+
navy: "#000080",
|
|
1749
|
+
teal: "#008080",
|
|
1750
|
+
olive: "#808000",
|
|
1751
|
+
gold: "#ffd700",
|
|
1752
|
+
coral: "#ff7f50",
|
|
1753
|
+
salmon: "#fa8072",
|
|
1754
|
+
crimson: "#dc143c",
|
|
1755
|
+
indigo: "#4b0082",
|
|
1756
|
+
violet: "#ee82ee",
|
|
1757
|
+
turquoise: "#40e0d0",
|
|
1758
|
+
tomato: "#ff6347",
|
|
1759
|
+
chocolate: "#d2691e",
|
|
1760
|
+
tan: "#d2b48c",
|
|
1761
|
+
beige: "#f5f5dc",
|
|
1762
|
+
ivory: "#fffff0",
|
|
1763
|
+
khaki: "#f0e68c",
|
|
1764
|
+
lavender: "#e6e6fa",
|
|
1765
|
+
mint: "#98ff98",
|
|
1766
|
+
skyblue: "#87ceeb",
|
|
1767
|
+
slategray: "#708090",
|
|
1768
|
+
dimgray: "#696969",
|
|
1769
|
+
lightgray: "#d3d3d3",
|
|
1770
|
+
darkgray: "#a9a9a9",
|
|
1771
|
+
whitesmoke: "#f5f5f5",
|
|
1772
|
+
hotpink: "#ff69b4",
|
|
1773
|
+
deeppink: "#ff1493",
|
|
1774
|
+
dodgerblue: "#1e90ff",
|
|
1775
|
+
royalblue: "#4169e1",
|
|
1776
|
+
steelblue: "#4682b4",
|
|
1777
|
+
midnightblue: "#191970",
|
|
1778
|
+
limegreen: "#32cd32",
|
|
1779
|
+
forestgreen: "#228b22",
|
|
1780
|
+
seagreen: "#2e8b57",
|
|
1781
|
+
darkorange: "#ff8c00",
|
|
1782
|
+
orangered: "#ff4500",
|
|
1783
|
+
firebrick: "#b22222",
|
|
1784
|
+
rebeccapurple: "#663399"
|
|
1785
|
+
};
|
|
1786
|
+
const clamp01 = (v) => v < 0 ? 0 : v > 1 ? 1 : v;
|
|
1787
|
+
function parseHex(h) {
|
|
1788
|
+
if (!/^[0-9a-f]+$/i.test(h)) return null;
|
|
1789
|
+
const x = (i, n) => parseInt(n === 1 ? h[i] + h[i] : h.slice(i, i + 2), 16) / 255;
|
|
1790
|
+
switch (h.length) {
|
|
1791
|
+
case 3: return [
|
|
1792
|
+
x(0, 1),
|
|
1793
|
+
x(1, 1),
|
|
1794
|
+
x(2, 1),
|
|
1795
|
+
1
|
|
1796
|
+
];
|
|
1797
|
+
case 4: return [
|
|
1798
|
+
x(0, 1),
|
|
1799
|
+
x(1, 1),
|
|
1800
|
+
x(2, 1),
|
|
1801
|
+
x(3, 1)
|
|
1802
|
+
];
|
|
1803
|
+
case 6: return [
|
|
1804
|
+
x(0, 2),
|
|
1805
|
+
x(2, 2),
|
|
1806
|
+
x(4, 2),
|
|
1807
|
+
1
|
|
1808
|
+
];
|
|
1809
|
+
case 8: return [
|
|
1810
|
+
x(0, 2),
|
|
1811
|
+
x(2, 2),
|
|
1812
|
+
x(4, 2),
|
|
1813
|
+
x(6, 2)
|
|
1814
|
+
];
|
|
1815
|
+
default: return null;
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
/** Splits `rgb(1 2 3 / 50%)` or `rgb(1, 2, 3, .5)` into its argument tokens. */
|
|
1819
|
+
function fnArgs(body) {
|
|
1820
|
+
return body.replace(/\s*\/\s*/, " ").split(/[\s,]+/).filter(Boolean);
|
|
1821
|
+
}
|
|
1822
|
+
/** A number, or a percentage scaled so 100% = `pct100`. */
|
|
1823
|
+
function num(tok, pct100) {
|
|
1824
|
+
if (tok === void 0 || tok === "none") return 0;
|
|
1825
|
+
if (tok.endsWith("%")) return parseFloat(tok) / 100 * pct100;
|
|
1826
|
+
return parseFloat(tok);
|
|
1827
|
+
}
|
|
1828
|
+
function hue(tok) {
|
|
1829
|
+
if (tok === void 0) return 0;
|
|
1830
|
+
if (tok.endsWith("turn")) return parseFloat(tok) * 360;
|
|
1831
|
+
if (tok.endsWith("rad")) return parseFloat(tok) * 180 / Math.PI;
|
|
1832
|
+
return parseFloat(tok);
|
|
1833
|
+
}
|
|
1834
|
+
function alpha(tok) {
|
|
1835
|
+
return tok === void 0 ? 1 : clamp01(num(tok, 1));
|
|
1836
|
+
}
|
|
1837
|
+
function hslToRgb(h, s, l) {
|
|
1838
|
+
const a = s * Math.min(l, 1 - l);
|
|
1839
|
+
const f = (n) => {
|
|
1840
|
+
const k = (n + h / 30) % 12;
|
|
1841
|
+
return l - a * Math.max(-1, Math.min(k - 3, 9 - k, 1));
|
|
1842
|
+
};
|
|
1843
|
+
return [
|
|
1844
|
+
f(0),
|
|
1845
|
+
f(8),
|
|
1846
|
+
f(4)
|
|
1847
|
+
];
|
|
1848
|
+
}
|
|
1849
|
+
const toLinear = (c) => c <= .04045 ? c / 12.92 : ((c + .055) / 1.055) ** 2.4;
|
|
1850
|
+
const toGamma = (c) => c <= .0031308 ? 12.92 * c : 1.055 * c ** (1 / 2.4) - .055;
|
|
1851
|
+
/** sRGB (0..1) → OKLab [L, a, b]. */
|
|
1852
|
+
function rgbToOklab(r, g, b) {
|
|
1853
|
+
const lr = toLinear(r);
|
|
1854
|
+
const lg = toLinear(g);
|
|
1855
|
+
const lb = toLinear(b);
|
|
1856
|
+
const l = Math.cbrt(.4122214708 * lr + .5363325363 * lg + .0514459929 * lb);
|
|
1857
|
+
const m = Math.cbrt(.2119034982 * lr + .6806995451 * lg + .1073969566 * lb);
|
|
1858
|
+
const s = Math.cbrt(.0883024619 * lr + .2817188376 * lg + .6299787005 * lb);
|
|
1859
|
+
return [
|
|
1860
|
+
.2104542553 * l + .793617785 * m - .0040720468 * s,
|
|
1861
|
+
1.9779984951 * l - 2.428592205 * m + .4505937099 * s,
|
|
1862
|
+
.0259040371 * l + .7827717662 * m - .808675766 * s
|
|
1863
|
+
];
|
|
1864
|
+
}
|
|
1865
|
+
/** OKLab → sRGB (0..1, clamped to gamut). */
|
|
1866
|
+
function oklabToRgb(L, a, b) {
|
|
1867
|
+
const l = (L + .3963377774 * a + .2158037573 * b) ** 3;
|
|
1868
|
+
const m = (L - .1055613458 * a - .0638541728 * b) ** 3;
|
|
1869
|
+
const s = (L - .0894841775 * a - 1.291485548 * b) ** 3;
|
|
1870
|
+
return [
|
|
1871
|
+
clamp01(toGamma(4.0767416621 * l - 3.3077115913 * m + .2309699292 * s)),
|
|
1872
|
+
clamp01(toGamma(-1.2684380046 * l + 2.6097574011 * m - .3413193965 * s)),
|
|
1873
|
+
clamp01(toGamma(-.0041960863 * l - .7034186147 * m + 1.707614701 * s))
|
|
1874
|
+
];
|
|
1875
|
+
}
|
|
1876
|
+
/**
|
|
1877
|
+
* Parses any CSS color this engine accepts: hex (3/4/6/8), `rgb()`/`rgba()`,
|
|
1878
|
+
* `hsl()`/`hsla()`, `oklch()`, `oklab()` (comma or space syntax, `/ alpha`)
|
|
1879
|
+
* and common named colors. Returns `null` when the string is not a color.
|
|
1880
|
+
*/
|
|
1881
|
+
function parseCssColor(input) {
|
|
1882
|
+
const s = input.trim().toLowerCase();
|
|
1883
|
+
if (!s) return null;
|
|
1884
|
+
if (s.startsWith("#")) return parseHex(s.slice(1));
|
|
1885
|
+
const named = NAMED[s];
|
|
1886
|
+
if (named) return parseHex(named.slice(1));
|
|
1887
|
+
const m = /^([a-z]+)\((.*)\)$/.exec(s);
|
|
1888
|
+
if (!m) return null;
|
|
1889
|
+
const [, fn, body] = m;
|
|
1890
|
+
const t = fnArgs(body);
|
|
1891
|
+
switch (fn) {
|
|
1892
|
+
case "rgb":
|
|
1893
|
+
case "rgba": return [
|
|
1894
|
+
clamp01(num(t[0], 255) / 255),
|
|
1895
|
+
clamp01(num(t[1], 255) / 255),
|
|
1896
|
+
clamp01(num(t[2], 255) / 255),
|
|
1897
|
+
alpha(t[3])
|
|
1898
|
+
];
|
|
1899
|
+
case "hsl":
|
|
1900
|
+
case "hsla": {
|
|
1901
|
+
const [r, g, b] = hslToRgb((hue(t[0]) % 360 + 360) % 360, clamp01(num(t[1], 100) / 100), clamp01(num(t[2], 100) / 100));
|
|
1902
|
+
return [
|
|
1903
|
+
r,
|
|
1904
|
+
g,
|
|
1905
|
+
b,
|
|
1906
|
+
alpha(t[3])
|
|
1907
|
+
];
|
|
1908
|
+
}
|
|
1909
|
+
case "oklch": {
|
|
1910
|
+
const L = num(t[0], 1);
|
|
1911
|
+
const C = num(t[1], .4);
|
|
1912
|
+
const H = hue(t[2]) * Math.PI / 180;
|
|
1913
|
+
const [r, g, b] = oklabToRgb(L, C * Math.cos(H), C * Math.sin(H));
|
|
1914
|
+
return [
|
|
1915
|
+
r,
|
|
1916
|
+
g,
|
|
1917
|
+
b,
|
|
1918
|
+
alpha(t[3])
|
|
1919
|
+
];
|
|
1920
|
+
}
|
|
1921
|
+
case "oklab": {
|
|
1922
|
+
const [r, g, b] = oklabToRgb(num(t[0], 1), num(t[1], .4), num(t[2], .4));
|
|
1923
|
+
return [
|
|
1924
|
+
r,
|
|
1925
|
+
g,
|
|
1926
|
+
b,
|
|
1927
|
+
alpha(t[3])
|
|
1928
|
+
];
|
|
1929
|
+
}
|
|
1930
|
+
default: return null;
|
|
1931
|
+
}
|
|
1932
|
+
}
|
|
1933
|
+
/** Formats straight sRGB as `#rrggbb` (or `#rrggbbaa` when translucent). */
|
|
1934
|
+
function formatHex([r, g, b, a]) {
|
|
1935
|
+
const h = (v) => Math.round(clamp01(v) * 255).toString(16).padStart(2, "0");
|
|
1936
|
+
return `#${h(r)}${h(g)}${h(b)}${a < .999 ? h(a) : ""}`;
|
|
1937
|
+
}
|
|
1938
|
+
const parseOr = (c) => parseCssColor(c) ?? [
|
|
1939
|
+
0,
|
|
1940
|
+
0,
|
|
1941
|
+
0,
|
|
1942
|
+
0
|
|
1943
|
+
];
|
|
1944
|
+
/**
|
|
1945
|
+
* Mixes two colors perceptually (in OKLab), `t` = 0 → `a`, 1 → `b`.
|
|
1946
|
+
* Midpoints keep their lightness and saturation instead of going muddy
|
|
1947
|
+
* the way a plain sRGB lerp does.
|
|
1948
|
+
*/
|
|
1949
|
+
function mixColors(a, b, t) {
|
|
1950
|
+
const ca = parseOr(a);
|
|
1951
|
+
const cb = parseOr(b);
|
|
1952
|
+
const pa = ca[3] < 1e-4 ? cb : ca;
|
|
1953
|
+
const pb = cb[3] < 1e-4 ? ca : cb;
|
|
1954
|
+
const la = rgbToOklab(pa[0], pa[1], pa[2]);
|
|
1955
|
+
const lb = rgbToOklab(pb[0], pb[1], pb[2]);
|
|
1956
|
+
const k = clamp01(t);
|
|
1957
|
+
const [r, g, bl] = oklabToRgb(la[0] + (lb[0] - la[0]) * k, la[1] + (lb[1] - la[1]) * k, la[2] + (lb[2] - la[2]) * k);
|
|
1958
|
+
return formatHex([
|
|
1959
|
+
r,
|
|
1960
|
+
g,
|
|
1961
|
+
bl,
|
|
1962
|
+
ca[3] + (cb[3] - ca[3]) * k
|
|
1963
|
+
]);
|
|
1964
|
+
}
|
|
1965
|
+
/** Samples a multi-stop gradient (stops in any order) at `t` ∈ [0, 1]. */
|
|
1966
|
+
function sampleColorStops(stops, t) {
|
|
1967
|
+
const list = normalizeColorStops(stops);
|
|
1968
|
+
if (list.length === 0) return "#00000000";
|
|
1969
|
+
if (t <= list[0].offset) return list[0].color;
|
|
1970
|
+
for (let i = 1; i < list.length; i++) {
|
|
1971
|
+
const b = list[i];
|
|
1972
|
+
if (t <= b.offset) {
|
|
1973
|
+
const a = list[i - 1];
|
|
1974
|
+
const span = b.offset - a.offset;
|
|
1975
|
+
return mixColors(a.color, b.color, span > 0 ? (t - a.offset) / span : 1);
|
|
1976
|
+
}
|
|
1977
|
+
}
|
|
1978
|
+
return list[list.length - 1].color;
|
|
1979
|
+
}
|
|
1980
|
+
/** Bare color strings become evenly spaced stops; result is sorted by offset. */
|
|
1981
|
+
function normalizeColorStops(stops) {
|
|
1982
|
+
const n = stops.length;
|
|
1983
|
+
return stops.map((s, i) => typeof s === "string" ? {
|
|
1984
|
+
offset: n > 1 ? i / (n - 1) : 0,
|
|
1985
|
+
color: s
|
|
1986
|
+
} : {
|
|
1987
|
+
offset: clamp01(s.offset),
|
|
1988
|
+
color: s.color
|
|
1989
|
+
}).sort((a, b) => a.offset - b.offset);
|
|
1990
|
+
}
|
|
1991
|
+
function oklchOf(c) {
|
|
1992
|
+
const [r, g, b, a] = parseOr(c);
|
|
1993
|
+
const [L, A, B] = rgbToOklab(r, g, b);
|
|
1994
|
+
return [
|
|
1995
|
+
L,
|
|
1996
|
+
Math.hypot(A, B),
|
|
1997
|
+
Math.atan2(B, A) * 180 / Math.PI,
|
|
1998
|
+
a
|
|
1999
|
+
];
|
|
2000
|
+
}
|
|
2001
|
+
function fromOklch(L, C, H, a) {
|
|
2002
|
+
const h = H * Math.PI / 180;
|
|
2003
|
+
const [r, g, b] = oklabToRgb(L, C * Math.cos(h), C * Math.sin(h));
|
|
2004
|
+
return formatHex([
|
|
2005
|
+
r,
|
|
2006
|
+
g,
|
|
2007
|
+
b,
|
|
2008
|
+
a
|
|
2009
|
+
]);
|
|
2010
|
+
}
|
|
2011
|
+
/**
|
|
2012
|
+
* Authoring helpers for colors. Every function returns a hex string, so the
|
|
2013
|
+
* result drops straight into any color prop or keyframe.
|
|
2014
|
+
*
|
|
2015
|
+
* ```ts
|
|
2016
|
+
* Color.oklch(0.7, 0.15, 250) // perceptual: equal L reads equally bright
|
|
2017
|
+
* Color.hsl(212, 0.95, 0.74)
|
|
2018
|
+
* Color.mix("#ff5a1f", "#1f6bff", 0.5) // OKLab, no muddy midpoint
|
|
2019
|
+
* const wave = Color.ramp(["#3b82f6", "#8b5cf6", "#ec4899"]);
|
|
2020
|
+
* wave(0.5) // sample a gradient
|
|
2021
|
+
* Color.lighten("#ff5a1f", 0.1), Color.alpha("#000", 0.4)
|
|
2022
|
+
* ```
|
|
2023
|
+
*/
|
|
2024
|
+
const Color = {
|
|
2025
|
+
parse: parseCssColor,
|
|
2026
|
+
hex(c) {
|
|
2027
|
+
return formatHex(parseOr(c));
|
|
2028
|
+
},
|
|
2029
|
+
rgb(r, g, b, a = 1) {
|
|
2030
|
+
return formatHex([
|
|
2031
|
+
r / 255,
|
|
2032
|
+
g / 255,
|
|
2033
|
+
b / 255,
|
|
2034
|
+
a
|
|
2035
|
+
]);
|
|
2036
|
+
},
|
|
2037
|
+
hsl(h, s, l, a = 1) {
|
|
2038
|
+
const [r, g, b] = hslToRgb((h % 360 + 360) % 360, clamp01(s), clamp01(l));
|
|
2039
|
+
return formatHex([
|
|
2040
|
+
r,
|
|
2041
|
+
g,
|
|
2042
|
+
b,
|
|
2043
|
+
a
|
|
2044
|
+
]);
|
|
2045
|
+
},
|
|
2046
|
+
oklch(l, c, h, a = 1) {
|
|
2047
|
+
return fromOklch(l, c, h, a);
|
|
2048
|
+
},
|
|
2049
|
+
mix: mixColors,
|
|
2050
|
+
ramp(stops) {
|
|
2051
|
+
const list = normalizeColorStops(stops);
|
|
2052
|
+
return (t) => sampleColorStops(list, t);
|
|
2053
|
+
},
|
|
2054
|
+
steps(stops, n) {
|
|
2055
|
+
const list = normalizeColorStops(stops);
|
|
2056
|
+
return Array.from({ length: n }, (_, i) => sampleColorStops(list, n > 1 ? i / (n - 1) : 0));
|
|
2057
|
+
},
|
|
2058
|
+
lighten(c, amount) {
|
|
2059
|
+
const [L, C, H, a] = oklchOf(c);
|
|
2060
|
+
return fromOklch(clamp01(L + amount), C, H, a);
|
|
2061
|
+
},
|
|
2062
|
+
darken(c, amount) {
|
|
2063
|
+
const [L, C, H, a] = oklchOf(c);
|
|
2064
|
+
return fromOklch(clamp01(L - amount), C, H, a);
|
|
2065
|
+
},
|
|
2066
|
+
saturate(c, factor) {
|
|
2067
|
+
const [L, C, H, a] = oklchOf(c);
|
|
2068
|
+
return fromOklch(L, C * factor, H, a);
|
|
2069
|
+
},
|
|
2070
|
+
rotate(c, degrees) {
|
|
2071
|
+
const [L, C, H, a] = oklchOf(c);
|
|
2072
|
+
return fromOklch(L, C, H + degrees, a);
|
|
2073
|
+
},
|
|
2074
|
+
alpha(c, a) {
|
|
2075
|
+
const [r, g, b] = parseOr(c);
|
|
2076
|
+
return formatHex([
|
|
2077
|
+
r,
|
|
2078
|
+
g,
|
|
2079
|
+
b,
|
|
2080
|
+
clamp01(a)
|
|
2081
|
+
]);
|
|
2082
|
+
},
|
|
2083
|
+
contrast(a, b) {
|
|
2084
|
+
const lum = (c) => {
|
|
2085
|
+
const [r, g, bl] = parseOr(c);
|
|
2086
|
+
return .2126 * toLinear(r) + .7152 * toLinear(g) + .0722 * toLinear(bl);
|
|
2087
|
+
};
|
|
2088
|
+
const [hi, lo] = [lum(a), lum(b)].sort((x, y) => y - x);
|
|
2089
|
+
return (hi + .05) / (lo + .05);
|
|
2090
|
+
},
|
|
2091
|
+
readableOn(background) {
|
|
2092
|
+
return Color.contrast(background, "#ffffff") >= Color.contrast(background, "#000000") ? "#ffffff" : "#000000";
|
|
2093
|
+
}
|
|
2094
|
+
};
|
|
2095
|
+
/**
|
|
2096
|
+
* CSS gradients (`linear-gradient`, `radial-gradient`, `conic-gradient`) as
|
|
2097
|
+
* values for any `background` or shape `fill`, plus `Gradient` helpers that
|
|
2098
|
+
* write them. Colors blend perceptually (OKLab), not through muddy sRGB.
|
|
2099
|
+
*/
|
|
2100
|
+
/** Gradients this renderer draws at most this many stops (extra ones are resampled). */
|
|
2101
|
+
const MAX_GRADIENT_STOPS = 8;
|
|
2102
|
+
const GRADIENT_RE = /^\s*(linear|radial|conic)-gradient\(\s*([\s\S]*)\)\s*$/i;
|
|
2103
|
+
function isCssGradient(value) {
|
|
2104
|
+
return typeof value === "string" && GRADIENT_RE.test(value);
|
|
2105
|
+
}
|
|
2106
|
+
/** Splits on commas that are not inside parentheses. */
|
|
2107
|
+
function splitTopLevel(s) {
|
|
2108
|
+
const out = [];
|
|
2109
|
+
let depth = 0;
|
|
2110
|
+
let cur = "";
|
|
2111
|
+
for (const ch of s) {
|
|
2112
|
+
if (ch === "(") depth++;
|
|
2113
|
+
if (ch === ")") depth--;
|
|
2114
|
+
if (ch === "," && depth === 0) {
|
|
2115
|
+
out.push(cur.trim());
|
|
2116
|
+
cur = "";
|
|
2117
|
+
} else cur += ch;
|
|
2118
|
+
}
|
|
2119
|
+
if (cur.trim()) out.push(cur.trim());
|
|
2120
|
+
return out;
|
|
2121
|
+
}
|
|
2122
|
+
function parseAngle(tok) {
|
|
2123
|
+
const m = /^(-?[\d.]+)(deg|turn|rad|grad)?$/i.exec(tok.trim());
|
|
2124
|
+
if (!m) return null;
|
|
2125
|
+
const v = parseFloat(m[1]);
|
|
2126
|
+
switch ((m[2] ?? "deg").toLowerCase()) {
|
|
2127
|
+
case "turn": return v * 360;
|
|
2128
|
+
case "rad": return v * 180 / Math.PI;
|
|
2129
|
+
case "grad": return v * .9;
|
|
2130
|
+
default: return v;
|
|
2131
|
+
}
|
|
2132
|
+
}
|
|
2133
|
+
const SIDE_ANGLES = {
|
|
2134
|
+
top: 0,
|
|
2135
|
+
right: 90,
|
|
2136
|
+
bottom: 180,
|
|
2137
|
+
left: 270,
|
|
2138
|
+
"top right": 45,
|
|
2139
|
+
"right top": 45,
|
|
2140
|
+
"bottom right": 135,
|
|
2141
|
+
"right bottom": 135,
|
|
2142
|
+
"bottom left": 225,
|
|
2143
|
+
"left bottom": 225,
|
|
2144
|
+
"top left": 315,
|
|
2145
|
+
"left top": 315
|
|
2146
|
+
};
|
|
2147
|
+
const POSITION_KEYWORDS = {
|
|
2148
|
+
left: 0,
|
|
2149
|
+
top: 0,
|
|
2150
|
+
center: .5,
|
|
2151
|
+
right: 1,
|
|
2152
|
+
bottom: 1
|
|
2153
|
+
};
|
|
2154
|
+
/** `at 30% 70%`, `at left top`, `at center`. */
|
|
2155
|
+
function parsePosition(tokens) {
|
|
2156
|
+
const vals = tokens.map((t) => t in POSITION_KEYWORDS ? {
|
|
2157
|
+
v: POSITION_KEYWORDS[t],
|
|
2158
|
+
axis: t === "top" || t === "bottom" ? "y" : t === "left" || t === "right" ? "x" : "any"
|
|
2159
|
+
} : {
|
|
2160
|
+
v: t.endsWith("%") ? parseFloat(t) / 100 : .5,
|
|
2161
|
+
axis: "any"
|
|
2162
|
+
});
|
|
2163
|
+
let x = .5;
|
|
2164
|
+
let y = .5;
|
|
2165
|
+
if (vals.length === 1) if (vals[0].axis === "y") y = vals[0].v;
|
|
2166
|
+
else x = vals[0].v;
|
|
2167
|
+
else if (vals.length >= 2) if (vals[0].axis === "y" || vals[1].axis === "x") {
|
|
2168
|
+
y = vals[0].v;
|
|
2169
|
+
x = vals[1].v;
|
|
2170
|
+
} else {
|
|
2171
|
+
x = vals[0].v;
|
|
2172
|
+
y = vals[1].v;
|
|
2173
|
+
}
|
|
2174
|
+
return [x, y];
|
|
2175
|
+
}
|
|
2176
|
+
/** Parses one `color [pos] [pos]` stop list entry; positions in 0..1 (or px later). */
|
|
2177
|
+
function parseStop(s) {
|
|
2178
|
+
const m = /^((?:[a-z]+\([^)]*\))|#[0-9a-f]+|[a-z]+)\s*(.*)$/i.exec(s.trim());
|
|
2179
|
+
if (!m) return null;
|
|
2180
|
+
const color = parseCssColor(m[1]);
|
|
2181
|
+
if (!color) return null;
|
|
2182
|
+
const positions = [];
|
|
2183
|
+
for (const p of m[2].split(/\s+/).filter(Boolean)) if (p.endsWith("%")) positions.push(parseFloat(p) / 100);
|
|
2184
|
+
else if (p === "0") positions.push(0);
|
|
2185
|
+
else if (/(deg|turn|rad|grad)$/i.test(p)) {
|
|
2186
|
+
const a = parseAngle(p);
|
|
2187
|
+
if (a !== null) positions.push(a / 360);
|
|
2188
|
+
}
|
|
2189
|
+
return {
|
|
2190
|
+
color,
|
|
2191
|
+
positions: positions.filter((p) => Number.isFinite(p))
|
|
2192
|
+
};
|
|
2193
|
+
}
|
|
2194
|
+
/** CSS stop fixup: clamp ascending, spread unpositioned stops evenly. */
|
|
2195
|
+
function resolveStops(raw) {
|
|
2196
|
+
const n = raw.length;
|
|
2197
|
+
if (n === 0) return [];
|
|
2198
|
+
const pos = raw.map((r) => r.position);
|
|
2199
|
+
if (pos[0] === void 0) pos[0] = 0;
|
|
2200
|
+
if (pos[n - 1] === void 0) pos[n - 1] = 1;
|
|
2201
|
+
let maxSoFar = -Infinity;
|
|
2202
|
+
for (let i = 0; i < n; i++) {
|
|
2203
|
+
const p = pos[i];
|
|
2204
|
+
if (p !== void 0) {
|
|
2205
|
+
pos[i] = Math.max(p, maxSoFar);
|
|
2206
|
+
maxSoFar = pos[i];
|
|
2207
|
+
}
|
|
2208
|
+
}
|
|
2209
|
+
for (let i = 1; i < n; i++) {
|
|
2210
|
+
if (pos[i] !== void 0) continue;
|
|
2211
|
+
let j = i;
|
|
2212
|
+
while (pos[j] === void 0) j++;
|
|
2213
|
+
const a = pos[i - 1];
|
|
2214
|
+
const b = pos[j];
|
|
2215
|
+
for (let k = i; k < j; k++) pos[k] = a + (b - a) * (k - i + 1) / (j - i + 1);
|
|
2216
|
+
}
|
|
2217
|
+
return raw.map((r, i) => ({
|
|
2218
|
+
offset: pos[i],
|
|
2219
|
+
color: r.color
|
|
2220
|
+
}));
|
|
2221
|
+
}
|
|
2222
|
+
const cache = /* @__PURE__ */ new Map();
|
|
2223
|
+
/** Parses a CSS gradient string; `null` when it is not one this engine draws. */
|
|
2224
|
+
function parseCssGradient(input) {
|
|
2225
|
+
const hit = cache.get(input);
|
|
2226
|
+
if (hit !== void 0) return hit;
|
|
2227
|
+
const result = parseUncached(input);
|
|
2228
|
+
if (cache.size > 512) cache.clear();
|
|
2229
|
+
cache.set(input, result);
|
|
2230
|
+
return result;
|
|
2231
|
+
}
|
|
2232
|
+
function parseUncached(input) {
|
|
2233
|
+
const m = GRADIENT_RE.exec(input);
|
|
2234
|
+
if (!m) return null;
|
|
2235
|
+
const type = m[1].toLowerCase();
|
|
2236
|
+
const parts = splitTopLevel(m[2]);
|
|
2237
|
+
const g = {
|
|
2238
|
+
type,
|
|
2239
|
+
angle: 180,
|
|
2240
|
+
center: [.5, .5],
|
|
2241
|
+
shape: "ellipse",
|
|
2242
|
+
from: 0,
|
|
2243
|
+
stops: []
|
|
2244
|
+
};
|
|
2245
|
+
const first = parts[0]?.toLowerCase().trim() ?? "";
|
|
2246
|
+
let consumedFirst = false;
|
|
2247
|
+
if (type === "linear") if (first.startsWith("to ")) {
|
|
2248
|
+
const side = first.slice(3).trim().replace(/\s+/g, " ");
|
|
2249
|
+
if (side in SIDE_ANGLES) {
|
|
2250
|
+
g.angle = SIDE_ANGLES[side];
|
|
2251
|
+
consumedFirst = true;
|
|
2252
|
+
}
|
|
2253
|
+
} else {
|
|
2254
|
+
const a = parseAngle(first);
|
|
2255
|
+
if (a !== null) {
|
|
2256
|
+
g.angle = a;
|
|
2257
|
+
consumedFirst = true;
|
|
2258
|
+
}
|
|
2259
|
+
}
|
|
2260
|
+
else {
|
|
2261
|
+
const tokens = first.split(/\s+/).filter(Boolean);
|
|
2262
|
+
const at = tokens.indexOf("at");
|
|
2263
|
+
const before = at >= 0 ? tokens.slice(0, at) : tokens;
|
|
2264
|
+
if (at >= 0 || before.some((t) => t === "circle" || t === "ellipse" || t === "from" || /^closest|^farthest/.test(t) || type === "radial" && /px$/.test(t))) {
|
|
2265
|
+
consumedFirst = true;
|
|
2266
|
+
if (at >= 0) g.center = parsePosition(tokens.slice(at + 1));
|
|
2267
|
+
if (type === "radial") {
|
|
2268
|
+
if (before.includes("circle")) g.shape = "circle";
|
|
2269
|
+
const px = before.filter((t) => /px$/.test(t)).map((t) => parseFloat(t));
|
|
2270
|
+
if (px.length === 1) {
|
|
2271
|
+
g.shape = "circle";
|
|
2272
|
+
g.radius = [px[0], px[0]];
|
|
2273
|
+
} else if (px.length >= 2) g.radius = [px[0], px[1]];
|
|
2274
|
+
} else {
|
|
2275
|
+
const f = before.indexOf("from");
|
|
2276
|
+
if (f >= 0 && before[f + 1]) g.from = parseAngle(before[f + 1]) ?? 0;
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
const raw = [];
|
|
2281
|
+
for (const p of consumedFirst ? parts.slice(1) : parts) {
|
|
2282
|
+
const stop = parseStop(p);
|
|
2283
|
+
if (!stop) return null;
|
|
2284
|
+
if (stop.positions.length === 0) raw.push({ color: stop.color });
|
|
2285
|
+
for (const pos of stop.positions) raw.push({
|
|
2286
|
+
color: stop.color,
|
|
2287
|
+
position: pos
|
|
2288
|
+
});
|
|
2289
|
+
}
|
|
2290
|
+
if (raw.length === 0) return null;
|
|
2291
|
+
if (raw.length === 1) raw.push({ ...raw[0] });
|
|
2292
|
+
g.stops = resolveStops(raw);
|
|
2293
|
+
return g;
|
|
2294
|
+
}
|
|
2295
|
+
/** Up to MAX_GRADIENT_STOPS stops: longer lists are resampled evenly. */
|
|
2296
|
+
function limitGradientStops(stops) {
|
|
2297
|
+
if (stops.length <= MAX_GRADIENT_STOPS) return stops;
|
|
2298
|
+
const out = [];
|
|
2299
|
+
const lo = stops[0].offset;
|
|
2300
|
+
const hi = stops[stops.length - 1].offset;
|
|
2301
|
+
for (let i = 0; i < MAX_GRADIENT_STOPS; i++) {
|
|
2302
|
+
const t = lo + (hi - lo) * i / (MAX_GRADIENT_STOPS - 1);
|
|
2303
|
+
let k = 1;
|
|
2304
|
+
while (k < stops.length - 1 && stops[k].offset < t) k++;
|
|
2305
|
+
const a = stops[k - 1];
|
|
2306
|
+
const b = stops[k];
|
|
2307
|
+
const span = b.offset - a.offset;
|
|
2308
|
+
const f = span > 0 ? Math.min(1, Math.max(0, (t - a.offset) / span)) : 1;
|
|
2309
|
+
out.push({
|
|
2310
|
+
offset: t,
|
|
2311
|
+
color: a.color.map((v, j) => v + (b.color[j] - v) * f)
|
|
2312
|
+
});
|
|
2313
|
+
}
|
|
2314
|
+
return out;
|
|
2315
|
+
}
|
|
2316
|
+
/**
|
|
2317
|
+
* Stops as OKLab + alpha for the GPU. A transparent stop borrows its
|
|
2318
|
+
* neighbor's color, so fading to `transparent` keeps the hue instead of
|
|
2319
|
+
* passing through grey (CSS premultiplied interpolation does the same).
|
|
2320
|
+
*/
|
|
2321
|
+
function gradientStopsToOklab(stops) {
|
|
2322
|
+
const lab = stops.map((s) => rgbToOklab(s.color[0], s.color[1], s.color[2]));
|
|
2323
|
+
return stops.map((s, i) => {
|
|
2324
|
+
let src = lab[i];
|
|
2325
|
+
if (s.color[3] < 1e-4) {
|
|
2326
|
+
const prev = stops.slice(0, i).reverse().findIndex((p) => p.color[3] > 1e-4);
|
|
2327
|
+
const next = stops.slice(i + 1).findIndex((p) => p.color[3] > 1e-4);
|
|
2328
|
+
const pi = prev >= 0 ? i - 1 - prev : -1;
|
|
2329
|
+
const ni = next >= 0 ? i + 1 + next : -1;
|
|
2330
|
+
if (pi >= 0 && ni >= 0) {
|
|
2331
|
+
const a = lab[pi];
|
|
2332
|
+
const b = lab[ni];
|
|
2333
|
+
src = [
|
|
2334
|
+
(a[0] + b[0]) / 2,
|
|
2335
|
+
(a[1] + b[1]) / 2,
|
|
2336
|
+
(a[2] + b[2]) / 2
|
|
2337
|
+
];
|
|
2338
|
+
} else if (pi >= 0) src = lab[pi];
|
|
2339
|
+
else if (ni >= 0) src = lab[ni];
|
|
2340
|
+
}
|
|
2341
|
+
return [
|
|
2342
|
+
src[0],
|
|
2343
|
+
src[1],
|
|
2344
|
+
src[2],
|
|
2345
|
+
s.color[3]
|
|
2346
|
+
];
|
|
2347
|
+
});
|
|
2348
|
+
}
|
|
2349
|
+
function stopList(stops) {
|
|
2350
|
+
return stops.map((s) => typeof s === "string" ? s : `${s.color} ${Math.round(s.offset * 1e4) / 100}%`).join(", ");
|
|
2351
|
+
}
|
|
2352
|
+
/**
|
|
2353
|
+
* Writes CSS gradient strings for `background` / `fill`:
|
|
2354
|
+
*
|
|
2355
|
+
* ```ts
|
|
2356
|
+
* Layer.box({ background: Gradient.linear(["#ff5a1f", "#7c3aed"], 135) })
|
|
2357
|
+
* Layer.shape("circle", { fill: Gradient.radial(["#fff", "transparent"]) })
|
|
2358
|
+
* Gradient.conic(["red", "yellow", "lime", "aqua", "blue", "magenta", "red"])
|
|
2359
|
+
* ```
|
|
2360
|
+
* Plain strings work too: `"linear-gradient(to right, #000, #fff 80%)"`.
|
|
2361
|
+
*/
|
|
2362
|
+
const Gradient = {
|
|
2363
|
+
linear(stops, angle = 180) {
|
|
2364
|
+
return `linear-gradient(${angle}deg, ${stopList(stops)})`;
|
|
2365
|
+
},
|
|
2366
|
+
radial(stops, options = {}) {
|
|
2367
|
+
const at = options.at ?? [.5, .5];
|
|
2368
|
+
return `radial-gradient(${options.radius !== void 0 ? `${options.radius}px` : options.circle ? "circle" : "ellipse"} at ${at[0] * 100}% ${at[1] * 100}%, ${stopList(stops)})`;
|
|
2369
|
+
},
|
|
2370
|
+
conic(stops, options = {}) {
|
|
2371
|
+
const at = options.at ?? [.5, .5];
|
|
2372
|
+
return `conic-gradient(from ${options.from ?? 0}deg at ${at[0] * 100}% ${at[1] * 100}%, ${stopList(stops)})`;
|
|
2373
|
+
},
|
|
2374
|
+
parse: parseCssGradient,
|
|
2375
|
+
is: isCssGradient
|
|
2376
|
+
};
|
|
1728
2377
|
/**
|
|
1729
2378
|
* Performs a deep comparison between two values to determine if they are equivalent.
|
|
1730
2379
|
* Handles primitives, objects, arrays, Dates, and NaNs.
|
|
@@ -1900,5 +2549,5 @@ function extractSvgDimensions(buffer) {
|
|
|
1900
2549
|
}
|
|
1901
2550
|
|
|
1902
2551
|
//#endregion
|
|
1903
|
-
export {
|
|
1904
|
-
//# sourceMappingURL=dist-
|
|
2552
|
+
export { TimelineTransformSchema as $, serializeSignalData as $t, MIME_TYPES as A, gradientStopsToOklab as At, OutputItemSchema as B, parseCssColor as Bt, FileDataSchema as C, generateId as Ct, HandleTypeVal as D, getLeafMediaType as Dt, Gradient as E, getFingerprint as Et, ModerationUnrefundableError as F, isVirtualMediaData as Ft, SignalGateDataSchema as G, reportRenderDiagnostic as Gt, Signal as H, programmaticSignal as Ht, MultiOutputGenericSchema as I, limitGradientStops as It, SingleOutputGenericSchema as J, resolveNumber as Jt, SignalMathDataSchema as K, resolveBoolean as Kt, NodeMetadataSchema as L, mixColors as Lt, MediaOperationSchema as M, isCssGradient as Mt, MediaSourceSchema as N, isEqual as Nt, JsonValueSchema as O, getMediaType as Ot, ModerationError as P, isSignal as Pt, TimelineSegmentSchema as Q, sampleColorStops as Qt, NodeResultSchema as R, normalizeColorStops as Rt, FileAssetSchema as S, frameSignal as St, GlobalCompositeOperation as T, getFileDataMetadata as Tt, SignalChannelMetaSchema as U, progressSignal as Ut, ProgrammaticSignal as V, parseCssGradient as Vt, SignalDataSchema as W, registerSignalDependency as Wt, TEXT_LAYER_DEFAULTS as X, resolveString as Xt, SourceOperationSchema as Y, resolveParam as Yt, TextOperationSchema as Z, rgbToOklab as Zt, DataTypeVal as _, deserializeSignalData as _t, BaseVideoLayerPropsSchema as a, timeSignal as an, VideoStylePropsSchema as at, ExportResultSchema as b, formatHex as bt, COMPOSITOR_DEFAULTS as c, VirtualMediaDataSchema as ct, ConfigSchemaRegistry as d, computeVideoCropRenderProps as dt, signal as en, TransitionSchema as et, DATA_TYPE_EXTENSIONS as f, computed as ft, DataType as g, dataTypeColors as gt, DEFAULT_MEDIA_DIMENSION as h, createVirtualMedia as ht, BaseMediaOperationPropsSchema as i, takeRenderDiagnostics as in, VideoSpatialPropsSchema as it, MediaMetadataSchema as j, hasOnlySingleSource as jt, MAX_GRADIENT_STOPS as k, getRenderFingerprint as kt, Color as l, appendOperation as lt, DEFAULT_FPS as m, createOutputItemSchema as mt, AnyOutputUnionSchema as n, sineSignal as nn, VideoAnimationSchema as nt, CAPTION_LAYER_DEFAULTS as o, updateClockSignals as on, VideoTextPropsSchema as ot, DEFAULT_DURATION_MS as p, cosineSignal as pt, SignalStatsSchema as q, resolveMediaMimeType as qt, AudioExtractorSignalDataSchema as r, stampResult as rn, VideoLayerTypeSchema as rt, COMPOSITE_OPERATIONS as s, VideoTimingPropsSchema as st, AnimationTypeSchema as t, signalBuilder as tn, TransitionTypeSchema as tt, ConfigHandleSchema as u, checkNodeResultCache as ut, DataTypes as v, extractSvgDimensions as vt, GeneratorSignalDataSchema as w, getActiveMediaMetadata as wt, ExtendedLayerSchema as x, frameArraySignal as xt, Effect as y, findSourceAsset as yt, NodeVisualConfigSchema as z, oklabToRgb as zt };
|
|
2553
|
+
//# sourceMappingURL=dist-CbG3QxDw.mjs.map
|