hyperframes 0.8.143 → 0.8.145
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/{add-Q5EYDUAY.js → add-B6OUH46W.js} +12 -12
- package/dist/{animatedGifPrep-H2DUQEZ3.js → animatedGifPrep-MIWRDJIO.js} +7 -7
- package/dist/{asset-C7JBYYX4.js → asset-XJ2B2PU3.js} +2 -2
- package/dist/{assetCataloger-FRO4G6OU.js → assetCataloger-A5ZLSCMZ.js} +3 -3
- package/dist/{auth-FRWLCO36.js → auth-5HOVCZMV.js} +1 -1
- package/dist/{autoUpdate-E4OZXQK6.js → autoUpdate-WVNL5K3D.js} +2 -2
- package/dist/{backgroundChecks-FSUVHN5L.js → backgroundChecks-IGF54SFH.js} +3 -3
- package/dist/backgroundChecksWorker.js +3 -3
- package/dist/{batchRender-4U73BYTU.js → batchRender-T6JEGCQV.js} +4 -4
- package/dist/{beats-U6KJWF35.js → beats-37T6Y6QP.js} +13 -13
- package/dist/{benchmark-5ONT7V7B.js → benchmark-ZVVLOWPP.js} +9 -9
- package/dist/{browser-R4DU46IE.js → browser-4SSJOLH4.js} +39 -55
- package/dist/{bundleWithLocalizedFonts-VH55VOAL.js → bundleWithLocalizedFonts-XWK423QP.js} +2 -2
- package/dist/{capture-OGQAEYKO.js → capture-2SF7YP57.js} +2 -2
- package/dist/{capture-26G2DPSI.js → capture-KZXOPBMO.js} +18 -18
- package/dist/{catalog-RKORTIUE.js → catalog-NLD4A2C6.js} +12 -12
- package/dist/{catch-up-4OBERRQO.js → catch-up-4BSRN6IR.js} +4 -4
- package/dist/{check-P2XDN57S.js → check-IA44QQWM.js} +66 -55
- package/dist/{checkBrowser-NTGJGAEA.js → checkBrowser-VM35KZMW.js} +81 -30
- package/dist/{chunk-LVX6NK36.js → chunk-3IBMBNYY.js} +1 -1
- package/dist/{chunk-6XMFEICO.js → chunk-3KU3PFDW.js} +77 -92
- package/dist/{chunk-PJU63L6W.js → chunk-4ORLNTET.js} +1 -1
- package/dist/{chunk-DF2BHILQ.js → chunk-4QWD6JYN.js} +3 -3
- package/dist/{chunk-BT27OYYX.js → chunk-5NRXZGKK.js} +18 -12
- package/dist/{chunk-UM2GRYM3.js → chunk-5WVW7P23.js} +3 -3
- package/dist/{chunk-I7QGQAZM.js → chunk-6LGNTUZN.js} +7 -7
- package/dist/{chunk-LAOCA3MQ.js → chunk-A4Q7W4LV.js} +13 -8
- package/dist/{chunk-4PFZPP2N.js → chunk-A6S35NYA.js} +54 -16
- package/dist/{chunk-QRKLPWEX.js → chunk-ADF3X6GM.js} +11 -2
- package/dist/chunk-AUWHD7RA.js +3753 -0
- package/dist/{chunk-W35EKBS6.js → chunk-BFACGEII.js} +2 -2
- package/dist/{chunk-HW4AKJ5F.js → chunk-BIAC7IJT.js} +1 -1
- package/dist/{chunk-ZLW2V65P.js → chunk-BSQ7XANM.js} +3 -2
- package/dist/{chunk-LCSMOLGX.js → chunk-BYSBRF24.js} +69 -8
- package/dist/{chunk-2LBBHMKT.js → chunk-CFUXNBWH.js} +1 -1
- package/dist/{chunk-BFDJ63J5.js → chunk-DDIVWXN7.js} +1 -1
- package/dist/{chunk-KOEWEFHK.js → chunk-DIRJ322I.js} +10 -5
- package/dist/{chunk-FVYXDXEV.js → chunk-DWUKJQTO.js} +2 -2
- package/dist/{chunk-POLR33RB.js → chunk-EPE2HRJK.js} +15 -17
- package/dist/{chunk-UICWP23D.js → chunk-FBCULCAL.js} +3 -3
- package/dist/{chunk-F26LCYRY.js → chunk-FDT6KQV4.js} +142 -81
- package/dist/{chunk-P7THMINS.js → chunk-FXJJCPPB.js} +1 -1
- package/dist/{chunk-BYK73CR7.js → chunk-GBGJ7A3D.js} +5 -5
- package/dist/{sherpa-LVIUEAGF.js → chunk-GEMJYBRU.js} +11 -45
- package/dist/{chunk-KO5QBV73.js → chunk-GMAJB2P6.js} +1 -1
- package/dist/{chunk-KQLGTGE5.js → chunk-GRY3PN3K.js} +2 -2
- package/dist/{chunk-7UYBQ6NF.js → chunk-GXJEGZL2.js} +30 -20
- package/dist/{chunk-KJJLA674.js → chunk-GZVP4TWN.js} +1 -46
- package/dist/{chunk-QVYVUCWD.js → chunk-HB7FJOY4.js} +1 -1
- package/dist/{chunk-QFN7NVWM.js → chunk-ICKDMTLA.js} +1 -1
- package/dist/{chunk-XONFUK3M.js → chunk-IEIJRMLZ.js} +47 -35
- package/dist/{chunk-PAGIICKN.js → chunk-IHTRYDFN.js} +1 -1
- package/dist/chunk-IR35BCLK.js +13 -0
- package/dist/{chunk-KDPYVTEU.js → chunk-KBB4RG6F.js} +6 -1
- package/dist/{chunk-ZQQ3SEIE.js → chunk-KIFHYXPB.js} +99 -31
- package/dist/{chunk-TAMQYQGJ.js → chunk-LAFJSYDL.js} +1 -1
- package/dist/{chunk-U3X3TPBW.js → chunk-MAYCCGMQ.js} +11 -2
- package/dist/{chunk-HC7EVDEL.js → chunk-OB5MJR4W.js} +1 -1
- package/dist/{chunk-N3DQEVSI.js → chunk-OTHDVXOJ.js} +8 -5
- package/dist/{chunk-Y6QL2LGO.js → chunk-PLR7Z6TC.js} +1 -1
- package/dist/{chunk-OBXQRJWQ.js → chunk-QATWIE4K.js} +1 -1
- package/dist/{chunk-HLYOEIWM.js → chunk-QLSM7K5S.js} +2 -2
- package/dist/{chunk-LW6HO6U3.js → chunk-R42WWQVB.js} +1 -1
- package/dist/{chunk-HMT2RPZU.js → chunk-U5QY7KTN.js} +13 -9
- package/dist/chunk-UPFUC4DB.js +136 -0
- package/dist/{chunk-33RZPZ4K.js → chunk-UXO2L7HJ.js} +366 -156
- package/dist/{chunk-GNBGPUJ7.js → chunk-VHFEMFYL.js} +3 -3
- package/dist/{chunk-4M4EC7JX.js → chunk-VRW6EBHV.js} +12 -1
- package/dist/{chunk-VIVBA6E6.js → chunk-XBX4QJP7.js} +1 -1
- package/dist/{chunk-CLOH4LIB.js → chunk-XIHCMVMG.js} +2 -2
- package/dist/{chunk-TVCRUG2S.js → chunk-ZEUONDQG.js} +1 -1
- package/dist/{chunk-OSSHSIMD.js → chunk-ZF7SXQJ7.js} +1 -1
- package/dist/{chunk-5FISWJ37.js → chunk-ZIYZ77MR.js} +4 -4
- package/dist/{chunk-3NE7ZYU2.js → chunk-ZSVUAVMT.js} +3 -3
- package/dist/{clean-YHGPY33K.js → clean-RDKJB5FK.js} +18 -18
- package/dist/cli.js +68 -56
- package/dist/{cloud-DOFI5ISR.js → cloud-QVPVVNCW.js} +4 -4
- package/dist/{cloudrun-KTZ4XDHL.js → cloudrun-3RE2UCQG.js} +4 -4
- package/dist/{compare-SMMIZN2C.js → compare-LEDOY7MO.js} +25 -25
- package/dist/{compiler-TEXQWW6N.js → compiler-F54OZZPM.js} +10 -4
- package/dist/{component-B3GCNGSS.js → component-N42M67WY.js} +3 -3
- package/dist/{compositions-OQNZZTKF.js → compositions-VB2J2LZI.js} +11 -11
- package/dist/{delete-EL5LVSEP.js → delete-Q6RWMJ4Z.js} +2 -2
- package/dist/{dist-5UVIRMSM.js → dist-KDJTFJHA.js} +2 -2
- package/dist/{dist-XN234YFQ.js → dist-Q4BI5A73.js} +4 -4
- package/dist/{doctor-UOL3OI2A.js → doctor-JMMUHDRV.js} +13 -13
- package/dist/{events-K2DB2PBC.js → events-6ZBSIBE5.js} +2 -2
- package/dist/{events-NIZBS6S7.js → events-RGUAHIBW.js} +3 -3
- package/dist/{feedback-QMP4E6L7.js → feedback-FIID6MZW.js} +9 -9
- package/dist/{ffmpeg-QIUFEFTY.js → ffmpeg-T5SH2EFJ.js} +3 -2
- package/dist/{figma-2AUJRNVC.js → figma-BL3JJC36.js} +3 -3
- package/dist/fontLocalizeCli.js +9 -9
- package/dist/{get-P5NC7SRM.js → get-P46GS7S6.js} +2 -2
- package/dist/{gpuPolicy-7N5MCE2G.js → gpuPolicy-AQ2BPLBK.js} +11 -9
- package/dist/{grade-compare-HV5AFZ6P.js → grade-compare-GDCWU7ZZ.js} +27 -27
- package/dist/{help-3TSTXBLN.js → help-HJR3RWFG.js} +2 -2
- package/dist/{history-D65XFJ6D.js → history-GGO5AWJB.js} +5 -5
- package/dist/hyperframe-runtime.js +59 -59
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +59 -59
- package/dist/hyperframes-player.global.js +3 -3
- package/dist/{info-TXV7MLFO.js → info-3GFWUBJC.js} +8 -8
- package/dist/{init-OSDMJZJV.js → init-36OPU2ZG.js} +35 -36
- package/dist/{inspect-RQQSAYIJ.js → inspect-F2HEL5ON.js} +26 -26
- package/dist/{installer-CDOB32HE.js → installer-NI6P6GC4.js} +5 -5
- package/dist/{keyframes-V75Q6GRM.js → keyframes-7OY3LMAZ.js} +6 -6
- package/dist/{lambda-RODV4RCX.js → lambda-6GJIWNJ3.js} +5 -5
- package/dist/{layout-IZAI5SFC.js → layout-FTMLNL5A.js} +26 -26
- package/dist/{lint-PLXOXY5R.js → lint-U6POHUON.js} +8 -8
- package/dist/{lintProject-OQ6H6XBR.js → lintProject-UBZ3TDHU.js} +2 -2
- package/dist/{list-BQBPNKDZ.js → list-IP5KI5Q2.js} +2 -2
- package/dist/{login-NP6F4FHC.js → login-4VWTVPHG.js} +4 -4
- package/dist/{manager-CT3D67CG.js → manager-BPSR6D3V.js} +2 -2
- package/dist/{manager-GXYF4AVO.js → manager-YKMHR6LN.js} +8 -5
- package/dist/{media-treatment-PXGMZ4A4.js → media-treatment-XGV44AGV.js} +16 -13
- package/dist/{models-CEZM6XZ7.js → models-UCXB6UR5.js} +59 -19
- package/dist/{motionShot-R4GHYWYM.js → motionShot-WPVNBXKA.js} +21 -22
- package/dist/{normalize-H6KUHHEI.js → normalize-U3SL5VG3.js} +2 -2
- package/dist/{normalize-audio-MQ7NFCOV.js → normalize-audio-TYJ3UEHO.js} +6 -6
- package/dist/{open-AKQTGNXF.js → open-HENOLVB2.js} +4 -4
- package/dist/parakeetRunner-VFQ6WFTD.js +67 -0
- package/dist/{pipeline-SYJYP2RM.js → pipeline-6WPSC3H4.js} +10 -9
- package/dist/{play-NBH4B7PL.js → play-OI53WNUM.js} +19 -19
- package/dist/{preflight-Y5DN5D37.js → preflight-B4AFK3RG.js} +4 -4
- package/dist/{present-XAX55CFS.js → present-NGMEQ4NO.js} +15 -15
- package/dist/{preview-OLANKNFA.js → preview-VT2HWRWZ.js} +19 -19
- package/dist/{producer-Q6YNZZUJ.js → producer-7TYEAUF7.js} +1 -1
- package/dist/{projectConfig-EM26P45P.js → projectConfig-B2AF5DXY.js} +7 -7
- package/dist/{publication-OXWJZKSX.js → publication-2PANQVC6.js} +3 -3
- package/dist/{publish-4VBWP2UB.js → publish-O5OL42BG.js} +11 -11
- package/dist/{remove-background-REB7427G.js → remove-background-T2JM6UVP.js} +11 -10
- package/dist/{render-K25YOG3M.js → render-OLPKOJRU.js} +11 -11
- package/dist/{render-3CVZ2SZG.js → render-W7OFXDOJ.js} +4 -4
- package/dist/{render-TSE75QUL.js → render-Z253WHBK.js} +26 -26
- package/dist/{render-batch-GGUOK3DS.js → render-batch-46IIBFKL.js} +4 -4
- package/dist/{renderCancellation-PZRWB53I.js → renderCancellation-QTZOCDJ2.js} +10 -9
- package/dist/renderSetupWorker.js +32 -44
- package/dist/{resolver-S5VK6UCB.js → resolver-J2PL5FVJ.js} +5 -5
- package/dist/sherpa-ZF42V3RN.js +75 -0
- package/dist/sherpaWorker.js +2 -1
- package/dist/skills/hyperframes/scripts/lib/frame-packets-core.mjs +2 -20
- package/dist/skills/hyperframes/scripts/lib/main-module.mjs +13 -0
- package/dist/skills/hyperframes/scripts/lib/main-module.test.mjs +51 -0
- package/dist/skills/hyperframes/scripts/plugin-cli.mjs +4 -3
- package/dist/skills/hyperframes/scripts/plugin-cli.test.mjs +5 -1
- package/dist/skills/hyperframes-cli/SKILL.md +2 -0
- package/dist/skills/hyperframes-cli/references/lint-validate-inspect.md +1 -1
- package/dist/skills/media-use/audio/scripts/heygen-voice.mjs +2 -2
- package/dist/skills/media-use/audio/scripts/lib/main-module.mjs +13 -0
- package/dist/skills/media-use/scripts/lib/cube-validate.mjs +2 -3
- package/dist/skills/media-use/scripts/lib/main-module.mjs +13 -0
- package/dist/{skills-I65FU5HD.js → skills-ACDOO3PX.js} +7 -7
- package/dist/{skillsUpdateCheck-J57RNNIV.js → skillsUpdateCheck-L5OXVVPU.js} +3 -3
- package/dist/{snapshot-YROOGY22.js → snapshot-UUVNZOW5.js} +28 -28
- package/dist/{src-JO5JOV7Y.js → src-BSLKXEGX.js} +10 -6
- package/dist/{src-X426BZAG.js → src-KS3AWFGT.js} +8 -8
- package/dist/{staticProjectServer-5VMBS262.js → staticProjectServer-2TTVGPQH.js} +15 -15
- package/dist/studio/assets/{hyperframes-player-BXSuksFh.js → hyperframes-player-DZ5JrMDg.js} +3 -3
- package/dist/studio/assets/{index-FgyO_5Kv.js → index-BOs6C0aZ.js} +1 -1
- package/dist/studio/assets/{index-BgOVCqjo.js → index-BqFRhNZa.js} +1 -1
- package/dist/studio/assets/{index-J7jpL4pj.js → index-D8W0a0Z9.js} +149 -149
- package/dist/studio/{chunk-TFLU2MGI.js → chunk-6JY3MTIX.js} +108 -2
- package/dist/studio/{chunk-H2DUOXTF.js → chunk-NZPJUZKT.js} +100 -4
- package/dist/studio/{chunk-UYWON5AX.js → chunk-TP6D3U37.js} +7 -100
- package/dist/studio/{chunk-LOVBLSMR.js → chunk-Y2OHHNM2.js} +35 -19
- package/dist/studio/{domEditingLayers-KBTPQKGA.js → domEditingLayers-PTP2ICGM.js} +3 -3
- package/dist/studio/index.d.ts +8 -5
- package/dist/studio/index.html +1 -1
- package/dist/studio/index.js +545 -495
- package/dist/studio/player.js +3 -3
- package/dist/studio/ui.d.ts +4 -5
- package/dist/studio/ui.js +1 -1
- package/dist/{studio-api-VRBZUGAE.js → studio-api-WYWF7XRC.js} +9 -9
- package/dist/{studioServer-DBNKZ6I6.js → studioServer-3FG4YTP7.js} +72 -54
- package/dist/{telemetry-CXAX3TO3.js → telemetry-PAOOB4T4.js} +3 -3
- package/dist/{timeline-VQ34WH7J.js → timeline-JIIJKKPC.js} +69 -47
- package/dist/{tokens-62R7VFAZ.js → tokens-3QRAM75Z.js} +2 -2
- package/dist/{transcribe-XOHPPL2O.js → transcribe-QSBP5MUG.js} +115 -51
- package/dist/{transcribe-7KR7IPJA.js → transcribe-SZB6UMXE.js} +14 -12
- package/dist/{tts-MUV42JXT.js → tts-B6AHFQEO.js} +1 -1
- package/dist/{updateCheck-POYNH3B5.js → updateCheck-V3DSB26K.js} +2 -2
- package/dist/{upgrade-NBNOT7J2.js → upgrade-L5GISOEV.js} +2 -2
- package/dist/{urlDownloader-3NS63A7B.js → urlDownloader-52FERT4X.js} +6 -6
- package/dist/{validate-Y2QDHAEP.js → validate-HVVLX7KO.js} +20 -20
- package/dist/{video-SJDMTSTL.js → video-MEOWRMFG.js} +7 -7
- package/package.json +1 -1
- package/dist/chunk-6TPZSTCL.js +0 -3681
- package/dist/studio/chunk-EEXSYY5F.js.map +0 -1
- package/dist/studio/chunk-H2DUOXTF.js.map +0 -1
- package/dist/studio/chunk-LOVBLSMR.js.map +0 -1
- package/dist/studio/chunk-PZ5AY32C.js.map +0 -1
- package/dist/studio/chunk-TFLU2MGI.js.map +0 -1
- package/dist/studio/chunk-UYWON5AX.js.map +0 -1
- package/dist/studio/domEditingLayers-KBTPQKGA.js.map +0 -1
- package/dist/studio/index.css.map +0 -1
- package/dist/studio/index.js.map +0 -1
- package/dist/studio/player.js.map +0 -1
- package/dist/studio/styles/tailwind-preset.js.map +0 -1
- package/dist/studio/ui.js.map +0 -1
- package/dist/{screenshotCapture-TEUIWXWN.js → screenshotCapture-3JXXUZND.js} +3 -3
- package/dist/{synthesize-C3IWDAXF.js → synthesize-UCI4X5O7.js} +4 -4
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/ui/HyperframesLogo.tsx"],"sourcesContent":["export function HyperframesLogo() {\n // Full logo from logo-dark.svg (263×79): heygen label + gradient mark + hyperframes wordmark.\n // The wordmark paths take the text colour, so the logo reads in both themes.\n const height = 28;\n const width = Math.round(height * (263 / 79));\n return (\n <svg\n width={width}\n height={height}\n viewBox=\"0 0 263 79\"\n fill=\"none\"\n className=\"text-text-0\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-label=\"Hyperframes\"\n >\n <defs>\n <linearGradient\n id=\"hf-g0\"\n x1=\"225.869\"\n y1=\"0\"\n x2=\"222.845\"\n y2=\"37.482\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"var(--color-brand-gradient-from)\" />\n <stop offset=\"1\" stopColor=\"var(--color-brand-gradient-to)\" />\n </linearGradient>\n <linearGradient\n id=\"hf-g1\"\n x1=\"230.87\"\n y1=\"39\"\n x2=\"244.661\"\n y2=\"6.303\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"var(--color-brand-gradient-from)\" />\n <stop offset=\"1\" stopColor=\"var(--color-brand-gradient-to)\" />\n </linearGradient>\n </defs>\n {/* heygen label */}\n <path\n d=\"M0 16.6738H4.96V23.3838H11.53V16.6738H16.49V35.4538H11.53V27.6738H4.96V35.4538H0V16.6738Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M17.8899 28.0137C17.8899 23.4237 21.2399 20.0237 25.7999 20.0237C30.0099 20.0237 32.9399 23.0837 32.9399 27.5637C32.9399 28.2037 32.8599 28.8237 32.8299 29.3337H22.6099C23.0399 31.1337 24.6199 32.1237 27.1399 32.1237C28.7199 32.1237 30.2199 31.7237 31.2999 31.0237V34.6737C30.1699 35.3937 28.2999 35.8537 26.3599 35.8537C21.2599 35.8537 17.8799 32.6037 17.8799 28.0237L17.8899 28.0137ZM28.5699 26.1937C28.4899 24.5337 27.3899 23.5637 25.7499 23.5637C24.1099 23.5637 22.9599 24.5337 22.6099 26.1937H28.5699Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M37.85 33.8638L32 20.4238H37.29L40.46 28.1538L43.6 20.4238H48.48L40.33 39.5738H35.26L37.86 33.8638H37.85Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M48.1797 26.1138C48.1797 20.4238 52.7097 16.2438 58.9397 16.2438C61.2997 16.2438 63.5297 16.8038 64.8197 17.7238V21.9338C63.5597 20.9138 61.6797 20.2938 59.7497 20.2938C55.7797 20.2938 53.2597 22.6238 53.2597 26.1438C53.2597 29.6638 55.5697 31.8838 58.8897 31.8838C59.6397 31.8838 60.4997 31.7538 61.1997 31.5038V27.8838H57.4697V24.2338H65.5197V33.7038C63.6697 35.0938 61.1997 35.8738 58.5997 35.8738C52.5397 35.8738 48.1897 31.7438 48.1897 26.1138H48.1797Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M66.6604 28.0137C66.6604 23.4237 70.0104 20.0237 74.5704 20.0237C78.7804 20.0237 81.7104 23.0837 81.7104 27.5637C81.7104 28.2037 81.6304 28.8237 81.6004 29.3337H71.3804C71.8104 31.1337 73.3904 32.1237 75.9104 32.1237C77.4904 32.1237 78.9904 31.7237 80.0704 31.0237V34.6737C78.9404 35.3937 77.0704 35.8537 75.1304 35.8537C70.0304 35.8537 66.6504 32.6037 66.6504 28.0237L66.6604 28.0137ZM77.3404 26.1937C77.2604 24.5337 76.1604 23.5637 74.5204 23.5637C72.8804 23.5637 71.7304 24.5337 71.3804 26.1937H77.3404Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M82.9688 20.4238H87.8488V22.4138C88.7588 20.9638 90.3488 20.1038 92.3288 20.1038C95.4988 20.1038 97.3988 22.3338 97.3988 25.8138V35.4438H92.5188V26.8638C92.5188 25.0438 91.8188 24.1838 90.4788 24.1838C88.9488 24.1838 87.8488 25.3638 87.8488 27.2638V35.4438H82.9688V20.4238Z\"\n fill=\"currentColor\"\n />\n {/* gradient icon mark */}\n <path\n d=\"M195.219 26.1937L213.529 38.9937C216.009 40.7237 220.239 38.7637 221.009 35.5337L228.419 4.33374C229.189 1.10374 225.879 -0.856262 222.589 0.873738L198.199 13.6737C192.649 16.5837 191.059 23.2837 195.219 26.1937Z\"\n fill=\"url(#hf-g0)\"\n />\n <path\n d=\"M256.97 25.9638L232.58 38.7638C229.28 40.4938 225.98 38.5338 226.75 35.3038L234.16 4.10376C234.93 0.873757 239.16 -1.08624 241.64 0.643757L259.95 13.4438C264.12 16.3538 262.52 23.0538 256.97 25.9638Z\"\n fill=\"url(#hf-g1)\"\n />\n {/* hyperframes wordmark */}\n <path\n d=\"M0 71.9996V42.7256H7.7367V53.1806H17.9826V42.7256H25.7193V71.9996H17.9826V59.8718H7.7367V71.9996H0Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M31.9606 78.4405L36.0171 69.5329L26.9004 48.5811H35.1389L40.0737 60.6252L44.9666 48.5811H52.5779L39.8646 78.4405H31.9606Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M53.3711 78.4404V48.5809H60.9823V52.052C62.446 49.501 65.0807 48.0791 68.3008 48.0791C74.3647 48.0791 78.9649 53.3066 78.9649 60.2487C78.9649 67.2745 74.3229 72.4602 68.259 72.4602C65.0807 72.4602 62.446 71.1637 60.9823 68.78V78.4404H53.3711ZM66.1262 66.1872C69.2627 66.1872 71.3119 63.7616 71.3119 60.2905C71.3119 56.8195 69.2627 54.4357 66.1262 54.4357C62.7388 54.4357 60.9823 57.2795 60.9823 59.7051V60.9178C60.9823 63.3434 62.7388 66.1872 66.1262 66.1872Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M93.4397 72.6269C85.4939 72.6269 80.2246 67.5667 80.2246 60.4155C80.2246 53.2643 85.4521 47.9531 92.5615 47.9531C99.1273 47.9531 103.686 52.7206 103.686 59.7045C103.686 60.7082 103.56 61.6701 103.518 62.4647H87.5849C88.2541 65.2666 90.7214 66.8139 94.6525 66.8139C97.1199 66.8139 99.4618 66.1866 101.135 65.0993V70.7868C99.3782 71.916 96.4508 72.6269 93.4397 72.6269ZM87.5849 57.5717H96.869C96.7435 54.9789 95.0289 53.4734 92.4779 53.4734C89.9687 53.4734 88.1286 54.9789 87.5849 57.5717Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M105.645 72V48.5808H113.214V52.9719C114.218 50.0445 116.183 48.2881 118.692 48.2881C119.361 48.2881 119.989 48.4135 120.407 48.6645V55.8993C119.822 55.5648 119.111 55.4393 118.274 55.4393C115.138 55.4393 113.256 57.6558 113.256 61.2941V72H105.645Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M122.643 71.9996V42.7256H139.371V49.124H130.379V54.477H138.911V60.5827H130.379V71.9996H122.643Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M141.258 72V48.5808H148.827V52.9719C149.831 50.0445 151.796 48.2881 154.306 48.2881C154.975 48.2881 155.602 48.4135 156.02 48.6645V55.8993C155.435 55.5648 154.724 55.4393 153.887 55.4393C150.751 55.4393 148.869 57.6558 148.869 61.2941V72H141.258Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M167.26 72.4602C161.154 72.4602 156.596 67.2745 156.596 60.3324C156.596 53.3066 161.196 48.0791 167.302 48.0791C170.438 48.0791 173.031 49.4173 174.536 51.8429V48.5809H182.148V72.0001H174.536V68.4873C173.031 71.0801 170.438 72.4602 167.26 72.4602ZM169.393 66.1872C172.78 66.1872 174.536 63.3434 174.536 60.876V59.6632C174.536 57.2377 172.78 54.4357 169.393 54.4357C166.298 54.4357 164.207 56.7777 164.207 60.2905C164.207 63.7616 166.298 66.1872 169.393 66.1872Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M184.998 72.0001V48.5809H192.609V51.6756C193.989 49.4173 196.373 48.0791 199.426 48.0791C202.521 48.0791 204.779 49.5428 206.075 52.052C207.497 49.5846 210.132 48.0791 213.352 48.0791C218.245 48.0791 221.214 51.592 221.214 57.0286V72.0001H213.603V58.5341C213.603 55.774 212.557 54.4357 210.634 54.4357C208.459 54.4357 206.912 56.234 206.912 59.0778V72.0001H199.3V58.5341C199.3 55.774 198.255 54.4357 196.373 54.4357C194.157 54.4357 192.609 56.234 192.609 59.0778V72.0001H184.998Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M236.338 72.6269C228.392 72.6269 223.123 67.5667 223.123 60.4155C223.123 53.2643 228.351 47.9531 235.46 47.9531C242.026 47.9531 246.584 52.7206 246.584 59.7045C246.584 60.7082 246.459 61.6701 246.417 62.4647H230.483C231.152 65.2666 233.62 66.8139 237.551 66.8139C240.018 66.8139 242.36 66.1866 244.033 65.0993V70.7868C242.277 71.916 239.349 72.6269 236.338 72.6269ZM230.483 57.5717H239.767C239.642 54.9789 237.927 53.4734 235.376 53.4734C232.867 53.4734 231.027 54.9789 230.483 57.5717Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M252.115 72.502C250.192 72.502 248.268 72.0838 246.93 71.3728V65.6853C247.808 66.3126 248.937 66.689 250.066 66.689C251.739 66.689 252.784 65.8526 252.784 64.5562C252.784 63.8452 252.492 63.0925 251.655 62.0888L249.899 59.956C248.728 58.4923 248.226 56.9031 248.226 55.2721C248.226 51.0065 251.864 48.0791 256.883 48.0791C258.723 48.0791 260.438 48.4555 261.65 49.0828V54.7703C260.898 54.2266 259.768 53.8503 258.723 53.8503C257.092 53.8503 256.046 54.6867 256.046 55.8994C256.046 56.6522 256.423 57.405 257.259 58.4086L258.974 60.4996C260.187 62.047 260.73 63.5943 260.73 65.2671C260.73 69.5746 257.05 72.502 252.115 72.502Z\"\n fill=\"currentColor\"\n />\n </svg>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/player/lib/time.ts","../src/player/store/liveTime.ts","../src/player/store/playerStore.ts","../src/player/store/playerStoreDevHandle.ts","../src/player/store/playerStoreSelection.ts","../src/components/dock/panelRegistry.ts","../src/components/dock/dockLayoutSchema.ts","../src/utils/studioUiPreferences.ts","../src/player/components/timelineZoom.ts","../src/player/store/keyframeSlice.ts","../src/player/store/automationSelectionSlice.ts","../src/player/store/editingModeSlice.ts","../src/player/store/timelineFocusState.ts","../src/player/lib/thumbnailPolicy.ts","../src/player/store/thumbnailSlice.ts","../src/player/store/readinessSlice.ts","../src/player/store/rangeSelectionSlice.ts","../src/player/store/timelineResetState.ts","../src/player/store/elementPatchQueue.ts","../src/player/components/Player.tsx","../src/hooks/useMountEffect.ts","../src/hooks/previewVariablesStore.ts"],"sourcesContent":["export const STUDIO_PREVIEW_FPS = 30;\n\nexport const clampToDuration = (time: number, duration: number) =>\n Math.max(0, duration > 0 ? Math.min(duration, time) : time);\n\nexport function formatTime(time: number): string {\n if (!Number.isFinite(time) || time < 0) return \"00:00\";\n const mins = Math.floor(time / 60);\n const secs = Math.floor(time % 60);\n // Zero-pad minutes as well as seconds so every readout is a stable-width\n // MM:SS (e.g. \"00:44\", not \"0:44\"). Minutes past 99 keep their extra digits\n // (\"120:00\"); an hours-style H:MM:SS grouping is applied by callers that need\n // it (see formatTimelineTickLabel), never here.\n return `${mins.toString().padStart(2, \"0\")}:${secs.toString().padStart(2, \"0\")}`;\n}\n\nexport function secondsToFrame(time: number, fps = STUDIO_PREVIEW_FPS): number {\n if (!Number.isFinite(time) || time <= 0) return 0;\n if (!Number.isFinite(fps) || fps <= 0) return 0;\n return Math.round(time * fps);\n}\n\nexport function frameToSeconds(frame: number, fps = STUDIO_PREVIEW_FPS): number {\n if (!Number.isFinite(frame) || frame <= 0) return 0;\n if (!Number.isFinite(fps) || fps <= 0) return 0;\n return frame / fps;\n}\n\nexport function stepFrameTime(time: number, deltaFrames: number, fps = STUDIO_PREVIEW_FPS): number {\n const currentFrame = secondsToFrame(time, fps);\n const nextFrame = Math.max(0, currentFrame + deltaFrames);\n return frameToSeconds(nextFrame, fps);\n}\n\nexport function formatFrameTime(time: number, duration: number, fps = STUDIO_PREVIEW_FPS): string {\n const currentFrame = secondsToFrame(time, fps);\n const totalFrames = secondsToFrame(duration, fps);\n return `${currentFrame}f / ${totalFrames}f`;\n}\n","// ponytail: Playback RAF updates the playhead/time display without per-frame React renders.\ntype TimeListener = (time: number) => void;\nconst timeListeners = new Set<TimeListener>();\nlet latestTime = 0;\nlet seekCount = 0;\n\nexport const liveTime = {\n notify: (time: number) => {\n latestTime = time;\n timeListeners.forEach((listener) => listener(time));\n },\n notifySeek: (time: number) => {\n seekCount += 1;\n liveTime.notify(time);\n },\n seekCount: () => seekCount,\n latest: () => latestTime,\n subscribe: (listener: TimeListener) => {\n timeListeners.add(listener);\n return () => timeListeners.delete(listener);\n },\n};\n","import { create } from \"zustand\";\nimport { attachPlayerStoreDevHandle } from \"./playerStoreDevHandle\";\nimport { nextSelectionSet, revealTargetsSelection } from \"./playerStoreSelection\";\nimport type { MusicBeatAnalysis } from \"@hyperframes/core/beats\";\nimport type { BeatEditState } from \"../../utils/beatEditing\";\nimport type { ClipManifestClip } from \"../lib/playbackTypes\";\nimport {\n readStudioUiPreferences,\n writeStudioUiPreferences,\n type TimelineTimeDisplayMode,\n} from \"../../utils/studioUiPreferences\";\nimport { clampTimelineZoomPercent, computePinnedZoomPercent } from \"../components/timelineZoom\";\nimport { createKeyframeSlice, type KeyframeSlice } from \"./keyframeSlice\";\nimport {\n createAutomationSelectionSlice,\n type AutomationSelectionSlice,\n} from \"./automationSelectionSlice\";\nimport { createEditingModeSlice, type EditingModeSlice } from \"./editingModeSlice\";\nimport { createTimelineFocusRequest, type TimelineFocusRequest } from \"./timelineFocusState\";\nimport { createThumbnailSlice, type ThumbnailSlice } from \"./thumbnailSlice\";\nimport { createPlaybackReadinessSlice } from \"./readinessSlice\";\nimport { createRangeSelectionSlice, type RangeSelectionSlice } from \"./rangeSelectionSlice\";\nimport { createTimelineResetState } from \"./timelineResetState\";\nimport { patchElements, queueElementPatch } from \"./elementPatchQueue\";\nexport type { KeyframeCacheEntry } from \"./keyframeSlice\";\nexport { liveTime } from \"./liveTime\";\nimport { liveTime } from \"./liveTime\";\nexport { createTimelineResetState };\n\nimport type {\n TimelineElement,\n TimelineElementPatch,\n SubCompositionHostState,\n} from \"./timelineElement\";\n\nexport type { TimelineElement, SubCompositionHostState };\nexport type ZoomMode = \"fit\" | \"manual\";\ntype TimelineTool = \"select\" | \"razor\";\n\nexport interface SelectElementOptions {\n preserveSet?: boolean;\n}\n\nfunction resolveElementSelection(\n ids: Iterable<string>,\n anchor?: string | null,\n): { selectedElementIds: Set<string>; selectedElementId: string | null } {\n const selectedElementIds = new Set(ids);\n if (selectedElementIds.size === 0) {\n return { selectedElementIds, selectedElementId: null };\n }\n if (anchor && selectedElementIds.has(anchor)) {\n return { selectedElementIds, selectedElementId: anchor };\n }\n return {\n selectedElementIds,\n selectedElementId: selectedElementIds.values().next().value ?? null,\n };\n}\n\ntype PlayerStoreSlices = KeyframeSlice &\n AutomationSelectionSlice &\n ThumbnailSlice &\n EditingModeSlice &\n ReturnType<typeof createPlaybackReadinessSlice> &\n RangeSelectionSlice;\ninterface PlayerState extends PlayerStoreSlices {\n isPlaying: boolean;\n currentTime: number;\n duration: number;\n /** Increments exactly once when the Studio switches to a different project. */\n timelineSessionEpoch: number;\n /** Project owning the current timeline session; null outside a project-scoped reset. */\n timelineProjectId: string | null;\n /** True while a beat dot is being dragged — hides the playhead guideline. */\n beatDragging: boolean;\n elements: TimelineElement[];\n selectedElementId: string | null;\n playbackRate: number;\n audioMuted: boolean;\n audioVolume: number;\n loopEnabled: boolean;\n /** Timeline zoom: 'fit' auto-scales to viewport, 'manual' uses manualZoomPercent */\n zoomMode: ZoomMode;\n /** Timeline zoom percent relative to the fit width when in manual mode */\n manualZoomPercent: number;\n userZoomCount: number;\n /**\n * Bumped on every live z-index edit (handleDomZIndexReorderCommit apply AND\n * rollback). Flashless z commits (skipReload) never reload the iframe or\n * bump refreshKey, so DOM-derived views (the Layers panel's z-sorted tree)\n * subscribe to this to re-read the live DOM while playback is paused.\n */\n zEditVersion: number;\n /** Work-area in-point (seconds). When set, loop starts here and A jumps here. */\n inPoint: number | null;\n /** Work-area out-point (seconds). When set, loop ends here and E jumps here. */\n outPoint: number | null;\n\n activeTool: TimelineTool;\n setActiveTool: (tool: TimelineTool) => void;\n selectLeftward: () => void;\n selectRightward: () => void;\n\n /** Tween-relative percentage of the last-clicked keyframe diamond. Operations\n * (drag, resize, rotate) target this instead of recomputing from playhead. */\n activeKeyframePct: number | null;\n setActiveKeyframePct: (pct: number | null) => void;\n\n /** Multi-select: additional selected elements beyond selectedElementId. */\n selectedElementIds: Set<string>;\n clearSelectedElementIds: () => void;\n /** Replace the whole multi-selection at once (marquee live updates). */\n setSelectedElementIds: (ids: Set<string>) => void;\n /** Timeline magnet toggle — when false, clip drags/trims/drops never snap. */\n timelineSnapEnabled: boolean;\n setTimelineSnapEnabled: (enabled: boolean) => void;\n /** Keeps the main track gapless on delete; distinct from the magnet above. */\n rippleEditEnabled: boolean;\n setRippleEditEnabled: (enabled: boolean) => void;\n /** Transport + ruler readout: timecode (\"time\") or frame number (\"frame\"). */\n timeDisplayMode: TimelineTimeDisplayMode;\n setTimeDisplayMode: (mode: TimelineTimeDisplayMode) => void;\n /** Pin the timeline zoom to its current scale before a duration change, so\n * it stops rescaling every clip. No-op once already pinned. */\n pinTimelineZoom: (currentPixelsPerSecond: number, fitPixelsPerSecond: number) => void;\n /** The timeline's live pixels-per-second + fit basis, published by <Timeline>. */\n timelinePps: number;\n timelineFitPps: number;\n setTimelineScale: (pps: number, fitPps: number) => void;\n setSelection: (ids: Iterable<string>, anchor?: string | null) => void;\n addSelectedElementId: (id: string) => void;\n toggleSelectedElementId: (id: string) => void;\n clearSelection: () => void;\n\n setIsPlaying: (playing: boolean) => void;\n setCurrentTime: (time: number) => void;\n setDuration: (duration: number) => void;\n setPlaybackRate: (rate: number) => void;\n setAudioMuted: (muted: boolean) => void;\n setAudioVolume: (volume: number) => void;\n setLoopEnabled: (enabled: boolean) => void;\n setBeatDragging: (dragging: boolean) => void;\n setElements: (elements: TimelineElement[]) => void;\n setSelectedElementId: (id: string | null, options?: SelectElementOptions) => void;\n /** Move the selection anchor within an active multi-selection without collapsing it. */\n setSelectionAnchor: (id: string | null) => void;\n updateElement: (elementId: string, updates: TimelineElementPatch) => void;\n setZoomMode: (mode: ZoomMode) => void;\n setManualZoomPercent: (percent: number) => void;\n bumpZEditVersion: () => void;\n setInPoint: (time: number | null) => void;\n setOutPoint: (time: number | null) => void;\n /** Owns the hard project boundary; repeated calls for one project are no-ops. */\n beginTimelineSession: (projectId: string) => void;\n /** Clears project data without creating a new hard-project session. */\n reset: () => void;\n\n /** Request a seek from outside the player loop (e.g. Layers panel);\n * useTimelinePlayer subscribes and calls adapter.seek() + liveTime.notify(). */\n requestedSeekTime: number | null;\n requestSeek: (time: number) => void;\n clearSeekRequest: () => void;\n\n /** Request the transport start or stop from outside the player loop: the FX\n * rack starts playback to audition a preset (silent while paused) and\n * restores the playhead on leave, without costing the author their place.\n * A nonce, not a bare boolean, so two hovers in a row both register. */\n playbackRequest: { playing: boolean; returnTo: number | null; nonce: number } | null;\n requestPlayback: (playing: boolean, returnTo?: number | null) => void;\n clearPlaybackRequest: () => void;\n\n /**\n * Request the timeline to scroll a clip into view (e.g. clicking an\n * already-added asset card in the sidebar). Consumed and cleared by\n * useTimelineRevealClip. The nonce makes repeat requests for the same\n * clip observable so a second click re-reveals after the user scrolls away.\n */\n clipRevealRequest: { elementId: string; nonce: number } | null;\n requestClipReveal: (elementId: string) => void;\n clearClipRevealRequest: () => void;\n\n timelineFocus: TimelineFocusRequest | null;\n timelineFocusNonce: number;\n requestTimelineFocus: (id: string) => void;\n clearTimelineFocus: (nonce: number) => void;\n\n lintFindingsByElement: Map<string, { count: number; messages: string[] }>;\n setLintFindingsByElement: (map: Map<string, { count: number; messages: string[] }>) => void;\n\n beatAnalysis: MusicBeatAnalysis | null;\n setBeatAnalysis: (analysis: MusicBeatAnalysis | null) => void;\n\n /** User edits (add/move/delete) layered over the detected beat grid. */\n beatEdits: BeatEditState | null;\n setBeatEdits: (edits: BeatEditState | null) => void;\n /** Undo/redo stacks for beat edits (in-memory, session-only). */\n beatUndo: BeatHistoryEntry[];\n beatRedo: BeatHistoryEntry[];\n commitBeatEdits: (next: BeatEditState | null, label: string) => void;\n undoBeatEdits: () => string | null;\n redoBeatEdits: () => string | null;\n resetBeatHistory: () => void;\n beatPersist: (() => void) | null;\n setBeatPersist: (fn: (() => void) | null) => void;\n\n clipManifest: ClipManifestClip[] | null;\n setClipManifest: (clips: ClipManifestClip[] | null) => void;\n clipParentMap: Map<string, string>;\n setClipParentMap: (map: Map<string, string>) => void;\n /**\n * Sub-composition DOM descendants (groups + their children) that have no\n * `data-start`, so they're absent from the clip manifest/tree. Collected\n * studio-side from the live preview so the timeline can expand a sub-comp row\n * to show its DOM-only children. Keeps the manifest lean (timed clips only).\n */\n domClipChildren: DomClipChild[];\n setDomClipChildren: (children: DomClipChild[]) => void;\n /**\n * Host-element state for every id'd element inside a sub-composition, keyed by\n * dom id. Collected from the live preview because it is the only place that\n * sees it: these elements are filtered out of `elements` before the flat store\n * is built, and the clip manifest carries timing, not attributes.\n */\n subCompositionHostState: Map<string, SubCompositionHostState>;\n setSubCompositionHostState: (state: Map<string, SubCompositionHostState>) => void;\n}\n\n/** A sub-comp DOM-only timeline child (no data-start) and its nesting context. */\nexport interface DomClipChild {\n id: string;\n parentId: string;\n /** The manifest sub-comp host clip id this descendant ultimately lives under. */\n hostId: string;\n label: string;\n stackingContextId: string;\n /**\n * The child's audio-group state, read off its live element during the DOM\n * walk — the only place that sees it. A sub-composition can declare a group\n * and its members entirely within itself, and those members never reach the\n * flat store, so an expanded child has no twin to inherit membership from.\n */\n audioGroup?: string;\n audioGroupLabel?: string;\n audioGroupVolume?: number;\n audioGroupHidden?: boolean;\n audioGroupFxChain?: string;\n /** The group element's `data-automation`, mirrored the same way. */\n audioGroupAutomation?: string;\n}\n\ninterface BeatHistoryEntry {\n restore: BeatEditState | null;\n at: number;\n label: string;\n}\n\n/** Selects like the marquee: the primary first, so its resets run, then the whole set. */\nfunction selectAroundPlayhead(\n state: PlayerState,\n keep: (el: TimelineElement, playhead: number) => boolean,\n): void {\n const playhead = state.isPlaying ? liveTime.latest() : state.currentTime;\n const ids = state.elements.filter((el) => keep(el, playhead)).map((el) => el.key ?? el.id);\n state.setSelectedElementId(ids[0] ?? null);\n state.setSelectedElementIds(new Set(ids));\n}\n\nexport const usePlayerStore = create<PlayerState>((set, get) => ({\n isPlaying: false,\n currentTime: 0,\n duration: 0,\n timelineSessionEpoch: 0,\n timelineProjectId: null,\n beatDragging: false,\n elements: [],\n selectedElementId: null,\n playbackRate: readStudioUiPreferences().playbackRate ?? 1,\n audioMuted: readStudioUiPreferences().audioMuted ?? false,\n audioVolume: readStudioUiPreferences().audioVolume ?? 1,\n loopEnabled: false,\n zoomMode: \"fit\",\n manualZoomPercent: 100,\n userZoomCount: 0,\n zEditVersion: 0,\n timelinePps: 100,\n timelineFitPps: 100,\n inPoint: null,\n outPoint: null,\n\n activeTool: \"select\",\n setActiveTool: (tool) => set({ activeTool: tool }),\n selectLeftward: () => selectAroundPlayhead(get(), (el, t) => el.start < t),\n selectRightward: () => selectAroundPlayhead(get(), (el, t) => el.start + el.duration > t),\n\n ...createKeyframeSlice(set, () => ({\n timelineProjectId: get().timelineProjectId,\n timelineSessionEpoch: get().timelineSessionEpoch,\n })),\n ...createThumbnailSlice(set),\n\n ...createAutomationSelectionSlice(set),\n ...createEditingModeSlice(set),\n ...createRangeSelectionSlice(),\n ...createPlaybackReadinessSlice(set),\n\n activeKeyframePct: null,\n setActiveKeyframePct: (pct) => set({ activeKeyframePct: pct }),\n\n selectedElementIds: new Set<string>(),\n setSelection: (ids, anchor) => set(resolveElementSelection(ids, anchor)),\n addSelectedElementId: (id: string) =>\n set((s) => {\n const next = new Set(s.selectedElementIds);\n next.add(id);\n return resolveElementSelection(next, s.selectedElementId);\n }),\n toggleSelectedElementId: (id: string) =>\n set((s) => {\n const next = new Set(s.selectedElementIds);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return resolveElementSelection(next, s.selectedElementId);\n }),\n clearSelection: () => set({ selectedElementId: null, selectedElementIds: new Set() }),\n\n requestedSeekTime: null,\n requestSeek: (time) => set({ requestedSeekTime: time }),\n clearSeekRequest: () => set({ requestedSeekTime: null }),\n\n playbackRequest: null,\n requestPlayback: (playing, returnTo = null) =>\n set((s) => ({\n playbackRequest: { playing, returnTo, nonce: (s.playbackRequest?.nonce ?? 0) + 1 },\n })),\n clearPlaybackRequest: () => set({ playbackRequest: null }),\n\n clipRevealRequest: null,\n requestClipReveal: (elementId) =>\n set((s) => ({\n clipRevealRequest: { elementId, nonce: (s.clipRevealRequest?.nonce ?? 0) + 1 },\n })),\n clearClipRevealRequest: () => set({ clipRevealRequest: null }),\n\n timelineFocus: null,\n timelineFocusNonce: 0,\n requestTimelineFocus: (id) =>\n set((s) => {\n const nonce = s.timelineFocusNonce + 1;\n return {\n timelineFocusNonce: nonce,\n timelineFocus: createTimelineFocusRequest(\n id,\n s.timelineProjectId,\n s.timelineSessionEpoch,\n nonce,\n ),\n };\n }),\n clearTimelineFocus: (nonce) =>\n set((s) => (s.timelineFocus?.nonce === nonce ? { timelineFocus: null } : s)),\n\n lintFindingsByElement: new Map(),\n setLintFindingsByElement: (map) => set({ lintFindingsByElement: map }),\n\n beatAnalysis: null,\n setBeatAnalysis: (analysis) => set({ beatAnalysis: analysis }),\n\n beatEdits: null,\n setBeatEdits: (edits) => set({ beatEdits: edits }),\n\n beatUndo: [],\n beatRedo: [],\n beatPersist: null,\n setBeatPersist: (fn) => set({ beatPersist: fn }),\n commitBeatEdits: (next, label) => {\n set((s) => ({\n beatEdits: next,\n beatUndo: [...s.beatUndo, { restore: s.beatEdits, at: Date.now(), label }],\n beatRedo: [],\n }));\n get().beatPersist?.();\n },\n undoBeatEdits: () => {\n const s = get();\n const entry = s.beatUndo[s.beatUndo.length - 1];\n if (!entry) return null;\n set({\n beatEdits: entry.restore,\n beatUndo: s.beatUndo.slice(0, -1),\n beatRedo: [...s.beatRedo, { restore: s.beatEdits, at: entry.at, label: entry.label }],\n });\n get().beatPersist?.();\n return entry.label;\n },\n resetBeatHistory: () => set({ beatUndo: [], beatRedo: [] }),\n redoBeatEdits: () => {\n const s = get();\n const entry = s.beatRedo[s.beatRedo.length - 1];\n if (!entry) return null;\n set({\n beatEdits: entry.restore,\n beatRedo: s.beatRedo.slice(0, -1),\n beatUndo: [...s.beatUndo, { restore: s.beatEdits, at: entry.at, label: entry.label }],\n });\n get().beatPersist?.();\n return entry.label;\n },\n\n clipManifest: null,\n setClipManifest: (clips) => set({ clipManifest: clips }),\n clipParentMap: new Map(),\n setClipParentMap: (map) => set({ clipParentMap: map }),\n domClipChildren: [],\n setDomClipChildren: (children) => set({ domClipChildren: children }),\n subCompositionHostState: new Map(),\n setSubCompositionHostState: (state) => set({ subCompositionHostState: state }),\n\n setIsPlaying: (playing) => {\n if (get().isPlaying === playing) return;\n set({ isPlaying: playing });\n },\n setPlaybackRate: (rate) => {\n writeStudioUiPreferences({ playbackRate: rate });\n set({ playbackRate: rate });\n },\n setAudioMuted: (muted) => {\n writeStudioUiPreferences({ audioMuted: muted });\n set({ audioMuted: muted });\n },\n setAudioVolume: (volume) => {\n const nextVolume = Number.isFinite(volume) ? Math.max(0, Math.min(1, volume)) : 1;\n writeStudioUiPreferences({ audioVolume: nextVolume });\n set({ audioVolume: nextVolume });\n },\n setLoopEnabled: (enabled) => set({ loopEnabled: enabled }),\n setZoomMode: (mode) => set({ zoomMode: mode }),\n clearSelectedElementIds: () => set({ selectedElementIds: new Set() }),\n setSelectedElementIds: (ids: Set<string>) => set({ selectedElementIds: new Set(ids) }),\n timelineSnapEnabled: readStudioUiPreferences().timelineSnapEnabled ?? true,\n setTimelineSnapEnabled: (enabled) => {\n writeStudioUiPreferences({ timelineSnapEnabled: enabled });\n set({ timelineSnapEnabled: enabled });\n },\n rippleEditEnabled: readStudioUiPreferences().rippleEditEnabled ?? true, // default on\n setRippleEditEnabled: (enabled) => {\n writeStudioUiPreferences({ rippleEditEnabled: enabled });\n set({ rippleEditEnabled: enabled });\n },\n timeDisplayMode: readStudioUiPreferences().timeDisplayMode ?? \"time\",\n setTimeDisplayMode: (mode) => {\n writeStudioUiPreferences({ timeDisplayMode: mode });\n set({ timeDisplayMode: mode });\n },\n pinTimelineZoom: (currentPixelsPerSecond, fitPixelsPerSecond) =>\n set((s) => {\n // Already pinned (or the user manually zoomed) — never clobber that.\n if (s.zoomMode === \"manual\") return {};\n const percent = computePinnedZoomPercent(currentPixelsPerSecond, fitPixelsPerSecond);\n writeStudioUiPreferences({\n timelineZoomMode: \"manual\",\n timelineManualZoomPercent: percent,\n });\n return { zoomMode: \"manual\", manualZoomPercent: percent };\n }),\n setTimelineScale: (pps, fitPps) => {\n const state = get();\n if (state.timelinePps === pps && state.timelineFitPps === fitPps) return;\n set({ timelinePps: pps, timelineFitPps: fitPps });\n },\n setInPoint: (time) =>\n set((state) => {\n const t = time !== null && Number.isFinite(time) ? time : null;\n return {\n inPoint: t,\n outPoint:\n t !== null && state.outPoint !== null && t >= state.outPoint ? null : state.outPoint,\n // Setting a work-area marker implies the user wants playback bounded by it.\n // Auto-enable loop so the playhead respects the marker instead of running past.\n loopEnabled: t !== null ? true : state.loopEnabled,\n };\n }),\n setOutPoint: (time) =>\n set((state) => {\n const t = time !== null && Number.isFinite(time) ? time : null;\n return {\n outPoint: t,\n inPoint: t !== null && state.inPoint !== null && t <= state.inPoint ? null : state.inPoint,\n loopEnabled: t !== null ? true : state.loopEnabled,\n };\n }),\n setManualZoomPercent: (percent) =>\n set((state) => ({\n manualZoomPercent: clampTimelineZoomPercent(percent, state.timelineFitPps),\n })),\n bumpZEditVersion: () => set((state) => ({ zEditVersion: state.zEditVersion + 1 })),\n setCurrentTime: (time) => set({ currentTime: Number.isFinite(time) ? time : 0 }),\n setDuration: (duration) => set({ duration: Number.isFinite(duration) ? duration : 0 }),\n setBeatDragging: (dragging) => set({ beatDragging: dragging }),\n setElements: (elements) => set({ elements }),\n // A genuine single selection: always collapse the set to just this element. User\n // intent (timeline click, preview click via applyDomSelection) flows here; DOM sync\n // echoes that must preserve a group go through setSelectionAnchor instead.\n setSelectedElementId: (id, options) =>\n set((s) => {\n const selectedElementIds = nextSelectionSet(s.selectedElementIds, id, options?.preserveSet);\n // Selecting a different element drops any active keyframe selection — otherwise\n // a stale activeKeyframePct from a prior diamond click would force the next drag\n // to \"modify\" a keyframe on the new element. A diamond click sets the pct AFTER\n // calling setSelectedElementId, so this never clobbers a genuine keyframe select.\n // A reveal request survives the selection it is FOR. `openClipFxRack`\n // raises the request and then selects the clip asynchronously, so the\n // selection lands afterwards and used to clear the very request that\n // caused it — the panel then read null and the section never opened.\n // Any OTHER selection still drops it: a request aimed elsewhere is stale.\n //\n // Compared across the ID-SPACE BOUNDARY, which is why this needs saying:\n // a request carries the BARE dom id (`runtimeAudioId`, because the panel\n // and the runtime speak that), while this store's ids are\n // `sourceFile#domId`. A direct `===` was silently never true — the exact\n // shape of failure the id-space split produces.\n const revealSurvives = revealTargetsSelection(s.revealedAudioFxTarget, id);\n return id !== s.selectedElementId\n ? {\n selectedElementId: id,\n selectedElementIds,\n activeKeyframePct: null,\n motionPathArmed: false,\n focusedEaseSegment: null,\n ...(revealSurvives ? {} : { revealedAudioFxTarget: null }),\n }\n : { selectedElementId: id, selectedElementIds };\n }),\n // Move the anchor within an active multi-selection WITHOUT collapsing it — used by\n // DOM->store sync echoes while a group gesture re-patches the preview. A non-member\n // id is treated as a genuine new single selection.\n setSelectionAnchor: (id) =>\n set((s) => {\n if (id != null && s.selectedElementIds.size > 1 && s.selectedElementIds.has(id)) {\n return {\n selectedElementId: id,\n focusedEaseSegment: id === s.selectedElementId ? s.focusedEaseSegment : null,\n };\n }\n return {\n selectedElementId: id,\n selectedElementIds: id ? new Set([id]) : new Set<string>(),\n focusedEaseSegment: id === s.selectedElementId ? s.focusedEaseSegment : null,\n };\n }),\n updateElement: (elementId, updates) => {\n if (queueElementPatch(elementId, updates)) return;\n set((state) => ({ elements: patchElements(state.elements, new Map([[elementId, updates]])) }));\n },\n // UI preferences intentionally survive reset. So do timelineSessionEpoch and\n // focusedEaseRequestNonce: the epoch advances only when project identity\n // changes, while a monotonic nonce prevents collisions with stale consumers.\n beginTimelineSession: (projectId) =>\n set((state) => {\n if (state.timelineProjectId === projectId) return state;\n return {\n ...createTimelineResetState(),\n timelineSessionEpoch: state.timelineSessionEpoch + 1,\n timelineProjectId: projectId,\n };\n }),\n reset: () => set(createTimelineResetState()),\n}));\n\nattachPlayerStoreDevHandle(usePlayerStore);\n\nexport function isPreviewBooted(projectId: string): boolean {\n const { previewBooted, timelineProjectId } = usePlayerStore.getState();\n return previewBooted && timelineProjectId === projectId;\n}\n\n/** True once projectId's live preview has booted, false once another project replaces it.\n * Open-time work the first frame does not need (server parses, lint) waits on it. */\nexport function whenPreviewBooted(projectId: string): Promise<boolean> {\n const openedFrom = usePlayerStore.getState().timelineProjectId;\n let seen = false;\n const settle = (state: PlayerState): boolean | null => {\n if (state.timelineProjectId === projectId) {\n seen = true;\n return state.previewBooted ? true : null;\n }\n return seen || state.timelineProjectId !== openedFrom ? false : null;\n };\n return new Promise((resolve) => {\n const now = settle(usePlayerStore.getState());\n if (now !== null) return resolve(now);\n const stop = usePlayerStore.subscribe((state) => {\n const result = settle(state);\n if (result === null) return;\n stop();\n resolve(result);\n });\n });\n}\n","/**\n * A console handle on the live store, dev builds only.\n *\n * Split out of `playerStore.ts` to keep it under the studio's 600-line cap. The\n * dev check is its own function because `import.meta.env` is absent under\n * Turbopack and other non-Vite bundlers, where reading it throws.\n */\n\nfunction isDevBuild(): boolean {\n try {\n return import.meta.env.DEV === true;\n } catch {\n return false;\n }\n}\n\n/** Expose `store` as `window.__playerStore` for dumping live Studio state\n * during bug-bash reproduction. No-op outside a dev build or a browser. */\nexport function attachPlayerStoreDevHandle(store: unknown): void {\n if (!isDevBuild() || typeof window === \"undefined\") return;\n (window as unknown as { __playerStore?: unknown }).__playerStore = store;\n}\n","/**\n * Selection-set arithmetic for the player store, and the reveal request's\n * cross-id-space match.\n *\n * Its own module so `playerStore.ts` stays under the studio's 600-line cap.\n */\n\nimport { splitTimelineElementKey } from \"../lib/timelineElementHelpers\";\n\n/**\n * The id set a selection change leaves behind.\n *\n * `preserveSet` means \"keep the multi-selection if this id is already in it\" —\n * a DOM→store echo re-announcing a member must not collapse the set — and\n * anything else is a genuine single selection.\n */\nexport function nextSelectionSet(\n current: ReadonlySet<string>,\n id: string | null,\n preserveSet: boolean | undefined,\n): Set<string> {\n if (preserveSet) return id && current.has(id) ? new Set(current) : new Set<string>();\n return id ? new Set([id]) : new Set<string>();\n}\n\n/**\n * Is a pending reveal request aimed at the element being selected?\n *\n * Compared across the ID-SPACE BOUNDARY, which is why it is a named function:\n * a request carries the BARE dom id (`runtimeAudioId` — the panel and the\n * runtime speak that), while the store's ids are `sourceFile#domId`. A direct\n * `===` between the two is silently never true, which is the exact shape of\n * failure the split produces and how the reveal came to be dead.\n */\nexport function revealTargetsSelection(\n request: { elementKey: string } | null,\n id: string | null,\n): boolean {\n if (!request || id === null) return false;\n return request.elementKey === splitTimelineElementKey(id).domId;\n}\n","import type { Direction } from \"dockview-react\";\n\nexport const PANEL_IDS = [\n \"preview\",\n \"timeline\",\n \"compositions\",\n \"assets\",\n \"code\",\n \"catalog\",\n \"design\",\n \"layers\",\n \"renders\",\n \"variables\",\n \"slideshow\",\n] as const;\n\nexport type PanelId = (typeof PANEL_IDS)[number];\nexport type PanelZone = \"left\" | \"center\" | \"right\";\n\nexport interface PanelDefinition {\n title: string;\n zone: PanelZone;\n /** Where Window > <panel> puts it when it has no saved place: next to `near`. */\n reopen: { near: PanelId; direction: Direction };\n /** Content stays mounted while its tab is hidden (the preview iframe must not reload). */\n keepMounted?: true;\n}\n\nexport const PANEL_DEFINITIONS = {\n preview: {\n title: \"Preview\",\n zone: \"center\",\n reopen: { near: \"timeline\", direction: \"above\" },\n keepMounted: true,\n },\n timeline: {\n title: \"Timeline\",\n zone: \"center\",\n reopen: { near: \"preview\", direction: \"below\" },\n keepMounted: true,\n },\n compositions: {\n title: \"Compositions\",\n zone: \"left\",\n reopen: { near: \"preview\", direction: \"left\" },\n },\n assets: { title: \"Assets\", zone: \"left\", reopen: { near: \"compositions\", direction: \"within\" } },\n code: { title: \"Code\", zone: \"left\", reopen: { near: \"compositions\", direction: \"within\" } },\n catalog: {\n title: \"Catalog\",\n zone: \"left\",\n reopen: { near: \"compositions\", direction: \"within\" },\n },\n design: { title: \"Design\", zone: \"right\", reopen: { near: \"preview\", direction: \"right\" } },\n layers: { title: \"Layers\", zone: \"right\", reopen: { near: \"design\", direction: \"within\" } },\n renders: { title: \"Renders\", zone: \"right\", reopen: { near: \"design\", direction: \"within\" } },\n variables: { title: \"Variables\", zone: \"right\", reopen: { near: \"design\", direction: \"within\" } },\n slideshow: { title: \"Slideshow\", zone: \"right\", reopen: { near: \"design\", direction: \"within\" } },\n} as const satisfies Record<PanelId, PanelDefinition>;\n\nexport function isPanelId(value: unknown): value is PanelId {\n return typeof value === \"string\" && (PANEL_IDS as readonly string[]).includes(value);\n}\n\nexport function panelsInZone(zone: PanelZone): PanelId[] {\n return PANEL_IDS.filter((id) => PANEL_DEFINITIONS[id].zone === zone);\n}\n","import type { SerializedDockview } from \"dockview-react\";\nimport { PANEL_IDS, isPanelId, type PanelId } from \"./panelRegistry\";\n\nexport const DOCK_PANEL_COMPONENT = \"panel\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction collectLeafViews(node: unknown, into: unknown[]): boolean {\n if (!isRecord(node)) return false;\n if (node.type === \"leaf\") {\n if (!isRecord(node.data) || !Array.isArray(node.data.views)) return false;\n into.push(...node.data.views);\n return true;\n }\n if (node.type === \"branch\") {\n return Array.isArray(node.data) && node.data.every((child) => collectLeafViews(child, into));\n }\n return false;\n}\n\nfunction hasGridShape(grid: Record<string, unknown>): boolean {\n const oriented = grid.orientation === \"HORIZONTAL\" || grid.orientation === \"VERTICAL\";\n return oriented && typeof grid.width === \"number\" && typeof grid.height === \"number\";\n}\n\nfunction panelsAreRegistered(\n panels: Record<string, unknown>,\n allowed: readonly PanelId[],\n): boolean {\n const ids = Object.keys(panels);\n return (\n ids.length > 0 &&\n ids.every((id) => {\n const state = panels[id];\n return (\n isPanelId(id) &&\n allowed.includes(id) &&\n isRecord(state) &&\n state.id === id &&\n state.contentComponent === DOCK_PANEL_COMPONENT\n );\n })\n );\n}\n\nfunction collectFloatingViews(floating: unknown, into: unknown[]): boolean {\n if (floating === undefined) return true;\n if (!Array.isArray(floating)) return false;\n return floating.every((group) => {\n if (!isRecord(group) || !isRecord(group.data) || !Array.isArray(group.data.views)) return false;\n into.push(...group.data.views);\n return true;\n });\n}\n\n/** Parses a stored layout at the trust boundary; null (stale or foreign shape) means use the default preset. */\nexport function parseDockLayout(\n value: unknown,\n allowed: readonly PanelId[] = PANEL_IDS,\n): SerializedDockview | null {\n if (!isRecord(value) || !isRecord(value.grid) || !isRecord(value.panels)) return null;\n const { grid, panels } = value;\n if (!hasGridShape(grid) || !panelsAreRegistered(panels, allowed)) return null;\n\n const views: unknown[] = [];\n if (!collectLeafViews(grid.root, views)) return null;\n if (!collectFloatingViews(value.floatingGroups, views)) return null;\n const everyViewIsAPanel = views.every((id) => typeof id === \"string\" && id in panels);\n const everyPanelIsPlaced = Object.keys(panels).every((id) => views.includes(id));\n return everyViewIsAPanel && everyPanelIsPlaced ? (value as unknown as SerializedDockview) : null;\n}\n","import type { SerializedDockview } from \"dockview-react\";\nimport { parseDockLayout } from \"../components/dock/dockLayoutSchema\";\n\nexport type TimelineTimeDisplayMode = \"time\" | \"frame\";\nexport type StudioTheme = \"light\" | \"dark\";\n\nexport interface StudioUiPreferences {\n timelineVisible?: boolean;\n playbackRate?: number;\n audioMuted?: boolean;\n audioVolume?: number;\n thumbnailMode?: \"adaptive\" | \"hidden\";\n recentBlocks?: string[];\n snapEnabled?: boolean;\n gridVisible?: boolean;\n rulerVisible?: boolean;\n safeMarginsVisible?: boolean;\n gridSpacing?: number;\n snapToGrid?: boolean;\n /** Timeline magnet: snap clip drags/trims/drops to playhead, clip edges, and beats. */\n timelineSnapEnabled?: boolean;\n /** Audio level meters at the timeline's right edge; hidden unless enabled here. */\n audioMetersVisible?: boolean;\n /** Keeps the main track gapless: deleting a clip closes the gap. Distinct\n * from `timelineSnapEnabled` (\"Magnet\", drag/trim snapping). */\n rippleEditEnabled?: boolean;\n /** Transport + ruler readout mode: timecode or frame number. */\n timeDisplayMode?: TimelineTimeDisplayMode;\n /**\n * Timeline zoom mode. Persisted so a zoom PINNED on the first edit survives the\n * post-edit iframe reload — otherwise the store reset to \"fit\" and the duration\n * change rescaled every clip (the blink-fix's rescale symptom).\n */\n timelineZoomMode?: \"fit\" | \"manual\";\n /** Manual timeline zoom percent, paired with `timelineZoomMode: \"manual\"`. */\n timelineManualZoomPercent?: number;\n /**\n * Expose Studio's editing capabilities to an agentic browser as WebMCP tools.\n * Absent means on: the browser still gates every actual call behind its own\n * permission prompt, so \"registered\" is not \"reachable without consent\".\n * Changes take effect on the next Studio reload because registration is\n * intentionally scoped to one mount.\n */\n agentToolsEnabled?: boolean;\n theme?: StudioTheme;\n /** The dock's serialized panel tree; parsed by `parseDockLayout` on read. */\n dockLayout?: SerializedDockview;\n linkedSelectionEnabled?: boolean;\n syncIndicatorsVisible?: boolean;\n}\n\nconst STUDIO_UI_PREFERENCES_KEY = \"hf-studio-ui-preferences\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction getBrowserStorage(): Storage | null {\n if (typeof window === \"undefined\") return null;\n try {\n return window.localStorage;\n } catch {\n return null;\n }\n}\n\nfunction storageKeyFor(projectId: string | null, key: string): string {\n return projectId ? `${key}:${projectId}` : key;\n}\n\n// fallow-ignore-next-line complexity\nfunction readStorage(storage: Storage | null, key: string): StudioUiPreferences {\n if (!storage) return {};\n try {\n const raw = storage.getItem(key);\n if (!raw) return {};\n const parsed: unknown = JSON.parse(raw);\n if (!isRecord(parsed)) return {};\n\n const preferences: StudioUiPreferences = {};\n if (typeof parsed.timelineVisible === \"boolean\") {\n preferences.timelineVisible = parsed.timelineVisible;\n }\n if (typeof parsed.playbackRate === \"number\" && Number.isFinite(parsed.playbackRate)) {\n preferences.playbackRate = parsed.playbackRate;\n }\n if (typeof parsed.audioMuted === \"boolean\") {\n preferences.audioMuted = parsed.audioMuted;\n }\n if (\n typeof parsed.audioVolume === \"number\" &&\n Number.isFinite(parsed.audioVolume) &&\n parsed.audioVolume >= 0 &&\n parsed.audioVolume <= 1\n ) {\n preferences.audioVolume = parsed.audioVolume;\n }\n if (parsed.thumbnailMode === \"adaptive\" || parsed.thumbnailMode === \"hidden\") {\n preferences.thumbnailMode = parsed.thumbnailMode;\n } else if (typeof parsed.thumbnailsEnabled === \"boolean\") {\n preferences.thumbnailMode = parsed.thumbnailsEnabled ? \"adaptive\" : \"hidden\";\n }\n if (Array.isArray(parsed.recentBlocks)) {\n preferences.recentBlocks = parsed.recentBlocks.filter(\n (v: unknown): v is string => typeof v === \"string\",\n );\n }\n if (typeof parsed.snapEnabled === \"boolean\") {\n preferences.snapEnabled = parsed.snapEnabled;\n }\n if (typeof parsed.gridVisible === \"boolean\") {\n preferences.gridVisible = parsed.gridVisible;\n }\n if (typeof parsed.rulerVisible === \"boolean\") {\n preferences.rulerVisible = parsed.rulerVisible;\n }\n if (typeof parsed.safeMarginsVisible === \"boolean\") {\n preferences.safeMarginsVisible = parsed.safeMarginsVisible;\n }\n if (typeof parsed.gridSpacing === \"number\" && Number.isFinite(parsed.gridSpacing)) {\n preferences.gridSpacing = parsed.gridSpacing;\n }\n if (typeof parsed.snapToGrid === \"boolean\") {\n preferences.snapToGrid = parsed.snapToGrid;\n }\n if (typeof parsed.timelineSnapEnabled === \"boolean\") {\n preferences.timelineSnapEnabled = parsed.timelineSnapEnabled;\n }\n if (typeof parsed.audioMetersVisible === \"boolean\") {\n preferences.audioMetersVisible = parsed.audioMetersVisible;\n }\n if (typeof parsed.rippleEditEnabled === \"boolean\") {\n preferences.rippleEditEnabled = parsed.rippleEditEnabled;\n }\n if (parsed.theme === \"light\" || parsed.theme === \"dark\") preferences.theme = parsed.theme;\n if (parsed.timeDisplayMode === \"time\" || parsed.timeDisplayMode === \"frame\") {\n preferences.timeDisplayMode = parsed.timeDisplayMode;\n }\n if (parsed.timelineZoomMode === \"fit\" || parsed.timelineZoomMode === \"manual\") {\n preferences.timelineZoomMode = parsed.timelineZoomMode;\n }\n if (\n typeof parsed.timelineManualZoomPercent === \"number\" &&\n Number.isFinite(parsed.timelineManualZoomPercent)\n ) {\n preferences.timelineManualZoomPercent = parsed.timelineManualZoomPercent;\n }\n if (typeof parsed.agentToolsEnabled === \"boolean\") {\n preferences.agentToolsEnabled = parsed.agentToolsEnabled;\n }\n if (typeof parsed.linkedSelectionEnabled === \"boolean\") {\n preferences.linkedSelectionEnabled = parsed.linkedSelectionEnabled;\n }\n if (typeof parsed.syncIndicatorsVisible === \"boolean\") {\n preferences.syncIndicatorsVisible = parsed.syncIndicatorsVisible;\n }\n const dockLayout = parseDockLayout(parsed.dockLayout);\n if (dockLayout) preferences.dockLayout = dockLayout;\n return preferences;\n } catch {\n return {};\n }\n}\n\n/** `projectId` opts a caller into a per-project entry (falls back once to the\n * shared entry so a project's first read isn't blank). Defaults to `null`:\n * most callers read once at mount, never on a live project switch. */\nexport function readStudioUiPreferences(\n storage: Storage | null = getBrowserStorage(),\n projectId: string | null = null,\n key: string = STUDIO_UI_PREFERENCES_KEY,\n): StudioUiPreferences {\n const scoped = readStorage(storage, storageKeyFor(projectId, key));\n if (!projectId || Object.keys(scoped).length > 0) return scoped;\n return readStorage(storage, key);\n}\n\nexport function writeStudioUiPreferences(\n patch: StudioUiPreferences,\n storage: Storage | null = getBrowserStorage(),\n projectId: string | null = null,\n key: string = STUDIO_UI_PREFERENCES_KEY,\n) {\n if (!storage) return;\n try {\n const next = {\n ...readStudioUiPreferences(storage, projectId, key),\n ...patch,\n };\n storage.setItem(storageKeyFor(projectId, key), JSON.stringify(next));\n } catch {\n /* localStorage may be unavailable or full */\n }\n}\n","import type { ZoomMode } from \"../store/playerStore\";\nimport { STUDIO_PREVIEW_FPS } from \"../lib/time\";\n\nexport const MIN_TIMELINE_ZOOM_PERCENT = 10;\nconst MAX_TIMELINE_FRAME_WIDTH_PX = 48;\n// CapCut-strength steps: one button press / pinch gesture moves the zoom\n// meaningfully (user feedback, twice-doubled: 1.25×/0.8× + 0.0035 felt like\n// \"zooming several times to get anywhere\", then 1.5× + 0.007 still too soft).\n// Kept reciprocal (2 × 0.5 = 1) so in+out round-trips.\nconst ZOOM_OUT_FACTOR = 0.5;\nconst ZOOM_IN_FACTOR = 2;\nconst PINCH_ZOOM_SENSITIVITY = 0.014;\n\nexport function getMaxTimelineZoomPercent(fitPixelsPerSecond: number): number {\n if (!Number.isFinite(fitPixelsPerSecond) || fitPixelsPerSecond <= 0) return 100;\n const frameLevelPixelsPerSecond = STUDIO_PREVIEW_FPS * MAX_TIMELINE_FRAME_WIDTH_PX;\n return Math.max(100, Math.round((frameLevelPixelsPerSecond / fitPixelsPerSecond) * 100));\n}\n\nexport function clampTimelineZoomPercent(percent: number, fitPixelsPerSecond: number): number {\n if (!Number.isFinite(percent)) return 100;\n const maxZoomPercent = getMaxTimelineZoomPercent(fitPixelsPerSecond);\n return Math.max(MIN_TIMELINE_ZOOM_PERCENT, Math.min(maxZoomPercent, Math.round(percent)));\n}\n\nexport function getTimelineZoomPercent(\n zoomMode: ZoomMode,\n manualZoomPercent: number,\n fitPixelsPerSecond: number,\n): number {\n return zoomMode === \"fit\" ? 100 : clampTimelineZoomPercent(manualZoomPercent, fitPixelsPerSecond);\n}\n\n/**\n * The manual-zoom percent that, applied to `fitPixelsPerSecond`, reproduces the\n * CURRENT on-screen pixels-per-second exactly. Used to PIN the timeline zoom on\n * the first edit so a duration change (which recomputes fit-pps) no longer\n * rescales every clip: we switch `zoomMode` to \"manual\" with this percent, so\n * `getTimelinePixelsPerSecond` keeps returning today's pps regardless of the new\n * fit basis.\n *\n * Since `pps = fitPps * (percent / 100)` in manual mode, and while fitting\n * `pps === fitPps`, the pinned percent is `currentPps / fitPps * 100`. Clamped to\n * the manual-zoom range so the pin can't land outside the slider's bounds; falls\n * back to 100 (a no-op pin at the current fit) when either input is unusable.\n */\nexport function computePinnedZoomPercent(\n currentPixelsPerSecond: number,\n fitPixelsPerSecond: number,\n): number {\n if (\n !Number.isFinite(currentPixelsPerSecond) ||\n currentPixelsPerSecond <= 0 ||\n !Number.isFinite(fitPixelsPerSecond) ||\n fitPixelsPerSecond <= 0\n ) {\n return 100;\n }\n return clampTimelineZoomPercent(\n (currentPixelsPerSecond / fitPixelsPerSecond) * 100,\n fitPixelsPerSecond,\n );\n}\n\nexport function getTimelinePixelsPerSecond(\n fitPixelsPerSecond: number,\n zoomMode: ZoomMode,\n manualZoomPercent: number,\n): number {\n if (!Number.isFinite(fitPixelsPerSecond) || fitPixelsPerSecond <= 0) return 100;\n const zoomPercent = getTimelineZoomPercent(zoomMode, manualZoomPercent, fitPixelsPerSecond);\n return zoomMode === \"fit\" ? fitPixelsPerSecond : fitPixelsPerSecond * (zoomPercent / 100);\n}\n\nexport function getNextTimelineZoomPercent(\n direction: \"in\" | \"out\",\n zoomMode: ZoomMode,\n manualZoomPercent: number,\n fitPixelsPerSecond: number,\n): number {\n const current = getTimelineZoomPercent(zoomMode, manualZoomPercent, fitPixelsPerSecond);\n const next = direction === \"in\" ? current * ZOOM_IN_FACTOR : current * ZOOM_OUT_FACTOR;\n return clampTimelineZoomPercent(next, fitPixelsPerSecond);\n}\n\nexport function getPinchTimelineZoomPercent(\n deltaY: number,\n zoomMode: ZoomMode,\n manualZoomPercent: number,\n fitPixelsPerSecond: number,\n): number {\n const current = getTimelineZoomPercent(zoomMode, manualZoomPercent, fitPixelsPerSecond);\n if (!Number.isFinite(deltaY) || deltaY === 0) return current;\n return clampTimelineZoomPercent(\n current * Math.exp(-deltaY * PINCH_ZOOM_SENSITIVITY),\n fitPixelsPerSecond,\n );\n}\n\nconst LOG_MIN = Math.log(MIN_TIMELINE_ZOOM_PERCENT);\n\n/**\n * Maps the frame-level zoom range to a slider position (0–100) using a log scale.\n * Linear would compress the useful low end into a tiny sliver of the slider.\n */\nexport function timelineZoomPercentToSlider(percent: number, fitPixelsPerSecond: number): number {\n const clamped = clampTimelineZoomPercent(percent, fitPixelsPerSecond);\n const logMax = Math.log(getMaxTimelineZoomPercent(fitPixelsPerSecond));\n return ((Math.log(clamped) - LOG_MIN) / (logMax - LOG_MIN)) * 100;\n}\n\n/**\n * Maps a slider position (0–100) to the frame-level zoom range using a log scale.\n * Inverse of `timelineZoomPercentToSlider`.\n */\nexport function timelineSliderToZoomPercent(slider: number, fitPixelsPerSecond: number): number {\n const clampedSlider = Math.max(0, Math.min(100, slider));\n const logMax = Math.log(getMaxTimelineZoomPercent(fitPixelsPerSecond));\n const logValue = LOG_MIN + (clampedSlider / 100) * (logMax - LOG_MIN);\n return clampTimelineZoomPercent(Math.exp(logValue), fitPixelsPerSecond);\n}\n","import type { GsapAnimation } from \"@hyperframes/core/gsap-parser\";\nimport type { StoreApi } from \"zustand\";\nimport type { AnimationKeyframeTarget } from \"../../hooks/gsapTweenSynth\";\n\n/** Minimal keyframe cache types — mirrors GsapKeyframesData without pulling in Node-only gsap-parser. */\nexport interface KeyframeCacheEntry {\n format: string;\n keyframes: Array<{\n percentage: number;\n /** Original tween-relative percentage (server mutations need this, not the clip-relative `percentage`). */\n tweenPercentage?: number;\n /** Which property group the source tween belongs to (position, scale, rotation, visual, etc.). */\n propertyGroup?: string;\n /** Source tween id — lets the inline clip-row ease button target a specific segment. */\n animationId?: string;\n properties: Record<string, number | string>;\n ease?: string;\n /** Source animation/keyframe targets that collide at this clip percentage. */\n collidingAnimationTargets?: AnimationKeyframeTarget[];\n }>;\n ease?: string;\n easeEach?: string;\n}\n\nexport interface FocusedEaseSegment {\n animationId: string;\n collidingAnimationTargets?: AnimationKeyframeTarget[];\n tweenPercentage: number;\n elementId: string;\n projectId: string | null;\n sessionEpoch: number;\n nonce: number;\n}\n\ntype FocusedEaseSegmentTarget = Omit<FocusedEaseSegment, \"projectId\" | \"sessionEpoch\" | \"nonce\">;\n\n/**\n * A request to reveal one automated parameter in the audio FX rack.\n *\n * `elementKey` is the timeline element whose rack it belongs to — a group's own\n * id for a group lane, the clip's key otherwise — so the panel can refuse a\n * request aimed at something it is not showing.\n */\nexport interface RevealedAudioFxTarget {\n elementKey: string;\n /** The lane's own `fx.<node>.<param>` / `volume` target. */\n automationTarget: string;\n projectId: string | null;\n sessionEpoch: number;\n nonce: number;\n}\n\nexport type RevealedAudioFxTargetRequest = Omit<\n RevealedAudioFxTarget,\n \"projectId\" | \"sessionEpoch\" | \"nonce\"\n>;\n\n/** Whether a reveal request still belongs to what is on screen. */\nexport function isRevealedAudioFxRequestCurrent(\n request: RevealedAudioFxTarget,\n state: TimelineSessionIdentity,\n): boolean {\n return (\n request.projectId === state.timelineProjectId &&\n request.sessionEpoch === state.timelineSessionEpoch\n );\n}\n\ninterface TimelineSessionIdentity {\n timelineProjectId: string | null;\n timelineSessionEpoch: number;\n}\n\nexport function isFocusedEaseRequestCurrent(\n request: FocusedEaseSegment,\n state: TimelineSessionIdentity & { selectedElementId: string | null },\n): boolean {\n return (\n request.projectId === state.timelineProjectId &&\n request.sessionEpoch === state.timelineSessionEpoch &&\n request.elementId === state.selectedElementId\n );\n}\n\nexport interface KeyframeSlice {\n /** Selected collapsed (`element:pct`) or expanded (`element:group:animation:clipPct`) diamonds. */\n selectedKeyframes: Set<string>;\n toggleSelectedKeyframe: (key: string) => void;\n clearSelectedKeyframes: () => void;\n\n /** Clips whose keyframe property lanes are expanded in the timeline. */\n expandedClipIds: Set<string>;\n toggleClipExpanded: (id: string) => void;\n setClipExpanded: (id: string, expanded: boolean) => void;\n /** Union-expand clips (keyframed clips are expanded by default on load). */\n expandClips: (ids: readonly string[]) => void;\n\n /**\n * Groups whose member rows the caret has HIDDEN (structural, not lanes).\n *\n * Inverted deliberately. As an expanded-set, \"not in the set\" could not tell\n * never-touched from deliberately-collapsed, so every group defaulted to\n * collapsed — and since nothing seeds the set on create, grouping three\n * tracks made all three vanish behind a header the user had not yet learned\n * to open. Groups are expanded until someone closes one.\n */\n collapsedGroupIds: Set<string>;\n toggleGroupExpanded: (id: string) => void;\n\n /** Rows (clip id or group id) whose automation-lane rows the `∿` button opened. */\n expandedLaneOwnerIds: Set<string>;\n toggleLaneOwnerExpanded: (id: string) => void;\n\n /**\n * Project/session/element-scoped request. Its nonce is monotonic across store\n * resets so a stale consumer can never collide with a later request.\n */\n focusedEaseSegment: FocusedEaseSegment | null;\n focusedEaseRequestNonce: number;\n setFocusedEaseSegment: (target: FocusedEaseSegmentTarget) => void;\n clearFocusedEaseSegment: (nonce: number) => void;\n\n /**\n * \"Show me this automated parameter in the rack\" — raised by clicking an\n * automation lane's label in the timeline, consumed by the property panel.\n *\n * Session-stamped and nonce-guarded exactly like `focusedEaseSegment`: a\n * request outlives the click, so one made against a different project or\n * before a reload must not reopen a rack on whatever is mounted later.\n */\n revealedAudioFxTarget: RevealedAudioFxTarget | null;\n revealedAudioFxNonce: number;\n setRevealedAudioFxTarget: (target: RevealedAudioFxTargetRequest) => void;\n clearRevealedAudioFxTarget: (nonce: number) => void;\n\n /** Keyframe data per element id, populated from parsed GSAP animations. */\n keyframeCache: Map<string, KeyframeCacheEntry>;\n /** Unmerged source tweens per element; expanded property lanes read this, never keyframeCache. */\n gsapAnimations: Map<string, GsapAnimation[]>;\n setGsapAnimations: (elementId: string, animations: GsapAnimation[] | undefined) => void;\n setKeyframeCache: (elementId: string, data: KeyframeCacheEntry | undefined) => void;\n}\n\nexport function createKeyframeSlice(\n set: StoreApi<KeyframeSlice>[\"setState\"],\n getTimelineSessionIdentity: () => TimelineSessionIdentity,\n): KeyframeSlice {\n return {\n selectedKeyframes: new Set(),\n toggleSelectedKeyframe: (key) =>\n set((state) => {\n const next = new Set(state.selectedKeyframes);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n return { selectedKeyframes: next };\n }),\n clearSelectedKeyframes: () => set({ selectedKeyframes: new Set() }),\n\n expandedClipIds: new Set(),\n toggleClipExpanded: (id) =>\n set((state) => {\n const next = new Set(state.expandedClipIds);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return { expandedClipIds: next };\n }),\n setClipExpanded: (id, expanded) =>\n set((state) => {\n if (state.expandedClipIds.has(id) === expanded) return state;\n const next = new Set(state.expandedClipIds);\n if (expanded) next.add(id);\n else next.delete(id);\n return { expandedClipIds: next };\n }),\n expandClips: (ids) =>\n set((state) => {\n if (ids.every((id) => state.expandedClipIds.has(id))) return state;\n const next = new Set(state.expandedClipIds);\n for (const id of ids) next.add(id);\n return { expandedClipIds: next };\n }),\n\n collapsedGroupIds: new Set(),\n toggleGroupExpanded: (id) =>\n set((state) => {\n const next = new Set(state.collapsedGroupIds);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return { collapsedGroupIds: next };\n }),\n\n expandedLaneOwnerIds: new Set(),\n toggleLaneOwnerExpanded: (id) =>\n set((state) => {\n const next = new Set(state.expandedLaneOwnerIds);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return { expandedLaneOwnerIds: next };\n }),\n\n focusedEaseSegment: null,\n focusedEaseRequestNonce: 0,\n setFocusedEaseSegment: (target) =>\n set((state) => {\n const nonce = state.focusedEaseRequestNonce + 1;\n const { timelineProjectId, timelineSessionEpoch } = getTimelineSessionIdentity();\n return {\n focusedEaseRequestNonce: nonce,\n focusedEaseSegment: {\n ...target,\n projectId: timelineProjectId,\n sessionEpoch: timelineSessionEpoch,\n nonce,\n },\n };\n }),\n clearFocusedEaseSegment: (nonce) =>\n set((state) =>\n state.focusedEaseSegment?.nonce === nonce ? { focusedEaseSegment: null } : state,\n ),\n\n revealedAudioFxTarget: null,\n revealedAudioFxNonce: 0,\n setRevealedAudioFxTarget: (target) =>\n set((state) => {\n const nonce = state.revealedAudioFxNonce + 1;\n const { timelineProjectId, timelineSessionEpoch } = getTimelineSessionIdentity();\n return {\n revealedAudioFxNonce: nonce,\n revealedAudioFxTarget: {\n ...target,\n projectId: timelineProjectId,\n sessionEpoch: timelineSessionEpoch,\n nonce,\n },\n };\n }),\n clearRevealedAudioFxTarget: (nonce) =>\n set((state) =>\n state.revealedAudioFxTarget?.nonce === nonce ? { revealedAudioFxTarget: null } : state,\n ),\n\n keyframeCache: new Map(),\n setKeyframeCache: (elementId, data) =>\n set((state) => {\n // A write that changes nothing must not emit a new Map: the cache has\n // several hot writers (per-element effect, file populate, post-commit\n // updater, delete) and every no-op re-rendered every subscriber.\n if (\n data ? state.keyframeCache.get(elementId) === data : !state.keyframeCache.has(elementId)\n )\n return state;\n const next = new Map(state.keyframeCache);\n if (data) next.set(elementId, data);\n else next.delete(elementId);\n return { keyframeCache: next };\n }),\n gsapAnimations: new Map(),\n setGsapAnimations: (elementId, animations) =>\n set((state) => {\n if (\n animations\n ? state.gsapAnimations.get(elementId) === animations\n : !state.gsapAnimations.has(elementId)\n )\n return state;\n const next = new Map(state.gsapAnimations);\n if (animations) next.set(elementId, animations);\n else next.delete(elementId);\n return { gsapAnimations: next };\n }),\n };\n}\n","/**\n * The active selection box on one automation lane.\n *\n * A store slice, not lane-local state, for the same reason keyframe selection\n * is one: Delete/copy/paste handlers and the shape menu live outside the lane\n * component and need to read it. Ephemeral by construction — nothing\n * serializes store state, and the selection must never survive into a render.\n */\nimport type { StoreApi } from \"zustand\";\n\nexport interface AutomationSelection {\n /** TimelineElement key (key ?? id) of the clip that owns the lane. */\n elementKey: string;\n /** Lane target: \"volume\" or \"fx.<nodeId>.<param>\". */\n target: string;\n /** Clip-local seconds; always t0 <= t1 (ordered on write). */\n t0: number;\n t1: number;\n /**\n * The box's value bounds, in the parameter's own units; always v0 <= v1.\n *\n * What makes the selection a box rather than a time span: a point is caught\n * only if it falls inside both axes. Span operations — copy, paste, shape\n * insert, simplify — still read t0/t1 alone, because they act on the envelope\n * over a stretch of time rather than on a set of breakpoints.\n */\n v0: number;\n v1: number;\n}\n\nexport interface AutomationSelectionSlice {\n automationSelection: AutomationSelection | null;\n setAutomationSelection: (sel: AutomationSelection) => void;\n clearAutomationSelection: () => void;\n}\n\nexport function createAutomationSelectionSlice(\n set: StoreApi<AutomationSelectionSlice>[\"setState\"],\n): AutomationSelectionSlice {\n return {\n automationSelection: null,\n setAutomationSelection: (sel) =>\n set({\n automationSelection: {\n ...sel,\n t0: Math.min(sel.t0, sel.t1),\n t1: Math.max(sel.t0, sel.t1),\n v0: Math.min(sel.v0, sel.v1),\n v1: Math.max(sel.v0, sel.v1),\n },\n }),\n clearAutomationSelection: () => set({ automationSelection: null }),\n };\n}\n","/**\n * The two editing-mode toggles the timeline toolbar owns.\n *\n * A store slice rather than toolbar-local state because both are read far from\n * where they are set: the motion-path arm is consumed by the canvas click\n * handler and published by MotionPathOverlay, and the auto-keyframe flag\n * decides what a drag/resize/rotate does inside the edit commit path.\n *\n * `motionPathArmed` is also cleared by playerStore on selection change — arming\n * survives neither a new element nor a project switch, so those resets stay\n * with the state they clear alongside.\n */\nimport type { StoreApi } from \"zustand\";\n\nexport interface EditingModeSlice {\n /** Motion-path \"set destination\" mode. Armed from the preview toolbar\n * (replaces the old double-click-on-canvas UX); while armed, one canvas\n * click places the new path's destination. */\n motionPathArmed: boolean;\n setMotionPathArmed: (armed: boolean) => void;\n /** Published by MotionPathOverlay so the toolbar shows the button only when\n * the selected element can actually take a path. */\n motionPathCreateAvailable: boolean;\n setMotionPathCreateAvailable: (available: boolean) => void;\n /** Global toggle for the \"Add keyframe\" diamond in the timeline toolbar\n * (#1808). When false, a manual drag/resize/rotate edit on an element that\n * already has a live tween shifts every keyframe by the edit's delta\n * (preserving the animation's shape) instead of inserting/updating a\n * keyframe at the playhead. */\n autoKeyframeEnabled: boolean;\n setAutoKeyframeEnabled: (enabled: boolean) => void;\n}\n\nexport function createEditingModeSlice(\n set: StoreApi<EditingModeSlice>[\"setState\"],\n): EditingModeSlice {\n return {\n motionPathArmed: false,\n setMotionPathArmed: (armed) => set({ motionPathArmed: armed }),\n motionPathCreateAvailable: false,\n setMotionPathCreateAvailable: (available) => set({ motionPathCreateAvailable: available }),\n autoKeyframeEnabled: true,\n setAutoKeyframeEnabled: (enabled) => set({ autoKeyframeEnabled: enabled }),\n };\n}\n","export interface TimelineFocusRequest {\n id: string;\n projectId: string | null;\n sessionEpoch: number;\n nonce: number;\n}\n\nexport function createTimelineFocusRequest(\n id: string,\n projectId: string | null,\n sessionEpoch: number,\n nonce: number,\n): TimelineFocusRequest {\n return { id, projectId, sessionEpoch, nonce };\n}\n","export type ThumbnailMode = \"adaptive\" | \"hidden\";\nexport type ThumbnailRuntimePolicy = \"follow-preference\" | \"force-hidden\" | \"legacy-default\";\n\n// \"Adaptive\" currently means the scheduler pauses rich work while scrolling.\n// The mode name leaves room for finer-grained runtime heuristics later.\n\nconst rawPolicy = import.meta.env?.VITE_STUDIO_TIMELINE_THUMBNAIL_POLICY;\n\nconst studioThumbnailRuntimePolicy: ThumbnailRuntimePolicy =\n rawPolicy === \"force-hidden\" || rawPolicy === \"legacy-default\" ? rawPolicy : \"follow-preference\";\n\nexport function defaultThumbnailMode(\n storedMode: ThumbnailMode | undefined,\n policy: ThumbnailRuntimePolicy = studioThumbnailRuntimePolicy,\n): ThumbnailMode {\n return storedMode ?? (policy === \"legacy-default\" ? \"hidden\" : \"adaptive\");\n}\n\nexport function effectiveThumbnailMode(\n preferredMode: ThumbnailMode,\n policy: ThumbnailRuntimePolicy = studioThumbnailRuntimePolicy,\n): ThumbnailMode {\n return policy === \"force-hidden\" ? \"hidden\" : preferredMode;\n}\n","import type { StoreApi } from \"zustand\";\nimport { readStudioUiPreferences, writeStudioUiPreferences } from \"../../utils/studioUiPreferences\";\nimport { defaultThumbnailMode, type ThumbnailMode } from \"../lib/thumbnailPolicy\";\n\n/** Revision that moves every composition's thumbnails at once. */\nconst EVERY_COMPOSITION = \"*\";\n\n/** Mounts may be written `./scene.html`; the server reports `scene.html`. */\nfunction revisionKey(path: string): string {\n return (path.split(/[?#]/)[0] ?? \"\").replace(/\\\\/g, \"/\").replace(/^\\.?\\//, \"\");\n}\n\nexport interface ThumbnailSlice {\n thumbnailMode: ThumbnailMode;\n /** Monotonic identity, per composition path, for persisted content shown by mounted thumbnails. */\n thumbnailRevisions: Readonly<Record<string, number>>;\n setThumbnailMode: (mode: ThumbnailMode) => void;\n /** `null` moves every composition, e.g. after a root or asset change. */\n bumpThumbnailRevisions: (compositions: readonly string[] | null) => void;\n}\n\nexport function thumbnailRevisionOf(\n revisions: Readonly<Record<string, number>>,\n compositionPath: string,\n): number {\n return (revisions[EVERY_COMPOSITION] ?? 0) + (revisions[revisionKey(compositionPath)] ?? 0);\n}\n\nexport function createThumbnailSlice(set: StoreApi<ThumbnailSlice>[\"setState\"]): ThumbnailSlice {\n return {\n thumbnailMode: defaultThumbnailMode(readStudioUiPreferences().thumbnailMode),\n thumbnailRevisions: {},\n setThumbnailMode: (mode) => {\n writeStudioUiPreferences({ thumbnailMode: mode });\n set({ thumbnailMode: mode });\n },\n bumpThumbnailRevisions: (compositions) =>\n set(({ thumbnailRevisions }) => {\n const next = { ...thumbnailRevisions };\n for (const path of compositions?.map(revisionKey) ?? [EVERY_COMPOSITION]) {\n next[path] = (next[path] ?? 0) + 1;\n }\n return { thumbnailRevisions: next };\n }),\n };\n}\n","/** Gates `timelineReady` on the composition's declared readiness inputs\n * (media, compute, and the paint-and-idle default) instead of just a known\n * duration. The generation counter is module-scope, not store state: it\n * guards an in-flight settlement, not something a component reads, so\n * bumping it shouldn't trigger a render. */\nimport type { StoreApi } from \"zustand\";\nimport { settleCompositionReadiness } from \"@hyperframes/core/composition-readiness\";\n\nexport interface PlaybackReadinessSlice {\n timelineReady: boolean;\n /** Latched when the project's first preview shows its first frame (or fails), kept through edit\n * reloads, so work that must not compete with the boot waits for it once. */\n previewBooted: boolean;\n setTimelineReady: (ready: boolean) => void;\n markPreviewBooted: () => void;\n playLocked: boolean;\n setPlayLocked: (locked: boolean) => void;\n /** Sets timelineReady once doc's readiness inputs settle, or immediately\n * if doc is null. A wait a later call supersedes never wins the race.\n * Waits for doc's load step first: it pauses and rewinds the preview, so a\n * Play enabled before it would be undone. */\n requestTimelineReady: (doc: Document | null) => void;\n /** Called by the preview's load step for the document it ran on. */\n markPreviewLoadStep: (doc: Document) => void;\n}\n\nlet timelineReadyGeneration = 0;\nconst loadStepDocs = new WeakSet<Document>();\nlet awaitingLoadStep: { doc: Document; generation: number } | null = null;\n\n/** For a full timeline reset: bumps the generation so any requestTimelineReady\n * wait in flight can never resolve into what replaced it. */\nexport function resetPlaybackReadinessState(): Pick<\n PlaybackReadinessSlice,\n \"timelineReady\" | \"previewBooted\"\n> {\n timelineReadyGeneration++;\n return { timelineReady: false, previewBooted: false };\n}\n\nexport function createPlaybackReadinessSlice(\n set: StoreApi<PlaybackReadinessSlice>[\"setState\"],\n): PlaybackReadinessSlice {\n const settle = (doc: Document, generation: number) =>\n settleCompositionReadiness(doc, () => {\n if (generation === timelineReadyGeneration) set({ timelineReady: true });\n });\n return {\n timelineReady: false,\n previewBooted: false,\n markPreviewBooted: () => set({ previewBooted: true }),\n playLocked: false,\n setPlayLocked: (locked) => set({ playLocked: locked }),\n setTimelineReady: (ready) => {\n timelineReadyGeneration++;\n set({ timelineReady: ready });\n },\n requestTimelineReady: (doc) => {\n const generation = ++timelineReadyGeneration;\n if (!doc) return set({ timelineReady: true });\n if (!loadStepDocs.has(doc)) {\n awaitingLoadStep = { doc, generation };\n return;\n }\n settle(doc, generation);\n },\n markPreviewLoadStep: (doc) => {\n loadStepDocs.add(doc);\n if (awaitingLoadStep?.doc !== doc) return;\n const { generation } = awaitingLoadStep;\n awaitingLoadStep = null;\n settle(doc, generation);\n },\n };\n}\n","export interface TimelineTimeRange {\n t0: number;\n t1: number;\n}\n\nexport interface RangeSelectionSlice {\n /** Shift-drag ruler range in seconds, normalized so t0 <= t1. */\n rangeSelection: TimelineTimeRange | null;\n}\n\nexport function createRangeSelectionSlice(): RangeSelectionSlice {\n return { rangeSelection: null };\n}\n","import type { GsapAnimation } from \"@hyperframes/core/gsap-parser\";\nimport type { KeyframeCacheEntry } from \"./keyframeSlice\";\nimport { resetPlaybackReadinessState } from \"./readinessSlice\";\nimport type { SubCompositionHostState } from \"./timelineElement\";\n\nexport function createTimelineResetState() {\n return {\n isPlaying: false,\n currentTime: 0,\n duration: 0,\n ...resetPlaybackReadinessState(),\n beatDragging: false,\n elements: [],\n selectedElementId: null,\n zEditVersion: 0,\n inPoint: null,\n outPoint: null,\n rangeSelection: null,\n activeTool: \"select\" as const,\n activeKeyframePct: null,\n motionPathArmed: false,\n motionPathCreateAvailable: false,\n selectedKeyframes: new Set<string>(),\n // Ephemeral like every other selection here. A range surviving a project\n // switch can match a same-keyed clip in the new project and redirect a\n // paste through `sel.elementKey === paste.elementKey` to a stale t0.\n automationSelection: null,\n expandedClipIds: new Set<string>(),\n // Per-composition: ids from comp A match nothing in B, silencing all of it.\n collapsedGroupIds: new Set<string>(),\n expandedLaneOwnerIds: new Set<string>(),\n focusedEaseSegment: null,\n revealedAudioFxTarget: null,\n selectedElementIds: new Set<string>(),\n requestedSeekTime: null,\n lintFindingsByElement: new Map<string, { count: number; messages: string[] }>(),\n timelineFocus: null,\n keyframeCache: new Map<string, KeyframeCacheEntry>(),\n gsapAnimations: new Map<string, GsapAnimation[]>(),\n beatAnalysis: null,\n beatEdits: null,\n beatUndo: [],\n beatRedo: [],\n beatPersist: null,\n clipManifest: null,\n clipParentMap: new Map<string, string>(),\n domClipChildren: [],\n subCompositionHostState: new Map<string, SubCompositionHostState>(),\n };\n}\n","import type { TimelineElement, TimelineElementPatch } from \"./timelineElement\";\n\nlet queued: Map<string, TimelineElementPatch> | null = null;\n\n/** Queues `updates` while a batch is collecting; false means the caller applies it now. */\nexport function queueElementPatch(key: string, updates: TimelineElementPatch): boolean {\n if (!queued) return false;\n queued.set(key, { ...queued.get(key), ...updates });\n return true;\n}\n\n/** Runs `run`, returning the patches it queued; null when an outer batch already collects them. */\nexport function collectElementPatches(run: () => void): Map<string, TimelineElementPatch> | null {\n if (queued) {\n run();\n return null;\n }\n const patches = (queued = new Map());\n try {\n run();\n } finally {\n queued = null;\n }\n return patches;\n}\n\nexport function patchElements(\n elements: TimelineElement[],\n patches: ReadonlyMap<string, TimelineElementPatch>,\n): TimelineElement[] {\n return elements.map((el) => {\n const patch = patches.get(el.key ?? el.id);\n return patch ? { ...el, ...patch } : el;\n });\n}\n","import { buildProjectApiPath } from \"../../utils/projectRouting\";\nimport { forwardRef, useEffect, useRef, useState } from \"react\";\nimport { isLottieAnimationLoaded } from \"@hyperframes/core/runtime/lottie-readiness\";\nimport { useMountEffect } from \"../../hooks/useMountEffect\";\nimport { applyPreviewVariablesToUrl } from \"../../hooks/previewVariablesStore\";\nimport { HyperframesLoader } from \"../../components/ui\";\nimport { usePlayerStore } from \"../store/playerStore\";\n// Importing \"@hyperframes/player\" registers a class extending HTMLElement at\n// module load, which throws under SSR, hence the dynamic import behind a\n// `typeof window` guard. Kicking it here rather than in the mount effect puts\n// the chunk request in flight before the shell's first layout. Clearing the memo\n// on rejection stops one failure poisoning every later mount; the browser's\n// module map still caches a failed fetch, so recovery is a page reload.\nlet playerModule: Promise<unknown> | null = null;\n\nexport function loadPlayerModule(): Promise<unknown> {\n playerModule ??= import(\"@hyperframes/player\").catch((err: unknown) => {\n playerModule = null;\n throw err;\n });\n return playerModule;\n}\n\nif (typeof window !== \"undefined\") void loadPlayerModule().catch(() => {});\n\ninterface PlayerProps {\n projectId?: string;\n directUrl?: string;\n onLoad: () => void;\n /** Fires once the loaded document is painted and every loader (shader, assets) has cleared. */\n onReadyToShowChange?: (ready: boolean) => void;\n onPreviewError?: (message: string) => void;\n onCompositionLoadingChange?: (loading: boolean) => void;\n onPainted?: (details: { iframe: HTMLIFrameElement; startedAt: number; loadId: number }) => void;\n portrait?: boolean;\n style?: React.CSSProperties;\n suppressLoadingOverlay?: boolean;\n}\n\ninterface HyperframesPlayerElement extends HTMLElement {\n iframeElement: HTMLIFrameElement;\n ready?: boolean;\n painted?: boolean;\n}\n\nconst MEDIA_HAVE_FUTURE_DATA = 3;\nconst MEDIA_NETWORK_NO_SOURCE = 3;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction getShaderTransitionLoading(event: Event): boolean | null {\n if (!(event instanceof CustomEvent)) return null;\n const detail: unknown = event.detail;\n if (!isRecord(detail)) return null;\n const state = detail.state;\n if (!isRecord(state)) return null;\n return state.loading === true && state.ready !== true;\n}\n\nconst COMPOSITION_LOADING_OVERLAY_DELAY_MS = 400;\nconst PREVIEW_BOOT_DEADLINE_MS = 5000;\nconst DEFAULT_PREVIEW_ERROR = \"The composition preview did not become ready.\";\n\nexport function shouldShowCompositionLoadingOverlay(compositionLoading: boolean): boolean {\n return compositionLoading;\n}\n\nexport function readPreviewErrorMessage(event: Event): string {\n if (!(event instanceof CustomEvent) || !isRecord(event.detail)) return DEFAULT_PREVIEW_ERROR;\n return typeof event.detail.message === \"string\" && event.detail.message.trim()\n ? event.detail.message\n : DEFAULT_PREVIEW_ERROR;\n}\n\nfunction enableInteractiveIframe(player: HyperframesPlayerElement): void {\n const root = player.shadowRoot;\n if (!root) return;\n\n const container = root.querySelector<HTMLElement>(\".hfp-container\");\n const iframe = root.querySelector<HTMLIFrameElement>(\".hfp-iframe\");\n\n container?.style.setProperty(\"pointer-events\", \"auto\");\n iframe?.style.setProperty(\"pointer-events\", \"auto\");\n}\n\nfunction isPreviewMediaElement(el: Element): el is HTMLMediaElement {\n const tagName = el.tagName.toLowerCase();\n return tagName === \"video\" || tagName === \"audio\";\n}\n\n// Assets are considered ready when every `<video>`/`<audio>` has enough data\n// to play through without buffering, and every registered Lottie animation has\n// finished loading.\n//\n// Returns whichever value was returned last on cross-origin / transient DOM\n// races so a brief access failure (e.g. an iframe that just swapped src)\n// doesn't flicker the overlay state — we keep showing whatever was most\n// recently true.\nexport function hasUnloadedAssets(iframe: HTMLIFrameElement, lastResult: boolean): boolean {\n try {\n const win = iframe.contentWindow as unknown as (Window & { __hfLottie?: unknown[] }) | null;\n const doc = iframe.contentDocument;\n if (!win || !doc) return lastResult;\n\n for (const el of doc.querySelectorAll(\"video, audio\")) {\n if (\n isPreviewMediaElement(el) &&\n !el.error &&\n el.networkState !== MEDIA_NETWORK_NO_SOURCE &&\n el.readyState < MEDIA_HAVE_FUTURE_DATA\n ) {\n return true;\n }\n }\n\n const lotties = win.__hfLottie;\n if (lotties?.length) {\n for (const anim of lotties) {\n if (!isLottieAnimationLoaded(anim)) return true;\n }\n }\n\n return false;\n } catch {\n return lastResult;\n }\n}\n\n/**\n * Renders a composition preview using the <hyperframes-player> web component.\n *\n * The web component handles iframe scaling, dimension detection, and\n * ResizeObserver internally. This wrapper bridges its inner iframe to the\n * forwarded ref so useTimelinePlayer can access it for clip manifest parsing,\n * timeline probing, and DOM inspection.\n */\nexport const Player = forwardRef<HTMLIFrameElement, PlayerProps>(\n (\n {\n projectId,\n directUrl,\n onLoad,\n onReadyToShowChange,\n onPreviewError,\n onCompositionLoadingChange,\n onPainted,\n portrait,\n style,\n suppressLoadingOverlay,\n },\n ref,\n ) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const loadCountRef = useRef(0);\n const assetPollRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const assetFadeRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const retryPreviewRef = useRef<(() => void) | null>(null);\n const loadStartedAtRef = useRef(0);\n const loadIdRef = useRef(0);\n const retryCountRef = useRef(0);\n // Read at call time: this element outlives its first props (a shadow preview is\n // promoted in place), so mount-time closures would go stale.\n const onLoadRef = useRef(onLoad);\n onLoadRef.current = onLoad;\n const onReadyToShowChangeRef = useRef(onReadyToShowChange);\n onReadyToShowChangeRef.current = onReadyToShowChange;\n const onPreviewErrorRef = useRef(onPreviewError);\n onPreviewErrorRef.current = onPreviewError;\n const [loaded, setLoaded] = useState(false);\n const [assetsLoading, setAssetsLoading] = useState(false);\n const [assetOverlayVisible, setAssetOverlayVisible] = useState(false);\n const [assetOverlayFading, setAssetOverlayFading] = useState(false);\n const [assetWaitLong, setAssetWaitLong] = useState(false);\n const [shaderTransitionLoading, setShaderTransitionLoading] = useState(false);\n const [compositionLoading, setCompositionLoading] = useState(true);\n const [painted, setPainted] = useState(false);\n const [compositionOverlayDeferred, setCompositionOverlayDeferred] = useState(true);\n const [previewError, setPreviewError] = useState<string | null>(null);\n\n // eslint-disable-next-line no-restricted-syntax\n useEffect(() => {\n if (!compositionLoading) {\n setCompositionOverlayDeferred(true);\n return;\n }\n const timer = setTimeout(\n () => setCompositionOverlayDeferred(false),\n COMPOSITION_LOADING_OVERLAY_DELAY_MS,\n );\n return () => clearTimeout(timer);\n }, [compositionLoading]);\n\n useMountEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const previewSource =\n directUrl || (projectId ? buildProjectApiPath(projectId, \"/preview\") : null);\n if (!previewSource) return;\n\n let canceled = false;\n let cleanup: (() => void) | undefined;\n\n void loadPlayerModule().then(() => {\n if (canceled) return;\n\n // Create the web component imperatively to avoid JSX custom-element typing.\n const player = document.createElement(\"hyperframes-player\") as HyperframesPlayerElement;\n const srcUrl = new URL(previewSource, window.location.origin);\n applyPreviewVariablesToUrl(srcUrl);\n const src = srcUrl.pathname + srcUrl.search;\n const retryPreview = () => {\n retryCountRef.current += 1;\n const retryUrl = new URL(src, window.location.origin);\n retryUrl.searchParams.set(\"_hfStudioRetry\", String(retryCountRef.current));\n setPreviewError(null);\n setCompositionLoading(true);\n loadStartedAtRef.current = performance.now();\n loadIdRef.current += 1;\n player.setAttribute(\"src\", retryUrl.pathname + retryUrl.search);\n };\n retryPreviewRef.current = retryPreview;\n const iframe = player.iframeElement;\n const preventToggle = (e: Event) => e.stopImmediatePropagation();\n const handleShaderTransitionState = (event: Event) => {\n const loading = getShaderTransitionLoading(event);\n if (loading !== null) setShaderTransitionLoading(loading);\n };\n const handleReady = () => {\n setPreviewError(null);\n setCompositionLoading(false);\n };\n const handlePainted = () => {\n setPainted(true);\n onPainted?.({ iframe, startedAt: loadStartedAtRef.current, loadId: loadIdRef.current });\n };\n const handleError = (event: Event) => {\n const message = readPreviewErrorMessage(event);\n onPreviewErrorRef.current?.(message);\n setPreviewError(message);\n setCompositionLoading(false);\n };\n const handleLoad = () => {\n loadCountRef.current++;\n setLoaded(true);\n setPreviewError(null);\n setShaderTransitionLoading(false);\n setCompositionLoading(!player.ready);\n setPainted(Boolean(player.painted));\n // Reveal animation on reload (hot-reload, composition switch)\n if (loadCountRef.current > 1) {\n container.classList.remove(\"preview-revealing\");\n void container.offsetWidth;\n container.classList.add(\"preview-revealing\");\n const onEnd = () => container.classList.remove(\"preview-revealing\");\n container.addEventListener(\"animationend\", onEnd, { once: true });\n }\n onLoadRef.current();\n\n // Show a loading overlay until every `<video>`/`<audio>` and Lottie\n // asset is ready. Without this users can click play before audio has\n // buffered — the runtime is resilient (queued play() resolves once\n // data arrives), but the overlay communicates why the first frame\n // or first audio beat may lag.\n //\n // Skip the overlay on subsequent loads (content refreshes via\n // refreshPlayer). The browser has already cached the assets from\n // the first load, so they resolve near-instantly and the overlay\n // just creates a disruptive flash.\n //\n // Poll with a 10 s safety cap (100 ticks × 100 ms). If the cap\n // trips we hide the overlay so the UI doesn't appear stuck forever,\n // but we log a debug warning so the case is diagnosable — a long\n // cold video or a broken asset can legitimately exceed 10 s on a\n // slow network.\n if (assetPollRef.current) clearInterval(assetPollRef.current);\n const isContentRefresh = loadCountRef.current > 1;\n let lastUnloaded = isContentRefresh ? false : hasUnloadedAssets(iframe, false);\n if (lastUnloaded) {\n setAssetsLoading(true);\n let attempts = 0;\n assetPollRef.current = setInterval(() => {\n attempts += 1;\n lastUnloaded = hasUnloadedAssets(iframe, lastUnloaded);\n if (!lastUnloaded || attempts > 100) {\n if (lastUnloaded && attempts > 100) {\n console.debug(\n \"[studio] asset readiness poll hit the 10s cap — continuing with unloaded assets\",\n );\n }\n if (assetPollRef.current) clearInterval(assetPollRef.current);\n assetPollRef.current = null;\n setAssetsLoading(false);\n }\n }, 100);\n } else {\n setAssetsLoading(false);\n }\n };\n\n // Attach lifecycle listeners before assigning src or connecting the\n // custom element. A warm local iframe can otherwise finish before\n // Studio observes its load and never initialize the timeline.\n iframe.addEventListener(\"load\", handleLoad);\n player.addEventListener(\"click\", preventToggle, { capture: true });\n player.addEventListener(\"shadertransitionstate\", handleShaderTransitionState);\n player.addEventListener(\"ready\", handleReady);\n player.addEventListener(\"painted\", handlePainted);\n player.addEventListener(\"error\", handleError);\n\n // Bridge the inner iframe to the forwarded ref for useTimelinePlayer.\n if (typeof ref === \"function\") {\n ref(iframe);\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLIFrameElement | null>).current = iframe;\n }\n\n player.setAttribute(\"shader-capture-scale\", \"1\");\n player.setAttribute(\"shader-loading\", \"player\");\n player.setAttribute(\"low-power-idle\", \"\");\n player.setAttribute(\"width\", String(portrait ? 1080 : 1920));\n player.setAttribute(\"height\", String(portrait ? 1920 : 1080));\n player.style.width = \"100%\";\n player.style.height = \"100%\";\n player.style.display = \"block\";\n player.style.background = \"transparent\";\n loadStartedAtRef.current = performance.now();\n loadIdRef.current += 1;\n player.setAttribute(\"src\", src);\n container.appendChild(player);\n\n // Inject pasteboard shadow: let the shadow around the canvas bleed\n // into the surrounding pasteboard area (overflow: visible on the container)\n // and add a subtle outline + drop-shadow so the canvas boundary reads\n // against the gray pasteboard, consistent with professional editors.\n if (player.shadowRoot) {\n const pasteboardStyle = document.createElement(\"style\");\n pasteboardStyle.textContent =\n \".hfp-container{overflow:visible}\" +\n \".hfp-iframe{box-shadow:0 0 0 1px rgba(255,255,255,0.08),0 4px 32px rgba(0,0,0,.7)}\";\n player.shadowRoot.appendChild(pasteboardStyle);\n }\n\n enableInteractiveIframe(player);\n\n cleanup = () => {\n iframe.removeEventListener(\"load\", handleLoad);\n player.removeEventListener(\"click\", preventToggle, { capture: true });\n player.removeEventListener(\"shadertransitionstate\", handleShaderTransitionState);\n player.removeEventListener(\"ready\", handleReady);\n player.removeEventListener(\"painted\", handlePainted);\n player.removeEventListener(\"error\", handleError);\n if (assetPollRef.current) clearInterval(assetPollRef.current);\n assetPollRef.current = null;\n // `remove()` rather than `container.removeChild(player)`: by the time\n // this cleanup runs the element may already be detached — React can\n // re-render the container, a crossfade refresh can swap it, or a\n // translation/extension can reparent it. `removeChild` then throws\n // NotFoundError, which the error boundary turns into a full-screen\n // \"Something went wrong\". `remove()` is a no-op when already detached.\n player.remove();\n if (retryPreviewRef.current === retryPreview) retryPreviewRef.current = null;\n // Clear the forwarded ref only if it still points to THIS iframe.\n // During crossfade refreshes the retiring Player unmounts after the\n // new Player has already assigned its iframe to the same ref — blindly\n // nulling it would break seeking in the new Player.\n // Callback refs are skipped — we can't read back the current value to\n // guard against clobbering a newer assignment. The mutable-ref branch\n // (the only path used today) is guarded by identity check.\n if (typeof ref === \"function\") {\n // no-op: can't safely guard callback refs\n } else if (ref) {\n const mutableRef = ref as React.MutableRefObject<HTMLIFrameElement | null>;\n if (mutableRef.current === iframe) {\n mutableRef.current = null;\n }\n }\n };\n });\n\n return () => {\n canceled = true;\n cleanup?.();\n };\n });\n\n // Surface a \"Continue anyway\" escape hatch once the asset wait drags on.\n // eslint-disable-next-line no-restricted-syntax\n useEffect(() => {\n if (!assetsLoading) {\n setAssetWaitLong(false);\n return;\n }\n const timer = setTimeout(() => setAssetWaitLong(true), 3000);\n return () => clearTimeout(timer);\n }, [assetsLoading]);\n\n useEffect(() => {\n if (assetFadeRef.current) {\n clearTimeout(assetFadeRef.current);\n assetFadeRef.current = null;\n }\n\n if (assetsLoading) {\n setAssetOverlayVisible(true);\n setAssetOverlayFading(false);\n return;\n }\n\n setAssetOverlayFading(true);\n assetFadeRef.current = setTimeout(() => {\n setAssetOverlayVisible(false);\n setAssetOverlayFading(false);\n assetFadeRef.current = null;\n }, 240);\n\n return () => {\n if (assetFadeRef.current) {\n clearTimeout(assetFadeRef.current);\n assetFadeRef.current = null;\n }\n };\n }, [assetsLoading]);\n\n const handleContinueAnyway = () => {\n if (assetPollRef.current) {\n clearInterval(assetPollRef.current);\n assetPollRef.current = null;\n }\n setAssetsLoading(false);\n };\n\n const firstFrameShown =\n loaded && painted && !compositionLoading && !shaderTransitionLoading && !previewError;\n const readyToShow = firstFrameShown && !assetsLoading;\n // Work waiting on the boot starts at the first frame, while media still buffers.\n useEffect(() => {\n if (firstFrameShown) usePlayerStore.getState().markPreviewBooted();\n }, [firstFrameShown]);\n // `painted` means the player's own loader has finished fading; two frames of grace on top.\n useEffect(() => {\n if (!readyToShow) {\n onReadyToShowChangeRef.current?.(false);\n return;\n }\n let second = 0;\n const first = requestAnimationFrame(() => {\n second = requestAnimationFrame(() => onReadyToShowChangeRef.current?.(true));\n });\n return () => {\n cancelAnimationFrame(first);\n cancelAnimationFrame(second);\n };\n }, [readyToShow]);\n\n useEffect(() => {\n if (previewError) usePlayerStore.getState().markPreviewBooted();\n }, [previewError]);\n\n useEffect(() => {\n const timer = setTimeout(\n () => usePlayerStore.getState().markPreviewBooted(),\n PREVIEW_BOOT_DEADLINE_MS,\n );\n return () => clearTimeout(timer);\n }, [projectId]);\n\n const showCompositionOverlay =\n !suppressLoadingOverlay &&\n !compositionOverlayDeferred &&\n shouldShowCompositionLoadingOverlay(compositionLoading);\n const showAssetOverlay =\n assetOverlayVisible && !shaderTransitionLoading && !showCompositionOverlay && !previewError;\n\n useEffect(() => {\n onCompositionLoadingChange?.(showCompositionOverlay || showAssetOverlay);\n }, [onCompositionLoadingChange, showCompositionOverlay, showAssetOverlay]);\n\n return (\n <div\n className=\"relative w-full h-full max-w-full max-h-full overflow-hidden flex items-center justify-center\"\n style={style}\n >\n <div ref={containerRef} className=\"w-full h-full\" />\n {showCompositionOverlay && (\n <div\n className=\"absolute inset-0 bg-black flex items-center justify-center z-30 select-none\"\n data-hyperframes-ignore=\"\"\n data-testid=\"composition-loading-overlay\"\n draggable={false}\n onDragStart={(event) => event.preventDefault()}\n onMouseDown={(event) => event.preventDefault()}\n onPointerDown={(event) => event.preventDefault()}\n >\n <HyperframesLoader\n title=\"Loading composition\"\n detail=\"Preparing the Studio preview.\"\n size={56}\n />\n </div>\n )}\n {showAssetOverlay && (\n <div\n className=\"absolute inset-0 bg-black flex items-center justify-center z-20 select-none\"\n data-hyperframes-ignore=\"\"\n draggable={false}\n style={{\n opacity: assetOverlayFading ? 0 : 1,\n pointerEvents: assetOverlayFading ? \"none\" : \"auto\",\n transition: \"opacity 180ms ease-in\",\n }}\n onDragStart={(event) => event.preventDefault()}\n onMouseDown={(event) => event.preventDefault()}\n >\n <div className=\"flex flex-col items-center gap-3\">\n <HyperframesLoader\n title=\"Preparing preview assets\"\n detail=\"Waiting for media and motion assets before playback starts.\"\n size={56}\n />\n {assetWaitLong && (\n <button\n type=\"button\"\n onClick={handleContinueAnyway}\n className=\"px-3 py-1.5 text-[11px] rounded-md border border-neutral-700 text-neutral-300 hover:border-neutral-500 hover:bg-neutral-800 transition-colors\"\n >\n Continue anyway\n </button>\n )}\n </div>\n </div>\n )}\n {previewError && (\n <div\n className=\"absolute inset-0 z-40 flex items-center justify-center bg-black/90 px-6 text-center\"\n data-hyperframes-ignore=\"\"\n data-testid=\"composition-preview-error\"\n >\n <div className=\"max-w-sm\">\n <p className=\"text-sm font-semibold text-white\">Preview failed to load</p>\n <p className=\"mt-1 text-xs text-neutral-400\">{previewError}</p>\n <button\n type=\"button\"\n className=\"mt-4 rounded-md bg-white px-3 py-1.5 text-xs font-semibold text-black transition-colors hover:bg-neutral-200\"\n onClick={() => retryPreviewRef.current?.()}\n >\n Retry preview\n </button>\n </div>\n </div>\n )}\n </div>\n );\n },\n);\n\nPlayer.displayName = \"Player\";\n","import { useEffect } from \"react\";\n\n/**\n * Run an effect exactly once on mount (and optional cleanup on unmount).\n * This is the ONLY sanctioned way to call useEffect in this codebase.\n *\n * If you need to react to prop/state changes, use one of:\n * - Derived state (compute inline, no hook needed)\n * - Event handlers (onClick, onChange, etc.)\n * - `key` prop to force remount\n * - Data-fetching library (useQuery, useSWR)\n *\n * @see https://react.dev/learn/you-might-not-need-an-effect\n */\nexport function useMountEffect(effect: () => void | (() => void)) {\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(effect, []);\n}\n","import { create } from \"zustand\";\n\n/**\n * Ephemeral composition-variable overrides for the preview iframe.\n *\n * Values here are NEVER persisted to the composition — they ride the preview\n * URL as `?variables=<json>` (see the studio-server preview routes), which the\n * server injects as `window.__hfVariables` exactly like render-time injection,\n * so what the user previews is what `hyperframes render --variables` produces.\n * `null` means \"preview with declared defaults\".\n */\ninterface PreviewVariablesState {\n values: Record<string, unknown> | null;\n setValues: (values: Record<string, unknown> | null) => void;\n}\n\nexport const usePreviewVariablesStore = create<PreviewVariablesState>((set) => ({\n values: null,\n setValues: (values) => set({ values: values && Object.keys(values).length > 0 ? values : null }),\n}));\n\n/**\n * Apply the current preview-variable overrides to a preview URL (both the\n * Player's initial mount and refreshPlayer's soft reload route through this,\n * so a hard remount can't silently drop the active overrides).\n */\nexport function applyPreviewVariablesToUrl(url: URL): void {\n const values = usePreviewVariablesStore.getState().values;\n if (values) {\n url.searchParams.set(\"variables\", JSON.stringify(values));\n } else {\n url.searchParams.delete(\"variables\");\n }\n}\n"],"mappings":"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","names":["isRecord","useEffect","create","isRecord","useEffect"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/ui/cn.ts","../src/components/ui/Button.tsx","../src/components/ui/IconButton.tsx","../src/components/ui/Tabs.tsx","../src/components/ui/HyperframesMark.tsx","../src/components/ui/HyperframesLoader.tsx","../src/components/ui/Menu.tsx","../src/components/ui/Tooltip.tsx","../src/components/ui/Popover.tsx","../src/components/ui/Input.tsx","../src/components/ui/NumberField.tsx","../src/components/ui/Select.tsx","../src/components/ui/Slider.tsx","../src/components/ui/Toggle.tsx"],"sourcesContent":["/**\n * Studio's tailwind-merge config: teaches it the two scales `theme.css`\n * invents (`text-step-*`, `ctl`/`ctl-sm`/`ctl-lg`) so overrides replace, not stack.\n */\n\nimport type { CnFunction } from \"cn\";\nimport { createCn } from \"cn/config\";\n\n/** `text-step-11`, `text-step-9`, … — the type scale from `theme.css`. */\nconst isTypeStep = (value: string) => /^step-\\d+$/.test(value);\n\n/** `ctl`, `ctl-sm`, `ctl-lg` — the control heights from `theme.css`. */\nconst isControlSize = (value: string) => /^ctl(-sm|-lg)?$/.test(value);\n\nexport const cn: CnFunction = createCn({\n extend: {\n classGroups: {\n \"font-size\": [{ text: [isTypeStep] }],\n h: [{ h: [isControlSize] }],\n w: [{ w: [isControlSize] }],\n size: [{ size: [isControlSize] }],\n \"min-h\": [{ \"min-h\": [isControlSize] }],\n \"min-w\": [{ \"min-w\": [isControlSize] }],\n },\n },\n});\n","/**\n * Button — a native `<button>` wearing Studio's tokens.\n *\n * Everything visual comes from `theme.css`: the three control heights, the\n * radius scale, the semantic colours, the motion durations. No value is decided\n * here, so a button cannot drift from the rest of the system.\n *\n * Two conventions: classes merge through `cn`, so a caller's `className`\n * always wins within its group; and every interactive look is written twice,\n * once as the real state and once as `data-[preview-state=…]` (CSS-only, for\n * screenshots). `Button.test.tsx` asserts the two stay in sync.\n */\n\nimport { forwardRef, type ButtonHTMLAttributes, type ReactNode } from \"react\";\nimport { cn } from \"./cn\";\n\nexport type ButtonVariant = \"primary\" | \"secondary\" | \"danger\" | \"ghost\";\nexport type ButtonSize = \"sm\" | \"md\" | \"lg\";\n\n/** Forces one interactive look for a gallery shot. CSS-only; see the header. */\nexport type PreviewState = \"hover\" | \"active\" | \"focus\";\n\nexport interface ButtonBaseProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n \"data-preview-state\"?: PreviewState;\n}\n\ninterface ButtonProps extends ButtonBaseProps {\n loading?: boolean;\n icon?: ReactNode;\n}\n\n/**\n * Shared by Button and IconButton. `disabled:` keeps pointer events alive so a\n * wrapping Tooltip can still explain why the control is disabled.\n */\nexport const buttonBase = cn(\n \"inline-flex items-center justify-center select-none cursor-pointer whitespace-nowrap\",\n \"transition-[background-color,border-color,color,filter,transform] ease-out-quint duration-press\",\n \"disabled:opacity-40 disabled:cursor-not-allowed\",\n \"outline-hidden\",\n \"focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-accent\",\n \"data-[preview-state=focus]:outline-solid data-[preview-state=focus]:outline-2 data-[preview-state=focus]:outline-offset-1 data-[preview-state=focus]:outline-accent\",\n);\n\n/**\n * One entry per variant. The `data-[preview-state=…]` half of each string\n * repeats the `hover:` and `active:` half exactly; the test pairs them.\n */\nexport const buttonVariants: Record<ButtonVariant, string> = {\n primary: cn(\n \"bg-accent text-on-accent font-semibold\",\n \"enabled:hover:bg-accent-hover data-[preview-state=hover]:bg-accent-hover\",\n \"enabled:active:scale-[0.98] data-[preview-state=active]:scale-[0.98]\",\n ),\n secondary: cn(\n \"bg-transparent text-text-1 font-medium border border-border-strong\",\n \"enabled:hover:bg-hover enabled:hover:text-text-0 data-[preview-state=hover]:bg-hover data-[preview-state=hover]:text-text-0\",\n \"enabled:active:scale-[0.98] data-[preview-state=active]:scale-[0.98]\",\n ),\n danger: cn(\n \"bg-danger text-on-danger font-medium\",\n \"enabled:hover:brightness-95 data-[preview-state=hover]:brightness-95\",\n \"enabled:active:scale-[0.98] data-[preview-state=active]:scale-[0.98]\",\n ),\n ghost: cn(\n \"bg-transparent text-text-2 font-medium\",\n \"enabled:hover:bg-hover enabled:hover:text-text-0 data-[preview-state=hover]:bg-hover data-[preview-state=hover]:text-text-0\",\n \"enabled:active:scale-[0.98] data-[preview-state=active]:scale-[0.98]\",\n ),\n};\n\n/**\n * The three control heights, 24 / 28 / 32 px, from `--spacing-ctl-*`.\n * Exported so the Capture download `<a href>` can wear the same recipe as a Button.\n */\nexport const buttonSizes: Record<ButtonSize, string> = {\n sm: \"h-ctl-sm px-2 gap-1 rounded-sm text-step-11\",\n md: \"h-ctl px-3 gap-1.5 rounded-md text-step-12\",\n lg: \"h-ctl-lg px-4 gap-2 rounded-md text-step-13\",\n};\n\nfunction Spinner() {\n return (\n <svg className=\"animate-spin size-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\" />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\"\n />\n </svg>\n );\n}\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n (\n { variant = \"secondary\", size = \"md\", loading, icon, children, className, disabled, ...props },\n ref,\n ) => {\n const isDisabled = disabled || loading;\n let leading: ReactNode = null;\n if (loading) leading = <Spinner />;\n else if (icon) leading = <span className=\"shrink-0\">{icon}</span>;\n return (\n <button\n ref={ref}\n disabled={isDisabled}\n // `aria-disabled` as well as `disabled`: assistive tech announces the\n // state even where the native attribute is filtered out of the tree.\n aria-disabled={isDisabled || undefined}\n className={cn(buttonBase, buttonVariants[variant], buttonSizes[size], className)}\n {...props}\n >\n {leading}\n {children}\n </button>\n );\n },\n);\nButton.displayName = \"Button\";\n","/**\n * IconButton — Button's square sibling; shares its base/variant classes so\n * the two never drift. `aria-label` is required for screen readers.\n */\n\nimport { forwardRef } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { buttonBase, buttonVariants, type ButtonBaseProps, type ButtonSize } from \"./Button\";\nimport { cn } from \"./cn\";\n\ninterface IconButtonProps extends ButtonBaseProps {\n icon: ReactNode;\n \"aria-label\": string;\n}\n\n/** Square boxes on the same 24 / 28 / 32 px control heights as Button. */\nconst iconSizeStyles: Record<ButtonSize, string> = {\n sm: \"size-ctl-sm rounded-sm\",\n md: \"size-ctl rounded-md\",\n lg: \"size-ctl-lg rounded-md\",\n};\n\nexport const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(\n ({ icon, size = \"md\", variant = \"ghost\", className, disabled, ...props }, ref) => {\n return (\n <button\n ref={ref}\n disabled={disabled}\n aria-disabled={disabled || undefined}\n className={cn(buttonBase, buttonVariants[variant], iconSizeStyles[size], className)}\n {...props}\n >\n {icon}\n </button>\n );\n },\n);\nIconButton.displayName = \"IconButton\";\n","/**\n * Tabs — Base UI's tabs wearing Studio's tokens; replaces six hand-rolled\n * strips with one implementation (roving tabindex, arrow/Home/End, `aria-controls`).\n */\n\nimport { Tabs as BaseTabs } from \"@base-ui/react/tabs\";\nimport type { ComponentPropsWithoutRef, ElementType } from \"react\";\nimport { cn } from \"./cn\";\nimport type { PreviewState } from \"./Button\";\n\n/**\n * Base UI lets `className` be a function of the part's state. Studio's parts\n * merge a string with `cn`, so the string form is the one they accept.\n */\ntype StyledProps<T extends ElementType> = Omit<ComponentPropsWithoutRef<T>, \"className\"> & {\n className?: string;\n};\n\n/**\n * Groups a tab list with its panels. Uncontrolled by default; pass `value` and\n * `onValueChange` for a strip whose selection lives in a store.\n */\nexport function Tabs(props: ComponentPropsWithoutRef<typeof BaseTabs.Root>) {\n return <BaseTabs.Root {...props} />;\n}\n\n/** The strip. Give it an `aria-label`: a tablist with no name is unlabelled. */\nexport function TabsList({ className, ...props }: StyledProps<typeof BaseTabs.List>) {\n return (\n <BaseTabs.List\n // Arrow keys move selection, matching today's sidebar strip.\n activateOnFocus\n className={cn(\"inline-flex items-center gap-0.5 rounded-lg bg-surface-alt p-1\", className)}\n {...props}\n />\n );\n}\n\ninterface TabProps extends StyledProps<typeof BaseTabs.Tab> {\n value: string;\n \"data-preview-state\"?: PreviewState;\n}\n\n/**\n * aria-selected drives the selected look (Base UI sets it) so assistive tech\n * and sighted users match. data-preview-state is for gallery shots only.\n */\nexport function Tab({ value, className, ...props }: TabProps) {\n return (\n <BaseTabs.Tab\n value={value}\n data-tab-id={value}\n className={cn(\n \"inline-flex h-ctl-sm cursor-pointer select-none items-center justify-center rounded-sm px-2.5\",\n \"text-step-11 font-semibold whitespace-nowrap text-text-3\",\n \"transition-[background-color,color] ease-out-quint duration-hover\",\n \"hover:text-text-1 data-[preview-state=hover]:text-text-1\",\n \"aria-selected:bg-hover aria-selected:text-text-0\",\n \"outline-hidden focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-accent\",\n \"data-[preview-state=focus]:outline-solid data-[preview-state=focus]:outline-2 data-[preview-state=focus]:outline-offset-1 data-[preview-state=focus]:outline-accent\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/** The panel for one tab. Base UI wires `aria-labelledby` back to its tab. */\nexport function TabPanel({ className, ...props }: StyledProps<typeof BaseTabs.Panel>) {\n return <BaseTabs.Panel className={cn(\"outline-hidden\", className)} {...props} />;\n}\n","import { useId, type SVGProps } from \"react\";\n\nexport function HyperframesMark({ viewBox = \"0 0 100 100\", ...props }: SVGProps<SVGSVGElement>) {\n const gradientId = useId();\n const leftGradient = `${gradientId}-left`;\n const rightGradient = `${gradientId}-right`;\n return (\n <svg\n viewBox={viewBox}\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n {...props}\n >\n <g transform=\"translate(50 50)\" opacity=\".92\">\n <g transform=\"translate(-50 -50)\">\n <path\n d=\"M10.1851 57.8021L33.1145 73.8313C36.2202 75.9978 41.5173 73.5433 42.4816 69.4984L51.7611 30.4271C52.7253 26.3822 48.5802 23.9277 44.4602 26.0942L13.917 42.1235C6.96677 45.7676 4.97564 54.1579 10.1851 57.8021Z\"\n fill={`url(#${leftGradient})`}\n />\n <path\n d=\"M87.5129 57.5141L56.9696 73.5433C52.8371 75.7098 48.7046 73.2553 49.6688 69.2104L58.9483 30.1391C59.9125 26.0942 65.2097 23.6397 68.3154 25.8062L91.2447 41.8354C96.4668 45.4796 94.4631 53.8699 87.5129 57.5141Z\"\n fill={`url(#${rightGradient})`}\n />\n </g>\n </g>\n <defs>\n <linearGradient\n id={leftGradient}\n x1=\"48.5676\"\n y1=\"25\"\n x2=\"44.7804\"\n y2=\"71.9384\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#06E3FA\" />\n <stop offset=\"1\" stopColor=\"#4FDB5E\" />\n </linearGradient>\n <linearGradient\n id={rightGradient}\n x1=\"54.8282\"\n y1=\"73.8392\"\n x2=\"72.0989\"\n y2=\"32.8932\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#06E3FA\" />\n <stop offset=\"1\" stopColor=\"#4FDB5E\" />\n </linearGradient>\n </defs>\n </svg>\n );\n}\n","import { HyperframesMark } from \"./HyperframesMark\";\n\nexport interface HyperframesLoaderProps {\n /** Status text shown below the mark. */\n title: string;\n /** Optional secondary detail line. */\n detail?: string;\n /** Optional monospace third line for IDs, counts, or percentages. */\n mono?: string;\n /** Pixel size of the mark itself; status text scales independently. */\n size?: number;\n /** Optional normalized progress value from 0 to 1. */\n progress?: number;\n}\n\nexport function HyperframesLoader({\n title,\n detail,\n mono,\n size = 64,\n progress,\n}: HyperframesLoaderProps) {\n const boundedProgress =\n typeof progress === \"number\" && Number.isFinite(progress)\n ? Math.min(1, Math.max(0, progress))\n : undefined;\n const markFrameSize = Math.round(size * 1.16);\n\n return (\n <div className=\"hf-loader\" role=\"status\" draggable={false}>\n <div\n className=\"hf-loader-mark-frame\"\n style={{ width: markFrameSize, height: markFrameSize }}\n draggable={false}\n >\n <HyperframesMark className=\"hf-loader-mark\" width={size} height={size} />\n </div>\n <div className=\"hf-loader-title\">{title}</div>\n {detail && <div className=\"hf-loader-detail\">{detail}</div>}\n {boundedProgress !== undefined && (\n <div\n className=\"hf-loader-progress\"\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={Math.round(boundedProgress * 100)}\n >\n <div\n className=\"hf-loader-progress__fill\"\n style={{ transform: `scaleX(${boundedProgress})` }}\n />\n </div>\n )}\n {mono && <div className=\"hf-loader-mono\">{mono}</div>}\n </div>\n );\n}\n\n// fallow-ignore-next-line unused-export\nexport function StatusFrame(props: HyperframesLoaderProps) {\n return (\n <div className=\"hf-frame\">\n <HyperframesLoader {...props} />\n </div>\n );\n}\n","/**\n * Menu and ContextMenu on Base UI. Dismissal is plain Base UI (capture-phase listeners survive the overlay's\n * `stopPropagation`); `trigger` is rendered, not wrapped; `container` exists for shadow roots.\n */\n\nimport { ContextMenu as BaseContextMenu } from \"@base-ui/react/context-menu\";\nimport { Menu as BaseMenu } from \"@base-ui/react/menu\";\nimport type { ComponentPropsWithoutRef, ElementType, ReactElement, ReactNode } from \"react\";\nimport { cn } from \"./cn\";\n\n/**\n * Base UI lets `className` be a function of the part's state. Studio's parts\n * merge a string with `cn`, so the string form is the one they accept.\n */\ntype StyledProps<T extends ElementType> = Omit<ComponentPropsWithoutRef<T>, \"className\"> & {\n className?: string;\n};\n\n/** Forces the settled open look for a gallery shot; CSS-only, open state stays controlled. */\nexport type PopupPreviewState = \"open\";\n\n/** Where the portal puts the popup. `null` keeps it inline, next to its trigger. */\ntype PortalContainer = ComponentPropsWithoutRef<typeof BaseMenu.Portal>[\"container\"];\n\n/** Matches Tooltip's gap from its trigger, and its viewport margin. */\nconst SIDE_OFFSET = 6;\nconst VIEWPORT_MARGIN = 8;\n\n/**\n * Enter and exit shared by menus, popovers, dropdowns, and tooltips.\n * The open duration class differs; the shape does not.\n * `data-starting-style`/`data-ending-style` are Base UI's transition attributes.\n */\nexport function floatingMotion(openDuration: \"duration-open\" | \"duration-tooltip\") {\n return cn(\n \"origin-[var(--transform-origin)] outline-hidden\",\n \"transition-[opacity,transform] ease-out-quint\",\n openDuration,\n \"data-[ending-style]:duration-close data-[ending-style]:ease-in\",\n \"data-[starting-style]:[opacity:var(--popup-enter-opacity)]\",\n \"data-[starting-style]:[scale:var(--popup-enter-scale)]\",\n \"data-[ending-style]:opacity-0\",\n );\n}\n\n/**\n * Chrome shared by every floating panel (`Popover` too); callers add their own shadow token.\n */\nexport const popupSurface = cn(\n \"rounded-lg border border-border-input bg-surface\",\n floatingMotion(\"duration-open\"),\n \"data-[preview-state=open]:opacity-100 data-[preview-state=open]:scale-100\",\n);\n\n/** Every floating list, menu, popover and tooltip sits on this layer, above panel chrome and modals. */\nexport const POPUP_LAYER = \"z-200\";\n\nconst menuPopup = cn(popupSurface, \"min-w-36 p-1 shadow-menu\");\n\n/** One row. `data-highlighted` is set by keyboard and pointer alike, so the seen row is the Enter row. */\nconst itemBase = cn(\n \"flex cursor-default select-none items-center justify-between gap-6 rounded-sm px-2 py-1.5\",\n \"text-step-11 whitespace-nowrap text-text-1\",\n \"outline-hidden transition-colors ease-out-quint duration-hover\",\n \"data-[highlighted]:bg-hover data-[highlighted]:text-text-0\",\n \"data-[preview-state=hover]:bg-hover data-[preview-state=hover]:text-text-0\",\n \"data-[disabled]:pointer-events-none data-[disabled]:opacity-40\",\n);\n\nconst itemDanger = cn(\n \"text-danger-ink data-[highlighted]:bg-danger/15 data-[highlighted]:text-danger-ink\",\n);\n\nexport type MenuItemTone = \"default\" | \"danger\";\n\ninterface PositionedProps {\n side?: \"top\" | \"bottom\" | \"left\" | \"right\";\n align?: \"start\" | \"center\" | \"end\";\n sideOffset?: number;\n /** Portal target. Pass the shadow root when the trigger lives in one. */\n container?: PortalContainer;\n /** Names the popup for assistive tech. A menu with no name is unlabelled. */\n \"aria-label\"?: string;\n className?: string;\n \"data-preview-state\"?: PopupPreviewState;\n}\n\ninterface MenuProps\n extends PositionedProps, Omit<ComponentPropsWithoutRef<typeof BaseMenu.Root>, \"children\"> {\n /** A single element. It becomes the trigger; no wrapper is added around it. */\n trigger: ReactElement;\n /** The items: `MenuItem`, `MenuRadioGroup`, `MenuSeparator`. */\n children: ReactNode;\n}\n\n/**\n * A menu opened by its trigger. Uncontrolled by default; pass `open` and\n * `onOpenChange` for a menu whose state lives in a store.\n */\nexport function Menu({\n trigger,\n children,\n side = \"bottom\",\n align = \"start\",\n sideOffset = SIDE_OFFSET,\n container,\n className,\n \"aria-label\": ariaLabel,\n \"data-preview-state\": previewState,\n ...root\n}: MenuProps) {\n return (\n <BaseMenu.Root {...root}>\n <BaseMenu.Trigger render={trigger} />\n <BaseMenu.Portal container={container}>\n <BaseMenu.Positioner\n side={side}\n align={align}\n sideOffset={sideOffset}\n collisionPadding={VIEWPORT_MARGIN}\n className={POPUP_LAYER}\n >\n <BaseMenu.Popup\n aria-label={ariaLabel}\n data-preview-state={previewState}\n className={cn(menuPopup, className)}\n >\n {children}\n </BaseMenu.Popup>\n </BaseMenu.Positioner>\n </BaseMenu.Portal>\n </BaseMenu.Root>\n );\n}\n\ninterface ContextMenuProps\n extends PositionedProps, Omit<ComponentPropsWithoutRef<typeof BaseContextMenu.Root>, \"children\"> {\n /**\n * The right-clickable area, as the caller's own element. Its children are\n * kept: the trigger renders that element rather than wrapping it.\n */\n trigger: ReactElement;\n children: ReactNode;\n}\n\n/** Opened by right click or long press at the pointer, so `side` and `align` are not offered. */\nexport function ContextMenu({\n trigger,\n children,\n container,\n className,\n \"aria-label\": ariaLabel,\n \"data-preview-state\": previewState,\n ...root\n}: Omit<ContextMenuProps, \"side\" | \"align\" | \"sideOffset\">) {\n return (\n <BaseContextMenu.Root {...root}>\n <BaseContextMenu.Trigger render={trigger} />\n <BaseContextMenu.Portal container={container}>\n <BaseContextMenu.Positioner collisionPadding={VIEWPORT_MARGIN} className={POPUP_LAYER}>\n <BaseContextMenu.Popup\n aria-label={ariaLabel}\n data-preview-state={previewState}\n className={cn(menuPopup, className)}\n >\n {children}\n </BaseContextMenu.Popup>\n </BaseContextMenu.Positioner>\n </BaseContextMenu.Portal>\n </BaseContextMenu.Root>\n );\n}\n\n/** Keyboard shortcut hint, mono and tabular; exported for hints that are not a plain string. */\nexport function MenuShortcut({ className, ...props }: StyledProps<\"span\">) {\n return (\n <span\n className={cn(\"shrink-0 font-mono text-step-10 tabular-nums text-text-4\", className)}\n aria-hidden=\"true\"\n {...props}\n />\n );\n}\n\ninterface MenuItemProps extends StyledProps<typeof BaseMenu.Item> {\n /** Rendered as a dim mono hint on the trailing edge. Decorative. */\n shortcut?: string;\n /** `danger` for a destructive action (Delete, Remove). */\n tone?: MenuItemTone;\n \"data-preview-state\"?: \"hover\";\n}\n\n/** One action. `disabled` items are skipped by the arrow keys, not just dimmed. */\nexport function MenuItem({ shortcut, tone, className, children, ...props }: MenuItemProps) {\n return (\n <BaseMenu.Item className={cn(itemBase, tone === \"danger\" && itemDanger, className)} {...props}>\n <span className=\"truncate\">{children}</span>\n {shortcut ? <MenuShortcut>{shortcut}</MenuShortcut> : null}\n </BaseMenu.Item>\n );\n}\n\n/** Single-choice group; selection is `aria-checked` on each item, which the dot indicator draws from. */\nexport function MenuRadioGroup(props: ComponentPropsWithoutRef<typeof BaseMenu.RadioGroup>) {\n return <BaseMenu.RadioGroup {...props} />;\n}\n\ninterface MenuRadioItemProps extends StyledProps<typeof BaseMenu.RadioItem> {\n \"data-preview-state\"?: \"hover\";\n}\n\n/** One choice in a `MenuRadioGroup`. The dot renders only while it is checked. */\nexport function MenuRadioItem({ className, children, ...props }: MenuRadioItemProps) {\n return (\n <BaseMenu.RadioItem className={cn(itemBase, className)} {...props}>\n <span className=\"truncate\">{children}</span>\n {/* Fixed box so a checked and an unchecked row keep the same width. */}\n <span className=\"flex size-3 shrink-0 items-center justify-center\">\n <BaseMenu.RadioItemIndicator className=\"size-1.5 rounded-full bg-accent\" />\n </span>\n </BaseMenu.RadioItem>\n );\n}\n\n/** An on/off row; the tick renders only while `checked`. */\nexport function MenuCheckboxItem({\n className,\n children,\n ...props\n}: StyledProps<typeof BaseMenu.CheckboxItem>) {\n return (\n <BaseMenu.CheckboxItem className={cn(itemBase, className)} {...props}>\n <span className=\"truncate\">{children}</span>\n <span className=\"flex size-3 shrink-0 items-center justify-center text-accent-ink\">\n <BaseMenu.CheckboxItemIndicator>✓</BaseMenu.CheckboxItemIndicator>\n </span>\n </BaseMenu.CheckboxItem>\n );\n}\n\n/** A hairline between two groups of items. */\nexport function MenuSeparator({ className, ...props }: StyledProps<typeof BaseMenu.Separator>) {\n return <BaseMenu.Separator className={cn(\"my-1 h-px bg-hairline\", className)} {...props} />;\n}\n","/**\n * Tooltip: Base UI's tooltip in Studio tokens. The trigger is a box-less\n * `display: contents` wrapper so a disabled control still gets hover.\n */\n\nimport { Tooltip as BaseTooltip } from \"@base-ui/react/tooltip\";\nimport { cloneElement, useId, useRef, useState, type ReactElement } from \"react\";\nimport { cn } from \"./cn\";\nimport { floatingMotion, POPUP_LAYER } from \"./Menu\";\n\ninterface TooltipProps {\n label: string;\n /** A single element, wrapped in a box-less span so a disabled one still gets hover. */\n children: ReactElement<{ \"aria-describedby\"?: string }>;\n /** Hover delay in ms. */\n delay?: number;\n disabled?: boolean;\n side?: \"top\" | \"bottom\" | \"left\" | \"right\";\n}\n\n/** Matches the old bubble's gap from its trigger, and its viewport margin. */\nconst SIDE_OFFSET = 6;\nconst VIEWPORT_MARGIN = 8;\n\nexport function Tooltip({\n label,\n children,\n delay = 400,\n side = \"top\",\n disabled = false,\n}: TooltipProps) {\n const [open, setOpen] = useState(false);\n const boxRef = useRef<HTMLSpanElement>(null);\n const tooltipId = useId();\n\n return (\n <BaseTooltip.Root open={open} onOpenChange={setOpen} disabled={disabled}>\n <BaseTooltip.Trigger delay={delay} render={<span ref={boxRef} className=\"contents\" />}>\n {cloneElement(children, {\n \"aria-describedby\": open && !disabled ? tooltipId : children.props[\"aria-describedby\"],\n })}\n </BaseTooltip.Trigger>\n <BaseTooltip.Portal>\n <BaseTooltip.Positioner\n anchor={() => boxRef.current?.firstElementChild ?? null}\n side={side}\n sideOffset={SIDE_OFFSET}\n collisionPadding={VIEWPORT_MARGIN}\n className={POPUP_LAYER}\n >\n <BaseTooltip.Popup\n id={tooltipId}\n role=\"tooltip\"\n className={cn(\n \"pointer-events-none rounded-md border border-border-input bg-surface px-2 py-1 text-step-10 font-medium text-text-1 whitespace-nowrap shadow-menu\",\n floatingMotion(\"duration-tooltip\"),\n )}\n >\n {label}\n </BaseTooltip.Popup>\n </BaseTooltip.Positioner>\n </BaseTooltip.Portal>\n </BaseTooltip.Root>\n );\n}\n","/**\n * Popover: `Menu`'s floating chrome (`popupSurface`) without item semantics, so arrow keys\n * stay with whatever is focused inside (rename inputs, forms). Only the shadow differs.\n */\n\nimport { Popover as BasePopover } from \"@base-ui/react/popover\";\nimport type { ComponentPropsWithoutRef, ReactElement, ReactNode } from \"react\";\nimport { cn } from \"./cn\";\nimport { POPUP_LAYER, popupSurface, type PopupPreviewState } from \"./Menu\";\n\ntype PortalContainer = ComponentPropsWithoutRef<typeof BasePopover.Portal>[\"container\"];\n\n/** Matches Menu's gap from its trigger, and its viewport margin. */\nconst SIDE_OFFSET = 6;\nconst VIEWPORT_MARGIN = 8;\n\n/** The arrow's 14x8 box overlaps the popup's border by 1px, so its fill hides the border where it meets the popup. */\nconst ARROW_PX = 7;\nconst ARROW_CORNER_CLEARANCE = 10;\nconst arrowPlace = cn(\n \"data-[side=bottom]:-top-[7px] data-[side=top]:-bottom-[7px] data-[side=top]:rotate-180\",\n \"data-[side=left]:-right-[10px] data-[side=left]:rotate-90\",\n \"data-[side=right]:-left-[10px] data-[side=right]:-rotate-90\",\n);\n\ninterface PopoverProps extends Omit<ComponentPropsWithoutRef<typeof BasePopover.Root>, \"children\"> {\n /** A single element. It becomes the trigger; no wrapper is added around it. */\n trigger: ReactElement;\n /** Arbitrary content. The popover owns none of its keys. */\n children: ReactNode;\n side?: \"top\" | \"bottom\" | \"left\" | \"right\";\n align?: \"start\" | \"center\" | \"end\";\n sideOffset?: number;\n /** Points the popup at its trigger. Off by default; the default gap from the trigger grows by the arrow's height. */\n arrow?: boolean;\n /** Portal target. Pass the shadow root when the trigger lives in one. */\n container?: PortalContainer;\n /** Names the popup for assistive tech. */\n \"aria-label\"?: string;\n /**\n * What to focus on open. Defaults to Base UI's behaviour (the first tabbable\n * element), which is what a rename field wants.\n */\n initialFocus?: ComponentPropsWithoutRef<typeof BasePopover.Popup>[\"initialFocus\"];\n className?: string;\n \"data-preview-state\"?: PopupPreviewState;\n}\n\nexport function Popover({\n trigger,\n children,\n side = \"bottom\",\n align = \"center\",\n arrow = false,\n sideOffset = arrow ? SIDE_OFFSET + ARROW_PX : SIDE_OFFSET,\n container,\n className,\n initialFocus,\n \"aria-label\": ariaLabel,\n \"data-preview-state\": previewState,\n ...root\n}: PopoverProps) {\n return (\n <BasePopover.Root {...root}>\n <BasePopover.Trigger render={trigger} />\n <BasePopover.Portal container={container}>\n <BasePopover.Positioner\n side={side}\n align={align}\n sideOffset={sideOffset}\n collisionPadding={VIEWPORT_MARGIN}\n arrowPadding={ARROW_CORNER_CLEARANCE}\n className={POPUP_LAYER}\n >\n <BasePopover.Popup\n aria-label={ariaLabel}\n initialFocus={initialFocus}\n data-preview-state={previewState}\n className={cn(popupSurface, \"p-3 text-step-11 text-text-1 shadow-popover\", className)}\n >\n {arrow && (\n <BasePopover.Arrow className={arrowPlace}>\n <svg width=\"14\" height=\"8\" viewBox=\"0 0 14 8\" aria-hidden=\"true\" className=\"block\">\n <path d=\"M0 8 L7 1 L14 8\" className=\"fill-surface stroke-border-input\" />\n </svg>\n </BasePopover.Arrow>\n )}\n {children}\n </BasePopover.Popup>\n </BasePopover.Positioner>\n </BasePopover.Portal>\n </BasePopover.Root>\n );\n}\n","/**\n * Input: a boxed text field. Typing edits a local draft; Enter and blur commit it,\n * Escape abandons it. `onTrack` fires once per commit, never per keystroke.\n */\n\nimport { Input as BaseInput } from \"@base-ui/react/input\";\nimport { useEffect, useRef, useState, type ComponentPropsWithoutRef } from \"react\";\nimport { cn } from \"./cn\";\nimport type { PreviewState } from \"./Button\";\n\n/**\n * Shared field look (also used by NumberField and Select). Each interactive state is written\n * twice, real and `data-[preview-state=...]`; `valueControls.test.tsx` asserts the lists match.\n */\nexport const fieldBase = cn(\n \"flex min-w-0 items-center gap-1.5 h-ctl px-2 rounded-md\",\n \"bg-input border border-border-input text-step-11 font-medium text-text-1\",\n \"transition-[border-color,background-color] ease-standard duration-focus\",\n \"hover:border-border-strong data-[preview-state=hover]:border-border-strong\",\n \"outline-hidden\",\n \"focus-within:outline-solid focus-within:outline-2 focus-within:outline-offset-1 focus-within:outline-accent\",\n \"data-[preview-state=focus]:outline-solid data-[preview-state=focus]:outline-2 data-[preview-state=focus]:outline-offset-1 data-[preview-state=focus]:outline-accent\",\n // `aria-invalid` is not one of Tailwind's built-in aria variants, so the\n // arbitrary form is the one that compiles. The token gate would have caught\n // the bare `aria-invalid:` spelling as a class that resolves to nothing.\n \"aria-[invalid]:border-danger-ink\",\n \"has-[:disabled]:opacity-40 has-[:disabled]:cursor-not-allowed\",\n);\n\n/** The text itself, inside the box. The box owns the border and the ring. */\nexport const fieldText = cn(\n \"min-w-0 w-full bg-transparent text-inherit outline-hidden\",\n \"placeholder:text-text-5 disabled:cursor-not-allowed\",\n);\n\nexport interface InputProps extends Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"value\" | \"onChange\" | \"className\"\n> {\n /** The committed value. A draft lives inside until Enter or blur. */\n value: string;\n /** Called with the draft on Enter and on blur, only when it really changed. */\n onCommit: (next: string) => void;\n /** Called once per committed change, for design-input telemetry. */\n onTrack?: () => void;\n /** Marks the field invalid: red boundary and `aria-invalid`. */\n invalid?: boolean;\n className?: string;\n \"data-preview-state\"?: PreviewState;\n}\n\nexport function Input({\n value,\n onCommit,\n onTrack,\n invalid,\n disabled,\n className,\n \"data-preview-state\": previewState,\n ...props\n}: InputProps) {\n const [draft, setDraft] = useState(value);\n const valueRef = useRef(value);\n valueRef.current = value;\n const dirtyRef = useRef(false);\n\n // An external write (a seek, an undo, another panel) is authoritative, but it\n // must not eat what the user is halfway through typing.\n useEffect(() => {\n if (!dirtyRef.current) setDraft(value);\n }, [value]);\n\n const commit = (next: string) => {\n dirtyRef.current = false;\n if (next === valueRef.current) return;\n onCommit(next);\n onTrack?.();\n };\n\n return (\n <div\n className={cn(fieldBase, className)}\n aria-invalid={invalid || undefined}\n data-preview-state={previewState}\n >\n <BaseInput\n value={draft}\n disabled={disabled}\n aria-invalid={invalid || undefined}\n className={fieldText}\n onValueChange={(next) => {\n dirtyRef.current = true;\n setDraft(next);\n }}\n onBlur={() => commit(draft)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n commit(draft);\n return;\n }\n if (event.key === \"Escape\") {\n // Abandon the draft rather than leave it for the blur commit.\n event.preventDefault();\n event.stopPropagation();\n dirtyRef.current = false;\n setDraft(valueRef.current);\n event.currentTarget.blur();\n }\n }}\n {...props}\n />\n </div>\n );\n}\n","/**\n * NumberField: the inspector's metric control. Commits only on blur, Enter, or a settled step (KTD11),\n * never per keystroke. The unit is a sibling of the input; unparseable text shows a red boundary and commits nothing.\n */\n\nimport { NumberField as BaseNumberField } from \"@base-ui/react/number-field\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { cn } from \"./cn\";\nimport { fieldBase, fieldText } from \"./Input\";\nimport type { PreviewState } from \"./Button\";\n\nexport interface NumberFieldProps {\n /** Accessible name. The inspector's row label is the usual one. */\n label: string;\n /** The committed value. */\n value: number;\n /** Called when a commit boundary produces a value different from `value`. */\n onCommit: (next: number) => void;\n /** Called once per committed change, for design-input telemetry. */\n onTrack?: () => void;\n /** Rendered beside the number: \"px\", \"%\", \"deg\". Never part of the text. */\n unit?: string;\n min?: number;\n max?: number;\n step?: number;\n disabled?: boolean;\n className?: string;\n \"data-preview-state\"?: PreviewState;\n}\n\nexport function NumberField({\n label,\n value,\n onCommit,\n onTrack,\n unit,\n min,\n max,\n step,\n disabled,\n className,\n \"data-preview-state\": previewState,\n}: NumberFieldProps) {\n const [draft, setDraft] = useState<number | null>(value);\n const [invalid, setInvalid] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n // What was last handed to `onCommit`, which is not the same as `value`: a\n // blur can fire both Base UI's commit and ours in one turn, before the parent\n // has re-rendered with the new prop, and the second must be a no-op.\n const committedRef = useRef(value);\n const valueRef = useRef(value);\n valueRef.current = value;\n\n useEffect(() => {\n committedRef.current = value;\n setDraft(value);\n setInvalid(false);\n }, [value]);\n\n const commit = (next: number | null) => {\n if (next === null || !Number.isFinite(next)) {\n setInvalid(true);\n return;\n }\n setInvalid(false);\n if (next === committedRef.current) return;\n committedRef.current = next;\n onCommit(next);\n onTrack?.();\n };\n\n /** Enter commits what is on screen, which Base UI has not parsed for us yet. */\n const commitFromText = () => {\n const text = inputRef.current?.value.trim() ?? \"\";\n commit(text === \"\" ? null : Number(text));\n };\n\n return (\n <BaseNumberField.Root\n value={draft}\n min={min}\n max={max}\n step={step}\n disabled={disabled}\n onValueChange={(next) => {\n setDraft(next);\n if (next !== null) setInvalid(false);\n }}\n onValueCommitted={(next) => commit(next)}\n >\n <BaseNumberField.Group\n className={cn(fieldBase, className)}\n aria-invalid={invalid || undefined}\n data-preview-state={previewState}\n >\n <BaseNumberField.Input\n ref={inputRef}\n aria-label={label}\n aria-invalid={invalid || undefined}\n className={cn(fieldText, \"tabular-nums\")}\n onKeyDown={(event) => {\n if (event.key !== \"Enter\") return;\n event.preventDefault();\n commitFromText();\n }}\n onBlur={() => {\n // Base UI's own blur handler returns without committing when the\n // text does not parse. That is the only case left for us: a valid\n // blur has already arrived through `onValueCommitted`.\n const text = inputRef.current?.value.trim() ?? \"\";\n if (text === \"\" || !Number.isFinite(Number(text))) setInvalid(true);\n }}\n />\n {unit && (\n <span className=\"shrink-0 select-none text-step-10 text-text-4\" aria-hidden=\"true\">\n {unit}\n </span>\n )}\n </BaseNumberField.Group>\n </BaseNumberField.Root>\n );\n}\n","/**\n * Select: Base UI select in Input's box. The trigger keeps `role=\"combobox\"`, which both hotkey selector\n * lists match. Options are data, not children, so typeahead and the value display can read labels.\n */\n\nimport { Select as BaseSelect } from \"@base-ui/react/select\";\nimport { cn } from \"./cn\";\nimport { fieldBase } from \"./Input\";\nimport { floatingMotion, POPUP_LAYER } from \"./Menu\";\nimport type { PreviewState } from \"./Button\";\n\nexport interface SelectOption {\n label: string;\n value: string;\n /** Offered but not choosable; the label stays visible so the reason stays visible too. */\n disabled?: boolean;\n}\n\nexport interface SelectProps {\n /** Accessible name for the trigger. */\n label: string;\n value: string;\n options: SelectOption[];\n /** Called when a different option is chosen. */\n onCommit: (next: string) => void;\n /** Called once per committed change, for design-input telemetry. */\n onTrack?: () => void;\n disabled?: boolean;\n className?: string;\n \"data-preview-state\"?: PreviewState;\n}\n\nexport function Select({\n label,\n value,\n options,\n onCommit,\n onTrack,\n disabled,\n className,\n \"data-preview-state\": previewState,\n}: SelectProps) {\n return (\n <BaseSelect.Root\n value={value}\n disabled={disabled}\n items={options}\n onValueChange={(next) => {\n const chosen = String(next);\n if (chosen === value) return;\n onCommit(chosen);\n onTrack?.();\n }}\n >\n <BaseSelect.Trigger\n aria-label={label}\n className={cn(\n fieldBase,\n \"w-full cursor-pointer justify-between text-left\",\n \"data-[popup-open]:border-border-strong\",\n className,\n )}\n data-preview-state={previewState}\n >\n <BaseSelect.Value className=\"truncate\" />\n <BaseSelect.Icon className=\"shrink-0 text-text-4\" aria-hidden=\"true\">\n <svg width=\"8\" height=\"5\" viewBox=\"0 0 8 5\" fill=\"none\">\n <path\n d=\"M1 1L4 4L7 1\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </BaseSelect.Icon>\n </BaseSelect.Trigger>\n\n <BaseSelect.Portal>\n <BaseSelect.Positioner sideOffset={4} alignItemWithTrigger={false} className={POPUP_LAYER}>\n <BaseSelect.Popup\n className={cn(\n \"min-w-[var(--anchor-width)] rounded-md border border-border bg-surface py-1 shadow-menu\",\n floatingMotion(\"duration-open\"),\n )}\n >\n <BaseSelect.List>\n {options.map((option) => (\n <BaseSelect.Item\n key={option.value}\n value={option.value}\n disabled={option.disabled}\n className={cn(\n \"flex h-ctl-sm cursor-pointer select-none items-center gap-2 px-2.5\",\n \"text-step-11 text-text-2 outline-hidden\",\n \"data-[highlighted]:bg-hover data-[highlighted]:text-text-0\",\n \"data-[selected]:text-text-0\",\n \"data-[disabled]:cursor-not-allowed data-[disabled]:opacity-40\",\n )}\n >\n <BaseSelect.ItemText className=\"truncate\">{option.label}</BaseSelect.ItemText>\n </BaseSelect.Item>\n ))}\n </BaseSelect.List>\n </BaseSelect.Popup>\n </BaseSelect.Positioner>\n </BaseSelect.Portal>\n </BaseSelect.Root>\n );\n}\n","/**\n * Slider: `onPreview` fires while the thumb moves and writes nothing durable; `onCommit` (with `onTrack`, once)\n * fires at a boundary. Right-click or Escape aborts a drag via `eventDetails.cancel()` and restores the start value.\n */\n\nimport { Slider as BaseSlider } from \"@base-ui/react/slider\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { cn } from \"./cn\";\nimport type { PreviewState } from \"./Button\";\n\nexport interface SliderProps {\n /** Accessible name for the thumb. The inspector's row label is the usual one. */\n label: string;\n /** The committed value. */\n value: number;\n min: number;\n max: number;\n step?: number;\n /** Every intermediate value while dragging or stepping. Not a commit. */\n onPreview?: (next: number) => void;\n /** Called at a commit boundary when the value really changed. */\n onCommit: (next: number) => void;\n /** Called once per commit boundary, for design-input telemetry. */\n onTrack?: () => void;\n disabled?: boolean;\n className?: string;\n \"data-preview-state\"?: PreviewState;\n}\n\nconst first = (next: number | number[]): number => (Array.isArray(next) ? next[0] : next);\n\nexport function Slider({\n label,\n value,\n min,\n max,\n step,\n onPreview,\n onCommit,\n onTrack,\n disabled,\n className,\n \"data-preview-state\": previewState,\n}: SliderProps) {\n const [draft, setDraft] = useState(value);\n const draggingRef = useRef(false);\n const abortedRef = useRef(false);\n // The committed value the current gesture started from, so an abort has\n // something to put back.\n const dragStartRef = useRef(value);\n // What was last handed to `onCommit`. A gesture's own commit lands before the\n // parent re-renders, so deduping against the `value` prop would double-fire.\n const committedRef = useRef(value);\n const valueRef = useRef(value);\n valueRef.current = value;\n\n // An external write wins, except mid-drag: the echo is a frame behind, and\n // applying it would snap the thumb backwards under the pointer.\n useEffect(() => {\n if (draggingRef.current) return;\n committedRef.current = value;\n setDraft(value);\n }, [value]);\n\n const commit = (next: number) => {\n if (next === committedRef.current) return;\n committedRef.current = next;\n onCommit(next);\n };\n\n const abort = () => {\n if (!draggingRef.current) return;\n abortedRef.current = true;\n const start = dragStartRef.current;\n setDraft(start);\n onPreview?.(start);\n commit(start);\n };\n\n return (\n <BaseSlider.Root\n value={draft}\n min={min}\n max={max}\n step={step}\n disabled={disabled}\n onValueChange={(next, details) => {\n if (abortedRef.current) {\n // The pointer is still down after a right-click abort. Base UI would\n // otherwise keep applying moves to a gesture the user cancelled.\n details.cancel();\n return;\n }\n const n = first(next);\n setDraft(n);\n onPreview?.(n);\n }}\n onValueCommitted={(next) => {\n draggingRef.current = false;\n if (abortedRef.current) {\n abortedRef.current = false;\n return;\n }\n commit(first(next));\n onTrack?.();\n }}\n className={cn(\"flex min-w-0 items-center\", className)}\n data-preview-state={previewState}\n >\n <BaseSlider.Control\n // A stable hook for the drag tests and for the screenshot script. Base\n // UI's own marker on this part only exists before hydration.\n data-slider-control=\"true\"\n // h-6 is the 24x24 WCAG 2.2 (2.5.8) target: the visible track stays\n // 2px, only the pointer box grows.\n className=\"flex h-6 w-full min-w-0 touch-none select-none items-center\"\n onPointerDown={() => {\n draggingRef.current = true;\n abortedRef.current = false;\n dragStartRef.current = valueRef.current;\n }}\n onContextMenu={(event) => {\n if (!draggingRef.current) return;\n event.preventDefault();\n abort();\n }}\n onKeyDown={(event) => {\n if (event.key !== \"Escape\" || !draggingRef.current) return;\n event.preventDefault();\n abort();\n }}\n >\n <BaseSlider.Track className=\"h-0.5 w-full rounded-full bg-hover\">\n <BaseSlider.Indicator className=\"rounded-full bg-text-5\" />\n <BaseSlider.Thumb\n aria-label={label}\n className={cn(\n // The ring separates the thumb from the track behind it. A drop\n // shadow would need a raw colour literal, which R5 does not allow\n // outside the token file, and no shadow token fits a 10px dot.\n \"size-2.5 rounded-full bg-text-0 ring-2 ring-bg-1\",\n \"cursor-grab active:cursor-grabbing data-[preview-state=active]:cursor-grabbing\",\n \"hover:scale-110 data-[preview-state=hover]:scale-110\",\n \"transition-transform ease-standard duration-hover\",\n \"has-[:focus-visible]:outline-solid has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-offset-2 has-[:focus-visible]:outline-accent\",\n \"data-[preview-state=focus]:outline-solid data-[preview-state=focus]:outline-2 data-[preview-state=focus]:outline-offset-2 data-[preview-state=focus]:outline-accent\",\n )}\n />\n </BaseSlider.Track>\n </BaseSlider.Control>\n </BaseSlider.Root>\n );\n}\n","/**\n * Toggle: a switch, not a checkbox (immediate effect). `role=\"switch\"` needed an entry in\n * `typingTarget.ts` so Space is not leaked to the global playback shortcut.\n */\n\nimport { Switch } from \"@base-ui/react/switch\";\nimport { cn } from \"./cn\";\nimport type { PreviewState } from \"./Button\";\n\nexport interface ToggleProps {\n /** Accessible name. */\n label: string;\n checked: boolean;\n /** Called on every flip. */\n onCommit: (next: boolean) => void;\n /** Called once per flip, for design-input telemetry. */\n onTrack?: () => void;\n disabled?: boolean;\n className?: string;\n \"data-preview-state\"?: PreviewState;\n}\n\nexport function Toggle({\n label,\n checked,\n onCommit,\n onTrack,\n disabled,\n className,\n \"data-preview-state\": previewState,\n}: ToggleProps) {\n return (\n <Switch.Root\n aria-label={label}\n checked={checked}\n disabled={disabled}\n onCheckedChange={(next) => {\n onCommit(next);\n onTrack?.();\n }}\n data-preview-state={previewState}\n className={cn(\n \"relative inline-flex h-4 w-7 shrink-0 cursor-pointer items-center rounded-full p-0.5\",\n \"border border-border-input bg-input\",\n \"transition-[background-color,border-color] ease-standard duration-press\",\n \"hover:border-border-strong data-[preview-state=hover]:border-border-strong\",\n \"data-[checked]:border-accent data-[checked]:bg-accent\",\n \"outline-hidden focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-accent\",\n \"data-[preview-state=focus]:outline-solid data-[preview-state=focus]:outline-2 data-[preview-state=focus]:outline-offset-1 data-[preview-state=focus]:outline-accent\",\n \"disabled:cursor-not-allowed disabled:opacity-40\",\n className,\n )}\n >\n <Switch.Thumb\n className={cn(\n \"size-3 rounded-full bg-text-3\",\n \"transition-[transform,background-color] ease-standard duration-press\",\n \"data-[checked]:translate-x-3 data-[checked]:bg-bg-0\",\n )}\n />\n </Switch.Root>\n );\n}\n"],"mappings":";AAMA,SAAS,gBAAgB;AAGzB,IAAM,aAAa,CAAC,UAAkB,aAAa,KAAK,KAAK;AAG7D,IAAM,gBAAgB,CAAC,UAAkB,kBAAkB,KAAK,KAAK;AAE9D,IAAM,KAAiB,SAAS;AAAA,EACrC,QAAQ;AAAA,IACN,aAAa;AAAA,MACX,aAAa,CAAC,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC;AAAA,MACpC,GAAG,CAAC,EAAE,GAAG,CAAC,aAAa,EAAE,CAAC;AAAA,MAC1B,GAAG,CAAC,EAAE,GAAG,CAAC,aAAa,EAAE,CAAC;AAAA,MAC1B,MAAM,CAAC,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC;AAAA,MAChC,SAAS,CAAC,EAAE,SAAS,CAAC,aAAa,EAAE,CAAC;AAAA,MACtC,SAAS,CAAC,EAAE,SAAS,CAAC,aAAa,EAAE,CAAC;AAAA,IACxC;AAAA,EACF;AACF,CAAC;;;ACZD,SAAS,kBAA6D;AAwElE,SACE,KADF;AAhDG,IAAM,aAAa;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAMO,IAAM,iBAAgD;AAAA,EAC3D,SAAS;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,WAAW;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAMO,IAAM,cAA0C;AAAA,EACrD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAEA,SAAS,UAAU;AACjB,SACE,qBAAC,SAAI,WAAU,yBAAwB,SAAQ,aAAY,MAAK,QAAO,eAAY,QACjF;AAAA,wBAAC,YAAO,WAAU,cAAa,IAAG,MAAK,IAAG,MAAK,GAAE,MAAK,QAAO,gBAAe,aAAY,KAAI;AAAA,IAC5F;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,MAAK;AAAA,QACL,GAAE;AAAA;AAAA,IACJ;AAAA,KACF;AAEJ;AAEO,IAAM,SAAS;AAAA,EACpB,CACE,EAAE,UAAU,aAAa,OAAO,MAAM,SAAS,MAAM,UAAU,WAAW,UAAU,GAAG,MAAM,GAC7F,QACG;AACH,UAAM,aAAa,YAAY;AAC/B,QAAI,UAAqB;AACzB,QAAI,QAAS,WAAU,oBAAC,WAAQ;AAAA,aACvB,KAAM,WAAU,oBAAC,UAAK,WAAU,YAAY,gBAAK;AAC1D,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,UAAU;AAAA,QAGV,iBAAe,cAAc;AAAA,QAC7B,WAAW,GAAG,YAAY,eAAe,OAAO,GAAG,YAAY,IAAI,GAAG,SAAS;AAAA,QAC9E,GAAG;AAAA,QAEH;AAAA;AAAA,UACA;AAAA;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AACA,OAAO,cAAc;;;ACpHrB,SAAS,cAAAA,mBAAkB;AAoBrB,gBAAAC,YAAA;AATN,IAAM,iBAA6C;AAAA,EACjD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAEO,IAAM,aAAaC;AAAA,EACxB,CAAC,EAAE,MAAM,OAAO,MAAM,UAAU,SAAS,WAAW,UAAU,GAAG,MAAM,GAAG,QAAQ;AAChF,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,iBAAe,YAAY;AAAA,QAC3B,WAAW,GAAG,YAAY,eAAe,OAAO,GAAG,eAAe,IAAI,GAAG,SAAS;AAAA,QACjF,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AACA,WAAW,cAAc;;;AChCzB,SAAS,QAAQ,gBAAgB;AAkBxB,gBAAAE,YAAA;AADF,SAAS,KAAK,OAAuD;AAC1E,SAAO,gBAAAA,KAAC,SAAS,MAAT,EAAe,GAAG,OAAO;AACnC;AAGO,SAAS,SAAS,EAAE,WAAW,GAAG,MAAM,GAAsC;AACnF,SACE,gBAAAA;AAAA,IAAC,SAAS;AAAA,IAAT;AAAA,MAEC,iBAAe;AAAA,MACf,WAAW,GAAG,kEAAkE,SAAS;AAAA,MACxF,GAAG;AAAA;AAAA,EACN;AAEJ;AAWO,SAAS,IAAI,EAAE,OAAO,WAAW,GAAG,MAAM,GAAa;AAC5D,SACE,gBAAAA;AAAA,IAAC,SAAS;AAAA,IAAT;AAAA,MACC;AAAA,MACA,eAAa;AAAA,MACb,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAGO,SAAS,SAAS,EAAE,WAAW,GAAG,MAAM,GAAuC;AACpF,SAAO,gBAAAA,KAAC,SAAS,OAAT,EAAe,WAAW,GAAG,kBAAkB,SAAS,GAAI,GAAG,OAAO;AAChF;;;ACtEA,SAAS,aAA4B;AAe7B,SACE,OAAAC,MADF,QAAAC,aAAA;AAbD,SAAS,gBAAgB,EAAE,UAAU,eAAe,GAAG,MAAM,GAA4B;AAC9F,QAAM,aAAa,MAAM;AACzB,QAAM,eAAe,GAAG,UAAU;AAClC,QAAM,gBAAgB,GAAG,UAAU;AACnC,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,MAAK;AAAA,MACL,OAAM;AAAA,MACN,eAAY;AAAA,MACX,GAAG;AAAA,MAEJ;AAAA,wBAAAD,KAAC,OAAE,WAAU,oBAAmB,SAAQ,OACtC,0BAAAC,MAAC,OAAE,WAAU,sBACX;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,GAAE;AAAA,cACF,MAAM,QAAQ,YAAY;AAAA;AAAA,UAC5B;AAAA,UACA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,GAAE;AAAA,cACF,MAAM,QAAQ,aAAa;AAAA;AAAA,UAC7B;AAAA,WACF,GACF;AAAA,QACA,gBAAAC,MAAC,UACC;AAAA,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,IAAI;AAAA,cACJ,IAAG;AAAA,cACH,IAAG;AAAA,cACH,IAAG;AAAA,cACH,IAAG;AAAA,cACH,eAAc;AAAA,cAEd;AAAA,gCAAAD,KAAC,UAAK,WAAU,WAAU;AAAA,gBAC1B,gBAAAA,KAAC,UAAK,QAAO,KAAI,WAAU,WAAU;AAAA;AAAA;AAAA,UACvC;AAAA,UACA,gBAAAC;AAAA,YAAC;AAAA;AAAA,cACC,IAAI;AAAA,cACJ,IAAG;AAAA,cACH,IAAG;AAAA,cACH,IAAG;AAAA,cACH,IAAG;AAAA,cACH,eAAc;AAAA,cAEd;AAAA,gCAAAD,KAAC,UAAK,WAAU,WAAU;AAAA,gBAC1B,gBAAAA,KAAC,UAAK,QAAO,KAAI,WAAU,WAAU;AAAA;AAAA;AAAA,UACvC;AAAA,WACF;AAAA;AAAA;AAAA,EACF;AAEJ;;;ACvBI,SAMI,OAAAE,MANJ,QAAAC,aAAA;AAdG,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AACF,GAA2B;AACzB,QAAM,kBACJ,OAAO,aAAa,YAAY,OAAO,SAAS,QAAQ,IACpD,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,QAAQ,CAAC,IACjC;AACN,QAAM,gBAAgB,KAAK,MAAM,OAAO,IAAI;AAE5C,SACE,gBAAAA,MAAC,SAAI,WAAU,aAAY,MAAK,UAAS,WAAW,OAClD;AAAA,oBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO,EAAE,OAAO,eAAe,QAAQ,cAAc;AAAA,QACrD,WAAW;AAAA,QAEX,0BAAAA,KAAC,mBAAgB,WAAU,kBAAiB,OAAO,MAAM,QAAQ,MAAM;AAAA;AAAA,IACzE;AAAA,IACA,gBAAAA,KAAC,SAAI,WAAU,mBAAmB,iBAAM;AAAA,IACvC,UAAU,gBAAAA,KAAC,SAAI,WAAU,oBAAoB,kBAAO;AAAA,IACpD,oBAAoB,UACnB,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,MAAK;AAAA,QACL,iBAAe;AAAA,QACf,iBAAe;AAAA,QACf,iBAAe,KAAK,MAAM,kBAAkB,GAAG;AAAA,QAE/C,0BAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO,EAAE,WAAW,UAAU,eAAe,IAAI;AAAA;AAAA,QACnD;AAAA;AAAA,IACF;AAAA,IAED,QAAQ,gBAAAA,KAAC,SAAI,WAAU,kBAAkB,gBAAK;AAAA,KACjD;AAEJ;;;ACnDA,SAAS,eAAe,uBAAuB;AAC/C,SAAS,QAAQ,gBAAgB;AA0G7B,SACE,OAAAE,MADF,QAAAC,aAAA;AAvFJ,IAAM,cAAc;AACpB,IAAM,kBAAkB;AAOjB,SAAS,eAAe,cAAoD;AACjF,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAKO,IAAM,eAAe;AAAA,EAC1B;AAAA,EACA,eAAe,eAAe;AAAA,EAC9B;AACF;AAGO,IAAM,cAAc;AAE3B,IAAM,YAAY,GAAG,cAAc,0BAA0B;AAG7D,IAAM,WAAW;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,aAAa;AAAA,EACjB;AACF;AA4BO,SAAS,KAAK;AAAA,EACnB;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,sBAAsB;AAAA,EACtB,GAAG;AACL,GAAc;AACZ,SACE,gBAAAA,MAAC,SAAS,MAAT,EAAe,GAAG,MACjB;AAAA,oBAAAD,KAAC,SAAS,SAAT,EAAiB,QAAQ,SAAS;AAAA,IACnC,gBAAAA,KAAC,SAAS,QAAT,EAAgB,WACf,0BAAAA;AAAA,MAAC,SAAS;AAAA,MAAT;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA,kBAAkB;AAAA,QAClB,WAAW;AAAA,QAEX,0BAAAA;AAAA,UAAC,SAAS;AAAA,UAAT;AAAA,YACC,cAAY;AAAA,YACZ,sBAAoB;AAAA,YACpB,WAAW,GAAG,WAAW,SAAS;AAAA,YAEjC;AAAA;AAAA,QACH;AAAA;AAAA,IACF,GACF;AAAA,KACF;AAEJ;AAaO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,sBAAsB;AAAA,EACtB,GAAG;AACL,GAA4D;AAC1D,SACE,gBAAAC,MAAC,gBAAgB,MAAhB,EAAsB,GAAG,MACxB;AAAA,oBAAAD,KAAC,gBAAgB,SAAhB,EAAwB,QAAQ,SAAS;AAAA,IAC1C,gBAAAA,KAAC,gBAAgB,QAAhB,EAAuB,WACtB,0BAAAA,KAAC,gBAAgB,YAAhB,EAA2B,kBAAkB,iBAAiB,WAAW,aACxE,0BAAAA;AAAA,MAAC,gBAAgB;AAAA,MAAhB;AAAA,QACC,cAAY;AAAA,QACZ,sBAAoB;AAAA,QACpB,WAAW,GAAG,WAAW,SAAS;AAAA,QAEjC;AAAA;AAAA,IACH,GACF,GACF;AAAA,KACF;AAEJ;AAGO,SAAS,aAAa,EAAE,WAAW,GAAG,MAAM,GAAwB;AACzE,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,4DAA4D,SAAS;AAAA,MACnF,eAAY;AAAA,MACX,GAAG;AAAA;AAAA,EACN;AAEJ;AAWO,SAAS,SAAS,EAAE,UAAU,MAAM,WAAW,UAAU,GAAG,MAAM,GAAkB;AACzF,SACE,gBAAAC,MAAC,SAAS,MAAT,EAAc,WAAW,GAAG,UAAU,SAAS,YAAY,YAAY,SAAS,GAAI,GAAG,OACtF;AAAA,oBAAAD,KAAC,UAAK,WAAU,YAAY,UAAS;AAAA,IACpC,WAAW,gBAAAA,KAAC,gBAAc,oBAAS,IAAkB;AAAA,KACxD;AAEJ;AAGO,SAAS,eAAe,OAA6D;AAC1F,SAAO,gBAAAA,KAAC,SAAS,YAAT,EAAqB,GAAG,OAAO;AACzC;AAOO,SAAS,cAAc,EAAE,WAAW,UAAU,GAAG,MAAM,GAAuB;AACnF,SACE,gBAAAC,MAAC,SAAS,WAAT,EAAmB,WAAW,GAAG,UAAU,SAAS,GAAI,GAAG,OAC1D;AAAA,oBAAAD,KAAC,UAAK,WAAU,YAAY,UAAS;AAAA,IAErC,gBAAAA,KAAC,UAAK,WAAU,oDACd,0BAAAA,KAAC,SAAS,oBAAT,EAA4B,WAAU,mCAAkC,GAC3E;AAAA,KACF;AAEJ;AAGO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAA8C;AAC5C,SACE,gBAAAC,MAAC,SAAS,cAAT,EAAsB,WAAW,GAAG,UAAU,SAAS,GAAI,GAAG,OAC7D;AAAA,oBAAAD,KAAC,UAAK,WAAU,YAAY,UAAS;AAAA,IACrC,gBAAAA,KAAC,UAAK,WAAU,oEACd,0BAAAA,KAAC,SAAS,uBAAT,EAA+B,oBAAC,GACnC;AAAA,KACF;AAEJ;AAGO,SAAS,cAAc,EAAE,WAAW,GAAG,MAAM,GAA2C;AAC7F,SAAO,gBAAAA,KAAC,SAAS,WAAT,EAAmB,WAAW,GAAG,yBAAyB,SAAS,GAAI,GAAG,OAAO;AAC3F;;;AC9OA,SAAS,WAAW,mBAAmB;AACvC,SAAS,cAAc,SAAAE,QAAO,QAAQ,gBAAmC;AA8BrE,SAC6C,OAAAC,MAD7C,QAAAC,aAAA;AAfJ,IAAMC,eAAc;AACpB,IAAMC,mBAAkB;AAEjB,SAAS,QAAQ;AAAA,EACtB;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,WAAW;AACb,GAAiB;AACf,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,SAAS,OAAwB,IAAI;AAC3C,QAAM,YAAYC,OAAM;AAExB,SACE,gBAAAH,MAAC,YAAY,MAAZ,EAAiB,MAAY,cAAc,SAAS,UACnD;AAAA,oBAAAD,KAAC,YAAY,SAAZ,EAAoB,OAAc,QAAQ,gBAAAA,KAAC,UAAK,KAAK,QAAQ,WAAU,YAAW,GAChF,uBAAa,UAAU;AAAA,MACtB,oBAAoB,QAAQ,CAAC,WAAW,YAAY,SAAS,MAAM,kBAAkB;AAAA,IACvF,CAAC,GACH;AAAA,IACA,gBAAAA,KAAC,YAAY,QAAZ,EACC,0BAAAA;AAAA,MAAC,YAAY;AAAA,MAAZ;AAAA,QACC,QAAQ,MAAM,OAAO,SAAS,qBAAqB;AAAA,QACnD;AAAA,QACA,YAAYE;AAAA,QACZ,kBAAkBC;AAAA,QAClB,WAAW;AAAA,QAEX,0BAAAH;AAAA,UAAC,YAAY;AAAA,UAAZ;AAAA,YACC,IAAI;AAAA,YACJ,MAAK;AAAA,YACL,WAAW;AAAA,cACT;AAAA,cACA,eAAe,kBAAkB;AAAA,YACnC;AAAA,YAEC;AAAA;AAAA,QACH;AAAA;AAAA,IACF,GACF;AAAA,KACF;AAEJ;;;AC3DA,SAAS,WAAW,mBAAmB;AA2DjC,gBAAAK,MAUI,QAAAC,aAVJ;AAnDN,IAAMC,eAAc;AACpB,IAAMC,mBAAkB;AAGxB,IAAM,WAAW;AACjB,IAAM,yBAAyB;AAC/B,IAAM,aAAa;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AACF;AAyBO,SAAS,QAAQ;AAAA,EACtB;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,aAAa,QAAQD,eAAc,WAAWA;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,sBAAsB;AAAA,EACtB,GAAG;AACL,GAAiB;AACf,SACE,gBAAAD,MAAC,YAAY,MAAZ,EAAkB,GAAG,MACpB;AAAA,oBAAAD,KAAC,YAAY,SAAZ,EAAoB,QAAQ,SAAS;AAAA,IACtC,gBAAAA,KAAC,YAAY,QAAZ,EAAmB,WAClB,0BAAAA;AAAA,MAAC,YAAY;AAAA,MAAZ;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA,kBAAkBG;AAAA,QAClB,cAAc;AAAA,QACd,WAAW;AAAA,QAEX,0BAAAF;AAAA,UAAC,YAAY;AAAA,UAAZ;AAAA,YACC,cAAY;AAAA,YACZ;AAAA,YACA,sBAAoB;AAAA,YACpB,WAAW,GAAG,cAAc,+CAA+C,SAAS;AAAA,YAEnF;AAAA,uBACC,gBAAAD,KAAC,YAAY,OAAZ,EAAkB,WAAW,YAC5B,0BAAAA,KAAC,SAAI,OAAM,MAAK,QAAO,KAAI,SAAQ,YAAW,eAAY,QAAO,WAAU,SACzE,0BAAAA,KAAC,UAAK,GAAE,mBAAkB,WAAU,oCAAmC,GACzE,GACF;AAAA,cAED;AAAA;AAAA;AAAA,QACH;AAAA;AAAA,IACF,GACF;AAAA,KACF;AAEJ;;;ACxFA,SAAS,SAAS,iBAAiB;AACnC,SAAS,WAAW,UAAAI,SAAQ,YAAAC,iBAA+C;AA+ErE,gBAAAC,YAAA;AAvEC,IAAM,YAAY;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA,EAIA;AAAA,EACA;AACF;AAGO,IAAM,YAAY;AAAA,EACvB;AAAA,EACA;AACF;AAkBO,SAAS,MAAM;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,sBAAsB;AAAA,EACtB,GAAG;AACL,GAAe;AACb,QAAM,CAAC,OAAO,QAAQ,IAAIC,UAAS,KAAK;AACxC,QAAM,WAAWC,QAAO,KAAK;AAC7B,WAAS,UAAU;AACnB,QAAM,WAAWA,QAAO,KAAK;AAI7B,YAAU,MAAM;AACd,QAAI,CAAC,SAAS,QAAS,UAAS,KAAK;AAAA,EACvC,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,SAAS,CAAC,SAAiB;AAC/B,aAAS,UAAU;AACnB,QAAI,SAAS,SAAS,QAAS;AAC/B,aAAS,IAAI;AACb,cAAU;AAAA,EACZ;AAEA,SACE,gBAAAF;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,WAAW,SAAS;AAAA,MAClC,gBAAc,WAAW;AAAA,MACzB,sBAAoB;AAAA,MAEpB,0BAAAA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,UACP;AAAA,UACA,gBAAc,WAAW;AAAA,UACzB,WAAW;AAAA,UACX,eAAe,CAAC,SAAS;AACvB,qBAAS,UAAU;AACnB,qBAAS,IAAI;AAAA,UACf;AAAA,UACA,QAAQ,MAAM,OAAO,KAAK;AAAA,UAC1B,WAAW,CAAC,UAAU;AACpB,gBAAI,MAAM,QAAQ,SAAS;AACzB,oBAAM,eAAe;AACrB,qBAAO,KAAK;AACZ;AAAA,YACF;AACA,gBAAI,MAAM,QAAQ,UAAU;AAE1B,oBAAM,eAAe;AACrB,oBAAM,gBAAgB;AACtB,uBAAS,UAAU;AACnB,uBAAS,SAAS,OAAO;AACzB,oBAAM,cAAc,KAAK;AAAA,YAC3B;AAAA,UACF;AAAA,UACC,GAAG;AAAA;AAAA,MACN;AAAA;AAAA,EACF;AAEJ;;;AC7GA,SAAS,eAAe,uBAAuB;AAC/C,SAAS,aAAAG,YAAW,UAAAC,SAAQ,YAAAC,iBAAgB;AAoFtC,SAKE,OAAAC,OALF,QAAAC,aAAA;AA5DC,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,sBAAsB;AACxB,GAAqB;AACnB,QAAM,CAAC,OAAO,QAAQ,IAAIC,UAAwB,KAAK;AACvD,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAS,KAAK;AAC5C,QAAM,WAAWC,QAAyB,IAAI;AAI9C,QAAM,eAAeA,QAAO,KAAK;AACjC,QAAM,WAAWA,QAAO,KAAK;AAC7B,WAAS,UAAU;AAEnB,EAAAC,WAAU,MAAM;AACd,iBAAa,UAAU;AACvB,aAAS,KAAK;AACd,eAAW,KAAK;AAAA,EAClB,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,SAAS,CAAC,SAAwB;AACtC,QAAI,SAAS,QAAQ,CAAC,OAAO,SAAS,IAAI,GAAG;AAC3C,iBAAW,IAAI;AACf;AAAA,IACF;AACA,eAAW,KAAK;AAChB,QAAI,SAAS,aAAa,QAAS;AACnC,iBAAa,UAAU;AACvB,aAAS,IAAI;AACb,cAAU;AAAA,EACZ;AAGA,QAAM,iBAAiB,MAAM;AAC3B,UAAM,OAAO,SAAS,SAAS,MAAM,KAAK,KAAK;AAC/C,WAAO,SAAS,KAAK,OAAO,OAAO,IAAI,CAAC;AAAA,EAC1C;AAEA,SACE,gBAAAJ;AAAA,IAAC,gBAAgB;AAAA,IAAhB;AAAA,MACC,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,eAAe,CAAC,SAAS;AACvB,iBAAS,IAAI;AACb,YAAI,SAAS,KAAM,YAAW,KAAK;AAAA,MACrC;AAAA,MACA,kBAAkB,CAAC,SAAS,OAAO,IAAI;AAAA,MAEvC,0BAAAC;AAAA,QAAC,gBAAgB;AAAA,QAAhB;AAAA,UACC,WAAW,GAAG,WAAW,SAAS;AAAA,UAClC,gBAAc,WAAW;AAAA,UACzB,sBAAoB;AAAA,UAEpB;AAAA,4BAAAD;AAAA,cAAC,gBAAgB;AAAA,cAAhB;AAAA,gBACC,KAAK;AAAA,gBACL,cAAY;AAAA,gBACZ,gBAAc,WAAW;AAAA,gBACzB,WAAW,GAAG,WAAW,cAAc;AAAA,gBACvC,WAAW,CAAC,UAAU;AACpB,sBAAI,MAAM,QAAQ,QAAS;AAC3B,wBAAM,eAAe;AACrB,iCAAe;AAAA,gBACjB;AAAA,gBACA,QAAQ,MAAM;AAIZ,wBAAM,OAAO,SAAS,SAAS,MAAM,KAAK,KAAK;AAC/C,sBAAI,SAAS,MAAM,CAAC,OAAO,SAAS,OAAO,IAAI,CAAC,EAAG,YAAW,IAAI;AAAA,gBACpE;AAAA;AAAA,YACF;AAAA,YACC,QACC,gBAAAA,MAAC,UAAK,WAAU,iDAAgD,eAAY,QACzE,gBACH;AAAA;AAAA;AAAA,MAEJ;AAAA;AAAA,EACF;AAEJ;;;ACpHA,SAAS,UAAU,kBAAkB;AAiD/B,SAUE,OAAAK,OAVF,QAAAC,aAAA;AAtBC,SAAS,OAAO;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,sBAAsB;AACxB,GAAgB;AACd,SACE,gBAAAA;AAAA,IAAC,WAAW;AAAA,IAAX;AAAA,MACC;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP,eAAe,CAAC,SAAS;AACvB,cAAM,SAAS,OAAO,IAAI;AAC1B,YAAI,WAAW,MAAO;AACtB,iBAAS,MAAM;AACf,kBAAU;AAAA,MACZ;AAAA,MAEA;AAAA,wBAAAA;AAAA,UAAC,WAAW;AAAA,UAAX;AAAA,YACC,cAAY;AAAA,YACZ,WAAW;AAAA,cACT;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,YACA,sBAAoB;AAAA,YAEpB;AAAA,8BAAAD,MAAC,WAAW,OAAX,EAAiB,WAAU,YAAW;AAAA,cACvC,gBAAAA,MAAC,WAAW,MAAX,EAAgB,WAAU,wBAAuB,eAAY,QAC5D,0BAAAA,MAAC,SAAI,OAAM,KAAI,QAAO,KAAI,SAAQ,WAAU,MAAK,QAC/C,0BAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,GAAE;AAAA,kBACF,QAAO;AAAA,kBACP,aAAY;AAAA,kBACZ,eAAc;AAAA,kBACd,gBAAe;AAAA;AAAA,cACjB,GACF,GACF;AAAA;AAAA;AAAA,QACF;AAAA,QAEA,gBAAAA,MAAC,WAAW,QAAX,EACC,0BAAAA,MAAC,WAAW,YAAX,EAAsB,YAAY,GAAG,sBAAsB,OAAO,WAAW,aAC5E,0BAAAA;AAAA,UAAC,WAAW;AAAA,UAAX;AAAA,YACC,WAAW;AAAA,cACT;AAAA,cACA,eAAe,eAAe;AAAA,YAChC;AAAA,YAEA,0BAAAA,MAAC,WAAW,MAAX,EACE,kBAAQ,IAAI,CAAC,WACZ,gBAAAA;AAAA,cAAC,WAAW;AAAA,cAAX;AAAA,gBAEC,OAAO,OAAO;AAAA,gBACd,UAAU,OAAO;AAAA,gBACjB,WAAW;AAAA,kBACT;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,gBAEA,0BAAAA,MAAC,WAAW,UAAX,EAAoB,WAAU,YAAY,iBAAO,OAAM;AAAA;AAAA,cAXnD,OAAO;AAAA,YAYd,CACD,GACH;AAAA;AAAA,QACF,GACF,GACF;AAAA;AAAA;AAAA,EACF;AAEJ;;;ACxGA,SAAS,UAAU,kBAAkB;AACrC,SAAS,aAAAE,YAAW,UAAAC,SAAQ,YAAAC,iBAAgB;AA8HpC,SACE,OAAAC,OADF,QAAAC,aAAA;AAvGR,IAAM,QAAQ,CAAC,SAAqC,MAAM,QAAQ,IAAI,IAAI,KAAK,CAAC,IAAI;AAE7E,SAAS,OAAO;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,sBAAsB;AACxB,GAAgB;AACd,QAAM,CAAC,OAAO,QAAQ,IAAIC,UAAS,KAAK;AACxC,QAAM,cAAcC,QAAO,KAAK;AAChC,QAAM,aAAaA,QAAO,KAAK;AAG/B,QAAM,eAAeA,QAAO,KAAK;AAGjC,QAAM,eAAeA,QAAO,KAAK;AACjC,QAAM,WAAWA,QAAO,KAAK;AAC7B,WAAS,UAAU;AAInB,EAAAC,WAAU,MAAM;AACd,QAAI,YAAY,QAAS;AACzB,iBAAa,UAAU;AACvB,aAAS,KAAK;AAAA,EAChB,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,SAAS,CAAC,SAAiB;AAC/B,QAAI,SAAS,aAAa,QAAS;AACnC,iBAAa,UAAU;AACvB,aAAS,IAAI;AAAA,EACf;AAEA,QAAM,QAAQ,MAAM;AAClB,QAAI,CAAC,YAAY,QAAS;AAC1B,eAAW,UAAU;AACrB,UAAM,QAAQ,aAAa;AAC3B,aAAS,KAAK;AACd,gBAAY,KAAK;AACjB,WAAO,KAAK;AAAA,EACd;AAEA,SACE,gBAAAJ;AAAA,IAAC,WAAW;AAAA,IAAX;AAAA,MACC,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,eAAe,CAAC,MAAM,YAAY;AAChC,YAAI,WAAW,SAAS;AAGtB,kBAAQ,OAAO;AACf;AAAA,QACF;AACA,cAAM,IAAI,MAAM,IAAI;AACpB,iBAAS,CAAC;AACV,oBAAY,CAAC;AAAA,MACf;AAAA,MACA,kBAAkB,CAAC,SAAS;AAC1B,oBAAY,UAAU;AACtB,YAAI,WAAW,SAAS;AACtB,qBAAW,UAAU;AACrB;AAAA,QACF;AACA,eAAO,MAAM,IAAI,CAAC;AAClB,kBAAU;AAAA,MACZ;AAAA,MACA,WAAW,GAAG,6BAA6B,SAAS;AAAA,MACpD,sBAAoB;AAAA,MAEpB,0BAAAA;AAAA,QAAC,WAAW;AAAA,QAAX;AAAA,UAGC,uBAAoB;AAAA,UAGpB,WAAU;AAAA,UACV,eAAe,MAAM;AACnB,wBAAY,UAAU;AACtB,uBAAW,UAAU;AACrB,yBAAa,UAAU,SAAS;AAAA,UAClC;AAAA,UACA,eAAe,CAAC,UAAU;AACxB,gBAAI,CAAC,YAAY,QAAS;AAC1B,kBAAM,eAAe;AACrB,kBAAM;AAAA,UACR;AAAA,UACA,WAAW,CAAC,UAAU;AACpB,gBAAI,MAAM,QAAQ,YAAY,CAAC,YAAY,QAAS;AACpD,kBAAM,eAAe;AACrB,kBAAM;AAAA,UACR;AAAA,UAEA,0BAAAC,MAAC,WAAW,OAAX,EAAiB,WAAU,sCAC1B;AAAA,4BAAAD,MAAC,WAAW,WAAX,EAAqB,WAAU,0BAAyB;AAAA,YACzD,gBAAAA;AAAA,cAAC,WAAW;AAAA,cAAX;AAAA,gBACC,cAAY;AAAA,gBACZ,WAAW;AAAA;AAAA;AAAA;AAAA,kBAIT;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA;AAAA,YACF;AAAA,aACF;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;;;ACnJA,SAAS,cAAc;AAgDjB,gBAAAK,aAAA;AA/BC,SAAS,OAAO;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,sBAAsB;AACxB,GAAgB;AACd,SACE,gBAAAA;AAAA,IAAC,OAAO;AAAA,IAAP;AAAA,MACC,cAAY;AAAA,MACZ;AAAA,MACA;AAAA,MACA,iBAAiB,CAAC,SAAS;AACzB,iBAAS,IAAI;AACb,kBAAU;AAAA,MACZ;AAAA,MACA,sBAAoB;AAAA,MACpB,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MAEA,0BAAAA;AAAA,QAAC,OAAO;AAAA,QAAP;AAAA,UACC,WAAW;AAAA,YACT;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;","names":["forwardRef","jsx","forwardRef","jsx","jsx","jsxs","jsx","jsxs","jsx","jsxs","useId","jsx","jsxs","SIDE_OFFSET","VIEWPORT_MARGIN","useId","jsx","jsxs","SIDE_OFFSET","VIEWPORT_MARGIN","useRef","useState","jsx","useState","useRef","useEffect","useRef","useState","jsx","jsxs","useState","useRef","useEffect","jsx","jsxs","useEffect","useRef","useState","jsx","jsxs","useState","useRef","useEffect","jsx"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|