hyperframes 0.8.106 → 0.8.107

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.
Files changed (164) hide show
  1. package/dist/{add-QRAI4CAF.js → add-DXZ3HNQI.js} +16 -16
  2. package/dist/{animatedGifPrep-RZVYVAXD.js → animatedGifPrep-2IQB4DGE.js} +7 -7
  3. package/dist/{asset-WFBQ5VS6.js → asset-KZIG3MZN.js} +2 -2
  4. package/dist/{assetCataloger-BQREHRS2.js → assetCataloger-4GE6PIUA.js} +3 -3
  5. package/dist/{auth-LVD6TWYG.js → auth-5IYF3H67.js} +2 -2
  6. package/dist/{autoUpdate-HGE2PUZY.js → autoUpdate-5C3FXM6Y.js} +2 -2
  7. package/dist/{backgroundChecks-63CSE4XR.js → backgroundChecks-75WGW4NB.js} +3 -3
  8. package/dist/backgroundChecksWorker.js +3 -3
  9. package/dist/{batchRender-AQN5PRXM.js → batchRender-FKKS3YBX.js} +4 -4
  10. package/dist/{beats-OBCN5OSQ.js → beats-ISR36NSK.js} +11 -11
  11. package/dist/{benchmark-DYHJSR7W.js → benchmark-U6TQ6DS2.js} +13 -13
  12. package/dist/{browser-JLYV5T7O.js → browser-VDS6QAVA.js} +10 -10
  13. package/dist/{bundleWithLocalizedFonts-JKJKZR2S.js → bundleWithLocalizedFonts-PMWWW5YG.js} +2 -2
  14. package/dist/{capture-5BCJWVC7.js → capture-5KE34KCD.js} +2 -2
  15. package/dist/{capture-QYLHIYKJ.js → capture-BKA3UCZS.js} +8 -8
  16. package/dist/{catalog-6UYNKENR.js → catalog-ZXOSU27O.js} +16 -16
  17. package/dist/{check-YOGAZ6UE.js → check-MZMZCXPN.js} +31 -31
  18. package/dist/{checkBrowser-M73YHPNM.js → checkBrowser-UIZJXYCQ.js} +30 -30
  19. package/dist/{chunk-LAHK4P7Q.js → chunk-3CYAZWF2.js} +3 -3
  20. package/dist/{chunk-TMLEIURT.js → chunk-3LBFLW7E.js} +1 -1
  21. package/dist/{chunk-JXXE3SWC.js → chunk-3WG63KFW.js} +11 -11
  22. package/dist/{chunk-UUE5BZGE.js → chunk-4DJXCVQJ.js} +53 -20
  23. package/dist/{chunk-I77CAR4W.js → chunk-4W4UDPCH.js} +2 -2
  24. package/dist/{chunk-PB2OX2JY.js → chunk-6QWHIARJ.js} +1 -1
  25. package/dist/{chunk-4WAMN4IF.js → chunk-73VPF3SS.js} +1 -1
  26. package/dist/{chunk-YVWILZCO.js → chunk-7BI5BYMQ.js} +5 -5
  27. package/dist/{chunk-4I6AQUWG.js → chunk-ADP6TMYP.js} +8 -8
  28. package/dist/{chunk-OSZJCBZX.js → chunk-AO4PBESP.js} +7 -7
  29. package/dist/{chunk-TYA65W4U.js → chunk-BRTGJ73L.js} +2 -2
  30. package/dist/{chunk-PUB5XZYL.js → chunk-C3KEF3UA.js} +1 -1
  31. package/dist/{chunk-VW5OMJNG.js → chunk-D5EJCP26.js} +14 -10
  32. package/dist/{chunk-Y2CZEJPK.js → chunk-FLUBCMNT.js} +2 -2
  33. package/dist/{chunk-5TBFBLIX.js → chunk-GLTHJJIF.js} +2 -2
  34. package/dist/{chunk-NRMYDPFQ.js → chunk-HGL4WJDI.js} +9 -9
  35. package/dist/{chunk-HFFR7TN7.js → chunk-HJCTKNXF.js} +2 -1
  36. package/dist/{chunk-FTXU3TQ4.js → chunk-I73Z6OOE.js} +1 -1
  37. package/dist/{chunk-2IZZZJDZ.js → chunk-J6CSEDK7.js} +4 -4
  38. package/dist/{chunk-USWOTTSP.js → chunk-JNY3VJWB.js} +1 -1
  39. package/dist/{chunk-J3Q3YC6P.js → chunk-KTPQ67TX.js} +1 -1
  40. package/dist/{chunk-JYRPUDVZ.js → chunk-L7XDI3DT.js} +1 -1
  41. package/dist/{chunk-6CN2QLB5.js → chunk-NHTRUAMD.js} +1 -1
  42. package/dist/{chunk-DVCYGZ7R.js → chunk-NX6G66F4.js} +2 -2
  43. package/dist/{chunk-6LPWMCPY.js → chunk-OGTR33KN.js} +2 -2
  44. package/dist/{chunk-HUHJYNST.js → chunk-P7XRDAWU.js} +1 -1
  45. package/dist/{chunk-FOKUJKBN.js → chunk-PMLZPNIB.js} +13 -2
  46. package/dist/{chunk-6F6EEQNB.js → chunk-PSGDNMM6.js} +1 -1
  47. package/dist/{chunk-O5TBFZ7X.js → chunk-PU2IOWX4.js} +2 -2
  48. package/dist/{chunk-AZQLJHAO.js → chunk-PZTEY73C.js} +1 -1
  49. package/dist/{chunk-XZSH5GS7.js → chunk-QH6UFY2O.js} +4 -4
  50. package/dist/{chunk-UVUAU3CH.js → chunk-QM2NUN2B.js} +47 -25
  51. package/dist/{chunk-TH4APNRP.js → chunk-R4IB642V.js} +2 -2
  52. package/dist/{chunk-GOI4GCUB.js → chunk-SGBOZ2HF.js} +1 -1
  53. package/dist/{chunk-GVZYTDOD.js → chunk-SKPL32FI.js} +1 -1
  54. package/dist/{chunk-IQ4UCWV7.js → chunk-T3BOWXPX.js} +1 -1
  55. package/dist/{chunk-AXWBDWAV.js → chunk-T4Z4UNSX.js} +3 -3
  56. package/dist/{chunk-IBCGKQB5.js → chunk-TI5Z4SWP.js} +3 -3
  57. package/dist/{chunk-2LCIQS3K.js → chunk-TPPIERG3.js} +3 -3
  58. package/dist/{chunk-TLYU5625.js → chunk-UUDQD62L.js} +6 -6
  59. package/dist/{chunk-TEXPOC5V.js → chunk-VMDEGITC.js} +2 -2
  60. package/dist/{chunk-I6M4GXMC.js → chunk-WBVPQC7J.js} +1 -1
  61. package/dist/{chunk-4Z5O7BTD.js → chunk-WEATBQTR.js} +10 -1
  62. package/dist/{chunk-R5RF3LGS.js → chunk-XMAL2A7Y.js} +1 -1
  63. package/dist/{chunk-4NJZZHYT.js → chunk-YVEZT6WT.js} +1 -1
  64. package/dist/{chunk-M4KS6MJN.js → chunk-YY5J75H5.js} +4 -4
  65. package/dist/{chunk-32Y3HRS3.js → chunk-Z4UAXNWV.js} +2 -2
  66. package/dist/{clean-GRX3GXKR.js → clean-46MZVA37.js} +16 -16
  67. package/dist/cli.js +50 -50
  68. package/dist/{cloud-TQCNBM6H.js → cloud-GAZQGPCW.js} +4 -4
  69. package/dist/{cloudrun-ISE6GSUO.js → cloudrun-ZWL7SLDD.js} +5 -5
  70. package/dist/{compare-QAWB3O4U.js → compare-66AAJESM.js} +25 -25
  71. package/dist/{compiler-QMEZK6CU.js → compiler-3N7XQRH6.js} +3 -3
  72. package/dist/{component-NXNNSXN7.js → component-3OCOHK2B.js} +3 -3
  73. package/dist/{compositions-I4PIPJKO.js → compositions-H2BP4N6F.js} +12 -12
  74. package/dist/{delete-ZC4ZRBBF.js → delete-WNJLVPGO.js} +4 -4
  75. package/dist/{deterministicFonts-XS3PGWH5.js → deterministicFonts-A4CNCSAL.js} +2 -2
  76. package/dist/{dist-E44WU6LH.js → dist-AY2RBEXL.js} +1 -1
  77. package/dist/{dist-R24TLUYO.js → dist-HSEMXPG3.js} +3 -3
  78. package/dist/docs/data-attributes.md +1 -1
  79. package/dist/{doctor-EFQ4XNT3.js → doctor-IFOZS45N.js} +11 -11
  80. package/dist/{events-COIPJKSK.js → events-5EKFJCCZ.js} +9 -9
  81. package/dist/{events-AVPSJNYU.js → events-6TH3FU3F.js} +10 -10
  82. package/dist/{feedback-3DYZDMLC.js → feedback-QRQNMORT.js} +11 -11
  83. package/dist/{figma-7XPHSMNG.js → figma-WONEPLUQ.js} +3 -3
  84. package/dist/fontLocalizeCli.js +10 -10
  85. package/dist/{get-TSBHDMKL.js → get-C7FCYNI2.js} +4 -4
  86. package/dist/{gpuPolicy-BQFPO7UA.js → gpuPolicy-BXXQF3VC.js} +7 -7
  87. package/dist/{grade-compare-5Y4LXQFG.js → grade-compare-SCCSZ5P3.js} +25 -25
  88. package/dist/{gsapParser-EZGJSSV5.js → gsapParser-KVMPC2SC.js} +5 -1
  89. package/dist/{help-5YBRP3C4.js → help-FJOUNXVD.js} +1 -1
  90. package/dist/{history-SRNXKL6D.js → history-OZY36NEC.js} +16 -16
  91. package/dist/hyperframe-runtime.js +10 -10
  92. package/dist/hyperframe.manifest.json +1 -1
  93. package/dist/hyperframe.runtime.iife.js +10 -10
  94. package/dist/hyperframes-player.global.js +1 -1
  95. package/dist/{info-U4BOXV2I.js → info-RG4SZQ2C.js} +12 -12
  96. package/dist/{init-T4JYHIBM.js → init-YGZCDKSS.js} +98 -42
  97. package/dist/{inspect-XYLD2BMM.js → inspect-X547EZ4I.js} +26 -26
  98. package/dist/{installer-UZSVMUKT.js → installer-6J24NTIV.js} +5 -5
  99. package/dist/{keyframes-BGPXWP7O.js → keyframes-EIWEION2.js} +13 -13
  100. package/dist/{lambda-U4WIJQCJ.js → lambda-DSZDMP7P.js} +6 -6
  101. package/dist/{layout-UREZQ37U.js → layout-B7KCBLBH.js} +26 -26
  102. package/dist/{lint-LSTEZZ6T.js → lint-RBDG4ERJ.js} +13 -13
  103. package/dist/{lintProject-4P4C6AN2.js → lintProject-CMPAR7BS.js} +1 -1
  104. package/dist/{list-6VICFTAM.js → list-BPHPHLDJ.js} +4 -4
  105. package/dist/{login-MXDIDOOG.js → login-HV7KBW2J.js} +4 -4
  106. package/dist/{media-treatment-ZVCWEACM.js → media-treatment-RS6BZSQC.js} +13 -13
  107. package/dist/{models-LXUIU5DC.js → models-K4U7GRXV.js} +8 -8
  108. package/dist/{motionShot-2LYUQF3T.js → motionShot-5AI2DALY.js} +11 -11
  109. package/dist/{normalize-audio-H3SI5V63.js → normalize-audio-J2PG6YXH.js} +11 -11
  110. package/dist/{pipeline-OFFKTFXS.js → pipeline-HIUESSET.js} +7 -7
  111. package/dist/{play-P56CWNVC.js → play-TTLQXBAH.js} +21 -21
  112. package/dist/{preflight-TVCVP5P2.js → preflight-63ODQ625.js} +8 -8
  113. package/dist/{present-ATMOWKMH.js → present-XKGZ26FQ.js} +17 -17
  114. package/dist/{preview-7U6HYHYE.js → preview-O2YEKMYJ.js} +18 -18
  115. package/dist/{producer-LGG3TOUI.js → producer-ZTQIJO7E.js} +1 -1
  116. package/dist/{projectConfig-V53SEFIS.js → projectConfig-VVFH7XW5.js} +7 -7
  117. package/dist/{publication-7RKKPKLM.js → publication-NALPAHDC.js} +3 -3
  118. package/dist/{publish-TRRFCEMQ.js → publish-G7OL45EL.js} +9 -9
  119. package/dist/{remove-background-HJFT46Z5.js → remove-background-LOLKFKLT.js} +8 -8
  120. package/dist/{render-2QZBNE2V.js → render-EXSRG666.js} +22 -22
  121. package/dist/{render-TPZ5FXHS.js → render-I65IU7RM.js} +4 -4
  122. package/dist/{render-YB7BARWL.js → render-ULQLUIWD.js} +15 -15
  123. package/dist/{render-batch-4ZF5C2LN.js → render-batch-RSNCREPB.js} +4 -4
  124. package/dist/{renderCancellation-4PYGAN5D.js → renderCancellation-2WB4SGXR.js} +7 -7
  125. package/dist/renderSetupWorker.js +1 -1
  126. package/dist/{resolver-4JRJPC6S.js → resolver-CVN2IM2R.js} +5 -5
  127. package/dist/{sherpa-MNCWRFD4.js → sherpa-OJUI54HG.js} +10 -10
  128. package/dist/{skills-ETBA5B46.js → skills-CPS5E5YP.js} +12 -12
  129. package/dist/{skillsUpdateCheck-DQOUIYV5.js → skillsUpdateCheck-3IT5CJWU.js} +3 -3
  130. package/dist/{snapshot-W3HTBAYH.js → snapshot-MSGC7HTA.js} +26 -26
  131. package/dist/{src-QF6RYX76.js → src-EZBJT4VH.js} +9 -9
  132. package/dist/{src-QX5PPANW.js → src-SV7CNZXN.js} +6 -6
  133. package/dist/{staticProjectServer-WBXW2CA4.js → staticProjectServer-5JAGMYT7.js} +15 -15
  134. package/dist/{status-C3IDZFDG.js → status-4W3EJYEH.js} +7 -7
  135. package/dist/studio/assets/{hyperframes-player-dl6K6ABp.js → hyperframes-player-h4mktSdm.js} +1 -1
  136. package/dist/studio/assets/{index-CMiYVGv5.js → index-CM1xA_jD.js} +195 -200
  137. package/dist/studio/assets/{index-ooaZZhKf.js → index-D8GKc2D9.js} +1 -1
  138. package/dist/studio/assets/{index-DKT5NF1Y.js → index-zoqPmBF6.js} +1 -1
  139. package/dist/studio/{chunk-ICTZJPQQ.js → chunk-4OZC426H.js} +12 -3
  140. package/dist/studio/chunk-4OZC426H.js.map +1 -0
  141. package/dist/studio/index.d.ts +367 -11
  142. package/dist/studio/index.html +1 -1
  143. package/dist/studio/index.js +1064 -714
  144. package/dist/studio/index.js.map +1 -1
  145. package/dist/studio/player.js +1 -1
  146. package/dist/{studio-api-6IJPJVG6.js → studio-api-L2TJ2JTK.js} +9 -9
  147. package/dist/{studioServer-77CY4XPO.js → studioServer-UV7YRYWN.js} +42 -41
  148. package/dist/{system-OAB2LYBV.js → system-OL4MXRPK.js} +7 -7
  149. package/dist/{telemetry-XTN5BO5S.js → telemetry-WRUU725E.js} +10 -10
  150. package/dist/templates/_shared/AGENTS.md +1 -1
  151. package/dist/templates/_shared/CLAUDE.md +1 -1
  152. package/dist/templates/from-file/index.html +3 -2
  153. package/dist/templates/warm-grain/index.html +2 -10
  154. package/dist/{timeline-YKKTGPL7.js → timeline-P43A53BW.js} +16 -16
  155. package/dist/{tokens-LU25F3IJ.js → tokens-NUHTJM2V.js} +2 -2
  156. package/dist/{transcribe-O7OL4RRU.js → transcribe-FSVNIFGF.js} +13 -13
  157. package/dist/{transcribe-AL3E5MBZ.js → transcribe-TRLZJK73.js} +10 -8
  158. package/dist/{updateCheck-MZZML4DL.js → updateCheck-33TAG46I.js} +2 -2
  159. package/dist/{upgrade-PQRTEJJY.js → upgrade-AJ6QBTH2.js} +2 -2
  160. package/dist/{urlDownloader-U3TNOPD5.js → urlDownloader-MP6GJIDV.js} +6 -6
  161. package/dist/{validate-KQETGCIR.js → validate-VL3A6VTJ.js} +16 -16
  162. package/dist/{video-KAHL76HG.js → video-KO7VT63P.js} +7 -7
  163. package/package.json +1 -1
  164. package/dist/studio/chunk-ICTZJPQQ.js.map +0 -1
