hyperframes 0.8.40 → 0.8.42

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.
@@ -56728,7 +56728,12 @@ var init_captureFailure = __esm({
56728
56728
  /Navigation timeout of \d+ ms exceeded/i,
56729
56729
  /ECONNREFUSED/i,
56730
56730
  /net::ERR_NETWORK_CHANGED/i,
56731
- /Composition has zero duration[\s\S]*Runtime ready: false/
56731
+ /Composition has zero duration[\s\S]*Runtime ready: false/,
56732
+ // CDP can refuse a capture call outright with this exact wording; timed-out
56733
+ // variants of the same call hit PROTOCOL_TIMEOUT_PATTERNS, checked first.
56734
+ // Anchored to this literal reason (not just the CDP method) so an unrelated,
56735
+ // genuinely deterministic Page.captureScreenshot error isn't swept in too.
56736
+ /Protocol error \(Page\.captureScreenshot\): Unable to capture screenshot/i
56732
56737
  ];
56733
56738
  PROTOCOL_TIMEOUT_PATTERNS = [
56734
56739
  /Network\.enable timed out/i,
@@ -59548,6 +59553,19 @@ function getHdrEncoderColorParams(transfer, mastering = DEFAULT_HDR10_MASTERING)
59548
59553
  mastering
59549
59554
  };
59550
59555
  }
