hyperframes 0.8.184 → 0.8.185
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/dist/{add-5ZTD3MUZ.js → add-ODTNPRGG.js} +14 -14
- package/dist/{agentPromptGenerator-VIIPZCJ3.js → agentPromptGenerator-KYO5MKTW.js} +1 -1
- package/dist/{animatedGifPrep-AGASIWVA.js → animatedGifPrep-PEP5GWOJ.js} +9 -9
- package/dist/api.js +17 -17
- package/dist/{asset-LSTEMPIB.js → asset-EZG42XPA.js} +2 -2
- package/dist/{assetCataloger-BKBMNL3A.js → assetCataloger-OHAJFCA7.js} +9 -9
- package/dist/{audio-KGK44XE4.js → audio-65R4T74I.js} +16 -15
- package/dist/{auth-MJWKYK77.js → auth-VP2SIZFN.js} +1 -1
- package/dist/{autoUpdate-2GGDKYR2.js → autoUpdate-RVSUX4SS.js} +2 -2
- package/dist/{backgroundChecks-7GRX5VQY.js → backgroundChecks-LEHK74NS.js} +3 -3
- package/dist/backgroundChecksWorker.js +3 -3
- package/dist/{batchRender-BCV2LELR.js → batchRender-3X6CL7PK.js} +5 -5
- package/dist/{beats-7BCFRBAL.js → beats-66VPQLSC.js} +6 -6
- package/dist/{benchmark-2R6CN5MQ.js → benchmark-PBJVTOJP.js} +10 -10
- package/dist/{browser-6AFGOI7G.js → browser-TPL5MWGC.js} +3 -3
- package/dist/{bundleWithLocalizedFonts-2EGPA5ZO.js → bundleWithLocalizedFonts-67MLTHKM.js} +2 -2
- package/dist/{capture-HOIAW6MO.js → capture-F3GNMRZM.js} +13 -13
- package/dist/{capture-HA2UHLIU.js → capture-YYRE7EV3.js} +2 -2
- package/dist/{captureCompositionFrame-4236FVWJ.js → captureCompositionFrame-PXV2ISHD.js} +13 -13
- package/dist/{catalog-A6CZAWW4.js → catalog-6SDD3OHF.js} +14 -14
- package/dist/{catch-up-TNA4DJOA.js → catch-up-CWIVA5VG.js} +4 -4
- package/dist/{check-5E5U2EQZ.js → check-YQ6REK2S.js} +34 -34
- package/dist/{checkBrowser-FNINXBMZ.js → checkBrowser-5XZCBRXM.js} +31 -31
- package/dist/{chunk-2ULXZ4PG.js → chunk-2TAS5O4P.js} +56 -11
- package/dist/{chunk-3TXNNBI2.js → chunk-37CNYTQQ.js} +2 -2
- package/dist/chunk-3NPOFC43.js +3805 -0
- package/dist/{chunk-EEP5Y5IE.js → chunk-46HEFGXJ.js} +1 -1
- package/dist/{chunk-2XA7KXQO.js → chunk-4CTNDBE3.js} +2 -2
- package/dist/{chunk-MFAETWIF.js → chunk-55YELV7B.js} +1 -1
- package/dist/{chunk-LRGYPXHF.js → chunk-5GUKZRQN.js} +1 -1
- package/dist/{chunk-SAX7HQ5E.js → chunk-6ASIXMFP.js} +1 -1
- package/dist/{chunk-SN7KI5JA.js → chunk-6GPR3G3C.js} +2 -2
- package/dist/{chunk-E32ZQ2WO.js → chunk-6RIZY7OP.js} +1 -1
- package/dist/{chunk-5CS4T6C6.js → chunk-7L37AB57.js} +1 -1
- package/dist/{chunk-BCHSTE7U.js → chunk-7PS6RVWD.js} +1 -1
- package/dist/{chunk-X3CG5YQA.js → chunk-7RAY4WZP.js} +3 -3
- package/dist/{chunk-YWHCXIMD.js → chunk-A6QCO474.js} +5 -5
- package/dist/{chunk-YMS5FOMC.js → chunk-B2A56S5C.js} +1 -1
- package/dist/{chunk-IWTNTUPQ.js → chunk-BH7TTIPN.js} +11 -13
- package/dist/{chunk-DWUGKEHR.js → chunk-BRAPBUPQ.js} +1 -1
- package/dist/{chunk-R2BFTECP.js → chunk-CX3USX23.js} +3 -3
- package/dist/{chunk-JB6ARMQS.js → chunk-D42NU3DZ.js} +1 -1
- package/dist/{chunk-GDEV42FA.js → chunk-EMAWIZ54.js} +481 -36
- package/dist/{chunk-UNNXFKVG.js → chunk-EMSDWBG3.js} +2 -2
- package/dist/{chunk-CXABAXB3.js → chunk-ESBMUZXZ.js} +1 -1
- package/dist/{chunk-EM7C7H7S.js → chunk-F3OPUWQX.js} +7 -7
- package/dist/{chunk-YOZPQCSR.js → chunk-FX6RUJUY.js} +3 -3
- package/dist/{chunk-PSKEKWVU.js → chunk-G2UANIDX.js} +1 -1
- package/dist/{chunk-UKOTVJFV.js → chunk-H5SM5PJI.js} +1 -1
- package/dist/{chunk-YWNJTZGN.js → chunk-H6UY725W.js} +2 -2
- package/dist/{chunk-PFYWVUHA.js → chunk-HDIRZGK4.js} +1 -1
- package/dist/{chunk-HR23IKLZ.js → chunk-HHSJJFVM.js} +2 -2
- package/dist/{chunk-LLC4CS6I.js → chunk-HXUTX5GR.js} +3 -3
- package/dist/{chunk-RGXVEYHI.js → chunk-I3IH5MV5.js} +6 -10
- package/dist/{chunk-Q33P4EAC.js → chunk-I45HL3VP.js} +3 -3
- package/dist/{chunk-TYXH3EKP.js → chunk-I5JRXMCV.js} +16 -1
- package/dist/{chunk-4N4P3ZWL.js → chunk-I7QMXZSB.js} +2 -2
- package/dist/{chunk-ICJEAFPD.js → chunk-IDFNKFPL.js} +7 -7
- package/dist/{chunk-VNVQGDPC.js → chunk-IDGLGXPA.js} +1 -1
- package/dist/{chunk-2PVE4WS2.js → chunk-IPDKZ5IN.js} +33 -6
- package/dist/{chunk-ABZYYUUH.js → chunk-ISTRDGIX.js} +1 -1
- package/dist/{chunk-3MDJIWOV.js → chunk-IVEFOUZI.js} +46 -30
- package/dist/{chunk-4KKKBEP3.js → chunk-J5XEZ24I.js} +3 -3
- package/dist/{chunk-7HJALUIO.js → chunk-K2ZKXTVL.js} +1 -1
- package/dist/{chunk-TE427YID.js → chunk-K73RJB23.js} +2 -2
- package/dist/{chunk-3QVMJ7GX.js → chunk-KQ4JEJLF.js} +9 -9
- package/dist/{chunk-J3QM7AHP.js → chunk-KROXPHXX.js} +9 -3
- package/dist/{chunk-OLZENUPI.js → chunk-LLFQA7XF.js} +1 -1
- package/dist/chunk-LLMSX6V6.js +17 -0
- package/dist/{chunk-WTFUDNW2.js → chunk-LYKSTRAY.js} +3 -3
- package/dist/{chunk-VDM3FEDP.js → chunk-OAG47RE6.js} +1 -1
- package/dist/{chunk-FGJEUV4S.js → chunk-PHMBMOXF.js} +1 -1
- package/dist/{chunk-7MB2ZAQF.js → chunk-PMMQRJDE.js} +1 -1
- package/dist/{chunk-ADDHW2FS.js → chunk-Q447CX26.js} +82 -12
- package/dist/{chunk-YALM6XN4.js → chunk-Q47FAYYK.js} +3 -3
- package/dist/{chunk-ZOCHDXDG.js → chunk-RTBSA3EA.js} +1 -1
- package/dist/{chunk-UJKUB2LH.js → chunk-RUEGYANA.js} +11 -11
- package/dist/{chunk-OYLO6TYK.js → chunk-RUOG4VB7.js} +1 -1
- package/dist/{chunk-ZRHO6YMM.js → chunk-SKYPMHQC.js} +4 -4
- package/dist/{chunk-ES426XRJ.js → chunk-SQVRXHOW.js} +3 -3
- package/dist/{chunk-QL2PNIXC.js → chunk-TAX2ZJAP.js} +24 -16
- package/dist/{chunk-KN46TGHV.js → chunk-TOI35GN2.js} +1 -1
- package/dist/{chunk-74JMKLVU.js → chunk-UPR3MU6Z.js} +1 -1
- package/dist/{chunk-JIUTXKWA.js → chunk-WQLKDL35.js} +2 -1
- package/dist/{chunk-WHPN2TIT.js → chunk-X6L6MD5B.js} +5 -5
- package/dist/{chunk-7NRI7HYX.js → chunk-XWC7CNPY.js} +1 -1
- package/dist/{clean-HGASSMWI.js → clean-7J6ZCCGV.js} +18 -18
- package/dist/cli.js +53 -53
- package/dist/{cloud-JPDVNXHN.js → cloud-7IJCJCDD.js} +4 -4
- package/dist/{cloudrun-AMMGSDRP.js → cloudrun-UNZRIIDB.js} +7 -7
- package/dist/commands/contrast-audit.browser.js +1 -2
- package/dist/commands/layout-audit.browser.js +196 -0
- package/dist/{compare-LHHVHUN3.js → compare-Q7VW5JZT.js} +28 -28
- package/dist/{compiler-Q3N6QXMT.js → compiler-KPHYGFXL.js} +6 -6
- package/dist/{component-D72J32Q7.js → component-UUBREJKN.js} +3 -3
- package/dist/{compositions-UQRJ5ROG.js → compositions-T4FTKIDP.js} +13 -13
- package/dist/{delete-P42VIDDA.js → delete-WZQF2IIA.js} +2 -2
- package/dist/{deploy-WZTH57O4.js → deploy-JU7A3XNC.js} +1 -1
- package/dist/{deterministicFonts-VQ5UBMXY.js → deterministicFonts-EGAAE7QL.js} +3 -3
- package/dist/{dist-SENYPQGW.js → dist-LM7AVHOU.js} +3 -3
- package/dist/{dist-DYS24AMA.js → dist-ULGTPSU4.js} +8 -4
- package/dist/docs/data-attributes.md +1 -1
- package/dist/{doctor-KEJIG2SK.js → doctor-VSNGRKXJ.js} +13 -13
- package/dist/{events-CYKSNR7N.js → events-CRW2DYUT.js} +3 -3
- package/dist/{events-UZXFQPMT.js → events-E63YBUL2.js} +3 -3
- package/dist/{feedback-LXNQF7CA.js → feedback-OSZWVR6N.js} +8 -8
- package/dist/{ffmpeg-BYHON577.js → ffmpeg-JLH3Z7G7.js} +9 -9
- package/dist/{figma-EIQ35PS6.js → figma-2BQNNR53.js} +3 -3
- package/dist/fontLocalizeCli.js +12 -12
- package/dist/{get-CC2YL7QO.js → get-P2XI53QW.js} +2 -2
- package/dist/{gpuPolicy-VFSACUQV.js → gpuPolicy-NTKQJY75.js} +9 -9
- package/dist/{grade-compare-TUQL7IV2.js → grade-compare-OYASIHIB.js} +29 -29
- package/dist/{gsapParserAcorn-7NCK2LVT.js → gsapParserAcorn-SKODXC2N.js} +2 -2
- package/dist/{help-ROROO5K6.js → help-HK6K2N4G.js} +1 -1
- package/dist/{history-PNELYLXX.js → history-JMTYKLXW.js} +6 -6
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +63 -63
- package/dist/hyperframes-player.global.js +1 -1
- package/dist/{info-4FZTH6AS.js → info-AW7CIVRE.js} +9 -9
- package/dist/{init-I43GHHVP.js → init-6KIDG4LB.js} +30 -30
- package/dist/{inspect-IT4TYIZ3.js → inspect-B7BLYMRZ.js} +29 -29
- package/dist/{installer-CWOJVK5K.js → installer-ZP2LQZUQ.js} +7 -7
- package/dist/{keyframes-3FBOGVD4.js → keyframes-EQ36A5JE.js} +7 -7
- package/dist/{lambda-H3V32I7M.js → lambda-E6VURLIS.js} +9 -9
- package/dist/{layout-BZ5LYJ5C.js → layout-XYC64QQQ.js} +29 -29
- package/dist/{lint-ZTNSGP2S.js → lint-V5DJYWBX.js} +9 -9
- package/dist/{lintProject-C2ONSH2U.js → lintProject-JATQKR64.js} +3 -3
- package/dist/{list-XM4GWJYY.js → list-RUGVRTVD.js} +2 -2
- package/dist/{login-H6HYKMWX.js → login-ZTKGKXGS.js} +4 -4
- package/dist/{manager-TWVDSJXO.js → manager-JUP7PM6N.js} +10 -10
- package/dist/{media-treatment-N7MY5NXB.js → media-treatment-VIUPK4OR.js} +15 -15
- package/dist/{models-WEMIMYBD.js → models-LJS2HBOZ.js} +13 -13
- package/dist/{motionShot-RHICTVPU.js → motionShot-3UAXZ7SN.js} +16 -16
- package/dist/{normalize-audio-ZFUZCJE3.js → normalize-audio-SBYI4YIH.js} +4 -4
- package/dist/{open-IBJ4FL3G.js → open-S27TUD3A.js} +14 -14
- package/dist/{parakeetRunner-XXO4WSLR.js → parakeetRunner-ETLMLJ4L.js} +14 -14
- package/dist/{pipeline-6ML3LUVK.js → pipeline-I2M22M24.js} +10 -10
- package/dist/{play-RV4NAVF5.js → play-COJU6VJK.js} +21 -21
- package/dist/{preflight-R3DEFMLA.js → preflight-FZ24NCHH.js} +10 -10
- package/dist/{present-5TBJGE6B.js → present-YAHKLC5D.js} +17 -17
- package/dist/{preview-FLKZ5CXJ.js → preview-KQOEU5YE.js} +20 -20
- package/dist/{producer-7XYSPVKH.js → producer-DTNNG4T6.js} +1 -1
- package/dist/{projectConfig-TBU2VWZX.js → projectConfig-4A76VYUP.js} +9 -9
- package/dist/{publication-CWWUJYJ5.js → publication-SQPMC2W3.js} +4 -4
- package/dist/{publish-FSNE4FEB.js → publish-QUEJBGGT.js} +11 -11
- package/dist/{remove-background-MDFWRWCT.js → remove-background-FP2ETAQH.js} +11 -11
- package/dist/{render-F4JQ553X.js → render-BIFIL4U6.js} +31 -31
- package/dist/{render-DBGQZAZT.js → render-GQFXJWLV.js} +17 -29
- package/dist/{render-LWZKXCLY.js → render-P664SMC7.js} +5 -5
- package/dist/{render-batch-PU7NMLIJ.js → render-batch-ZCPMYH6Z.js} +5 -5
- package/dist/renderSetupWorker.js +3 -3
- package/dist/{resolver-RUBGFXPC.js → resolver-BUC2GFZQ.js} +6 -6
- package/dist/{sherpa-X2TBNO6P.js → sherpa-HFT6XEP6.js} +13 -13
- package/dist/skills/hyperframes/SKILL.md +52 -174
- package/dist/skills/hyperframes/assets/frame-presets/biennale-yellow/FRAME.md +289 -0
- package/dist/skills/hyperframes/assets/frame-presets/biennale-yellow/caption-skin.html +220 -0
- package/dist/skills/hyperframes/assets/frame-presets/biennale-yellow/frame-showcase.html +1214 -0
- package/dist/skills/hyperframes/assets/frame-presets/blockframe/FRAME.md +275 -0
- package/dist/skills/hyperframes/assets/frame-presets/blockframe/caption-skin.html +223 -0
- package/dist/skills/hyperframes/assets/frame-presets/blockframe/frame-showcase.html +1347 -0
- package/dist/skills/hyperframes/assets/frame-presets/blue-professional/FRAME.md +307 -0
- package/dist/skills/hyperframes/assets/frame-presets/blue-professional/caption-skin.html +222 -0
- package/dist/skills/hyperframes/assets/frame-presets/blue-professional/frame-showcase.html +1372 -0
- package/dist/skills/hyperframes/assets/frame-presets/bold-poster/FRAME.md +275 -0
- package/dist/skills/hyperframes/assets/frame-presets/bold-poster/caption-skin.html +229 -0
- package/dist/skills/hyperframes/assets/frame-presets/bold-poster/frame-showcase.html +1140 -0
- package/dist/skills/hyperframes/assets/frame-presets/broadside/FRAME.md +284 -0
- package/dist/skills/hyperframes/assets/frame-presets/broadside/caption-skin.html +224 -0
- package/dist/skills/hyperframes/assets/frame-presets/broadside/frame-showcase.html +1166 -0
- package/dist/skills/hyperframes/assets/frame-presets/capsule/FRAME.md +284 -0
- package/dist/skills/hyperframes/assets/frame-presets/capsule/caption-skin.html +223 -0
- package/dist/skills/hyperframes/assets/frame-presets/capsule/frame-showcase.html +1465 -0
- package/dist/skills/hyperframes/assets/frame-presets/cartesian/FRAME.md +278 -0
- package/dist/skills/hyperframes/assets/frame-presets/cartesian/caption-skin.html +221 -0
- package/dist/skills/hyperframes/assets/frame-presets/cartesian/frame-showcase.html +1263 -0
- package/dist/skills/hyperframes/assets/frame-presets/cobalt-grid/FRAME.md +265 -0
- package/dist/skills/hyperframes/assets/frame-presets/cobalt-grid/caption-skin.html +237 -0
- package/dist/skills/hyperframes/assets/frame-presets/cobalt-grid/frame-showcase.html +1468 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/FRAME.md +277 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/caption-skin.html +223 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/EBGaramond-400.woff2 +0 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/EBGaramond-700.woff2 +0 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/Inter-400.woff2 +0 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/Inter-700.woff2 +0 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/JetBrainsMono-400.woff2 +0 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/JetBrainsMono-700.woff2 +0 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/OFL-eb-garamond.txt +93 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/OFL-inter.txt +93 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/OFL-jetbrains-mono.txt +93 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/frame-showcase.html +1438 -0
- package/dist/skills/hyperframes/assets/frame-presets/coral/FRAME.md +314 -0
- package/dist/skills/hyperframes/assets/frame-presets/coral/caption-skin.html +225 -0
- package/dist/skills/hyperframes/assets/frame-presets/coral/frame-showcase.html +1268 -0
- package/dist/skills/hyperframes/assets/frame-presets/creative-mode/FRAME.md +333 -0
- package/dist/skills/hyperframes/assets/frame-presets/creative-mode/caption-skin.html +226 -0
- package/dist/skills/hyperframes/assets/frame-presets/creative-mode/frame-showcase.html +1330 -0
- package/dist/skills/hyperframes/assets/frame-presets/daisy-days/FRAME.md +274 -0
- package/dist/skills/hyperframes/assets/frame-presets/daisy-days/caption-skin.html +229 -0
- package/dist/skills/hyperframes/assets/frame-presets/daisy-days/frame-showcase.html +1444 -0
- package/dist/skills/hyperframes/assets/frame-presets/editorial-forest/FRAME.md +265 -0
- package/dist/skills/hyperframes/assets/frame-presets/editorial-forest/caption-skin.html +222 -0
- package/dist/skills/hyperframes/assets/frame-presets/editorial-forest/frame-showcase.html +1273 -0
- package/dist/skills/hyperframes/references/captions.md +46 -0
- package/dist/skills/hyperframes/references/film.md +47 -0
- package/dist/skills/hyperframes/references/format.md +157 -0
- package/dist/skills/hyperframes/references/look.md +69 -0
- package/dist/skills/hyperframes/references/motion.md +94 -0
- package/dist/skills/hyperframes/references/overlays.md +39 -0
- package/dist/skills/hyperframes/references/plugin-installation.md +3 -3
- package/dist/skills/hyperframes/references/review.md +51 -0
- package/dist/skills/hyperframes/references/runtimes.md +43 -0
- package/dist/skills/hyperframes/references/skill-lifecycle.md +21 -13
- package/dist/skills/hyperframes/references/sound.md +43 -0
- package/dist/skills/hyperframes/references/spec.md +76 -0
- package/dist/skills/hyperframes/references/story.md +103 -0
- package/dist/skills/hyperframes/references/storyboard-format.md +30 -22
- package/dist/skills/hyperframes/references/storyboard.md +36 -0
- package/dist/skills/hyperframes/references/types/3d.md +25 -0
- package/dist/skills/hyperframes/references/types/character.md +20 -0
- package/dist/skills/hyperframes/references/types/data.md +19 -0
- package/dist/skills/hyperframes/references/types/explainer.md +34 -0
- package/dist/skills/hyperframes/references/types/launch.md +31 -0
- package/dist/skills/hyperframes/references/types/music.md +24 -0
- package/dist/skills/hyperframes/references/types/vertical.md +23 -0
- package/dist/skills/hyperframes/scripts/bake-basemap.mjs +324 -0
- package/dist/skills/hyperframes/scripts/lib/main-module.test.mjs +1 -6
- package/dist/skills/hyperframes/scripts/locate.mjs +228 -0
- package/dist/skills/hyperframes-cli/SKILL.md +76 -179
- package/dist/skills/hyperframes-cli/references/beats.md +1 -1
- package/dist/skills/hyperframes-cli/references/cloud.md +2 -2
- package/dist/skills/hyperframes-cli/references/cloudrun.md +1 -1
- package/dist/skills/hyperframes-cli/references/conventions.md +17 -0
- package/dist/skills/hyperframes-cli/references/feedback.md +14 -0
- package/dist/skills/hyperframes-cli/references/init-and-scaffold.md +11 -7
- package/dist/skills/hyperframes-cli/references/lambda.md +1 -1
- package/dist/skills/hyperframes-cli/references/lint-validate-inspect.md +19 -8
- package/dist/skills/hyperframes-cli/references/preview-render.md +8 -2
- package/dist/skills/hyperframes-cli/references/upgrade-info-misc.md +8 -0
- package/dist/skills/media-use/SKILL.md +47 -91
- package/dist/skills/media-use/audio/references/bgm.md +1 -1
- package/dist/skills/media-use/audio/references/captions/authoring.md +1 -2
- package/dist/skills/media-use/audio/references/captions/motion.md +5 -5
- package/dist/skills/media-use/audio/references/tts.md +0 -3
- package/dist/skills/media-use/audio/scripts/audio.mjs +5 -6
- package/dist/skills/media-use/audio/scripts/carve.mjs +560 -0
- package/dist/skills/media-use/audio/scripts/carve.test.mjs +254 -0
- package/dist/skills/media-use/audio/scripts/extract-audio-data.py +199 -0
- package/dist/skills/media-use/references/local.md +24 -0
- package/dist/skills/media-use/references/memory.md +4 -4
- package/dist/skills/media-use/references/mixing.md +71 -0
- package/dist/skills/media-use/references/operations.md +1 -1
- package/dist/skills/media-use/scripts/compatibility.test.mjs +1 -56
- package/dist/skills/media-use/scripts/lib/prefs-store.mjs +1 -1
- package/dist/skills/media-use/scripts/lib/recipe-store.mjs +1 -1
- package/dist/skills/media-use/scripts/prefs.mjs +2 -3
- package/dist/skills/media-use/scripts/recipe.mjs +1 -3
- package/dist/{skills-WHKMWO2D.js → skills-3WEVO3NU.js} +20 -13
- package/dist/{skillsUpdateCheck-XQGZGJJG.js → skillsUpdateCheck-BFPWFOK5.js} +3 -3
- package/dist/{snapshot-M4NUUSNU.js → snapshot-WDQ6S7CJ.js} +457 -98
- package/dist/{src-6MSC62U2.js → src-NPR2JZOJ.js} +11 -11
- package/dist/{src-4UYM2K3S.js → src-RZ574OKP.js} +8 -8
- package/dist/{staticProjectServer-ERDTFP45.js → staticProjectServer-FTGTEZI4.js} +17 -17
- package/dist/studio/assets/{hyperframes-player-DEncBxR7.js → hyperframes-player-CoOdf435.js} +1 -1
- package/dist/studio/assets/{index-Cc22mgvY.js → index-CR85xg2x.js} +1 -1
- package/dist/studio/assets/{index-BABXr78Q.js → index-C_6rTpaB.js} +5 -5
- package/dist/studio/index.html +1 -1
- package/dist/{studio-api-SAKD3VKC.js → studio-api-TAWB7B23.js} +11 -11
- package/dist/{studioServer-IRI7EVOM.js → studioServer-HRQGJTBU.js} +48 -48
- package/dist/{telemetry-F4XADVAF.js → telemetry-QZ6HJF4W.js} +3 -3
- package/dist/templates/_shared/AGENTS.md +14 -19
- package/dist/templates/_shared/CLAUDE.md +14 -19
- package/dist/templates/blank/index.html +10 -4
- package/dist/{timeline-5I444RRE.js → timeline-IKUEW42T.js} +20 -19
- package/dist/{tokens-LRRYM35A.js → tokens-AUGUEWHS.js} +2 -2
- package/dist/{transcribe-44XDFNVU.js → transcribe-7734CG3N.js} +18 -18
- package/dist/{transcribe-WHYHWAB2.js → transcribe-FWU6EMEO.js} +12 -12
- package/dist/{updateCheck-7CPH3CAZ.js → updateCheck-VIPQ3FPW.js} +2 -2
- package/dist/{upgrade-WW4GQ2RI.js → upgrade-4VNDQTVO.js} +2 -2
- package/dist/{urlDownloader-OHLLP45A.js → urlDownloader-6CXL4CL7.js} +8 -8
- package/dist/{validate-VNCDH2LW.js → validate-QWCMVWID.js} +23 -23
- package/dist/{video-5OHTLL2D.js → video-245Q5WN4.js} +9 -9
- package/dist/warmCheck.js +36 -36
- package/package.json +1 -1
- package/dist/chunk-R2SQBPMH.js +0 -3805
- package/dist/skills/hyperframes/references/brief-contract.md +0 -108
- package/dist/skills/hyperframes/references/brief-format.md +0 -72
- package/dist/skills/hyperframes/references/capability-menu.md +0 -47
- package/dist/skills/hyperframes/references/frame-worker-core.md +0 -82
- package/dist/skills/hyperframes/references/intent-interview.md +0 -73
- package/dist/skills/hyperframes/references/pitch-round.md +0 -40
- package/dist/skills/hyperframes/references/production-loop.md +0 -26
- package/dist/skills/hyperframes/references/review-loop.md +0 -37
- package/dist/skills/hyperframes/references/route-briefs.md +0 -11
- package/dist/skills/hyperframes/references/routes/embedded-captions.md +0 -11
- package/dist/skills/hyperframes/references/routes/faceless-explainer.md +0 -12
- package/dist/skills/hyperframes/references/routes/general-video.md +0 -12
- package/dist/skills/hyperframes/references/routes/motion-graphics.md +0 -11
- package/dist/skills/hyperframes/references/routes/music-to-video.md +0 -12
- package/dist/skills/hyperframes/references/routes/pr-to-video.md +0 -28
- package/dist/skills/hyperframes/references/routes/product-launch-video.md +0 -13
- package/dist/skills/hyperframes/references/routes/remotion-to-hyperframes.md +0 -9
- package/dist/skills/hyperframes/references/routes/slideshow.md +0 -11
- package/dist/skills/hyperframes/references/routes/talking-head-recut.md +0 -11
- package/dist/skills/hyperframes/references/script-format.md +0 -52
- package/dist/skills/hyperframes/references/subagent-dispatch.md +0 -35
- package/dist/skills/hyperframes/references/workflow-catalog.md +0 -10
- package/dist/skills/hyperframes/scripts/lib/frame-packets-core.mjs +0 -176
- package/dist/skills/media-use/audio/scripts/lib/host-audio.mjs +0 -28
- package/dist/skills/media-use/audio/scripts/lib/host-audio.test.mjs +0 -106
|
@@ -11,13 +11,13 @@ import {
|
|
|
11
11
|
} from "./chunk-57GN6KWT.js";
|
|
12
12
|
import {
|
|
13
13
|
captureArtifactRevision
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-OAG47RE6.js";
|
|
15
15
|
import {
|
|
16
16
|
loadProducer
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-7PS6RVWD.js";
|
|
18
18
|
import {
|
|
19
19
|
trackLintRun
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-I45HL3VP.js";
|
|
21
21
|
import {
|
|
22
22
|
beginCheckSnapshots,
|
|
23
23
|
checkSnapshotDirectory,
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
import {
|
|
28
28
|
CONTENT_OVERLAP_HELD_ERROR_MS,
|
|
29
29
|
DEFAULT_MAX_STATIC_SEC,
|
|
30
|
+
END_CARD_HOLD_SEC,
|
|
30
31
|
assertionTargets,
|
|
31
32
|
buildLayoutSampleTimes,
|
|
32
33
|
buildTransitionSampleTimes,
|
|
@@ -45,27 +46,27 @@ import {
|
|
|
45
46
|
mergeSampleTimes,
|
|
46
47
|
parseAt,
|
|
47
48
|
readMotionSpec
|
|
48
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-TAX2ZJAP.js";
|
|
49
50
|
import {
|
|
50
51
|
resolveProject
|
|
51
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-5GUKZRQN.js";
|
|
52
53
|
import {
|
|
53
54
|
recordArtifacts
|
|
54
55
|
} from "./chunk-U6RXZNZE.js";
|
|
55
56
|
import {
|
|
56
57
|
BrowserCleanupError,
|
|
57
58
|
closeManagedBrowser
|
|
58
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-TOI35GN2.js";
|
|
59
60
|
import {
|
|
60
61
|
withRemainingBudget
|
|
61
62
|
} from "./chunk-EHSBBBR2.js";
|
|
62
63
|
import {
|
|
63
64
|
resolveLocalBrowserGpuMode
|
|
64
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-EMSDWBG3.js";
|
|
65
66
|
import {
|
|
66
67
|
trackCheckReport,
|
|
67
68
|
trackCommandFailure
|
|
68
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-WQLKDL35.js";
|
|
69
70
|
import {
|
|
70
71
|
swallowedFlagUsageError
|
|
71
72
|
} from "./chunk-HTIUNMTP.js";
|
|
@@ -85,17 +86,17 @@ import {
|
|
|
85
86
|
import {
|
|
86
87
|
extractMediaMetadata,
|
|
87
88
|
findHdrAutoPromotion
|
|
88
|
-
} from "./chunk-
|
|
89
|
+
} from "./chunk-I3IH5MV5.js";
|
|
89
90
|
import {
|
|
90
91
|
lintProject,
|
|
91
92
|
shouldBlockRender
|
|
92
|
-
} from "./chunk-
|
|
93
|
+
} from "./chunk-Q447CX26.js";
|
|
93
94
|
import {
|
|
94
95
|
resolveProjectRelativeSrc
|
|
95
96
|
} from "./chunk-6BNTGNGD.js";
|
|
96
97
|
import {
|
|
97
98
|
withMeta
|
|
98
|
-
} from "./chunk-
|
|
99
|
+
} from "./chunk-ISTRDGIX.js";
|
|
99
100
|
import {
|
|
100
101
|
normalizeErrorMessage
|
|
101
102
|
} from "./chunk-KNU5COPB.js";
|
|
@@ -201,9 +202,378 @@ import { mkdirSync, writeFileSync } from "fs";
|
|
|
201
202
|
import { readFile } from "fs/promises";
|
|
202
203
|
import { join, relative } from "path";
|
|
203
204
|
|
|
205
|
+
// src/utils/craftAudit.ts
|
|
206
|
+
var CRAFT_THRESHOLDS = {
|
|
207
|
+
readHeightAt1080: 30,
|
|
208
|
+
readOpacity: 0.5,
|
|
209
|
+
shortLineWords: 2,
|
|
210
|
+
shortLineFloorSec: 0.4,
|
|
211
|
+
holdBaseSec: 0.5,
|
|
212
|
+
holdPerWordSec: 0.3,
|
|
213
|
+
holdFloorFraction: 0.75,
|
|
214
|
+
finalLineFloorSec: 2,
|
|
215
|
+
deadStretchSec: 3,
|
|
216
|
+
endCardSec: END_CARD_HOLD_SEC,
|
|
217
|
+
typeFloorFraction: 0.026,
|
|
218
|
+
typeFloorHoldSec: 0.5,
|
|
219
|
+
silentFilmSec: 15,
|
|
220
|
+
/** One video frame: a line held exactly at its floor measures a hair under it. */
|
|
221
|
+
measureToleranceSec: 1 / 30,
|
|
222
|
+
/** Halvings of a grid step when re-measuring a line's edges (0.125 s → ~8 ms). */
|
|
223
|
+
refineSteps: 4,
|
|
224
|
+
maxRefinedLines: 24
|
|
225
|
+
};
|
|
226
|
+
var T = CRAFT_THRESHOLDS;
|
|
227
|
+
var ZERO_BBOX = { x: 0, y: 0, width: 0, height: 0 };
|
|
228
|
+
var WORD_RUNS = /[\p{L}\p{M}\p{N}%$]+/gu;
|
|
229
|
+
var WORD_SEGMENTER = new Intl.Segmenter("ja", { granularity: "word" });
|
|
230
|
+
function readingWords(text) {
|
|
231
|
+
const runs = text.toLowerCase().normalize("NFC").match(WORD_RUNS) ?? [];
|
|
232
|
+
return runs.reduce(
|
|
233
|
+
(count, run) => count + Math.max(1, [...WORD_SEGMENTER.segment(run)].filter((s) => s.isWordLike).length),
|
|
234
|
+
0
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
function lineTargetSec(words) {
|
|
238
|
+
return T.holdBaseSec + T.holdPerWordSec * words;
|
|
239
|
+
}
|
|
240
|
+
function lineFloorSec(words, finalLine) {
|
|
241
|
+
const floor = words <= T.shortLineWords ? T.shortLineFloorSec : T.holdFloorFraction * lineTargetSec(words);
|
|
242
|
+
return finalLine ? Math.max(floor, T.finalLineFloorSec) : floor;
|
|
243
|
+
}
|
|
244
|
+
async function auditCraft(input, probe) {
|
|
245
|
+
const frames = [...input.frames].sort((a, b) => a.time - b.time);
|
|
246
|
+
const step = sampleStep(frames);
|
|
247
|
+
const findings = [
|
|
248
|
+
...detectFirstFrameEmpty(frames),
|
|
249
|
+
...await detectLineUnread(frames, input.duration, input.canvas, probe),
|
|
250
|
+
...input.stillnessJudgedElsewhere ? [] : detectDeadStretches(frames, input.duration),
|
|
251
|
+
...detectTextBelowFloor(frames, input.duration, input.canvas),
|
|
252
|
+
...detectFilmSilent(input.duration, input.soundSources)
|
|
253
|
+
].sort((a, b) => a.time - b.time);
|
|
254
|
+
return { enabled: true, step, samples: frames.length, findings };
|
|
255
|
+
}
|
|
256
|
+
function sampleStep(frames) {
|
|
257
|
+
const gaps = frames.slice(1).map((frame, index) => frame.time - (frames[index]?.time ?? frame.time)).filter((gap) => gap > 0).sort((a, b) => a - b);
|
|
258
|
+
return gaps[Math.floor(gaps.length / 2)] ?? 0;
|
|
259
|
+
}
|
|
260
|
+
function seconds(value) {
|
|
261
|
+
return `${value.toFixed(2)} s`;
|
|
262
|
+
}
|
|
263
|
+
function filmFinding(code, time, message, extra = {}) {
|
|
264
|
+
return {
|
|
265
|
+
code,
|
|
266
|
+
severity: "warning",
|
|
267
|
+
message,
|
|
268
|
+
selector: "[data-composition-id]",
|
|
269
|
+
dataAttributes: {},
|
|
270
|
+
sourceFile: "index.html",
|
|
271
|
+
bbox: ZERO_BBOX,
|
|
272
|
+
time,
|
|
273
|
+
...extra
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
function detectFirstFrameEmpty(frames) {
|
|
277
|
+
const first = frames[0];
|
|
278
|
+
if (!first || first.time > 1e-3 || first.painted) return [];
|
|
279
|
+
return [
|
|
280
|
+
filmFinding(
|
|
281
|
+
"first_frame_empty",
|
|
282
|
+
0,
|
|
283
|
+
"Frame 0 shows only the background, and the first frame is the thumbnail on social players: have the title or key image already on screen at 0 s instead of entering from nothing; see references/review.md."
|
|
284
|
+
)
|
|
285
|
+
];
|
|
286
|
+
}
|
|
287
|
+
function detectFilmSilent(duration, soundSources) {
|
|
288
|
+
if (soundSources === null || soundSources > 0 || duration <= T.silentFilmSec) return [];
|
|
289
|
+
return [
|
|
290
|
+
filmFinding(
|
|
291
|
+
"film_silent",
|
|
292
|
+
0,
|
|
293
|
+
`This ${Math.round(duration)} s film has no sound source (no <audio>, no <video> with sound): add a music bed and sounds on the visible actions unless the person asked for silence; see references/sound.md.`
|
|
294
|
+
)
|
|
295
|
+
];
|
|
296
|
+
}
|
|
297
|
+
function detectDeadStretches(frames, duration) {
|
|
298
|
+
const endCardStart = duration - T.endCardSec;
|
|
299
|
+
const findings = [];
|
|
300
|
+
let start = null;
|
|
301
|
+
let end = 0;
|
|
302
|
+
const flush = () => {
|
|
303
|
+
if (start !== null && end - start > T.deadStretchSec) findings.push(deadStretch(start, end));
|
|
304
|
+
start = null;
|
|
305
|
+
};
|
|
306
|
+
for (let index = 1; index < frames.length; index += 1) {
|
|
307
|
+
const before = frames[index - 1];
|
|
308
|
+
const after = frames[index];
|
|
309
|
+
if (!before || !after) continue;
|
|
310
|
+
const still = before.signature !== "" && before.signature === after.signature && !before.held && !after.held && before.time < endCardStart;
|
|
311
|
+
if (!still) {
|
|
312
|
+
flush();
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
start ??= before.time;
|
|
316
|
+
end = Math.min(after.time, endCardStart);
|
|
317
|
+
}
|
|
318
|
+
flush();
|
|
319
|
+
return findings;
|
|
320
|
+
}
|
|
321
|
+
function deadStretch(start, end) {
|
|
322
|
+
const length = end - start;
|
|
323
|
+
return filmFinding(
|
|
324
|
+
"dead_stretch",
|
|
325
|
+
start,
|
|
326
|
+
`Nothing on screen changes for ${seconds(length)} (${start.toFixed(2)}\u2013${end.toFixed(2)} s): start the next move within ${T.deadStretchSec} s, or put data-hold on the element whose stillness is deliberate; see references/motion.md.`,
|
|
327
|
+
{ seconds: round(length), floorSeconds: T.deadStretchSec, until: round(end) }
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
function readableBlocks(frame, readHeight) {
|
|
331
|
+
const blocks = /* @__PURE__ */ new Map();
|
|
332
|
+
for (const part of frame.parts) {
|
|
333
|
+
if (part.captions || part.opacity < T.readOpacity) continue;
|
|
334
|
+
const rect = {
|
|
335
|
+
left: part.rect.left,
|
|
336
|
+
top: part.rect.top,
|
|
337
|
+
right: part.rect.left + part.rect.width,
|
|
338
|
+
bottom: part.rect.top + part.rect.height
|
|
339
|
+
};
|
|
340
|
+
const block = blocks.get(part.block);
|
|
341
|
+
if (!block) {
|
|
342
|
+
blocks.set(part.block, {
|
|
343
|
+
text: part.text,
|
|
344
|
+
rect,
|
|
345
|
+
selector: part.blockSelector,
|
|
346
|
+
sourceFile: part.sourceFile
|
|
347
|
+
});
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
block.text = `${block.text} ${part.text}`;
|
|
351
|
+
block.rect = {
|
|
352
|
+
left: Math.min(block.rect.left, rect.left),
|
|
353
|
+
top: Math.min(block.rect.top, rect.top),
|
|
354
|
+
right: Math.max(block.rect.right, rect.right),
|
|
355
|
+
bottom: Math.max(block.rect.bottom, rect.bottom)
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
for (const [key, block] of blocks) {
|
|
359
|
+
if (block.rect.bottom - block.rect.top < readHeight) blocks.delete(key);
|
|
360
|
+
}
|
|
361
|
+
return blocks;
|
|
362
|
+
}
|
|
363
|
+
function trackBlocks(frames, readHeight) {
|
|
364
|
+
const tracks = /* @__PURE__ */ new Map();
|
|
365
|
+
frames.forEach((frame, index) => {
|
|
366
|
+
for (const [key, block] of readableBlocks(frame, readHeight)) {
|
|
367
|
+
const track = tracks.get(key) ?? {
|
|
368
|
+
key,
|
|
369
|
+
selector: block.selector,
|
|
370
|
+
sourceFile: block.sourceFile,
|
|
371
|
+
seen: /* @__PURE__ */ new Map()
|
|
372
|
+
};
|
|
373
|
+
track.seen.set(index, { text: block.text, rect: block.rect });
|
|
374
|
+
tracks.set(key, track);
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
return [...tracks.values()];
|
|
378
|
+
}
|
|
379
|
+
function indexRuns(indices) {
|
|
380
|
+
const sorted = [...indices].sort((a, b) => a - b);
|
|
381
|
+
const runs = [];
|
|
382
|
+
for (const index of sorted) {
|
|
383
|
+
const last = runs[runs.length - 1];
|
|
384
|
+
if (last && index === last[1] + 1) last[1] = index;
|
|
385
|
+
else runs.push([index, index]);
|
|
386
|
+
}
|
|
387
|
+
return runs;
|
|
388
|
+
}
|
|
389
|
+
function windowSeconds(window2) {
|
|
390
|
+
return (window2.endIn + window2.endOut) / 2 - (window2.startOut + window2.startIn) / 2;
|
|
391
|
+
}
|
|
392
|
+
function runWindow(frames, [first, last], duration) {
|
|
393
|
+
const timeAt = (index) => frames[Math.min(Math.max(index, 0), frames.length - 1)]?.time ?? 0;
|
|
394
|
+
const reachesEnd = last === frames.length - 1;
|
|
395
|
+
return {
|
|
396
|
+
startOut: timeAt(first - 1),
|
|
397
|
+
startIn: timeAt(first),
|
|
398
|
+
endIn: reachesEnd ? duration : timeAt(last),
|
|
399
|
+
endOut: reachesEnd ? duration : timeAt(last + 1)
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
function lineCandidates(frames, duration, canvas) {
|
|
403
|
+
const readHeight = T.readHeightAt1080 * (Math.min(canvas.width, canvas.height) / 1080);
|
|
404
|
+
const tracks = trackBlocks(frames, readHeight);
|
|
405
|
+
const lastEnd = (track) => Math.max(...track.seen.keys());
|
|
406
|
+
const latest = Math.max(-1, ...tracks.map(lastEnd));
|
|
407
|
+
const candidates = [];
|
|
408
|
+
for (const track of tracks) {
|
|
409
|
+
const runs = indexRuns([...track.seen.keys()]);
|
|
410
|
+
const finalLine = lastEnd(track) === latest;
|
|
411
|
+
const windows = runs.map((run2) => runWindow(frames, run2, duration));
|
|
412
|
+
const chosen = finalLine ? windows.length - 1 : windows.reduce((best, window3, index) => {
|
|
413
|
+
const bestWindow = windows[best];
|
|
414
|
+
return bestWindow && windowSeconds(window3) > windowSeconds(bestWindow) ? index : best;
|
|
415
|
+
}, 0);
|
|
416
|
+
const window2 = windows[chosen];
|
|
417
|
+
const run = runs[chosen];
|
|
418
|
+
if (!window2 || !run) continue;
|
|
419
|
+
const texts = [...track.seen.values()].map((seen) => seen.text);
|
|
420
|
+
const text = texts.reduce(
|
|
421
|
+
(longest, next) => readingWords(next) > readingWords(longest) ? next : longest
|
|
422
|
+
);
|
|
423
|
+
const words = readingWords(text);
|
|
424
|
+
if (words === 0) continue;
|
|
425
|
+
const floor = lineFloorSec(words, finalLine);
|
|
426
|
+
if (window2.endIn - window2.startIn >= floor) continue;
|
|
427
|
+
candidates.push({ track, words, text, finalLine, floor, window: window2, firstIndex: run[0] });
|
|
428
|
+
}
|
|
429
|
+
return candidates;
|
|
430
|
+
}
|
|
431
|
+
async function refineWindow(candidate, probe, canvas) {
|
|
432
|
+
const readHeight = T.readHeightAt1080 * (Math.min(canvas.width, canvas.height) / 1080);
|
|
433
|
+
const visibleAt = async (time) => readableBlocks(await probe(time), readHeight).has(candidate.track.key);
|
|
434
|
+
const window2 = { ...candidate.window };
|
|
435
|
+
for (let step = 0; step < T.refineSteps; step += 1) {
|
|
436
|
+
if (window2.startIn > window2.startOut) {
|
|
437
|
+
const mid = (window2.startOut + window2.startIn) / 2;
|
|
438
|
+
if (await visibleAt(mid)) window2.startIn = mid;
|
|
439
|
+
else window2.startOut = mid;
|
|
440
|
+
}
|
|
441
|
+
if (window2.endOut > window2.endIn) {
|
|
442
|
+
const mid = (window2.endIn + window2.endOut) / 2;
|
|
443
|
+
if (await visibleAt(mid)) window2.endIn = mid;
|
|
444
|
+
else window2.endOut = mid;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
return window2;
|
|
448
|
+
}
|
|
449
|
+
async function detectLineUnread(frames, duration, canvas, probe) {
|
|
450
|
+
const findings = [];
|
|
451
|
+
const candidates = lineCandidates(frames, duration, canvas);
|
|
452
|
+
for (const [index, candidate] of candidates.entries()) {
|
|
453
|
+
const window2 = probe && index < T.maxRefinedLines ? await refineWindow(candidate, probe, canvas) : candidate.window;
|
|
454
|
+
const held = windowSeconds(window2);
|
|
455
|
+
if (held >= candidate.floor - T.measureToleranceSec) continue;
|
|
456
|
+
const error = Math.max(window2.startIn - window2.startOut, window2.endOut - window2.endIn) / 2;
|
|
457
|
+
findings.push(lineUnreadFinding(candidate, window2, held, error));
|
|
458
|
+
}
|
|
459
|
+
return findings;
|
|
460
|
+
}
|
|
461
|
+
function lineUnreadFinding(candidate, window2, held, error) {
|
|
462
|
+
const { track, words, text, finalLine, floor } = candidate;
|
|
463
|
+
const quoted = quote(text, 60);
|
|
464
|
+
const wordLabel = `${words} word${words === 1 ? "" : "s"}`;
|
|
465
|
+
const measured = `${seconds(held)} (\xB1${Math.max(0.01, error).toFixed(2)} s)`;
|
|
466
|
+
const target = lineTargetSec(words);
|
|
467
|
+
const message = finalLine ? `The film's last line ${quoted} (${wordLabel}) is on screen ${measured}, under the ${seconds(floor)} a closing line needs: hold it about 0.5 s + 0.3 s a word and at least 2 s before the film ends; see references/motion.md.` : `${quoted} (${wordLabel}) is on screen ${measured}, under its ${seconds(floor)} floor: hold it about 0.5 s + 0.3 s a word (${seconds(target)} here) before it leaves or changes; see references/motion.md.`;
|
|
468
|
+
const firstSeen = track.seen.get(candidate.firstIndex);
|
|
469
|
+
const rect = firstSeen?.rect;
|
|
470
|
+
return {
|
|
471
|
+
code: "line_unread",
|
|
472
|
+
severity: "warning",
|
|
473
|
+
message,
|
|
474
|
+
text,
|
|
475
|
+
selector: track.selector,
|
|
476
|
+
dataAttributes: {},
|
|
477
|
+
sourceFile: track.sourceFile,
|
|
478
|
+
bbox: rect ? { x: rect.left, y: rect.top, width: rect.right - rect.left, height: rect.bottom - rect.top } : ZERO_BBOX,
|
|
479
|
+
time: round(window2.startIn),
|
|
480
|
+
words,
|
|
481
|
+
seconds: round(held),
|
|
482
|
+
floorSeconds: round(floor)
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
function typeFloorPx(canvas) {
|
|
486
|
+
return Math.round(T.typeFloorFraction * Math.min(canvas.width, canvas.height));
|
|
487
|
+
}
|
|
488
|
+
function detectTextBelowFloor(frames, duration, canvas) {
|
|
489
|
+
const floorPx = typeFloorPx(canvas);
|
|
490
|
+
const step = sampleStep(frames);
|
|
491
|
+
const sightings = /* @__PURE__ */ new Map();
|
|
492
|
+
frames.forEach((frame, index) => {
|
|
493
|
+
for (const part of frame.parts) {
|
|
494
|
+
if (part.captions || part.opacity < T.readOpacity) continue;
|
|
495
|
+
if (part.fontPx >= floorPx - 0.5 || readingWords(part.text) === 0) continue;
|
|
496
|
+
const seen = sightings.get(part.key) ?? /* @__PURE__ */ new Map();
|
|
497
|
+
seen.set(index, part);
|
|
498
|
+
sightings.set(part.key, seen);
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
const small = [];
|
|
502
|
+
for (const seen of sightings.values()) {
|
|
503
|
+
const [first, last] = longestRun(indexRuns([...seen.keys()]));
|
|
504
|
+
const start = frames[first]?.time ?? 0;
|
|
505
|
+
const end = last === frames.length - 1 ? duration : (frames[last]?.time ?? start) + step;
|
|
506
|
+
if (end - start < T.typeFloorHoldSec) continue;
|
|
507
|
+
const parts = [...seen.values()];
|
|
508
|
+
const part = parts[0];
|
|
509
|
+
if (!part) continue;
|
|
510
|
+
small.push({
|
|
511
|
+
selector: part.selector,
|
|
512
|
+
sourceFile: part.sourceFile,
|
|
513
|
+
text: part.text,
|
|
514
|
+
fontPx: Math.min(...parts.map((entry) => entry.fontPx)),
|
|
515
|
+
seconds: end - start,
|
|
516
|
+
time: start,
|
|
517
|
+
bbox: {
|
|
518
|
+
x: part.rect.left,
|
|
519
|
+
y: part.rect.top,
|
|
520
|
+
width: part.rect.width,
|
|
521
|
+
height: part.rect.height
|
|
522
|
+
}
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
const shortSide = Math.min(canvas.width, canvas.height);
|
|
526
|
+
return groupBySourceFile(small).map((group) => smallTextFinding(group, floorPx, shortSide));
|
|
527
|
+
}
|
|
528
|
+
function longestRun(runs) {
|
|
529
|
+
return runs.reduce((best, run) => run[1] - run[0] > best[1] - best[0] ? run : best, [0, -1]);
|
|
530
|
+
}
|
|
531
|
+
function groupBySourceFile(small) {
|
|
532
|
+
const groups = /* @__PURE__ */ new Map();
|
|
533
|
+
for (const entry of small)
|
|
534
|
+
groups.set(entry.sourceFile, [...groups.get(entry.sourceFile) ?? [], entry]);
|
|
535
|
+
return [...groups.values()].map(
|
|
536
|
+
(group) => group.sort((a, b) => a.fontPx - b.fontPx || a.time - b.time)
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
function quote(text, max) {
|
|
540
|
+
return `"${text.length > max ? `${text.slice(0, max - 3)}...` : text}"`;
|
|
541
|
+
}
|
|
542
|
+
function smallTextFinding(group, floorPx, shortSide) {
|
|
543
|
+
const [smallest] = group;
|
|
544
|
+
if (!smallest) throw new Error("text_below_floor group is empty");
|
|
545
|
+
const subject = group.length === 1 ? `${quote(smallest.text, 48)} renders at ${Math.round(smallest.fontPx)} px for ${seconds(smallest.seconds)}` : `${group.length} text elements stay under it for 0.5 s or more, the smallest ${quote(smallest.text, 40)} at ${Math.round(smallest.fontPx)} px`;
|
|
546
|
+
const byTime = [...group].sort((a, b) => a.time - b.time);
|
|
547
|
+
return {
|
|
548
|
+
code: "text_below_floor",
|
|
549
|
+
severity: "warning",
|
|
550
|
+
message: `Type floor is ${floorPx} px (2.6% of the ${shortSide} px short side, what a phone can read) and ${subject}: set reading text to at least ${floorPx} px, or put data-layout-ignore on text that is texture rather than reading; see references/look.md.`,
|
|
551
|
+
text: smallest.text,
|
|
552
|
+
selector: smallest.selector,
|
|
553
|
+
dataAttributes: {},
|
|
554
|
+
sourceFile: smallest.sourceFile,
|
|
555
|
+
bbox: smallest.bbox,
|
|
556
|
+
time: round(smallest.time),
|
|
557
|
+
times: byTime.map((entry) => round(entry.time)),
|
|
558
|
+
fontPx: round(smallest.fontPx),
|
|
559
|
+
floorPx,
|
|
560
|
+
seconds: round(smallest.seconds),
|
|
561
|
+
elements: group.map((entry) => ({
|
|
562
|
+
selector: entry.selector,
|
|
563
|
+
text: entry.text,
|
|
564
|
+
fontPx: round(entry.fontPx),
|
|
565
|
+
time: round(entry.time),
|
|
566
|
+
seconds: round(entry.seconds)
|
|
567
|
+
}))
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
function round(value) {
|
|
571
|
+
return Math.round(value * 1e3) / 1e3;
|
|
572
|
+
}
|
|
573
|
+
|
|
204
574
|
// src/utils/hdrPromotion.ts
|
|
205
575
|
async function bundleProjectHtml(projectDir) {
|
|
206
|
-
const { bundleToSingleHtml } = await import("./compiler-
|
|
576
|
+
const { bundleToSingleHtml } = await import("./compiler-KPHYGFXL.js");
|
|
207
577
|
return bundleToSingleHtml(projectDir);
|
|
208
578
|
}
|
|
209
579
|
async function collectBundledRenderMedia(html) {
|
|
@@ -279,7 +649,7 @@ function parseColorRGBA(color) {
|
|
|
279
649
|
// src/utils/checkPipeline.ts
|
|
280
650
|
var MOTION_FPS = 20;
|
|
281
651
|
var MOTION_MAX_SAMPLES = 300;
|
|
282
|
-
var
|
|
652
|
+
var ZERO_BBOX2 = { x: 0, y: 0, width: 0, height: 0 };
|
|
283
653
|
var FRAME_BREACH_FLOOR_PX = 120;
|
|
284
654
|
var FRAME_BREACH_FLOOR_FRACTION = 0.06;
|
|
285
655
|
var DEFAULT_CHECK_OPTIONS = {
|
|
@@ -518,7 +888,8 @@ function emptyGridSamples() {
|
|
|
518
888
|
contrastMs: 0,
|
|
519
889
|
layoutStateSignatures: [],
|
|
520
890
|
rotationSamples: [],
|
|
521
|
-
indicatorFrames: []
|
|
891
|
+
indicatorFrames: [],
|
|
892
|
+
craftFrames: []
|
|
522
893
|
};
|
|
523
894
|
}
|
|
524
895
|
function appendGridSamples(into, from) {
|
|
@@ -530,6 +901,7 @@ function appendGridSamples(into, from) {
|
|
|
530
901
|
into.layoutStateSignatures.push(...from.layoutStateSignatures);
|
|
531
902
|
into.rotationSamples.push(...from.rotationSamples);
|
|
532
903
|
into.indicatorFrames.push(...from.indicatorFrames);
|
|
904
|
+
into.craftFrames.push(...from.craftFrames);
|
|
533
905
|
}
|
|
534
906
|
async function collectSampleAt(driver, options, grid, motion, sets, time) {
|
|
535
907
|
const collected = emptyGridSamples();
|
|
@@ -605,9 +977,18 @@ async function collectGridSamples(driver, options, grid, motion, helpers) {
|
|
|
605
977
|
driver.markSamples?.("end");
|
|
606
978
|
const collected = emptyGridSamples();
|
|
607
979
|
for (const samples of perTime) appendGridSamples(collected, samples);
|
|
608
|
-
await collectMotionOverlapSamples(
|
|
980
|
+
await collectMotionOverlapSamples(
|
|
981
|
+
driver,
|
|
982
|
+
grid,
|
|
983
|
+
collected,
|
|
984
|
+
options.range,
|
|
985
|
+
craftEnabled(driver, options)
|
|
986
|
+
);
|
|
609
987
|
return collected;
|
|
610
988
|
}
|
|
989
|
+
function craftEnabled(driver, options) {
|
|
990
|
+
return !options.range && typeof driver.collectCraftFrame === "function";
|
|
991
|
+
}
|
|
611
992
|
async function collectContrastAt(driver, options, time, issuesAtTime, collected) {
|
|
612
993
|
const contrastStart = Date.now();
|
|
613
994
|
const capture = options.snapshots ? await driver.collectContrast(time, annotationBoxesFrom(issuesAtTime)) : await driver.collectContrast(time);
|
|
@@ -683,9 +1064,16 @@ async function denseOverlapTimes(driver, grid, range) {
|
|
|
683
1064
|
const overlapTimes = buildOverlapSampleTimes(range ? range[1] - range[0] : grid.duration, edges);
|
|
684
1065
|
return range ? mergeSampleTimes(overlapTimes.map((time) => time + range[0])) : overlapTimes;
|
|
685
1066
|
}
|
|
686
|
-
async function collectMotionOverlapSamples(driver, grid, collected, range) {
|
|
1067
|
+
async function collectMotionOverlapSamples(driver, grid, collected, range, craft) {
|
|
687
1068
|
const baseTimes = new Set(grid.layoutSamples);
|
|
688
1069
|
const shiftedTimes = await denseOverlapTimes(driver, grid, range);
|
|
1070
|
+
if (craft) {
|
|
1071
|
+
for (const time of buildCraftSampleTimes(grid.duration)) {
|
|
1072
|
+
if (time >= grid.duration) continue;
|
|
1073
|
+
await driver.seekGeometry(time);
|
|
1074
|
+
collected.craftFrames.push(...await collectCraftFrame(driver, time));
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
689
1077
|
const probeHold = holdProber(driver, collected, range ? range[1] : grid.duration);
|
|
690
1078
|
const gridIssues = await driver.collectOverlapGrid(shiftedTimes.filter((t) => !baseTimes.has(t)));
|
|
691
1079
|
let sample = 0;
|
|
@@ -696,6 +1084,22 @@ async function collectMotionOverlapSamples(driver, grid, collected, range) {
|
|
|
696
1084
|
await probeHold(time, shiftedTimes[index + 1] ?? Number.POSITIVE_INFINITY, issues);
|
|
697
1085
|
}
|
|
698
1086
|
}
|
|
1087
|
+
var CRAFT_SAMPLE_FPS = 8;
|
|
1088
|
+
var CRAFT_MAX_SAMPLES = 600;
|
|
1089
|
+
function buildCraftSampleTimes(duration) {
|
|
1090
|
+
if (!Number.isFinite(duration) || duration <= 0) return [];
|
|
1091
|
+
const count = Math.min(
|
|
1092
|
+
CRAFT_MAX_SAMPLES,
|
|
1093
|
+
Math.max(2, Math.ceil(duration * CRAFT_SAMPLE_FPS) + 1)
|
|
1094
|
+
);
|
|
1095
|
+
const step = duration / (count - 1);
|
|
1096
|
+
return mergeSampleTimes(
|
|
1097
|
+
Array.from({ length: count }, (_, index) => Math.round(index * step * 1e3) / 1e3)
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1100
|
+
async function collectCraftFrame(driver, time) {
|
|
1101
|
+
return driver.collectCraftFrame ? [await driver.collectCraftFrame(time)] : [];
|
|
1102
|
+
}
|
|
699
1103
|
var SWEEP_STATIC_MIN_DURATION_SEC = 3;
|
|
700
1104
|
var ZERO_LAYOUT_RECT = {
|
|
701
1105
|
left: 0,
|
|
@@ -797,7 +1201,7 @@ function sweepStaticIssue(kind) {
|
|
|
797
1201
|
selector: "[data-composition-id]",
|
|
798
1202
|
dataAttributes: {},
|
|
799
1203
|
sourceFile: "index.html",
|
|
800
|
-
bbox:
|
|
1204
|
+
bbox: ZERO_BBOX2,
|
|
801
1205
|
rect: ZERO_LAYOUT_RECT,
|
|
802
1206
|
message: SWEEP_STATIC_MESSAGES[kind],
|
|
803
1207
|
fixHint: kind === "error" ? "An animation on the page never moved under seek. Build it on the paused GSAP timeline registered in `window.__timelines[compositionId]`, or as a CSS animation, so the seek drives it." : STILL_FIX_HINT
|
|
@@ -1131,6 +1535,14 @@ function detectOffPivotRotation(frames) {
|
|
|
1131
1535
|
function annotationBoxesFrom(issues) {
|
|
1132
1536
|
return issues.filter((issue) => issue.severity === "error" && issue.bbox.width > 0 && issue.bbox.height > 0).map((issue, index) => ({ label: `${index + 1} ${issue.code}`, bbox: issue.bbox }));
|
|
1133
1537
|
}
|
|
1538
|
+
function wholeCompositionKeepsMoving(assertions) {
|
|
1539
|
+
return assertions.some(
|
|
1540
|
+
(assertion) => assertion.kind === "keepsMoving" && assertion.withinSelector === void 0
|
|
1541
|
+
);
|
|
1542
|
+
}
|
|
1543
|
+
function disabledCraft() {
|
|
1544
|
+
return { enabled: false, step: 0, samples: 0, findings: [] };
|
|
1545
|
+
}
|
|
1134
1546
|
async function runAuditGrid(driver, options, motion, helpers = Promise.resolve([])) {
|
|
1135
1547
|
await driver.initialize(options.contrast);
|
|
1136
1548
|
const grid = await buildSampleGrid(driver, options);
|
|
@@ -1145,23 +1557,19 @@ async function runAuditGrid(driver, options, motion, helpers = Promise.resolve([
|
|
|
1145
1557
|
let motionIssues = plan.preflightIssues;
|
|
1146
1558
|
if (motion.kind === "valid" && plan.assertions.length > 0 && collected.motionFrames.length > 0) {
|
|
1147
1559
|
const canvas = await driver.getCanvas();
|
|
1148
|
-
let evaluated = evaluateMotion(collected.motionFrames, plan.assertions, canvas);
|
|
1560
|
+
let evaluated = evaluateMotion(collected.motionFrames, plan.assertions, canvas, grid.duration);
|
|
1149
1561
|
if (evaluated.some((issue) => issue.code === "motion_frozen")) {
|
|
1150
1562
|
const frames = await withFrameMotion(driver, collected.motionFrames, plan.assertions);
|
|
1151
|
-
evaluated = evaluateMotion(frames, plan.assertions, canvas);
|
|
1563
|
+
evaluated = evaluateMotion(frames, plan.assertions, canvas, grid.duration);
|
|
1152
1564
|
}
|
|
1153
1565
|
motionIssues = [...motionIssues, ...await driver.anchorMotionIssues(evaluated)];
|
|
1154
1566
|
}
|
|
1155
1567
|
const userPicked = new Set(grid.userPickedSamples);
|
|
1568
|
+
const noTimeline = await driver.hasNoTimelineDeclaration();
|
|
1156
1569
|
const sweepSamples = collected.layoutStateSignatures.filter(
|
|
1157
1570
|
(sample) => !userPicked.has(sample.time)
|
|
1158
1571
|
);
|
|
1159
|
-
const sweepVerdict = options.range ? [] : detectSweepStatic(
|
|
1160
|
-
grid.duration,
|
|
1161
|
-
sweepSamples,
|
|
1162
|
-
motionIssues,
|
|
1163
|
-
await driver.hasNoTimelineDeclaration()
|
|
1164
|
-
);
|
|
1572
|
+
const sweepVerdict = options.range ? [] : detectSweepStatic(grid.duration, sweepSamples, motionIssues, noTimeline);
|
|
1165
1573
|
const sweepFindings = sweepVerdict.length > 0 && await framesMoved(
|
|
1166
1574
|
driver,
|
|
1167
1575
|
sweepSamples.map((sample) => sample.time)
|
|
@@ -1172,6 +1580,20 @@ async function runAuditGrid(driver, options, motion, helpers = Promise.resolve([
|
|
|
1172
1580
|
);
|
|
1173
1581
|
const offPivotFindings = detectOffPivotRotation(collected.indicatorFrames);
|
|
1174
1582
|
const contrast = buildContrastResults(collected.contrastEntries);
|
|
1583
|
+
const craft = craftEnabled(driver, options) ? await auditCraft(
|
|
1584
|
+
{
|
|
1585
|
+
frames: collected.craftFrames,
|
|
1586
|
+
duration: grid.duration,
|
|
1587
|
+
canvas: await driver.getCanvas(),
|
|
1588
|
+
soundSources: driver.collectCraftFilm ? (await driver.collectCraftFilm()).soundSources : null,
|
|
1589
|
+
stillnessJudgedElsewhere: noTimeline || sweepFindings.length > 0 || wholeCompositionKeepsMoving(plan.assertions)
|
|
1590
|
+
},
|
|
1591
|
+
async (time) => {
|
|
1592
|
+
await driver.seekGeometry(time);
|
|
1593
|
+
if (!driver.collectCraftFrame) throw new Error("craft sampling unavailable");
|
|
1594
|
+
return driver.collectCraftFrame(time);
|
|
1595
|
+
}
|
|
1596
|
+
) : disabledCraft();
|
|
1175
1597
|
if (options.components?.length) {
|
|
1176
1598
|
if (!driver.matchComponents)
|
|
1177
1599
|
throw new Error("Component filtering unavailable in this check driver");
|
|
@@ -1181,7 +1603,8 @@ async function runAuditGrid(driver, options, motion, helpers = Promise.resolve([
|
|
|
1181
1603
|
...rotationFindings,
|
|
1182
1604
|
...offPivotFindings,
|
|
1183
1605
|
...motionIssues,
|
|
1184
|
-
...contrast.findings
|
|
1606
|
+
...contrast.findings,
|
|
1607
|
+
...craft.findings
|
|
1185
1608
|
];
|
|
1186
1609
|
const matches = await driver.matchComponents(options.components, findings);
|
|
1187
1610
|
findings.forEach((finding, i) => {
|
|
@@ -1206,6 +1629,7 @@ async function runAuditGrid(driver, options, motion, helpers = Promise.resolve([
|
|
|
1206
1629
|
contrastFindings: contrast.findings,
|
|
1207
1630
|
contrastChecked: collected.contrastEntries.length,
|
|
1208
1631
|
contrastPassed: contrast.passed,
|
|
1632
|
+
craft,
|
|
1209
1633
|
screenshots: collected.screenshots,
|
|
1210
1634
|
timings: { launchSettleMs: 0, seekLoopMs, contrastMs: collected.contrastMs },
|
|
1211
1635
|
skipped: false
|
|
@@ -1443,7 +1867,7 @@ function buildLintSection(result) {
|
|
|
1443
1867
|
selector: finding.selector ?? (finding.elementId ? `#${finding.elementId}` : "[data-composition-id]"),
|
|
1444
1868
|
dataAttributes: {},
|
|
1445
1869
|
sourceFile: finding.file ?? file,
|
|
1446
|
-
bbox:
|
|
1870
|
+
bbox: ZERO_BBOX2,
|
|
1447
1871
|
time: 0,
|
|
1448
1872
|
fixHint: finding.fixHint
|
|
1449
1873
|
}))
|
|
@@ -1458,10 +1882,12 @@ function buildReport(options, lint, browser, motion, extraMotionFindings, snapsh
|
|
|
1458
1882
|
const runtime = section(browser.runtimeFindings);
|
|
1459
1883
|
const motionSection = section(motionFindings);
|
|
1460
1884
|
const contrastSection = section(browser.contrastFindings);
|
|
1461
|
-
const
|
|
1462
|
-
const
|
|
1885
|
+
const craftSection = section(browser.craft.findings);
|
|
1886
|
+
const warningCount = lint.warningCount + runtime.warningCount + layout.warningCount + motionSection.warningCount + contrastSection.warningCount + craftSection.warningCount;
|
|
1887
|
+
const errorCount = lint.errorCount + runtime.errorCount + layout.errorCount + motionSection.errorCount + contrastSection.errorCount + craftSection.errorCount;
|
|
1888
|
+
const strictWarningCount = warningCount - craftSection.warningCount;
|
|
1463
1889
|
const report = {
|
|
1464
|
-
ok: errorCount === 0 && (!options.strict ||
|
|
1890
|
+
ok: errorCount === 0 && (!options.strict || strictWarningCount === 0),
|
|
1465
1891
|
strict: options.strict,
|
|
1466
1892
|
browserSkipped: browser.skipped,
|
|
1467
1893
|
lint,
|
|
@@ -1480,6 +1906,12 @@ function buildReport(options, lint, browser, motion, extraMotionFindings, snapsh
|
|
|
1480
1906
|
checked: browser.contrastChecked,
|
|
1481
1907
|
passed: browser.contrastPassed
|
|
1482
1908
|
},
|
|
1909
|
+
craft: {
|
|
1910
|
+
...craftSection,
|
|
1911
|
+
enabled: browser.craft.enabled,
|
|
1912
|
+
step: browser.craft.step,
|
|
1913
|
+
samples: browser.craft.samples
|
|
1914
|
+
},
|
|
1483
1915
|
hdr: { autoPromotion: hdrPromotion, inspection: hdrInspection },
|
|
1484
1916
|
snapshots: {
|
|
1485
1917
|
enabled: options.snapshots,
|
|
@@ -1504,6 +1936,7 @@ function buildReport(options, lint, browser, motion, extraMotionFindings, snapsh
|
|
|
1504
1936
|
motionWarnings: motionSection.warningCount,
|
|
1505
1937
|
contrastErrors: contrastSection.errorCount,
|
|
1506
1938
|
contrastWarnings: contrastSection.warningCount,
|
|
1939
|
+
craftWarnings: craftSection.warningCount,
|
|
1507
1940
|
launchSettleMs: browser.timings.launchSettleMs,
|
|
1508
1941
|
seekLoopMs: browser.timings.seekLoopMs,
|
|
1509
1942
|
contrastMs: browser.timings.contrastMs,
|
|
@@ -1525,11 +1958,11 @@ function filterComponentReport(report, options) {
|
|
|
1525
1958
|
notes: [
|
|
1526
1959
|
"Static lint and unscoped runtime failures remain project-wide.",
|
|
1527
1960
|
...options.range ? [
|
|
1528
|
-
"Whole-timeline motion assertions
|
|
1961
|
+
"Whole-timeline motion assertions, frozen-sweep detection and craft warnings are skipped for range checks."
|
|
1529
1962
|
] : []
|
|
1530
1963
|
]
|
|
1531
1964
|
};
|
|
1532
|
-
for (const group of [report.layout, report.motion, report.contrast]) {
|
|
1965
|
+
for (const group of [report.layout, report.motion, report.contrast, report.craft]) {
|
|
1533
1966
|
const before = group.findings.length;
|
|
1534
1967
|
group.findings = group.findings.filter((f) => f.componentMatch !== false);
|
|
1535
1968
|
report.scope.hiddenFindings += before - group.findings.length;
|
|
@@ -1612,6 +2045,7 @@ function emptyBrowserResult() {
|
|
|
1612
2045
|
contrastFindings: [],
|
|
1613
2046
|
contrastChecked: 0,
|
|
1614
2047
|
contrastPassed: 0,
|
|
2048
|
+
craft: disabledCraft(),
|
|
1615
2049
|
screenshots: [],
|
|
1616
2050
|
timings: { launchSettleMs: 0, seekLoopMs: 0, contrastMs: 0 },
|
|
1617
2051
|
skipped: true
|
|
@@ -1633,7 +2067,7 @@ function findingAtRoot(code, severity, message, sourceFile) {
|
|
|
1633
2067
|
selector: "[data-composition-id]",
|
|
1634
2068
|
dataAttributes: {},
|
|
1635
2069
|
sourceFile,
|
|
1636
|
-
bbox:
|
|
2070
|
+
bbox: ZERO_BBOX2,
|
|
1637
2071
|
time: 0
|
|
1638
2072
|
};
|
|
1639
2073
|
}
|
|
@@ -1662,7 +2096,7 @@ function resolveMotionSpec(projectDir) {
|
|
|
1662
2096
|
};
|
|
1663
2097
|
}
|
|
1664
2098
|
async function runBrowserCheck(project, options, motion, deadline, prelaunched) {
|
|
1665
|
-
const module = await import("./checkBrowser-
|
|
2099
|
+
const module = await import("./checkBrowser-5XZCBRXM.js");
|
|
1666
2100
|
return module.runBrowserCheck(project, options, motion, runAuditGrid, deadline, prelaunched);
|
|
1667
2101
|
}
|
|
1668
2102
|
var adoptedBrowser;
|
|
@@ -1676,7 +2110,7 @@ async function prelaunchBrowser(project, options) {
|
|
|
1676
2110
|
if (adopted) return adopted;
|
|
1677
2111
|
const html = await readFile(project.indexPath, "utf8").catch(() => void 0);
|
|
1678
2112
|
if (html === void 0) return void 0;
|
|
1679
|
-
const { prelaunchCompositionBrowser } = await import("./captureCompositionFrame-
|
|
2113
|
+
const { prelaunchCompositionBrowser } = await import("./captureCompositionFrame-PXV2ISHD.js");
|
|
1680
2114
|
return prelaunchCompositionBrowser(html, options.browserGpuMode);
|
|
1681
2115
|
}
|
|
1682
2116
|
async function writeSnapshot(projectDir, index, time, pngBase64) {
|
|
@@ -1688,7 +2122,7 @@ async function writeSnapshot(projectDir, index, time, pngBase64) {
|
|
|
1688
2122
|
return relative(projectDir, path);
|
|
1689
2123
|
}
|
|
1690
2124
|
async function captureFindingCrops(project, options, requests, deadline) {
|
|
1691
|
-
const module = await import("./checkBrowser-
|
|
2125
|
+
const module = await import("./checkBrowser-5XZCBRXM.js");
|
|
1692
2126
|
return module.captureFindingCrops(project, options, requests, deadline);
|
|
1693
2127
|
}
|
|
1694
2128
|
var DEFAULT_DEPENDENCIES2 = {
|
|
@@ -2134,6 +2568,7 @@ function printHumanReport(report) {
|
|
|
2134
2568
|
printLayoutSection("Layout", report.layout);
|
|
2135
2569
|
printSection("Motion", report.motion);
|
|
2136
2570
|
printContrastSection(report);
|
|
2571
|
+
printCraftSection(report);
|
|
2137
2572
|
printSnapshotSection(report);
|
|
2138
2573
|
console.log();
|
|
2139
2574
|
const label = report.ok ? c.success("Check passed") : c.error("Check failed");
|
|
@@ -2192,6 +2627,16 @@ function printContrastSection(report) {
|
|
|
2192
2627
|
}
|
|
2193
2628
|
printCounts(section2);
|
|
2194
2629
|
}
|
|
2630
|
+
function printCraftSection(report) {
|
|
2631
|
+
const section2 = report.craft;
|
|
2632
|
+
if (!section2.enabled) {
|
|
2633
|
+
console.log();
|
|
2634
|
+
console.log(c.bold("Craft"));
|
|
2635
|
+
console.log(` ${c.dim("\u25C7")} skipped`);
|
|
2636
|
+
return;
|
|
2637
|
+
}
|
|
2638
|
+
printSection("Craft", section2);
|
|
2639
|
+
}
|
|
2195
2640
|
function printSnapshotSection(report) {
|
|
2196
2641
|
console.log();
|
|
2197
2642
|
console.log(c.bold("Snapshots"));
|