@@ -6,7 +6,7 @@ var __filename = __hf_fileURLToPath(import.meta.url);
6
6
  var __dirname = __hf_dirname(__filename);
7
7
  import {
8
8
  resolveWritePath
9
- } from "./chunk-4Z5O7BTD.js";
9
+ } from "./chunk-WEATBQTR.js";
10
10
 
11
11
  // src/cloud/download.ts
12
12
  import {
@@ -8,7 +8,7 @@ import {
8
8
  firstFrameColourArgs,
9
9
  hdrToSdrToneMapFilter,
10
10
  parseFirstFrameColour
11
- } from "./chunk-TEXPOC5V.js";
11
+ } from "./chunk-VMDEGITC.js";
12
12
  import {
13
13
  mkdirWithinProject,
14
14
  realProjectRoot,
@@ -21,7 +21,7 @@ import {
21
21
  isUnresolvedAssetPlaceholder,
22
22
  maskNonScannableRanges,
23
23
  resolveLocalAssetCandidates
24
- } from "./chunk-UVUAU3CH.js";
24
+ } from "./chunk-QM2NUN2B.js";
25
25
  import {
26
26
  findFfBinary
27
27
  } from "./chunk-PJ3HDUCY.js";
@@ -7,7 +7,7 @@ var __dirname = __hf_dirname(__filename);
7
7
  import {
8
8
  VALID_CANVAS_RESOLUTIONS,
9
9
  resolveResolutionFlagPair
10
- } from "./chunk-TLYU5625.js";
10
+ } from "./chunk-UUDQD62L.js";
11
11
 