59556
+ function sanitizeHdrAutoPromotionAsset(asset) {
59557
+ return asset.split(/[\r\n?#]/, 1)[0] ?? "";
59558
+ }
59559
+ function findHdrAutoPromotion(sources) {
59560
+ const source = sources.find(({ colorSpace }) => isHdrColorSpace(colorSpace));
59561
+ return source ? {
59562
+ triggeringAsset: sanitizeHdrAutoPromotionAsset(source.asset),
59563
+ output: HDR_AUTO_PROMOTION_PIPELINE
59564
+ } : null;
59565
+ }
59566
+ function formatHdrAutoPromotionWarning(promotion) {
59567
+ return `[Render] HDR auto-promotion triggered by "${promotion.triggeringAsset}" \u2014 output: ${promotion.output.colorSpace} / ${promotion.output.codec}`;
59568
+ }
59551
59569
  function analyzeCompositionHdr(colorSpaces) {
59552
59570
  let hasPq = false;
59553
59571
  let hasHdr = false;
@@ -59560,7 +59578,7 @@ function analyzeCompositionHdr(colorSpaces) {
59560
59578
  const dominantTransfer = hasPq ? "pq" : "hlg";
59561
59579
  return { hasHdr: true, dominantTransfer };
59562
59580
  }
59563
- var DEFAULT_HDR10_MASTERING;
59581
+ var DEFAULT_HDR10_MASTERING, HDR_AUTO_PROMOTION_PIPELINE;
59564
59582
  var init_hdr = __esm({
59565
59583
  "../engine/src/utils/hdr.ts"() {
59566
59584
  "use strict";
@@ -59568,6 +59586,10 @@ var init_hdr = __esm({
59568
59586
  masterDisplay: "G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1)",
59569
59587
  maxCll: "1000,400"
59570
59588
  };
59589
+ HDR_AUTO_PROMOTION_PIPELINE = {
59590
+ colorSpace: "BT.2020",
59591
+ codec: "HEVC Main10"
59592
+ };
59571
59593
  }
59572
59594
  });
59573
59595
 
@@ -70906,6 +70928,7 @@ var init_dist3 = __esm({
70906
70928
  init_composition();
70907
70929
  init_slideshow();
70908
70930
  init_esm10();
70931
+ init_esm10();
70909
70932
  COMPOSITION_ID_IN_CSS_PATTERN = /\[data-composition-id=["']([^"']+)["']\]/g;
70910
70933
  TIMELINE_REGISTRY_INIT_PATTERN = /window\.__timelines\s*=\s*window\.__timelines\s*\|\|\s*\{\}|window\.__timelines\s*=\s*\{\}|window\.__timelines\s*\?\?=\s*\{\}/i;
70911
70934
  TIMELINE_REGISTRY_OBJECT_LITERAL_PATTERN = /window\.__timelines\s*=\s*\{\s*(?:["'][^"']+["']|[A-Za-z_$][\w$]*)\s*:/i;
@@ -74630,13 +74653,20 @@ function publishCacheEntry(entry, partialDir) {
74630
74653
  return adoptPublishedWinner(entry, partialDir) ?? { dir: partialDir, published: false };
74631
74654
  }
74632
74655
  }
74633
- function touchCacheEntry(entry) {
74656
+ function touchCacheDir(dir) {
74657
+ const now = /* @__PURE__ */ new Date();
74658
+ try {
74659
+ utimesSync(dir, now, now);
74660
+ } catch {
74661
+ }
74634
74662
  try {
74635
- const now = /* @__PURE__ */ new Date();
74636
- utimesSync(join10(entry.dir, COMPLETE_SENTINEL), now, now);
74663
+ utimesSync(join10(dir, COMPLETE_SENTINEL), now, now);
74637
74664
  } catch {
74638
74665
  }
74639
74666
  }
74667
+ function touchCacheEntry(entry) {
74668
+ touchCacheDir(entry.dir);
74669
+ }
74640
74670
  function isCacheLikeChild(name) {
74641
74671
  return name.startsWith(CACHE_GENERATION_PREFIX) || name.includes(".partial-");
74642
74672
  }
@@ -75168,6 +75198,9 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
75168
75198
  if (options.sdrToHdrTransfer) {
75169
75199
  vfFilters.push(SDR_TO_HDR_COLORSPACE_FILTER);
75170
75200
  }
75201
+ if (options.toneMapHdrToSdr && isHdr && !isMacOS) {
75202
+ vfFilters.push(HDR_TO_SDR_TONEMAP_FILTER);
75203
+ }
75171
75204
  if (vfFilters.length > 0) args.push("-vf", vfFilters.join(","));
75172
75205
  if (!options.finalFrameOnly && metadata.isVFR) {
75173
75206
  args.push("-fps_mode", "cfr", "-r", ffmpegFps);
@@ -75260,6 +75293,10 @@ function resolveSegmentDuration(requested, mediaStart, sourceDuration) {
75260
75293
  function resolvePlayableVideoDuration(metadata) {
75261
75294
  return Number.isFinite(metadata.videoStreamDurationSeconds) && metadata.videoStreamDurationSeconds > 0 ? metadata.videoStreamDurationSeconds : metadata.durationSeconds;
75262
75295
  }
75296
+ function canHoldFinalFramePastEof(video) {
75297
+ const timelineDuration = video.end - video.start;
75298
+ return !video.loop && Number.isFinite(timelineDuration) && timelineDuration > 0;
75299
+ }
75263
75300
  function resolveTimelineExtractionWindow(video, resolvedDuration, timelineEnd, sourceDuration) {
75264
75301
  const playbackRate = normalizePlaybackRate(video.playbackRate ?? 1);
75265
75302
  const withTimelineDuration = (window3, timelineDurationSeconds) => playbackRate === 1 ? window3 : { ...window3, timelineDurationSeconds };
@@ -75328,6 +75365,18 @@ function resolveTimelineExtractionWindow(video, resolvedDuration, timelineEnd, s
75328
75365
  },
75329
75366
  visibleDuration
75330
75367
  );
75368
+ } else if (canHoldFinalFramePastEof(video)) {
75369
+ const logicalDuration = Math.min(sourceDuration, FINAL_FRAME_LOGICAL_DURATION_SECONDS);
75370
+ return withTimelineDuration(
75371
+ {
75372
+ compositionStart: video.start,
75373
+ mediaStart: sourceDuration - logicalDuration,
75374
+ durationSeconds: logicalDuration,
75375
+ preserveTimelineEnd: true,
75376
+ ensureFinalFrame: true
75377
+ },
75378
+ visibleDuration
75379
+ );
75331
75380
  }
75332
75381
  }
75333
75382
  return withTimelineDuration(
@@ -75352,7 +75401,10 @@ async function resolveFinalFrameExtractionWindow(videoPath, video, metadata, win
75352
75401
  );
75353
75402
  if (window3.mediaStart < finalFrameTimestamp - 1e-9) return window3;
75354
75403
  const sourceRemaining = playableDuration - video.mediaStart;
75355
- const logicalDuration = Math.min(sourceRemaining, FINAL_FRAME_LOGICAL_DURATION_SECONDS);
75404
+ const logicalDuration = Math.min(
75405
+ Math.max(sourceRemaining, window3.durationSeconds),
75406
+ FINAL_FRAME_LOGICAL_DURATION_SECONDS
75407
+ );
75356
75408
  return {
75357
75409
  compositionStart: Math.max(0, video.start),
75358
75410
  mediaStart: playableDuration - logicalDuration,
@@ -75373,7 +75425,9 @@ function resolveVideoExtractionWindow(video, metadata, timelineEnd) {
75373
75425
  `Playable video stream duration is ${playableDuration}s`
75374
75426
  );
75375
75427
  }
75376
- if (video.mediaStart >= playableDuration) {
75428
+ const requestedTimelineDuration = video.end - video.start;
75429
+ const heldPastEof = video.mediaStart >= playableDuration && canHoldFinalFramePastEof(video);
75430
+ if (video.mediaStart >= playableDuration && !heldPastEof) {
75377
75431
  throw new VideoSourceExtractionError(
75378
75432
  "media_start_out_of_range",
75379
75433
  false,
@@ -75382,9 +75436,13 @@ function resolveVideoExtractionWindow(video, metadata, timelineEnd) {
75382
75436
  );
75383
75437
  }
75384
75438
  const playbackRate = normalizePlaybackRate(video.playbackRate ?? 1);
75385
- const requestedTimelineDuration = video.end - video.start;
75386
75439
  const resolvedDuration = Number.isFinite(requestedTimelineDuration) && requestedTimelineDuration > 0 ? requestedTimelineDuration : resolveSegmentDuration(requestedTimelineDuration, video.mediaStart, playableDuration) / playbackRate;
75387
- return resolveTimelineExtractionWindow(video, resolvedDuration, timelineEnd, playableDuration);
75440
+ return resolveTimelineExtractionWindow(
75441
+ video,
75442
+ resolvedDuration,
75443
+ timelineEnd ?? (heldPastEof ? video.end : void 0),
75444
+ playableDuration
75445
+ );
75388
75446
  }
75389
75447
  function resolveVideoExtractionDuration(video, metadata, timelineEnd) {
75390
75448
  return resolveVideoExtractionWindow(video, metadata, timelineEnd).durationSeconds;
@@ -75433,6 +75491,7 @@ function supersetGroupingKey(work, fps) {
75433
75491
  String(fps),
75434
75492
  work.format,
75435
75493
  work.sdrToHdrTransfer ?? "",
75494
+ work.toneMapHdrToSdr ? HDR_TO_SDR_TRANSFORM_KEY : "",
75436
75495
  work.finalFrameOnly ? "final" : "range"
75437
75496
  ].join("\0");
75438
75497
  }
@@ -75700,7 +75759,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
75700
75759
  const metadata = videoMetadata[i];
75701
75760
  if (!entry || !metadata) continue;
75702
75761
  const playableDuration = resolvePlayableVideoDuration(metadata);
75703
- if (entry.video.mediaStart >= playableDuration) {
75762
+ if (entry.video.mediaStart >= playableDuration && !canHoldFinalFramePastEof(entry.video)) {
75704
75763
  errors.push({
75705
75764
  videoId: entry.video.id,
75706
75765
  kind: "media_start_out_of_range",
@@ -75764,6 +75823,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
75764
75823
  ...options,
75765
75824
  format: work.format,
75766
75825
  sdrToHdrTransfer: work.sdrToHdrTransfer,
75826
+ toneMapHdrToSdr: work.toneMapHdrToSdr,
75767
75827
  finalFrameOnly: work.finalFrameOnly
75768
75828
  };
75769
75829
  }
@@ -75783,6 +75843,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
75783
75843
  if (!keyInput) return { work };
75784
75844
  const transformParts = [
75785
75845
  work.sdrToHdrTransfer ? sdrToHdrTransformKey(work.sdrToHdrTransfer) : void 0,
75846
+ work.toneMapHdrToSdr ? HDR_TO_SDR_TRANSFORM_KEY : void 0,
75786
75847
  work.finalFrameOnly ? "final-frame" : void 0
75787
75848
  ].filter((part) => part !== void 0);
75788
75849
  const transform = transformParts.length > 0 ? transformParts.join("+") : void 0;
@@ -75963,8 +76024,9 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
75963
76024
  if (keyInput) keyInput.mediaStart = extractionMediaStart;
75964
76025
  const format = resolveFrameFormat(metadata, options.format);
75965
76026
  const sdrToHdrTransfer = sdrToHdrTransfers[index];
76027
+ const toneMapHdrToSdr = options.toneMapHdrToSdr === true && isHdrColorSpace(metadata.colorSpace);
75966
76028
  const finalFrameOnly = window3.finalFrameOnly === true;
75967
- const dedupeKey = `${videoPath}\0${extractionMediaStart}\0${videoDuration}\0${fpsKey}\0${format}\0${sdrToHdrTransfer ?? ""}\0${finalFrameOnly ? "final" : "range"}`;
76029
+ const dedupeKey = `${videoPath}\0${extractionMediaStart}\0${videoDuration}\0${fpsKey}\0${format}\0${sdrToHdrTransfer ?? ""}\0${toneMapHdrToSdr ? HDR_TO_SDR_TRANSFORM_KEY : ""}\0${finalFrameOnly ? "final" : "range"}`;
75968
76030
  return {
75969
76031
  work: {
75970
76032
  video,
@@ -75976,6 +76038,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
75976
76038
  finalFrameOnly,
75977
76039
  format,
75978
76040
  sdrToHdrTransfer,
76041
+ toneMapHdrToSdr,
75979
76042
  dedupeKey
75980
76043
  }
75981
76044
  };
@@ -76110,7 +76173,7 @@ function createFrameLookupTable(videos, extracted) {
76110
76173
  }
76111
76174
  return table;
76112
76175
  }
76113
- var VIDEO_FRAME_FORMATS, EXTRACT_CACHE_MIN_AGE_MS, GC_STALENESS_MS, SDR_TO_HDR_COLORSPACE_FILTER, VideoSourceExtractionError, TRANSIENT_FFMPEG_SPAWN_CODES, FINAL_FRAME_LOGICAL_DURATION_SECONDS, ALPHA_CAPABLE_CODECS, FrameLookupTable;
76176
+ var VIDEO_FRAME_FORMATS, EXTRACT_CACHE_MIN_AGE_MS, GC_STALENESS_MS, SDR_TO_HDR_COLORSPACE_FILTER, HDR_TO_SDR_TONEMAP_FILTER, HDR_TO_SDR_TRANSFORM_KEY, VideoSourceExtractionError, TRANSIENT_FFMPEG_SPAWN_CODES, FINAL_FRAME_LOGICAL_DURATION_SECONDS, ALPHA_CAPABLE_CODECS, FrameLookupTable;
76114
76177
  var init_videoFrameExtractor = __esm({
76115
76178
  "../engine/src/services/videoFrameExtractor.ts"() {
76116
76179
  "use strict";
@@ -76130,6 +76193,8 @@ var init_videoFrameExtractor = __esm({
76130
76193
  EXTRACT_CACHE_MIN_AGE_MS = 60 * 60 * 1e3;
76131
76194
  GC_STALENESS_MS = 24 * 60 * 60 * 1e3;
76132
76195
  SDR_TO_HDR_COLORSPACE_FILTER = "colorspace=all=bt2020:iall=bt709:range=tv";
76196
+ HDR_TO_SDR_TONEMAP_FILTER = "zscale=t=linear:npl=100,tonemap=hable:desat=0,zscale=p=bt709:t=bt709:m=bt709:r=tv";
76197
+ HDR_TO_SDR_TRANSFORM_KEY = "hdr2sdr-hable-bt709";
76133
76198
  VideoSourceExtractionError = class extends Error {
76134
76199
  constructor(kind, retryable, message, diagnostic = message) {
76135
76200
  super(message);
@@ -76267,6 +76332,7 @@ var init_videoFrameExtractor = __esm({
76267
76332
 
76268
76333
  // ../engine/src/services/videoFrameInjector.ts
76269
76334
  import { promises as fs } from "fs";
76335
+ import { dirname as dirname7 } from "path";
76270
76336
  function createFrameSourceCache(entryLimit, bytesLimit, frameSrcResolver) {
76271
76337
  const cache = /* @__PURE__ */ new Map();
76272
76338
  const inFlight = /* @__PURE__ */ new Map();
@@ -76346,6 +76412,15 @@ function createVideoFrameInjector(frameLookup, config) {
76346
76412
  const bytesLimit = bytesLimitMb * 1024 * 1024;
76347
76413
  const frameCache = createFrameSourceCache(entryLimit, bytesLimit, config?.frameSrcResolver);
76348
76414
  const lastInjectedFrameByVideo = /* @__PURE__ */ new Map();
76415
+ const lastCacheTouchByDir = /* @__PURE__ */ new Map();
76416
+ function renewCacheLease(framePath) {
76417
+ const cacheDir = dirname7(framePath);
76418
+ const now = Date.now();
76419
+ const lastTouch = lastCacheTouchByDir.get(cacheDir);
76420
+ if (lastTouch !== void 0 && now - lastTouch < CACHE_TOUCH_THROTTLE_MS) return;
76421
+ touchCacheDir(cacheDir);
76422
+ lastCacheTouchByDir.set(cacheDir, now);
76423
+ }
76349
76424
  return async (page, time) => {
76350
76425
  const activePayloads = frameLookup.getActiveFramePayloads(time);
76351
76426
  const updates = [];
@@ -76354,6 +76429,7 @@ function createVideoFrameInjector(frameLookup, config) {
76354
76429
  const pendingReads = [];
76355
76430
  for (const [videoId, payload] of activePayloads) {
76356
76431
  activeIds.add(videoId);
76432
+ renewCacheLease(payload.framePath);
76357
76433
  const lastFrameIndex = lastInjectedFrameByVideo.get(videoId);
76358
76434
  if (lastFrameIndex === payload.frameIndex) continue;
76359
76435
  pendingReads.push(
@@ -76679,12 +76755,15 @@ async function queryElementStacking(page, nativeHdrIds) {
76679
76755
  RENDER_FRAME_ID_SUFFIX
76680
76756
  );
76681
76757
  }
76758
+ var CACHE_TOUCH_THROTTLE_MS;
76682
76759
  var init_videoFrameInjector = __esm({
76683
76760
  "../engine/src/services/videoFrameInjector.ts"() {
76684
76761
  "use strict";
76762
+ init_extractionCache();
76685
76763
  init_screenshotService();
76686
76764
  init_config();
76687
76765
  init_dist2();
76766
+ CACHE_TOUCH_THROTTLE_MS = 5 * 60 * 1e3;
76688
76767
  }
76689
76768
  });
76690
76769
 
@@ -76839,7 +76918,7 @@ var init_wavChunks = __esm({
76839
76918
 
76840
76919
  // ../engine/src/services/audioVolumeEnvelope.ts
76841
76920
  import { mkdtempSync as mkdtempSync3, readFileSync as readFileSync3, renameSync as renameSync2, rmSync as rmSync4, writeFileSync as writeFileSync4 } from "fs";
76842
- import { dirname as dirname7, join as join12 } from "path";
76921
+ import { dirname as dirname8, join as join12 } from "path";
76843
76922
  function readFmtChunk(buffer, body) {
76844
76923
  const format = buffer.readUInt16LE(body);
76845
76924
  const bits = buffer.readUInt16LE(body + 14);
@@ -76911,7 +76990,7 @@ function applyVolumeEnvelopeToWav(wavPath, keyframes, trackStart, baseVolume) {
76911
76990
  const layout2 = parseWavLayout(buffer);
76912
76991
  if (!layout2) return false;
76913
76992
  scaleSamples(buffer, layout2, gainAt);
76914
- stagingDir = mkdtempSync3(join12(dirname7(wavPath), ".hf-volume-"));
76993
+ stagingDir = mkdtempSync3(join12(dirname8(wavPath), ".hf-volume-"));
76915
76994
  const tempPath = join12(stagingDir, "audio.wav");
76916
76995
  writeFileSync4(tempPath, buffer, { flag: "wx" });
76917
76996
  renameSync2(tempPath, wavPath);
@@ -78384,7 +78463,7 @@ var init_audioFxRender = __esm({
78384
78463
 
78385
78464
  // ../engine/src/services/audioMixer.ts
78386
78465
  import { closeSync as closeSync2, existsSync as existsSync12, mkdirSync as mkdirSync7, mkdtempSync as mkdtempSync5, openSync as openSync2, rmSync as rmSync6, writeFileSync as writeFileSync6 } from "fs";
78387
- import { join as join14, dirname as dirname8 } from "path";
78466
+ import { join as join14, dirname as dirname9 } from "path";
78388
78467
  function memberGroupKey(el) {
78389
78468
  return el.getAttribute(AUDIO_GROUP_RENDER_ID_ATTR) ?? el.getAttribute(HF_AUDIO_GROUP_ATTR);
78390
78469
  }
@@ -78687,7 +78766,7 @@ function parseAudioElements(html) {
78687
78766
  }
78688
78767
  async function extractAudioFromVideo(videoPath, outputPath, options, signal, config) {
78689
78768
  const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
78690
- const outputDir = dirname8(outputPath);
78769
+ const outputDir = dirname9(outputPath);
78691
78770
  if (!existsSync12(outputDir)) mkdirSync7(outputDir, { recursive: true });
78692
78771
  const playbackRate = normalizePlaybackRate(options?.playbackRate ?? 1);
78693
78772
  const args = [];
@@ -78731,7 +78810,7 @@ async function extractAudioFromVideo(videoPath, outputPath, options, signal, con
78731
78810
  }
78732
78811
  async function prepareAudioTrack(srcPath, outputPath, mediaStart, duration, playbackRate = 1, signal, config) {
78733
78812
  const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
78734
- const outputDir = dirname8(outputPath);
78813
+ const outputDir = dirname9(outputPath);
78735
78814
  if (!existsSync12(outputDir)) mkdirSync7(outputDir, { recursive: true });
78736
78815
  const normalizedPlaybackRate = normalizePlaybackRate(playbackRate);
78737
78816
  const outputArgs = await preparedAudioOutputArgs(srcPath, normalizedPlaybackRate);
@@ -78778,7 +78857,7 @@ async function prepareAudioTrack(srcPath, outputPath, mediaStart, duration, play
78778
78857
  }
78779
78858
  async function generateSilence(outputPath, duration, signal, config) {
78780
78859
  const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
78781
- const outputDir = dirname8(outputPath);
78860
+ const outputDir = dirname9(outputPath);
78782
78861
  if (!existsSync12(outputDir)) mkdirSync7(outputDir, { recursive: true });
78783
78862
  const args = [
78784
78863
  "-f",
@@ -78832,7 +78911,7 @@ async function mixAudioTracks(tracks, outputPath, totalDuration, signal, config)
78832
78911
  failures: result2.failure ? [result2.failure] : void 0
78833
78912
  };
78834
78913
  }
78835
- const outputDir = dirname8(outputPath);
78914
+ const outputDir = dirname9(outputPath);
78836
78915
  if (!existsSync12(outputDir)) mkdirSync7(outputDir, { recursive: true });
78837
78916
  const buildFilterComplex = (ignoreAutomation) => {
78838
78917
  const filterParts = [];
@@ -78940,7 +79019,7 @@ function groupNormalizeOptionUnsupported(stderr) {
78940
79019
  }
78941
79020
  async function mixGroupMembers(memberTracks, outputPath, totalDuration, signal, config) {
78942
79021
  const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
78943
- const outputDir = dirname8(outputPath);
79022
+ const outputDir = dirname9(outputPath);
78944
79023
  if (!existsSync12(outputDir)) mkdirSync7(outputDir, { recursive: true });
78945
79024
  const buildInputFilters = (ignoreKeyframes) => memberTracks.map((track, i) => {
78946
79025
  const delayMs = Math.round(track.start * 1e3);
@@ -81841,6 +81920,7 @@ __export(src_exports, {
81841
81920
  FFMPEG_PATH_ENV: () => FFMPEG_PATH_ENV,
81842
81921
  FFPROBE_PATH_ENV: () => FFPROBE_PATH_ENV,
81843
81922
  FrameLookupTable: () => FrameLookupTable,
81923
+ HDR_AUTO_PROMOTION_PIPELINE: () => HDR_AUTO_PROMOTION_PIPELINE,
81844
81924
  LOW_MEMORY_TOTAL_MB_THRESHOLD: () => LOW_MEMORY_TOTAL_MB_THRESHOLD,
81845
81925
  MAX_VP9_CPU_USED: () => MAX_VP9_CPU_USED,
81846
81926
  MEDIA_VISUAL_STYLE_PROPERTIES: () => MEDIA_VISUAL_STYLE_PROPERTIES,
@@ -81925,9 +82005,11 @@ __export(src_exports, {
81925
82005
  extractVideoMetadata: () => extractVideoMetadata,
81926
82006
  extractionFrameCountForDuration: () => extractionFrameCountForDuration,
81927
82007
  fetchPublicHttpsText: () => fetchPublicHttpsText,
82008
+ findHdrAutoPromotion: () => findHdrAutoPromotion,
81928
82009
  fingerprintElementId: () => fingerprintElementId,
81929
82010
  float16ToPqRgb: () => float16ToPqRgb,
81930
82011
  formatFfmpegError: () => formatFfmpegError,
82012
+ formatHdrAutoPromotionWarning: () => formatHdrAutoPromotionWarning,
81931
82013
  getCapturePerfSummary: () => getCapturePerfSummary,
81932
82014
  getCdpSession: () => getCdpSession,
81933
82015
  getCgroupMemoryLimitMb: () => getCgroupMemoryLimitMb,
@@ -82009,6 +82091,7 @@ __export(src_exports, {
82009
82091
  safeDownloadUrlIdentity: () => safeDownloadUrlIdentity,
82010
82092
  safeVideoExtractionSourceIdentity: () => safeVideoExtractionSourceIdentity,
82011
82093
  sampleRgb48le: () => sampleRgb48le,
82094
+ sanitizeHdrAutoPromotionAsset: () => sanitizeHdrAutoPromotionAsset,
82012
82095
  scaleProtocolTimeoutForComposition: () => scaleProtocolTimeoutForComposition,
82013
82096
  selectVerifySampleIndicesForTask: () => selectVerifySampleIndicesForTask,
82014
82097
  shouldClampToScreenshotForConcreteGpu: () => shouldClampToScreenshotForConcreteGpu,
@@ -85243,7 +85326,7 @@ import {
85243
85326
  writeFileSync as writeFileSync8
85244
85327
  } from "fs";
85245
85328
  import { homedir as homedir4, tmpdir as tmpdir4 } from "os";
85246
- import { dirname as dirname12, join as join25 } from "path";
85329
+ import { dirname as dirname13, join as join25 } from "path";
85247
85330
  async function compressToWoff2(input) {
85248
85331
  return Buffer.from(await compress(input));
85249
85332
  }
@@ -85270,8 +85353,8 @@ function readCachedCompression(path) {
85270
85353
  function cacheCompression(path, compressed) {
85271
85354
  let tempDir;
85272
85355
  try {
85273
- mkdirSync10(dirname12(path), { recursive: true });
85274
- tempDir = mkdtempSync7(join25(dirname12(path), ".compression-"));
85356
+ mkdirSync10(dirname13(path), { recursive: true });
85357
+ tempDir = mkdtempSync7(join25(dirname13(path), ".compression-"));
85275
85358
  const tmpPath = join25(tempDir, "font.woff2");
85276
85359
  writeFileSync8(tmpPath, compressed, { flag: "wx", mode: 420 });
85277
85360
  renameSync4(tmpPath, path);
@@ -85338,7 +85421,7 @@ import {
85338
85421
  appendFileSync
85339
85422
  } from "fs";
85340
85423
  import { tmpdir as tmpdir7 } from "os";
85341
- import { join as join43, dirname as dirname18, resolve as resolve13 } from "path";
85424
+ import { join as join43, dirname as dirname19, resolve as resolve13 } from "path";
85342
85425
  import { totalmem as totalmem3 } from "os";
85343
85426
  import { randomUUID as randomUUID3 } from "crypto";
85344
85427
  import { fileURLToPath as fileURLToPath5 } from "url";
@@ -85366,9 +85449,9 @@ import { join as join19, extname as extname4, resolve as resolve7, sep as sep3 }
85366
85449
  // ../producer/src/services/hyperframeRuntimeLoader.ts
85367
85450
  import { createHash as createHash4 } from "crypto";
85368
85451
  import { existsSync as existsSync15, readFileSync as readFileSync6 } from "fs";
85369
- import { dirname as dirname9, resolve as resolve6 } from "path";
85452
+ import { dirname as dirname10, resolve as resolve6 } from "path";
85370
85453
  import { fileURLToPath as fileURLToPath2 } from "url";
85371
- var PRODUCER_DIR = dirname9(fileURLToPath2(import.meta.url));
85454
+ var PRODUCER_DIR = dirname10(fileURLToPath2(import.meta.url));
85372
85455
  var SIBLING_MANIFEST_PATH = resolve6(PRODUCER_DIR, "hyperframe.manifest.json");
85373
85456
  var MODULE_RELATIVE_MANIFEST_PATH = resolve6(
85374
85457
  PRODUCER_DIR,
@@ -85411,7 +85494,7 @@ function resolveVerifiedHyperframeRuntime() {
85411
85494
  `[HyperframeRuntimeLoader] Invalid manifest at ${manifestPath}; missing iife artifact or sha256.`
85412
85495
  );
85413
85496
  }
85414
- const runtimePath = resolve6(dirname9(manifestPath), runtimeFileName);
85497
+ const runtimePath = resolve6(dirname10(manifestPath), runtimeFileName);
85415
85498
  if (!existsSync15(runtimePath)) {
85416
85499
  throw new Error(`[HyperframeRuntimeLoader] Missing runtime artifact at ${runtimePath}.`);
85417
85500
  }
@@ -86085,7 +86168,7 @@ import {
86085
86168
  symlinkSync,
86086
86169
  writeFileSync as writeFileSync7
86087
86170
  } from "fs";
86088
- import { basename as basename4, dirname as dirname10, isAbsolute as isAbsolute2, join as join21, relative, resolve as resolve8 } from "path";
86171
+ import { basename as basename4, dirname as dirname11, isAbsolute as isAbsolute2, join as join21, relative, resolve as resolve8 } from "path";
86089
86172
 
86090
86173
  // ../producer/src/utils/paths.ts
86091
86174
  import {
@@ -86170,7 +86253,7 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
86170
86253
  writeFileSync7(join21(compileDir, "index.html"), compiled.html, "utf-8");
86171
86254
  for (const [srcPath, html] of compiled.subCompositions) {
86172
86255
  const outPath = join21(compileDir, srcPath);
86173
- mkdirSync9(dirname10(outPath), { recursive: true });
86256
+ mkdirSync9(dirname11(outPath), { recursive: true });
86174
86257
  writeFileSync7(outPath, html, "utf-8");
86175
86258
  }
86176
86259
  for (const [relativePath, absolutePath] of compiled.externalAssets) {
@@ -86179,7 +86262,7 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
86179
86262
  console.warn(`[Render] Skipping external asset with unsafe path: ${relativePath}`);
86180
86263
  continue;
86181
86264
  }
86182
- mkdirSync9(dirname10(outPath), { recursive: true });
86265
+ mkdirSync9(dirname11(outPath), { recursive: true });
86183
86266
  copyFileSync3(absolutePath, outPath);
86184
86267
  }
86185
86268
  if (includeSummary) {
@@ -86233,7 +86316,7 @@ function updateJobStatus(job, status, stage, progress, onProgress) {
86233
86316
  var materializePathModule = {
86234
86317
  resolve: resolve8,
86235
86318
  join: join21,
86236
- dirname: dirname10,
86319
+ dirname: dirname11,
86237
86320
  basename: basename4,
86238
86321
  relative,
86239
86322
  isAbsolute: isAbsolute2
@@ -86535,7 +86618,7 @@ import {
86535
86618
  renameSync as renameSync3,
86536
86619
  rmSync as rmSync8
86537
86620
  } from "fs";
86538
- import { basename as basename5, dirname as dirname11, extname as extname5, join as join22, resolve as resolve9 } from "path";
86621
+ import { basename as basename5, dirname as dirname12, extname as extname5, join as join22, resolve as resolve9 } from "path";
86539
86622
 
86540
86623
  // ../producer/src/utils/ffprobe.ts
86541
86624
  init_src();
@@ -86554,7 +86637,7 @@ async function defaultArtifactDurationProbe(path) {
86554
86637
  };
86555
86638
  }
86556
86639
  function createSiblingTransactionDirectory(destination) {
86557
- const parent = dirname11(destination);
86640
+ const parent = dirname12(destination);
86558
86641
  const extension = extname5(destination);
86559
86642
  const stem = extension ? basename5(destination, extension) : basename5(destination);
86560
86643
  return mkdtempSync6(join22(parent, `.${stem}.hf-transaction-`));
@@ -86725,6 +86808,10 @@ var ArtifactTransaction = class {
86725
86808
  }
86726
86809
  }
86727
86810
  };
86811
+ async function commitArtifactTransaction(transaction, assertNotAborted) {
86812
+ assertNotAborted();
86813
+ await transaction.commit();
86814
+ }
86728
86815
 
86729
86816
  // ../producer/src/services/render/capturePlan.ts
86730
86817
  function drawElementVerificationFailure(plan2, hasDiskFallbackHeadroom) {
@@ -86827,6 +86914,42 @@ function replanAfterFailure(plan2, failure) {
86827
86914
 
86828
86915
  // ../producer/src/services/render/hdrMode.ts
86829
86916
  init_src();
86917
+ function findRenderHdrAutoPromotionTrigger(input) {
86918
+ for (const extracted of input.extractionResult?.extracted ?? []) {
86919
+ if (!isHdrColorSpace(extracted.metadata.colorSpace)) continue;
86920
+ const source = input.videos.find(({ id }) => id === extracted.videoId)?.src;
86921
+ if (source) return source;
86922
+ }
86923
+ return input.images.find(({ id }) => input.nativeHdrImageIds.has(id))?.src;
86924
+ }
86925
+ function logHdrResolution(input, hdrMode, effectiveHdr, forcedHdrWithoutSources) {
86926
+ if (forcedHdrWithoutSources) {
86927
+ input.log.warn(
86928
+ "[Render] HDR forced by --hdr flag, but no HDR sources were detected \u2014 defaulting to HLG. SDR-only compositions may look perceptually wrong on HDR displays."
86929
+ );
86930
+ }
86931
+ if (!effectiveHdr) {
86932
+ input.log.info(
86933
+ hdrMode === "force-sdr" ? "[Render] SDR forced by --sdr flag" : "[Render] No HDR sources detected \u2014 rendering SDR"
86934
+ );
86935
+ return;
86936
+ }
86937
+ if (hdrMode === "auto") {
86938
+ input.log.warn(
86939
+ formatHdrAutoPromotionWarning({
86940
+ triggeringAsset: sanitizeHdrAutoPromotionAsset(
86941
+ input.autoPromotionTrigger ?? "an HDR-tagged asset"
86942
+ ),
86943
+ output: HDR_AUTO_PROMOTION_PIPELINE
86944
+ })
86945
+ );
86946
+ return;
86947
+ }
86948
+ const reason = forcedHdrWithoutSources ? "forced by --hdr flag (no HDR sources detected \u2014 defaulting to HLG)" : "forced by --hdr flag";
86949
+ input.log.info(
86950
+ `[Render] HDR ${reason} \u2014 output: ${effectiveHdr.transfer.toUpperCase()} (BT.2020, 10-bit H.265)`
86951
+ );
86952
+ }
86830
86953
  function resolveEffectiveHdrMode(input) {
86831
86954
  const hdrMode = input.hdrMode ?? "auto";
86832
86955
  const videoColorSpaces = (input.extractionResult?.extracted ?? []).map(
@@ -86855,26 +86978,7 @@ function resolveEffectiveHdrMode(input) {
86855
86978
  );
86856
86979
  effectiveHdr = void 0;
86857
86980
  }
86858
- if (forcedHdrWithoutSources) {
86859
- input.log.warn(
86860
- "[Render] HDR forced by --hdr flag, but no HDR sources were detected \u2014 defaulting to HLG. SDR-only compositions may look perceptually wrong on HDR displays."
86861
- );
86862
- }
86863
- if (effectiveHdr) {
86864
- let reason;
86865
- if (hdrMode === "force-hdr") {
86866
- reason = forcedHdrWithoutSources ? "forced by --hdr flag (no HDR sources detected \u2014 defaulting to HLG)" : "forced by --hdr flag";
86867
- } else {
86868
- reason = "auto-detected from source(s)";
86869
- }
86870
- input.log.info(
86871
- `[Render] HDR ${reason} \u2014 output: ${effectiveHdr.transfer.toUpperCase()} (BT.2020, 10-bit H.265)`
86872
- );
86873
- } else if (hdrMode === "force-sdr") {
86874
- input.log.info("[Render] SDR forced by --sdr flag");
86875
- } else {
86876
- input.log.info("[Render] No HDR sources detected \u2014 rendering SDR");
86877
- }
86981
+ logHdrResolution(input, hdrMode, effectiveHdr, forcedHdrWithoutSources);
86878
86982
  return effectiveHdr;
86879
86983
  }
86880
86984
 
@@ -87900,7 +88004,7 @@ init_subCompositionValidity();
87900
88004
  init_assetResolution();
87901
88005
  import { createHash as createHash9 } from "crypto";
87902
88006
  import { createReadStream as createReadStream4, existsSync as existsSync24, mkdirSync as mkdirSync13, readFileSync as readFileSync10 } from "fs";
87903
- import { join as join28, dirname as dirname14, resolve as resolve12, basename as basename6, relative as relative2 } from "path";
88007
+ import { join as join28, dirname as dirname15, resolve as resolve12, basename as basename6, relative as relative2 } from "path";
87904
88008
 
87905
88009
  // ../producer/src/services/renderMediaCollector.ts
87906
88010
  init_esm10();
@@ -89249,7 +89353,7 @@ import {
89249
89353
  rmSync as rmSync10,
89250
89354
  statSync as statSync8
89251
89355
  } from "fs";
89252
- import { dirname as dirname13, isAbsolute as isAbsolute3, join as join27, resolve as resolve11 } from "path";
89356
+ import { dirname as dirname14, isAbsolute as isAbsolute3, join as join27, resolve as resolve11 } from "path";
89253
89357
  var PREPARED_GIF_SUBDIR = "_animated_gif";
89254
89358
  var CACHE_SCHEMA = "hfgif-v1";
89255
89359
  function splitUrlSuffix(src) {
@@ -89402,11 +89506,11 @@ async function runAnimatedGifTranscode(request) {
89402
89506
  throw result.error ?? new Error(`Animated GIF transcode failed (${result.exitCode}): ${result.stderr.slice(-500)}`);
89403
89507
  }
89404
89508
  async function ensurePreparedWebm(input) {
89405
- if (!existsSync22(dirname13(input.cachePath))) {
89406
- mkdirSync12(dirname13(input.cachePath), { recursive: true });
89509
+ if (!existsSync22(dirname14(input.cachePath))) {
89510
+ mkdirSync12(dirname14(input.cachePath), { recursive: true });
89407
89511
  }
89408
- if (!existsSync22(dirname13(input.outputPath))) {
89409
- mkdirSync12(dirname13(input.outputPath), { recursive: true });
89512
+ if (!existsSync22(dirname14(input.outputPath))) {
89513
+ mkdirSync12(dirname14(input.outputPath), { recursive: true });
89410
89514
  }
89411
89515
  if (!isUsableFile(input.cachePath)) {
89412
89516
  const tmpPath = `${input.cachePath}.tmp-${process.pid}-${Date.now()}`;
@@ -90329,7 +90433,7 @@ async function parseSubCompositions(html, projectDir, downloadDir, visited = /*
90329
90433
  workItems.map(async (item) => {
90330
90434
  const { html: compiledSub } = await compileHtmlFile(
90331
90435
  item.rawSubHtml,
90332
- dirname14(item.filePath),
90436
+ dirname15(item.filePath),
90333
90437
  downloadDir
90334
90438
  );
90335
90439
  const nested = await parseSubCompositions(
@@ -92560,6 +92664,7 @@ async function runExtractVideosStage(input) {
92560
92664
  fps: job.config.fps,
92561
92665
  outputDir: join31(compiledDir, "__hyperframes_video_frames"),
92562
92666
  format: job.config.videoFrameFormat ?? "auto",
92667
+ toneMapHdrToSdr: job.config.hdrMode === "force-sdr",
92563
92668
  timelineEnd: composition.duration,
92564
92669
  maxTransientRetries: extractionPolicy.maxTransientRetries,
92565
92670
  collectProbeFailures: extractionPolicy.failureMode === "enforce"
@@ -94762,7 +94867,7 @@ import { join as join38 } from "path";
94762
94867
  // ../producer/src/services/shaderTransitionWorkerPool.ts
94763
94868
  import { Worker as Worker2 } from "worker_threads";
94764
94869
  import { fileURLToPath as fileURLToPath4, pathToFileURL as pathToFileURL2 } from "url";
94765
- import { dirname as dirname15, join as join37 } from "path";
94870
+ import { dirname as dirname16, join as join37 } from "path";
94766
94871
  import { createRequire as createRequire2 } from "module";
94767
94872
  import { existsSync as existsSync26 } from "fs";
94768
94873
  import { cpus as cpus3 } from "os";
@@ -94775,7 +94880,7 @@ function resolveWorkerEntry(explicit) {
94775
94880
  const isTs = override.endsWith(".ts");
94776
94881
  return { path: override, isTs };
94777
94882
  }
94778
- const moduleDir = dirname15(fileURLToPath4(import.meta.url));
94883
+ const moduleDir = dirname16(fileURLToPath4(import.meta.url));
94779
94884
  const jsPath = join37(moduleDir, "shaderTransitionWorker.js");
94780
94885
  if (existsSync26(jsPath)) return { path: jsPath, isTs: false };
94781
94886
  const tsPath = join37(moduleDir, "shaderTransitionWorker.ts");
@@ -95486,7 +95591,7 @@ async function runCaptureHdrStage(input) {
95486
95591
  // ../producer/src/services/render/stages/encodeStage.ts
95487
95592
  init_src();
95488
95593
  import { copyFileSync as copyFileSync5, existsSync as existsSync28, mkdirSync as mkdirSync16, readdirSync as readdirSync10, rmSync as rmSync12, statSync as statSync9 } from "fs";
95489
- import { dirname as dirname16, join as join41 } from "path";
95594
+ import { dirname as dirname17, join as join41 } from "path";
95490
95595
 
95491
95596
  // ../producer/src/services/render/stages/gifEncodeArgs.ts
95492
95597
  import { join as join40 } from "path";
@@ -95657,7 +95762,7 @@ async function runEncodeStage(input) {
95657
95762
  const encodeResult2 = await encodeGifFromDir(framesDir, framePattern2, outputPath, {
95658
95763
  fps: job.config.fps,
95659
95764
  loop,
95660
- palettePath: join41(dirname16(videoOnlyPath), "gif-palette.png"),
95765
+ palettePath: join41(dirname17(videoOnlyPath), "gif-palette.png"),
95661
95766
  preserveAlpha: needsAlpha,
95662
95767
  signal: abortSignal,
95663
95768
  timeout: engineCfg.ffmpegEncodeTimeout
@@ -95724,7 +95829,7 @@ init_src();
95724
95829
  init_dist2();
95725
95830
  import { spawn as spawn5 } from "child_process";
95726
95831
  import { mkdtempSync as mkdtempSync10, renameSync as renameSync6, rmSync as rmSync13 } from "fs";
95727
- import { dirname as dirname17, join as join42 } from "path";
95832
+ import { dirname as dirname18, join as join42 } from "path";
95728
95833
  var AUDIO_DURATION_TOLERANCE_SECONDS = 1e-3;
95729
95834
  var AAC_DELIVERY_TRUE_PEAK_DBFS = -1;
95730
95835
  var AAC_TRUE_PEAK_CORRECTION_HEADROOM_DB = 0.5;
@@ -95925,7 +96030,7 @@ async function padOrTrimAudioToVideoFrameCount(input) {
95925
96030
  async function enforceAacTruePeak(input) {
95926
96031
  let scratchDir;
95927
96032
  try {
95928
- scratchDir = mkdtempSync10(join42(dirname17(input.audioPath), ".true-peak-"));
96033
+ scratchDir = mkdtempSync10(join42(dirname18(input.audioPath), ".true-peak-"));
95929
96034
  const correctedPath = join42(scratchDir, "audio.m4a");
95930
96035
  const correctionTargetDbfs = AAC_DELIVERY_TRUE_PEAK_DBFS - AAC_TRUE_PEAK_CORRECTION_HEADROOM_DB;
95931
96036
  const measurements = [];
@@ -96380,7 +96485,7 @@ function getNextRetryWorkerCount(currentWorkers) {
96380
96485
  }
96381
96486
  function resolveRenderWorkDirPrefix(outputPath, jobId, platform3 = process.platform, systemTempDir = tmpdir7()) {
96382
96487
  if (platform3 === "win32") return join43(systemTempDir, "hf-render-");
96383
- return join43(dirname18(outputPath), `work-${jobId}-`);
96488
+ return join43(dirname19(outputPath), `work-${jobId}-`);
96384
96489
  }
96385
96490
  var MAX_TRANSIENT_CAPTURE_RETRIES = 1;
96386
96491
  function captureAttemptMadeProgress(attemptTargetFrameCount, remainingFrameCount) {
@@ -96740,6 +96845,7 @@ function shouldRetryViaPinnedFallback(args) {
96740
96845
  if (args.isCancellation || args.isEncoderInterrupted) return false;
96741
96846
  if (args.isVerifyError || args.isDeCaptureError) return true;
96742
96847
  if (args.isDeRendererStall === true || args.isSequentialCaptureStall === true) return true;
96848
+ if (args.isTransientCaptureError === true) return true;
96743
96849
  return args.deWorkerInversion === "inverted" || args.deParallelRouter === "routed";
96744
96850
  }
96745
96851
  function isDeRendererStallError(err) {
@@ -96801,11 +96907,11 @@ function deVerifyFallbackTelemetry(err) {
96801
96907
  thresholdDb: roundDb(details?.verifyThresholdDb)
96802
96908
  };
96803
96909
  }
96804
- async function executeRenderJob(job, projectDir, outputPath, progressSink, abortSignal) {
96805
- const moduleDir = dirname18(fileURLToPath5(import.meta.url));
96910
+ async function executeRenderJob(job, projectDir, outputPath, progressSink, abortSignal, assertRenderActive) {
96911
+ const moduleDir = dirname19(fileURLToPath5(import.meta.url));
96806
96912
  const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve13(process.env.PRODUCER_RENDERS_DIR, "..") : resolve13(moduleDir, "../..");
96807
96913
  const debugDir = join43(producerRoot, ".debug");
96808
- const outputDir = dirname18(outputPath);
96914
+ const outputDir = dirname19(outputPath);
96809
96915
  if (!existsSync29(outputDir)) mkdirSync17(outputDir, { recursive: true });
96810
96916
  const workDir = job.config.debug ? join43(debugDir, job.id) : mkdtempSync11(resolveRenderWorkDirPrefix(outputPath, job.id));
96811
96917
  const pipelineStart = Date.now();
@@ -96834,14 +96940,24 @@ async function executeRenderJob(job, projectDir, outputPath, progressSink, abort
96834
96940
  workDir,
96835
96941
  logPath,
96836
96942
  pipelineStart,
96837
- execution
96943
+ execution,
96944
+ assertRenderActive
96838
96945
  });
96839
96946
  } finally {
96840
96947
  await execution.dispose();
96841
96948
  }
96842
96949
  }
96843
96950
  async function executeRenderPipeline(input) {
96844
- const { job, projectDir, outputPath, workDir, logPath, pipelineStart, execution } = input;
96951
+ const {
96952
+ job,
96953
+ projectDir,
96954
+ outputPath,
96955
+ workDir,
96956
+ logPath,
96957
+ pipelineStart,
96958
+ execution,
96959
+ assertRenderActive
96960
+ } = input;
96845
96961
  const log = execution.logger;
96846
96962
  const eventPublisher = execution.events;
96847
96963
  const onProgress = execution.onProgress;
@@ -97170,11 +97286,18 @@ async function executeRenderPipeline(input) {
97170
97286
  });
97171
97287
  if (failureToEnforce) throw failureToEnforce;
97172
97288
  assertVideoFrameCoverage(coverageReports, coverageThreshold);
97289
+ const autoPromotionTrigger = findRenderHdrAutoPromotionTrigger({
97290
+ extractionResult,
97291
+ videos: composition.videos,
97292
+ images: composition.images,
97293
+ nativeHdrImageIds
97294
+ });
97173
97295
  const effectiveHdr = resolveEffectiveHdrMode({
97174
97296
  hdrMode: job.config.hdrMode,
97175
97297
  outputFormat,
97176
97298
  extractionResult,
97177
97299
  imageColorSpaces,
97300
+ autoPromotionTrigger,
97178
97301
  log
97179
97302
  });
97180
97303
  observability.checkpoint("hdr_detection", "resolved", {
@@ -97853,7 +97976,8 @@ async function executeRenderPipeline(input) {
97853
97976
  deWorkerInversion,
97854
97977
  deParallelRouter,
97855
97978
  isDeRendererStall: isDeStall,
97856
- isSequentialCaptureStall: isSequentialStall
97979
+ isSequentialCaptureStall: isSequentialStall,
97980
+ isTransientCaptureError: isTransientBrowserError(err)
97857
97981
  }))
97858
97982
  throw err;
97859
97983
  const isMemoryExhaustion = !isVerifyError && isMemoryExhaustionError(err);
@@ -98194,7 +98318,10 @@ async function executeRenderPipeline(input) {
98194
98318
  copyFileSync6(stagedOutputPath, debugOutput);
98195
98319
  }
98196
98320
  }
98197
- await artifactTransaction.commit();
98321
+ await commitArtifactTransaction(artifactTransaction, () => {
98322
+ assertRenderActive?.();
98323
+ assertNotAborted();
98324
+ });
98198
98325
  job.outputPath = outputPath;
98199
98326
  updateJobStatus(job, "complete", "Render complete", 100, onProgress);
98200
98327
  await eventPublisher.flush();
@@ -98533,7 +98660,7 @@ import {
98533
98660
  rmSync as rmSync15,
98534
98661
  createReadStream as createReadStream5
98535
98662
  } from "fs";
98536
- import { resolve as resolve15, dirname as dirname20, join as join46 } from "path";
98663
+ import { resolve as resolve15, dirname as dirname21, join as join46 } from "path";
98537
98664
  import { tmpdir as tmpdir8 } from "os";
98538
98665
  import { parseArgs } from "util";
98539
98666
  import crypto from "crypto";
@@ -98662,7 +98789,7 @@ async function runHyperframeLint(prepared) {
98662
98789
  // ../producer/src/services/healthWorker.ts
98663
98790
  import { Worker as Worker3 } from "worker_threads";
98664
98791
  import { fileURLToPath as fileURLToPath6 } from "url";
98665
- import { dirname as dirname19, join as join45 } from "path";
98792
+ import { dirname as dirname20, join as join45 } from "path";
98666
98793
  import { existsSync as existsSync31 } from "fs";
98667
98794
  var DEFAULT_HEALTH_PORT = 9848;
98668
98795
  async function startHealthWorker(options = {}) {
@@ -98737,7 +98864,7 @@ function defaultLogger2() {
98737
98864
  };
98738
98865
  }
98739
98866
  function resolveWorkerEntry2() {
98740
- const here = dirname19(fileURLToPath6(import.meta.url));
98867
+ const here = dirname20(fileURLToPath6(import.meta.url));
98741
98868
  const candidates = [join45(here, "healthWorkerThread.js"), join45(here, "healthWorkerThread.ts")];
98742
98869
  for (const candidate of candidates) {
98743
98870
  if (existsSync31(candidate)) return candidate;
@@ -98875,7 +99002,7 @@ function buildRenderJobConfig(input, outputPath, log) {
98875
99002
  function resolvePreparedRenderOutput(prepared, rendersDir, log) {
98876
99003
  const { input, cleanupProjectDir } = prepared;
98877
99004
  const absoluteOutputPath = resolveOutputPath(input.projectDir, input.outputPath, rendersDir, log);
98878
- const outputDir = dirname20(absoluteOutputPath);
99005
+ const outputDir = dirname21(absoluteOutputPath);
98879
99006
  if (!existsSync32(outputDir)) mkdirSync18(outputDir, { recursive: true });
98880
99007
  return { input, cleanupProjectDir, absoluteOutputPath };
98881
99008
  }
@@ -99441,7 +99568,7 @@ var FIELD_DELIMITER = Buffer.from([0]);
99441
99568
  // ../producer/src/services/distributed/shared.ts
99442
99569
  init_src();
99443
99570
  import { execFile as execFileCallback } from "child_process";
99444
- import { dirname as dirname21, join as join48 } from "path";
99571
+ import { dirname as dirname22, join as join48 } from "path";
99445
99572
  import { existsSync as existsSync34, readFileSync as readFileSync15 } from "fs";
99446
99573
  import { fileURLToPath as fileURLToPath7 } from "url";
99447
99574
  import { promisify as promisify4 } from "util";
@@ -99488,7 +99615,7 @@ import {
99488
99615
  } from "fs";
99489
99616
  import { createHash as createHash12 } from "crypto";
99490
99617
  import { tmpdir as tmpdir9 } from "os";
99491
- import { dirname as dirname23, isAbsolute as isAbsolute5, join as join53, relative as relative7, resolve as resolve17, sep as sep6 } from "path";
99618
+ import { dirname as dirname24, isAbsolute as isAbsolute5, join as join53, relative as relative7, resolve as resolve17, sep as sep6 } from "path";
99492
99619
 
99493
99620
  // ../producer/src/services/distributed/planV2Publisher.ts
99494
99621
  import {
@@ -99502,7 +99629,7 @@ import {
99502
99629
  statSync as statSync13,
99503
99630
  writeFileSync as writeFileSync14
99504
99631
  } from "fs";
99505
- import { dirname as dirname22, join as join52 } from "path";
99632
+ import { dirname as dirname23, join as join52 } from "path";
99506
99633
 
99507
99634
  // ../producer/src/services/distributed/planV2Layout.ts
99508
99635
  import { join as join51 } from "path";
@@ -99526,7 +99653,7 @@ import {
99526
99653
  statSync as statSync15,
99527
99654
  writeFileSync as writeFileSync16
99528
99655
  } from "fs";
99529
- import { dirname as dirname24, join as join54 } from "path";
99656
+ import { dirname as dirname25, join as join54 } from "path";
99530
99657
 
99531
99658
  // ../producer/src/services/distributed/renderChunk.ts
99532
99659
  init_src();
@@ -99579,8 +99706,8 @@ async function runFontLocalize(io, localize) {
99579
99706
  }
99580
99707
 
99581
99708
  // src/version.ts
99582
- var VERSION = true ? "0.8.40" : "0.0.0-dev";
99583
- var PRODUCER_VERSION = true ? "0.8.40" : "0.0.0-dev";
99709
+ var VERSION = true ? "0.8.42" : "0.0.0-dev";
99710
+ var PRODUCER_VERSION = true ? "0.8.42" : "0.0.0-dev";
99584
99711
 
99585
99712
  // src/fontLocalizeCli.ts
99586
99713
  async function readStdin() {