@ignix-social/editor 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +190 -0
- package/NOTICE +54 -0
- package/README.md +23 -0
- package/bin/ignix-editor.mjs +8 -0
- package/package.json +53 -0
- package/patches/index.mjs +53 -0
- package/scripts/build-ffmpeg-macos.sh +35 -0
- package/scripts/build-whisper-macos.sh +21 -0
- package/scripts/vendor.mjs +41 -0
- package/skills/ignix-editor/SKILL.md +132 -0
- package/src/audio.mjs +31 -0
- package/src/binaries.json +46 -0
- package/src/binaries.mjs +83 -0
- package/src/cli.mjs +254 -0
- package/src/prepare.mjs +74 -0
- package/src/runtime/ignix-frame.js +92 -0
- package/src/transcribe.mjs +71 -0
- package/src/validate.mjs +71 -0
- package/templates/blank/index.html +41 -0
- package/vendor/hyperframes/README.md +181 -0
- package/vendor/hyperframes/UPSTREAM.json +12 -0
- package/vendor/hyperframes/bin/hyperframes-localize-fonts.mjs +12 -0
- package/vendor/hyperframes/bin/hyperframes.mjs +11 -0
- package/vendor/hyperframes/dist/add-LR3ZR2A5.js +79 -0
- package/vendor/hyperframes/dist/agentPromptGenerator-VIIPZCJ3.js +143 -0
- package/vendor/hyperframes/dist/animatedGifPrep-P2T6YM7Z.js +34 -0
- package/vendor/hyperframes/dist/asset-BE2DOV72.js +26 -0
- package/vendor/hyperframes/dist/assetCataloger-VBLPHX24.js +340 -0
- package/vendor/hyperframes/dist/auth-RCQB2ZT7.js +60 -0
- package/vendor/hyperframes/dist/autoUpdate-RJAX3DAZ.js +268 -0
- package/vendor/hyperframes/dist/backgroundChecks-H2LCUIMJ.js +61 -0
- package/vendor/hyperframes/dist/backgroundChecksWorker.js +26 -0
- package/vendor/hyperframes/dist/batchRender-FT7AP7XH.js +355 -0
- package/vendor/hyperframes/dist/beat-analyzer.global.js +338 -0
- package/vendor/hyperframes/dist/beats-Y2EOP72P.js +309 -0
- package/vendor/hyperframes/dist/benchmark-MZ7GY3JW.js +231 -0
- package/vendor/hyperframes/dist/browser-HUTAMRQE.js +237 -0
- package/vendor/hyperframes/dist/bundleWithLocalizedFonts-5QOPOB5D.js +52 -0
- package/vendor/hyperframes/dist/capture-RLZA6EMR.js +4079 -0
- package/vendor/hyperframes/dist/capture-SZZ4IYJK.js +290 -0
- package/vendor/hyperframes/dist/captureFile-LYOJOUIE.js +15 -0
- package/vendor/hyperframes/dist/captureTimeout-PA4FYWT5.js +27 -0
- package/vendor/hyperframes/dist/catalog-KYU55EWR.js +1001 -0
- package/vendor/hyperframes/dist/check-TCG4PXLR.js +1697 -0
- package/vendor/hyperframes/dist/checkBrowser-RPMO4OW5.js +1032 -0
- package/vendor/hyperframes/dist/chunk-2EAXUCCE.js +88 -0
- package/vendor/hyperframes/dist/chunk-2EGFTPWD.js +1077 -0
- package/vendor/hyperframes/dist/chunk-2PSPARWP.js +6058 -0
- package/vendor/hyperframes/dist/chunk-2YN64IN5.js +5747 -0
- package/vendor/hyperframes/dist/chunk-3GXQPCJC.js +682 -0
- package/vendor/hyperframes/dist/chunk-3ZP5DXE7.js +15 -0
- package/vendor/hyperframes/dist/chunk-4NWOGZZS.js +1990 -0
- package/vendor/hyperframes/dist/chunk-4PFZPP2N.js +587 -0
- package/vendor/hyperframes/dist/chunk-4THIAPBL.js +128 -0
- package/vendor/hyperframes/dist/chunk-4YYJOFKS.js +28 -0
- package/vendor/hyperframes/dist/chunk-54HJ63Q2.js +29 -0
- package/vendor/hyperframes/dist/chunk-5ETJX6WM.js +89 -0
- package/vendor/hyperframes/dist/chunk-5IAKAQA7.js +389 -0
- package/vendor/hyperframes/dist/chunk-5Z63TBTX.js +37 -0
- package/vendor/hyperframes/dist/chunk-6BEFEWFB.js +25 -0
- package/vendor/hyperframes/dist/chunk-6CSYCFQV.js +68 -0
- package/vendor/hyperframes/dist/chunk-6CTIGJY7.js +154 -0
- package/vendor/hyperframes/dist/chunk-7HG4BFIN.js +93 -0
- package/vendor/hyperframes/dist/chunk-7JZ4FXP2.js +118 -0
- package/vendor/hyperframes/dist/chunk-A2Z4Z4VL.js +2961 -0
- package/vendor/hyperframes/dist/chunk-AMKC3AXA.js +25 -0
- package/vendor/hyperframes/dist/chunk-AVUUN2XD.js +4847 -0
- package/vendor/hyperframes/dist/chunk-AWDFDFI3.js +46 -0
- package/vendor/hyperframes/dist/chunk-AWNBM3MZ.js +94 -0
- package/vendor/hyperframes/dist/chunk-BXCMXMJQ.js +73 -0
- package/vendor/hyperframes/dist/chunk-BZ56MTDX.js +6 -0
- package/vendor/hyperframes/dist/chunk-CFKU7HTK.js +171 -0
- package/vendor/hyperframes/dist/chunk-CWPVM2QV.js +308 -0
- package/vendor/hyperframes/dist/chunk-DPVXBVLL.js +31292 -0
- package/vendor/hyperframes/dist/chunk-DQBY7FRR.js +397 -0
- package/vendor/hyperframes/dist/chunk-E6RPWJVC.js +213 -0
- package/vendor/hyperframes/dist/chunk-EISRN4E6.js +294 -0
- package/vendor/hyperframes/dist/chunk-EOVYQ3IG.js +143 -0
- package/vendor/hyperframes/dist/chunk-F3WZGU7C.js +479 -0
- package/vendor/hyperframes/dist/chunk-FCSIGXXP.js +366 -0
- package/vendor/hyperframes/dist/chunk-FI4I7CME.js +56 -0
- package/vendor/hyperframes/dist/chunk-FLWXXDNS.js +15 -0
- package/vendor/hyperframes/dist/chunk-GK4AIFIH.js +11171 -0
- package/vendor/hyperframes/dist/chunk-GMECXFAN.js +57 -0
- package/vendor/hyperframes/dist/chunk-GULOKZLI.js +155 -0
- package/vendor/hyperframes/dist/chunk-H4YZZ2VQ.js +68 -0
- package/vendor/hyperframes/dist/chunk-H6QMKUYA.js +477 -0
- package/vendor/hyperframes/dist/chunk-HBBJFK6I.js +273 -0
- package/vendor/hyperframes/dist/chunk-HRUGC23L.js +212 -0
- package/vendor/hyperframes/dist/chunk-HVW7ABXD.js +19 -0
- package/vendor/hyperframes/dist/chunk-HW6OYASV.js +344 -0
- package/vendor/hyperframes/dist/chunk-HWKCIWQT.js +3578 -0
- package/vendor/hyperframes/dist/chunk-I465DBM6.js +1214 -0
- package/vendor/hyperframes/dist/chunk-IGLEPPTN.js +24 -0
- package/vendor/hyperframes/dist/chunk-IGNAAHS3.js +433 -0
- package/vendor/hyperframes/dist/chunk-IHFUKJOR.js +85 -0
- package/vendor/hyperframes/dist/chunk-IQ3OUQ5Z.js +213 -0
- package/vendor/hyperframes/dist/chunk-ISN5GRYI.js +20 -0
- package/vendor/hyperframes/dist/chunk-IUZFXWSV.js +446 -0
- package/vendor/hyperframes/dist/chunk-JH556Q42.js +647 -0
- package/vendor/hyperframes/dist/chunk-JTHMTOMQ.js +601 -0
- package/vendor/hyperframes/dist/chunk-K2EQN4VU.js +405 -0
- package/vendor/hyperframes/dist/chunk-K2FTXJYH.js +16044 -0
- package/vendor/hyperframes/dist/chunk-K4WIOZFP.js +32 -0
- package/vendor/hyperframes/dist/chunk-K4WKGXRC.js +18 -0
- package/vendor/hyperframes/dist/chunk-KBJUXVOJ.js +172 -0
- package/vendor/hyperframes/dist/chunk-KC5XXX3X.js +590 -0
- package/vendor/hyperframes/dist/chunk-KNU5COPB.js +29 -0
- package/vendor/hyperframes/dist/chunk-KZI44OPA.js +185 -0
- package/vendor/hyperframes/dist/chunk-L3YOGIPG.js +48 -0
- package/vendor/hyperframes/dist/chunk-LAOCA3MQ.js +189 -0
- package/vendor/hyperframes/dist/chunk-LCSMOLGX.js +312 -0
- package/vendor/hyperframes/dist/chunk-LFGJWOVA.js +61 -0
- package/vendor/hyperframes/dist/chunk-LHSR3M4M.js +498 -0
- package/vendor/hyperframes/dist/chunk-LYNI3FOL.js +123 -0
- package/vendor/hyperframes/dist/chunk-M2WBOQ2Q.js +54 -0
- package/vendor/hyperframes/dist/chunk-MRF4AMKD.js +104 -0
- package/vendor/hyperframes/dist/chunk-MWB3ZIFM.js +852 -0
- package/vendor/hyperframes/dist/chunk-NGKM64BP.js +39 -0
- package/vendor/hyperframes/dist/chunk-NXMYHJAL.js +43 -0
- package/vendor/hyperframes/dist/chunk-OAF4XJOW.js +192 -0
- package/vendor/hyperframes/dist/chunk-OFQWTKPW.js +117 -0
- package/vendor/hyperframes/dist/chunk-P6LJ4Y32.js +4662 -0
- package/vendor/hyperframes/dist/chunk-PBN6GBJE.js +108 -0
- package/vendor/hyperframes/dist/chunk-PDAMK4Q5.js +28 -0
- package/vendor/hyperframes/dist/chunk-PFCFR3KZ.js +20 -0
- package/vendor/hyperframes/dist/chunk-PJ3HDUCY.js +108 -0
- package/vendor/hyperframes/dist/chunk-PMRBLBUP.js +152 -0
- package/vendor/hyperframes/dist/chunk-PPQUYWTW.js +240 -0
- package/vendor/hyperframes/dist/chunk-Q5X2B5WT.js +29 -0
- package/vendor/hyperframes/dist/chunk-Q7IU7MOR.js +351 -0
- package/vendor/hyperframes/dist/chunk-QC4FJVLM.js +371 -0
- package/vendor/hyperframes/dist/chunk-QNYYOUU3.js +1318 -0
- package/vendor/hyperframes/dist/chunk-RDNNAKEP.js +161 -0
- package/vendor/hyperframes/dist/chunk-RMHUQGRK.js +657 -0
- package/vendor/hyperframes/dist/chunk-RQVDTPGD.js +6 -0
- package/vendor/hyperframes/dist/chunk-RVCWIIZ7.js +68 -0
- package/vendor/hyperframes/dist/chunk-S3D6GE5W.js +72 -0
- package/vendor/hyperframes/dist/chunk-S3S4TGEH.js +424 -0
- package/vendor/hyperframes/dist/chunk-S7NPLFWV.js +11395 -0
- package/vendor/hyperframes/dist/chunk-SHB5VDMH.js +51 -0
- package/vendor/hyperframes/dist/chunk-TCLGPL65.js +860 -0
- package/vendor/hyperframes/dist/chunk-THXFSPLV.js +40 -0
- package/vendor/hyperframes/dist/chunk-TJSTGSAW.js +354 -0
- package/vendor/hyperframes/dist/chunk-TQFG7HTI.js +1024 -0
- package/vendor/hyperframes/dist/chunk-TVCRUG2S.js +265 -0
- package/vendor/hyperframes/dist/chunk-TWWSYAKJ.js +24 -0
- package/vendor/hyperframes/dist/chunk-U7CZBDMV.js +27 -0
- package/vendor/hyperframes/dist/chunk-UEZXMWG3.js +139 -0
- package/vendor/hyperframes/dist/chunk-UYEZTK4U.js +61 -0
- package/vendor/hyperframes/dist/chunk-VC76R6W2.js +27 -0
- package/vendor/hyperframes/dist/chunk-VFCKXTBB.js +159 -0
- package/vendor/hyperframes/dist/chunk-VWG7OQKU.js +22 -0
- package/vendor/hyperframes/dist/chunk-VXVRPIJA.js +105 -0
- package/vendor/hyperframes/dist/chunk-WBLXWOYK.js +15 -0
- package/vendor/hyperframes/dist/chunk-WERLJGIC.js +20 -0
- package/vendor/hyperframes/dist/chunk-WMQNIQDJ.js +2057 -0
- package/vendor/hyperframes/dist/chunk-WPHMNO44.js +4528 -0
- package/vendor/hyperframes/dist/chunk-X5HWXQPU.js +113 -0
- package/vendor/hyperframes/dist/chunk-X7MTZ4T2.js +6 -0
- package/vendor/hyperframes/dist/chunk-XH4DSOS5.js +59 -0
- package/vendor/hyperframes/dist/chunk-XS4EJSKU.js +23 -0
- package/vendor/hyperframes/dist/chunk-XT5P4QMO.js +181 -0
- package/vendor/hyperframes/dist/chunk-XT7X6QCP.js +6 -0
- package/vendor/hyperframes/dist/chunk-XUHOIDKG.js +6 -0
- package/vendor/hyperframes/dist/chunk-XUXGIA7H.js +485 -0
- package/vendor/hyperframes/dist/chunk-XZABUQTX.js +113 -0
- package/vendor/hyperframes/dist/chunk-Y6W4DVPS.js +356 -0
- package/vendor/hyperframes/dist/chunk-YEIFI443.js +44 -0
- package/vendor/hyperframes/dist/chunk-YQZNILVH.js +375 -0
- package/vendor/hyperframes/dist/chunk-Z27A7NUB.js +65 -0
- package/vendor/hyperframes/dist/chunk-Z6B37SNM.js +3081 -0
- package/vendor/hyperframes/dist/chunk-ZJUKFZ2P.js +10954 -0
- package/vendor/hyperframes/dist/chunk-ZKDMAOFU.js +32 -0
- package/vendor/hyperframes/dist/chunk-ZMXUQLI2.js +17219 -0
- package/vendor/hyperframes/dist/chunk-ZTZ7NCJT.js +58 -0
- package/vendor/hyperframes/dist/chunk-ZTZA4UWZ.js +108 -0
- package/vendor/hyperframes/dist/clean-W57E5YQ3.js +293 -0
- package/vendor/hyperframes/dist/cli.js +495 -0
- package/vendor/hyperframes/dist/cloud-FFTJGZ24.js +70 -0
- package/vendor/hyperframes/dist/cloudrun-AJUTHUEA.js +763 -0
- package/vendor/hyperframes/dist/colors-HKWSZCGK.js +15 -0
- package/vendor/hyperframes/dist/commands/contrast-audit.browser.js +459 -0
- package/vendor/hyperframes/dist/commands/layout-audit.browser.js +2102 -0
- package/vendor/hyperframes/dist/commands/motion-sample.browser.js +74 -0
- package/vendor/hyperframes/dist/commands/motion-signature.browser.js +374 -0
- package/vendor/hyperframes/dist/compare-AYCTT55F.js +421 -0
- package/vendor/hyperframes/dist/compiler-QO36EXLS.js +121 -0
- package/vendor/hyperframes/dist/component-VFFR2O7T.js +176 -0
- package/vendor/hyperframes/dist/compositions-QTVN3U2A.js +228 -0
- package/vendor/hyperframes/dist/contactSheet-27SRU7A4.js +22 -0
- package/vendor/hyperframes/dist/delete-ZAKYCB7I.js +114 -0
- package/vendor/hyperframes/dist/deploy-MX76RZ36.js +101 -0
- package/vendor/hyperframes/dist/destroy-H2TZBYHH.js +42 -0
- package/vendor/hyperframes/dist/deterministicFonts-HAEMV4TM.js +50 -0
- package/vendor/hyperframes/dist/dist-EWXJGN63.js +129 -0
- package/vendor/hyperframes/dist/dist-FNNGCKFS.js +29 -0
- package/vendor/hyperframes/dist/dist-S3PJNPXQ.js +392 -0
- package/vendor/hyperframes/dist/docker/Dockerfile.render +65 -0
- package/vendor/hyperframes/dist/docs/compositions.md +67 -0
- package/vendor/hyperframes/dist/docs/data-attributes.md +27 -0
- package/vendor/hyperframes/dist/docs/examples.md +19 -0
- package/vendor/hyperframes/dist/docs/gsap.md +26 -0
- package/vendor/hyperframes/dist/docs/rendering.md +35 -0
- package/vendor/hyperframes/dist/docs/troubleshooting.md +29 -0
- package/vendor/hyperframes/dist/docs-QAPJEGLS.js +131 -0
- package/vendor/hyperframes/dist/doctor-AI7C3FON.js +67 -0
- package/vendor/hyperframes/dist/dom-IROKGVJI.js +14 -0
- package/vendor/hyperframes/dist/dotEnv-AECLXQSO.js +14 -0
- package/vendor/hyperframes/dist/events-7LALYNKZ.js +92 -0
- package/vendor/hyperframes/dist/events-FQY3HGKZ.js +88 -0
- package/vendor/hyperframes/dist/feedback-WCMDMSTK.js +472 -0
- package/vendor/hyperframes/dist/ffmpeg-QIUFEFTY.js +35 -0
- package/vendor/hyperframes/dist/figma-64WY462P.js +63 -0
- package/vendor/hyperframes/dist/fontData.generated-NXAOI4GH.js +13 -0
- package/vendor/hyperframes/dist/fontLocalizeCli.js +132 -0
- package/vendor/hyperframes/dist/get-FPOMJMZB.js +103 -0
- package/vendor/hyperframes/dist/gpuPolicy-2ZUZE5D6.js +38 -0
- package/vendor/hyperframes/dist/grade-compare-E2CKPST4.js +647 -0
- package/vendor/hyperframes/dist/gsapParser-DIYYX6JT.js +2846 -0
- package/vendor/hyperframes/dist/gsapParserAcorn-E3GEIRZB.js +28 -0
- package/vendor/hyperframes/dist/help-YRQIDDML.js +197 -0
- package/vendor/hyperframes/dist/history-PP5NDRV3.js +571 -0
- package/vendor/hyperframes/dist/hyperframe-runtime.js +1081 -0
- package/vendor/hyperframes/dist/hyperframe.manifest.json +22 -0
- package/vendor/hyperframes/dist/hyperframe.runtime.iife.js +1081 -0
- package/vendor/hyperframes/dist/hyperframes-player.global.js +474 -0
- package/vendor/hyperframes/dist/hyperframes-slideshow.global.js +149 -0
- package/vendor/hyperframes/dist/info-SEX3B7JL.js +153 -0
- package/vendor/hyperframes/dist/init-U3AKHO5B.js +1147 -0
- package/vendor/hyperframes/dist/inspect-Q3K6EDEK.js +97 -0
- package/vendor/hyperframes/dist/installer-K6O5WF44.js +37 -0
- package/vendor/hyperframes/dist/keyframes-DC64JCI3.js +2602 -0
- package/vendor/hyperframes/dist/lambda-D7UMN4DJ.js +451 -0
- package/vendor/hyperframes/dist/layout-XSPPDHOO.js +86 -0
- package/vendor/hyperframes/dist/lib-TPG2ZMAX.js +128 -0
- package/vendor/hyperframes/dist/lint-7DQZE7L3.js +164 -0
- package/vendor/hyperframes/dist/lintProject-OHBBM3DJ.js +27 -0
- package/vendor/hyperframes/dist/list-4K5MVDQX.js +162 -0
- package/vendor/hyperframes/dist/login-NTX4OWXL.js +377 -0
- package/vendor/hyperframes/dist/logout-Q654A3SI.js +100 -0
- package/vendor/hyperframes/dist/manager-67P2XFXQ.js +34 -0
- package/vendor/hyperframes/dist/manager-CT3D67CG.js +38 -0
- package/vendor/hyperframes/dist/manager-GFN75DM4.js +30 -0
- package/vendor/hyperframes/dist/media-treatment-5FYAOPNL.js +972 -0
- package/vendor/hyperframes/dist/media-use-4XXGABIL.js +113 -0
- package/vendor/hyperframes/dist/models-C4E4IWJD.js +137 -0
- package/vendor/hyperframes/dist/motionShot-S4MIGMT5.js +614 -0
- package/vendor/hyperframes/dist/normalize-O76AC4HE.js +333 -0
- package/vendor/hyperframes/dist/normalize-audio-CSFTXLXD.js +276 -0
- package/vendor/hyperframes/dist/open-2ZD6BHZG.js +115 -0
- package/vendor/hyperframes/dist/pipeline-TNGWUZQC.js +54 -0
- package/vendor/hyperframes/dist/play-CTMUXX6E.js +349 -0
- package/vendor/hyperframes/dist/policies-FSDZVS2E.js +292 -0
- package/vendor/hyperframes/dist/preflight-SMNV6RW2.js +45 -0
- package/vendor/hyperframes/dist/present-WQVHV5CR.js +350 -0
- package/vendor/hyperframes/dist/preview-JOJXTH75.js +1820 -0
- package/vendor/hyperframes/dist/producer-ECLEN5RP.js +13 -0
- package/vendor/hyperframes/dist/progress-FBIEEB7Y.js +73 -0
- package/vendor/hyperframes/dist/projectConfig-HYJMJ5BY.js +56 -0
- package/vendor/hyperframes/dist/publication-HQ5Y3KBM.js +29 -0
- package/vendor/hyperframes/dist/publish-VHDYQASC.js +430 -0
- package/vendor/hyperframes/dist/refresh-K24ETHMA.js +53 -0
- package/vendor/hyperframes/dist/remove-background-W2YX2NVH.js +253 -0
- package/vendor/hyperframes/dist/render-AO5VX3YI.js +177 -0
- package/vendor/hyperframes/dist/render-LNO62LEL.js +2367 -0
- package/vendor/hyperframes/dist/render-TTQI7TGN.js +796 -0
- package/vendor/hyperframes/dist/render-batch-YH7CTWNY.js +284 -0
- package/vendor/hyperframes/dist/renderCancellation-JPIHE47X.js +35 -0
- package/vendor/hyperframes/dist/renderSetupWorker.js +79 -0
- package/vendor/hyperframes/dist/resolver-IZ647GBZ.js +38 -0
- package/vendor/hyperframes/dist/runtimeVersion.js +18 -0
- package/vendor/hyperframes/dist/screenshotCapture-ECBTLCU6.js +179 -0
- package/vendor/hyperframes/dist/shaderTransitionWorker.js +44 -0
- package/vendor/hyperframes/dist/sherpa-KKLNW6U2.js +314 -0
- package/vendor/hyperframes/dist/sherpaWorker.js +77 -0
- package/vendor/hyperframes/dist/sites-TNVKZS73.js +52 -0
- package/vendor/hyperframes/dist/skill-ZHVLH7KX.js +15 -0
- package/vendor/hyperframes/dist/skills/hyperframes/SKILL.md +152 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/brief-contract.md +108 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/brief-format.md +72 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/capability-menu.md +47 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/frame-worker-core.md +80 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/intent-interview.md +73 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/pitch-round.md +40 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/plugin-installation.md +43 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/production-loop.md +26 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/review-loop.md +37 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/route-briefs.md +11 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/embedded-captions.md +11 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/faceless-explainer.md +12 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/general-video.md +12 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/motion-graphics.md +11 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/music-to-video.md +12 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/pr-to-video.md +28 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/product-launch-video.md +13 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/remotion-to-hyperframes.md +9 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/slideshow.md +11 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/talking-head-recut.md +11 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/script-format.md +52 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/skill-lifecycle.md +35 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/storyboard-format.md +99 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/subagent-dispatch.md +35 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/workflow-catalog.md +10 -0
- package/vendor/hyperframes/dist/skills/hyperframes/scripts/lib/frame-packets-core.mjs +194 -0
- package/vendor/hyperframes/dist/skills/hyperframes/scripts/plugin-cli.mjs +88 -0
- package/vendor/hyperframes/dist/skills/hyperframes/scripts/plugin-cli.test.mjs +117 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/SKILL.md +189 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/beats.md +19 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/cloud.md +163 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/cloudrun.md +62 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/compare-and-batch.md +105 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/doctor-browser.md +57 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/init-and-scaffold.md +74 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/lambda.md +185 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/lint-validate-inspect.md +132 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/preview-render.md +193 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/upgrade-info-misc.md +134 -0
- package/vendor/hyperframes/dist/skills/media-use/SKILL.md +100 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/CREDITS.md +35 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/chime.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/click-soft.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/click.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/error.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/glitch-1.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/glitch-2.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/glitch-3.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/impact-bass-1.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/impact-bass-2.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/key-press.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/manifest.json +97 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/notification.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/ping.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/pop.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/riser.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/sparkle.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/typing.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/whoosh-cinematic.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/whoosh-short.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/whoosh.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/bgm.md +76 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/captions/authoring.md +163 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/captions/motion.md +87 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/captions/transcript-handling.md +97 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/remove-background.md +143 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/requirements.md +29 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/sfx.md +42 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/transcribe.md +52 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/tts-to-captions.md +35 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/tts.md +260 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/audio.mjs +311 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/audio.test.mjs +159 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/gemini-pipeline.test.mjs +131 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/heygen-tts.mjs +122 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/heygen-tts.test.mjs +38 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/heygen-voice.mjs +98 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/heygen-voice.test.mjs +233 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/audio-meta.mjs +39 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/audio-meta.test.mjs +136 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/bgm-volume.mjs +4 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/bgm.mjs +257 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/bgm.test.mjs +74 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/concurrency.mjs +14 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/concurrency.test.mjs +41 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-auth.mjs +43 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-auth.py +52 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-auth.test.mjs +86 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-auth_test.py +90 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-tts.mjs +122 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-tts.test.mjs +243 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/heygen.mjs +197 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/heygen.test.mjs +185 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/media-record.mjs +114 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/media-record.test.mjs +205 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/python.mjs +77 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/python.test.mjs +136 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/sfx.mjs +165 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/sfx.test.mjs +121 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/tts.mjs +389 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/tts.spawn.test.mjs +158 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/tts.test.mjs +230 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lyria-recipe.py +136 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/wait-bgm.mjs +175 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/wait-bgm.test.mjs +108 -0
- package/vendor/hyperframes/dist/skills/media-use/luts/README.md +28 -0
- package/vendor/hyperframes/dist/skills/media-use/luts/index.json +57 -0
- package/vendor/hyperframes/dist/skills/media-use/references/audio.md +20 -0
- package/vendor/hyperframes/dist/skills/media-use/references/grading.md +160 -0
- package/vendor/hyperframes/dist/skills/media-use/references/media-treatment-recipes.md +929 -0
- package/vendor/hyperframes/dist/skills/media-use/references/media-treatments.md +202 -0
- package/vendor/hyperframes/dist/skills/media-use/references/memory.md +37 -0
- package/vendor/hyperframes/dist/skills/media-use/references/meta.md +61 -0
- package/vendor/hyperframes/dist/skills/media-use/references/operations.md +327 -0
- package/vendor/hyperframes/dist/skills/media-use/references/resolve.md +150 -0
- package/vendor/hyperframes/dist/skills/media-use/references/setup-providers.md +80 -0
- package/vendor/hyperframes/dist/skills/media-use/references/telemetry-dashboard.md +49 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/audio-duck.mjs +113 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/compatibility.test.mjs +96 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/dither.mjs +328 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/dither.test.mjs +176 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/eval.mjs +369 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/adopt.mjs +128 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/adopt.test.mjs +95 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/bgm-provider.mjs +20 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/brand-provider.mjs +59 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/bundled-sfx-provider.mjs +119 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/bundled-sfx-provider.test.mjs +139 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cache.mjs +148 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/candidates.mjs +91 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/candidates.test.mjs +155 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/codex-provider.mjs +161 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/codex-provider.test.mjs +34 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/config-lock.d.mts +3 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/config-lock.mjs +45 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/config-lock.test.mjs +79 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/coverage.test.mjs +136 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cube-build.mjs +181 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cube-build.test.mjs +80 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cube-validate.mjs +198 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cube-validate.test.mjs +125 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cutlist.mjs +184 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cutlist.test.mjs +162 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/duck.mjs +95 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/duck.test.mjs +153 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/error-diffusion.mjs +230 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/error-diffusion.test.mjs +102 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/ff-binaries.mjs +37 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/freeze.mjs +72 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/freeze.test.mjs +138 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/grade-analyzer.mjs +265 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/grade-analyzer.test.mjs +285 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-cli.mjs +191 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-cli.test.mjs +301 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-search.mjs +45 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-search.test.mjs +49 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-video-provider.mjs +138 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-video-provider.test.mjs +435 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/image-provider.mjs +44 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/index-gen.mjs +63 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/local-media-search.mjs +32 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/local-models.mjs +318 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/local-models.test.mjs +220 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/local-run.mjs +78 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/local-run.test.mjs +121 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/logo-provider.mjs +244 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/logo-provider.test.mjs +298 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/ltx-video-provider.mjs +94 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/ltx-video-provider.test.mjs +316 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/lut-preset-provider.mjs +271 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/lut-preset-provider.test.mjs +199 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/manifest.d.mts +19 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/manifest.mjs +279 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/manifest.test.mjs +397 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/match.mjs +47 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-fetch.mjs +85 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-fetch.test.mjs +197 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-home.mjs +20 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-home.test.mjs +61 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-search.d.mts +9 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-search.mjs +107 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/mflux-provider.mjs +128 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/mflux-provider.test.mjs +174 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/misses.mjs +49 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/misses.test.mjs +89 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/npx-sync.mjs +31 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/npx-sync.test.mjs +50 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/parakeet-words.mjs +27 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/parakeet-words.test.mjs +44 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/prefs-store.mjs +180 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/prefs-store.test.mjs +189 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/probe.mjs +41 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/probe.test.mjs +148 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/providers.mjs +5 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/recipe-store.mjs +367 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/recipe-store.test.mjs +367 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/registry.mjs +212 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/registry.test.mjs +262 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/search.mjs +24 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/search.test.mjs +32 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/sfx-provider.mjs +23 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/specs.mjs +132 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/specs.test.mjs +157 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/stats.mjs +117 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/stats.test.mjs +165 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/svg-sanitize.mjs +21 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/telemetry.mjs +210 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/telemetry.test.mjs +437 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/test-home.test.mjs +10 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/transcriptCutFade.mjs +21 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/transcriptCutFade.test.mjs +33 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/tts-local-provider.mjs +94 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/tts-local-provider.test.mjs +72 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/usage.mjs +57 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/usage.test.mjs +54 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/voice-provider.mjs +57 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/voice-provider.test.mjs +46 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/words.mjs +18 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/prefs.mjs +70 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/recipe.mjs +103 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/resolve-plugin.test.mjs +62 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/resolve.mjs +1369 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/transcribe.mjs +194 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/transcribe.test.mjs +112 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/transcript-cut.mjs +270 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/transcript-cut.test.mjs +117 -0
- package/vendor/hyperframes/dist/skills-MJ2J4GEM.js +808 -0
- package/vendor/hyperframes/dist/skillsUpdateCheck-TKTYQN5R.js +26 -0
- package/vendor/hyperframes/dist/slideshow-EJ4IMY6P.js +24 -0
- package/vendor/hyperframes/dist/snapshot-KIVDUUMN.js +875 -0
- package/vendor/hyperframes/dist/src-6YQBJGWR.js +202 -0
- package/vendor/hyperframes/dist/src-PVYUYV3M.js +471 -0
- package/vendor/hyperframes/dist/state-KAXGHF77.js +26 -0
- package/vendor/hyperframes/dist/staticProjectServer-7EU666GS.js +49 -0
- package/vendor/hyperframes/dist/status-YM52BQ6S.js +311 -0
- package/vendor/hyperframes/dist/studio/assets/hyperframes-player-Cp8e_Zst.js +473 -0
- package/vendor/hyperframes/dist/studio/assets/index-BX3KHhGX.js +71 -0
- package/vendor/hyperframes/dist/studio/assets/index-CASEBNy2.js +1 -0
- package/vendor/hyperframes/dist/studio/assets/index-D11atkBt.css +1 -0
- package/vendor/hyperframes/dist/studio/assets/index-DMTt9nTf.js +531 -0
- package/vendor/hyperframes/dist/studio/assets/index-oE1pOdAy.js +399 -0
- package/vendor/hyperframes/dist/studio/chunk-5VSXRGIX.js +948 -0
- package/vendor/hyperframes/dist/studio/chunk-5VSXRGIX.js.map +1 -0
- package/vendor/hyperframes/dist/studio/chunk-7UQWVN52.js +938 -0
- package/vendor/hyperframes/dist/studio/chunk-7UQWVN52.js.map +1 -0
- package/vendor/hyperframes/dist/studio/chunk-EEXSYY5F.js +190 -0
- package/vendor/hyperframes/dist/studio/chunk-EEXSYY5F.js.map +1 -0
- package/vendor/hyperframes/dist/studio/chunk-FOEID72M.js +1441 -0
- package/vendor/hyperframes/dist/studio/chunk-FOEID72M.js.map +1 -0
- package/vendor/hyperframes/dist/studio/chunk-PZ5AY32C.js +10 -0
- package/vendor/hyperframes/dist/studio/chunk-PZ5AY32C.js.map +1 -0
- package/vendor/hyperframes/dist/studio/chunk-TDWGXBUT.js +1103 -0
- package/vendor/hyperframes/dist/studio/chunk-TDWGXBUT.js.map +1 -0
- package/vendor/hyperframes/dist/studio/domEditingLayers-IEVLO54Z.js +47 -0
- package/vendor/hyperframes/dist/studio/domEditingLayers-IEVLO54Z.js.map +1 -0
- package/vendor/hyperframes/dist/studio/favicon.svg +14 -0
- package/vendor/hyperframes/dist/studio/icons/timeline/audio.svg +7 -0
- package/vendor/hyperframes/dist/studio/icons/timeline/captions.svg +5 -0
- package/vendor/hyperframes/dist/studio/icons/timeline/composition.svg +12 -0
- package/vendor/hyperframes/dist/studio/icons/timeline/image.svg +18 -0
- package/vendor/hyperframes/dist/studio/icons/timeline/music.svg +10 -0
- package/vendor/hyperframes/dist/studio/icons/timeline/text.svg +3 -0
- package/vendor/hyperframes/dist/studio/index.css +165 -0
- package/vendor/hyperframes/dist/studio/index.css.map +1 -0
- package/vendor/hyperframes/dist/studio/index.d.ts +4296 -0
- package/vendor/hyperframes/dist/studio/index.html +23 -0
- package/vendor/hyperframes/dist/studio/index.js +99693 -0
- package/vendor/hyperframes/dist/studio/index.js.map +1 -0
- package/vendor/hyperframes/dist/studio/player.d.ts +30 -0
- package/vendor/hyperframes/dist/studio/player.js +10 -0
- package/vendor/hyperframes/dist/studio/player.js.map +1 -0
- package/vendor/hyperframes/dist/studio/styles/tailwind-preset.d.ts +39 -0
- package/vendor/hyperframes/dist/studio/styles/tailwind-preset.js +50 -0
- package/vendor/hyperframes/dist/studio/styles/tailwind-preset.js.map +1 -0
- package/vendor/hyperframes/dist/studio/styles.css +1 -0
- package/vendor/hyperframes/dist/studio/ui.d.ts +296 -0
- package/vendor/hyperframes/dist/studio/ui.js +66 -0
- package/vendor/hyperframes/dist/studio/ui.js.map +1 -0
- package/vendor/hyperframes/dist/studio-api-PNQZRPX5.js +136 -0
- package/vendor/hyperframes/dist/studioSelectionClient-IUUPKUHZ.js +25 -0
- package/vendor/hyperframes/dist/studioServer-UWRBPIOJ.js +1457 -0
- package/vendor/hyperframes/dist/synthesize-K62TIZWI.js +182 -0
- package/vendor/hyperframes/dist/system-EZYZNUFD.js +44 -0
- package/vendor/hyperframes/dist/telemetry-2YC4SGQU.js +144 -0
- package/vendor/hyperframes/dist/telemetry-QMYM4WME.js +95 -0
- package/vendor/hyperframes/dist/templates/_shared/AGENTS.md +107 -0
- package/vendor/hyperframes/dist/templates/_shared/CLAUDE.md +107 -0
- package/vendor/hyperframes/dist/templates/blank/index.html +55 -0
- package/vendor/hyperframes/dist/templates/from-file/index.html +75 -0
- package/vendor/hyperframes/dist/templates/warm-grain/compositions/captions.html +154 -0
- package/vendor/hyperframes/dist/templates/warm-grain/compositions/graphics.html +162 -0
- package/vendor/hyperframes/dist/templates/warm-grain/compositions/intro.html +87 -0
- package/vendor/hyperframes/dist/templates/warm-grain/index.html +264 -0
- package/vendor/hyperframes/dist/templates/warm-grain/registry-item.json +34 -0
- package/vendor/hyperframes/dist/timeline-77Z3BBQM.js +1377 -0
- package/vendor/hyperframes/dist/tokens-OBGTYE4Z.js +92 -0
- package/vendor/hyperframes/dist/transcribe-7NVFHCGA.js +387 -0
- package/vendor/hyperframes/dist/transcribe-BNSJRR4M.js +62 -0
- package/vendor/hyperframes/dist/tts-P3LIPIL5.js +234 -0
- package/vendor/hyperframes/dist/updateCheck-UDWIJ4ZQ.js +39 -0
- package/vendor/hyperframes/dist/upgrade-CT3CPO3E.js +231 -0
- package/vendor/hyperframes/dist/urlDownloader-H6WRI2UE.js +39 -0
- package/vendor/hyperframes/dist/usage-EC3KFUIJ.js +2139 -0
- package/vendor/hyperframes/dist/validate-65QDZJWZ.js +70 -0
- package/vendor/hyperframes/dist/video-FGSGKRSV.js +261 -0
- package/vendor/hyperframes/dist/workspaceBuildCheck-TOLGAI4T.js +133 -0
- package/vendor/hyperframes/package.json +80 -0
|
@@ -0,0 +1,2602 @@
|
|
|
1
|
+
import { createRequire as __hf_createRequire } from "node:module";
|
|
2
|
+
import { fileURLToPath as __hf_fileURLToPath } from "node:url";
|
|
3
|
+
import { dirname as __hf_dirname } from "node:path";
|
|
4
|
+
var require = __hf_createRequire(import.meta.url);
|
|
5
|
+
var __filename = __hf_fileURLToPath(import.meta.url);
|
|
6
|
+
var __dirname = __hf_dirname(__filename);
|
|
7
|
+
import {
|
|
8
|
+
resolveProject
|
|
9
|
+
} from "./chunk-S3D6GE5W.js";
|
|
10
|
+
import "./chunk-IHFUKJOR.js";
|
|
11
|
+
import {
|
|
12
|
+
ensureDOMParser
|
|
13
|
+
} from "./chunk-PFCFR3KZ.js";
|
|
14
|
+
import "./chunk-JTHMTOMQ.js";
|
|
15
|
+
import "./chunk-EISRN4E6.js";
|
|
16
|
+
import "./chunk-VWG7OQKU.js";
|
|
17
|
+
import {
|
|
18
|
+
c
|
|
19
|
+
} from "./chunk-ZTZA4UWZ.js";
|
|
20
|
+
import "./chunk-IUZFXWSV.js";
|
|
21
|
+
import "./chunk-AMKC3AXA.js";
|
|
22
|
+
import {
|
|
23
|
+
defineCommand
|
|
24
|
+
} from "./chunk-S3S4TGEH.js";
|
|
25
|
+
import "./chunk-54HJ63Q2.js";
|
|
26
|
+
import "./chunk-PBN6GBJE.js";
|
|
27
|
+
import "./chunk-K2FTXJYH.js";
|
|
28
|
+
import "./chunk-2YN64IN5.js";
|
|
29
|
+
import "./chunk-AVUUN2XD.js";
|
|
30
|
+
import {
|
|
31
|
+
require_lib,
|
|
32
|
+
require_main
|
|
33
|
+
} from "./chunk-DPVXBVLL.js";
|
|
34
|
+
import "./chunk-Z6B37SNM.js";
|
|
35
|
+
import "./chunk-HWKCIWQT.js";
|
|
36
|
+
import "./chunk-VC76R6W2.js";
|
|
37
|
+
import "./chunk-OFQWTKPW.js";
|
|
38
|
+
import "./chunk-TWWSYAKJ.js";
|
|
39
|
+
import {
|
|
40
|
+
readProjectFile
|
|
41
|
+
} from "./chunk-ZJUKFZ2P.js";
|
|
42
|
+
import "./chunk-HBBJFK6I.js";
|
|
43
|
+
import "./chunk-PJ3HDUCY.js";
|
|
44
|
+
import "./chunk-TQFG7HTI.js";
|
|
45
|
+
import "./chunk-GK4AIFIH.js";
|
|
46
|
+
import {
|
|
47
|
+
ancestor,
|
|
48
|
+
parse,
|
|
49
|
+
simple
|
|
50
|
+
} from "./chunk-2PSPARWP.js";
|
|
51
|
+
import {
|
|
52
|
+
withMeta
|
|
53
|
+
} from "./chunk-HW6OYASV.js";
|
|
54
|
+
import "./chunk-K4WIOZFP.js";
|
|
55
|
+
import "./chunk-XUXGIA7H.js";
|
|
56
|
+
import "./chunk-WERLJGIC.js";
|
|
57
|
+
import "./chunk-ISN5GRYI.js";
|
|
58
|
+
import "./chunk-FLWXXDNS.js";
|
|
59
|
+
import "./chunk-KNU5COPB.js";
|
|
60
|
+
import "./chunk-3GXQPCJC.js";
|
|
61
|
+
import "./chunk-RQVDTPGD.js";
|
|
62
|
+
import "./chunk-PMRBLBUP.js";
|
|
63
|
+
import {
|
|
64
|
+
__toESM
|
|
65
|
+
} from "./chunk-M2WBOQ2Q.js";
|
|
66
|
+
|
|
67
|
+
// src/commands/keyframes.ts
|
|
68
|
+
import { existsSync, readFileSync } from "fs";
|
|
69
|
+
import { resolve, dirname, basename, join, relative, sep } from "path";
|
|
70
|
+
|
|
71
|
+
// ../parsers/dist/gsapParserExports.js
|
|
72
|
+
var recast = __toESM(require_main(), 1);
|
|
73
|
+
var import_parser = __toESM(require_lib(), 1);
|
|
74
|
+
var GSAP_DEFAULT_DURATION = 0.5;
|
|
75
|
+
var BUILTIN_VAR_KEYS = /* @__PURE__ */ new Set(["duration", "ease", "delay"]);
|
|
76
|
+
var DROPPED_VAR_KEYS = /* @__PURE__ */ new Set([
|
|
77
|
+
"onComplete",
|
|
78
|
+
"onStart",
|
|
79
|
+
"onUpdate",
|
|
80
|
+
"onRepeat"
|
|
81
|
+
]);
|
|
82
|
+
var EXTRAS_KEYS = /* @__PURE__ */ new Set([
|
|
83
|
+
"stagger",
|
|
84
|
+
"yoyo",
|
|
85
|
+
"repeat",
|
|
86
|
+
"repeatDelay",
|
|
87
|
+
"snap",
|
|
88
|
+
"overwrite",
|
|
89
|
+
"immediateRender"
|
|
90
|
+
]);
|
|
91
|
+
var PROPERTY_GROUPS = {
|
|
92
|
+
position: /* @__PURE__ */ new Set(["x", "y", "xPercent", "yPercent"]),
|
|
93
|
+
scale: /* @__PURE__ */ new Set(["scale", "scaleX", "scaleY"]),
|
|
94
|
+
size: /* @__PURE__ */ new Set(["width", "height"]),
|
|
95
|
+
rotation: /* @__PURE__ */ new Set(["rotation", "skewX", "skewY"]),
|
|
96
|
+
visual: /* @__PURE__ */ new Set(["opacity", "autoAlpha"]),
|
|
97
|
+
other: /* @__PURE__ */ new Set()
|
|
98
|
+
};
|
|
99
|
+
var PROP_TO_GROUP = /* @__PURE__ */ new Map();
|
|
100
|
+
for (const [group, props] of Object.entries(PROPERTY_GROUPS)) {
|
|
101
|
+
for (const p of props) PROP_TO_GROUP.set(p, group);
|
|
102
|
+
}
|
|
103
|
+
function classifyPropertyGroup(prop) {
|
|
104
|
+
return PROP_TO_GROUP.get(prop) ?? "other";
|
|
105
|
+
}
|
|
106
|
+
function classifyTweenPropertyGroup(properties) {
|
|
107
|
+
const groups = /* @__PURE__ */ new Set();
|
|
108
|
+
for (const key of Object.keys(properties)) {
|
|
109
|
+
if (key === "transformOrigin" || key === "_auto" || key === "data") continue;
|
|
110
|
+
const g = classifyPropertyGroup(key);
|
|
111
|
+
groups.add(g);
|
|
112
|
+
}
|
|
113
|
+
if (groups.size === 1) return groups.values().next().value;
|
|
114
|
+
return void 0;
|
|
115
|
+
}
|
|
116
|
+
function buildArcPath(coords, curviness, autoRotate, isCubic) {
|
|
117
|
+
const first = coords[0];
|
|
118
|
+
if (coords.length < 2 || !first) return void 0;
|
|
119
|
+
const segments = [];
|
|
120
|
+
let waypoints;
|
|
121
|
+
if (isCubic && coords.length >= 4) {
|
|
122
|
+
waypoints = [first];
|
|
123
|
+
for (let i = 1; i + 2 < coords.length; i += 3) {
|
|
124
|
+
const cp1 = coords[i];
|
|
125
|
+
const cp2 = coords[i + 1];
|
|
126
|
+
const anchor = coords[i + 2];
|
|
127
|
+
if (!cp1 || !cp2 || !anchor) continue;
|
|
128
|
+
waypoints.push(anchor);
|
|
129
|
+
segments.push({ curviness, cp1, cp2 });
|
|
130
|
+
}
|
|
131
|
+
} else {
|
|
132
|
+
waypoints = coords;
|
|
133
|
+
for (let i = 0; i < waypoints.length - 1; i++) segments.push({ curviness });
|
|
134
|
+
}
|
|
135
|
+
return { arcPath: { enabled: true, autoRotate, segments }, waypoints };
|
|
136
|
+
}
|
|
137
|
+
var roundPercentage = (percentage) => Math.round(percentage * 10) / 10;
|
|
138
|
+
function getObjectArrayKeyframeTiming(durations) {
|
|
139
|
+
const steps = durations.map((duration) => duration ?? GSAP_DEFAULT_DURATION);
|
|
140
|
+
if (!steps.every(
|
|
141
|
+
(duration) => typeof duration === "number" && Number.isFinite(duration) && duration > 0
|
|
142
|
+
)) {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
const totalDuration = steps.reduce((sum, duration) => sum + duration, 0);
|
|
146
|
+
let cumulative = 0;
|
|
147
|
+
return {
|
|
148
|
+
percentages: steps.map((duration) => {
|
|
149
|
+
cumulative += duration;
|
|
150
|
+
return roundPercentage(cumulative / totalDuration * 100);
|
|
151
|
+
}),
|
|
152
|
+
totalDuration
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
var SKIP_KEYS = /* @__PURE__ */ new Set([
|
|
156
|
+
"type",
|
|
157
|
+
"start",
|
|
158
|
+
"end",
|
|
159
|
+
"loc",
|
|
160
|
+
"range",
|
|
161
|
+
"__hfProvenance",
|
|
162
|
+
"__hfOrder",
|
|
163
|
+
"__hfSiteStart"
|
|
164
|
+
]);
|
|
165
|
+
var FUNCTION_TYPES = /* @__PURE__ */ new Set([
|
|
166
|
+
"ArrowFunctionExpression",
|
|
167
|
+
"FunctionExpression",
|
|
168
|
+
"FunctionDeclaration"
|
|
169
|
+
]);
|
|
170
|
+
var GSAP_METHODS = /* @__PURE__ */ new Set(["set", "to", "from", "fromTo"]);
|
|
171
|
+
var MAX_DEPTH = 8;
|
|
172
|
+
var MAX_ITERS = 512;
|
|
173
|
+
function isFunctionNode(node) {
|
|
174
|
+
return !!node && FUNCTION_TYPES.has(node.type);
|
|
175
|
+
}
|
|
176
|
+
function isNode(x) {
|
|
177
|
+
return !!x && typeof x === "object" && typeof x.type === "string";
|
|
178
|
+
}
|
|
179
|
+
function transformChildren(node, fn) {
|
|
180
|
+
for (const key of Object.keys(node)) {
|
|
181
|
+
if (SKIP_KEYS.has(key) || isNonValueIdentifierSlot(node, key)) continue;
|
|
182
|
+
const child = node[key];
|
|
183
|
+
if (Array.isArray(child)) {
|
|
184
|
+
for (let i = 0; i < child.length; i++) child[i] = fn(child[i]);
|
|
185
|
+
} else {
|
|
186
|
+
node[key] = fn(child);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function cloneNode(node) {
|
|
191
|
+
return structuredClone(node);
|
|
192
|
+
}
|
|
193
|
+
function collectPatternNames(pattern, out) {
|
|
194
|
+
if (pattern?.type === "Identifier") out.add(pattern.name);
|
|
195
|
+
else if (pattern?.type === "AssignmentPattern") collectPatternNames(pattern.left, out);
|
|
196
|
+
else if (pattern?.type === "RestElement") collectPatternNames(pattern.argument, out);
|
|
197
|
+
}
|
|
198
|
+
function boundPatterns(node) {
|
|
199
|
+
if (isFunctionNode(node)) return node.params ?? [];
|
|
200
|
+
if (node.type === "VariableDeclarator") return [node.id];
|
|
201
|
+
if (node.type === "CatchClause") return [node.param];
|
|
202
|
+
if (node.type === "AssignmentExpression" && node.left?.type === "Identifier") return [node.left];
|
|
203
|
+
return [];
|
|
204
|
+
}
|
|
205
|
+
function collectBoundNames(root) {
|
|
206
|
+
const names = /* @__PURE__ */ new Set();
|
|
207
|
+
const visit = (node) => {
|
|
208
|
+
if (!isNode(node)) return node;
|
|
209
|
+
for (const pattern of boundPatterns(node)) collectPatternNames(pattern, names);
|
|
210
|
+
transformChildren(node, visit);
|
|
211
|
+
return node;
|
|
212
|
+
};
|
|
213
|
+
visit(root);
|
|
214
|
+
return names;
|
|
215
|
+
}
|
|
216
|
+
function isNonValueIdentifierSlot(node, key) {
|
|
217
|
+
if (node.computed) return false;
|
|
218
|
+
return node.type === "MemberExpression" && key === "property" || node.type === "Property" && key === "key";
|
|
219
|
+
}
|
|
220
|
+
function substituteParams(node, bindings) {
|
|
221
|
+
const shadowed = collectBoundNames(node);
|
|
222
|
+
let effective = bindings;
|
|
223
|
+
if (shadowed.size > 0) {
|
|
224
|
+
effective = new Map(bindings);
|
|
225
|
+
for (const name of shadowed) effective.delete(name);
|
|
226
|
+
}
|
|
227
|
+
if (effective.size === 0) return node;
|
|
228
|
+
return replace(node, effective);
|
|
229
|
+
}
|
|
230
|
+
function replace(node, bindings) {
|
|
231
|
+
if (!isNode(node)) return node;
|
|
232
|
+
if (node.type === "Identifier" && bindings.has(node.name)) {
|
|
233
|
+
return cloneNode(bindings.get(node.name));
|
|
234
|
+
}
|
|
235
|
+
transformChildren(node, (child) => replace(child, bindings));
|
|
236
|
+
return node;
|
|
237
|
+
}
|
|
238
|
+
function tagProvenance(node, provenance) {
|
|
239
|
+
if (node && typeof node === "object") node.__hfProvenance = provenance;
|
|
240
|
+
return node;
|
|
241
|
+
}
|
|
242
|
+
function readProvenance(node) {
|
|
243
|
+
return node?.__hfProvenance;
|
|
244
|
+
}
|
|
245
|
+
function numericLiteral(value) {
|
|
246
|
+
return { type: "Literal", value, raw: String(value) };
|
|
247
|
+
}
|
|
248
|
+
function walkNodes(node, fn) {
|
|
249
|
+
if (!isNode(node)) return;
|
|
250
|
+
fn(node);
|
|
251
|
+
for (const key of Object.keys(node)) {
|
|
252
|
+
if (SKIP_KEYS.has(key)) continue;
|
|
253
|
+
const child = node[key];
|
|
254
|
+
if (Array.isArray(child)) for (const c2 of child) walkNodes(c2, fn);
|
|
255
|
+
else walkNodes(child, fn);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
function timelineRootName(call) {
|
|
259
|
+
let obj = call.callee?.object;
|
|
260
|
+
while (obj?.type === "CallExpression") obj = obj.callee?.object;
|
|
261
|
+
return obj?.type === "Identifier" ? obj.name : null;
|
|
262
|
+
}
|
|
263
|
+
function isTimelineRooted(call, timelineVar) {
|
|
264
|
+
if (timelineRootName(call) !== timelineVar) return false;
|
|
265
|
+
return call.callee?.property?.type === "Identifier" && GSAP_METHODS.has(call.callee.property.name);
|
|
266
|
+
}
|
|
267
|
+
function isAddLabelCall(call, timelineVar) {
|
|
268
|
+
return timelineRootName(call) === timelineVar && call.callee?.property?.name === "addLabel";
|
|
269
|
+
}
|
|
270
|
+
function containsTimelineCall(node, timelineVar) {
|
|
271
|
+
let found = false;
|
|
272
|
+
walkNodes(node, (n) => {
|
|
273
|
+
if (n.type === "CallExpression" && isTimelineRooted(n, timelineVar)) found = true;
|
|
274
|
+
});
|
|
275
|
+
return found;
|
|
276
|
+
}
|
|
277
|
+
function rangeOf(node) {
|
|
278
|
+
return typeof node.start === "number" && typeof node.end === "number" ? [node.start, node.end] : void 0;
|
|
279
|
+
}
|
|
280
|
+
var SAFE_DEFAULT_NODES = /* @__PURE__ */ new Set([
|
|
281
|
+
"ArrayExpression",
|
|
282
|
+
"BinaryExpression",
|
|
283
|
+
"ChainExpression",
|
|
284
|
+
"ConditionalExpression",
|
|
285
|
+
"Identifier",
|
|
286
|
+
"Literal",
|
|
287
|
+
"LogicalExpression",
|
|
288
|
+
"MemberExpression",
|
|
289
|
+
"ObjectExpression",
|
|
290
|
+
"Property",
|
|
291
|
+
"SpreadElement",
|
|
292
|
+
"TemplateElement",
|
|
293
|
+
"TemplateLiteral",
|
|
294
|
+
"UnaryExpression"
|
|
295
|
+
]);
|
|
296
|
+
function isSafeDefaultExpression(node, earlierParams) {
|
|
297
|
+
let safe = true;
|
|
298
|
+
const visit = (current, parent, key) => {
|
|
299
|
+
if (!isNode(current) || !safe) return;
|
|
300
|
+
if (!SAFE_DEFAULT_NODES.has(current.type)) {
|
|
301
|
+
safe = false;
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
if (current.type === "UnaryExpression" && current.operator === "delete") {
|
|
305
|
+
safe = false;
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
if (current.type === "Identifier") {
|
|
309
|
+
const nonValue = parent && key ? isNonValueIdentifierSlot(parent, key) : false;
|
|
310
|
+
if (!nonValue && current.name !== "undefined" && !earlierParams.has(current.name)) {
|
|
311
|
+
safe = false;
|
|
312
|
+
}
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
for (const childKey of Object.keys(current)) {
|
|
316
|
+
if (SKIP_KEYS.has(childKey)) continue;
|
|
317
|
+
const child = current[childKey];
|
|
318
|
+
if (Array.isArray(child)) {
|
|
319
|
+
for (const item of child) visit(item, current, childKey);
|
|
320
|
+
} else {
|
|
321
|
+
visit(child, current, childKey);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
visit(node);
|
|
326
|
+
return safe;
|
|
327
|
+
}
|
|
328
|
+
var SUPPORTED_PARAMS_CACHE = /* @__PURE__ */ new WeakMap();
|
|
329
|
+
function supportedParam(param, earlier) {
|
|
330
|
+
if (param.type === "Identifier") return { name: param.name };
|
|
331
|
+
if (param.type !== "AssignmentPattern" || param.left?.type !== "Identifier") return null;
|
|
332
|
+
if (!isSafeDefaultExpression(param.right, earlier)) return null;
|
|
333
|
+
return { name: param.left.name, defaultExpression: param.right };
|
|
334
|
+
}
|
|
335
|
+
function supportedParams(fn) {
|
|
336
|
+
if (SUPPORTED_PARAMS_CACHE.has(fn)) return SUPPORTED_PARAMS_CACHE.get(fn) ?? null;
|
|
337
|
+
const params = [];
|
|
338
|
+
const earlier = /* @__PURE__ */ new Set();
|
|
339
|
+
for (const param of fn.params ?? []) {
|
|
340
|
+
const parsed = supportedParam(param, earlier);
|
|
341
|
+
if (!parsed) {
|
|
342
|
+
SUPPORTED_PARAMS_CACHE.set(fn, null);
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
params.push(parsed);
|
|
346
|
+
earlier.add(parsed.name);
|
|
347
|
+
}
|
|
348
|
+
SUPPORTED_PARAMS_CACHE.set(fn, params);
|
|
349
|
+
return params;
|
|
350
|
+
}
|
|
351
|
+
function isShapeEligible(fn) {
|
|
352
|
+
return isFunctionNode(fn) && fn.body?.type === "BlockStatement" && supportedParams(fn) !== null;
|
|
353
|
+
}
|
|
354
|
+
function callsAny(node, names) {
|
|
355
|
+
let hit = false;
|
|
356
|
+
walkNodes(node, (n) => {
|
|
357
|
+
if (n.type === "CallExpression" && n.callee?.type === "Identifier" && names.has(n.callee.name)) {
|
|
358
|
+
hit = true;
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
return hit;
|
|
362
|
+
}
|
|
363
|
+
function varDeclHelper(stmt) {
|
|
364
|
+
if (stmt.declarations?.length !== 1) return null;
|
|
365
|
+
const d = stmt.declarations[0];
|
|
366
|
+
return d.id?.type === "Identifier" && isShapeEligible(d.init) ? [d.id.name, d.init] : null;
|
|
367
|
+
}
|
|
368
|
+
function helperFromStatement(stmt) {
|
|
369
|
+
if (stmt.type === "FunctionDeclaration") {
|
|
370
|
+
return stmt.id && isShapeEligible(stmt) ? [stmt.id.name, stmt] : null;
|
|
371
|
+
}
|
|
372
|
+
if (stmt.type === "VariableDeclaration") return varDeclHelper(stmt);
|
|
373
|
+
return null;
|
|
374
|
+
}
|
|
375
|
+
function gatherHelperCandidates(program) {
|
|
376
|
+
const candidates = /* @__PURE__ */ new Map();
|
|
377
|
+
for (const stmt of program.body ?? []) {
|
|
378
|
+
const helper = helperFromStatement(stmt);
|
|
379
|
+
if (helper) candidates.set(helper[0], helper[1]);
|
|
380
|
+
}
|
|
381
|
+
return candidates;
|
|
382
|
+
}
|
|
383
|
+
function timelineBuildingNames(candidates, timelineVar) {
|
|
384
|
+
const building = /* @__PURE__ */ new Set();
|
|
385
|
+
for (const [name, fn] of candidates) {
|
|
386
|
+
if (containsTimelineCall(fn.body, timelineVar)) building.add(name);
|
|
387
|
+
}
|
|
388
|
+
for (let changed = true; changed; ) {
|
|
389
|
+
changed = false;
|
|
390
|
+
for (const [name, fn] of candidates) {
|
|
391
|
+
if (!building.has(name) && callsAny(fn.body, building)) {
|
|
392
|
+
building.add(name);
|
|
393
|
+
changed = true;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return building;
|
|
398
|
+
}
|
|
399
|
+
function bump(counts, key) {
|
|
400
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
401
|
+
}
|
|
402
|
+
function undefinedIdentifier() {
|
|
403
|
+
return { type: "Identifier", name: "undefined" };
|
|
404
|
+
}
|
|
405
|
+
function isExplicitUndefined(node) {
|
|
406
|
+
return node?.type === "Identifier" && node.name === "undefined" || node?.type === "UnaryExpression" && node.operator === "void" && node.argument?.type === "Literal" && node.argument.value === 0;
|
|
407
|
+
}
|
|
408
|
+
function resolveHelperBindings(call, params) {
|
|
409
|
+
if (call.arguments?.some((arg) => arg?.type === "SpreadElement")) return null;
|
|
410
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
411
|
+
for (let i = 0; i < params.length; i++) {
|
|
412
|
+
const param = params[i];
|
|
413
|
+
const arg = call.arguments?.[i];
|
|
414
|
+
if (arg && !isExplicitUndefined(arg)) {
|
|
415
|
+
bindings.set(param.name, arg);
|
|
416
|
+
} else if (param.defaultExpression) {
|
|
417
|
+
bindings.set(param.name, substituteParams(cloneNode(param.defaultExpression), bindings));
|
|
418
|
+
} else {
|
|
419
|
+
bindings.set(param.name, undefinedIdentifier());
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
return bindings;
|
|
423
|
+
}
|
|
424
|
+
function statementHelperCall(node, names) {
|
|
425
|
+
if (node.type !== "ExpressionStatement") return void 0;
|
|
426
|
+
const expression = node.expression;
|
|
427
|
+
if (expression?.type !== "CallExpression" || expression.callee?.type !== "Identifier") {
|
|
428
|
+
return void 0;
|
|
429
|
+
}
|
|
430
|
+
return names.has(expression.callee.name) ? expression : void 0;
|
|
431
|
+
}
|
|
432
|
+
function safelyDroppable(program, candidates) {
|
|
433
|
+
const names = new Set(candidates.keys());
|
|
434
|
+
const totalIds = /* @__PURE__ */ new Map();
|
|
435
|
+
const stmtCalls = /* @__PURE__ */ new Map();
|
|
436
|
+
const unbindable = /* @__PURE__ */ new Set();
|
|
437
|
+
walkNodes(program, (n) => {
|
|
438
|
+
if (n.type === "Identifier" && names.has(n.name)) bump(totalIds, n.name);
|
|
439
|
+
const call = statementHelperCall(n, names);
|
|
440
|
+
if (!call) return;
|
|
441
|
+
bump(stmtCalls, call.callee.name);
|
|
442
|
+
const fn = candidates.get(call.callee.name);
|
|
443
|
+
const params = fn && supportedParams(fn);
|
|
444
|
+
if (!params || !resolveHelperBindings(call, params)) unbindable.add(call.callee.name);
|
|
445
|
+
});
|
|
446
|
+
const safe = /* @__PURE__ */ new Map();
|
|
447
|
+
for (const [name, fn] of candidates) {
|
|
448
|
+
if (!unbindable.has(name) && (totalIds.get(name) ?? 0) === 1 + (stmtCalls.get(name) ?? 0)) {
|
|
449
|
+
safe.set(name, fn);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
return safe;
|
|
453
|
+
}
|
|
454
|
+
function collectInlinableHelpers(program, timelineVar) {
|
|
455
|
+
const candidates = gatherHelperCandidates(program);
|
|
456
|
+
if (candidates.size === 0) return candidates;
|
|
457
|
+
const building = timelineBuildingNames(candidates, timelineVar);
|
|
458
|
+
for (const name of [...candidates.keys()]) if (!building.has(name)) candidates.delete(name);
|
|
459
|
+
if (candidates.size === 0) return candidates;
|
|
460
|
+
return safelyDroppable(program, candidates);
|
|
461
|
+
}
|
|
462
|
+
function isHelperDecl(stmt, helpers) {
|
|
463
|
+
if (stmt.type === "FunctionDeclaration") return !!stmt.id && helpers.get(stmt.id.name) === stmt;
|
|
464
|
+
if (stmt.type === "VariableDeclaration" && stmt.declarations?.length === 1) {
|
|
465
|
+
const d = stmt.declarations[0];
|
|
466
|
+
return d.id?.type === "Identifier" && helpers.get(d.id.name) === d.init;
|
|
467
|
+
}
|
|
468
|
+
return false;
|
|
469
|
+
}
|
|
470
|
+
function bodyStatements(node) {
|
|
471
|
+
if (node?.type === "BlockStatement") return node.body ?? [];
|
|
472
|
+
return node ? [{ type: "ExpressionStatement", expression: node }] : [];
|
|
473
|
+
}
|
|
474
|
+
function tagTimelineCalls(stmts, prov, ctx) {
|
|
475
|
+
for (const stmt of stmts) {
|
|
476
|
+
const calls = [];
|
|
477
|
+
walkNodes(stmt, (n) => {
|
|
478
|
+
if (n.type === "CallExpression" && (isTimelineRooted(n, ctx.timelineVar) || isAddLabelCall(n, ctx.timelineVar)))
|
|
479
|
+
calls.push(n);
|
|
480
|
+
});
|
|
481
|
+
calls.sort((a, b) => a.callee.property.start - b.callee.property.start);
|
|
482
|
+
for (const n of calls) {
|
|
483
|
+
tagProvenance(n, { ...prov });
|
|
484
|
+
n.__hfOrder = ctx.order.n++;
|
|
485
|
+
n.__hfSiteStart = ctx.rootStart;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
function expandBody(bodyStmts, bindings, prov, ctx) {
|
|
490
|
+
const block = substituteParams(cloneNode({ type: "BlockStatement", body: bodyStmts }), bindings);
|
|
491
|
+
tagProvenance(block, prov);
|
|
492
|
+
tagTimelineCalls(block.body, prov, ctx);
|
|
493
|
+
block.body = expandStatements(block.body, { ...ctx, depth: ctx.depth + 1 });
|
|
494
|
+
return [block];
|
|
495
|
+
}
|
|
496
|
+
function inlineHelper(call, ctx) {
|
|
497
|
+
const fn = ctx.helpers.get(call.callee.name);
|
|
498
|
+
if (!fn) return null;
|
|
499
|
+
const params = supportedParams(fn);
|
|
500
|
+
if (!params) return null;
|
|
501
|
+
const bindings = resolveHelperBindings(call, params);
|
|
502
|
+
if (!bindings) return null;
|
|
503
|
+
const prov = {
|
|
504
|
+
kind: "helper",
|
|
505
|
+
fn: call.callee.name,
|
|
506
|
+
callSite: ++ctx.site.n,
|
|
507
|
+
sourceRange: rangeOf(call)
|
|
508
|
+
};
|
|
509
|
+
return expandBody(fn.body.body, bindings, prov, ctx);
|
|
510
|
+
}
|
|
511
|
+
function assignStep(update, resolve2) {
|
|
512
|
+
if (update.operator === "+=") return asNum(resolve2(update.right));
|
|
513
|
+
if (update.operator === "-=") {
|
|
514
|
+
const s = asNum(resolve2(update.right));
|
|
515
|
+
return s === void 0 ? void 0 : -s;
|
|
516
|
+
}
|
|
517
|
+
if (update.operator === "=" && update.right?.type === "BinaryExpression") {
|
|
518
|
+
return asNum(resolve2(update.right.right));
|
|
519
|
+
}
|
|
520
|
+
return void 0;
|
|
521
|
+
}
|
|
522
|
+
function updatedVarName(update) {
|
|
523
|
+
if (update?.type === "UpdateExpression") return update.argument?.name ?? null;
|
|
524
|
+
if (update?.type === "AssignmentExpression") return update.left?.name ?? null;
|
|
525
|
+
return null;
|
|
526
|
+
}
|
|
527
|
+
function loopStep(update, varName, resolve2) {
|
|
528
|
+
if (updatedVarName(update) !== varName) return void 0;
|
|
529
|
+
if (update.type === "UpdateExpression") return update.operator === "++" ? 1 : -1;
|
|
530
|
+
return assignStep(update, resolve2);
|
|
531
|
+
}
|
|
532
|
+
function asNum(v) {
|
|
533
|
+
return typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
534
|
+
}
|
|
535
|
+
function loopSatisfied(op, x, end) {
|
|
536
|
+
if (op === "<") return x < end;
|
|
537
|
+
if (op === "<=") return x <= end;
|
|
538
|
+
if (op === ">") return x > end;
|
|
539
|
+
if (op === ">=") return x >= end;
|
|
540
|
+
return false;
|
|
541
|
+
}
|
|
542
|
+
function forInitVar(init) {
|
|
543
|
+
if (init?.type !== "VariableDeclaration" || init.declarations?.length !== 1) return null;
|
|
544
|
+
const d = init.declarations[0];
|
|
545
|
+
return d.id?.type === "Identifier" ? { name: d.id.name, initExpr: d.init } : null;
|
|
546
|
+
}
|
|
547
|
+
function parseForHeader(stmt, resolve2) {
|
|
548
|
+
const iv = forInitVar(stmt.init);
|
|
549
|
+
const test = stmt.test;
|
|
550
|
+
if (!iv || test?.type !== "BinaryExpression" || test.left?.name !== iv.name) return null;
|
|
551
|
+
const start = asNum(resolve2(iv.initExpr));
|
|
552
|
+
const end = asNum(resolve2(test.right));
|
|
553
|
+
const step = loopStep(stmt.update, iv.name, resolve2);
|
|
554
|
+
if (start === void 0 || end === void 0 || !step) return null;
|
|
555
|
+
return { v: iv.name, start, end, op: test.operator, step };
|
|
556
|
+
}
|
|
557
|
+
function unrollFor(stmt, ctx) {
|
|
558
|
+
const h = parseForHeader(stmt, ctx.resolve);
|
|
559
|
+
if (!h) return null;
|
|
560
|
+
const body = bodyStatements(stmt.body);
|
|
561
|
+
const out = [];
|
|
562
|
+
const site = ++ctx.site.n;
|
|
563
|
+
let iteration = 0;
|
|
564
|
+
for (let x = h.start; loopSatisfied(h.op, x, h.end); x += h.step) {
|
|
565
|
+
if (iteration >= MAX_ITERS) return null;
|
|
566
|
+
const prov = {
|
|
567
|
+
kind: "loop",
|
|
568
|
+
callSite: site,
|
|
569
|
+
iteration,
|
|
570
|
+
sourceRange: rangeOf(stmt)
|
|
571
|
+
};
|
|
572
|
+
out.push(...expandBody(body, /* @__PURE__ */ new Map([[h.v, numericLiteral(x)]]), prov, ctx));
|
|
573
|
+
iteration++;
|
|
574
|
+
}
|
|
575
|
+
return out;
|
|
576
|
+
}
|
|
577
|
+
function forOfVarName(left) {
|
|
578
|
+
if (left?.type === "VariableDeclaration") {
|
|
579
|
+
const id = left.declarations?.[0]?.id;
|
|
580
|
+
return id?.type === "Identifier" ? id.name : null;
|
|
581
|
+
}
|
|
582
|
+
return left?.type === "Identifier" ? left.name : null;
|
|
583
|
+
}
|
|
584
|
+
function unrollOverArray(elements, body, elName, idxName, range, ctx) {
|
|
585
|
+
const out = [];
|
|
586
|
+
const site = ++ctx.site.n;
|
|
587
|
+
elements.forEach((el, i) => {
|
|
588
|
+
if (!el) return;
|
|
589
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
590
|
+
if (elName) bindings.set(elName, el);
|
|
591
|
+
if (idxName) bindings.set(idxName, numericLiteral(i));
|
|
592
|
+
const prov = { kind: "loop", callSite: site, iteration: i, sourceRange: range };
|
|
593
|
+
out.push(...expandBody(body, bindings, prov, ctx));
|
|
594
|
+
});
|
|
595
|
+
return out;
|
|
596
|
+
}
|
|
597
|
+
function unrollForOf(stmt, ctx) {
|
|
598
|
+
if (stmt.right?.type !== "ArrayExpression") return null;
|
|
599
|
+
const elName = forOfVarName(stmt.left);
|
|
600
|
+
if (!elName) return null;
|
|
601
|
+
return unrollOverArray(
|
|
602
|
+
stmt.right.elements ?? [],
|
|
603
|
+
bodyStatements(stmt.body),
|
|
604
|
+
elName,
|
|
605
|
+
null,
|
|
606
|
+
rangeOf(stmt),
|
|
607
|
+
ctx
|
|
608
|
+
);
|
|
609
|
+
}
|
|
610
|
+
function callbackParamNames(cb) {
|
|
611
|
+
const names = [];
|
|
612
|
+
for (const p of [cb.params?.[0], cb.params?.[1]]) {
|
|
613
|
+
if (!p) names.push(null);
|
|
614
|
+
else if (p.type !== "Identifier") return null;
|
|
615
|
+
else names.push(p.name);
|
|
616
|
+
}
|
|
617
|
+
return { el: names[0], idx: names[1] };
|
|
618
|
+
}
|
|
619
|
+
function isForEachCall(callee) {
|
|
620
|
+
return callee?.type === "MemberExpression" && callee.property?.name === "forEach" && callee.object?.type === "ArrayExpression";
|
|
621
|
+
}
|
|
622
|
+
function forEachTarget(call) {
|
|
623
|
+
if (!isForEachCall(call.callee)) return null;
|
|
624
|
+
const cb = call.arguments?.[0];
|
|
625
|
+
return isFunctionNode(cb) ? { elements: call.callee.object.elements ?? [], cb } : null;
|
|
626
|
+
}
|
|
627
|
+
function unrollForEach(call, ctx) {
|
|
628
|
+
const target = forEachTarget(call);
|
|
629
|
+
if (!target) return null;
|
|
630
|
+
const params = callbackParamNames(target.cb);
|
|
631
|
+
if (!params) return null;
|
|
632
|
+
return unrollOverArray(
|
|
633
|
+
target.elements,
|
|
634
|
+
bodyStatements(target.cb.body),
|
|
635
|
+
params.el,
|
|
636
|
+
params.idx,
|
|
637
|
+
rangeOf(call),
|
|
638
|
+
ctx
|
|
639
|
+
);
|
|
640
|
+
}
|
|
641
|
+
function expandCall(call, ctx) {
|
|
642
|
+
if (call.callee?.type === "Identifier" && ctx.helpers.has(call.callee.name)) {
|
|
643
|
+
return inlineHelper(call, ctx);
|
|
644
|
+
}
|
|
645
|
+
return unrollForEach(call, ctx);
|
|
646
|
+
}
|
|
647
|
+
function expandStatement(stmt, ctx) {
|
|
648
|
+
if (ctx.depth >= MAX_DEPTH) return null;
|
|
649
|
+
if (stmt.type === "ForStatement") return unrollFor(stmt, ctx);
|
|
650
|
+
if (stmt.type === "ForOfStatement") return unrollForOf(stmt, ctx);
|
|
651
|
+
if (stmt.type === "ExpressionStatement" && stmt.expression?.type === "CallExpression") {
|
|
652
|
+
return expandCall(stmt.expression, ctx);
|
|
653
|
+
}
|
|
654
|
+
return null;
|
|
655
|
+
}
|
|
656
|
+
function expandStatements(stmts, ctx) {
|
|
657
|
+
const out = [];
|
|
658
|
+
for (const stmt of stmts) {
|
|
659
|
+
const expanded = expandStatement(stmt, ctx);
|
|
660
|
+
if (expanded) out.push(...expanded);
|
|
661
|
+
else out.push(stmt);
|
|
662
|
+
}
|
|
663
|
+
return out;
|
|
664
|
+
}
|
|
665
|
+
function inlineComputedTimelines(ast, timelineVar, resolve2) {
|
|
666
|
+
const helpers = collectInlinableHelpers(ast, timelineVar);
|
|
667
|
+
const ctx = {
|
|
668
|
+
helpers,
|
|
669
|
+
timelineVar,
|
|
670
|
+
resolve: resolve2,
|
|
671
|
+
depth: 0,
|
|
672
|
+
site: { n: 0 },
|
|
673
|
+
order: { n: 0 },
|
|
674
|
+
rootStart: 0
|
|
675
|
+
};
|
|
676
|
+
const body = (ast.body ?? []).filter((stmt) => !isHelperDecl(stmt, helpers));
|
|
677
|
+
ast.body = body.flatMap((stmt) => {
|
|
678
|
+
ctx.rootStart = stmt.start;
|
|
679
|
+
return expandStatements([stmt], ctx);
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
var GSAP_METHODS2 = /* @__PURE__ */ new Set(["set", "to", "from", "fromTo"]);
|
|
683
|
+
var QUERY_METHODS = /* @__PURE__ */ new Set(["querySelector", "querySelectorAll"]);
|
|
684
|
+
var ITERATION_METHODS = /* @__PURE__ */ new Set(["forEach", "map"]);
|
|
685
|
+
var SCOPE_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
686
|
+
"Program",
|
|
687
|
+
"BlockStatement",
|
|
688
|
+
"FunctionDeclaration",
|
|
689
|
+
"FunctionExpression",
|
|
690
|
+
"ArrowFunctionExpression"
|
|
691
|
+
]);
|
|
692
|
+
function parseProgram(script) {
|
|
693
|
+
try {
|
|
694
|
+
return parse(script, {
|
|
695
|
+
ecmaVersion: "latest",
|
|
696
|
+
sourceType: "script",
|
|
697
|
+
locations: true
|
|
698
|
+
});
|
|
699
|
+
} catch {
|
|
700
|
+
return parse(script, {
|
|
701
|
+
ecmaVersion: "latest",
|
|
702
|
+
sourceType: "module",
|
|
703
|
+
locations: true
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
var CONST_NODES = /* @__PURE__ */ Symbol("hf.constNodes");
|
|
708
|
+
function constNodesOf(scope) {
|
|
709
|
+
return scope[CONST_NODES];
|
|
710
|
+
}
|
|
711
|
+
var MATH_FNS = /* @__PURE__ */ new Set(["min", "max", "round", "floor", "ceil", "abs", "sqrt", "sign", "trunc"]);
|
|
712
|
+
var MATH_CONSTS = { PI: Math.PI, E: Math.E, SQRT2: Math.SQRT2 };
|
|
713
|
+
function resolveMemberNode(node, scope) {
|
|
714
|
+
if (node.object?.type === "Identifier" && node.object.name === "Math") {
|
|
715
|
+
const key = node.property?.name;
|
|
716
|
+
return typeof key === "string" ? MATH_CONSTS[key] : void 0;
|
|
717
|
+
}
|
|
718
|
+
const objNode = resolveConstNode(node.object, scope);
|
|
719
|
+
if (!objNode) return void 0;
|
|
720
|
+
let valueNode;
|
|
721
|
+
if (node.computed) {
|
|
722
|
+
const idx = resolveNode(node.property, scope);
|
|
723
|
+
if (objNode.type === "ArrayExpression" && typeof idx === "number") {
|
|
724
|
+
valueNode = objNode.elements?.[idx];
|
|
725
|
+
} else if (objNode.type === "ObjectExpression" && (typeof idx === "string" || typeof idx === "number")) {
|
|
726
|
+
valueNode = findPropertyNode(objNode, String(idx));
|
|
727
|
+
}
|
|
728
|
+
} else if (objNode.type === "ObjectExpression") {
|
|
729
|
+
valueNode = findPropertyNode(objNode, node.property?.name ?? node.property?.value);
|
|
730
|
+
}
|
|
731
|
+
return valueNode ? resolveNode(valueNode, scope) : void 0;
|
|
732
|
+
}
|
|
733
|
+
function resolveConstMember(objNode, node, scope) {
|
|
734
|
+
if (!node.computed) {
|
|
735
|
+
return objNode.type === "ObjectExpression" ? findPropertyNode(objNode, node.property?.name ?? node.property?.value) : void 0;
|
|
736
|
+
}
|
|
737
|
+
const idx = resolveNode(node.property, scope);
|
|
738
|
+
if (objNode.type === "ArrayExpression" && typeof idx === "number") return objNode.elements?.[idx];
|
|
739
|
+
if (objNode.type === "ObjectExpression") return findPropertyNode(objNode, String(idx));
|
|
740
|
+
return void 0;
|
|
741
|
+
}
|
|
742
|
+
function resolveConstNode(node, scope) {
|
|
743
|
+
if (!node) return void 0;
|
|
744
|
+
if (node.type === "ArrayExpression" || node.type === "ObjectExpression") return node;
|
|
745
|
+
if (node.type === "Identifier") return constNodesOf(scope)?.get(node.name);
|
|
746
|
+
if (node.type !== "MemberExpression") return void 0;
|
|
747
|
+
const objNode = resolveConstNode(node.object, scope);
|
|
748
|
+
return objNode ? resolveConstMember(objNode, node, scope) : void 0;
|
|
749
|
+
}
|
|
750
|
+
function resolveNode(node, scope) {
|
|
751
|
+
if (!node) return void 0;
|
|
752
|
+
if (node.type === "NumericLiteral" || node.type === "Literal" && typeof node.value === "number")
|
|
753
|
+
return node.value;
|
|
754
|
+
if (node.type === "StringLiteral" || node.type === "Literal" && typeof node.value === "string")
|
|
755
|
+
return node.value;
|
|
756
|
+
if (node.type === "BooleanLiteral" || node.type === "Literal" && typeof node.value === "boolean")
|
|
757
|
+
return node.value;
|
|
758
|
+
if (node.type === "UnaryExpression" && node.operator === "-" && node.argument) {
|
|
759
|
+
const val = resolveNode(node.argument, scope);
|
|
760
|
+
return typeof val === "number" ? -val : void 0;
|
|
761
|
+
}
|
|
762
|
+
if (node.type === "BinaryExpression") {
|
|
763
|
+
const left = resolveNode(node.left, scope);
|
|
764
|
+
const right = resolveNode(node.right, scope);
|
|
765
|
+
if (typeof left === "number" && typeof right === "number") {
|
|
766
|
+
switch (node.operator) {
|
|
767
|
+
case "+":
|
|
768
|
+
return left + right;
|
|
769
|
+
case "-":
|
|
770
|
+
return left - right;
|
|
771
|
+
case "*":
|
|
772
|
+
return left * right;
|
|
773
|
+
case "/":
|
|
774
|
+
return right !== 0 ? left / right : void 0;
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
if (typeof left === "string" && node.operator === "+") return left + String(right ?? "");
|
|
778
|
+
if (typeof right === "string" && node.operator === "+") return String(left ?? "") + right;
|
|
779
|
+
}
|
|
780
|
+
if (node.type === "Identifier" && scope.has(node.name)) {
|
|
781
|
+
return scope.get(node.name);
|
|
782
|
+
}
|
|
783
|
+
if (node.type === "TemplateLiteral" && node.expressions?.length === 0) {
|
|
784
|
+
return node.quasis?.[0]?.value?.cooked ?? void 0;
|
|
785
|
+
}
|
|
786
|
+
if (node.type === "MemberExpression") {
|
|
787
|
+
return resolveMemberNode(node, scope);
|
|
788
|
+
}
|
|
789
|
+
if (node.type === "CallExpression" && node.callee?.type === "MemberExpression" && node.callee.object?.type === "Identifier" && node.callee.object.name === "Math" && MATH_FNS.has(node.callee.property?.name)) {
|
|
790
|
+
const args = (node.arguments ?? []).map((a) => resolveNode(a, scope));
|
|
791
|
+
if (args.every((a) => typeof a === "number")) {
|
|
792
|
+
return Math[node.callee.property.name](...args);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
return void 0;
|
|
796
|
+
}
|
|
797
|
+
function extractLiteralValue(node, scope) {
|
|
798
|
+
return resolveNode(node, scope);
|
|
799
|
+
}
|
|
800
|
+
function selectorFromQueryCall(node, scope) {
|
|
801
|
+
if (node?.type !== "CallExpression") return null;
|
|
802
|
+
const callee = node.callee;
|
|
803
|
+
if (callee?.type !== "MemberExpression" || callee.property?.type !== "Identifier") return null;
|
|
804
|
+
const method = callee.property.name;
|
|
805
|
+
const argValue = resolveNode(node.arguments?.[0], scope);
|
|
806
|
+
if (typeof argValue !== "string" || argValue.length === 0) return null;
|
|
807
|
+
if (QUERY_METHODS.has(method) || method === "toArray") return argValue;
|
|
808
|
+
if (method === "getElementById") return `#${argValue}`;
|
|
809
|
+
return null;
|
|
810
|
+
}
|
|
811
|
+
function enclosingScopeNodeFromAncestors(ancestors, includeBlocks = true) {
|
|
812
|
+
for (let i = ancestors.length - 2; i >= 0; i--) {
|
|
813
|
+
const node = ancestors[i];
|
|
814
|
+
if (node && SCOPE_NODE_TYPES.has(node.type) && (includeBlocks || node.type !== "BlockStatement")) {
|
|
815
|
+
return node;
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
return null;
|
|
819
|
+
}
|
|
820
|
+
function scopeChainFromAncestors(ancestors) {
|
|
821
|
+
const chain = [];
|
|
822
|
+
for (let i = ancestors.length - 1; i >= 0; i--) {
|
|
823
|
+
const node = ancestors[i];
|
|
824
|
+
if (node && SCOPE_NODE_TYPES.has(node.type)) chain.push(node);
|
|
825
|
+
}
|
|
826
|
+
return chain;
|
|
827
|
+
}
|
|
828
|
+
function nearestExpandedScopeFromAncestors(ancestors) {
|
|
829
|
+
for (let index = ancestors.length - 2; index >= 0; index--) {
|
|
830
|
+
const candidate = ancestors[index];
|
|
831
|
+
if (candidate?.type === "BlockStatement" && readProvenance(candidate)) return candidate;
|
|
832
|
+
}
|
|
833
|
+
return void 0;
|
|
834
|
+
}
|
|
835
|
+
function findVisibleIdentifierDeclaration(name, ancestors, index, usageStart = Number.POSITIVE_INFINITY) {
|
|
836
|
+
const declarations = index.declarationsByName.get(name) ?? [];
|
|
837
|
+
const expandedScopeNode = nearestExpandedScopeFromAncestors(ancestors);
|
|
838
|
+
for (const scopeNode of scopeChainFromAncestors(ancestors)) {
|
|
839
|
+
const candidates = declarations.filter(
|
|
840
|
+
(declaration) => declaration.scopeNode === scopeNode && (!declaration.expandedScopeNode || declaration.expandedScopeNode === expandedScopeNode) && (declaration.kind === "var" || declaration.kind === "param" || declaration.node.start < usageStart)
|
|
841
|
+
).sort((left, right) => right.node.start - left.node.start);
|
|
842
|
+
if (candidates[0]) return candidates[0];
|
|
843
|
+
}
|
|
844
|
+
return void 0;
|
|
845
|
+
}
|
|
846
|
+
function collectIdentifierBindingIndex(ast) {
|
|
847
|
+
const declarationsByName = /* @__PURE__ */ new Map();
|
|
848
|
+
const reassignedDeclarations = /* @__PURE__ */ new Set();
|
|
849
|
+
ancestor(ast, {
|
|
850
|
+
VariableDeclarator(node, _, ancestors) {
|
|
851
|
+
const name = node.id?.name;
|
|
852
|
+
if (!name) return;
|
|
853
|
+
const declaration = ancestors.at(-2);
|
|
854
|
+
const kind = declaration?.kind;
|
|
855
|
+
if (!kind) return;
|
|
856
|
+
const includeBlocks = declaration?.type !== "VariableDeclaration" || kind !== "var";
|
|
857
|
+
const scopeNode = enclosingScopeNodeFromAncestors(ancestors, includeBlocks);
|
|
858
|
+
const expandedScopeNode = nearestExpandedScopeFromAncestors(ancestors);
|
|
859
|
+
const entries = declarationsByName.get(name) ?? [];
|
|
860
|
+
entries.push({ node, scopeNode, expandedScopeNode, name, kind });
|
|
861
|
+
declarationsByName.set(name, entries);
|
|
862
|
+
},
|
|
863
|
+
FunctionDeclaration: indexFunctionParameters,
|
|
864
|
+
FunctionExpression: indexFunctionParameters,
|
|
865
|
+
ArrowFunctionExpression: indexFunctionParameters
|
|
866
|
+
});
|
|
867
|
+
const index = { declarationsByName, reassignedDeclarations };
|
|
868
|
+
ancestor(ast, {
|
|
869
|
+
AssignmentExpression(node, _, ancestors) {
|
|
870
|
+
const name = node.left?.type === "Identifier" ? node.left.name : void 0;
|
|
871
|
+
if (!name) return;
|
|
872
|
+
const declaration = findVisibleIdentifierDeclaration(name, ancestors, index, node.start);
|
|
873
|
+
if (declaration) reassignedDeclarations.add(declaration.node);
|
|
874
|
+
}
|
|
875
|
+
});
|
|
876
|
+
return index;
|
|
877
|
+
function indexFunctionParameters(node) {
|
|
878
|
+
for (const parameter of node.params ?? []) {
|
|
879
|
+
if (parameter?.type !== "Identifier") continue;
|
|
880
|
+
const entries = declarationsByName.get(parameter.name) ?? [];
|
|
881
|
+
entries.push({ node: parameter, scopeNode: node, name: parameter.name, kind: "param" });
|
|
882
|
+
declarationsByName.set(parameter.name, entries);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
function addBinding(bindings, scopeNode, name, selector) {
|
|
887
|
+
let scoped = bindings.get(scopeNode);
|
|
888
|
+
if (!scoped) {
|
|
889
|
+
scoped = /* @__PURE__ */ new Map();
|
|
890
|
+
bindings.set(scopeNode, scoped);
|
|
891
|
+
}
|
|
892
|
+
if (!scoped.has(name)) scoped.set(name, selector);
|
|
893
|
+
}
|
|
894
|
+
function lookupBindingFromAncestors(name, ancestors, bindings) {
|
|
895
|
+
for (const scopeNode of scopeChainFromAncestors(ancestors)) {
|
|
896
|
+
const selector = bindings.get(scopeNode)?.get(name);
|
|
897
|
+
if (selector !== void 0) return selector;
|
|
898
|
+
}
|
|
899
|
+
return bindings.get(null)?.get(name) ?? null;
|
|
900
|
+
}
|
|
901
|
+
function isFunctionNode2(node) {
|
|
902
|
+
return node?.type === "ArrowFunctionExpression" || node?.type === "FunctionExpression" || node?.type === "FunctionDeclaration";
|
|
903
|
+
}
|
|
904
|
+
function resolveCollectionSelector(node, ancestors, scope, bindings) {
|
|
905
|
+
if (node?.type === "Identifier")
|
|
906
|
+
return lookupBindingFromAncestors(node.name, ancestors, bindings);
|
|
907
|
+
if (node?.type === "CallExpression") return selectorFromQueryCall(node, scope);
|
|
908
|
+
return null;
|
|
909
|
+
}
|
|
910
|
+
function collectScopeBindings(ast) {
|
|
911
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
912
|
+
const ambiguousBindings = /* @__PURE__ */ new Set();
|
|
913
|
+
const constNodes = /* @__PURE__ */ new Map();
|
|
914
|
+
Object.defineProperty(bindings, CONST_NODES, { value: constNodes, enumerable: false });
|
|
915
|
+
simple(ast, {
|
|
916
|
+
VariableDeclarator(node) {
|
|
917
|
+
const name = node.id?.name;
|
|
918
|
+
const init = node.init;
|
|
919
|
+
if (!name || !init) return;
|
|
920
|
+
if (init.type === "ArrayExpression" || init.type === "ObjectExpression") {
|
|
921
|
+
constNodes.set(name, init);
|
|
922
|
+
return;
|
|
923
|
+
}
|
|
924
|
+
const val = resolveNode(init, bindings);
|
|
925
|
+
if (val === void 0 || ambiguousBindings.has(name)) return;
|
|
926
|
+
const existing = bindings.get(name);
|
|
927
|
+
if (existing !== void 0 && existing !== val) {
|
|
928
|
+
bindings.delete(name);
|
|
929
|
+
ambiguousBindings.add(name);
|
|
930
|
+
} else if (existing === void 0) {
|
|
931
|
+
bindings.set(name, val);
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
});
|
|
935
|
+
return bindings;
|
|
936
|
+
}
|
|
937
|
+
function collectTargetBindings(ast, scope, identifierBindings) {
|
|
938
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
939
|
+
ancestor(ast, {
|
|
940
|
+
VariableDeclarator(node, _, ancestors) {
|
|
941
|
+
const name = node.id?.name;
|
|
942
|
+
const selector = selectorFromQueryCall(node.init, scope);
|
|
943
|
+
if (name && selector !== null) {
|
|
944
|
+
const declaration = ancestors.at(-2);
|
|
945
|
+
const includeBlocks = declaration?.type !== "VariableDeclaration" || declaration.kind !== "var";
|
|
946
|
+
addBinding(
|
|
947
|
+
bindings,
|
|
948
|
+
enclosingScopeNodeFromAncestors(ancestors, includeBlocks),
|
|
949
|
+
name,
|
|
950
|
+
selector
|
|
951
|
+
);
|
|
952
|
+
}
|
|
953
|
+
},
|
|
954
|
+
AssignmentExpression(node, _, ancestors) {
|
|
955
|
+
const left = node.left;
|
|
956
|
+
const selector = selectorFromQueryCall(node.right, scope);
|
|
957
|
+
if (left?.type === "Identifier" && selector !== null) {
|
|
958
|
+
const declaration = findVisibleIdentifierDeclaration(
|
|
959
|
+
left.name,
|
|
960
|
+
ancestors,
|
|
961
|
+
identifierBindings,
|
|
962
|
+
node.start
|
|
963
|
+
);
|
|
964
|
+
addBinding(
|
|
965
|
+
bindings,
|
|
966
|
+
declaration?.scopeNode ?? nearestExpandedScopeFromAncestors(ancestors) ?? enclosingScopeNodeFromAncestors(ancestors),
|
|
967
|
+
left.name,
|
|
968
|
+
selector
|
|
969
|
+
);
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
});
|
|
973
|
+
ancestor(ast, {
|
|
974
|
+
// fallow-ignore-next-line complexity
|
|
975
|
+
CallExpression(node, _, ancestors) {
|
|
976
|
+
const callee = node.callee;
|
|
977
|
+
if (callee?.type === "MemberExpression" && callee.property?.type === "Identifier" && ITERATION_METHODS.has(callee.property.name)) {
|
|
978
|
+
const collectionSelector = resolveCollectionSelector(
|
|
979
|
+
callee.object,
|
|
980
|
+
ancestors,
|
|
981
|
+
scope,
|
|
982
|
+
bindings
|
|
983
|
+
);
|
|
984
|
+
const fn = node.arguments?.[0];
|
|
985
|
+
const param = fn?.params?.[0];
|
|
986
|
+
if (collectionSelector && param?.type === "Identifier" && isFunctionNode2(fn)) {
|
|
987
|
+
addBinding(bindings, fn, param.name, collectionSelector);
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
});
|
|
992
|
+
const COLLECTION_ALIAS_METHODS = /* @__PURE__ */ new Set(["slice", "filter", "concat", "reverse"]);
|
|
993
|
+
ancestor(ast, {
|
|
994
|
+
// fallow-ignore-next-line complexity
|
|
995
|
+
VariableDeclarator(node, _, ancestors) {
|
|
996
|
+
const name = node.id?.name;
|
|
997
|
+
const init = node.init;
|
|
998
|
+
if (!name || !init) return;
|
|
999
|
+
let sourceVar;
|
|
1000
|
+
if (init.type === "MemberExpression" && init.object?.type === "Identifier") {
|
|
1001
|
+
sourceVar = init.object.name;
|
|
1002
|
+
} else if (init.type === "CallExpression" && init.callee?.type === "MemberExpression" && init.callee.object?.type === "Identifier" && init.callee.property?.type === "Identifier" && COLLECTION_ALIAS_METHODS.has(init.callee.property.name)) {
|
|
1003
|
+
sourceVar = init.callee.object.name;
|
|
1004
|
+
}
|
|
1005
|
+
if (!sourceVar) return;
|
|
1006
|
+
const selector = lookupBindingFromAncestors(sourceVar, ancestors, bindings);
|
|
1007
|
+
if (selector)
|
|
1008
|
+
addBinding(bindings, enclosingScopeNodeFromAncestors(ancestors), name, selector);
|
|
1009
|
+
}
|
|
1010
|
+
});
|
|
1011
|
+
return bindings;
|
|
1012
|
+
}
|
|
1013
|
+
function resolveTargetSelector(node, ancestors, scope, bindings) {
|
|
1014
|
+
if (!node) return null;
|
|
1015
|
+
if (node.type === "StringLiteral" || node.type === "Literal") {
|
|
1016
|
+
return typeof node.value === "string" ? node.value : null;
|
|
1017
|
+
}
|
|
1018
|
+
if (node.type === "Identifier") {
|
|
1019
|
+
return lookupBindingFromAncestors(node.name, ancestors, bindings);
|
|
1020
|
+
}
|
|
1021
|
+
if (node.type === "CallExpression") {
|
|
1022
|
+
return selectorFromQueryCall(node, scope);
|
|
1023
|
+
}
|
|
1024
|
+
if (node.type === "ArrayExpression") {
|
|
1025
|
+
const parts = node.elements.map((el) => resolveTargetSelector(el, ancestors, scope, bindings)).filter((s) => typeof s === "string" && s.length > 0);
|
|
1026
|
+
return parts.length > 0 ? parts.join(", ") : null;
|
|
1027
|
+
}
|
|
1028
|
+
if (node.type === "MemberExpression" && node.object?.type === "Identifier") {
|
|
1029
|
+
return lookupBindingFromAncestors(node.object.name, ancestors, bindings);
|
|
1030
|
+
}
|
|
1031
|
+
return null;
|
|
1032
|
+
}
|
|
1033
|
+
function hasUnresolvedArrayPart(node, ancestors, scope, bindings) {
|
|
1034
|
+
return node?.type === "ArrayExpression" && node.elements.some(
|
|
1035
|
+
(el) => !resolveTargetSelector(el, ancestors, scope, bindings) || hasUnresolvedArrayPart(el, ancestors, scope, bindings)
|
|
1036
|
+
);
|
|
1037
|
+
}
|
|
1038
|
+
function describeProxyTarget(targetNode, varsNode, scope) {
|
|
1039
|
+
const objNode = targetNode?.type === "ObjectExpression" ? targetNode : targetNode?.type === "Identifier" ? resolveConstNode(targetNode, scope) : void 0;
|
|
1040
|
+
if (objNode?.type !== "ObjectExpression") return null;
|
|
1041
|
+
const onUpdate = findPropertyNode(varsNode, "onUpdate");
|
|
1042
|
+
const driven = onUpdate ? drivenDomChannel(onUpdate) : void 0;
|
|
1043
|
+
if (driven) return `proxy \u2192 ${driven}`;
|
|
1044
|
+
return "dwell/hold";
|
|
1045
|
+
}
|
|
1046
|
+
function isStyleAssignmentTarget(left) {
|
|
1047
|
+
return left?.type === "MemberExpression" && left.object?.type === "MemberExpression" && left.object.property?.name === "style" && !!left.property?.name;
|
|
1048
|
+
}
|
|
1049
|
+
function drivenDomChannel(fnNode) {
|
|
1050
|
+
let found;
|
|
1051
|
+
simple(fnNode, {
|
|
1052
|
+
CallExpression(node) {
|
|
1053
|
+
if (node.callee?.type === "MemberExpression" && node.callee.property?.name === "setAttribute" && typeof node.arguments?.[0]?.value === "string") {
|
|
1054
|
+
found ??= node.arguments[0].value;
|
|
1055
|
+
}
|
|
1056
|
+
},
|
|
1057
|
+
AssignmentExpression(node) {
|
|
1058
|
+
const left = node.left;
|
|
1059
|
+
if (isStyleAssignmentTarget(left)) found ??= `style.${left.property.name}`;
|
|
1060
|
+
}
|
|
1061
|
+
});
|
|
1062
|
+
return found;
|
|
1063
|
+
}
|
|
1064
|
+
function isObjectProperty(prop) {
|
|
1065
|
+
return prop?.type === "ObjectProperty" || prop?.type === "Property";
|
|
1066
|
+
}
|
|
1067
|
+
function propKeyName(prop) {
|
|
1068
|
+
return prop?.key?.name ?? prop?.key?.value;
|
|
1069
|
+
}
|
|
1070
|
+
function findPropertyNode(varsArgNode, key) {
|
|
1071
|
+
if (varsArgNode?.type !== "ObjectExpression") return void 0;
|
|
1072
|
+
for (const prop of varsArgNode.properties ?? []) {
|
|
1073
|
+
if (!isObjectProperty(prop)) continue;
|
|
1074
|
+
if (propKeyName(prop) === key) return prop.value;
|
|
1075
|
+
}
|
|
1076
|
+
return void 0;
|
|
1077
|
+
}
|
|
1078
|
+
function extractRawPropertySource(varsArgNode, key, source) {
|
|
1079
|
+
const node = findPropertyNode(varsArgNode, key);
|
|
1080
|
+
return node ? source.slice(node.start, node.end) : void 0;
|
|
1081
|
+
}
|
|
1082
|
+
function objectExpressionToRecord(node, scope, source) {
|
|
1083
|
+
const result = {};
|
|
1084
|
+
if (node?.type !== "ObjectExpression") return result;
|
|
1085
|
+
for (const prop of node.properties ?? []) {
|
|
1086
|
+
if (!isObjectProperty(prop)) continue;
|
|
1087
|
+
const key = prop.key?.name ?? prop.key?.value;
|
|
1088
|
+
if (!key) continue;
|
|
1089
|
+
const resolved = resolveNode(prop.value, scope);
|
|
1090
|
+
if (resolved !== void 0) {
|
|
1091
|
+
result[key] = resolved;
|
|
1092
|
+
} else {
|
|
1093
|
+
result[key] = `__raw:${source.slice(prop.value.start, prop.value.end)}`;
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
return result;
|
|
1097
|
+
}
|
|
1098
|
+
function isGsapTimelineCall(node) {
|
|
1099
|
+
return node?.type === "CallExpression" && node.callee?.type === "MemberExpression" && node.callee.object?.name === "gsap" && node.callee.property?.name === "timeline";
|
|
1100
|
+
}
|
|
1101
|
+
function hasUnknownDuration(varsNode, scope) {
|
|
1102
|
+
if (!varsNode) return false;
|
|
1103
|
+
if (varsNode.type !== "ObjectExpression") return true;
|
|
1104
|
+
const props = varsNode.properties ?? [];
|
|
1105
|
+
if (props.some((p) => p.type === "SpreadElement")) return true;
|
|
1106
|
+
const prop = props.find((p) => isObjectProperty(p) && propKeyName(p) === "duration");
|
|
1107
|
+
return prop !== void 0 && typeof resolveNode(prop.value, scope) !== "number";
|
|
1108
|
+
}
|
|
1109
|
+
function staticMemberKey(node) {
|
|
1110
|
+
if (!node || node.type !== "MemberExpression") return null;
|
|
1111
|
+
if (node.computed) {
|
|
1112
|
+
const p = node.property;
|
|
1113
|
+
if (p?.type === "Literal" && typeof p.value === "string") return p.value;
|
|
1114
|
+
return null;
|
|
1115
|
+
}
|
|
1116
|
+
return node.property?.type === "Identifier" ? node.property.name : null;
|
|
1117
|
+
}
|
|
1118
|
+
function isStaticMemberRef(node) {
|
|
1119
|
+
return node?.type === "MemberExpression" && staticMemberKey(node) !== null;
|
|
1120
|
+
}
|
|
1121
|
+
function sameMemberAccess(a, b) {
|
|
1122
|
+
if (a?.type !== "MemberExpression" || b?.type !== "MemberExpression") return false;
|
|
1123
|
+
if (staticMemberKey(a) !== staticMemberKey(b) || staticMemberKey(a) === null) return false;
|
|
1124
|
+
const ao = a.object;
|
|
1125
|
+
const bo = b.object;
|
|
1126
|
+
if (ao?.type === "Identifier" && bo?.type === "Identifier") return ao.name === bo.name;
|
|
1127
|
+
if (ao?.type === "MemberExpression" && bo?.type === "MemberExpression")
|
|
1128
|
+
return sameMemberAccess(ao, bo);
|
|
1129
|
+
return false;
|
|
1130
|
+
}
|
|
1131
|
+
function timelineRootSource(ref, script) {
|
|
1132
|
+
return ref.kind === "identifier" ? ref.name : script.slice(ref.node.start, ref.node.end);
|
|
1133
|
+
}
|
|
1134
|
+
function escapeRegExp(s) {
|
|
1135
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1136
|
+
}
|
|
1137
|
+
function extractTimelineDefaults(callNode, scope) {
|
|
1138
|
+
const arg = callNode.arguments?.[0];
|
|
1139
|
+
if (!arg || arg.type !== "ObjectExpression") return void 0;
|
|
1140
|
+
const defaultsProp = arg.properties?.find(
|
|
1141
|
+
(p) => isObjectProperty(p) && propKeyName(p) === "defaults"
|
|
1142
|
+
);
|
|
1143
|
+
if (!defaultsProp?.value || defaultsProp.value.type !== "ObjectExpression") return void 0;
|
|
1144
|
+
const result = {};
|
|
1145
|
+
for (const prop of defaultsProp.value.properties ?? []) {
|
|
1146
|
+
if (!isObjectProperty(prop)) continue;
|
|
1147
|
+
const key = propKeyName(prop);
|
|
1148
|
+
const val = resolveNode(prop.value, scope);
|
|
1149
|
+
if (key === "ease" && typeof val === "string") result.ease = val;
|
|
1150
|
+
if (key === "duration") {
|
|
1151
|
+
if (typeof val === "number") result.duration = val;
|
|
1152
|
+
else result.durationUnresolved = true;
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
1156
|
+
}
|
|
1157
|
+
function findTimelineVar(ast, scope) {
|
|
1158
|
+
let timelineVar = null;
|
|
1159
|
+
let ref = null;
|
|
1160
|
+
let timelineCount = 0;
|
|
1161
|
+
let defaults;
|
|
1162
|
+
const emptyScope = scope ?? /* @__PURE__ */ new Map();
|
|
1163
|
+
simple(ast, {
|
|
1164
|
+
VariableDeclarator(node) {
|
|
1165
|
+
if (isGsapTimelineCall(node.init)) {
|
|
1166
|
+
timelineCount += 1;
|
|
1167
|
+
if (!ref && node.id?.type === "Identifier") {
|
|
1168
|
+
timelineVar = node.id.name;
|
|
1169
|
+
ref = { kind: "identifier", name: node.id.name };
|
|
1170
|
+
defaults = extractTimelineDefaults(node.init, emptyScope);
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
},
|
|
1174
|
+
AssignmentExpression(node) {
|
|
1175
|
+
if (isGsapTimelineCall(node.right)) {
|
|
1176
|
+
timelineCount += 1;
|
|
1177
|
+
if (!ref) {
|
|
1178
|
+
const left = node.left;
|
|
1179
|
+
if (left?.type === "Identifier") {
|
|
1180
|
+
timelineVar = left.name;
|
|
1181
|
+
ref = { kind: "identifier", name: left.name };
|
|
1182
|
+
defaults = extractTimelineDefaults(node.right, emptyScope);
|
|
1183
|
+
} else if (isStaticMemberRef(left)) {
|
|
1184
|
+
ref = { kind: "member", node: left };
|
|
1185
|
+
defaults = extractTimelineDefaults(node.right, emptyScope);
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
});
|
|
1191
|
+
return { timelineVar, ref, timelineCount, defaults };
|
|
1192
|
+
}
|
|
1193
|
+
function isTimelineRootedCall(callNode, ref) {
|
|
1194
|
+
let obj = callNode.callee?.object;
|
|
1195
|
+
while (obj?.type === "CallExpression") {
|
|
1196
|
+
obj = obj.callee?.object;
|
|
1197
|
+
}
|
|
1198
|
+
if (ref.kind === "identifier") return obj?.type === "Identifier" && obj.name === ref.name;
|
|
1199
|
+
return sameMemberAccess(obj, ref.node);
|
|
1200
|
+
}
|
|
1201
|
+
function findAllTweenCalls(ast, ref, scope, targetBindings) {
|
|
1202
|
+
const results = [];
|
|
1203
|
+
function visit(node, ancestors) {
|
|
1204
|
+
if (!node || typeof node !== "object") return;
|
|
1205
|
+
const nodeAncestors = [...ancestors, node];
|
|
1206
|
+
if (node.type === "CallExpression") {
|
|
1207
|
+
const callee = node.callee;
|
|
1208
|
+
const gsapSetArg = node.arguments?.[0];
|
|
1209
|
+
const isGlobalSet = callee?.type === "MemberExpression" && callee.object?.type === "Identifier" && callee.object.name === "gsap" && callee.property?.type === "Identifier" && callee.property.name === "set" && (gsapSetArg?.type === "StringLiteral" || gsapSetArg?.type === "Literal" && typeof gsapSetArg.value === "string");
|
|
1210
|
+
if (callee?.type === "MemberExpression" && callee.property?.type === "Identifier" && (isTimelineRootedCall(node, ref) || isGlobalSet) && GSAP_METHODS2.has(callee.property.name)) {
|
|
1211
|
+
const method = callee.property.name;
|
|
1212
|
+
const args = node.arguments;
|
|
1213
|
+
const selectorValue = args.length >= 1 ? resolveTargetSelector(args[0], nodeAncestors, scope, targetBindings) ?? "__unresolved__" : "__unresolved__";
|
|
1214
|
+
const partial = hasUnresolvedArrayPart(args[0], nodeAncestors, scope, targetBindings) ? { selectorPartial: true } : {};
|
|
1215
|
+
if (method === "fromTo" && args.length >= 3) {
|
|
1216
|
+
results.push({
|
|
1217
|
+
node,
|
|
1218
|
+
ancestors: nodeAncestors,
|
|
1219
|
+
method: "fromTo",
|
|
1220
|
+
selector: selectorValue,
|
|
1221
|
+
...partial,
|
|
1222
|
+
fromArg: args[1],
|
|
1223
|
+
varsArg: args[2],
|
|
1224
|
+
positionArg: args[3]
|
|
1225
|
+
});
|
|
1226
|
+
} else if (method !== "fromTo" && args.length >= 2) {
|
|
1227
|
+
results.push({
|
|
1228
|
+
node,
|
|
1229
|
+
ancestors: nodeAncestors,
|
|
1230
|
+
method,
|
|
1231
|
+
selector: selectorValue,
|
|
1232
|
+
...partial,
|
|
1233
|
+
varsArg: args[1],
|
|
1234
|
+
positionArg: args[2],
|
|
1235
|
+
...isGlobalSet ? { global: true } : {}
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
for (const key of Object.keys(node)) {
|
|
1241
|
+
if (key === "type" || key === "start" || key === "end" || key === "loc") continue;
|
|
1242
|
+
const child = node[key];
|
|
1243
|
+
if (Array.isArray(child)) {
|
|
1244
|
+
for (const item of child) {
|
|
1245
|
+
if (item && typeof item === "object" && item.type) visit(item, nodeAncestors);
|
|
1246
|
+
}
|
|
1247
|
+
} else if (child && typeof child === "object" && child.type) {
|
|
1248
|
+
visit(child, nodeAncestors);
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
visit(ast, []);
|
|
1253
|
+
return results;
|
|
1254
|
+
}
|
|
1255
|
+
var PERCENTAGE_KEY_RE = /^(\d+(?:\.\d+)?)%$/;
|
|
1256
|
+
function tryResolveStringProp(propValue, scope, source) {
|
|
1257
|
+
const val = resolveNode(propValue, scope);
|
|
1258
|
+
if (typeof val === "string") return val;
|
|
1259
|
+
return source === void 0 ? void 0 : `__raw:${source.slice(propValue.start, propValue.end)}`;
|
|
1260
|
+
}
|
|
1261
|
+
function parsePercentageKeyframes(node, scope, source) {
|
|
1262
|
+
const keyframes = [];
|
|
1263
|
+
let ease;
|
|
1264
|
+
let easeEach;
|
|
1265
|
+
for (const prop of node.properties ?? []) {
|
|
1266
|
+
if (prop.type !== "ObjectProperty" && prop.type !== "Property") continue;
|
|
1267
|
+
const key = prop.key?.value ?? prop.key?.name;
|
|
1268
|
+
if (typeof key !== "string") continue;
|
|
1269
|
+
const pctMatch = PERCENTAGE_KEY_RE.exec(key);
|
|
1270
|
+
if (pctMatch) {
|
|
1271
|
+
if (!isPlainStep(prop.value)) return void 0;
|
|
1272
|
+
const percentage = Number.parseFloat(pctMatch[1] ?? "0");
|
|
1273
|
+
const record = objectExpressionToRecord(prop.value, scope, source);
|
|
1274
|
+
const properties = {};
|
|
1275
|
+
let kfEase;
|
|
1276
|
+
for (const [k, v] of Object.entries(record)) {
|
|
1277
|
+
if (k === "ease" && typeof v === "string") {
|
|
1278
|
+
kfEase = v;
|
|
1279
|
+
} else if (k === "duration") {
|
|
1280
|
+
continue;
|
|
1281
|
+
} else if (typeof v === "number" || typeof v === "string") {
|
|
1282
|
+
properties[k] = v;
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
keyframes.push({ percentage, properties, ...kfEase ? { ease: kfEase } : {} });
|
|
1286
|
+
} else if (key === "ease") {
|
|
1287
|
+
ease = tryResolveStringProp(prop.value, scope, source) ?? ease;
|
|
1288
|
+
} else if (key === "easeEach") {
|
|
1289
|
+
easeEach = tryResolveStringProp(prop.value, scope, source) ?? easeEach;
|
|
1290
|
+
} else {
|
|
1291
|
+
return void 0;
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
keyframes.sort((a, b) => a.percentage - b.percentage);
|
|
1295
|
+
return {
|
|
1296
|
+
format: "percentage",
|
|
1297
|
+
keyframes,
|
|
1298
|
+
...ease ? { ease } : {},
|
|
1299
|
+
...easeEach ? { easeEach } : {}
|
|
1300
|
+
};
|
|
1301
|
+
}
|
|
1302
|
+
function computeKeyframesTotalDuration(varsNode, scope, source) {
|
|
1303
|
+
const kfNode = (varsNode.properties ?? []).find(
|
|
1304
|
+
(p) => (p.key?.name ?? p.key?.value) === "keyframes"
|
|
1305
|
+
)?.value;
|
|
1306
|
+
if (!kfNode || kfNode.type !== "ArrayExpression") return void 0;
|
|
1307
|
+
const durations = [];
|
|
1308
|
+
for (const el of kfNode.elements ?? []) {
|
|
1309
|
+
if (!el || el.type !== "ObjectExpression") continue;
|
|
1310
|
+
const r = objectExpressionToRecord(el, scope, source);
|
|
1311
|
+
durations.push(r.duration);
|
|
1312
|
+
}
|
|
1313
|
+
return getObjectArrayKeyframeTiming(durations)?.totalDuration;
|
|
1314
|
+
}
|
|
1315
|
+
function staticKeyName(prop) {
|
|
1316
|
+
if (prop.type !== "ObjectProperty" && prop.type !== "Property") return void 0;
|
|
1317
|
+
if (prop.method || prop.kind && prop.kind !== "init") return void 0;
|
|
1318
|
+
const key = prop.computed ? prop.key?.type === "Literal" && prop.key.value : prop.key?.name ?? prop.key?.value;
|
|
1319
|
+
return typeof key === "string" ? key : void 0;
|
|
1320
|
+
}
|
|
1321
|
+
var isPlainObject = (node) => node?.type === "ObjectExpression" && (node.properties ?? []).every((p) => staticKeyName(p) !== void 0);
|
|
1322
|
+
var isPlainStep = (node) => node?.type === "Literal" || isPlainObject(node);
|
|
1323
|
+
function parseObjectArrayKeyframes(node, scope, source) {
|
|
1324
|
+
const elements = node.elements ?? [];
|
|
1325
|
+
const raw = [];
|
|
1326
|
+
for (const el of elements) {
|
|
1327
|
+
if (!isPlainObject(el)) return void 0;
|
|
1328
|
+
const record = objectExpressionToRecord(el, scope, source);
|
|
1329
|
+
const properties = {};
|
|
1330
|
+
let duration;
|
|
1331
|
+
let ease;
|
|
1332
|
+
for (const [k, v] of Object.entries(record)) {
|
|
1333
|
+
if (k === "duration") {
|
|
1334
|
+
duration = v;
|
|
1335
|
+
} else if (k === "ease" && typeof v === "string") {
|
|
1336
|
+
ease = v;
|
|
1337
|
+
} else if (typeof v === "number" || typeof v === "string") {
|
|
1338
|
+
properties[k] = v;
|
|
1339
|
+
} else {
|
|
1340
|
+
return void 0;
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
raw.push({ properties, duration, ease });
|
|
1344
|
+
}
|
|
1345
|
+
const timing = getObjectArrayKeyframeTiming(raw.map((entry) => entry.duration));
|
|
1346
|
+
if (!timing) return void 0;
|
|
1347
|
+
const keyframes = raw.map((entry, index) => ({
|
|
1348
|
+
percentage: timing.percentages[index],
|
|
1349
|
+
properties: entry.properties,
|
|
1350
|
+
...entry.ease ? { ease: entry.ease } : {}
|
|
1351
|
+
}));
|
|
1352
|
+
return { format: "object-array", keyframes };
|
|
1353
|
+
}
|
|
1354
|
+
function parseSimpleArrayKeyframes(node, scope) {
|
|
1355
|
+
const arrayProps = /* @__PURE__ */ new Map();
|
|
1356
|
+
let ease;
|
|
1357
|
+
let easeEach;
|
|
1358
|
+
for (const prop of node.properties ?? []) {
|
|
1359
|
+
if (prop.type !== "ObjectProperty" && prop.type !== "Property") continue;
|
|
1360
|
+
const key = prop.key?.name ?? prop.key?.value;
|
|
1361
|
+
if (typeof key !== "string") continue;
|
|
1362
|
+
if (prop.value?.type === "ArrayExpression") {
|
|
1363
|
+
const values = [];
|
|
1364
|
+
for (const el of prop.value.elements ?? []) {
|
|
1365
|
+
const val = resolveNode(el, scope);
|
|
1366
|
+
if (typeof val !== "number" && typeof val !== "string") return void 0;
|
|
1367
|
+
values.push(val);
|
|
1368
|
+
}
|
|
1369
|
+
if (values.length > 0) arrayProps.set(key, values);
|
|
1370
|
+
} else if (key === "ease") {
|
|
1371
|
+
ease = tryResolveStringProp(prop.value, scope) ?? ease;
|
|
1372
|
+
} else if (key === "easeEach") {
|
|
1373
|
+
easeEach = tryResolveStringProp(prop.value, scope) ?? easeEach;
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
const maxLen = Math.max(...[...arrayProps.values()].map((a) => a.length), 0);
|
|
1377
|
+
const keyframes = [];
|
|
1378
|
+
for (let i = 0; i < maxLen; i++) {
|
|
1379
|
+
const percentage = maxLen > 1 ? Math.round(i / (maxLen - 1) * 100) : 0;
|
|
1380
|
+
const properties = {};
|
|
1381
|
+
for (const [key, values] of arrayProps) {
|
|
1382
|
+
if (i < values.length) properties[key] = values[i];
|
|
1383
|
+
}
|
|
1384
|
+
keyframes.push({ percentage, properties });
|
|
1385
|
+
}
|
|
1386
|
+
return {
|
|
1387
|
+
format: "simple-array",
|
|
1388
|
+
keyframes,
|
|
1389
|
+
...ease ? { ease } : {},
|
|
1390
|
+
...easeEach ? { easeEach } : {}
|
|
1391
|
+
};
|
|
1392
|
+
}
|
|
1393
|
+
function parseKeyframesNode(node, scope, source) {
|
|
1394
|
+
if (!node) return void 0;
|
|
1395
|
+
if (node.type === "ArrayExpression") {
|
|
1396
|
+
return parseObjectArrayKeyframes(node, scope, source);
|
|
1397
|
+
}
|
|
1398
|
+
if (node.type !== "ObjectExpression") return void 0;
|
|
1399
|
+
const props = node.properties ?? [];
|
|
1400
|
+
if (!props.every((p) => staticKeyName(p) !== void 0)) return void 0;
|
|
1401
|
+
let hasPercentageKey = false;
|
|
1402
|
+
let hasArrayValue = false;
|
|
1403
|
+
for (const prop of props) {
|
|
1404
|
+
if (prop.type !== "ObjectProperty" && prop.type !== "Property") continue;
|
|
1405
|
+
const key = prop.key?.value ?? prop.key?.name;
|
|
1406
|
+
if (typeof key === "string" && PERCENTAGE_KEY_RE.test(key)) {
|
|
1407
|
+
hasPercentageKey = true;
|
|
1408
|
+
break;
|
|
1409
|
+
}
|
|
1410
|
+
if (prop.value?.type === "ArrayExpression") {
|
|
1411
|
+
hasArrayValue = true;
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
if (hasPercentageKey) return parsePercentageKeyframes(node, scope, source);
|
|
1415
|
+
if (hasArrayValue) return parseSimpleArrayKeyframes(node, scope);
|
|
1416
|
+
return void 0;
|
|
1417
|
+
}
|
|
1418
|
+
function parseMotionPathNode(node, scope, source) {
|
|
1419
|
+
if (!node) return void 0;
|
|
1420
|
+
let pathNode;
|
|
1421
|
+
let autoRotate = false;
|
|
1422
|
+
let curviness = 1;
|
|
1423
|
+
let isCubic = false;
|
|
1424
|
+
if (node.type === "ObjectExpression") {
|
|
1425
|
+
for (const prop of node.properties ?? []) {
|
|
1426
|
+
if (!isObjectProperty(prop)) continue;
|
|
1427
|
+
const key = propKeyName(prop);
|
|
1428
|
+
if (key === "path") pathNode = prop.value;
|
|
1429
|
+
else if (key === "autoRotate") {
|
|
1430
|
+
const val = resolveNode(prop.value, scope);
|
|
1431
|
+
autoRotate = typeof val === "number" ? val : val === true;
|
|
1432
|
+
} else if (key === "curviness") {
|
|
1433
|
+
const val = resolveNode(prop.value, scope);
|
|
1434
|
+
if (typeof val === "number") curviness = val;
|
|
1435
|
+
} else if (key === "type") {
|
|
1436
|
+
const val = resolveNode(prop.value, scope);
|
|
1437
|
+
if (val === "cubic") isCubic = true;
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
} else if (node.type === "ArrayExpression") {
|
|
1441
|
+
pathNode = node;
|
|
1442
|
+
}
|
|
1443
|
+
if (!pathNode || pathNode.type !== "ArrayExpression") return void 0;
|
|
1444
|
+
const elements = pathNode.elements ?? [];
|
|
1445
|
+
const coords = [];
|
|
1446
|
+
for (const elem of elements) {
|
|
1447
|
+
if (!elem || elem.type !== "ObjectExpression") continue;
|
|
1448
|
+
const rec = objectExpressionToRecord(elem, scope, source);
|
|
1449
|
+
const x = typeof rec.x === "number" ? rec.x : void 0;
|
|
1450
|
+
const y = typeof rec.y === "number" ? rec.y : void 0;
|
|
1451
|
+
if (x !== void 0 && y !== void 0) coords.push({ x, y });
|
|
1452
|
+
}
|
|
1453
|
+
return buildArcPath(coords, curviness, autoRotate, isCubic);
|
|
1454
|
+
}
|
|
1455
|
+
function tweenCallToAnimation(call, scope, source, identifierBindings) {
|
|
1456
|
+
const provenance = readProvenance(call.node);
|
|
1457
|
+
const vars = objectExpressionToRecord(call.varsArg, scope, source);
|
|
1458
|
+
const properties = {};
|
|
1459
|
+
const extras = {};
|
|
1460
|
+
let keyframesData;
|
|
1461
|
+
let hasUnresolvedKeyframes = false;
|
|
1462
|
+
let motionPathResult;
|
|
1463
|
+
for (const [key, val] of Object.entries(vars)) {
|
|
1464
|
+
if (BUILTIN_VAR_KEYS.has(key)) continue;
|
|
1465
|
+
if (DROPPED_VAR_KEYS.has(key)) continue;
|
|
1466
|
+
if (key === "keyframes") {
|
|
1467
|
+
const kfNode = findPropertyNode(call.varsArg, "keyframes");
|
|
1468
|
+
keyframesData = parseKeyframesNode(kfNode, scope, source);
|
|
1469
|
+
if (!keyframesData && kfNode) hasUnresolvedKeyframes = true;
|
|
1470
|
+
continue;
|
|
1471
|
+
}
|
|
1472
|
+
if (key === "motionPath") {
|
|
1473
|
+
const mpNode = findPropertyNode(call.varsArg, "motionPath");
|
|
1474
|
+
motionPathResult = parseMotionPathNode(mpNode, scope, source);
|
|
1475
|
+
continue;
|
|
1476
|
+
}
|
|
1477
|
+
if (key === "easeEach") continue;
|
|
1478
|
+
if (EXTRAS_KEYS.has(key)) {
|
|
1479
|
+
const rawSource = extractRawPropertySource(call.varsArg, key, source);
|
|
1480
|
+
if (rawSource !== void 0) {
|
|
1481
|
+
extras[key] = `__raw:${rawSource}`;
|
|
1482
|
+
} else if (val !== void 0) {
|
|
1483
|
+
extras[key] = val;
|
|
1484
|
+
}
|
|
1485
|
+
continue;
|
|
1486
|
+
}
|
|
1487
|
+
if (typeof val === "number" || typeof val === "string") {
|
|
1488
|
+
properties[key] = val;
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
if (keyframesData && typeof vars.easeEach === "string") {
|
|
1492
|
+
keyframesData.easeEach = vars.easeEach;
|
|
1493
|
+
}
|
|
1494
|
+
if (motionPathResult) {
|
|
1495
|
+
const { waypoints } = motionPathResult;
|
|
1496
|
+
if (!keyframesData) {
|
|
1497
|
+
const kf = waypoints.map((wp, i) => ({
|
|
1498
|
+
percentage: waypoints.length > 1 ? Math.round(i / (waypoints.length - 1) * 100) : 0,
|
|
1499
|
+
properties: { x: wp.x, y: wp.y }
|
|
1500
|
+
}));
|
|
1501
|
+
keyframesData = { format: "percentage", keyframes: kf, fromMotionPath: true };
|
|
1502
|
+
} else {
|
|
1503
|
+
const kfs = keyframesData.keyframes;
|
|
1504
|
+
if (kfs.length === waypoints.length) {
|
|
1505
|
+
for (let i = 0; i < kfs.length; i++) {
|
|
1506
|
+
const kf = kfs[i];
|
|
1507
|
+
const wp = waypoints[i];
|
|
1508
|
+
if (kf && wp) {
|
|
1509
|
+
kf.properties.x = wp.x;
|
|
1510
|
+
kf.properties.y = wp.y;
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
let fromProperties;
|
|
1517
|
+
if (call.method === "fromTo" && call.fromArg) {
|
|
1518
|
+
fromProperties = {};
|
|
1519
|
+
const fromVars = objectExpressionToRecord(call.fromArg, scope, source);
|
|
1520
|
+
for (const [key, val] of Object.entries(fromVars)) {
|
|
1521
|
+
if (typeof val === "number" || typeof val === "string") {
|
|
1522
|
+
fromProperties[key] = val;
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
const hasPositionArg = !!call.positionArg;
|
|
1527
|
+
const posVal = hasPositionArg ? extractLiteralValue(call.positionArg, scope) : 0;
|
|
1528
|
+
const position = typeof posVal === "number" ? posVal : typeof posVal === "string" ? posVal : hasPositionArg ? `__raw:${source.slice(call.positionArg.start, call.positionArg.end)}` : 0;
|
|
1529
|
+
let duration = typeof vars.duration === "number" ? vars.duration : void 0;
|
|
1530
|
+
const ease = typeof vars.ease === "string" ? vars.ease : void 0;
|
|
1531
|
+
const durationUnresolved = call.method !== "set" && duration === void 0 && hasUnknownDuration(call.varsArg, scope);
|
|
1532
|
+
if (duration === void 0 && keyframesData && !durationUnresolved) {
|
|
1533
|
+
duration = computeKeyframesTotalDuration(call.varsArg, scope, source);
|
|
1534
|
+
}
|
|
1535
|
+
let selector = call.selector;
|
|
1536
|
+
let targetIdentity;
|
|
1537
|
+
if (selector === "__unresolved__") {
|
|
1538
|
+
const targetNode = call.node.arguments?.[0];
|
|
1539
|
+
const proxyLabel = describeProxyTarget(targetNode, call.varsArg, scope);
|
|
1540
|
+
if (proxyLabel) {
|
|
1541
|
+
selector = proxyLabel;
|
|
1542
|
+
if (targetNode?.type === "Identifier") {
|
|
1543
|
+
const declaration = findVisibleIdentifierDeclaration(
|
|
1544
|
+
targetNode.name,
|
|
1545
|
+
call.ancestors,
|
|
1546
|
+
identifierBindings,
|
|
1547
|
+
call.node.start
|
|
1548
|
+
);
|
|
1549
|
+
if (declaration?.node.init?.type === "ObjectExpression" && !identifierBindings.reassignedDeclarations.has(declaration.node)) {
|
|
1550
|
+
const declarationProvenance = readProvenance(declaration.scopeNode) ?? readProvenance(declaration.expandedScopeNode);
|
|
1551
|
+
const instanceIdentity = declarationProvenance && (declarationProvenance.kind === "helper" || declarationProvenance.kind === "loop") ? `:${declarationProvenance.kind}:${declarationProvenance.callSite ?? ""}:${declarationProvenance.iteration ?? ""}` : "";
|
|
1552
|
+
targetIdentity = `proxy:${targetNode.name}@${declaration.node.start}${instanceIdentity}`;
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
const anim = {
|
|
1558
|
+
targetSelector: selector,
|
|
1559
|
+
method: call.method,
|
|
1560
|
+
position,
|
|
1561
|
+
properties,
|
|
1562
|
+
fromProperties,
|
|
1563
|
+
duration,
|
|
1564
|
+
ease
|
|
1565
|
+
};
|
|
1566
|
+
if (targetIdentity) anim.targetIdentity = targetIdentity;
|
|
1567
|
+
if (!hasPositionArg) anim.implicitPosition = true;
|
|
1568
|
+
let group = classifyTweenPropertyGroup(properties);
|
|
1569
|
+
if (!group && keyframesData) {
|
|
1570
|
+
const kfProps = {};
|
|
1571
|
+
for (const kf of keyframesData.keyframes) {
|
|
1572
|
+
for (const k of Object.keys(kf.properties)) kfProps[k] = true;
|
|
1573
|
+
}
|
|
1574
|
+
group = classifyTweenPropertyGroup(kfProps);
|
|
1575
|
+
}
|
|
1576
|
+
if (group) anim.propertyGroup = group;
|
|
1577
|
+
if (call.global) anim.global = true;
|
|
1578
|
+
if (Object.keys(extras).length > 0) anim.extras = extras;
|
|
1579
|
+
if (keyframesData) anim.keyframes = keyframesData;
|
|
1580
|
+
if (motionPathResult) anim.arcPath = motionPathResult.arcPath;
|
|
1581
|
+
if (hasUnresolvedKeyframes) anim.hasUnresolvedKeyframes = true;
|
|
1582
|
+
if (durationUnresolved) anim.durationUnresolved = true;
|
|
1583
|
+
if (selector === "__unresolved__") anim.hasUnresolvedSelector = true;
|
|
1584
|
+
if (call.selectorPartial) anim.hasPartialSelector = true;
|
|
1585
|
+
if (provenance) anim.provenance = provenance;
|
|
1586
|
+
return anim;
|
|
1587
|
+
}
|
|
1588
|
+
function staggerAmount(raw) {
|
|
1589
|
+
if (typeof raw === "number") return raw;
|
|
1590
|
+
if (typeof raw !== "string") return void 0;
|
|
1591
|
+
const src = raw.startsWith("__raw:") ? raw.slice(6) : raw;
|
|
1592
|
+
const m = /(?:each\s*:\s*)?(-?\d+(?:\.\d+)?)/.exec(src);
|
|
1593
|
+
if (!m) return void 0;
|
|
1594
|
+
const n = Number.parseFloat(m[1]);
|
|
1595
|
+
return Number.isFinite(n) ? n : void 0;
|
|
1596
|
+
}
|
|
1597
|
+
function restValue(prop) {
|
|
1598
|
+
return prop === "opacity" || prop.startsWith("scale") ? 1 : 0;
|
|
1599
|
+
}
|
|
1600
|
+
function staggeredKeyframes(anim, each) {
|
|
1601
|
+
const vars = { ...anim.properties };
|
|
1602
|
+
let from;
|
|
1603
|
+
let to;
|
|
1604
|
+
if (anim.method === "fromTo") {
|
|
1605
|
+
from = { ...anim.fromProperties ?? {} };
|
|
1606
|
+
to = vars;
|
|
1607
|
+
} else if (anim.method === "from") {
|
|
1608
|
+
from = vars;
|
|
1609
|
+
to = {};
|
|
1610
|
+
for (const k of Object.keys(vars)) to[k] = restValue(k);
|
|
1611
|
+
} else {
|
|
1612
|
+
from = { ...anim.fromProperties ?? {} };
|
|
1613
|
+
for (const k of Object.keys(vars)) if (from[k] === void 0) from[k] = restValue(k);
|
|
1614
|
+
to = vars;
|
|
1615
|
+
}
|
|
1616
|
+
return [
|
|
1617
|
+
{ percentage: 0, properties: { ...from, stagger: each } },
|
|
1618
|
+
{ percentage: 100, properties: { ...to, stagger: each } }
|
|
1619
|
+
];
|
|
1620
|
+
}
|
|
1621
|
+
function annotateStaggeredCollections(anims) {
|
|
1622
|
+
for (const anim of anims) {
|
|
1623
|
+
if (anim.keyframes || anim.arcPath) continue;
|
|
1624
|
+
const each = staggerAmount(anim.extras?.stagger);
|
|
1625
|
+
if (each === void 0) continue;
|
|
1626
|
+
anim.keyframes = { format: "percentage", keyframes: staggeredKeyframes(anim, each) };
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
function resolvePositionString(pos, cursor, prevStart) {
|
|
1630
|
+
const trimmed = pos.trim();
|
|
1631
|
+
if (trimmed === "") return cursor;
|
|
1632
|
+
if (trimmed.startsWith("+=")) {
|
|
1633
|
+
const n2 = Number.parseFloat(trimmed.slice(2));
|
|
1634
|
+
return Number.isFinite(n2) ? cursor + n2 : null;
|
|
1635
|
+
}
|
|
1636
|
+
if (trimmed.startsWith("-=")) {
|
|
1637
|
+
const n2 = Number.parseFloat(trimmed.slice(2));
|
|
1638
|
+
return Number.isFinite(n2) ? cursor - n2 : null;
|
|
1639
|
+
}
|
|
1640
|
+
if (trimmed === "<") return prevStart;
|
|
1641
|
+
if (trimmed === ">") return cursor;
|
|
1642
|
+
if (trimmed.startsWith("<")) {
|
|
1643
|
+
const n2 = Number.parseFloat(trimmed.slice(1));
|
|
1644
|
+
return Number.isFinite(n2) ? prevStart + n2 : null;
|
|
1645
|
+
}
|
|
1646
|
+
if (trimmed.startsWith(">")) {
|
|
1647
|
+
const n2 = Number.parseFloat(trimmed.slice(1));
|
|
1648
|
+
return Number.isFinite(n2) ? cursor + n2 : null;
|
|
1649
|
+
}
|
|
1650
|
+
const n = Number.parseFloat(trimmed);
|
|
1651
|
+
return Number.isFinite(n) ? n : null;
|
|
1652
|
+
}
|
|
1653
|
+
function collectGsapSetStates(ast, scope, bindings, source) {
|
|
1654
|
+
const states = /* @__PURE__ */ new Map();
|
|
1655
|
+
ancestor(ast, {
|
|
1656
|
+
// fallow-ignore-next-line complexity
|
|
1657
|
+
CallExpression(node, _, ancestors) {
|
|
1658
|
+
const callee = node.callee;
|
|
1659
|
+
if (callee?.type !== "MemberExpression" || callee.object?.name !== "gsap" || callee.property?.name !== "set")
|
|
1660
|
+
return;
|
|
1661
|
+
const selector = resolveTargetSelector(node.arguments?.[0], ancestors, scope, bindings);
|
|
1662
|
+
if (!selector) return;
|
|
1663
|
+
const rec = objectExpressionToRecord(node.arguments?.[1], scope, source);
|
|
1664
|
+
const props = states.get(selector) ?? {};
|
|
1665
|
+
for (const [k, v] of Object.entries(rec)) {
|
|
1666
|
+
if (typeof v === "number" || typeof v === "string") props[k] = v;
|
|
1667
|
+
}
|
|
1668
|
+
states.set(selector, props);
|
|
1669
|
+
}
|
|
1670
|
+
});
|
|
1671
|
+
return states;
|
|
1672
|
+
}
|
|
1673
|
+
function mergeProps(target, props) {
|
|
1674
|
+
for (const [k, v] of Object.entries(props)) target[k] = v;
|
|
1675
|
+
return target;
|
|
1676
|
+
}
|
|
1677
|
+
function seedFromPreState(anim, cur) {
|
|
1678
|
+
const from = { ...anim.fromProperties ?? {} };
|
|
1679
|
+
let seeded = false;
|
|
1680
|
+
for (const prop of Object.keys(anim.properties)) {
|
|
1681
|
+
if (from[prop] === void 0 && cur[prop] !== void 0) {
|
|
1682
|
+
from[prop] = cur[prop];
|
|
1683
|
+
seeded = true;
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
if (seeded) anim.fromProperties = from;
|
|
1687
|
+
}
|
|
1688
|
+
function seedSetStates(anims, initial) {
|
|
1689
|
+
const state = /* @__PURE__ */ new Map();
|
|
1690
|
+
for (const [sel, props] of initial) state.set(sel, { ...props });
|
|
1691
|
+
for (const anim of anims) {
|
|
1692
|
+
const sel = anim.targetSelector;
|
|
1693
|
+
if (anim.method === "set") {
|
|
1694
|
+
state.set(sel, mergeProps(state.get(sel) ?? {}, anim.properties));
|
|
1695
|
+
continue;
|
|
1696
|
+
}
|
|
1697
|
+
const cur = state.get(sel);
|
|
1698
|
+
if (anim.method === "to" && cur) seedFromPreState(anim, cur);
|
|
1699
|
+
state.set(sel, mergeProps(state.get(sel) ?? {}, anim.properties));
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
function applyTimelineDefaults(anims, defaults) {
|
|
1703
|
+
if (!defaults) return;
|
|
1704
|
+
for (const anim of anims) {
|
|
1705
|
+
if (anim.method === "set") continue;
|
|
1706
|
+
if (anim.duration === void 0 && !anim.durationUnresolved) {
|
|
1707
|
+
if (defaults.duration !== void 0) anim.duration = defaults.duration;
|
|
1708
|
+
else if (defaults.durationUnresolved) anim.durationUnresolved = true;
|
|
1709
|
+
}
|
|
1710
|
+
if (anim.ease === void 0 && defaults.ease !== void 0 && (!anim.keyframes || anim.keyframes.fromMotionPath)) {
|
|
1711
|
+
anim.ease = defaults.ease;
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
function resolveLabelPosition(pos, labels, cursor) {
|
|
1716
|
+
const m = /^([A-Za-z_$][\w$]*)\s*(?:([+-])=\s*([\d.]+))?$/.exec(pos.trim());
|
|
1717
|
+
if (!m) return null;
|
|
1718
|
+
const name = m[1];
|
|
1719
|
+
let base = labels.get(name);
|
|
1720
|
+
if (base === void 0) {
|
|
1721
|
+
base = cursor;
|
|
1722
|
+
labels.set(name, base);
|
|
1723
|
+
}
|
|
1724
|
+
if (m[2] && m[3]) {
|
|
1725
|
+
const n = Number.parseFloat(m[3]);
|
|
1726
|
+
if (Number.isFinite(n)) return m[2] === "+" ? base + n : base - n;
|
|
1727
|
+
}
|
|
1728
|
+
return base;
|
|
1729
|
+
}
|
|
1730
|
+
function resolveAnimStart(anim, cursor, prevStart, labels) {
|
|
1731
|
+
if (anim.implicitPosition) return cursor;
|
|
1732
|
+
if (typeof anim.position === "number") return anim.position;
|
|
1733
|
+
if (typeof anim.position === "string") {
|
|
1734
|
+
return resolveLabelPosition(anim.position, labels, cursor) ?? resolvePositionString(anim.position, cursor, prevStart);
|
|
1735
|
+
}
|
|
1736
|
+
return cursor;
|
|
1737
|
+
}
|
|
1738
|
+
function resolveTimelinePositions(anims, labelDefs = []) {
|
|
1739
|
+
let cursor = 0;
|
|
1740
|
+
let prevStart = 0;
|
|
1741
|
+
let cursorKnown = true;
|
|
1742
|
+
const labels = /* @__PURE__ */ new Map();
|
|
1743
|
+
let labelIdx = 0;
|
|
1744
|
+
const sortedLabels = [...labelDefs].sort((a, b) => a.order - b.order);
|
|
1745
|
+
const defineLabel = (def) => {
|
|
1746
|
+
let value;
|
|
1747
|
+
if (typeof def.position === "number") value = def.position;
|
|
1748
|
+
else if (!cursorKnown) return;
|
|
1749
|
+
else if (typeof def.position === "string") {
|
|
1750
|
+
value = resolveLabelPosition(def.position, labels, cursor) ?? cursor;
|
|
1751
|
+
} else value = cursor;
|
|
1752
|
+
labels.set(def.name, Math.max(0, value));
|
|
1753
|
+
};
|
|
1754
|
+
anims.forEach((anim, i) => {
|
|
1755
|
+
while (labelIdx < sortedLabels.length && sortedLabels[labelIdx].order <= i) {
|
|
1756
|
+
defineLabel(sortedLabels[labelIdx]);
|
|
1757
|
+
labelIdx++;
|
|
1758
|
+
}
|
|
1759
|
+
if (anim.method === "set" && anim.global) {
|
|
1760
|
+
anim.resolvedStart = 0;
|
|
1761
|
+
return;
|
|
1762
|
+
}
|
|
1763
|
+
const duration = anim.method === "set" ? 0 : anim.duration ?? GSAP_DEFAULT_DURATION;
|
|
1764
|
+
const readsCursor = anim.implicitPosition || typeof anim.position !== "number";
|
|
1765
|
+
const start = cursorKnown || !readsCursor ? resolveAnimStart(anim, cursor, prevStart, labels) : null;
|
|
1766
|
+
if (start == null || anim.durationUnresolved) cursorKnown = false;
|
|
1767
|
+
if (start != null) {
|
|
1768
|
+
anim.resolvedStart = Math.max(0, start);
|
|
1769
|
+
prevStart = anim.resolvedStart;
|
|
1770
|
+
cursor = Math.max(cursor, anim.resolvedStart + duration);
|
|
1771
|
+
}
|
|
1772
|
+
});
|
|
1773
|
+
while (labelIdx < sortedLabels.length) defineLabel(sortedLabels[labelIdx++]);
|
|
1774
|
+
}
|
|
1775
|
+
function collectAddLabelDefs(ast, ref, scope, sortedCalls) {
|
|
1776
|
+
const callKeys = sortedCalls.map((c2) => ({
|
|
1777
|
+
site: callSiteStart(c2),
|
|
1778
|
+
order: c2.node.__hfOrder
|
|
1779
|
+
}));
|
|
1780
|
+
const comesAfter = (site, order, labelSite, labelOrder) => {
|
|
1781
|
+
if (site === void 0) return false;
|
|
1782
|
+
if (site !== labelSite) return site > labelSite;
|
|
1783
|
+
return (order ?? -Infinity) > (labelOrder ?? -Infinity);
|
|
1784
|
+
};
|
|
1785
|
+
const defs = [];
|
|
1786
|
+
simple(ast, {
|
|
1787
|
+
// fallow-ignore-next-line complexity
|
|
1788
|
+
CallExpression(node) {
|
|
1789
|
+
const callee = node.callee;
|
|
1790
|
+
const objMatches = ref.kind === "identifier" ? callee.object?.type === "Identifier" && callee.object.name === ref.name : sameMemberAccess(callee.object, ref.node);
|
|
1791
|
+
if (callee?.type !== "MemberExpression" || !objMatches || callee.property?.name !== "addLabel")
|
|
1792
|
+
return;
|
|
1793
|
+
const nameNode = node.arguments?.[0];
|
|
1794
|
+
const name = typeof nameNode?.value === "string" ? nameNode.value : void 0;
|
|
1795
|
+
if (!name) return;
|
|
1796
|
+
const posVal = resolveNode(node.arguments?.[1], scope);
|
|
1797
|
+
const position = typeof posVal === "number" || typeof posVal === "string" ? posVal : void 0;
|
|
1798
|
+
const labelStart = node.__hfSiteStart ?? callee.property?.start;
|
|
1799
|
+
const labelOrder = node.__hfOrder;
|
|
1800
|
+
let order = sortedCalls.length;
|
|
1801
|
+
if (labelStart !== void 0) {
|
|
1802
|
+
order = callKeys.findIndex((k) => comesAfter(k.site, k.order, labelStart, labelOrder));
|
|
1803
|
+
if (order === -1) order = sortedCalls.length;
|
|
1804
|
+
}
|
|
1805
|
+
defs.push({ name, position, order });
|
|
1806
|
+
}
|
|
1807
|
+
});
|
|
1808
|
+
return defs;
|
|
1809
|
+
}
|
|
1810
|
+
function compareByLoc(a, b) {
|
|
1811
|
+
const aLoc = a.node.callee?.property?.loc?.start;
|
|
1812
|
+
const bLoc = b.node.callee?.property?.loc?.start;
|
|
1813
|
+
if (!aLoc || !bLoc) return 0;
|
|
1814
|
+
return aLoc.line - bLoc.line || aLoc.column - bLoc.column;
|
|
1815
|
+
}
|
|
1816
|
+
function callSiteStart(call) {
|
|
1817
|
+
return call.node.__hfSiteStart ?? call.node.callee?.property?.start;
|
|
1818
|
+
}
|
|
1819
|
+
function compareCallOrder(a, b) {
|
|
1820
|
+
const aSite = callSiteStart(a);
|
|
1821
|
+
const bSite = callSiteStart(b);
|
|
1822
|
+
if (aSite !== void 0 && bSite !== void 0 && aSite !== bSite) return aSite - bSite;
|
|
1823
|
+
const ao = a.node.__hfOrder;
|
|
1824
|
+
const bo = b.node.__hfOrder;
|
|
1825
|
+
if (ao !== void 0 && bo !== void 0) return ao - bo;
|
|
1826
|
+
return compareByLoc(a, b);
|
|
1827
|
+
}
|
|
1828
|
+
function sortBySourcePosition(calls) {
|
|
1829
|
+
calls.sort(compareCallOrder);
|
|
1830
|
+
}
|
|
1831
|
+
function assignStableIds(anims) {
|
|
1832
|
+
const counts = /* @__PURE__ */ new Map();
|
|
1833
|
+
return anims.map((anim) => {
|
|
1834
|
+
const posKey = typeof anim.position === "number" ? String(Math.round(anim.position * 1e3)) : String(anim.position);
|
|
1835
|
+
const groupSuffix = anim.propertyGroup ? `-${anim.propertyGroup}` : "";
|
|
1836
|
+
const base = `${anim.targetSelector}-${anim.method}-${posKey}${groupSuffix}`;
|
|
1837
|
+
const count = (counts.get(base) ?? 0) + 1;
|
|
1838
|
+
counts.set(base, count);
|
|
1839
|
+
const id = count === 1 ? base : `${base}-${count}`;
|
|
1840
|
+
return { ...anim, id };
|
|
1841
|
+
});
|
|
1842
|
+
}
|
|
1843
|
+
var PARSE_MEMO_ENTRIES = 4;
|
|
1844
|
+
var parseMemo = /* @__PURE__ */ new Map();
|
|
1845
|
+
function parseGsapScriptAcorn(script) {
|
|
1846
|
+
const parsed = parseMemo.get(script) ?? parseGsapScriptAcornUncached(script);
|
|
1847
|
+
parseMemo.delete(script);
|
|
1848
|
+
parseMemo.set(script, parsed);
|
|
1849
|
+
if (parseMemo.size > PARSE_MEMO_ENTRIES) parseMemo.delete(parseMemo.keys().next().value);
|
|
1850
|
+
return structuredClone(parsed);
|
|
1851
|
+
}
|
|
1852
|
+
function parseGsapScriptAcornUncached(script) {
|
|
1853
|
+
try {
|
|
1854
|
+
const ast = parseProgram(script);
|
|
1855
|
+
const scope = collectScopeBindings(ast);
|
|
1856
|
+
const detection = findTimelineVar(ast, scope);
|
|
1857
|
+
const ref = detection.ref ?? { kind: "identifier", name: "tl" };
|
|
1858
|
+
const timelineVar = timelineRootSource(ref, script);
|
|
1859
|
+
if (ref.kind === "identifier") {
|
|
1860
|
+
try {
|
|
1861
|
+
inlineComputedTimelines(ast, timelineVar, (node) => resolveNode(node, scope));
|
|
1862
|
+
} catch {
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
const identifierBindings = collectIdentifierBindingIndex(ast);
|
|
1866
|
+
const targetBindings = collectTargetBindings(ast, scope, identifierBindings);
|
|
1867
|
+
const calls = findAllTweenCalls(ast, ref, scope, targetBindings);
|
|
1868
|
+
sortBySourcePosition(calls);
|
|
1869
|
+
const rawAnims = calls.map(
|
|
1870
|
+
(call) => tweenCallToAnimation(call, scope, script, identifierBindings)
|
|
1871
|
+
);
|
|
1872
|
+
applyTimelineDefaults(rawAnims, detection.defaults);
|
|
1873
|
+
seedSetStates(rawAnims, collectGsapSetStates(ast, scope, targetBindings, script));
|
|
1874
|
+
const labelDefs = collectAddLabelDefs(ast, ref, scope, calls);
|
|
1875
|
+
resolveTimelinePositions(rawAnims, labelDefs);
|
|
1876
|
+
annotateStaggeredCollections(rawAnims);
|
|
1877
|
+
const animations = assignStableIds(rawAnims);
|
|
1878
|
+
const declPattern = ref.kind === "identifier" ? `(?:const|let|var)\\s+${timelineVar}\\s*=\\s*gsap\\.timeline\\s*\\([^)]*\\)\\s*;?` : `${escapeRegExp(timelineVar)}\\s*=\\s*gsap\\.timeline\\s*\\([^)]*\\)\\s*;?`;
|
|
1879
|
+
const timelineMatch = script.match(new RegExp(`^[\\s\\S]*?${declPattern}`));
|
|
1880
|
+
const fallbackPreamble = ref.kind === "identifier" ? `const ${timelineVar} = gsap.timeline({ paused: true });` : `${timelineVar} = gsap.timeline({ paused: true });`;
|
|
1881
|
+
const preamble = timelineMatch?.[0] ?? fallbackPreamble;
|
|
1882
|
+
const lastCallIdx = script.lastIndexOf(`${timelineVar}.`);
|
|
1883
|
+
let postamble = "";
|
|
1884
|
+
if (lastCallIdx !== -1) {
|
|
1885
|
+
const afterLast = script.slice(lastCallIdx);
|
|
1886
|
+
const endOfCall = afterLast.indexOf(";");
|
|
1887
|
+
if (endOfCall !== -1) {
|
|
1888
|
+
postamble = script.slice(lastCallIdx + endOfCall + 1).trim();
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
const result = { animations, timelineVar, preamble, postamble };
|
|
1892
|
+
if (detection.timelineCount > 1) result.multipleTimelines = true;
|
|
1893
|
+
if (detection.timelineCount > 0 && detection.ref === null)
|
|
1894
|
+
result.unsupportedTimelinePattern = true;
|
|
1895
|
+
return result;
|
|
1896
|
+
} catch {
|
|
1897
|
+
return { animations: [], timelineVar: "tl", preamble: "", postamble: "" };
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
|
|
1901
|
+
// src/commands/keyframes.ts
|
|
1902
|
+
var examples = [
|
|
1903
|
+
["Surface every keyframe + motion path in the project", "hyperframes keyframes"],
|
|
1904
|
+
["Inspect one composition file", "hyperframes keyframes compositions/scene.html"],
|
|
1905
|
+
["Machine-readable output for an agent", "hyperframes keyframes --json"],
|
|
1906
|
+
["Only one element's keyframes", "hyperframes keyframes --selector '#puck-a'"],
|
|
1907
|
+
["Runtime-aware hint for CSS/Anime compositions", "hyperframes keyframes --runtime all"]
|
|
1908
|
+
];
|
|
1909
|
+
function queryIncludingTemplates(html, selector) {
|
|
1910
|
+
const doc = new DOMParser().parseFromString(html, "text/html");
|
|
1911
|
+
const roots = [doc];
|
|
1912
|
+
const queue = Array.from(doc.querySelectorAll("template"));
|
|
1913
|
+
while (queue.length > 0) {
|
|
1914
|
+
const content = queue.shift().content;
|
|
1915
|
+
if (!content) continue;
|
|
1916
|
+
roots.push(content);
|
|
1917
|
+
queue.push(...Array.from(content.querySelectorAll("template")));
|
|
1918
|
+
}
|
|
1919
|
+
return roots.flatMap((root) => Array.from(root.querySelectorAll(selector)));
|
|
1920
|
+
}
|
|
1921
|
+
function inlineScriptText(html) {
|
|
1922
|
+
return queryIncludingTemplates(html, "script").filter((s) => !s.getAttribute("src")).map((s) => s.textContent ?? "").join("\n");
|
|
1923
|
+
}
|
|
1924
|
+
function inlineStyleText(html) {
|
|
1925
|
+
return queryIncludingTemplates(html, "style").map((s) => s.textContent ?? "").join("\n");
|
|
1926
|
+
}
|
|
1927
|
+
function num(v) {
|
|
1928
|
+
if (typeof v === "number") return v;
|
|
1929
|
+
if (typeof v === "string") {
|
|
1930
|
+
const n = Number.parseFloat(v);
|
|
1931
|
+
return Number.isFinite(n) ? n : null;
|
|
1932
|
+
}
|
|
1933
|
+
return null;
|
|
1934
|
+
}
|
|
1935
|
+
function isPositionTween(anim) {
|
|
1936
|
+
if (anim.propertyGroup === "position") return true;
|
|
1937
|
+
const has = (p) => !!p && ("x" in p || "y" in p);
|
|
1938
|
+
if (has(anim.properties) || has(anim.fromProperties)) return true;
|
|
1939
|
+
return (anim.keyframes?.keyframes ?? []).some(
|
|
1940
|
+
(kf) => "x" in kf.properties || "y" in kf.properties
|
|
1941
|
+
);
|
|
1942
|
+
}
|
|
1943
|
+
function baseProps(props) {
|
|
1944
|
+
const base = {};
|
|
1945
|
+
for (const k of Object.keys(props)) {
|
|
1946
|
+
if (k === "ease") continue;
|
|
1947
|
+
base[k] = k === "opacity" || k.startsWith("scale") ? 1 : 0;
|
|
1948
|
+
}
|
|
1949
|
+
return base;
|
|
1950
|
+
}
|
|
1951
|
+
function flatKeyframes(anim) {
|
|
1952
|
+
if (anim.method === "fromTo") {
|
|
1953
|
+
return [
|
|
1954
|
+
{ pct: 0, time: 0, properties: anim.fromProperties ?? {} },
|
|
1955
|
+
{ pct: 100, time: 0, properties: anim.properties ?? {} }
|
|
1956
|
+
];
|
|
1957
|
+
}
|
|
1958
|
+
const vars = anim.properties ?? {};
|
|
1959
|
+
const base = baseProps(vars);
|
|
1960
|
+
return anim.method === "from" ? [
|
|
1961
|
+
{ pct: 0, time: 0, properties: vars },
|
|
1962
|
+
{ pct: 100, time: 0, properties: base }
|
|
1963
|
+
] : [
|
|
1964
|
+
{ pct: 0, time: 0, properties: base },
|
|
1965
|
+
{ pct: 100, time: 0, properties: vars }
|
|
1966
|
+
];
|
|
1967
|
+
}
|
|
1968
|
+
function isHoldMarker(anim) {
|
|
1969
|
+
return anim.properties?.data === "hf-hold" || anim.fromProperties?.data === "hf-hold";
|
|
1970
|
+
}
|
|
1971
|
+
function cleanProps(props) {
|
|
1972
|
+
const out = {};
|
|
1973
|
+
for (const [k, v] of Object.entries(props)) {
|
|
1974
|
+
if (k === "data" || k === "ease") continue;
|
|
1975
|
+
out[k] = v;
|
|
1976
|
+
}
|
|
1977
|
+
return out;
|
|
1978
|
+
}
|
|
1979
|
+
function surfaceTween(anim) {
|
|
1980
|
+
const start = typeof anim.resolvedStart === "number" ? anim.resolvedStart : num(anim.position) ?? 0;
|
|
1981
|
+
const duration = anim.duration ?? 0;
|
|
1982
|
+
let shape;
|
|
1983
|
+
let rawKfs;
|
|
1984
|
+
if (anim.keyframes?.keyframes?.length) {
|
|
1985
|
+
shape = "keyframes";
|
|
1986
|
+
rawKfs = anim.keyframes.keyframes;
|
|
1987
|
+
} else if (anim.arcPath?.enabled) {
|
|
1988
|
+
shape = "motionPath";
|
|
1989
|
+
rawKfs = [];
|
|
1990
|
+
} else {
|
|
1991
|
+
shape = "flat";
|
|
1992
|
+
rawKfs = flatKeyframes(anim).map((k) => ({ percentage: k.pct, properties: k.properties }));
|
|
1993
|
+
}
|
|
1994
|
+
const keyframes = rawKfs.map((kf) => ({
|
|
1995
|
+
pct: kf.percentage,
|
|
1996
|
+
time: Math.round((start + kf.percentage / 100 * duration) * 1e3) / 1e3,
|
|
1997
|
+
properties: cleanProps(kf.properties)
|
|
1998
|
+
}));
|
|
1999
|
+
return {
|
|
2000
|
+
id: anim.id,
|
|
2001
|
+
target: anim.targetSelector,
|
|
2002
|
+
method: anim.method,
|
|
2003
|
+
group: anim.propertyGroup,
|
|
2004
|
+
start: Math.round(start * 1e3) / 1e3,
|
|
2005
|
+
duration,
|
|
2006
|
+
end: Math.round((start + duration) * 1e3) / 1e3,
|
|
2007
|
+
shape,
|
|
2008
|
+
keyframes,
|
|
2009
|
+
path: isPositionTween(anim) ? positionPath(keyframes) : null
|
|
2010
|
+
};
|
|
2011
|
+
}
|
|
2012
|
+
function positionPath(keyframes) {
|
|
2013
|
+
if (keyframes.length === 0) return null;
|
|
2014
|
+
let lastX = 0;
|
|
2015
|
+
let lastY = 0;
|
|
2016
|
+
return keyframes.map((kf) => {
|
|
2017
|
+
const x = num(kf.properties.x);
|
|
2018
|
+
const y = num(kf.properties.y);
|
|
2019
|
+
if (x !== null) lastX = x;
|
|
2020
|
+
if (y !== null) lastY = y;
|
|
2021
|
+
return { x: lastX, y: lastY };
|
|
2022
|
+
});
|
|
2023
|
+
}
|
|
2024
|
+
function surfaceComposition(html, label, source) {
|
|
2025
|
+
const script = inlineScriptText(html);
|
|
2026
|
+
let animations = [];
|
|
2027
|
+
try {
|
|
2028
|
+
animations = parseGsapScriptAcorn(script).animations;
|
|
2029
|
+
} catch {
|
|
2030
|
+
animations = [];
|
|
2031
|
+
}
|
|
2032
|
+
const tweens = animations.filter((a) => !isHoldMarker(a)).map(surfaceTween);
|
|
2033
|
+
attachComposedAncestors(tweens, html);
|
|
2034
|
+
return {
|
|
2035
|
+
composition: label,
|
|
2036
|
+
source,
|
|
2037
|
+
tweens,
|
|
2038
|
+
traces: groupTraces(tweens),
|
|
2039
|
+
cssKeyframes: surfaceCssKeyframes(inlineStyleText(html)),
|
|
2040
|
+
anime: surfaceAnime(inlineScriptText(html))
|
|
2041
|
+
};
|
|
2042
|
+
}
|
|
2043
|
+
function readBalancedBlock(text, openBrace) {
|
|
2044
|
+
if (text[openBrace] !== "{") return null;
|
|
2045
|
+
let depth = 0;
|
|
2046
|
+
for (let i = openBrace; i < text.length; i++) {
|
|
2047
|
+
const ch = text[i];
|
|
2048
|
+
if (ch === "{") depth++;
|
|
2049
|
+
else if (ch === "}") {
|
|
2050
|
+
depth--;
|
|
2051
|
+
if (depth === 0) {
|
|
2052
|
+
return { body: text.slice(openBrace + 1, i), end: i + 1 };
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
}
|
|
2056
|
+
return null;
|
|
2057
|
+
}
|
|
2058
|
+
function parseDeclarations(body) {
|
|
2059
|
+
return body.split(";").map((part) => part.trim()).filter(Boolean);
|
|
2060
|
+
}
|
|
2061
|
+
function stripRanges(text, ranges) {
|
|
2062
|
+
let out = "";
|
|
2063
|
+
let cursor = 0;
|
|
2064
|
+
for (const range of [...ranges].sort((a, b) => a.start - b.start)) {
|
|
2065
|
+
out += text.slice(cursor, range.start);
|
|
2066
|
+
cursor = range.end;
|
|
2067
|
+
}
|
|
2068
|
+
return out + text.slice(cursor);
|
|
2069
|
+
}
|
|
2070
|
+
function collectKeyframeBlocks(css) {
|
|
2071
|
+
const keyframes = [];
|
|
2072
|
+
const ranges = [];
|
|
2073
|
+
const re = /@keyframes\s+([a-zA-Z0-9_-]+)/g;
|
|
2074
|
+
let match;
|
|
2075
|
+
while (match = re.exec(css)) {
|
|
2076
|
+
const open = css.indexOf("{", re.lastIndex);
|
|
2077
|
+
const block = open >= 0 ? readBalancedBlock(css, open) : null;
|
|
2078
|
+
if (!block) continue;
|
|
2079
|
+
ranges.push({ start: match.index, end: block.end });
|
|
2080
|
+
const stops = [];
|
|
2081
|
+
const stopRe = /([^{}]+)\{([^{}]*)\}/g;
|
|
2082
|
+
let stop;
|
|
2083
|
+
while (stop = stopRe.exec(block.body)) {
|
|
2084
|
+
stops.push({
|
|
2085
|
+
selector: stop[1].trim().replace(/\s+/g, " "),
|
|
2086
|
+
declarations: parseDeclarations(stop[2])
|
|
2087
|
+
});
|
|
2088
|
+
}
|
|
2089
|
+
keyframes.push({ name: match[1], stops });
|
|
2090
|
+
}
|
|
2091
|
+
return { keyframes, ranges };
|
|
2092
|
+
}
|
|
2093
|
+
function stripQuotes(raw) {
|
|
2094
|
+
return raw.trim().replace(/^["']|["']$/g, "");
|
|
2095
|
+
}
|
|
2096
|
+
function addAnimationNameDeclNames(body, knownNames, out) {
|
|
2097
|
+
const nameRe = /animation-name\s*:\s*([^;]+)/g;
|
|
2098
|
+
let nameMatch;
|
|
2099
|
+
while (nameMatch = nameRe.exec(body)) {
|
|
2100
|
+
for (const raw of nameMatch[1].split(",")) {
|
|
2101
|
+
const name = stripQuotes(raw);
|
|
2102
|
+
if (knownNames.has(name)) out.add(name);
|
|
2103
|
+
}
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
function addAnimationShorthandNames(body, knownNames, out) {
|
|
2107
|
+
const animationRe = /animation\s*:\s*([^;]+)/g;
|
|
2108
|
+
let animationMatch;
|
|
2109
|
+
while (animationMatch = animationRe.exec(body)) {
|
|
2110
|
+
for (const raw of animationMatch[1].split(",")) {
|
|
2111
|
+
for (const token of raw.trim().split(/\s+/)) {
|
|
2112
|
+
const normalized = stripQuotes(token);
|
|
2113
|
+
if (knownNames.has(normalized)) out.add(normalized);
|
|
2114
|
+
}
|
|
2115
|
+
}
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
function animationNamesFromDeclarations(body, knownNames) {
|
|
2119
|
+
const out = /* @__PURE__ */ new Set();
|
|
2120
|
+
addAnimationNameDeclNames(body, knownNames, out);
|
|
2121
|
+
addAnimationShorthandNames(body, knownNames, out);
|
|
2122
|
+
return [...out];
|
|
2123
|
+
}
|
|
2124
|
+
function stripCssComments(css) {
|
|
2125
|
+
return css.replace(/\/\*[\s\S]*?\*\//g, " ");
|
|
2126
|
+
}
|
|
2127
|
+
function surfaceCssKeyframes(rawCss) {
|
|
2128
|
+
const css = stripCssComments(rawCss);
|
|
2129
|
+
if (!css.trim()) return [];
|
|
2130
|
+
const { keyframes, ranges } = collectKeyframeBlocks(css);
|
|
2131
|
+
if (keyframes.length === 0) return [];
|
|
2132
|
+
const selectorsByName = /* @__PURE__ */ new Map();
|
|
2133
|
+
for (const kf of keyframes) selectorsByName.set(kf.name, /* @__PURE__ */ new Set());
|
|
2134
|
+
const knownNames = new Set(keyframes.map((kf) => kf.name));
|
|
2135
|
+
const cssWithoutKeyframes = stripRanges(css, ranges);
|
|
2136
|
+
const ruleRe = /([^{}@]+)\{([^{}]*animation[^{}]*)\}/g;
|
|
2137
|
+
let rule;
|
|
2138
|
+
while (rule = ruleRe.exec(cssWithoutKeyframes)) {
|
|
2139
|
+
const selector = rule[1].trim().replace(/\s+/g, " ");
|
|
2140
|
+
if (!selector) continue;
|
|
2141
|
+
for (const name of animationNamesFromDeclarations(rule[2], knownNames)) {
|
|
2142
|
+
selectorsByName.get(name)?.add(selector);
|
|
2143
|
+
}
|
|
2144
|
+
}
|
|
2145
|
+
return keyframes.map((kf) => ({
|
|
2146
|
+
name: kf.name,
|
|
2147
|
+
selectors: [...selectorsByName.get(kf.name) ?? /* @__PURE__ */ new Set()],
|
|
2148
|
+
keyframes: kf.stops
|
|
2149
|
+
}));
|
|
2150
|
+
}
|
|
2151
|
+
function valuesFromProperty(script, property) {
|
|
2152
|
+
const values = [];
|
|
2153
|
+
const quoted = property + "\\s*:\\s*([\"'`])([^\"'`]+)\\1";
|
|
2154
|
+
const numeric = property + "\\s*:\\s*([0-9]+(?:\\.[0-9]+)?)";
|
|
2155
|
+
const re = new RegExp(`${quoted}|${numeric}`, "g");
|
|
2156
|
+
let match;
|
|
2157
|
+
while (match = re.exec(script)) {
|
|
2158
|
+
if (match[2] !== void 0) values.push(match[2]);
|
|
2159
|
+
else if (match[3] !== void 0) values.push(Number(match[3]));
|
|
2160
|
+
}
|
|
2161
|
+
return values;
|
|
2162
|
+
}
|
|
2163
|
+
function animeAddTargets(script) {
|
|
2164
|
+
const values = [];
|
|
2165
|
+
const re = /\.add\s*\(\s*(["'`])([^"'`]+)\1/g;
|
|
2166
|
+
let match;
|
|
2167
|
+
while (match = re.exec(script)) values.push(match[2]);
|
|
2168
|
+
return values;
|
|
2169
|
+
}
|
|
2170
|
+
function surfaceAnime(script) {
|
|
2171
|
+
if (!/\banime\s*(?:\.(?:timeline|createTimeline))?\s*\(/.test(script)) return [];
|
|
2172
|
+
const registered = /__hfAnime[\s\S]*?\.push\s*\(/.test(script) || /__hfAnime\s*=/.test(script);
|
|
2173
|
+
const timelineCount = (script.match(/\banime\.(?:timeline|createTimeline)\s*\(/g) ?? []).length;
|
|
2174
|
+
const animationCount = (script.match(/\banime\s*\(/g) ?? []).length;
|
|
2175
|
+
const targets = [
|
|
2176
|
+
...valuesFromProperty(script, "targets").filter(
|
|
2177
|
+
(value) => typeof value === "string"
|
|
2178
|
+
),
|
|
2179
|
+
...animeAddTargets(script)
|
|
2180
|
+
];
|
|
2181
|
+
const durations = valuesFromProperty(script, "duration");
|
|
2182
|
+
const out = [];
|
|
2183
|
+
for (let i = 0; i < timelineCount; i++) {
|
|
2184
|
+
out.push({ kind: "timeline", targets, durations, registered });
|
|
2185
|
+
}
|
|
2186
|
+
for (let i = 0; i < animationCount; i++) {
|
|
2187
|
+
out.push({ kind: "animation", targets, durations, registered });
|
|
2188
|
+
}
|
|
2189
|
+
return out;
|
|
2190
|
+
}
|
|
2191
|
+
function attachComposedAncestors(tweens, html) {
|
|
2192
|
+
const animated = [...new Set(tweens.filter((t) => t.method !== "set").map((t) => t.target))];
|
|
2193
|
+
if (animated.length < 2) return;
|
|
2194
|
+
const doc = new DOMParser().parseFromString(html, "text/html");
|
|
2195
|
+
for (const t of tweens) {
|
|
2196
|
+
const ancestors = animatedAncestors(doc, t.target, animated);
|
|
2197
|
+
if (ancestors.length) {
|
|
2198
|
+
t.composedWith = ancestors.map((sel) => ({
|
|
2199
|
+
selector: sel,
|
|
2200
|
+
summary: summarizeMotion(tweens, sel)
|
|
2201
|
+
}));
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
var safeMatches = (el, sel) => {
|
|
2206
|
+
try {
|
|
2207
|
+
return el.matches(sel);
|
|
2208
|
+
} catch {
|
|
2209
|
+
return false;
|
|
2210
|
+
}
|
|
2211
|
+
};
|
|
2212
|
+
function animatedAncestors(doc, target, animated) {
|
|
2213
|
+
let el = null;
|
|
2214
|
+
try {
|
|
2215
|
+
el = doc.querySelector(target);
|
|
2216
|
+
} catch {
|
|
2217
|
+
return [];
|
|
2218
|
+
}
|
|
2219
|
+
const out = [];
|
|
2220
|
+
for (let n = el?.parentElement ?? null; n; n = n.parentElement) {
|
|
2221
|
+
for (const sel of animated) {
|
|
2222
|
+
if (sel !== target && !out.includes(sel) && safeMatches(n, sel)) out.push(sel);
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2225
|
+
return out;
|
|
2226
|
+
}
|
|
2227
|
+
function summarizeMotion(tweens, sel) {
|
|
2228
|
+
const ranges = /* @__PURE__ */ new Map();
|
|
2229
|
+
const kfs = tweens.filter((t) => t.target === sel && t.method !== "set").flatMap((t) => t.keyframes);
|
|
2230
|
+
for (const kf of kfs) {
|
|
2231
|
+
for (const [k, v] of Object.entries(kf.properties)) {
|
|
2232
|
+
const n = num(v);
|
|
2233
|
+
if (n !== null) bumpRange(ranges, k, n);
|
|
2234
|
+
}
|
|
2235
|
+
}
|
|
2236
|
+
const varying = [...ranges.entries()].filter(([, r]) => r.max - r.min > 0.5).map(([k, r]) => `${k} ${Math.round(r.min)}..${Math.round(r.max)}`);
|
|
2237
|
+
return varying.length ? varying.join(", ") : "(static)";
|
|
2238
|
+
}
|
|
2239
|
+
function bumpRange(ranges, k, n) {
|
|
2240
|
+
const r = ranges.get(k);
|
|
2241
|
+
if (r) {
|
|
2242
|
+
r.min = Math.min(r.min, n);
|
|
2243
|
+
r.max = Math.max(r.max, n);
|
|
2244
|
+
} else ranges.set(k, { min: n, max: n });
|
|
2245
|
+
}
|
|
2246
|
+
function pathTravels(points) {
|
|
2247
|
+
const first = points[0];
|
|
2248
|
+
if (!first) return false;
|
|
2249
|
+
return points.some((p) => Math.abs(p.x - first.x) > 0.5 || Math.abs(p.y - first.y) > 0.5);
|
|
2250
|
+
}
|
|
2251
|
+
function groupTraces(tweens) {
|
|
2252
|
+
const byTarget = /* @__PURE__ */ new Map();
|
|
2253
|
+
for (const t of tweens) {
|
|
2254
|
+
if (t.method === "set") continue;
|
|
2255
|
+
if (!t.path || t.path.length < 2) continue;
|
|
2256
|
+
if (!pathTravels(t.path)) continue;
|
|
2257
|
+
const list = byTarget.get(t.target);
|
|
2258
|
+
if (list) list.push(t);
|
|
2259
|
+
else byTarget.set(t.target, [t]);
|
|
2260
|
+
}
|
|
2261
|
+
const traces = [];
|
|
2262
|
+
for (const [target, list] of byTarget) {
|
|
2263
|
+
if (list.length < 2) continue;
|
|
2264
|
+
const strokes = [...list].sort((a, b) => a.start - b.start).map((t) => ({
|
|
2265
|
+
id: t.id,
|
|
2266
|
+
start: t.start,
|
|
2267
|
+
end: t.end,
|
|
2268
|
+
keyframes: t.keyframes,
|
|
2269
|
+
points: t.path
|
|
2270
|
+
}));
|
|
2271
|
+
traces.push({ target, strokes });
|
|
2272
|
+
}
|
|
2273
|
+
return traces;
|
|
2274
|
+
}
|
|
2275
|
+
function collectCompositions(indexPath) {
|
|
2276
|
+
const html = readFileSync(indexPath, "utf-8");
|
|
2277
|
+
const baseDir = dirname(indexPath);
|
|
2278
|
+
const out = [
|
|
2279
|
+
surfaceComposition(html, basename(indexPath), basename(indexPath))
|
|
2280
|
+
];
|
|
2281
|
+
const doc = new DOMParser().parseFromString(html, "text/html");
|
|
2282
|
+
for (const div of Array.from(doc.querySelectorAll("[data-composition-src]"))) {
|
|
2283
|
+
const src = div.getAttribute("data-composition-src");
|
|
2284
|
+
if (!src) continue;
|
|
2285
|
+
const subPath = resolve(baseDir, src);
|
|
2286
|
+
const sub = readProjectFile(subPath);
|
|
2287
|
+
if (sub.kind !== "file") continue;
|
|
2288
|
+
const id = div.getAttribute("data-composition-id") ?? src;
|
|
2289
|
+
out.push(surfaceComposition(sub.text, id, src));
|
|
2290
|
+
}
|
|
2291
|
+
return out;
|
|
2292
|
+
}
|
|
2293
|
+
function fmtProps(props) {
|
|
2294
|
+
return Object.entries(props).filter(([k]) => k !== "ease").map(([k, v]) => `${k}:${v}`).join(" ");
|
|
2295
|
+
}
|
|
2296
|
+
function printTween(t) {
|
|
2297
|
+
const timing = c.dim(`@${t.start}s\u2192${t.end}s (${t.duration}s)`);
|
|
2298
|
+
const group = t.group ? c.dim(` ${t.group}`) : "";
|
|
2299
|
+
console.log(` ${c.accent(t.target)}${group} ${c.dim(t.method)}/${t.shape} ${timing}`);
|
|
2300
|
+
if (t.shape === "motionPath") {
|
|
2301
|
+
console.log(c.dim(` motionPath arc (${t.keyframes.length} stops)`));
|
|
2302
|
+
} else {
|
|
2303
|
+
const kfLine = t.keyframes.map((k) => `${k.pct}% {${fmtProps(k.properties)}}`).join(" ");
|
|
2304
|
+
console.log(` ${c.dim(kfLine)}`);
|
|
2305
|
+
}
|
|
2306
|
+
if (t.composedWith?.length) {
|
|
2307
|
+
for (const a of t.composedWith) {
|
|
2308
|
+
console.log(c.dim(` \u2191 composed with ${c.accent(a.selector)}${c.dim(": " + a.summary)}`));
|
|
2309
|
+
}
|
|
2310
|
+
}
|
|
2311
|
+
console.log();
|
|
2312
|
+
}
|
|
2313
|
+
function printTrace(tr) {
|
|
2314
|
+
const start = Math.min(...tr.strokes.map((s) => s.start));
|
|
2315
|
+
const end = Math.max(...tr.strokes.map((s) => s.end));
|
|
2316
|
+
const n = tr.strokes.length;
|
|
2317
|
+
console.log(
|
|
2318
|
+
` ${c.accent(tr.target)}${c.dim(" position")} ${c.dim("trace")} ${c.dim(`${n} strokes`)} ${c.dim(`@${start}s\u2192${end}s`)}`
|
|
2319
|
+
);
|
|
2320
|
+
tr.strokes.forEach((s, i) => {
|
|
2321
|
+
const kfLine = s.keyframes.map((k) => `${k.pct}% {${fmtProps(k.properties)}}`).join(" ");
|
|
2322
|
+
console.log(` ${c.dim(`stroke ${i + 1}:`)} ${c.dim(kfLine)}`);
|
|
2323
|
+
});
|
|
2324
|
+
console.log();
|
|
2325
|
+
}
|
|
2326
|
+
function addTraceSelectors(selectors, cmp) {
|
|
2327
|
+
for (const tr of cmp.traces) selectors.add(tr.target);
|
|
2328
|
+
}
|
|
2329
|
+
function addTweenSelectors(selectors, cmp) {
|
|
2330
|
+
for (const t of cmp.tweens) {
|
|
2331
|
+
if (t.method !== "set" && t.target !== "__unresolved__") selectors.add(t.target);
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2334
|
+
function addCssKeyframeSelectors(selectors, cmp) {
|
|
2335
|
+
for (const css of cmp.cssKeyframes) {
|
|
2336
|
+
for (const selector of css.selectors) {
|
|
2337
|
+
if (selector) selectors.add(selector);
|
|
2338
|
+
}
|
|
2339
|
+
}
|
|
2340
|
+
}
|
|
2341
|
+
function addAnimeSelectors(selectors, cmp) {
|
|
2342
|
+
for (const anime of cmp.anime) {
|
|
2343
|
+
for (const selector of anime.targets) {
|
|
2344
|
+
if (selector) selectors.add(selector);
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2348
|
+
function collectShotSelectors(comps) {
|
|
2349
|
+
const selectors = /* @__PURE__ */ new Set();
|
|
2350
|
+
for (const cmp of comps) {
|
|
2351
|
+
addTraceSelectors(selectors, cmp);
|
|
2352
|
+
addTweenSelectors(selectors, cmp);
|
|
2353
|
+
addCssKeyframeSelectors(selectors, cmp);
|
|
2354
|
+
addAnimeSelectors(selectors, cmp);
|
|
2355
|
+
}
|
|
2356
|
+
return [...selectors].map((selector) => ({ selector }));
|
|
2357
|
+
}
|
|
2358
|
+
function onionShotGuardError(projectDir, requests, ghost) {
|
|
2359
|
+
if (!projectDir) return "--shot needs a project directory (not a single .html file).";
|
|
2360
|
+
if (requests.length === 0 && !ghost)
|
|
2361
|
+
return "--shot: no statically resolved animated element to sample for the selection. Use a direct DOM selector or --ghost for runtime-only targets.";
|
|
2362
|
+
return null;
|
|
2363
|
+
}
|
|
2364
|
+
function onionShotOptions(args) {
|
|
2365
|
+
return {
|
|
2366
|
+
samples: num(args.samples) ?? 9,
|
|
2367
|
+
layout: args.layout === "strip" ? "strip" : "path",
|
|
2368
|
+
fit: args.fit ?? true,
|
|
2369
|
+
from: num(args.from),
|
|
2370
|
+
to: num(args.to),
|
|
2371
|
+
angle: args.angle,
|
|
2372
|
+
scopeSelector: args.selector ?? null,
|
|
2373
|
+
ghost: args.ghost ?? false
|
|
2374
|
+
};
|
|
2375
|
+
}
|
|
2376
|
+
function printOnionShotSaved(saved, elementCount) {
|
|
2377
|
+
console.log(`${c.success("\u25C7")} onion-skin screenshot saved ${c.accent(saved)}`);
|
|
2378
|
+
console.log(
|
|
2379
|
+
c.dim(
|
|
2380
|
+
` ${elementCount} element${elementCount === 1 ? "" : "s"} \xB7 open it to verify the motion matches your target, then read the keyframes below.`
|
|
2381
|
+
)
|
|
2382
|
+
);
|
|
2383
|
+
console.log();
|
|
2384
|
+
}
|
|
2385
|
+
async function runOnionShot(comps, allComps, projectDir, entryFile, args) {
|
|
2386
|
+
const { captureMotionPathShot } = await import("./motionShot-S4MIGMT5.js");
|
|
2387
|
+
const requests = collectShotSelectors(args.selector ? allComps : comps);
|
|
2388
|
+
const guardError = onionShotGuardError(projectDir, requests, args.ghost ?? false);
|
|
2389
|
+
if (guardError) {
|
|
2390
|
+
console.log(c.dim(guardError));
|
|
2391
|
+
return true;
|
|
2392
|
+
}
|
|
2393
|
+
const saved = await captureMotionPathShot(projectDir, requests, resolve(args.shot), {
|
|
2394
|
+
...onionShotOptions(args),
|
|
2395
|
+
entryFile
|
|
2396
|
+
});
|
|
2397
|
+
printOnionShotSaved(saved, requests.length);
|
|
2398
|
+
return false;
|
|
2399
|
+
}
|
|
2400
|
+
function resolveScope(args) {
|
|
2401
|
+
const raw = args.target?.trim();
|
|
2402
|
+
let comps;
|
|
2403
|
+
let projectName;
|
|
2404
|
+
let projectDir;
|
|
2405
|
+
let entryFile;
|
|
2406
|
+
const entry = raw?.endsWith(".html") ? readProjectFile(raw) : void 0;
|
|
2407
|
+
if (raw && entry?.kind === "file") {
|
|
2408
|
+
const entryPath = resolve(raw);
|
|
2409
|
+
comps = [surfaceComposition(entry.text, basename(entryPath), entryPath)];
|
|
2410
|
+
projectName = basename(entryPath);
|
|
2411
|
+
projectDir = findProjectRoot(entryPath);
|
|
2412
|
+
entryFile = relative(projectDir, entryPath).split(sep).join("/");
|
|
2413
|
+
} else {
|
|
2414
|
+
const project = resolveProject(raw);
|
|
2415
|
+
comps = collectCompositions(project.indexPath);
|
|
2416
|
+
projectName = project.name;
|
|
2417
|
+
projectDir = project.dir;
|
|
2418
|
+
}
|
|
2419
|
+
const allComps = comps;
|
|
2420
|
+
if (args.selector) {
|
|
2421
|
+
const sel = args.selector;
|
|
2422
|
+
const matches = (target) => target.split(",").some((s) => s.trim() === sel);
|
|
2423
|
+
comps = comps.map((cmp) => ({
|
|
2424
|
+
...cmp,
|
|
2425
|
+
tweens: cmp.tweens.filter((t) => matches(t.target)),
|
|
2426
|
+
traces: cmp.traces.filter((tr) => matches(tr.target)),
|
|
2427
|
+
cssKeyframes: cmp.cssKeyframes.filter((kf) => kf.selectors.some(matches)),
|
|
2428
|
+
anime: cmp.anime.filter((a) => a.targets.some(matches))
|
|
2429
|
+
})).filter(
|
|
2430
|
+
(cmp) => cmp.tweens.length > 0 || cmp.traces.length > 0 || cmp.cssKeyframes.length > 0 || cmp.anime.length > 0
|
|
2431
|
+
);
|
|
2432
|
+
}
|
|
2433
|
+
return { comps, allComps, projectName, projectDir, entryFile };
|
|
2434
|
+
}
|
|
2435
|
+
function findProjectRoot(entryPath) {
|
|
2436
|
+
const entryDir = dirname(entryPath);
|
|
2437
|
+
let candidate = entryDir;
|
|
2438
|
+
for (; ; ) {
|
|
2439
|
+
if (existsSync(join(candidate, "index.html"))) return candidate;
|
|
2440
|
+
if (existsSync(join(candidate, ".git"))) return entryDir;
|
|
2441
|
+
const parent = dirname(candidate);
|
|
2442
|
+
if (parent === candidate) return entryDir;
|
|
2443
|
+
candidate = parent;
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
function isEmptyComposition(cmp) {
|
|
2447
|
+
return cmp.tweens.length === 0 && cmp.traces.length === 0 && cmp.cssKeyframes.length === 0 && cmp.anime.length === 0;
|
|
2448
|
+
}
|
|
2449
|
+
function printCompositionTweens(cmp) {
|
|
2450
|
+
const tracedIds = new Set(cmp.traces.flatMap((tr) => tr.strokes.map((s) => s.id)));
|
|
2451
|
+
const tracedTargets = new Set(cmp.traces.map((tr) => tr.target));
|
|
2452
|
+
for (const t of cmp.tweens) {
|
|
2453
|
+
if (tracedIds.has(t.id)) continue;
|
|
2454
|
+
if (t.method === "set" && tracedTargets.has(t.target)) continue;
|
|
2455
|
+
printTween(t);
|
|
2456
|
+
}
|
|
2457
|
+
}
|
|
2458
|
+
function printComposition(cmp) {
|
|
2459
|
+
if (isEmptyComposition(cmp)) return;
|
|
2460
|
+
console.log(c.bold(`${cmp.composition}`) + c.dim(` (${cmp.source})`));
|
|
2461
|
+
for (const tr of cmp.traces) printTrace(tr);
|
|
2462
|
+
printCompositionTweens(cmp);
|
|
2463
|
+
for (const cssKeyframes of cmp.cssKeyframes) printCssKeyframes(cssKeyframes);
|
|
2464
|
+
for (const anime of cmp.anime) printAnime(anime);
|
|
2465
|
+
}
|
|
2466
|
+
function printCssKeyframes(cssKeyframes) {
|
|
2467
|
+
const selectors = cssKeyframes.selectors.length ? cssKeyframes.selectors.join(", ") : "(no selector found)";
|
|
2468
|
+
console.log(
|
|
2469
|
+
` ${c.accent(`@keyframes ${cssKeyframes.name}`)}${c.dim(" css")} ${c.dim(selectors)}`
|
|
2470
|
+
);
|
|
2471
|
+
for (const stop of cssKeyframes.keyframes) {
|
|
2472
|
+
console.log(` ${c.dim(`${stop.selector} {${stop.declarations.join("; ")}}`)}`);
|
|
2473
|
+
}
|
|
2474
|
+
console.log();
|
|
2475
|
+
}
|
|
2476
|
+
function printAnime(anime) {
|
|
2477
|
+
const targets = anime.targets.length ? anime.targets.join(", ") : "(targets not parsed)";
|
|
2478
|
+
const durations = anime.durations.length ? ` duration ${anime.durations.join(",")}` : "";
|
|
2479
|
+
const registered = anime.registered ? "registered" : "not registered";
|
|
2480
|
+
console.log(
|
|
2481
|
+
` ${c.accent(`anime.${anime.kind}`)}${c.dim(` ${registered}`)} ${c.dim(`${targets}${durations}`)}`
|
|
2482
|
+
);
|
|
2483
|
+
console.log();
|
|
2484
|
+
}
|
|
2485
|
+
var defaultKeyframesCommand = {
|
|
2486
|
+
name: "keyframes",
|
|
2487
|
+
description: "See, debug, and refine keyframes \u2014 surface GSAP, CSS @keyframes, Anime.js, paths, and onion-shot diagnostics",
|
|
2488
|
+
invocation: "hyperframes keyframes",
|
|
2489
|
+
defaultRuntime: "all"
|
|
2490
|
+
};
|
|
2491
|
+
function createKeyframesCommand(options = {}) {
|
|
2492
|
+
const commandOptions = { ...defaultKeyframesCommand, ...options };
|
|
2493
|
+
return defineCommand({
|
|
2494
|
+
meta: {
|
|
2495
|
+
name: commandOptions.name,
|
|
2496
|
+
description: commandOptions.description
|
|
2497
|
+
},
|
|
2498
|
+
args: {
|
|
2499
|
+
target: {
|
|
2500
|
+
type: "positional",
|
|
2501
|
+
description: "Project dir or composition .html",
|
|
2502
|
+
required: false
|
|
2503
|
+
},
|
|
2504
|
+
selector: { type: "string", description: "Only keyframes matching this CSS selector" },
|
|
2505
|
+
runtime: {
|
|
2506
|
+
type: "string",
|
|
2507
|
+
description: "Runtime filter hint: gsap|css|anime|all. Surfaces GSAP tweens, CSS @keyframes, and Anime.js timelines when detectable."
|
|
2508
|
+
},
|
|
2509
|
+
json: { type: "boolean", description: "Machine-readable JSON (for agents)", default: false },
|
|
2510
|
+
shot: {
|
|
2511
|
+
type: "string",
|
|
2512
|
+
description: "Onion-skin screenshot to PNG: the real element sampled over the timeline (true 3D, every channel) for visual self-verify. Pair with --selector to focus one element."
|
|
2513
|
+
},
|
|
2514
|
+
samples: {
|
|
2515
|
+
type: "string",
|
|
2516
|
+
description: "Onion samples (equal-time steps) for --shot. Default 9."
|
|
2517
|
+
},
|
|
2518
|
+
layout: {
|
|
2519
|
+
type: "string",
|
|
2520
|
+
description: "--shot layout: 'path' (ghosts at real positions + path, default) or 'strip' (for in-place/overlapping motion). 'strip' captures a real per-time pixel filmstrip only when --selector targets an SVG element; any other selector (e.g. a DOM/sub-composition host) instead gets one live frame plus vector position markers."
|
|
2521
|
+
},
|
|
2522
|
+
from: { type: "string", description: "--shot: sample only from this time (seconds)." },
|
|
2523
|
+
to: { type: "string", description: "--shot: sample only up to this time (seconds)." },
|
|
2524
|
+
angle: {
|
|
2525
|
+
type: "string",
|
|
2526
|
+
description: "--shot orbit camera: a preset (front|iso|top|side|rear-iso) or 'yaw,pitch' degrees \u2014 view 3D motion from the angle that reveals it."
|
|
2527
|
+
},
|
|
2528
|
+
fit: {
|
|
2529
|
+
type: "boolean",
|
|
2530
|
+
description: "--shot: zoom the motion to fill the frame (default true; --no-fit to disable).",
|
|
2531
|
+
default: true
|
|
2532
|
+
},
|
|
2533
|
+
ghost: {
|
|
2534
|
+
type: "boolean",
|
|
2535
|
+
description: "--shot: rendered onion-skin \u2014 composite the real canvas/WebGL frames as translucent ghosts (older fainter), instead of bbox markers. For the canvas-internal 3D motion the marker onion can't see (requires a <canvas>).",
|
|
2536
|
+
default: false
|
|
2537
|
+
}
|
|
2538
|
+
},
|
|
2539
|
+
async run({ args }) {
|
|
2540
|
+
ensureDOMParser();
|
|
2541
|
+
const runtime = normalizeRuntime(args.runtime, commandOptions.defaultRuntime);
|
|
2542
|
+
if (runtime === "css" || runtime === "anime") {
|
|
2543
|
+
console.log(
|
|
2544
|
+
c.dim(
|
|
2545
|
+
`${commandOptions.name}: ${runtime} output is a static authoring surface; use validate/render/snapshot to verify runtime adapter seekability.`
|
|
2546
|
+
)
|
|
2547
|
+
);
|
|
2548
|
+
console.log();
|
|
2549
|
+
}
|
|
2550
|
+
const { comps: rawComps, allComps, projectName, projectDir, entryFile } = resolveScope(args);
|
|
2551
|
+
const comps = filterCompositionsByRuntime(rawComps, runtime);
|
|
2552
|
+
if (args.shot && await runOnionShot(comps, allComps, projectDir, entryFile, args)) return;
|
|
2553
|
+
if (args.json) {
|
|
2554
|
+
console.log(
|
|
2555
|
+
JSON.stringify(withMeta({ project: projectName, runtime, compositions: comps }), null, 2)
|
|
2556
|
+
);
|
|
2557
|
+
return;
|
|
2558
|
+
}
|
|
2559
|
+
const total = comps.reduce(
|
|
2560
|
+
(n, cmp) => n + cmp.tweens.length + cmp.cssKeyframes.length + cmp.anime.length,
|
|
2561
|
+
0
|
|
2562
|
+
);
|
|
2563
|
+
if (total === 0) {
|
|
2564
|
+
console.log(`${c.success("\u25C7")} ${c.accent(projectName)} ${c.dim("\u2014 no keyframes found")}`);
|
|
2565
|
+
return;
|
|
2566
|
+
}
|
|
2567
|
+
console.log(
|
|
2568
|
+
`${c.success("\u25C7")} ${c.accent(projectName)} ${c.dim("\u2014")} ${c.dim(`${total} item${total === 1 ? "" : "s"}`)}`
|
|
2569
|
+
);
|
|
2570
|
+
console.log();
|
|
2571
|
+
for (const cmp of comps) printComposition(cmp);
|
|
2572
|
+
console.log(
|
|
2573
|
+
c.dim(
|
|
2574
|
+
`Tip: edit the keyframes in source, then \`${commandOptions.invocation} --shot out.png\` to see the rendered motion.`
|
|
2575
|
+
)
|
|
2576
|
+
);
|
|
2577
|
+
}
|
|
2578
|
+
});
|
|
2579
|
+
}
|
|
2580
|
+
function normalizeRuntime(runtime, fallback) {
|
|
2581
|
+
if (typeof runtime !== "string") return fallback;
|
|
2582
|
+
const normalized = runtime.toLowerCase();
|
|
2583
|
+
return normalized === "gsap" || normalized === "css" || normalized === "anime" || normalized === "all" ? normalized : fallback;
|
|
2584
|
+
}
|
|
2585
|
+
function filterCompositionsByRuntime(comps, runtime) {
|
|
2586
|
+
return comps.map((cmp) => ({
|
|
2587
|
+
...cmp,
|
|
2588
|
+
tweens: runtime === "gsap" || runtime === "all" ? cmp.tweens : [],
|
|
2589
|
+
traces: runtime === "gsap" || runtime === "all" ? cmp.traces : [],
|
|
2590
|
+
cssKeyframes: runtime === "css" || runtime === "all" ? cmp.cssKeyframes : [],
|
|
2591
|
+
anime: runtime === "anime" || runtime === "all" ? cmp.anime : []
|
|
2592
|
+
}));
|
|
2593
|
+
}
|
|
2594
|
+
var keyframes_default = createKeyframesCommand();
|
|
2595
|
+
export {
|
|
2596
|
+
collectCompositions,
|
|
2597
|
+
collectShotSelectors,
|
|
2598
|
+
keyframes_default as default,
|
|
2599
|
+
examples,
|
|
2600
|
+
resolveScope,
|
|
2601
|
+
surfaceComposition
|
|
2602
|
+
};
|