12
12
  // src/utils/parseOutputResolution.ts
13
13
  function parseOutputResolutionFlag(raw, options) {
@@ -12,18 +12,18 @@ import {
12
12
  } from "./chunk-262C25DQ.js";
13
13
  import {
14
14
  resolveDiagnosticNavigationTimeoutMs
15
- } from "./chunk-IQ4UCWV7.js";
15
+ } from "./chunk-T3BOWXPX.js";
16
16
  import {
17
17
  resolveCaptureBrowserGpuMode,
18
18
  resolveLocalBrowserGpuMode
19
- } from "./chunk-4WAMN4IF.js";
19
+ } from "./chunk-73VPF3SS.js";
20
20
  import {
21
21
  c
22
22
  } from "./chunk-ZTZA4UWZ.js";
23
23
  import {
24
24
  assertWebGpuAdapterAvailable,
25
25
  compositionRequiresWebGpu
26
- } from "./chunk-VW5OMJNG.js";
26
+ } from "./chunk-D5EJCP26.js";
27
27
  import {
28
28
  normalizeErrorMessage
29
29
  } from "./chunk-KNU5COPB.js";
@@ -99,7 +99,7 @@ async function openSettledCompositionPage(html, url, options) {
99
99
  const { ensureBrowser, findSystemBrowser } = await import("./manager-NEVLEZK3.js");
100
100
  const browser = await ensureBrowser();
101
101
  const puppeteer = await import("puppeteer-core");
102
- const { buildChromeArgs } = await import("./src-QX5PPANW.js");
102
+ const { buildChromeArgs } = await import("./src-SV7CNZXN.js");
103
103
  const requestedGpuMode = options.browserGpuMode ?? resolveCliChromeGpuMode();
104
104
  const requiresWebGpu = compositionRequiresWebGpu(html);
105
105
  const launch = async (executablePath) => {
@@ -4006,6 +4006,28 @@ function readAttr(tagSource, attr) {
4006
4006
  const match = tagSource.match(new RegExp(`(?<![\\w-])${escaped}\\s*=\\s*["']([^"']+)["']`, "i"));
4007
4007
  return match?.[1] || null;
4008
4008
  }
4009
+ function hasAttrName(tagSource, attr) {
4010
+ const escaped = attr.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4011
+ const attrs = tagSource.replace(/^<\s*[a-z][\w:-]*/i, "");
4012
+ return new RegExp(`(?:^|\\s)${escaped}(?:\\s*=|\\s|/?>)`, "i").test(attrs);
4013
+ }
4014
+ function isAudibleVideoTag(tagSource) {
4015
+ if (hasAttrName(tagSource, "muted")) return false;
4016
+ if (!hasAttrName(tagSource, "data-has-audio")) return true;
4017
+ const declared = readAttr(tagSource, "data-has-audio");
4018
+ return declared !== null && declared.trim().toLowerCase() !== "false";
4019
+ }
4020
+ function mediaTimeWindow(tagSource) {
4021
+ const start = Number(readAttr(tagSource, "data-start"));
4022
+ const duration = Number(readAttr(tagSource, "data-duration"));
4023
+ if (!readAttr(tagSource, "data-start") || !readAttr(tagSource, "data-duration")) return null;
4024
+ if (!Number.isFinite(start) || !Number.isFinite(duration)) return null;
4025
+ return { start, end: start + duration };
4026
+ }
4027
+ function mediaWindowsOverlap(a, b) {
4028
+ if (!a || !b) return true;
4029
+ return a.start < b.end && b.start < a.end;
4030
+ }
4009
4031
  function readDecodedAttr(tagSource, attr) {
4010
4032
  if (!tagSource) return null;
4011
4033
  let value = null;
@@ -5243,11 +5265,6 @@ function tweensVolumeInSameCall(script, id) {
5243
5265
  function escapeRegExp(value) {
5244
5266
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5245
5267
  }
5246
- function hasAttrName(tagSource, attr) {
5247
- const escaped = escapeRegExp(attr);
5248
- const attrs = tagSource.replace(/^<\s*[a-z][\w:-]*/i, "");
5249
- return new RegExp(`(?:^|\\s)${escaped}(?:\\s*=|\\s|/?>)`, "i").test(attrs);
5250
- }
5251
5268
  var IMAGE_SRC_EXT = /* @__PURE__ */ new Set([
5252
5269
  "jpg",
5253
5270
  "jpeg",
@@ -5648,14 +5665,15 @@ var mediaRules = [
5648
5665
  if (tag.name !== "video") continue;
5649
5666
  const hasMuted = hasAttrName(tag.raw, "muted");
5650
5667
  const hasDeclaredAudio = readAttr(tag.raw, "data-has-audio") === "true";
5651
- if (!hasMuted && !hasDeclaredAudio && readAttr(tag.raw, "data-start")) {
5668
+ const declaresAudioState = hasAttrName(tag.raw, "data-has-audio");
5669
+ if (!hasMuted && !declaresAudioState && readAttr(tag.raw, "data-start")) {
5652
5670
  const elementId = readAttr(tag.raw, "id") || void 0;
5653
5671
  findings.push({
5654
5672
  code: "video_missing_muted",
5655
5673
  severity: "error",
5656
- message: `<video${elementId ? ` id="${elementId}"` : ""}> has data-start but is not muted. Mark audible videos with data-has-audio="true"; otherwise keep video muted and use a separate <audio> element for sound.`,
5674
+ message: `<video${elementId ? ` id="${elementId}"` : ""}> has data-start but declares neither muted nor data-has-audio. If the file has sound, add data-has-audio="true" (the sound stays on this clip). If it is silent, add muted.`,
5657
5675
  elementId,
5658
- fixHint: 'Add the `muted` attribute for silent video, or add data-has-audio="true" when the video track should contribute audio.',
5676
+ fixHint: 'Add data-has-audio="true" when the file has sound (recommended \u2014 keeps picture and sound on one clip), or add `muted` for silent footage.',
5659
5677
  snippet: truncateSnippet(tag.raw)
5660
5678
  });
5661
5679
  }
@@ -5881,31 +5899,31 @@ var mediaRules = [
5881
5899
  // <audio> pointing to the same file, which causes double playback at runtime
5882
5900
  ({ tags }) => {
5883
5901
  const findings = [];
5884
- const videoSources = /* @__PURE__ */ new Map();
5885
- const audioSources = /* @__PURE__ */ new Map();
5902
+ const videos = [];
5903
+ const audios = [];
5886
5904
  for (const tag of tags) {
5887
5905
  if (!readAttr(tag.raw, "data-start")) continue;
5888
5906
  const src = readAttr(tag.raw, "src");
5889
5907
  if (!src) continue;
5890
- const elementId = readAttr(tag.raw, "id") || void 0;
5908
+ const source = { id: readAttr(tag.raw, "id") || void 0, raw: tag.raw };
5891
5909
  if (tag.name === "video") {
5892
- const isMuted = hasAttrName(tag.raw, "muted");
5893
- if (!isMuted) {
5894
- videoSources.set(src, { id: elementId, raw: tag.raw });
5895
- }
5910
+ if (isAudibleVideoTag(tag.raw)) videos.push([src, source]);
5896
5911
  } else if (tag.name === "audio") {
5897
- audioSources.set(src, { id: elementId, raw: tag.raw });
5912
+ audios.push([src, source]);
5898
5913
  }
5899
5914
  }
5900
- for (const [src, audioInfo] of audioSources) {
5901
- const videoInfo = videoSources.get(src);
5902
- if (!videoInfo) continue;
5915
+ for (const [src, audioInfo] of audios) {
5916
+ const match = videos.find(
5917
+ ([videoSrc, video]) => videoSrc === src && mediaWindowsOverlap(mediaTimeWindow(video.raw), mediaTimeWindow(audioInfo.raw))
5918
+ );
5919
+ if (!match) continue;
5920
+ const videoInfo = match[1];
5903
5921
  findings.push({
5904
5922
  code: "video_audio_double_source",
5905
5923
  severity: "error",
5906
- message: `<audio${audioInfo.id ? ` id="${audioInfo.id}"` : ""}> and <video${videoInfo.id ? ` id="${videoInfo.id}"` : ""}> both point to the same source. The unmuted video already provides audio \u2014 the duplicate <audio> will cause double playback and echo.`,
5924
+ message: `<audio${audioInfo.id ? ` id="${audioInfo.id}"` : ""}> and <video${videoInfo.id ? ` id="${videoInfo.id}"` : ""}> both point to the same source at the same time. The unmuted video already provides audio \u2014 the duplicate <audio> will cause double playback and echo.`,
5907
5925
  elementId: audioInfo.id,
5908
- fixHint: "Either mute the video (add `muted` attribute) and keep the separate <audio>, or remove the <audio> element and let the video provide its own audio track.",
5926
+ fixHint: "Remove the <audio> element and let the video carry its own sound (recommended), or mute the video (add `muted`) and keep the separate <audio> when picture and sound must be cut independently.",
5909
5927
  snippet: truncateSnippet(audioInfo.raw)
5910
5928
  });
5911
5929
  }
@@ -10404,7 +10422,10 @@ function lintProjectAudioFiles(projectDir, htmlSources) {
10404
10422
  }
10405
10423
  if (audioFiles.length === 0) return findings;
10406
10424
  const hasAudioElement = htmlSources.some(({ html }) => /<audio\b/i.test(html));
10407
- if (!hasAudioElement) {
10425
+ const hasAudibleVideo = htmlSources.some(
10426
+ ({ html }) => (html.match(/<video\b[^>]*>/gi) ?? []).some(isAudibleVideoTag)
10427
+ );
10428
+ if (!hasAudioElement && !hasAudibleVideo) {
10408
10429
  findings.push({
10409
10430
  code: "audio_file_without_element",
10410
10431
  severity: "warning",
@@ -10554,10 +10575,11 @@ function lintDuplicateAudioTracks(htmlSources) {
10554
10575
  const tracks = [];
10555
10576
  const seen = /* @__PURE__ */ new Set();
10556
10577
  for (const { html } of htmlSources) {
10557
- const audioTagRe = /<audio\b[^>]*>/gi;
10578
+ const soundTagRe = /<(?:audio|video)\b[^>]*>/gi;
10558
10579
  let match;
10559
- while ((match = audioTagRe.exec(html)) !== null) {
10580
+ while ((match = soundTagRe.exec(html)) !== null) {
10560
10581
  const tag = match[0];
10582
+ if (/^<video/i.test(tag) && !isAudibleVideoTag(tag)) continue;
10561
10583
  const trackStr = extractAttr(tag, "data-track-index");
10562
10584
  const startStr = extractAttr(tag, "data-start");
10563
10585
  const durStr = extractAttr(tag, "data-duration");
@@ -10581,7 +10603,7 @@ function lintDuplicateAudioTracks(htmlSources) {
10581
10603
  findings.push({
10582
10604
  code: "duplicate_audio_track",
10583
10605
  severity: "warning",
10584
- message: `Multiple <audio> elements on track ${a.trackIndex} overlap (${a.src} at ${a.start}-${Number.isFinite(a.end) ? a.end.toFixed(1) : "end"}s, ${b.src} at ${b.start}-${Number.isFinite(b.end) ? b.end.toFixed(1) : "end"}s). This causes layered audio playback.`,
10606
+ message: `Multiple audible <audio>/<video> elements on track ${a.trackIndex} overlap (${a.src} at ${a.start}-${Number.isFinite(a.end) ? a.end.toFixed(1) : "end"}s, ${b.src} at ${b.start}-${Number.isFinite(b.end) ? b.end.toFixed(1) : "end"}s). This causes layered audio playback.`,
10585
10607
  fixHint: "Use non-overlapping time windows or different track indices."
10586
10608
  });
10587
10609
  }
@@ -21,7 +21,7 @@ import {
21
21
  shouldClampResolvedMediaDuration,
22
22
  stripEmbeddedRuntimeScripts,
23
23
  warnUnknownEnumValues
24
- } from "./chunk-FOKUJKBN.js";
24
+ } from "./chunk-PMLZPNIB.js";
25
25
  import {
26
26
  cssVariableName
27
27
  } from "./chunk-VC76R6W2.js";
@@ -31,7 +31,7 @@ import {
31
31
  } from "./chunk-OFQWTKPW.js";
32
32
  import {
33
33
  lintHyperframeHtml
34
- } from "./chunk-UVUAU3CH.js";
34
+ } from "./chunk-QM2NUN2B.js";
35
35
  import {
36
36
  CSS_URL_RE,
37
37
  checkSubCompositionUsability,
@@ -7,7 +7,7 @@ var __dirname = __hf_dirname(__filename);
7
7
 
8
8
  // src/utils/producer.ts
9
9
  async function loadProducer() {
10
- return await import("./src-QF6RYX76.js");
10
+ return await import("./src-EZBJT4VH.js");
11
11
  }
12
12
 
13
13
  export {
@@ -6,7 +6,7 @@ var __filename = __hf_fileURLToPath(import.meta.url);
6
6
  var __dirname = __hf_dirname(__filename);
7
7
  import {
8
8
  updateNoticesSuppressed
9
- } from "./chunk-4NJZZHYT.js";
9
+ } from "./chunk-YVEZT6WT.js";
10
10
  import {
11
11
  hostAnswers
12
12
  } from "./chunk-K4WIOZFP.js";
@@ -15,7 +15,7 @@ import {
15
15
  } from "./chunk-PBN6GBJE.js";
16
16
  import {
17
17
  parseFps
18
- } from "./chunk-TEXPOC5V.js";
18
+ } from "./chunk-VMDEGITC.js";
19
19
 
20
20
  // src/utils/renderArgs.ts
21
21
  import { readFileSync } from "fs";
@@ -7,7 +7,7 @@ var __dirname = __hf_dirname(__filename);
7
7
  import {
8
8
  getMimeType,
9
9
  injectMediaCodecMapIntoHtml
10
- } from "./chunk-UUE5BZGE.js";
10
+ } from "./chunk-4DJXCVQJ.js";
11
11
  import {
12
12
  PROXY_VARIANT_CONFIG,
13
13
  ProxyCapacityError,
@@ -18,10 +18,10 @@ import {
18
18
  recordProxyRequest,
19
19
  resolveProxy,
20
20
  resolveProxyVariantRequest
21
- } from "./chunk-O5TBFZ7X.js";
21
+ } from "./chunk-PU2IOWX4.js";
22
22
  import {
23
23
  resolveAutoProxy
24
- } from "./chunk-HUHJYNST.js";
24
+ } from "./chunk-P7XRDAWU.js";
25
25
 
26
26
  // src/utils/staticProjectServer.ts
27
27
  import { createServer } from "http";
@@ -7,14 +7,14 @@ var __dirname = __hf_dirname(__filename);
7
7
  import {
8
8
  trackLintReport,
9
9
  trackLintRuleStreak
10
- } from "./chunk-2LCIQS3K.js";
10
+ } from "./chunk-TPPIERG3.js";
11
11
  import {
12
12
  shouldTrack
13
- } from "./chunk-LAHK4P7Q.js";
13
+ } from "./chunk-3CYAZWF2.js";
14
14
  import {
15
15
  LINT_RULE_COUNT,
16
16
  LINT_RULE_GROUP_COUNTS
17
- } from "./chunk-UVUAU3CH.js";
17
+ } from "./chunk-QM2NUN2B.js";
18
18
 
19
19
  // src/telemetry/lintStreaks.ts
20
20
  import { createHash } from "crypto";
@@ -8,16 +8,16 @@ import {
8
8
  flush,
9
9
  shouldTrack,
10
10
  trackEvent
11
- } from "./chunk-LAHK4P7Q.js";
11
+ } from "./chunk-3CYAZWF2.js";
12
12
  import {
13
13
  getPowerState
14
- } from "./chunk-PUB5XZYL.js";
14
+ } from "./chunk-C3KEF3UA.js";
15
15
  import {
16
16
  CliRuntimeError
17
17
  } from "./chunk-PBN6GBJE.js";
18
18
  import {
19
19
  redactTelemetryString
20
- } from "./chunk-TEXPOC5V.js";
20
+ } from "./chunk-VMDEGITC.js";
21
21
  import {
22
22
  readConfig
23
23
  } from "./chunk-XUXGIA7H.js";
@@ -4088,11 +4088,13 @@ function updateElementInHtml(html, elementId, updates) {
4088
4088
  el.removeAttribute("data-volume");
4089
4089
  }
4090
4090
  }
4091
- if ("hasAudio" in updates) {
4091
+ if (el.tagName.toLowerCase() === "video" && "hasAudio" in updates) {
4092
4092
  if (updates.hasAudio === true) {
4093
4093
  el.setAttribute("data-has-audio", "true");
4094
- } else {
4094
+ el.removeAttribute("muted");
4095
+ } else if (updates.hasAudio === false) {
4095
4096
  el.removeAttribute("data-has-audio");
4097
+ el.setAttribute("muted", "");
4096
4098
  }
4097
4099
  }
4098
4100
  if (!doc.documentElement) {
@@ -4126,12 +4128,10 @@ function addElementToHtml(html, element) {
4126
4128
  case "video": {
4127
4129
  const mediaEl = element;
4128
4130
  newEl = doc.createElement("video");
4129
- newEl.setAttribute("muted", "");
4130
4131
  newEl.setAttribute("playsinline", "");
4131
4132
  applyMediaAttrs(newEl, mediaEl);
4132
- if (mediaEl.hasAudio) {
4133
- newEl.setAttribute("data-has-audio", "true");
4134
- }
4133
+ if (mediaEl.hasAudio) newEl.setAttribute("data-has-audio", "true");
4134
+ else newEl.setAttribute("muted", "");
4135
4135
  break;
4136
4136
  }
4137
4137
  case "image": {
@@ -11,13 +11,13 @@ import {
11
11
  isTextElement,
12
12
  keyframesToGsapAnimations,
13
13
  serializeGsapAnimations
14
- } from "./chunk-TLYU5625.js";
14
+ } from "./chunk-UUDQD62L.js";
15
15
  import {
16
16
  isMediaElement as isMediaElement2,
17
17
  parseStrictFiniteTimingNumber,
18
18
  resolveNaturalMediaTimelineDuration,
19
19
  resolveTimedImageDurationSeconds
20
- } from "./chunk-FOKUJKBN.js";
20
+ } from "./chunk-PMLZPNIB.js";
21
21
  import {
22
22
  COMPOSITION_ATTRIBUTES,
23
23
  parseStartExpression
@@ -13,7 +13,7 @@ import {
13
13
  } from "./chunk-AWDFDFI3.js";
14
14
  import {
15
15
  isBlockedNetworkHost
16
- } from "./chunk-VW5OMJNG.js";
16
+ } from "./chunk-D5EJCP26.js";
17
17
  import {
18
18
  DOMParser,
19
19
  parseHTML
@@ -17,6 +17,13 @@ var BUSY_RENAME = /* @__PURE__ */ new Set(["EPERM", "EBUSY", "EACCES"]);
17
17
  var RENAME_RETRY_DELAYS_MS = [10, 20, 30, 40];
18
18
  var MAX_LINK_HOPS = 40;
19
19
  var TEMP_NAME_TRIES = 3;
20
+ var TEMP_SUFFIX = /\.hf[0-9a-f]{6}\.tmp$/;
21
+ function atomicTempPath(filePath) {
22
+ return `${filePath}.hf${randomBytes(3).toString("hex")}.tmp`;
23
+ }
24
+ function isAtomicTempPath(path) {
25
+ return TEMP_SUFFIX.test(path);
26
+ }
20
27
  function replaceFileAtomically(filePath, content, mode, operations = fs) {
21
28
  publishSibling(filePath, content, mode, operations, (tempPath) => renameWithRetry(operations, tempPath, filePath));
22
29
  }
@@ -72,7 +79,7 @@ function publishSibling(filePath, content, mode, operations, publish) {
72
79
  }
73
80
  function writeTempSibling(filePath, content, mode, operations) {
74
81
  for (let attempt = 1; ; attempt++) {
75
- const tempPath = `${filePath}.${randomBytes(4).toString("hex")}.tmp`;
82
+ const tempPath = atomicTempPath(filePath);
76
83
  try {
77
84
  operations.writeFileSync(tempPath, content, { encoding: "utf-8", mode, flag: "wx" });
78
85
  return tempPath;
@@ -108,6 +115,8 @@ function errorCode(error) {
108
115
  }
109
116
 
110
117
  export {
118
+ atomicTempPath,
119
+ isAtomicTempPath,
111
120
  replaceFileAtomically,
112
121
  createFileAtomically,
113
122
  resolveWritePath
@@ -17,7 +17,7 @@ import {
17
17
  import {
18
18
  FONT_ALIAS_MAP,
19
19
  resolveAliasDisplayName
20
- } from "./chunk-TLYU5625.js";
20
+ } from "./chunk-UUDQD62L.js";
21
21
  import {
22
22
  parseHTML
23
23
  } from "./chunk-GK4AIFIH.js";
@@ -17,7 +17,7 @@ import {
17
17
  } from "./chunk-ISN5GRYI.js";
18
18
  import {
19
19
  VERSION
20
- } from "./chunk-6LPWMCPY.js";
20
+ } from "./chunk-OGTR33KN.js";
21
21
 
22
22
  // src/utils/updateCheck.ts
23
23
  import { existsSync, readFileSync } from "fs";
@@ -8,19 +8,19 @@ import {
8
8
  isAllowedHtmlAttribute,
9
9
  isSafeAttributeValue,
10
10
  sanitizeRichTextChildren
11
- } from "./chunk-TEXPOC5V.js";
11
+ } from "./chunk-VMDEGITC.js";
12
12
  import {
13
13
  removeElementWithGsapCascade
14
- } from "./chunk-TLYU5625.js";
14
+ } from "./chunk-UUDQD62L.js";
15
15
  import {
16
16
  EXCLUDED_TAGS,
17
17
  ensureHfIds,
18
18
  mintHfId,
19
19
  walkCompositionDescendants
20
- } from "./chunk-TH4APNRP.js";
20
+ } from "./chunk-R4IB642V.js";
21
21
  import {
22
22
  require_dist
23
- } from "./chunk-UVUAU3CH.js";
23
+ } from "./chunk-QM2NUN2B.js";
24
24
  import {
25
25
  readClipTiming,
26
26
  readMediaOffsetSeconds,
@@ -8,10 +8,10 @@ import {
8
8
  DEFAULT_VP9_CPU_USED,
9
9
  isHttpUrl,
10
10
  runFfmpeg
11
- } from "./chunk-VW5OMJNG.js";
11
+ } from "./chunk-D5EJCP26.js";
12
12
  import {
13
13
  parseAnimatedGifMetadata
14
- } from "./chunk-TEXPOC5V.js";
14
+ } from "./chunk-VMDEGITC.js";
15
15
  import {
16
16
  parseHTML
17
17
  } from "./chunk-GK4AIFIH.js";
@@ -6,33 +6,33 @@ var __filename = __hf_fileURLToPath(import.meta.url);
6
6
  var __dirname = __hf_dirname(__filename);
7
7
  import {
8
8
  redactHome
9
- } from "./chunk-YVWILZCO.js";
9
+ } from "./chunk-7BI5BYMQ.js";
10
10
  import "./chunk-Z27A7NUB.js";
11
11
  import "./chunk-5ETJX6WM.js";
12
12
  import {
13
13
  loadProducer
14
- } from "./chunk-GOI4GCUB.js";
14
+ } from "./chunk-SGBOZ2HF.js";
15
15
  import {
16
16
  DEFAULT_HISTORY_ROOT,
17
17
  listProjectHistories,
18
18
  pruneGoneProjectHistories
19
- } from "./chunk-UUE5BZGE.js";
20
- import "./chunk-M4KS6MJN.js";
21
- import "./chunk-4Z5O7BTD.js";
19
+ } from "./chunk-4DJXCVQJ.js";
20
+ import "./chunk-YY5J75H5.js";
21
+ import "./chunk-WEATBQTR.js";
22
22
  import {
23
23
  CACHE_DIR_NAME,
24
24
  cleanupProxyCache
25
- } from "./chunk-O5TBFZ7X.js";
25
+ } from "./chunk-PU2IOWX4.js";
26
26
  import {
27
27
  formatBytes
28
28
  } from "./chunk-IHFUKJOR.js";
29
- import "./chunk-PB2OX2JY.js";
29
+ import "./chunk-6QWHIARJ.js";
30
30
  import "./chunk-TVCRUG2S.js";
31
31
  import "./chunk-RDMAU7AJ.js";
32
32
  import {
33
33
  c
34
34
  } from "./chunk-ZTZA4UWZ.js";
35
- import "./chunk-PUB5XZYL.js";
35
+ import "./chunk-C3KEF3UA.js";
36
36
  import "./chunk-AMKC3AXA.js";
37
37
  import {
38
38
  defineCommand
@@ -47,18 +47,18 @@ import {
47
47
  directorySizeBytes,
48
48
  gcExtractionCache,
49
49
  resolveExtractCacheDir
50
- } from "./chunk-VW5OMJNG.js";
51
- import "./chunk-TEXPOC5V.js";
52
- import "./chunk-TLYU5625.js";
50
+ } from "./chunk-D5EJCP26.js";
51
+ import "./chunk-VMDEGITC.js";
52
+ import "./chunk-UUDQD62L.js";
53
53
  import "./chunk-DPVXBVLL.js";
54
- import "./chunk-TH4APNRP.js";
55
- import "./chunk-FOKUJKBN.js";
54
+ import "./chunk-R4IB642V.js";
55
+ import "./chunk-PMLZPNIB.js";
56
56
  import "./chunk-VC76R6W2.js";
57
57
  import "./chunk-OFQWTKPW.js";
58
58
  import "./chunk-N34BYX3E.js";
59
59
  import "./chunk-LCSMOLGX.js";
60
60
  import "./chunk-TWWSYAKJ.js";
61
- import "./chunk-UVUAU3CH.js";
61
+ import "./chunk-QM2NUN2B.js";
62
62
  import "./chunk-HBBJFK6I.js";
63
63
  import "./chunk-PJ3HDUCY.js";
64
64
  import "./chunk-TQFG7HTI.js";
@@ -66,12 +66,12 @@ import "./chunk-GK4AIFIH.js";
66
66
  import "./chunk-2PSPARWP.js";
67
67
  import {
68
68
  withMeta
69
- } from "./chunk-4NJZZHYT.js";
69
+ } from "./chunk-YVEZT6WT.js";
70
70
  import "./chunk-K4WIOZFP.js";
71
71
  import "./chunk-XUXGIA7H.js";
72
72
  import "./chunk-WERLJGIC.js";
73
73
  import "./chunk-ISN5GRYI.js";
74
- import "./chunk-6LPWMCPY.js";
74
+ import "./chunk-OGTR33KN.js";
75
75
  import "./chunk-KNU5COPB.js";
76
76
  import "./chunk-XT5P4QMO.js";
77
77
  import "./chunk-6BEFEWFB.js";