hyperframes 0.8.37 → 0.8.38

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 (30) hide show
  1. package/dist/cli.js +118 -142
  2. package/dist/docs/examples.md +1 -1
  3. package/dist/fontLocalizeCli.js +3 -92
  4. package/dist/hyperframes-player.global.js +1 -1
  5. package/dist/skills/hyperframes/SKILL.md +1 -1
  6. package/dist/skills/hyperframes/references/brief-contract.md +108 -0
  7. package/dist/skills/hyperframes/references/brief-format.md +72 -0
  8. package/dist/skills/hyperframes/references/capability-menu.md +1 -1
  9. package/dist/skills/hyperframes/references/frame-worker-core.md +80 -0
  10. package/dist/skills/hyperframes/references/intent-interview.md +8 -8
  11. package/dist/skills/hyperframes/references/production-loop.md +26 -0
  12. package/dist/skills/hyperframes/references/review-loop.md +41 -0
  13. package/dist/skills/hyperframes/references/route-briefs.md +1 -1
  14. package/dist/skills/hyperframes/references/script-format.md +52 -0
  15. package/dist/skills/hyperframes/references/storyboard-format.md +130 -0
  16. package/dist/skills/hyperframes/references/subagent-dispatch.md +35 -0
  17. package/dist/skills/hyperframes/scripts/lib/frame-packets-core.mjs +212 -0
  18. package/dist/skills/hyperframes-cli/SKILL.md +9 -8
  19. package/dist/skills/hyperframes-cli/references/init-and-scaffold.md +6 -6
  20. package/dist/skills/hyperframes-cli/references/preview-render.md +6 -3
  21. package/dist/studio/assets/{hyperframes-player-DrGk-lf5.js → hyperframes-player-otov4oIw.js} +1 -1
  22. package/dist/studio/assets/{index-xK1YGiPD.js → index-B-FzDhAR.js} +1 -1
  23. package/dist/studio/assets/{index-BtGF7Kl-.js → index-Bw6cyxOm.js} +1 -1
  24. package/dist/studio/assets/{index-DMsdtB-j.js → index-DWFEyVJZ.js} +4 -4
  25. package/dist/studio/index.html +1 -1
  26. package/dist/studio/index.js +1 -1
  27. package/dist/studio/index.js.map +1 -1
  28. package/dist/templates/blank/index.html +17 -37
  29. package/dist/templates/from-file/index.html +74 -0
  30. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -50,7 +50,7 @@ var VERSION;
50
50
  var init_version = __esm({
51
51
  "src/version.ts"() {
52
52
  "use strict";
53
- VERSION = true ? "0.8.37" : "0.0.0-dev";
53
+ VERSION = true ? "0.8.38" : "0.0.0-dev";
54
54
  }
55
55
  });
56
56
 
@@ -80970,10 +80970,6 @@ function targetHasNoStableIdentity(selector, identity) {
80970
80970
  if (identity) return false;
80971
80971
  return selector === UNRESOLVED_TARGET || selector === "dwell/hold" || selector.startsWith("proxy \u2192 ");
80972
80972
  }
