hyperframes 0.8.41 → 0.8.43

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.
@@ -50279,7 +50279,7 @@ function resolveAliasDisplayName(alias) {
50279
50279
  if (!slug) return void 0;
50280
50280
  return CANONICAL_FONT_DISPLAY_NAMES[slug];
50281
50281
  }
50282
- var recast, import_parser2, CANVAS_DIMENSIONS, VALID_CANVAS_RESOLUTIONS, RESOLUTION_ALIASES, ASPECT_AGNOSTIC_RESOLUTION_ALIASES, PROPERTY_GROUPS, PROP_TO_GROUP, COMPOSITION_ATTRIBUTES, CANONICAL_AUTHORED_TIMING_ATTRIBUTES, DERIVED_TIMING_ATTRIBUTES, LEGACY_TIMING_ATTRIBUTES, OK, FONT_ALIAS_MAP, FONT_ALIAS_KEYS, CANONICAL_FONT_DISPLAY_NAMES;
50282
+ var recast, import_parser2, CANVAS_DIMENSIONS, VALID_CANVAS_RESOLUTIONS, RESOLUTION_ALIASES, ASPECT_AGNOSTIC_RESOLUTION_ALIASES, PROPERTY_GROUPS, PROP_TO_GROUP, COMPOSITION_ATTRIBUTES, CANONICAL_AUTHORED_TIMING_ATTRIBUTES, DERIVED_TIMING_ATTRIBUTES, LEGACY_TIMING_ATTRIBUTES, OK, HTML_BODY_CSS_WIDTH_FIRST_RE, HTML_BODY_CSS_HEIGHT_FIRST_RE, VIEWPORT_META_SIZE_RE, FONT_ALIAS_MAP, FONT_ALIAS_KEYS, CANONICAL_FONT_DISPLAY_NAMES;
50283
50283
  var init_dist = __esm({
50284
50284
  "../parsers/dist/index.js"() {
50285
50285
  "use strict";
@@ -50355,6 +50355,9 @@ var init_dist = __esm({
50355
50355
  COMPOSITION_ATTRIBUTES.legacyTrack
50356
50356
  ]);
50357
50357
  OK = { ok: true };
50358
+ HTML_BODY_CSS_WIDTH_FIRST_RE = /html\s*,\s*body\s*\{[^}]*?width:\s*(\d+)px[^}]*?height:\s*(\d+)px/i;
50359
+ HTML_BODY_CSS_HEIGHT_FIRST_RE = /html\s*,\s*body\s*\{[^}]*?height:\s*(\d+)px[^}]*?width:\s*(\d+)px/i;
50360
+ VIEWPORT_META_SIZE_RE = /<meta[^>]*name=["']viewport["'][^>]*content=["']width=(\d+),\s*height=(\d+)/i;
50358
50361
  FONT_ALIAS_MAP = {
50359
50362
  // ── Canonical bundled fonts (self-referencing) ────────────────────────
50360
50363
  inter: "inter",
@@ -59553,6 +59556,19 @@ function getHdrEncoderColorParams(transfer, mastering = DEFAULT_HDR10_MASTERING)
59553
59556
  mastering
59554
59557
  };
59555
59558
  }
59559
+ function sanitizeHdrAutoPromotionAsset(asset) {
59560
+ return asset.split(/[\r\n?#]/, 1)[0] ?? "";
59561
+ }
59562
+ function findHdrAutoPromotion(sources) {
59563
+ const source = sources.find(({ colorSpace }) => isHdrColorSpace(colorSpace));
59564
+ return source ? {
59565
+ triggeringAsset: sanitizeHdrAutoPromotionAsset(source.asset),
59566
+ output: HDR_AUTO_PROMOTION_PIPELINE
59567
+ } : null;
59568
+ }
59569
+ function formatHdrAutoPromotionWarning(promotion) {
59570
+ return `[Render] HDR auto-promotion triggered by "${promotion.triggeringAsset}" \u2014 output: ${promotion.output.colorSpace} / ${promotion.output.codec}`;
59571
+ }
59556
59572
  function analyzeCompositionHdr(colorSpaces) {
59557
59573
  let hasPq = false;
59558
59574
  let hasHdr = false;
@@ -59565,7 +59581,7 @@ function analyzeCompositionHdr(colorSpaces) {
59565
59581
  const dominantTransfer = hasPq ? "pq" : "hlg";
59566
59582
  return { hasHdr: true, dominantTransfer };
59567
59583
  }
59568
- var DEFAULT_HDR10_MASTERING;
59584
+ var DEFAULT_HDR10_MASTERING, HDR_AUTO_PROMOTION_PIPELINE;
59569
59585
  var init_hdr = __esm({
59570
59586
  "../engine/src/utils/hdr.ts"() {
59571
59587
  "use strict";
@@ -59573,6 +59589,10 @@ var init_hdr = __esm({
59573
59589
  masterDisplay: "G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1)",
59574
59590
  maxCll: "1000,400"
59575
59591
  };
59592
+ HDR_AUTO_PROMOTION_PIPELINE = {
59593
+ colorSpace: "BT.2020",
59594
+ codec: "HEVC Main10"
59595
+ };
59576
59596
  }
59577
59597
  });
59578
59598
 
@@ -69407,6 +69427,35 @@ function findVisibleMarkupCommentLeak(source) {
69407
69427
  }
69408
69428
  return null;
69409
69429
  }
69430
+ function readHtmlBodyCssSize(source) {
69431
+ const widthFirst = source.match(HTML_BODY_CSS_WIDTH_FIRST_RE);
69432
+ if (widthFirst) {
69433
+ const [, width = "", height = ""] = widthFirst;
69434
+ return { width, height };
69435
+ }
69436
+ const heightFirst = source.match(HTML_BODY_CSS_HEIGHT_FIRST_RE);
69437
+ if (heightFirst) {
69438
+ const [, height = "", width = ""] = heightFirst;
69439
+ return { width, height };
69440
+ }
69441
+ return null;
69442
+ }
69443
+ function readViewportMetaSize(source) {
69444
+ const match = source.match(VIEWPORT_META_SIZE_RE);
69445
+ if (!match) return null;
69446
+ const [, width = "", height = ""] = match;
69447
+ return { width, height };
69448
+ }
69449
+ function describeSizeMismatch(label, size, dataWidth, dataHeight) {
69450
+ if (!size || size.width === dataWidth && size.height === dataHeight) return null;
69451
+ return `${label} is ${size.width}x${size.height}`;
69452
+ }
69453
+ function findScaffoldSizeMismatches(source, dataWidth, dataHeight) {
69454
+ return [
69455
+ describeSizeMismatch("html/body CSS", readHtmlBodyCssSize(source), dataWidth, dataHeight),
69456
+ describeSizeMismatch("the viewport meta", readViewportMetaSize(source), dataWidth, dataHeight)
69457
+ ].filter((mismatch) => mismatch !== null);
69458
+ }
69410
69459
  function tweensVolumeInSameCall(script, id) {
69411
69460
  const selector = new RegExp(`#${escapeRegExp3(id)}(?![\\w-])`, "g");
69412
69461
  for (let hit = selector.exec(script); hit; hit = selector.exec(script)) {
@@ -70903,6 +70952,7 @@ var init_dist3 = __esm({
70903
70952
  "use strict";
70904
70953
  init_esm6();
70905
70954
  import_postcss_selector_parser = __toESM(require_dist(), 1);
70955
+ init_dist();
70906
70956
  init_colorGradingContract();
70907
70957
  init_dist();
70908
70958
  init_esm10();
@@ -71014,6 +71064,37 @@ var init_dist3 = __esm({
71014
71064
  }
71015
71065
  return findings;
71016
71066
  },
71067
+ // root_dimensions_mismatch
71068
+ //
71069
+ // Render size and the runtime's forced #root size both read the root's own
71070
+ // data-width/data-height, so they stay correct. But editing only those two
71071
+ // attributes — rather than scaffolding with `hyperframes init --resolution`,
71072
+ // which rewrites the scaffold's other copies of the resolution too — leaves
71073
+ // the `html, body` CSS and the `<meta viewport>` at the old value, and a
71074
+ // stale body with `overflow: hidden` visually clips the correctly-sized
71075
+ // root. `hyperframes check`'s layout audits can't see it: they measure
71076
+ // against the root's own (already-correct) rect, not the body's.
71077
+ //
71078
+ // A sub-composition fragment has no html/body or viewport to compare
71079
+ // against, which makes this top-level-only without a separate guard.
71080
+ ({ rootTag, source }) => {
71081
+ if (!rootTag) return [];
71082
+ const dataWidth = readAttr(rootTag.raw, "data-width");
71083
+ const dataHeight = readAttr(rootTag.raw, "data-height");
71084
+ if (!dataWidth || !dataHeight) return [];
71085
+ const mismatches = findScaffoldSizeMismatches(source, dataWidth, dataHeight);
71086
+ if (mismatches.length === 0) return [];
71087
+ return [
71088
+ {
71089
+ code: "root_dimensions_mismatch",
71090
+ severity: "warning",
71091
+ message: `Root composition declares data-width="${dataWidth}" data-height="${dataHeight}", but ${mismatches.join(" and ")}. The scaffolded body clips the composition at its old size.`,
71092
+ elementId: readAttr(rootTag.raw, "id") || void 0,
71093
+ fixHint: "update html/body CSS and the meta viewport to match, or scaffold with `hyperframes init --resolution portrait`",
71094
+ snippet: truncateSnippet(rootTag.raw)
71095
+ }
71096
+ ];
71097
+ },
71017
71098
  // unbalanced_style_tags
71018
71099
  ({ source }) => {
71019
71100
  let opens = 0;
@@ -75181,6 +75262,9 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
75181
75262
  if (options.sdrToHdrTransfer) {
75182
75263
  vfFilters.push(SDR_TO_HDR_COLORSPACE_FILTER);
75183
75264
  }
75265
+ if (options.toneMapHdrToSdr && isHdr && !isMacOS) {
75266
+ vfFilters.push(HDR_TO_SDR_TONEMAP_FILTER);
75267
+ }
75184
75268
  if (vfFilters.length > 0) args.push("-vf", vfFilters.join(","));
75185
75269
  if (!options.finalFrameOnly && metadata.isVFR) {
75186
75270
  args.push("-fps_mode", "cfr", "-r", ffmpegFps);
@@ -75471,6 +75555,7 @@ function supersetGroupingKey(work, fps) {
75471
75555
  String(fps),
75472
75556
  work.format,
75473
75557
  work.sdrToHdrTransfer ?? "",
75558
+ work.toneMapHdrToSdr ? HDR_TO_SDR_TRANSFORM_KEY : "",
75474
75559
  work.finalFrameOnly ? "final" : "range"
75475
75560
  ].join("\0");
75476
75561
  }
@@ -75802,6 +75887,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
75802
75887
  ...options,
75803
75888
  format: work.format,
75804
75889
  sdrToHdrTransfer: work.sdrToHdrTransfer,
75890
+ toneMapHdrToSdr: work.toneMapHdrToSdr,
75805
75891
  finalFrameOnly: work.finalFrameOnly
75806
75892
  };
75807
75893
  }
@@ -75821,6 +75907,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
75821
75907
  if (!keyInput) return { work };
75822
75908
  const transformParts = [
75823
75909
  work.sdrToHdrTransfer ? sdrToHdrTransformKey(work.sdrToHdrTransfer) : void 0,
75910
+ work.toneMapHdrToSdr ? HDR_TO_SDR_TRANSFORM_KEY : void 0,
75824
75911
  work.finalFrameOnly ? "final-frame" : void 0
75825
75912
  ].filter((part) => part !== void 0);
75826
75913
  const transform = transformParts.length > 0 ? transformParts.join("+") : void 0;
@@ -76001,8 +76088,9 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
76001
76088
  if (keyInput) keyInput.mediaStart = extractionMediaStart;
76002
76089
  const format = resolveFrameFormat(metadata, options.format);
76003
76090
  const sdrToHdrTransfer = sdrToHdrTransfers[index];
76091
+ const toneMapHdrToSdr = options.toneMapHdrToSdr === true && isHdrColorSpace(metadata.colorSpace);
76004
76092
  const finalFrameOnly = window3.finalFrameOnly === true;
76005
- const dedupeKey = `${videoPath}\0${extractionMediaStart}\0${videoDuration}\0${fpsKey}\0${format}\0${sdrToHdrTransfer ?? ""}\0${finalFrameOnly ? "final" : "range"}`;
76093
+ const dedupeKey = `${videoPath}\0${extractionMediaStart}\0${videoDuration}\0${fpsKey}\0${format}\0${sdrToHdrTransfer ?? ""}\0${toneMapHdrToSdr ? HDR_TO_SDR_TRANSFORM_KEY : ""}\0${finalFrameOnly ? "final" : "range"}`;
76006
76094
  return {
76007
76095
  work: {
76008
76096
  video,
@@ -76014,6 +76102,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
76014
76102
  finalFrameOnly,
76015
76103
  format,
76016
76104
  sdrToHdrTransfer,
76105
+ toneMapHdrToSdr,
76017
76106
  dedupeKey
76018
76107
  }
76019
76108
  };
@@ -76148,7 +76237,7 @@ function createFrameLookupTable(videos, extracted) {
76148
76237
  }
76149
76238
  return table;
76150
76239
  }
76151
- 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;
76240
+ 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;
76152
76241
  var init_videoFrameExtractor = __esm({
76153
76242
  "../engine/src/services/videoFrameExtractor.ts"() {
76154
76243
  "use strict";
@@ -76168,6 +76257,8 @@ var init_videoFrameExtractor = __esm({
76168
76257
  EXTRACT_CACHE_MIN_AGE_MS = 60 * 60 * 1e3;
76169
76258
  GC_STALENESS_MS = 24 * 60 * 60 * 1e3;
76170
76259
  SDR_TO_HDR_COLORSPACE_FILTER = "colorspace=all=bt2020:iall=bt709:range=tv";
76260
+ HDR_TO_SDR_TONEMAP_FILTER = "zscale=t=linear:npl=100,tonemap=hable:desat=0,zscale=p=bt709:t=bt709:m=bt709:r=tv";
76261
+ HDR_TO_SDR_TRANSFORM_KEY = "hdr2sdr-hable-bt709";
76171
76262
  VideoSourceExtractionError = class extends Error {
76172
76263
  constructor(kind, retryable, message, diagnostic = message) {
76173
76264
  super(message);
@@ -81893,6 +81984,7 @@ __export(src_exports, {
81893
81984
  FFMPEG_PATH_ENV: () => FFMPEG_PATH_ENV,
81894
81985
  FFPROBE_PATH_ENV: () => FFPROBE_PATH_ENV,
81895
81986
  FrameLookupTable: () => FrameLookupTable,
81987
+ HDR_AUTO_PROMOTION_PIPELINE: () => HDR_AUTO_PROMOTION_PIPELINE,
81896
81988
  LOW_MEMORY_TOTAL_MB_THRESHOLD: () => LOW_MEMORY_TOTAL_MB_THRESHOLD,
81897
81989
  MAX_VP9_CPU_USED: () => MAX_VP9_CPU_USED,
81898
81990
  MEDIA_VISUAL_STYLE_PROPERTIES: () => MEDIA_VISUAL_STYLE_PROPERTIES,
@@ -81977,9 +82069,11 @@ __export(src_exports, {
81977
82069
  extractVideoMetadata: () => extractVideoMetadata,
81978
82070
  extractionFrameCountForDuration: () => extractionFrameCountForDuration,
81979
82071
  fetchPublicHttpsText: () => fetchPublicHttpsText,
82072
+ findHdrAutoPromotion: () => findHdrAutoPromotion,
81980
82073
  fingerprintElementId: () => fingerprintElementId,
81981
82074
  float16ToPqRgb: () => float16ToPqRgb,
81982
82075
  formatFfmpegError: () => formatFfmpegError,
82076
+ formatHdrAutoPromotionWarning: () => formatHdrAutoPromotionWarning,
81983
82077
  getCapturePerfSummary: () => getCapturePerfSummary,
81984
82078
  getCdpSession: () => getCdpSession,
81985
82079
  getCgroupMemoryLimitMb: () => getCgroupMemoryLimitMb,
@@ -82061,6 +82155,7 @@ __export(src_exports, {
82061
82155
  safeDownloadUrlIdentity: () => safeDownloadUrlIdentity,
82062
82156
  safeVideoExtractionSourceIdentity: () => safeVideoExtractionSourceIdentity,
82063
82157
  sampleRgb48le: () => sampleRgb48le,
82158
+ sanitizeHdrAutoPromotionAsset: () => sanitizeHdrAutoPromotionAsset,
82064
82159
  scaleProtocolTimeoutForComposition: () => scaleProtocolTimeoutForComposition,
82065
82160
  selectVerifySampleIndicesForTask: () => selectVerifySampleIndicesForTask,
82066
82161
  shouldClampToScreenshotForConcreteGpu: () => shouldClampToScreenshotForConcreteGpu,
@@ -86777,6 +86872,10 @@ var ArtifactTransaction = class {
86777
86872
  }
86778
86873
  }
86779
86874
  };
86875
+ async function commitArtifactTransaction(transaction, assertNotAborted) {
86876
+ assertNotAborted();
86877
+ await transaction.commit();
86878
+ }
86780
86879
 
86781
86880
  // ../producer/src/services/render/capturePlan.ts
86782
86881
  function drawElementVerificationFailure(plan2, hasDiskFallbackHeadroom) {
@@ -86879,6 +86978,42 @@ function replanAfterFailure(plan2, failure) {
86879
86978
 
86880
86979
  // ../producer/src/services/render/hdrMode.ts
86881
86980
  init_src();
86981
+ function findRenderHdrAutoPromotionTrigger(input) {
86982
+ for (const extracted of input.extractionResult?.extracted ?? []) {
86983
+ if (!isHdrColorSpace(extracted.metadata.colorSpace)) continue;
86984
+ const source = input.videos.find(({ id }) => id === extracted.videoId)?.src;
86985
+ if (source) return source;
86986
+ }
86987
+ return input.images.find(({ id }) => input.nativeHdrImageIds.has(id))?.src;
86988
+ }
86989
+ function logHdrResolution(input, hdrMode, effectiveHdr, forcedHdrWithoutSources) {
86990
+ if (forcedHdrWithoutSources) {
86991
+ input.log.warn(
86992
+ "[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."
86993
+ );
86994
+ }
86995
+ if (!effectiveHdr) {
86996
+ input.log.info(
86997
+ hdrMode === "force-sdr" ? "[Render] SDR forced by --sdr flag" : "[Render] No HDR sources detected \u2014 rendering SDR"
86998
+ );
86999
+ return;
87000
+ }
87001
+ if (hdrMode === "auto") {
87002
+ input.log.warn(
87003
+ formatHdrAutoPromotionWarning({
87004
+ triggeringAsset: sanitizeHdrAutoPromotionAsset(
87005
+ input.autoPromotionTrigger ?? "an HDR-tagged asset"
87006
+ ),
87007
+ output: HDR_AUTO_PROMOTION_PIPELINE
87008
+ })
87009
+ );
87010
+ return;
87011
+ }
87012
+ const reason = forcedHdrWithoutSources ? "forced by --hdr flag (no HDR sources detected \u2014 defaulting to HLG)" : "forced by --hdr flag";
87013
+ input.log.info(
87014
+ `[Render] HDR ${reason} \u2014 output: ${effectiveHdr.transfer.toUpperCase()} (BT.2020, 10-bit H.265)`
87015
+ );
87016
+ }
86882
87017
  function resolveEffectiveHdrMode(input) {
86883
87018
  const hdrMode = input.hdrMode ?? "auto";
86884
87019
  const videoColorSpaces = (input.extractionResult?.extracted ?? []).map(
@@ -86907,26 +87042,7 @@ function resolveEffectiveHdrMode(input) {
86907
87042
  );
86908
87043
  effectiveHdr = void 0;
86909
87044
  }
86910
- if (forcedHdrWithoutSources) {
86911
- input.log.warn(
86912
- "[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."
86913
- );
86914
- }
86915
- if (effectiveHdr) {
86916
- let reason;
86917
- if (hdrMode === "force-hdr") {
86918
- reason = forcedHdrWithoutSources ? "forced by --hdr flag (no HDR sources detected \u2014 defaulting to HLG)" : "forced by --hdr flag";
86919
- } else {
86920
- reason = "auto-detected from source(s)";
86921
- }
86922
- input.log.info(
86923
- `[Render] HDR ${reason} \u2014 output: ${effectiveHdr.transfer.toUpperCase()} (BT.2020, 10-bit H.265)`
86924
- );
86925
- } else if (hdrMode === "force-sdr") {
86926
- input.log.info("[Render] SDR forced by --sdr flag");
86927
- } else {
86928
- input.log.info("[Render] No HDR sources detected \u2014 rendering SDR");
86929
- }
87045
+ logHdrResolution(input, hdrMode, effectiveHdr, forcedHdrWithoutSources);
86930
87046
  return effectiveHdr;
86931
87047
  }
86932
87048
 
@@ -87072,6 +87188,9 @@ function aggregateDrawElement(perfs, de) {
87072
87188
  preInversionWorkers: de.preInversionWorkers,
87073
87189
  compositionElementCount: de.compositionElementCount,
87074
87190
  compositionElementCountSource: de.compositionElementCountSource,
87191
+ compositionElementTags: de.compositionElementTags,
87192
+ arollVideoCount: de.arollVideoCount,
87193
+ heygenVideoCount: de.heygenVideoCount,
87075
87194
  shortBand: de.shortBand,
87076
87195
  parallelRouter: de.parallelRouter ?? "none",
87077
87196
  preRouterWorkers: de.preRouterWorkers,
@@ -92612,6 +92731,7 @@ async function runExtractVideosStage(input) {
92612
92731
  fps: job.config.fps,
92613
92732
  outputDir: join31(compiledDir, "__hyperframes_video_frames"),
92614
92733
  format: job.config.videoFrameFormat ?? "auto",
92734
+ toneMapHdrToSdr: job.config.hdrMode === "force-sdr",
92615
92735
  timelineEnd: composition.duration,
92616
92736
  maxTransientRetries: extractionPolicy.maxTransientRetries,
92617
92737
  collectProbeFailures: extractionPolicy.failureMode === "enforce"
@@ -96690,16 +96810,31 @@ function envInt(name, fallback) {
96690
96810
  const parsed = Number(raw);
96691
96811
  return Number.isInteger(parsed) ? parsed : fallback;
96692
96812
  }
96693
- function countElementTags(html) {
96813
+ var MAX_REPORTED_ELEMENT_TAGS = 50;
96814
+ function scanElementTags(html) {
96694
96815
  let markup = html;
96695
96816
  for (let previous = ""; markup !== previous; ) {
96696
96817
  previous = markup;
96697
96818
  markup = markup.replace(/<(script|style)\b[^>]*>[\s\S]*?<\/\1>/gi, "");
96698
96819
  }
96699
- const matches2 = markup.match(
96700
- /<\/[a-zA-Z]|<(?:img|br|hr|input|source|track|area|base|col|embed|link|meta|param|wbr)\b|<[a-zA-Z][-a-zA-Z0-9]*\b[^>]*\/>/gi
96820
+ let total = 0;
96821
+ const counts = /* @__PURE__ */ new Map();
96822
+ for (const m of markup.matchAll(
96823
+ /<\/([a-zA-Z][-a-zA-Z0-9]*)|<(img|br|hr|input|source|track|area|base|col|embed|link|meta|param|wbr)\b|<([a-zA-Z][-a-zA-Z0-9]*)\b[^>]*\/>/gi
96824
+ )) {
96825
+ total++;
96826
+ const tag = (m[1] ?? m[2] ?? m[3] ?? "").toLowerCase();
96827
+ counts.set(tag, (counts.get(tag) ?? 0) + 1);
96828
+ }
96829
+ const ranked = [...counts.entries()].sort((a, b) => b[1] - a[1]);
96830
+ const byTag = Object.fromEntries(
96831
+ ranked.slice(0, MAX_REPORTED_ELEMENT_TAGS)
96701
96832
  );
96702
- return matches2 === null ? 0 : matches2.length;
96833
+ const otherCount = ranked.slice(MAX_REPORTED_ELEMENT_TAGS).reduce((sum, [, count]) => sum + count, 0);
96834
+ if (otherCount > 0) byTag.other = (byTag.other ?? 0) + otherCount;
96835
+ const arollVideoCount = markup.match(/<video\b[^>]*\bdata-aroll=["']true["'][^>]*>/gi)?.length ?? 0;
96836
+ const heygenVideoCount = markup.match(/<video\b[^>]*\bdata-media-source=["']heygen["'][^>]*>/gi)?.length ?? 0;
96837
+ return { total, byTag, arollVideoCount, heygenVideoCount };
96703
96838
  }
96704
96839
  async function resolveCompositionElementCount(probeSession, html) {
96705
96840
  if (probeSession?.isInitialized) {
@@ -96715,7 +96850,14 @@ async function resolveCompositionElementCount(probeSession, html) {
96715
96850
  } catch {
96716
96851
  }
96717
96852
  }
96718
- return { count: countElementTags(html), source: "static" };
96853
+ const scan = scanElementTags(html);
96854
+ return {
96855
+ count: scan.total,
96856
+ source: "static",
96857
+ byTag: scan.byTag,
96858
+ arollVideoCount: scan.arollVideoCount,
96859
+ heygenVideoCount: scan.heygenVideoCount
96860
+ };
96719
96861
  }
96720
96862
  function mergeWorkerInitObservability(perfs) {
96721
96863
  let initDurationMs;
@@ -96854,7 +96996,7 @@ function deVerifyFallbackTelemetry(err) {
96854
96996
  thresholdDb: roundDb(details?.verifyThresholdDb)
96855
96997
  };
96856
96998
  }
96857
- async function executeRenderJob(job, projectDir, outputPath, progressSink, abortSignal) {
96999
+ async function executeRenderJob(job, projectDir, outputPath, progressSink, abortSignal, assertRenderActive) {
96858
97000
  const moduleDir = dirname19(fileURLToPath5(import.meta.url));
96859
97001
  const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve13(process.env.PRODUCER_RENDERS_DIR, "..") : resolve13(moduleDir, "../..");
96860
97002
  const debugDir = join43(producerRoot, ".debug");
@@ -96887,14 +97029,24 @@ async function executeRenderJob(job, projectDir, outputPath, progressSink, abort
96887
97029
  workDir,
96888
97030
  logPath,
96889
97031
  pipelineStart,
96890
- execution
97032
+ execution,
97033
+ assertRenderActive
96891
97034
  });
96892
97035
  } finally {
96893
97036
  await execution.dispose();
96894
97037
  }
96895
97038
  }
96896
97039
  async function executeRenderPipeline(input) {
96897
- const { job, projectDir, outputPath, workDir, logPath, pipelineStart, execution } = input;
97040
+ const {
97041
+ job,
97042
+ projectDir,
97043
+ outputPath,
97044
+ workDir,
97045
+ logPath,
97046
+ pipelineStart,
97047
+ execution,
97048
+ assertRenderActive
97049
+ } = input;
96898
97050
  const log = execution.logger;
96899
97051
  const eventPublisher = execution.events;
96900
97052
  const onProgress = execution.onProgress;
@@ -97223,11 +97375,18 @@ async function executeRenderPipeline(input) {
97223
97375
  });
97224
97376
  if (failureToEnforce) throw failureToEnforce;
97225
97377
  assertVideoFrameCoverage(coverageReports, coverageThreshold);
97378
+ const autoPromotionTrigger = findRenderHdrAutoPromotionTrigger({
97379
+ extractionResult,
97380
+ videos: composition.videos,
97381
+ images: composition.images,
97382
+ nativeHdrImageIds
97383
+ });
97226
97384
  const effectiveHdr = resolveEffectiveHdrMode({
97227
97385
  hdrMode: job.config.hdrMode,
97228
97386
  outputFormat,
97229
97387
  extractionResult,
97230
97388
  imageColorSpaces,
97389
+ autoPromotionTrigger,
97231
97390
  log
97232
97391
  });
97233
97392
  observability.checkpoint("hdr_detection", "resolved", {
@@ -97356,7 +97515,13 @@ async function executeRenderPipeline(input) {
97356
97515
  const deSingleMinFrames = Number.isFinite(deSingleMinFramesNum) ? deSingleMinFramesNum : 900;
97357
97516
  const deShortBandMinFrames = envInt("HF_DE_SHORT_MIN_FRAMES", 250);
97358
97517
  const deShortBandMaxElements = envInt("HF_DE_SHORT_MAX_ELEMENTS", 2500);
97359
- const { count: compositionElementCount, source: compositionElementCountSource } = await resolveCompositionElementCount(probeSession, compiled.html);
97518
+ const {
97519
+ count: compositionElementCount,
97520
+ source: compositionElementCountSource,
97521
+ byTag: compositionElementTags,
97522
+ arollVideoCount,
97523
+ heygenVideoCount
97524
+ } = await resolveCompositionElementCount(probeSession, compiled.html);
97360
97525
  const deShortBandEnabled = deShortBandMaxElements > 0;
97361
97526
  const deShortBandOpen = deShortBandEnabled && deShortBandMinFrames > 0 && compositionElementCountSource === "live" && compositionElementCount <= deShortBandMaxElements;
97362
97527
  const deShortBandRoute = process.env.HF_DE_SHORT_BAND_ROUTE === "true";
@@ -97550,6 +97715,9 @@ async function executeRenderPipeline(input) {
97550
97715
  // perf shift can be split into "the new band did it" vs "unchanged".
97551
97716
  compositionElementCount,
97552
97717
  compositionElementCountSource,
97718
+ compositionElementTags,
97719
+ arollVideoCount,
97720
+ heygenVideoCount,
97553
97721
  deShortBand,
97554
97722
  // Same rationale as the counters above: carried on live capture
97555
97723
  // observability, not only the success-path perfSummary, so a crash /
@@ -98214,6 +98382,9 @@ async function executeRenderPipeline(input) {
98214
98382
  preInversionWorkers: deWorkerInversion ? preRoutingWorkerCount : void 0,
98215
98383
  compositionElementCount,
98216
98384
  compositionElementCountSource,
98385
+ compositionElementTags,
98386
+ arollVideoCount,
98387
+ heygenVideoCount,
98217
98388
  shortBand: deShortBand,
98218
98389
  parallelRouter: deParallelRouter,
98219
98390
  preRouterWorkers: deParallelRouter ? preRoutingWorkerCount : void 0,
@@ -98248,7 +98419,10 @@ async function executeRenderPipeline(input) {
98248
98419
  copyFileSync6(stagedOutputPath, debugOutput);
98249
98420
  }
98250
98421
  }
98251
- await artifactTransaction.commit();
98422
+ await commitArtifactTransaction(artifactTransaction, () => {
98423
+ assertRenderActive?.();
98424
+ assertNotAborted();
98425
+ });
98252
98426
  job.outputPath = outputPath;
98253
98427
  updateJobStatus(job, "complete", "Render complete", 100, onProgress);
98254
98428
  await eventPublisher.flush();
@@ -99633,8 +99807,8 @@ async function runFontLocalize(io, localize) {
99633
99807
  }
99634
99808
 
99635
99809
  // src/version.ts
99636
- var VERSION = true ? "0.8.41" : "0.0.0-dev";
99637
- var PRODUCER_VERSION = true ? "0.8.41" : "0.0.0-dev";
99810
+ var VERSION = true ? "0.8.43" : "0.0.0-dev";
99811
+ var PRODUCER_VERSION = true ? "0.8.43" : "0.0.0-dev";
99638
99812
 
99639
99813
  // src/fontLocalizeCli.ts
99640
99814
  async function readStdin() {