80973
- function readRegisteredTimelineCompositionId(script) {
80974
- const match = script.match(WINDOW_TIMELINE_ASSIGN_PATTERN);
80975
- return match?.[1] || match?.[2] || null;
80976
- }
80977
80973
  function unwrapRaw(value) {
80978
80974
  if (typeof value === "number") return value;
80979
80975
  if (typeof value !== "string") return void 0;
@@ -81140,21 +81136,6 @@ function makesOverlayVisible(win) {
81140
81136
  if (win.method === "from" && isHiddenGsapState(win.propertyValues)) return true;
81141
81137
  return isVisibleGsapState(win.propertyValues);
81142
81138
  }
81143
- function isSceneBoundaryExit(win) {
81144
- if (win.end <= win.position) return false;
81145
- if (win.method !== "to" && win.method !== "fromTo") return false;
81146
- return isHiddenGsapState(win.propertyValues);
81147
- }
81148
- function isHardKillSet(win, selector, boundary) {
81149
- return win.method === "set" && win.targetSelector === selector && Math.abs(win.position - boundary) <= SCENE_BOUNDARY_EPSILON_SECONDS && isHiddenGsapState(win.propertyValues);
81150
- }
81151
- function hiddenStateLiteral(values) {
81152
- if (zeroValue(values.autoAlpha)) return "{ autoAlpha: 0 }";
81153
- if (zeroValue(values.opacity)) return "{ opacity: 0 }";
81154
- if (stringValue(values.visibility)?.toLowerCase() === "hidden") return '{ visibility: "hidden" }';
81155
- if (stringValue(values.display)?.toLowerCase() === "none") return '{ display: "none" }';
81156
- return "{ opacity: 0 }";
81157
- }
81158
81139
  function findTagEnd2(source, tag) {
81159
81140
  const escapedTagName = tag.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
81160
81141
  const pattern = new RegExp(`<\\/?${escapedTagName}\\b[^>]*>`, "gi");
@@ -81171,56 +81152,11 @@ function findTagEnd2(source, tag) {
81171
81152
  }
81172
81153
  return source.length;
81173
81154
  }
81174
- function collectCompositionRanges(source, tags) {
81175
- return tags.map((tag) => {
81176
- const id = readDecodedAttr(tag.raw, "data-composition-id");
81177
- if (!id) return null;
81178
- return {
81179
- id,
81180
- start: tag.index,
81181
- end: findTagEnd2(source, tag)
81182
- };
81183
- }).filter((range) => range !== null);
81184
- }
81185
- function findContainingCompositionId(tag, ranges) {
81186
- let match = null;
81187
- for (const range of ranges) {
81188
- if (tag.index < range.start || tag.index >= range.end) continue;
81189
- if (!match || range.start >= match.start) match = range;
81190
- }
81191
- return match?.id || null;
81192
- }
81193
81155
  function getClipTagClasses(tag) {
81194
81156
  const classAttr = readAttr(tag.raw, "class") || "";
81195
81157
  const classes = classAttr.split(/\s+/).filter(Boolean);
81196
81158
  return classes.includes("clip") ? { classAttr, classes } : null;
81197
81159
  }
81198
- function collectClipStartBoundariesByComposition(source, tags) {
81199
- const ranges = collectCompositionRanges(source, tags);
81200
- const boundaries = /* @__PURE__ */ new Map();
81201
- for (const tag of tags) {
81202
- if (!getClipTagClasses(tag)) continue;
81203
- const compositionId = findContainingCompositionId(tag, ranges);
81204
- if (!compositionId) continue;
81205
- const start = numberValue(readAttr(tag.raw, "data-start") ?? void 0);
81206
- if (start == null || start <= 0) continue;
81207
- const compositionBoundaries = boundaries.get(compositionId) ?? /* @__PURE__ */ new Set();
81208
- compositionBoundaries.add(start);
81209
- boundaries.set(compositionId, compositionBoundaries);
81210
- }
81211
- return new Map(
81212
- [...boundaries.entries()].map(([compositionId, values]) => [
81213
- compositionId,
81214
- [...values].sort((a, b2) => a - b2)
81215
- ])
81216
- );
81217
- }
81218
- function findMatchingSceneBoundary(time, boundaries) {
81219
- for (const boundary of boundaries) {
81220
- if (Math.abs(time - boundary) <= SCENE_BOUNDARY_EPSILON_SECONDS) return boundary;
81221
- }
81222
- return null;
81223
- }
81224
81160
  function readStyleProperty(style, property) {
81225
81161
  const escapedProperty = property.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
81226
81162
  const match = style.match(new RegExp(`(?:^|;)\\s*${escapedProperty}\\s*:\\s*([^;]+)`, "i"));
@@ -84143,7 +84079,7 @@ ${allInlineStyles}`.replace(/\/\*[\s\S]*?\*\//g, "");
84143
84079
  },
84144
84080
  // overlapping_gsap_tweens + gsap_animates_clip_element
84145
84081
  // fallow-ignore-next-line complexity
84146
- async ({ source, tags, scripts, styles, rootCompositionId }) => {
84082
+ async ({ tags, scripts, styles }) => {
84147
84083
  const findings = [];
84148
84084
  const authoredHiddenSelectors = new Set(
84149
84085
  scripts.flatMap((script) => [...extractStandaloneHiddenSelectors(script.content)])
@@ -84164,13 +84100,10 @@ ${allInlineStyles}`.replace(/\/\*[\s\S]*?\*\//g, "");
84164
84100
  if (cls !== "clip") clipClasses.set(`.${cls}`, info);
84165
84101
  }
84166
84102
  }
84167
- const clipStartBoundariesByComposition = collectClipStartBoundariesByComposition(source, tags);
84168
84103
  const styleRules = collectSimpleStyleRules(styles);
84169
84104
  const reportedVisibleOverlayKeys = /* @__PURE__ */ new Set();
84170
84105
  for (const script of scripts) {
84171
- const localTimelineCompId = readRegisteredTimelineCompositionId(script.content);
84172
84106
  const gsapWindows = await cachedExtractGsapWindows(script.content);
84173
- const clipStartBoundaries = clipStartBoundariesByComposition.get(localTimelineCompId || rootCompositionId || "") ?? [];
84174
84107
  for (let i2 = 0; i2 < gsapWindows.length; i2++) {
84175
84108
  const left = gsapWindows[i2];
84176
84109
  if (!left) continue;
@@ -84232,28 +84165,6 @@ ${right.raw}`)
84232
84165
  snippet: truncateSnippet(fromToWindows.map((win) => win.raw).join("\n"))
84233
84166
  });
84234
84167
  }
84235
- if (clipStartBoundaries.length > 0) {
84236
- for (const win of gsapWindows) {
84237
- if (win.targetSelector === UNRESOLVED_TARGET) continue;
84238
- if (!isSceneBoundaryExit(win)) continue;
84239
- const boundary = findMatchingSceneBoundary(win.end, clipStartBoundaries);
84240
- if (boundary == null) continue;
84241
- const hasHardKill = gsapWindows.some(
84242
- (candidate) => isHardKillSet(candidate, win.targetSelector, boundary)
84243
- );
84244
- if (hasHardKill) continue;
84245
- const exitClipInfo = clipIds.get(win.targetSelector) || clipClasses.get(win.targetSelector);
84246
- const fixHint = exitClipInfo ? `"${win.targetSelector}" is a clip element \u2014 the framework already manages its visibility. Wrap the scene's content in an inner non-clip <div>, move the exit tween and the hard kill (\`tl.set("<inner-selector>", ${hiddenStateLiteral(win.propertyValues)}, ${boundary.toFixed(2)})\`) onto that wrapper instead.` : `Add \`tl.set("${win.targetSelector}", ${hiddenStateLiteral(win.propertyValues)}, ${boundary.toFixed(2)})\` after the exit tween.`;
84247
- findings.push({
84248
- code: "gsap_exit_missing_hard_kill",
84249
- severity: "error",
84250
- message: `GSAP exit on "${win.targetSelector}" ends at the ${boundary.toFixed(2)}s clip start boundary without a matching tl.set hard kill. Non-linear seeking can land after the fade and leave stale visibility state.`,
84251
- selector: win.targetSelector,
84252
- fixHint,
84253
- snippet: truncateSnippet(win.raw)
84254
- });
84255
- }
84256
- }
84257
84168
  for (const tag of tags) {
84258
84169
  const selectors = tagSimpleSelectors(tag);
84259
84170
  if (selectors.length === 0) continue;
@@ -106332,7 +106243,7 @@ var init_generators = __esm({
106332
106243
  {
106333
106244
  id: "blank",
106334
106245
  label: "Blank",
106335
- hint: "Empty composition \u2014 just the scaffolding",
106246
+ hint: "Centered Inter stage, paused timeline",
106336
106247
  source: "bundled"
106337
106248
  }
106338
106249
  ];
@@ -110272,6 +110183,27 @@ function formatRenderSummaryDetail(input2) {
110272
110183
  const renderTime = `rendered in ${formatDuration(input2.elapsedMs)}`;
110273
110184
  return [middle, renderTime].filter(Boolean).join(" \xB7 ");
110274
110185
  }
110186
+ function resolvePrintedCaptureMode(sessionMode, observabilityCaptureMode) {
110187
+ if (sessionMode && sessionMode !== "unknown") return sessionMode;
110188
+ return observabilityCaptureMode;
110189
+ }
110190
+ function formatRenderPipelineDetail(input2) {
110191
+ const parts = [];
110192
+ if (input2.captureMode) parts.push(`${input2.captureMode} capture`);
110193
+ if (input2.browserGpuMode) parts.push(`${input2.browserGpuMode} gpu`);
110194
+ for (const [key2, stageLabel] of PIPELINE_STAGES) {
110195
+ const ms = input2.stages[key2];
110196
+ if (ms == null) continue;
110197
+ const label2 = key2 === "encodeMs" && input2.streamingEncode ? "encode (during capture)" : stageLabel;
110198
+ parts.push(`${label2} ${formatDuration(ms)}`);
110199
+ }
110200
+ return parts.length > 0 ? parts.join(" \xB7 ") : void 0;
110201
+ }
110202
+ function formatScreenshotFallbackHint(input2) {
110203
+ if (input2.platform !== "linux" || input2.requestedGpuMode !== "auto") return void 0;
110204
+ if (input2.captureMode !== "screenshot" || input2.browserGpuMode !== "software") return void 0;
110205
+ return "Screenshot capture (slower): BeginFrame did not run. Needs chrome-headless-shell and no --resolution upscale. Heavy compositions can stall on software GL.";
110206
+ }
110275
110207
  function label(name, value) {
110276
110208
  const pad4 = 14 - name.length;
110277
110209
  return ` ${c.dim(name)}${" ".repeat(Math.max(1, pad4))}${c.bold(value)}`;
@@ -110287,10 +110219,21 @@ ${c.dim(indented)}`);
110287
110219
  if (suggestion) console.error(` ${c.accent(suggestion)}`);
110288
110220
  console.error();
110289
110221
  }
110222
+ var PIPELINE_STAGES;
110290
110223
  var init_format = __esm({
110291
110224
  "src/ui/format.ts"() {
110292
110225
  "use strict";
110293
110226
  init_colors();
110227
+ PIPELINE_STAGES = [
110228
+ ["compileMs", "compile"],
110229
+ ["videoExtractMs", "extract"],
110230
+ ["audioProcessMs", "audio"],
110231
+ ["browserProbeMs", "probe"],
110232
+ ["captureSetupMs", "setup"],
110233
+ ["captureFrameMs", "capture"],
110234
+ ["encodeMs", "encode"],
110235
+ ["assembleMs", "assemble"]
110236
+ ];
110294
110237
  }
110295
110238
  });
110296
110239
 
@@ -149098,6 +149041,12 @@ import {
149098
149041
  import { resolve as resolve43, basename as basename16, join as join87, dirname as dirname37 } from "path";
149099
149042
  import { fileURLToPath as fileURLToPath9 } from "url";
149100
149043
  import { execFileSync as execFileSync10, spawn as spawn14 } from "child_process";
149044
+ function resolveScaffoldTemplateId(exampleFlag, hasMediaFile) {
149045
+ const example = exampleFlag === "agent" ? "blank" : exampleFlag;
149046
+ if (example && example !== "blank") return example;
149047
+ if (hasMediaFile) return "from-file";
149048
+ return "blank";
149049
+ }
149101
149050
  function resolveVideoDurationSeconds({
149102
149051
  streamDuration,
149103
149052
  frameDuration,
@@ -149534,14 +149483,11 @@ var init_init = __esm({
149534
149483
  ["Scaffold a portrait video", "hyperframes init my-video --resolution portrait"],
149535
149484
  ["Start from an existing video file", "hyperframes init my-video --video clip.mp4"],
149536
149485
  ["Start from an audio file", "hyperframes init my-video --audio track.mp3"],
149537
- ["Scaffold with Tailwind CSS", "hyperframes init my-video --example blank --tailwind"],
149538
- [
149539
- "Non-interactive mode (for CI or AI agents)",
149540
- "hyperframes init my-video --example blank --non-interactive"
149541
- ],
149486
+ ["Scaffold with Tailwind CSS", "hyperframes init my-video --tailwind"],
149487
+ ["Non-interactive mode (for CI or AI agents)", "hyperframes init my-video --non-interactive"],
149542
149488
  [
149543
149489
  "Opt out of the GitHub skills check (CI/tests only)",
149544
- "HYPERFRAMES_SKIP_SKILLS=1 hyperframes init my-video --example blank --non-interactive"
149490
+ "HYPERFRAMES_SKIP_SKILLS=1 hyperframes init my-video --non-interactive"
149545
149491
  ]
149546
149492
  ];
149547
149493
  WEB_CODECS = /* @__PURE__ */ new Set(["h264", "vp8", "vp9", "av1", "theora"]);
@@ -149611,6 +149557,11 @@ var init_init = __esm({
149611
149557
  type: "boolean",
149612
149558
  description: "Disable interactive prompts (for CI/agents)"
149613
149559
  },
149560
+ agent: {
149561
+ type: "boolean",
149562
+ hidden: true,
149563
+ description: "Deprecated alias; default init is the centered blank"
149564
+ },
149614
149565
  "skip-skills": {
149615
149566
  type: "boolean",
149616
149567
  description: "[temporarily ignored] init always checks AI skills against GitHub while the skills.sh registry catches up; set HYPERFRAMES_SKIP_SKILLS=1 to opt out (CI/tests)"
@@ -149658,7 +149609,7 @@ var init_init = __esm({
149658
149609
  const skipSkills = process.env.HYPERFRAMES_SKIP_SKILLS === "1";
149659
149610
  const skipSkillsFlagIgnored = args["skip-skills"] === true && !skipSkills;
149660
149611
  const tailwind = args.tailwind === true;
149661
- const nonInteractive = args["non-interactive"] === true;
149612
+ const nonInteractive = args["non-interactive"] === true || args.agent === true;
149662
149613
  const modelFlag = args.model;
149663
149614
  const languageFlag = args.language;
149664
149615
  const initialTranscriptionModel = initialModelForLanguage(
@@ -149686,15 +149637,7 @@ var init_init = __esm({
149686
149637
  }
149687
149638
  }
149688
149639
  if (!interactive) {
149689
- if (!exampleFlag && !videoFlag && !audioFlag) {
149690
- console.error(
149691
- c.error(
149692
- "Non-interactive init requires --example, --video, or --audio. For an empty starter project, pass --example blank explicitly."
149693
- )
149694
- );
149695
- failCommand();
149696
- }
149697
- const templateId2 = exampleFlag ?? "blank";
149640
+ const templateId2 = resolveScaffoldTemplateId(exampleFlag, Boolean(videoFlag || audioFlag));
149698
149641
  const name2 = args.name ?? "my-video";
149699
149642
  const destDir2 = resolve43(name2);
149700
149643
  if (existsSync71(destDir2) && readdirSync27(destDir2).length > 0) {
@@ -149916,8 +149859,8 @@ var init_init = __esm({
149916
149859
  }
149917
149860
  }
149918
149861
  let templateId;
149919
- if (exampleFlag) {
149920
- templateId = exampleFlag;
149862
+ if (exampleFlag || videoFlag || audioFlag) {
149863
+ templateId = resolveScaffoldTemplateId(exampleFlag, Boolean(videoFlag || audioFlag));
149921
149864
  } else {
149922
149865
  const allTemplates = await resolveTemplateList();
149923
149866
  const defaultTemplate = "blank";
@@ -154352,12 +154295,16 @@ function createRenderPlan(args, now = /* @__PURE__ */ new Date()) {
154352
154295
  failUsage();
154353
154296
  }
154354
154297
  let fps = fpsParse.value;
154355
- const qualityRaw = args.quality ?? "standard";
154356
- if (!VALID_QUALITY.has(qualityRaw)) {
154357
- errorBox("Invalid quality", `Got "${qualityRaw}". Must be draft, standard, or high.`);
154298
+ const qualityRaw = args.quality ?? "looks";
154299
+ if (!(qualityRaw in QUALITY_ALIASES)) {
154300
+ errorBox(
154301
+ "Invalid quality",
154302
+ `Got "${qualityRaw}". Must be draft, looks, delivery, standard, or high.`
154303
+ );
154358
154304
  failUsage();
154359
154305
  }
154360
- const quality = qualityRaw;
154306
+ const qualityAlias = QUALITY_ALIASES[qualityRaw];
154307
+ const quality = qualityAlias.quality;
154361
154308
  const flagSkill = normalizeSkillSlug(args.skill);
154362
154309
  const authoringSkill = flagSkill ?? loadProjectConfig(project.dir).authoringSkill;
154363
154310
  const invalidAuthoringSkill = typeof args.skill === "string" && args.skill.trim() !== "" && !flagSkill ? args.skill : void 0;
@@ -154505,7 +154452,7 @@ function createRenderPlan(args, now = /* @__PURE__ */ new Date()) {
154505
154452
  "Invalid crf",
154506
154453
  `Got "${args.crf}". Must be a non-negative integer.`,
154507
154454
  0
154508
- ) : void 0;
154455
+ ) : format === "mov" || args["video-bitrate"] ? void 0 : "crf" in qualityAlias ? qualityAlias.crf : void 0;
154509
154456
  let vp9CpuUsed;
154510
154457
  if (args["vp9-cpu-used"] != null) {
154511
154458
  const parsed = Number(args["vp9-cpu-used"]);
@@ -154596,7 +154543,7 @@ function resolveBrowserGpuForCli(useDocker, browserGpuArg, envMode = process.env
154596
154543
  if (envMode === "hardware" || envMode === "software" || envMode === "auto") return envMode;
154597
154544
  return "auto";
154598
154545
  }
154599
- var VALID_QUALITY, RENDER_FORMATS, VALID_FORMAT, RENDER_FORMAT_LABEL, FORMAT_EXT;
154546
+ var QUALITY_ALIASES, RENDER_FORMATS, VALID_FORMAT, RENDER_FORMAT_LABEL, FORMAT_EXT;
154600
154547
  var init_plan2 = __esm({
154601
154548
  "src/commands/render/plan.ts"() {
154602
154549
  "use strict";
@@ -154609,7 +154556,13 @@ var init_plan2 = __esm({
154609
154556
  init_skill();
154610
154557
  init_projectConfig();
154611
154558
  init_catalogUsage();
154612
- VALID_QUALITY = /* @__PURE__ */ new Set(["draft", "standard", "high"]);
154559
+ QUALITY_ALIASES = {
154560
+ draft: { quality: "draft" },
154561
+ standard: { quality: "standard" },
154562
+ high: { quality: "high" },
154563
+ looks: { quality: "standard", crf: 16 },
154564
+ delivery: { quality: "high" }
154565
+ };
154613
154566
  RENDER_FORMATS = ["mp4", "webm", "mov", "png-sequence", "gif"];
154614
154567
  VALID_FORMAT = new Set(RENDER_FORMATS);
154615
154568
  RENDER_FORMAT_LABEL = "mp4, webm, mov, png-sequence, or gif";
@@ -156032,6 +155985,9 @@ async function renderLocal(projectDir, outputPath, options) {
156032
155985
  );
156033
155986
  const engineConfig = producer.resolveConfig({
156034
155987
  browserGpuMode: options.browserGpuMode ?? "software",
155988
+ // Local auto opts out of the software-GPU screenshot clamp. Docker and
155989
+ // --no-browser-gpu request software; --resolution supersamples via screenshot.
155990
+ ...options.browserGpuMode === "auto" && options.outputResolution == null && process.env.PRODUCER_FORCE_SCREENSHOT !== "true" ? { forceScreenshot: false } : {},
156035
155991
  ...options.pageNavigationTimeoutMs != null ? { pageNavigationTimeout: options.pageNavigationTimeoutMs } : {},
156036
155992
  ...options.protocolTimeout != null && { protocolTimeout: options.protocolTimeout },
156037
155993
  ...options.playerReadyTimeout != null && { playerReadyTimeout: options.playerReadyTimeout },
@@ -156094,8 +156050,8 @@ async function renderLocal(projectDir, outputPath, options) {
156094
156050
  outputPath,
156095
156051
  elapsed,
156096
156052
  options.quiet,
156097
- job.perfSummary?.compositionDurationSeconds,
156098
- job.perfSummary?.totalFrames
156053
+ job.perfSummary,
156054
+ options.browserGpuMode
156099
156055
  )
156100
156056
  );
156101
156057
  runPostRenderStep(
@@ -156446,37 +156402,57 @@ function trackRenderMetrics(job, elapsedMs, options, docker) {
156446
156402
  ...getMemorySnapshot()
156447
156403
  });
156448
156404
  }
156449
- function printRenderComplete(outputPath, elapsedMs, quiet, outputDurationSeconds, frameCount) {
156450
- if (quiet) return;
156451
- let fileSize = "unknown";
156452
- let isDirectory = false;
156405
+ function readOutputFootprint(outputPath) {
156453
156406
  try {
156454
156407
  const stat3 = statSync31(outputPath);
156455
- isDirectory = stat3.isDirectory();
156456
- if (stat3.isDirectory()) {
156457
- let total = 0;
156458
- for (const entry of readdirSync29(outputPath, { withFileTypes: true })) {
156459
- if (!entry.isFile()) continue;
156460
- try {
156461
- total += statSync31(join97(outputPath, entry.name)).size;
156462
- } catch {
156463
- }
156408
+ if (!stat3.isDirectory()) return { fileSize: formatBytes(stat3.size), isDirectory: false };
156409
+ let total = 0;
156410
+ for (const entry of readdirSync29(outputPath, { withFileTypes: true })) {
156411
+ if (!entry.isFile()) continue;
156412
+ try {
156413
+ total += statSync31(join97(outputPath, entry.name)).size;
156414
+ } catch {
156464
156415
  }
156465
- fileSize = formatBytes(total);
156466
- } else {
156467
- fileSize = formatBytes(stat3.size);
156468
156416
  }
156417
+ return { fileSize: formatBytes(total), isDirectory: true };
156469
156418
  } catch {
156419
+ return { fileSize: "unknown", isDirectory: false };
156470
156420
  }
156421
+ }
156422
+ function printRenderComplete(outputPath, elapsedMs, quiet, perf, requestedGpuMode) {
156423
+ if (quiet) return;
156424
+ const { fileSize, isDirectory } = readOutputFootprint(outputPath);
156471
156425
  const detail = formatRenderSummaryDetail({
156472
156426
  elapsedMs,
156473
- outputDurationSeconds,
156427
+ outputDurationSeconds: perf?.compositionDurationSeconds,
156474
156428
  isDirectory,
156475
- frameCount
156429
+ frameCount: perf?.totalFrames
156476
156430
  });
156477
156431
  console.log("");
156478
156432
  console.log(c.success("\u25C7") + " " + c.accent(outputPath));
156479
156433
  console.log(" " + c.bold(fileSize) + c.dim(" \xB7 " + detail));
156434
+ if (perf) printRenderPipeline(perf, requestedGpuMode);
156435
+ }
156436
+ function printRenderPipeline(perf, requestedGpuMode) {
156437
+ const capture2 = {
156438
+ captureMode: resolvePrintedCaptureMode(
156439
+ perf.drawElement?.mode,
156440
+ perf.observability?.capture.captureMode
156441
+ ),
156442
+ browserGpuMode: perf.observability?.capture.browserGpuMode
156443
+ };
156444
+ const pipeline5 = formatRenderPipelineDetail({
156445
+ ...capture2,
156446
+ streamingEncode: perf.observability?.capture.useStreamingEncode,
156447
+ stages: perf.stages
156448
+ });
156449
+ if (pipeline5) console.log(" " + c.dim(pipeline5));
156450
+ const hint2 = formatScreenshotFallbackHint({
156451
+ ...capture2,
156452
+ requestedGpuMode,
156453
+ platform: process.platform
156454
+ });
156455
+ if (hint2) console.log(" " + c.dim(hint2));
156480
156456
  }
156481
156457
  var examples9, render_default, DOCKER_IMAGE_PREFIX, deParallelRouterUserManaged, deParallelRouterUserManagedResolved, deParallelRouterBreakerTrippedThisProcess;
156482
156458
  var init_render = __esm({
@@ -156583,8 +156559,8 @@ var init_render = __esm({
156583
156559
  quality: {
156584
156560
  type: "string",
156585
156561
  alias: "q",
156586
- description: "Quality: draft, standard, high. MOV always uses the fixed alpha-preserving ProRes 4444 profile.",
156587
- default: "standard"
156562
+ description: "Quality: draft, looks, delivery, or standard/high. looks is the default (CRF 16). delivery is high. MOV always uses the fixed alpha-preserving ProRes 4444 profile.",
156563
+ default: "looks"
156588
156564
  },
156589
156565
  skill: {
156590
156566
  type: "string",
@@ -219968,7 +219944,7 @@ async function streamVideo(url, destPath, asJson) {
219968
219944
  failCommand();
219969
219945
  }
219970
219946
  }
219971
- var VALID_QUALITY2, VALID_FORMAT2, VALID_RESOLUTION, VALID_ASPECT_RATIO, DIRECT_UPLOAD_LIMIT_BYTES, ARCHIVE_DIAGNOSTIC_THRESHOLD_BYTES, LARGEST_FILE_COUNT, FORMAT_EXT2, examples36, render_default2, IDEMPOTENCY_KEY_RE, ASPECT_FALLBACK_HINT;
219947
+ var VALID_QUALITY, VALID_FORMAT2, VALID_RESOLUTION, VALID_ASPECT_RATIO, DIRECT_UPLOAD_LIMIT_BYTES, ARCHIVE_DIAGNOSTIC_THRESHOLD_BYTES, LARGEST_FILE_COUNT, FORMAT_EXT2, examples36, render_default2, IDEMPOTENCY_KEY_RE, ASPECT_FALLBACK_HINT;
219972
219948
  var init_render3 = __esm({
219973
219949
  "src/commands/cloud/render.ts"() {
219974
219950
  "use strict";
@@ -219987,7 +219963,7 @@ var init_render3 = __esm({
219987
219963
  init_parsing();
219988
219964
  init_upload();
219989
219965
  init_statusColor();
219990
- VALID_QUALITY2 = ["draft", "standard", "high"];
219966
+ VALID_QUALITY = ["draft", "standard", "high"];
219991
219967
  VALID_FORMAT2 = ["mp4", "webm", "mov"];
219992
219968
  VALID_RESOLUTION = ["1080p", "4k"];
219993
219969
  VALID_ASPECT_RATIO = ["16:9", "9:16", "1:1"];
@@ -220109,7 +220085,7 @@ var init_render3 = __esm({
220109
220085
  async run({ args }) {
220110
220086
  const asJson = Boolean(args.json);
220111
220087
  const fps = parseIntFlag3(args.fps, { flag: "--fps", min: 1, max: 240 });
220112
- const quality = parseEnumFlag(args.quality, VALID_QUALITY2, { flag: "--quality" });
220088
+ const quality = parseEnumFlag(args.quality, VALID_QUALITY, { flag: "--quality" });
220113
220089
  const format = parseEnumFlag(args.format, VALID_FORMAT2, { flag: "--format" });
220114
220090
  const resolution = parseEnumFlag(args.resolution, VALID_RESOLUTION, {
220115
220091
  flag: "--resolution"
@@ -4,7 +4,7 @@ Built-in templates available via `npx hyperframes init --example <name>`.
4
4
 
5
5
  ## blank
6
6
 
7
- Empty 1920x1080 composition with GSAP timeline wired up. Start from scratch.
7
+ Centered Inter stage, paused GSAP timeline. Default `hyperframes init` scaffold.
8
8
 
9
9
  ## title-card
10
10
 
@@ -69963,10 +69963,6 @@ function targetHasNoStableIdentity(selector, identity) {
69963
69963
  if (identity) return false;
69964
69964
  return selector === UNRESOLVED_TARGET || selector === "dwell/hold" || selector.startsWith("proxy \u2192 ");
69965
69965
  }
69966
- function readRegisteredTimelineCompositionId(script) {
69967
- const match = script.match(WINDOW_TIMELINE_ASSIGN_PATTERN);
69968
- return match?.[1] || match?.[2] || null;
69969
- }
69970
69966
  function unwrapRaw(value) {
69971
69967
  if (typeof value === "number") return value;
69972
69968
  if (typeof value !== "string") return void 0;
@@ -70133,21 +70129,6 @@ function makesOverlayVisible(win) {
70133
70129
  if (win.method === "from" && isHiddenGsapState(win.propertyValues)) return true;
70134
70130
  return isVisibleGsapState(win.propertyValues);
70135
70131
  }
70136
- function isSceneBoundaryExit(win) {
70137
- if (win.end <= win.position) return false;
70138
- if (win.method !== "to" && win.method !== "fromTo") return false;
70139
- return isHiddenGsapState(win.propertyValues);
70140
- }
70141
- function isHardKillSet(win, selector, boundary) {
70142
- return win.method === "set" && win.targetSelector === selector && Math.abs(win.position - boundary) <= SCENE_BOUNDARY_EPSILON_SECONDS && isHiddenGsapState(win.propertyValues);
70143
- }
70144
- function hiddenStateLiteral(values) {
70145
- if (zeroValue(values.autoAlpha)) return "{ autoAlpha: 0 }";
70146
- if (zeroValue(values.opacity)) return "{ opacity: 0 }";
70147
- if (stringValue(values.visibility)?.toLowerCase() === "hidden") return '{ visibility: "hidden" }';
70148
- if (stringValue(values.display)?.toLowerCase() === "none") return '{ display: "none" }';
70149
- return "{ opacity: 0 }";
70150
- }
70151
70132
  function findTagEnd2(source, tag) {
70152
70133
  const escapedTagName = tag.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
70153
70134
  const pattern = new RegExp(`<\\/?${escapedTagName}\\b[^>]*>`, "gi");
@@ -70164,56 +70145,11 @@ function findTagEnd2(source, tag) {
70164
70145
  }
70165
70146
  return source.length;
70166
70147
  }
70167
- function collectCompositionRanges(source, tags) {
70168
- return tags.map((tag) => {
70169
- const id = readDecodedAttr(tag.raw, "data-composition-id");
70170
- if (!id) return null;
70171
- return {
70172
- id,
70173
- start: tag.index,
70174
- end: findTagEnd2(source, tag)
70175
- };
70176
- }).filter((range) => range !== null);
70177
- }
70178
- function findContainingCompositionId(tag, ranges) {
70179
- let match = null;
70180
- for (const range of ranges) {
70181
- if (tag.index < range.start || tag.index >= range.end) continue;
70182
- if (!match || range.start >= match.start) match = range;
70183
- }
70184
- return match?.id || null;
70185
- }
70186
70148
  function getClipTagClasses(tag) {
70187
70149
  const classAttr = readAttr(tag.raw, "class") || "";
70188
70150
  const classes = classAttr.split(/\s+/).filter(Boolean);
70189
70151
  return classes.includes("clip") ? { classAttr, classes } : null;
70190
70152
  }
70191
- function collectClipStartBoundariesByComposition(source, tags) {
70192
- const ranges = collectCompositionRanges(source, tags);
70193
- const boundaries = /* @__PURE__ */ new Map();
70194
- for (const tag of tags) {
70195
- if (!getClipTagClasses(tag)) continue;
70196
- const compositionId = findContainingCompositionId(tag, ranges);
70197
- if (!compositionId) continue;
70198
- const start = numberValue(readAttr(tag.raw, "data-start") ?? void 0);
70199
- if (start == null || start <= 0) continue;
70200
- const compositionBoundaries = boundaries.get(compositionId) ?? /* @__PURE__ */ new Set();
70201
- compositionBoundaries.add(start);
70202
- boundaries.set(compositionId, compositionBoundaries);
70203
- }
70204
- return new Map(
70205
- [...boundaries.entries()].map(([compositionId, values]) => [
70206
- compositionId,
70207
- [...values].sort((a, b) => a - b)
70208
- ])
70209
- );
70210
- }
70211
- function findMatchingSceneBoundary(time, boundaries) {
70212
- for (const boundary of boundaries) {
70213
- if (Math.abs(time - boundary) <= SCENE_BOUNDARY_EPSILON_SECONDS) return boundary;
70214
- }
70215
- return null;
70216
- }
70217
70153
  function readStyleProperty(style, property) {
70218
70154
  const escapedProperty = property.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
70219
70155
  const match = style.match(new RegExp(`(?:^|;)\\s*${escapedProperty}\\s*:\\s*([^;]+)`, "i"));
@@ -72548,7 +72484,7 @@ ${allInlineStyles}`.replace(/\/\*[\s\S]*?\*\//g, "");
72548
72484
  },
72549
72485
  // overlapping_gsap_tweens + gsap_animates_clip_element
72550
72486
  // fallow-ignore-next-line complexity
72551
- async ({ source, tags, scripts, styles, rootCompositionId }) => {
72487
+ async ({ tags, scripts, styles }) => {
72552
72488
  const findings = [];
72553
72489
  const authoredHiddenSelectors = new Set(
72554
72490
  scripts.flatMap((script) => [...extractStandaloneHiddenSelectors(script.content)])
@@ -72569,13 +72505,10 @@ ${allInlineStyles}`.replace(/\/\*[\s\S]*?\*\//g, "");
72569
72505
  if (cls !== "clip") clipClasses.set(`.${cls}`, info);
72570
72506
  }
72571
72507
  }
72572
- const clipStartBoundariesByComposition = collectClipStartBoundariesByComposition(source, tags);
72573
72508
  const styleRules = collectSimpleStyleRules(styles);
72574
72509
  const reportedVisibleOverlayKeys = /* @__PURE__ */ new Set();
72575
72510
  for (const script of scripts) {
72576
- const localTimelineCompId = readRegisteredTimelineCompositionId(script.content);
72577
72511
  const gsapWindows = await cachedExtractGsapWindows(script.content);
72578
- const clipStartBoundaries = clipStartBoundariesByComposition.get(localTimelineCompId || rootCompositionId || "") ?? [];
72579
72512
  for (let i = 0; i < gsapWindows.length; i++) {
72580
72513
  const left = gsapWindows[i];
72581
72514
  if (!left) continue;
@@ -72637,28 +72570,6 @@ ${right.raw}`)
72637
72570
  snippet: truncateSnippet(fromToWindows.map((win) => win.raw).join("\n"))
72638
72571
  });
72639
72572
  }
72640
- if (clipStartBoundaries.length > 0) {
72641
- for (const win of gsapWindows) {
72642
- if (win.targetSelector === UNRESOLVED_TARGET) continue;
72643
- if (!isSceneBoundaryExit(win)) continue;
72644
- const boundary = findMatchingSceneBoundary(win.end, clipStartBoundaries);
72645
- if (boundary == null) continue;
72646
- const hasHardKill = gsapWindows.some(
72647
- (candidate) => isHardKillSet(candidate, win.targetSelector, boundary)
72648
- );
72649
- if (hasHardKill) continue;
72650
- const exitClipInfo = clipIds.get(win.targetSelector) || clipClasses.get(win.targetSelector);
72651
- const fixHint = exitClipInfo ? `"${win.targetSelector}" is a clip element \u2014 the framework already manages its visibility. Wrap the scene's content in an inner non-clip <div>, move the exit tween and the hard kill (\`tl.set("<inner-selector>", ${hiddenStateLiteral(win.propertyValues)}, ${boundary.toFixed(2)})\`) onto that wrapper instead.` : `Add \`tl.set("${win.targetSelector}", ${hiddenStateLiteral(win.propertyValues)}, ${boundary.toFixed(2)})\` after the exit tween.`;
72652
- findings.push({
72653
- code: "gsap_exit_missing_hard_kill",
72654
- severity: "error",
72655
- message: `GSAP exit on "${win.targetSelector}" ends at the ${boundary.toFixed(2)}s clip start boundary without a matching tl.set hard kill. Non-linear seeking can land after the fade and leave stale visibility state.`,
72656
- selector: win.targetSelector,
72657
- fixHint,
72658
- snippet: truncateSnippet(win.raw)
72659
- });
72660
- }
72661
- }
72662
72573
  for (const tag of tags) {
72663
72574
  const selectors = tagSimpleSelectors(tag);
72664
72575
  if (selectors.length === 0) continue;
@@ -99656,8 +99567,8 @@ async function runFontLocalize(io, localize) {
99656
99567
  }
99657
99568
 
99658
99569
  // src/version.ts
99659
- var VERSION = true ? "0.8.37" : "0.0.0-dev";
99660
- var PRODUCER_VERSION = true ? "0.8.37" : "0.0.0-dev";
99570
+ var VERSION = true ? "0.8.38" : "0.0.0-dev";
99571
+ var PRODUCER_VERSION = true ? "0.8.38" : "0.0.0-dev";
99661
99572
 
99662
99573
  // src/fontLocalizeCli.ts
99663
99574
  async function readStdin() {
@@ -1,4 +1,4 @@
1
- "use strict";var HyperframesPlayer=(()=>{var ee=Object.defineProperty;var et=Object.getOwnPropertyDescriptor;var tt=Object.getOwnPropertyNames;var it=Object.prototype.hasOwnProperty;var rt=(r,e)=>{for(var t in e)ee(r,t,{get:e[t],enumerable:!0})},nt=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of tt(e))!it.call(r,n)&&n!==t&&ee(r,n,{get:()=>e[n],enumerable:!(i=et(e,n))||i.enumerable});return r};var ot=r=>nt(ee({},"__esModule",{value:!0}),r);var Ht={};rt(Ht,{HyperframesPlayer:()=>K,SPEED_PRESETS:()=>re,formatSpeed:()=>O,formatTime:()=>q});function we(r){return r.hasRuntime||r.runtimeInjected?!1:!!(r.hasNestedCompositions||r.hasTimelines&&r.attempts>=5)}function P(r){return typeof r=="object"&&r!==null}function Ae(r){return P(r)&&typeof r.getDuration=="function"}function Ce(r){return P(r)&&typeof r.duration=="function"&&typeof r.time=="function"&&typeof r.seek=="function"&&typeof r.play=="function"&&typeof r.pause=="function"}var k="https://cdn.jsdelivr.net/npm/@hyperframes/core@0.8.37/dist/hyperframe.runtime.iife.js";function N(r){if(r===null)return null;let e=Number.parseInt(r,10);return Number.isFinite(e)&&e>0?e:null}function at(r){let e=r?.querySelector("[data-composition-id][data-width][data-height]")??r?.querySelector("[data-width][data-height]");if(!e)return null;let t=N(e.getAttribute("data-width")),i=N(e.getAttribute("data-height"));return t!==null&&i!==null?{width:t,height:i}:null}var W=class{constructor(e,t){this._iframe=e;this._callbacks=t}_iframe;_callbacks;_interval=null;_runtimeInjected=!1;get runtimeInjected(){return this._runtimeInjected}start(){this.stop(),this._runtimeInjected=!1;let e=0;this._interval=setInterval(()=>{e++;try{let t=this._iframe.contentWindow;if(!t)return;let i=!!(t.__hf||t.__player),n=!!(t.__timelines&&Object.keys(t.__timelines).length>0),o=!!this._iframe.contentDocument?.querySelector("[data-composition-src]");if(we({hasRuntime:i,hasTimelines:n,hasNestedCompositions:o,runtimeInjected:this._runtimeInjected,attempts:e})){this._injectRuntime();return}if(this._runtimeInjected&&!i)return;let d=this._resolvePlaybackDurationAdapter(t);if(d&&d.getDuration()>0){this.stop();let s=at(this._iframe.contentDocument);this._callbacks.onReady({duration:d.getDuration(),adapter:d,compositionSize:s});return}}catch{}e>=40&&(this.stop(),this._callbacks.onError("Composition timeline not found after 8s"))},200)}stop(){this._interval!==null&&(clearInterval(this._interval),this._interval=null)}resolveDirectTimelineAdapter(){try{let e=this._iframe.contentWindow;return e?this._resolveDirectTimelineAdapterFromWindow(e):null}catch{return null}}resolveDirectTimelineAdapterFromWindow(e){return this._resolveDirectTimelineAdapterFromWindow(e)}hasRuntimeBridge(e){return Reflect.get(e,"__hf")!==void 0||P(Reflect.get(e,"__player"))}_injectRuntime(){this._runtimeInjected=!0;try{let e=this._iframe.contentDocument;if(!e)return;let t=e.createElement("script");t.src=k,(e.head||e.documentElement).appendChild(t),this._callbacks.onRuntimeInjected?.()}catch{}}_resolveDirectTimelineAdapterFromWindow(e){if(this.hasRuntimeBridge(e))return null;let t=Reflect.get(e,"__timelines");if(!P(t))return null;let i=Object.keys(t);if(i.length===0)return null;let n=this._iframe.contentDocument?.querySelector("[data-composition-id]")?.getAttribute("data-composition-id"),o=n&&n in t?n:i[i.length-1],d=t[o];return Ce(d)?d:null}_resolvePlaybackDurationAdapter(e){let t=Reflect.get(e,"__player");if(Ae(t))return{kind:"runtime",getDuration:()=>t.getDuration()};let i=this._resolveDirectTimelineAdapterFromWindow(e);return i?{kind:"direct-timeline",timeline:i,getDuration:()=>i.duration()}:null}};var Re=`
1
+ "use strict";var HyperframesPlayer=(()=>{var ee=Object.defineProperty;var et=Object.getOwnPropertyDescriptor;var tt=Object.getOwnPropertyNames;var it=Object.prototype.hasOwnProperty;var rt=(r,e)=>{for(var t in e)ee(r,t,{get:e[t],enumerable:!0})},nt=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of tt(e))!it.call(r,n)&&n!==t&&ee(r,n,{get:()=>e[n],enumerable:!(i=et(e,n))||i.enumerable});return r};var ot=r=>nt(ee({},"__esModule",{value:!0}),r);var Ht={};rt(Ht,{HyperframesPlayer:()=>K,SPEED_PRESETS:()=>re,formatSpeed:()=>O,formatTime:()=>q});function we(r){return r.hasRuntime||r.runtimeInjected?!1:!!(r.hasNestedCompositions||r.hasTimelines&&r.attempts>=5)}function P(r){return typeof r=="object"&&r!==null}function Ae(r){return P(r)&&typeof r.getDuration=="function"}function Ce(r){return P(r)&&typeof r.duration=="function"&&typeof r.time=="function"&&typeof r.seek=="function"&&typeof r.play=="function"&&typeof r.pause=="function"}var k="https://cdn.jsdelivr.net/npm/@hyperframes/core@0.8.38/dist/hyperframe.runtime.iife.js";function N(r){if(r===null)return null;let e=Number.parseInt(r,10);return Number.isFinite(e)&&e>0?e:null}function at(r){let e=r?.querySelector("[data-composition-id][data-width][data-height]")??r?.querySelector("[data-width][data-height]");if(!e)return null;let t=N(e.getAttribute("data-width")),i=N(e.getAttribute("data-height"));return t!==null&&i!==null?{width:t,height:i}:null}var W=class{constructor(e,t){this._iframe=e;this._callbacks=t}_iframe;_callbacks;_interval=null;_runtimeInjected=!1;get runtimeInjected(){return this._runtimeInjected}start(){this.stop(),this._runtimeInjected=!1;let e=0;this._interval=setInterval(()=>{e++;try{let t=this._iframe.contentWindow;if(!t)return;let i=!!(t.__hf||t.__player),n=!!(t.__timelines&&Object.keys(t.__timelines).length>0),o=!!this._iframe.contentDocument?.querySelector("[data-composition-src]");if(we({hasRuntime:i,hasTimelines:n,hasNestedCompositions:o,runtimeInjected:this._runtimeInjected,attempts:e})){this._injectRuntime();return}if(this._runtimeInjected&&!i)return;let d=this._resolvePlaybackDurationAdapter(t);if(d&&d.getDuration()>0){this.stop();let s=at(this._iframe.contentDocument);this._callbacks.onReady({duration:d.getDuration(),adapter:d,compositionSize:s});return}}catch{}e>=40&&(this.stop(),this._callbacks.onError("Composition timeline not found after 8s"))},200)}stop(){this._interval!==null&&(clearInterval(this._interval),this._interval=null)}resolveDirectTimelineAdapter(){try{let e=this._iframe.contentWindow;return e?this._resolveDirectTimelineAdapterFromWindow(e):null}catch{return null}}resolveDirectTimelineAdapterFromWindow(e){return this._resolveDirectTimelineAdapterFromWindow(e)}hasRuntimeBridge(e){return Reflect.get(e,"__hf")!==void 0||P(Reflect.get(e,"__player"))}_injectRuntime(){this._runtimeInjected=!0;try{let e=this._iframe.contentDocument;if(!e)return;let t=e.createElement("script");t.src=k,(e.head||e.documentElement).appendChild(t),this._callbacks.onRuntimeInjected?.()}catch{}}_resolveDirectTimelineAdapterFromWindow(e){if(this.hasRuntimeBridge(e))return null;let t=Reflect.get(e,"__timelines");if(!P(t))return null;let i=Object.keys(t);if(i.length===0)return null;let n=this._iframe.contentDocument?.querySelector("[data-composition-id]")?.getAttribute("data-composition-id"),o=n&&n in t?n:i[i.length-1],d=t[o];return Ce(d)?d:null}_resolvePlaybackDurationAdapter(e){let t=Reflect.get(e,"__player");if(Ae(t))return{kind:"runtime",getDuration:()=>t.getDuration()};let i=this._resolveDirectTimelineAdapterFromWindow(e);return i?{kind:"direct-timeline",timeline:i,getDuration:()=>i.duration()}:null}};var Re=`
2
2
  :host {
3
3
  display: block;
4
4
  position: relative;