hyperframes 0.7.34 → 0.7.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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.7.34" : "0.0.0-dev";
53
+ VERSION = true ? "0.7.35" : "0.0.0-dev";
54
54
  }
55
55
  });
56
56
 
@@ -4891,7 +4891,7 @@ var require_util = __commonJS({
4891
4891
  return path2;
4892
4892
  }
4893
4893
  exports.normalize = normalize;
4894
- function join113(aRoot, aPath) {
4894
+ function join114(aRoot, aPath) {
4895
4895
  if (aRoot === "") {
4896
4896
  aRoot = ".";
4897
4897
  }
@@ -4923,7 +4923,7 @@ var require_util = __commonJS({
4923
4923
  }
4924
4924
  return joined;
4925
4925
  }
4926
- exports.join = join113;
4926
+ exports.join = join114;
4927
4927
  exports.isAbsolute = function(aPath) {
4928
4928
  return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
4929
4929
  };
@@ -5096,7 +5096,7 @@ var require_util = __commonJS({
5096
5096
  parsed.path = parsed.path.substring(0, index + 1);
5097
5097
  }
5098
5098
  }
5099
- sourceURL = join113(urlGenerate(parsed), sourceURL);
5099
+ sourceURL = join114(urlGenerate(parsed), sourceURL);
5100
5100
  }
5101
5101
  return normalize(sourceURL);
5102
5102
  }
@@ -62126,10 +62126,47 @@ var init_processTracker = __esm({
62126
62126
 
62127
62127
  // ../engine/src/utils/ffmpegBinaries.ts
62128
62128
  import { execFileSync } from "child_process";
62129
- import { existsSync as existsSync5 } from "fs";
62130
- import { resolve as resolve5 } from "path";
62129
+ import { accessSync, constants, existsSync as existsSync5 } from "fs";
62130
+ import { delimiter, join as join7, resolve as resolve5 } from "path";
62131
+ function candidateFileName(candidate) {
62132
+ return candidate.split(/[\\/]/).at(-1)?.toLowerCase() ?? candidate.toLowerCase();
62133
+ }
62134
+ function chooseBestPathCandidate(name, candidates) {
62135
+ const normalized = candidates.map((candidate) => candidate.trim()).filter(Boolean);
62136
+ return normalized.find((candidate) => candidateFileName(candidate) === `${name}.exe`) ?? normalized.find((candidate) => candidateFileName(candidate) === name) ?? normalized.find((candidate) => !candidateFileName(candidate).match(/\.(cmd|bat)$/i)) ?? normalized[0];
62137
+ }
62138
+ function scanPath(name) {
62139
+ const pathValue = process.env.PATH;
62140
+ if (!pathValue) return void 0;
62141
+ const extensions = process.platform === "win32" ? [
62142
+ ".exe",
62143
+ ...new Set(
62144
+ (process.env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").map((ext) => ext.trim().toLowerCase()).filter(Boolean)
62145
+ ),
62146
+ ""
62147
+ ] : [""];
62148
+ const candidates = [];
62149
+ for (const dir of pathValue.split(delimiter)) {
62150
+ if (!dir) continue;
62151
+ for (const ext of extensions) {
62152
+ const candidate = join7(dir, `${name}${ext}`);
62153
+ if (isExecutablePathCandidate(candidate)) candidates.push(candidate);
62154
+ }
62155
+ }
62156
+ return chooseBestPathCandidate(name, candidates);
62157
+ }
62158
+ function isExecutablePathCandidate(candidate) {
62159
+ if (process.platform === "win32") return existsSync5(candidate);
62160
+ try {
62161
+ accessSync(candidate, constants.X_OK);
62162
+ return true;
62163
+ } catch {
62164
+ return false;
62165
+ }
62166
+ }
62131
62167
  function findOnPath(name) {
62132
62168
  if (pathCache.has(name)) return pathCache.get(name);
62169
+ let found;
62133
62170
  try {
62134
62171
  const command2 = process.platform === "win32" ? "where" : "which";
62135
62172
  const output = execFileSync(command2, [name], {
@@ -62137,14 +62174,13 @@ function findOnPath(name) {
62137
62174
  stdio: ["pipe", "pipe", "pipe"],
62138
62175
  timeout: 5e3
62139
62176
  });
62140
- const first = output.split(/\r?\n/).map((s2) => s2.trim()).find(Boolean);
62141
- const resolved = first ? resolve5(first) : void 0;
62142
- pathCache.set(name, resolved);
62143
- return resolved;
62177
+ found = chooseBestPathCandidate(name, output.split(/\r?\n/));
62144
62178
  } catch {
62145
- pathCache.set(name, void 0);
62146
- return void 0;
62179
+ found = scanPath(name);
62147
62180
  }
62181
+ const resolved = found ? resolve5(found) : void 0;
62182
+ pathCache.set(name, resolved);
62183
+ return resolved;
62148
62184
  }
62149
62185
  function getConfiguredBinary(envName, binaryName) {
62150
62186
  const configured = process.env[envName]?.trim();
@@ -62161,16 +62197,20 @@ function assertConfiguredFfmpegBinariesExist() {
62161
62197
  const ffmpegPath = process.env[FFMPEG_PATH_ENV]?.trim();
62162
62198
  if (ffmpegPath && !existsSync5(ffmpegPath)) {
62163
62199
  throw new Error(
62164
- `[FFmpeg] FFmpeg binary not found at ${FFMPEG_PATH_ENV}="${ffmpegPath}". Install FFmpeg or unset the override.`
62200
+ `[FFmpeg] FFmpeg binary not found at ${FFMPEG_PATH_ENV}="${ffmpegPath}". Install FFmpeg or unset the override.${pathEncodingHint(ffmpegPath)}`
62165
62201
  );
62166
62202
  }
62167
62203
  const ffprobePath = process.env[FFPROBE_PATH_ENV]?.trim();
62168
62204
  if (ffprobePath && !existsSync5(ffprobePath)) {
62169
62205
  throw new Error(
62170
- `[FFmpeg] FFprobe binary not found at ${FFPROBE_PATH_ENV}="${ffprobePath}". Install FFmpeg or unset the override.`
62206
+ `[FFmpeg] FFprobe binary not found at ${FFPROBE_PATH_ENV}="${ffprobePath}". Install FFmpeg or unset the override.${pathEncodingHint(ffprobePath)}`
62171
62207
  );
62172
62208
  }
62173
62209
  }
62210
+ function pathEncodingHint(configuredPath) {
62211
+ if (!configuredPath.includes("\uFFFD")) return "";
62212
+ return " The path contains a Unicode replacement character, which usually means it was mangled while being copied or decoded.";
62213
+ }
62174
62214
  var FFMPEG_PATH_ENV, FFPROBE_PATH_ENV, pathCache;
62175
62215
  var init_ffmpegBinaries = __esm({
62176
62216
  "../engine/src/utils/ffmpegBinaries.ts"() {
@@ -62820,7 +62860,7 @@ var init_ffprobe = __esm({
62820
62860
  // ../engine/src/services/chunkEncoder.ts
62821
62861
  import { spawn as spawn4 } from "child_process";
62822
62862
  import { copyFileSync, existsSync as existsSync6, mkdirSync as mkdirSync3, readdirSync as readdirSync2, statSync, writeFileSync as writeFileSync3 } from "fs";
62823
- import { join as join7, dirname as dirname4, extname as extname2 } from "path";
62863
+ import { join as join8, dirname as dirname4, extname as extname2 } from "path";
62824
62864
  function appendEncodeTimeoutMessage(error, timedOut, timeoutMs) {
62825
62865
  if (!timedOut) return error;
62826
62866
  return `${error}
@@ -63067,7 +63107,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
63067
63107
  if (options.useGpu) {
63068
63108
  gpuEncoder = await getCachedGpuEncoder();
63069
63109
  }
63070
- const inputPath = join7(framesDir, framePattern);
63110
+ const inputPath = join8(framesDir, framePattern);
63071
63111
  const inputArgs = ["-framerate", fpsToFfmpegArg(options.fps), "-i", inputPath];
63072
63112
  const args = buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder);
63073
63113
  return new Promise((resolve62) => {
@@ -63155,7 +63195,7 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
63155
63195
  }
63156
63196
  const chunkSize = Math.max(30, Math.floor(chunkSizeFrames));
63157
63197
  const chunkCount = Math.ceil(files.length / chunkSize);
63158
- const chunkDir = join7(dirname4(outputPath), "chunk-encode");
63198
+ const chunkDir = join8(dirname4(outputPath), "chunk-encode");
63159
63199
  if (!existsSync6(chunkDir)) mkdirSync3(chunkDir, { recursive: true });
63160
63200
  const chunkPaths = [];
63161
63201
  for (let i2 = 0; i2 < chunkCount; i2++) {
@@ -63172,8 +63212,8 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
63172
63212
  const startNumber = i2 * chunkSize;
63173
63213
  const framesInChunk = Math.min(chunkSize, files.length - startNumber);
63174
63214
  const ext = outputPath.endsWith(".webm") ? ".webm" : outputPath.endsWith(".mov") ? ".mov" : ".mp4";
63175
- const chunkPath = join7(chunkDir, `chunk_${String(i2).padStart(4, "0")}${ext}`);
63176
- const inputPath = join7(framesDir, framePattern);
63215
+ const chunkPath = join8(chunkDir, `chunk_${String(i2).padStart(4, "0")}${ext}`);
63216
+ const inputPath = join8(framesDir, framePattern);
63177
63217
  const inputArgs = [
63178
63218
  "-framerate",
63179
63219
  fpsToFfmpegArg(options.fps),
@@ -63238,7 +63278,7 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
63238
63278
  }
63239
63279
  chunkPaths.push(chunkPath);
63240
63280
  }
63241
- const concatListPath = join7(chunkDir, "concat-list.txt");
63281
+ const concatListPath = join8(chunkDir, "concat-list.txt");
63242
63282
  const concatInput = chunkPaths.map((path2) => `file '${path2.replace(/'/g, "'\\''")}'`).join("\n");
63243
63283
  writeFileSync3(concatListPath, concatInput, "utf-8");
63244
63284
  const concatArgs = [
@@ -63786,7 +63826,7 @@ var init_streamingEncoder = __esm({
63786
63826
  // ../engine/src/utils/urlDownloader.ts
63787
63827
  import { createWriteStream, existsSync as existsSync8, mkdirSync as mkdirSync5 } from "fs";
63788
63828
  import { createHash } from "crypto";
63789
- import { join as join8, extname as extname3 } from "path";
63829
+ import { join as join9, extname as extname3 } from "path";
63790
63830
  import { Readable } from "stream";
63791
63831
  import { finished } from "stream/promises";
63792
63832
  function isBlockedHost(hostname) {
@@ -63838,7 +63878,7 @@ async function downloadToTemp(url, destDir, timeoutMs = 3e5) {
63838
63878
  mkdirSync5(destDir, { recursive: true });
63839
63879
  }
63840
63880
  const filename = getFilenameFromUrl(url);
63841
- const localPath = join8(destDir, filename);
63881
+ const localPath = join9(destDir, filename);
63842
63882
  if (existsSync8(localPath)) {
63843
63883
  downloadPathCache.set(url, localPath);
63844
63884
  return localPath;
@@ -66358,7 +66398,7 @@ __export(dist_exports2, {
66358
66398
  import postcss2 from "postcss";
66359
66399
  import postcss22 from "postcss";
66360
66400
  import { existsSync as existsSync9, readFileSync as readFileSync4, readdirSync as readdirSync3 } from "fs";
66361
- import { dirname as dirname6, extname as extname4, isAbsolute as isAbsolute2, join as join9, posix as posix2, relative as relative2, resolve as resolve7 } from "path";
66401
+ import { dirname as dirname6, extname as extname4, isAbsolute as isAbsolute2, join as join10, posix as posix2, relative as relative2, resolve as resolve7 } from "path";
66362
66402
  function extractOpenTags(source) {
66363
66403
  const tags = [];
66364
66404
  let match;
@@ -67669,7 +67709,7 @@ function collectExternalStyles(projectDir, html, compSrcPath) {
67669
67709
  if (!rel.split(/\s+/).some((part) => part.toLowerCase() === "stylesheet")) continue;
67670
67710
  const href = tag.match(/\bhref\s*=\s*["']([^"']+)["']/i)?.[1] ?? "";
67671
67711
  if (!isLocalStylesheetHref(href)) continue;
67672
- const rootRelative = compSrcPath ? join9(dirname6(compSrcPath), href) : href;
67712
+ const rootRelative = compSrcPath ? join10(dirname6(compSrcPath), href) : href;
67673
67713
  const stylesheet = resolveExistingLocalAsset(projectDir, rootRelative);
67674
67714
  if (!stylesheet) continue;
67675
67715
  styles.push({ href, content: readFileSync4(stylesheet.resolved, "utf-8") });
@@ -67691,7 +67731,7 @@ function collectCssSources(projectDir, html, compSrcPath) {
67691
67731
  if (!rel.split(/\s+/).some((part) => part.toLowerCase() === "stylesheet")) continue;
67692
67732
  const href = readHtmlAttr(tag, "href") ?? "";
67693
67733
  if (!isLocalStylesheetHref(href)) continue;
67694
- const rootRelativePath = compSrcPath ? join9(dirname6(compSrcPath), href) : href;
67734
+ const rootRelativePath = compSrcPath ? join10(dirname6(compSrcPath), href) : href;
67695
67735
  const stylesheet = resolveExistingLocalAsset(projectDir, rootRelativePath);
67696
67736
  if (!stylesheet) continue;
67697
67737
  sources.push({
@@ -67751,7 +67791,7 @@ function resolveExistingLocalAsset(projectDir, url) {
67751
67791
  function resolveCssAssetCandidates(projectDir, url, htmlCompSrcPath, cssRootRelativePath) {
67752
67792
  if (url.startsWith("/")) return resolveLocalAssetCandidates(projectDir, url);
67753
67793
  if (cssRootRelativePath) {
67754
- return resolveLocalAssetCandidates(projectDir, join9(dirname6(cssRootRelativePath), url));
67794
+ return resolveLocalAssetCandidates(projectDir, join10(dirname6(cssRootRelativePath), url));
67755
67795
  }
67756
67796
  if (htmlCompSrcPath) {
67757
67797
  return resolveLocalAssetCandidates(projectDir, rewriteAssetPath(htmlCompSrcPath, url));
@@ -67780,14 +67820,14 @@ async function lintProject(projectDir) {
67780
67820
  const out = [];
67781
67821
  for (const entry of readdirSync3(dir, { withFileTypes: true })) {
67782
67822
  const relPath = rel ? `${rel}/${entry.name}` : entry.name;
67783
- if (entry.isDirectory()) out.push(...collectHtmlFiles(join9(dir, entry.name), relPath));
67823
+ if (entry.isDirectory()) out.push(...collectHtmlFiles(join10(dir, entry.name), relPath));
67784
67824
  else if (entry.isFile() && entry.name.endsWith(".html")) out.push(relPath);
67785
67825
  }
67786
67826
  return out;
67787
67827
  };
67788
67828
  const files = collectHtmlFiles(compositionsDir, "").sort();
67789
67829
  for (const file of files) {
67790
- const filePath = join9(compositionsDir, file);
67830
+ const filePath = join10(compositionsDir, file);
67791
67831
  const html = readFileSync4(filePath, "utf-8");
67792
67832
  const compSrcPath = `compositions/${file}`;
67793
67833
  allHtmlSources.push({ html, compSrcPath });
@@ -67965,7 +68005,7 @@ function lintMultipleRootCompositions(projectDir) {
67965
68005
  const rootCompositions = [];
67966
68006
  for (const file of rootHtmlFiles) {
67967
68007
  if (file === "caption-skin.html") continue;
67968
- const content = readFileSync4(join9(projectDir, file), "utf-8");
68008
+ const content = readFileSync4(join10(projectDir, file), "utf-8");
67969
68009
  if (/data-composition-id/i.test(content)) {
67970
68010
  rootCompositions.push(file);
67971
68011
  }
@@ -70464,7 +70504,7 @@ var init_inlineSubCompositions = __esm({
70464
70504
 
70465
70505
  // ../core/dist/compiler/htmlBundler.js
70466
70506
  import { readFileSync as readFileSync5, existsSync as existsSync10 } from "fs";
70467
- import { join as join10, resolve as resolve8, relative as relative3, dirname as dirname7, isAbsolute as isAbsolute3, sep as sep2 } from "path";
70507
+ import { join as join11, resolve as resolve8, relative as relative3, dirname as dirname7, isAbsolute as isAbsolute3, sep as sep2 } from "path";
70468
70508
  import { transformSync } from "esbuild";
70469
70509
  function getRuntimeScriptUrl() {
70470
70510
  const configured = (process.env.HYPERFRAME_RUNTIME_URL || "").trim();
@@ -70978,7 +71018,7 @@ function hoistCompositionScripts(container, opts) {
70978
71018
  }
70979
71019
  }
70980
71020
  async function bundleToSingleHtml(projectDir, options) {
70981
- const indexPath2 = join10(projectDir, "index.html");
71021
+ const indexPath2 = join11(projectDir, "index.html");
70982
71022
  if (!existsSync10(indexPath2))
70983
71023
  throw new Error("index.html not found in project directory");
70984
71024
  const rawHtml = readFileSync5(indexPath2, "utf-8");
@@ -71366,7 +71406,7 @@ import {
71366
71406
  utimesSync,
71367
71407
  writeFileSync as writeFileSync4
71368
71408
  } from "fs";
71369
- import { join as join11 } from "path";
71409
+ import { join as join12 } from "path";
71370
71410
  function readKeyStat(videoPath) {
71371
71411
  try {
71372
71412
  const stat3 = statSync3(videoPath);
@@ -71397,8 +71437,8 @@ function cacheEntryDirName(keyHash) {
71397
71437
  }
71398
71438
  function lookupCacheEntry(rootDir, input2) {
71399
71439
  const keyHash = computeCacheKey(input2);
71400
- const dir = join11(rootDir, cacheEntryDirName(keyHash));
71401
- const complete = existsSync11(join11(dir, COMPLETE_SENTINEL));
71440
+ const dir = join12(rootDir, cacheEntryDirName(keyHash));
71441
+ const complete = existsSync11(join12(dir, COMPLETE_SENTINEL));
71402
71442
  return { entry: { dir, keyHash }, hit: complete };
71403
71443
  }
71404
71444
  function partialCacheEntryDir(entry) {
@@ -71409,13 +71449,13 @@ function isTargetExistsRenameError(err) {
71409
71449
  return code === "EEXIST" || code === "ENOTEMPTY" || code === "EPERM";
71410
71450
  }
71411
71451
  function adoptPublishedWinner(entry, partialDir) {
71412
- if (!existsSync11(join11(entry.dir, COMPLETE_SENTINEL))) return null;
71452
+ if (!existsSync11(join12(entry.dir, COMPLETE_SENTINEL))) return null;
71413
71453
  removeDir(partialDir);
71414
71454
  return { dir: entry.dir, published: true };
71415
71455
  }
71416
71456
  function publishCacheEntry(entry, partialDir) {
71417
71457
  try {
71418
- writeFileSync4(join11(partialDir, COMPLETE_SENTINEL), "", "utf-8");
71458
+ writeFileSync4(join12(partialDir, COMPLETE_SENTINEL), "", "utf-8");
71419
71459
  } catch {
71420
71460
  return { dir: partialDir, published: false };
71421
71461
  }
@@ -71442,7 +71482,7 @@ function publishCacheEntry(entry, partialDir) {
71442
71482
  function touchCacheEntry(entry) {
71443
71483
  try {
71444
71484
  const now = /* @__PURE__ */ new Date();
71445
- utimesSync(join11(entry.dir, COMPLETE_SENTINEL), now, now);
71485
+ utimesSync(join12(entry.dir, COMPLETE_SENTINEL), now, now);
71446
71486
  } catch {
71447
71487
  }
71448
71488
  }
@@ -71467,7 +71507,7 @@ function directorySizeBytes(path2) {
71467
71507
  return 0;
71468
71508
  }
71469
71509
  for (const child of children) {
71470
- const childPath = join11(path2, child);
71510
+ const childPath = join12(path2, child);
71471
71511
  try {
71472
71512
  const stat3 = lstatSync(childPath);
71473
71513
  if (stat3.isDirectory()) {
@@ -71496,7 +71536,7 @@ function collectGcEntry(dir, name, now, minAgeMs, stats) {
71496
71536
  }
71497
71537
  let lastUseMs = dirStat.mtimeMs;
71498
71538
  try {
71499
- lastUseMs = statSync3(join11(dir, COMPLETE_SENTINEL)).mtimeMs;
71539
+ lastUseMs = statSync3(join12(dir, COMPLETE_SENTINEL)).mtimeMs;
71500
71540
  } catch {
71501
71541
  }
71502
71542
  return { dir, size: directorySizeBytes(dir), lastUseMs, ageMs: now - lastUseMs };
@@ -71506,7 +71546,7 @@ function collectGcEntry(dir, name, now, minAgeMs, stats) {
71506
71546
  }
71507
71547
  function gcSweepDue(rootDir, maxAgeMs) {
71508
71548
  try {
71509
- return Date.now() - statSync3(join11(rootDir, GC_MARKER)).mtimeMs > maxAgeMs;
71549
+ return Date.now() - statSync3(join12(rootDir, GC_MARKER)).mtimeMs > maxAgeMs;
71510
71550
  } catch {
71511
71551
  return true;
71512
71552
  }
@@ -71514,7 +71554,7 @@ function gcSweepDue(rootDir, maxAgeMs) {
71514
71554
  function gcExtractionCache(rootDir, opts) {
71515
71555
  const stats = { evictedEntries: 0, evictedBytes: 0, agedPartialsRemoved: 0 };
71516
71556
  try {
71517
- writeFileSync4(join11(rootDir, GC_MARKER), "", "utf-8");
71557
+ writeFileSync4(join12(rootDir, GC_MARKER), "", "utf-8");
71518
71558
  } catch {
71519
71559
  }
71520
71560
  try {
@@ -71523,7 +71563,7 @@ function gcExtractionCache(rootDir, opts) {
71523
71563
  for (const child of readdirSync4(rootDir, { withFileTypes: true })) {
71524
71564
  if (!child.isDirectory() || !isCacheLikeChild(child.name)) continue;
71525
71565
  const entry = collectGcEntry(
71526
- join11(rootDir, child.name),
71566
+ join12(rootDir, child.name),
71527
71567
  child.name,
71528
71568
  now,
71529
71569
  opts.minAgeMs,
@@ -71552,7 +71592,7 @@ function rehydrateCacheEntry(entry, options) {
71552
71592
  const suffix = `.${options.format}`;
71553
71593
  const files = readdirSync4(entry.dir).filter((f3) => f3.startsWith(FRAME_FILENAME_PREFIX) && f3.endsWith(suffix)).sort();
71554
71594
  files.forEach((file, idx) => {
71555
- framePaths.set(idx, join11(entry.dir, file));
71595
+ framePaths.set(idx, join12(entry.dir, file));
71556
71596
  });
71557
71597
  return {
71558
71598
  videoId: options.videoId,
@@ -71581,7 +71621,7 @@ var init_extractionCache = __esm({
71581
71621
  // ../engine/src/services/videoFrameExtractor.ts
71582
71622
  import { spawn as spawn6 } from "child_process";
71583
71623
  import { copyFileSync as copyFileSync2, existsSync as existsSync12, linkSync, mkdirSync as mkdirSync7, readdirSync as readdirSync5, rmSync as rmSync2 } from "fs";
71584
- import { isAbsolute as isAbsolute4, join as join12, posix as posix3, resolve as resolve9, sep as sep3 } from "path";
71624
+ import { isAbsolute as isAbsolute4, join as join13, posix as posix3, resolve as resolve9, sep as sep3 } from "path";
71585
71625
  function isVideoFrameFormat(value) {
71586
71626
  return typeof value === "string" && VIDEO_FRAME_FORMATS.includes(value);
71587
71627
  }
@@ -71657,12 +71697,12 @@ function parseImageElements(html) {
71657
71697
  async function extractVideoFramesRange(videoPath, videoId, startTime, duration, options, signal, config, outputDirOverride) {
71658
71698
  const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
71659
71699
  const { fps, outputDir, quality = 95 } = options;
71660
- const videoOutputDir = outputDirOverride ?? join12(outputDir, videoId);
71700
+ const videoOutputDir = outputDirOverride ?? join13(outputDir, videoId);
71661
71701
  if (!existsSync12(videoOutputDir)) mkdirSync7(videoOutputDir, { recursive: true });
71662
71702
  const metadata = await extractMediaMetadata(videoPath);
71663
71703
  const format = resolveFrameFormat(metadata, options.format);
71664
71704
  const framePattern = `${FRAME_FILENAME_PREFIX}%05d.${format}`;
71665
- const outputPattern = join12(videoOutputDir, framePattern);
71705
+ const outputPattern = join13(videoOutputDir, framePattern);
71666
71706
  const isHdr = isHdrColorSpace(metadata.colorSpace);
71667
71707
  const isMacOS = process.platform === "darwin";
71668
71708
  const args = [];
@@ -71723,7 +71763,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
71723
71763
  const framePaths = /* @__PURE__ */ new Map();
71724
71764
  const files = readdirSync5(videoOutputDir).filter((f3) => f3.startsWith(FRAME_FILENAME_PREFIX) && f3.endsWith(`.${format}`)).sort();
71725
71765
  files.forEach((file, index) => {
71726
- framePaths.set(index, join12(videoOutputDir, file));
71766
+ framePaths.set(index, join13(videoOutputDir, file));
71727
71767
  });
71728
71768
  resolve62({
71729
71769
  videoId,
@@ -71774,7 +71814,7 @@ function extractedFramesFromDirectory(work, outputDir, srcPath, fps) {
71774
71814
  const framePattern = `${FRAME_FILENAME_PREFIX}%05d.${work.format}`;
71775
71815
  const framePaths = /* @__PURE__ */ new Map();
71776
71816
  extractedFrameFileNames(outputDir, work.format).forEach((file, index) => {
71777
- framePaths.set(index, join12(outputDir, file));
71817
+ framePaths.set(index, join13(outputDir, file));
71778
71818
  });
71779
71819
  return {
71780
71820
  videoId: work.video.id,
@@ -71883,7 +71923,7 @@ function sliceSupersetMember(member, superset, outputDir, fps) {
71883
71923
  for (let i2 = 0; i2 < frameCount; i2 += 1) {
71884
71924
  const sourceFrame = superset.framePaths.get(member.offsetFrames + i2);
71885
71925
  if (!sourceFrame) throw new Error(`superset frame ${member.offsetFrames + i2} missing`);
71886
- linkOrCopyFrame(sourceFrame, join12(outputDir, frameFileName(i2 + 1, work.format)));
71926
+ linkOrCopyFrame(sourceFrame, join13(outputDir, frameFileName(i2 + 1, work.format)));
71887
71927
  }
71888
71928
  return extractedFramesFromDirectory(work, outputDir, work.videoPath, fps);
71889
71929
  }
@@ -71895,22 +71935,22 @@ function resolveProjectRelativeSrc(src, baseDir, compiledDir) {
71895
71935
  if (!candidates.includes(candidate)) candidates.push(candidate);
71896
71936
  };
71897
71937
  for (const variant of decodeUrlPathVariants(cleanSrc)) {
71898
- const fromCompiled = compiledDir ? join12(compiledDir, variant) : null;
71899
- const fromBase = join12(baseDir, variant);
71938
+ const fromCompiled = compiledDir ? join13(compiledDir, variant) : null;
71939
+ const fromBase = join13(baseDir, variant);
71900
71940
  const baseAbs = resolve9(baseDir);
71901
71941
  const fromBaseAbs = resolve9(fromBase);
71902
71942
  if (!fromBaseAbs.startsWith(baseAbs + sep3) && fromBaseAbs !== baseAbs) {
71903
71943
  const normalized = posix3.normalize(variant.replace(/\\/g, "/"));
71904
71944
  const stripped = normalized.replace(/^(\.\.\/)+/, "");
71905
71945
  if (stripped && stripped !== variant && !stripped.startsWith("..")) {
71906
- if (compiledDir) addCandidate2(join12(compiledDir, stripped));
71907
- addCandidate2(join12(baseDir, stripped));
71946
+ if (compiledDir) addCandidate2(join13(compiledDir, stripped));
71947
+ addCandidate2(join13(baseDir, stripped));
71908
71948
  }
71909
71949
  }
71910
71950
  if (fromCompiled) addCandidate2(fromCompiled);
71911
71951
  addCandidate2(fromBase);
71912
71952
  }
71913
- return candidates.find(existsSync12) ?? join12(baseDir, cleanSrc);
71953
+ return candidates.find(existsSync12) ?? join13(baseDir, cleanSrc);
71914
71954
  }
71915
71955
  async function extractAllVideoFrames(videos, baseDir, options, signal, config, compiledDir) {
71916
71956
  const startTime = Date.now();
@@ -71944,7 +71984,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
71944
71984
  videoPath = resolveProjectRelativeSrc(video.src, baseDir, compiledDir);
71945
71985
  }
71946
71986
  if (isHttpUrl(videoPath)) {
71947
- const downloadDir = join12(options.outputDir, "_downloads");
71987
+ const downloadDir = join13(options.outputDir, "_downloads");
71948
71988
  mkdirSync7(downloadDir, { recursive: true });
71949
71989
  videoPath = await downloadToTemp(videoPath, downloadDir);
71950
71990
  }
@@ -72138,7 +72178,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
72138
72178
  return sliceSupersetMember(
72139
72179
  member,
72140
72180
  superset,
72141
- join12(options.outputDir, work.video.id),
72181
+ join13(options.outputDir, work.video.id),
72142
72182
  options.fps
72143
72183
  );
72144
72184
  }
@@ -72154,7 +72194,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
72154
72194
  async function executeSupersetGroup(group) {
72155
72195
  const first = group.members[0]?.miss.work;
72156
72196
  if (!first) return [];
72157
- const tempDir = cacheRootDir ? join12(cacheRootDir, `${group.groupId}.partial-${process.pid}`) : join12(options.outputDir, group.groupId);
72197
+ const tempDir = cacheRootDir ? join13(cacheRootDir, `${group.groupId}.partial-${process.pid}`) : join13(options.outputDir, group.groupId);
72158
72198
  try {
72159
72199
  rmSync2(tempDir, { recursive: true, force: true });
72160
72200
  const superset = await extractVideoFramesRange(
@@ -72997,7 +73037,7 @@ var init_audioVolumeEnvelope = __esm({
72997
73037
 
72998
73038
  // ../engine/src/services/audioMixer.ts
72999
73039
  import { closeSync, existsSync as existsSync13, mkdirSync as mkdirSync8, mkdtempSync, openSync, rmSync as rmSync3, writeFileSync as writeFileSync6 } from "fs";
73000
- import { isAbsolute as isAbsolute5, join as join13, dirname as dirname8 } from "path";
73040
+ import { isAbsolute as isAbsolute5, join as join14, dirname as dirname8 } from "path";
73001
73041
  function clampVolume(volume) {
73002
73042
  if (!Number.isFinite(volume)) return 1;
73003
73043
  return Math.max(0, Math.min(1, volume));
@@ -73259,8 +73299,8 @@ async function mixAudioTracks(tracks, outputPath, totalDuration, signal, config)
73259
73299
  const runMix = (ignoreAutomation) => {
73260
73300
  const inputs = [];
73261
73301
  tracks.forEach((track) => inputs.push("-i", track.srcPath));
73262
- const scriptDir = mkdtempSync(join13(outputDir, ".filter-complex-"));
73263
- const scriptPath = join13(scriptDir, "graph.txt");
73302
+ const scriptDir = mkdtempSync(join14(outputDir, ".filter-complex-"));
73303
+ const scriptPath = join14(scriptDir, "graph.txt");
73264
73304
  const fd = openSync(scriptPath, "wx", 384);
73265
73305
  try {
73266
73306
  writeFileSync6(fd, buildFilterComplex(ignoreAutomation));
@@ -73359,7 +73399,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
73359
73399
  }
73360
73400
  let audioSrcPath = srcPath;
73361
73401
  if (element.type === "video") {
73362
- const extractedPath = join13(workDir, `${element.id}-extracted.wav`);
73402
+ const extractedPath = join14(workDir, `${element.id}-extracted.wav`);
73363
73403
  const extractResult = await extractAudioFromVideo(
73364
73404
  srcPath,
73365
73405
  extractedPath,
@@ -73376,7 +73416,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
73376
73416
  }
73377
73417
  audioSrcPath = extractedPath;
73378
73418
  } else {
73379
- const trimmedPath = join13(workDir, `${element.id}-trimmed.wav`);
73419
+ const trimmedPath = join14(workDir, `${element.id}-trimmed.wav`);
73380
73420
  const prepResult = await prepareAudioTrack(
73381
73421
  srcPath,
73382
73422
  trimmedPath,
@@ -73529,7 +73569,7 @@ var init_readWebGlVendorInfoFromCanvas = __esm({
73529
73569
  import { cpus, freemem } from "os";
73530
73570
  import { existsSync as existsSync14, mkdirSync as mkdirSync9, readdirSync as readdirSync6 } from "fs";
73531
73571
  import { copyFile, rename } from "fs/promises";
73532
- import { join as join14 } from "path";
73572
+ import { join as join15 } from "path";
73533
73573
  function defaultSafeMaxWorkers() {
73534
73574
  return Math.max(6, Math.min(16, Math.floor(cpus().length / 8)));
73535
73575
  }
@@ -73608,7 +73648,7 @@ function distributeFrames(totalFrames, workerCount, workDir, rangeStart = 0) {
73608
73648
  workerId: i2,
73609
73649
  startFrame,
73610
73650
  endFrame,
73611
- outputDir: join14(workDir, `worker-${i2}`),
73651
+ outputDir: join15(workDir, `worker-${i2}`),
73612
73652
  outputFrameOffset: rangeStart
73613
73653
  });
73614
73654
  }
@@ -73746,8 +73786,8 @@ async function mergeWorkerFrames(workDir, tasks, outputDir) {
73746
73786
  }
73747
73787
  const files = readdirSync6(task.outputDir).filter((f3) => f3.startsWith("frame_") && (f3.endsWith(".jpg") || f3.endsWith(".png"))).sort();
73748
73788
  const copyTasks = files.map(async (file) => {
73749
- const sourcePath = join14(task.outputDir, file);
73750
- const targetPath = join14(outputDir, file);
73789
+ const sourcePath = join15(task.outputDir, file);
73790
+ const targetPath = join15(outputDir, file);
73751
73791
  try {
73752
73792
  await rename(sourcePath, targetPath);
73753
73793
  } catch {
@@ -73789,7 +73829,7 @@ var init_parallelCoordinator = __esm({
73789
73829
  import { Hono } from "hono";
73790
73830
  import { serve } from "@hono/node-server";
73791
73831
  import { readFileSync as readFileSync7, existsSync as existsSync15, statSync as statSync4 } from "fs";
73792
- import { join as join15, extname as extname5 } from "path";
73832
+ import { join as join16, extname as extname5 } from "path";
73793
73833
  function createFileServer(options) {
73794
73834
  const { projectDir, compiledDir, port = 0, stripEmbeddedRuntime = true } = options;
73795
73835
  const headScripts = options.headScripts ?? [];
@@ -73799,11 +73839,11 @@ function createFileServer(options) {
73799
73839
  let requestPath = c3.req.path;
73800
73840
  if (requestPath === "/") requestPath = "/index.html";
73801
73841
  const relativePath = requestPath.replace(/^\//, "");
73802
- const compiledPath = compiledDir ? join15(compiledDir, relativePath) : null;
73842
+ const compiledPath = compiledDir ? join16(compiledDir, relativePath) : null;
73803
73843
  const hasCompiledFile = Boolean(
73804
73844
  compiledPath && existsSync15(compiledPath) && statSync4(compiledPath).isFile()
73805
73845
  );
73806
- const filePath = hasCompiledFile ? compiledPath : join15(projectDir, relativePath);
73846
+ const filePath = hasCompiledFile ? compiledPath : join16(projectDir, relativePath);
73807
73847
  if (!existsSync15(filePath) || !statSync4(filePath).isFile()) {
73808
73848
  return c3.text("Not found", 404);
73809
73849
  }
@@ -75118,7 +75158,7 @@ var init_shaderTransitions = __esm({
75118
75158
 
75119
75159
  // ../engine/src/services/hdrCapture.ts
75120
75160
  import { existsSync as existsSync16, readdirSync as readdirSync7 } from "fs";
75121
- import { join as join16 } from "path";
75161
+ import { join as join17 } from "path";
75122
75162
  import { homedir as homedir3 } from "os";
75123
75163
  function linearToPQ(L2) {
75124
75164
  const Lp = Math.max(0, L2 * SDR_NITS / PQ_MAX_NITS);
@@ -75234,12 +75274,12 @@ function float16ToPqRgb(rawBuffer, bytesPerRow, width, height) {
75234
75274
  return output;
75235
75275
  }
75236
75276
  function resolveHeadedChromePath() {
75237
- const baseDir = join16(homedir3(), ".cache", "puppeteer", "chrome");
75277
+ const baseDir = join17(homedir3(), ".cache", "puppeteer", "chrome");
75238
75278
  if (!existsSync16(baseDir)) return void 0;
75239
75279
  const versions = readdirSync7(baseDir).sort().reverse();
75240
75280
  for (const version2 of versions) {
75241
75281
  const candidates = [
75242
- join16(
75282
+ join17(
75243
75283
  baseDir,
75244
75284
  version2,
75245
75285
  "chrome-mac-arm64",
@@ -75248,7 +75288,7 @@ function resolveHeadedChromePath() {
75248
75288
  "MacOS",
75249
75289
  "Google Chrome for Testing"
75250
75290
  ),
75251
- join16(
75291
+ join17(
75252
75292
  baseDir,
75253
75293
  version2,
75254
75294
  "chrome-mac-x64",
@@ -75257,8 +75297,8 @@ function resolveHeadedChromePath() {
75257
75297
  "MacOS",
75258
75298
  "Google Chrome for Testing"
75259
75299
  ),
75260
- join16(baseDir, version2, "chrome-linux64", "chrome"),
75261
- join16(baseDir, version2, "chrome-win64", "chrome.exe")
75300
+ join17(baseDir, version2, "chrome-linux64", "chrome"),
75301
+ join17(baseDir, version2, "chrome-win64", "chrome.exe")
75262
75302
  ];
75263
75303
  for (const binary of candidates) {
75264
75304
  if (existsSync16(binary)) return binary;
@@ -78344,11 +78384,11 @@ var init_banner = __esm({
78344
78384
 
78345
78385
  // src/registry/remote.ts
78346
78386
  import { mkdirSync as mkdirSync10, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "fs";
78347
- import { join as join17, dirname as dirname9 } from "path";
78387
+ import { join as join18, dirname as dirname9 } from "path";
78348
78388
  import { homedir as homedir4 } from "os";
78349
78389
  function cachePath(baseUrl, key2) {
78350
78390
  const slug = baseUrl.replace(/[^a-zA-Z0-9]/g, "_");
78351
- return join17(CACHE_DIR, `${slug}__${key2}.json`);
78391
+ return join18(CACHE_DIR, `${slug}__${key2}.json`);
78352
78392
  }
78353
78393
  function readCache(path2) {
78354
78394
  try {
@@ -78419,7 +78459,7 @@ var init_remote = __esm({
78419
78459
  init_dist3();
78420
78460
  DEFAULT_REGISTRY_URL = "https://raw.githubusercontent.com/heygen-com/hyperframes/main/registry";
78421
78461
  FETCH_TIMEOUT_MS = 1e4;
78422
- CACHE_DIR = join17(homedir4(), ".hyperframes", "cache");
78462
+ CACHE_DIR = join18(homedir4(), ".hyperframes", "cache");
78423
78463
  CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
78424
78464
  }
78425
78465
  });
@@ -78697,7 +78737,7 @@ var init_compatibility = __esm({
78697
78737
 
78698
78738
  // src/templates/remote.ts
78699
78739
  import { existsSync as existsSync19 } from "fs";
78700
- import { join as join18 } from "path";
78740
+ import { join as join19 } from "path";
78701
78741
  async function fetchRemoteTemplate(templateId, destDir) {
78702
78742
  const items = await resolveItemWithDependencies(templateId);
78703
78743
  const warnings = gateRegistryItemsCompatibility(items);
@@ -78708,7 +78748,7 @@ async function fetchRemoteTemplate(templateId, destDir) {
78708
78748
  for (const item of items) {
78709
78749
  await installItem(item, { destDir });
78710
78750
  }
78711
- if (!existsSync19(join18(destDir, "index.html"))) {
78751
+ if (!existsSync19(join19(destDir, "index.html"))) {
78712
78752
  throw new Error(
78713
78753
  `Example "${templateId}" installed but missing index.html. The registry item may be malformed.`
78714
78754
  );
@@ -79067,7 +79107,7 @@ __export(manager_exports, {
79067
79107
  import { execFileSync as execFileSync3 } from "child_process";
79068
79108
  import { existsSync as existsSync22, mkdirSync as mkdirSync11, rmSync as rmSync4 } from "fs";
79069
79109
  import { homedir as homedir5, platform as platform4 } from "os";
79070
- import { join as join19 } from "path";
79110
+ import { join as join20 } from "path";
79071
79111
  function isWhisperUnavailable(err) {
79072
79112
  if (err instanceof WhisperUnavailableError) return true;
79073
79113
  return err instanceof Error && "code" in err && err.code === "WHISPER_UNAVAILABLE";
@@ -79110,8 +79150,8 @@ function findFromSystem() {
79110
79150
  }
79111
79151
  function findBuiltBinary() {
79112
79152
  for (const p2 of [
79113
- join19(BUILD_DIR, "build", "bin", "whisper-cli"),
79114
- join19(BUILD_DIR, "build", "whisper-cli")
79153
+ join20(BUILD_DIR, "build", "bin", "whisper-cli"),
79154
+ join20(BUILD_DIR, "build", "whisper-cli")
79115
79155
  ]) {
79116
79156
  if (existsSync22(p2)) return { executablePath: p2, source: "build" };
79117
79157
  }
@@ -79123,7 +79163,7 @@ function buildFromSource(onProgress) {
79123
79163
  }
79124
79164
  if (!existsSync22(BUILD_DIR)) {
79125
79165
  onProgress?.("Downloading whisper.cpp...");
79126
- mkdirSync11(join19(homedir5(), ".cache", "hyperframes", "whisper"), {
79166
+ mkdirSync11(join20(homedir5(), ".cache", "hyperframes", "whisper"), {
79127
79167
  recursive: true
79128
79168
  });
79129
79169
  execFileSync3("git", ["clone", "--depth", "1", WHISPER_REPO, BUILD_DIR], {
@@ -79208,7 +79248,7 @@ async function ensureWhisper(options) {
79208
79248
  throw new WhisperUnavailableError(`whisper-cpp not found. Install: ${getInstallInstructions()}`);
79209
79249
  }
79210
79250
  async function ensureModel(model = DEFAULT_MODEL, options) {
79211
- const modelPath2 = join19(MODELS_DIR, `ggml-${model}.bin`);
79251
+ const modelPath2 = join20(MODELS_DIR, `ggml-${model}.bin`);
79212
79252
  if (existsSync22(modelPath2)) return modelPath2;
79213
79253
  mkdirSync11(MODELS_DIR, { recursive: true });
79214
79254
  options?.onProgress?.(`Downloading model ${model}...`);
@@ -79227,7 +79267,7 @@ var init_manager = __esm({
79227
79267
  "use strict";
79228
79268
  init_ffmpeg();
79229
79269
  init_download();
79230
- MODELS_DIR = join19(homedir5(), ".cache", "hyperframes", "whisper", "models");
79270
+ MODELS_DIR = join20(homedir5(), ".cache", "hyperframes", "whisper", "models");
79231
79271
  DEFAULT_MODEL = "small.en";
79232
79272
  WhisperUnavailableError = class extends Error {
79233
79273
  code = "WHISPER_UNAVAILABLE";
@@ -79236,7 +79276,7 @@ var init_manager = __esm({
79236
79276
  this.name = "WhisperUnavailableError";
79237
79277
  }
79238
79278
  };
79239
- BUILD_DIR = join19(homedir5(), ".cache", "hyperframes", "whisper", "whisper.cpp");
79279
+ BUILD_DIR = join20(homedir5(), ".cache", "hyperframes", "whisper", "whisper.cpp");
79240
79280
  WHISPER_REPO = "https://github.com/ggml-org/whisper.cpp.git";
79241
79281
  }
79242
79282
  });
@@ -79253,7 +79293,7 @@ __export(normalize_exports, {
79253
79293
  wordsToCues: () => wordsToCues
79254
79294
  });
79255
79295
  import { readFileSync as readFileSync14, readdirSync as readdirSync8, writeFileSync as writeFileSync9 } from "fs";
79256
- import { extname as extname6, join as join20 } from "path";
79296
+ import { extname as extname6, join as join21 } from "path";
79257
79297
  function detectFormat(filePath) {
79258
79298
  const ext = extname6(filePath).toLowerCase();
79259
79299
  if (ext === ".srt") return "srt";
@@ -79530,7 +79570,7 @@ function patchCaptionHtml(dir, words) {
79530
79570
  const wordsJson = JSON.stringify(words, null, 2).replace(/\n/g, "\n ");
79531
79571
  let htmlFiles;
79532
79572
  try {
79533
- htmlFiles = readdirSync8(dir, { withFileTypes: true, recursive: true }).filter((e3) => e3.isFile() && e3.name.endsWith(".html")).map((e3) => join20(e3.parentPath, e3.name));
79573
+ htmlFiles = readdirSync8(dir, { withFileTypes: true, recursive: true }).filter((e3) => e3.isFile() && e3.name.endsWith(".html")).map((e3) => join21(e3.parentPath, e3.name));
79534
79574
  } catch {
79535
79575
  return;
79536
79576
  }
@@ -79571,9 +79611,9 @@ __export(projectConfig_exports, {
79571
79611
  writeProjectConfig: () => writeProjectConfig
79572
79612
  });
79573
79613
  import { readFileSync as readFileSync15, writeFileSync as writeFileSync10 } from "fs";
79574
- import { join as join21, resolve as resolve12 } from "path";
79614
+ import { join as join22, resolve as resolve12 } from "path";
79575
79615
  function projectConfigPath(projectDir) {
79576
- return join21(resolve12(projectDir), PROJECT_CONFIG_FILENAME);
79616
+ return join22(resolve12(projectDir), PROJECT_CONFIG_FILENAME);
79577
79617
  }
79578
79618
  function readProjectConfig(projectDir) {
79579
79619
  const path2 = projectConfigPath(projectDir);
@@ -79749,14 +79789,14 @@ import { execFile } from "child_process";
79749
79789
  import { createHash as createHash3 } from "crypto";
79750
79790
  import { existsSync as existsSync23, readdirSync as readdirSync9, readFileSync as readFileSync16, statSync as statSync6 } from "fs";
79751
79791
  import { homedir as homedir6 } from "os";
79752
- import { isAbsolute as isAbsolute7, join as join22, relative as relative5, resolve as resolve13, sep as sep4 } from "path";
79792
+ import { isAbsolute as isAbsolute7, join as join23, relative as relative5, resolve as resolve13, sep as sep4 } from "path";
79753
79793
  import { promisify } from "util";
79754
79794
  function listFilesSorted(dir) {
79755
79795
  const out = [];
79756
79796
  const walk = (d2) => {
79757
79797
  for (const name of readdirSync9(d2)) {
79758
79798
  if (name === ".DS_Store") continue;
79759
- const p2 = join22(d2, name);
79799
+ const p2 = join23(d2, name);
79760
79800
  if (statSync6(p2).isDirectory()) walk(p2);
79761
79801
  else out.push(p2);
79762
79802
  }
@@ -79780,9 +79820,9 @@ function hashSkillBundle(skillDir) {
79780
79820
  return { hash: h3.digest("hex").slice(0, 16), files: files.length };
79781
79821
  }
79782
79822
  function buildManifest(skillsRoot, meta) {
79783
- const names = readdirSync9(skillsRoot).filter((n2) => existsSync23(join22(skillsRoot, n2, "SKILL.md"))).sort();
79823
+ const names = readdirSync9(skillsRoot).filter((n2) => existsSync23(join23(skillsRoot, n2, "SKILL.md"))).sort();
79784
79824
  const skills = {};
79785
- for (const name of names) skills[name] = hashSkillBundle(join22(skillsRoot, name));
79825
+ for (const name of names) skills[name] = hashSkillBundle(join23(skillsRoot, name));
79786
79826
  return { source: meta.source, skills };
79787
79827
  }
79788
79828
  function agentLabel(hostDir) {
@@ -79804,12 +79844,12 @@ function listSubdirs(dir) {
79804
79844
  function discoverSkillRoots(base2, scope) {
79805
79845
  const candidates = [];
79806
79846
  const add2 = (hostBase, host) => {
79807
- const dir = join22(hostBase, host, "skills");
79847
+ const dir = join23(hostBase, host, "skills");
79808
79848
  if (existsSync23(dir) && statSync6(dir).isDirectory())
79809
79849
  candidates.push({ dir, agent: agentLabel(host), scope });
79810
79850
  };
79811
79851
  for (const host of listSubdirs(base2)) add2(base2, host);
79812
- const xdg = join22(base2, ".config");
79852
+ const xdg = join23(base2, ".config");
79813
79853
  for (const host of listSubdirs(xdg)) add2(xdg, host);
79814
79854
  return candidates.sort((a, b2) => {
79815
79855
  if (a.agent !== b2.agent) {
@@ -79843,15 +79883,15 @@ function locateInstall(skillNames, opts = {}) {
79843
79883
  ...discoverSkillRoots(opts.cwd ?? process.cwd(), "project")
79844
79884
  ];
79845
79885
  for (const root of roots) {
79846
- if (skillNames.some((n2) => existsSync23(join22(root.dir, n2, "SKILL.md")))) return root;
79886
+ if (skillNames.some((n2) => existsSync23(join23(root.dir, n2, "SKILL.md")))) return root;
79847
79887
  }
79848
79888
  return null;
79849
79889
  }
79850
79890
  function hashInstalled(root, skillNames) {
79851
79891
  const out = {};
79852
79892
  for (const name of skillNames) {
79853
- const skillDir = join22(root.dir, name);
79854
- if (existsSync23(join22(skillDir, "SKILL.md"))) out[name] = hashSkillBundle(skillDir);
79893
+ const skillDir = join23(root.dir, name);
79894
+ if (existsSync23(join23(skillDir, "SKILL.md"))) out[name] = hashSkillBundle(skillDir);
79855
79895
  }
79856
79896
  return out;
79857
79897
  }
@@ -79892,10 +79932,10 @@ function skillsAttributedToSource(lock, source) {
79892
79932
  return Object.entries(lock.skills).filter(([, e3]) => repoSlug(e3.source) === want || repoSlug(e3.sourceUrl) === want).map(([name]) => name);
79893
79933
  }
79894
79934
  function lockPathForScope(scope, opts) {
79895
- if (scope === "project") return join22(opts.cwd ?? process.cwd(), "skills-lock.json");
79935
+ if (scope === "project") return join23(opts.cwd ?? process.cwd(), "skills-lock.json");
79896
79936
  const xdgStateHome = process.env.XDG_STATE_HOME;
79897
- if (xdgStateHome) return join22(xdgStateHome, "skills", ".skill-lock.json");
79898
- return join22(opts.home ?? homedir6(), ".agents", ".skill-lock.json");
79937
+ if (xdgStateHome) return join23(xdgStateHome, "skills", ".skill-lock.json");
79938
+ return join23(opts.home ?? homedir6(), ".agents", ".skill-lock.json");
79899
79939
  }
79900
79940
  function readSkillLock(path2) {
79901
79941
  try {
@@ -79916,9 +79956,9 @@ function detectRemoved(root, latest, opts) {
79916
79956
  function findRepoManifest(cwd = process.cwd()) {
79917
79957
  let dir = cwd;
79918
79958
  for (let i2 = 0; i2 < 16; i2++) {
79919
- const p2 = join22(dir, MANIFEST_FILE);
79959
+ const p2 = join23(dir, MANIFEST_FILE);
79920
79960
  if (existsSync23(p2)) return p2;
79921
- const parent = join22(dir, "..");
79961
+ const parent = join23(dir, "..");
79922
79962
  if (parent === dir) break;
79923
79963
  dir = parent;
79924
79964
  }
@@ -79956,9 +79996,9 @@ async function remoteHeadSha(repoSlug2) {
79956
79996
  }
79957
79997
  }
79958
79998
  function resolveLocalManifest(source) {
79959
- const direct = source.endsWith(".json") ? source : join22(source, MANIFEST_FILE);
79999
+ const direct = source.endsWith(".json") ? source : join23(source, MANIFEST_FILE);
79960
80000
  if (existsSync23(direct)) return JSON.parse(readFileSync16(direct, "utf8"));
79961
- const skillsRoot = source.endsWith("skills") ? source : join22(source, "skills");
80001
+ const skillsRoot = source.endsWith("skills") ? source : join23(source, "skills");
79962
80002
  if (existsSync23(skillsRoot)) return buildManifest(skillsRoot, { source: skillsRoot });
79963
80003
  throw new Error(`No skills manifest found at: ${source}`);
79964
80004
  }
@@ -80117,22 +80157,22 @@ var init_agentDirs_generated = __esm({
80117
80157
  // src/utils/skillsMirror.ts
80118
80158
  import { cpSync, existsSync as existsSync24, mkdirSync as mkdirSync12, readdirSync as readdirSync10, rmSync as rmSync5, symlinkSync } from "fs";
80119
80159
  import { homedir as homedir7 } from "os";
80120
- import { dirname as dirname10, isAbsolute as isAbsolute8, join as join23, relative as relative6 } from "path";
80160
+ import { dirname as dirname10, isAbsolute as isAbsolute8, join as join24, relative as relative6 } from "path";
80121
80161
  function resolveBases(home, env) {
80122
80162
  const xdg = env["XDG_CONFIG_HOME"]?.trim();
80123
80163
  return {
80124
80164
  home,
80125
- configHome: xdg && isAbsolute8(xdg) ? xdg : join23(home, ".config"),
80126
- codexHome: env["CODEX_HOME"]?.trim() || join23(home, ".codex"),
80127
- claudeHome: env["CLAUDE_CONFIG_DIR"]?.trim() || join23(home, ".claude"),
80128
- vibeHome: env["VIBE_HOME"]?.trim() || join23(home, ".vibe"),
80129
- hermesHome: env["HERMES_HOME"]?.trim() || join23(home, ".hermes"),
80130
- autohandHome: env["AUTOHAND_HOME"]?.trim() || join23(home, ".autohand")
80165
+ configHome: xdg && isAbsolute8(xdg) ? xdg : join24(home, ".config"),
80166
+ codexHome: env["CODEX_HOME"]?.trim() || join24(home, ".codex"),
80167
+ claudeHome: env["CLAUDE_CONFIG_DIR"]?.trim() || join24(home, ".claude"),
80168
+ vibeHome: env["VIBE_HOME"]?.trim() || join24(home, ".vibe"),
80169
+ hermesHome: env["HERMES_HOME"]?.trim() || join24(home, ".hermes"),
80170
+ autohandHome: env["AUTOHAND_HOME"]?.trim() || join24(home, ".autohand")
80131
80171
  };
80132
80172
  }
80133
80173
  function listSkillDirs(store) {
80134
80174
  return readdirSync10(store, { withFileTypes: true }).filter(
80135
- (e3) => (e3.isDirectory() || e3.isSymbolicLink()) && existsSync24(join23(store, e3.name, "SKILL.md"))
80175
+ (e3) => (e3.isDirectory() || e3.isSymbolicLink()) && existsSync24(join24(store, e3.name, "SKILL.md"))
80136
80176
  ).map((e3) => e3.name);
80137
80177
  }
80138
80178
  function linkOrCopy(sourceSkill, targetSkill, platform10) {
@@ -80151,7 +80191,7 @@ function mirrorInto(targetDir, source, skills, platform10) {
80151
80191
  }
80152
80192
  for (const skill of skills) {
80153
80193
  try {
80154
- linkOrCopy(join23(source, skill), join23(targetDir, skill), platform10);
80194
+ linkOrCopy(join24(source, skill), join24(targetDir, skill), platform10);
80155
80195
  } catch {
80156
80196
  }
80157
80197
  }
@@ -80161,15 +80201,15 @@ function mirrorGlobalSkills(opts) {
80161
80201
  const home = opts.home ?? homedir7();
80162
80202
  const platform10 = opts.platform ?? process.platform;
80163
80203
  const bases = resolveBases(home, opts.env ?? process.env);
80164
- const source = join23(bases.claudeHome, "skills");
80165
- const universalStore = join23(home, ".agents", "skills");
80204
+ const source = join24(bases.claudeHome, "skills");
80205
+ const universalStore = join24(home, ".agents", "skills");
80166
80206
  if (!existsSync24(source)) return { source: null, mirrored: [] };
80167
80207
  const allowed = new Set(opts.skills);
80168
80208
  const skills = listSkillDirs(source).filter((name) => allowed.has(name));
80169
80209
  if (skills.length === 0) return { source, mirrored: [] };
80170
80210
  const mirrored = [];
80171
80211
  for (const { agent, base: base2, sub } of AGENT_GLOBAL_DIRS) {
80172
- const targetDir = join23(bases[base2], ...sub.split("/").filter(Boolean));
80212
+ const targetDir = join24(bases[base2], ...sub.split("/").filter(Boolean));
80173
80213
  if (targetDir === source || targetDir === universalStore) continue;
80174
80214
  if (!existsSync24(dirname10(targetDir))) continue;
80175
80215
  if (mirrorInto(targetDir, source, skills, platform10)) mirrored.push({ agent, dir: targetDir });
@@ -80479,7 +80519,7 @@ __export(transcribe_exports, {
80479
80519
  });
80480
80520
  import { execFileSync as execFileSync5 } from "child_process";
80481
80521
  import { existsSync as existsSync25, readFileSync as readFileSync17, mkdirSync as mkdirSync13, unlinkSync as unlinkSync2 } from "fs";
80482
- import { join as join24, extname as extname7 } from "path";
80522
+ import { join as join25, extname as extname7 } from "path";
80483
80523
  import { tmpdir as tmpdir2 } from "os";
80484
80524
  import { randomUUID as randomUUID3 } from "crypto";
80485
80525
  function detectLanguage(whisperPath, modelPath2, wavPath) {
@@ -80559,7 +80599,7 @@ function isVideoFile(filePath) {
80559
80599
  return VIDEO_EXTENSIONS.has(extname7(filePath).toLowerCase());
80560
80600
  }
80561
80601
  function tempWavPath() {
80562
- return join24(tmpdir2(), `hyperframes-audio-${process.pid}-${randomUUID3()}.wav`);
80602
+ return join25(tmpdir2(), `hyperframes-audio-${process.pid}-${randomUUID3()}.wav`);
80563
80603
  }
80564
80604
  function extractAudio(videoPath) {
80565
80605
  const ffmpegPath = findFFmpeg();
@@ -80650,7 +80690,7 @@ async function transcribe(inputPath, outputDir, options) {
80650
80690
  effectiveModel = multilingualModel;
80651
80691
  }
80652
80692
  options?.onProgress?.("Transcribing...");
80653
- const outputBase = join24(outputDir, "transcript");
80693
+ const outputBase = join25(outputDir, "transcript");
80654
80694
  mkdirSync13(outputDir, { recursive: true });
80655
80695
  const whisperArgs = [
80656
80696
  "--model",
@@ -88346,7 +88386,7 @@ var init_hfIds = __esm({
88346
88386
  import { execFileSync as execFileSync6 } from "child_process";
88347
88387
  import { existsSync as existsSync29, lstatSync as lstatSync2, readdirSync as readdirSync11, realpathSync as realpathSync3 } from "fs";
88348
88388
  import { homedir as homedir8, platform as platform5 } from "os";
88349
- import { join as join25, resolve as resolve18 } from "path";
88389
+ import { join as join26, resolve as resolve18 } from "path";
88350
88390
  function getAllowedFontDirs() {
88351
88391
  if (allowedDirsCache)
88352
88392
  return allowedDirsCache;
@@ -88415,7 +88455,7 @@ function fontDirectories() {
88415
88455
  const home = homedir8();
88416
88456
  if (platform5() === "darwin") {
88417
88457
  return [
88418
- join25(home, "Library", "Fonts"),
88458
+ join26(home, "Library", "Fonts"),
88419
88459
  "/Library/Fonts",
88420
88460
  "/System/Library/Fonts",
88421
88461
  "/System/Library/Fonts/Supplemental"
@@ -88423,13 +88463,13 @@ function fontDirectories() {
88423
88463
  }
88424
88464
  if (platform5() === "win32") {
88425
88465
  return [
88426
- join25(process.env.WINDIR || "C:\\Windows", "Fonts"),
88427
- join25(process.env.LOCALAPPDATA || join25(homedir8(), "AppData", "Local"), "Microsoft", "Windows", "Fonts")
88466
+ join26(process.env.WINDIR || "C:\\Windows", "Fonts"),
88467
+ join26(process.env.LOCALAPPDATA || join26(homedir8(), "AppData", "Local"), "Microsoft", "Windows", "Fonts")
88428
88468
  ];
88429
88469
  }
88430
88470
  return [
88431
- join25(home, ".fonts"),
88432
- join25(home, ".local", "share", "fonts"),
88471
+ join26(home, ".fonts"),
88472
+ join26(home, ".local", "share", "fonts"),
88433
88473
  "/usr/local/share/fonts",
88434
88474
  "/usr/share/fonts"
88435
88475
  ];
@@ -88440,7 +88480,7 @@ function collectFontFileEntries(dir, depth = 0) {
88440
88480
  const entries2 = [];
88441
88481
  try {
88442
88482
  for (const entry of readdirSync11(dir, { withFileTypes: true })) {
88443
- const fullPath = join25(dir, entry.name);
88483
+ const fullPath = join26(dir, entry.name);
88444
88484
  if (entry.isDirectory()) {
88445
88485
  entries2.push(...collectFontFileEntries(fullPath, depth + 1));
88446
88486
  continue;
@@ -91251,8 +91291,8 @@ var init_gsapParser = __esm({
91251
91291
  // ../studio-server/dist/index.js
91252
91292
  import { Hono as Hono2 } from "hono";
91253
91293
  import { readFile } from "fs/promises";
91254
- import { join as join26 } from "path";
91255
91294
  import { join as join27 } from "path";
91295
+ import { join as join28 } from "path";
91256
91296
  import { readdirSync as readdirSync12 } from "fs";
91257
91297
  import { existsSync as existsSync30, readFileSync as readFileSync19 } from "fs";
91258
91298
  import { bodyLimit } from "hono/body-limit";
@@ -91297,7 +91337,7 @@ import { join as join112 } from "path";
91297
91337
  import { createHash as createHash22 } from "crypto";
91298
91338
  import { existsSync as existsSync82, readFileSync as readFileSync112, writeFileSync as writeFileSync72, mkdirSync as mkdirSync62 } from "fs";
91299
91339
  import { join as join122 } from "path";
91300
- import { closeSync as closeSync2, constants, fstatSync, openSync as openSync2, readSync } from "fs";
91340
+ import { closeSync as closeSync2, constants as constants2, fstatSync, openSync as openSync2, readSync } from "fs";
91301
91341
  function shouldIgnoreDir(rel) {
91302
91342
  return rel === ".hyperframes/backup";
91303
91343
  }
@@ -91311,7 +91351,7 @@ function walkDir(dir, prefix = "") {
91311
91351
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
91312
91352
  if (IGNORE_DIRS.has(entry.name) || shouldIgnoreDir(rel)) continue;
91313
91353
  if (entry.isDirectory()) {
91314
- files.push(...walkDir(join27(dir, entry.name), rel));
91354
+ files.push(...walkDir(join28(dir, entry.name), rel));
91315
91355
  } else {
91316
91356
  files.push(rel);
91317
91357
  }
@@ -91323,7 +91363,7 @@ async function filterCompositionFiles(projectDir, files) {
91323
91363
  const checks = await Promise.all(
91324
91364
  htmlFiles.map(async (f3) => {
91325
91365
  try {
91326
- const content = await readFile(join26(projectDir, f3), "utf-8");
91366
+ const content = await readFile(join27(projectDir, f3), "utf-8");
91327
91367
  return COMPOSITION_ID_RE.test(content);
91328
91368
  } catch {
91329
91369
  return false;
@@ -95116,7 +95156,7 @@ function registerFontRoutes(api) {
95116
95156
  if (!located) return c3.json({ error: "font not found" }, 404);
95117
95157
  let fd;
95118
95158
  try {
95119
- fd = openSync2(located.path, constants.O_RDONLY | constants.O_NOFOLLOW);
95159
+ fd = openSync2(located.path, constants2.O_RDONLY | constants2.O_NOFOLLOW);
95120
95160
  } catch {
95121
95161
  return c3.json({ error: "font file not accessible" }, 404);
95122
95162
  }
@@ -95530,7 +95570,7 @@ import { execSync as execSync5, spawnSync as spawnSync2 } from "child_process";
95530
95570
  import { existsSync as existsSync31, mkdirSync as mkdirSync15, readdirSync as readdirSync13, rmSync as rmSync7, statSync as statSync9 } from "fs";
95531
95571
  import { basename as basename4 } from "path";
95532
95572
  import { homedir as homedir9 } from "os";
95533
- import { join as join28 } from "path";
95573
+ import { join as join29 } from "path";
95534
95574
  async function loadPuppeteerBrowsers() {
95535
95575
  try {
95536
95576
  return await import("@puppeteer/browsers");
@@ -95685,15 +95725,15 @@ function findFromPuppeteerCache() {
95685
95725
  }
95686
95726
  for (const version2 of versions) {
95687
95727
  const candidates = [
95688
- join28(PUPPETEER_CACHE_DIR, version2, "chrome-headless-shell-linux64", "chrome-headless-shell"),
95689
- join28(
95728
+ join29(PUPPETEER_CACHE_DIR, version2, "chrome-headless-shell-linux64", "chrome-headless-shell"),
95729
+ join29(
95690
95730
  PUPPETEER_CACHE_DIR,
95691
95731
  version2,
95692
95732
  "chrome-headless-shell-mac-arm64",
95693
95733
  "chrome-headless-shell"
95694
95734
  ),
95695
- join28(PUPPETEER_CACHE_DIR, version2, "chrome-headless-shell-mac-x64", "chrome-headless-shell"),
95696
- join28(
95735
+ join29(PUPPETEER_CACHE_DIR, version2, "chrome-headless-shell-mac-x64", "chrome-headless-shell"),
95736
+ join29(
95697
95737
  PUPPETEER_CACHE_DIR,
95698
95738
  version2,
95699
95739
  "chrome-headless-shell-win64",
@@ -95872,11 +95912,11 @@ var init_manager2 = __esm({
95872
95912
  "use strict";
95873
95913
  init_errorMessage();
95874
95914
  CHROME_VERSION = "131.0.6778.85";
95875
- CACHE_ROOT_DIR = join28(homedir9(), ".cache", "hyperframes");
95876
- CACHE_DIR2 = join28(homedir9(), ".cache", "hyperframes", "chrome");
95877
- PUPPETEER_CACHE_DIR = join28(homedir9(), ".cache", "puppeteer", "chrome-headless-shell");
95878
- INSTALL_LOCK_DIR = join28(CACHE_ROOT_DIR, ".chrome.install.lock");
95879
- INSTALL_RECLAIM_LOCK_DIR = join28(CACHE_ROOT_DIR, ".chrome.install.reclaim.lock");
95915
+ CACHE_ROOT_DIR = join29(homedir9(), ".cache", "hyperframes");
95916
+ CACHE_DIR2 = join29(homedir9(), ".cache", "hyperframes", "chrome");
95917
+ PUPPETEER_CACHE_DIR = join29(homedir9(), ".cache", "puppeteer", "chrome-headless-shell");
95918
+ INSTALL_LOCK_DIR = join29(CACHE_ROOT_DIR, ".chrome.install.lock");
95919
+ INSTALL_RECLAIM_LOCK_DIR = join29(CACHE_ROOT_DIR, ".chrome.install.reclaim.lock");
95880
95920
  INSTALL_LOCK_TIMEOUT_MS = 12e4;
95881
95921
  INSTALL_LOCK_POLL_MS = 200;
95882
95922
  SYSTEM_CHROME_PATHS = process.platform === "darwin" ? ["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"] : [
@@ -99161,7 +99201,7 @@ __export(deterministicFonts_exports, {
99161
99201
  import { createHash as createHash6 } from "crypto";
99162
99202
  import { existsSync as existsSync33, mkdirSync as mkdirSync16, readFileSync as readFileSync20, writeFileSync as writeFileSync12 } from "fs";
99163
99203
  import { homedir as homedir10, tmpdir as tmpdir4 } from "os";
99164
- import { join as join29 } from "path";
99204
+ import { join as join30 } from "path";
99165
99205
  import postcss4 from "postcss";
99166
99206
  function parseFontFamilyValue(value) {
99167
99207
  return value.split(",").map((piece) => piece.trim().replace(/^['"]/, "").replace(/['"]$/, "").trim()).filter((piece) => piece.length > 0);
@@ -99478,13 +99518,13 @@ function warnUnresolvedFonts(unresolved) {
99478
99518
  );
99479
99519
  }
99480
99520
  function resolveFontCacheRoot() {
99481
- return process.env.HYPERFRAMES_FONT_CACHE_DIR ?? (process.env.AWS_LAMBDA_FUNCTION_NAME ? join29(tmpdir4(), "hyperframes", "fonts") : join29(homedir10(), ".cache", "hyperframes", "fonts"));
99521
+ return process.env.HYPERFRAMES_FONT_CACHE_DIR ?? (process.env.AWS_LAMBDA_FUNCTION_NAME ? join30(tmpdir4(), "hyperframes", "fonts") : join30(homedir10(), ".cache", "hyperframes", "fonts"));
99482
99522
  }
99483
99523
  function fontSlug(familyName) {
99484
99524
  return familyName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
99485
99525
  }
99486
99526
  function fontCacheDir(slug) {
99487
- const dir = join29(GOOGLE_FONTS_CACHE_DIR, slug);
99527
+ const dir = join30(GOOGLE_FONTS_CACHE_DIR, slug);
99488
99528
  if (!existsSync33(dir)) {
99489
99529
  mkdirSync16(dir, { recursive: true });
99490
99530
  }
@@ -99494,7 +99534,7 @@ function subsetToken(woff2Url) {
99494
99534
  return createHash6("sha1").update(woff2Url).digest("hex").slice(0, 12);
99495
99535
  }
99496
99536
  function cachedWoff2Path(slug, weight, style, subset) {
99497
- return join29(fontCacheDir(slug), `${weight}-${style}-${subset}.woff2`);
99537
+ return join30(fontCacheDir(slug), `${weight}-${style}-${subset}.woff2`);
99498
99538
  }
99499
99539
  function fontFetchError(familyName, url, what, cause) {
99500
99540
  const reason = "status" in cause ? `returned HTTP ${cause.status}` : `failed: ${cause.error.message}`;
@@ -99779,7 +99819,7 @@ import {
99779
99819
  rmSync as rmSync8,
99780
99820
  statSync as statSync10
99781
99821
  } from "fs";
99782
- import { dirname as dirname13, isAbsolute as isAbsolute10, join as join30, resolve as resolve20 } from "path";
99822
+ import { dirname as dirname13, isAbsolute as isAbsolute10, join as join31, resolve as resolve20 } from "path";
99783
99823
  function splitUrlSuffix2(src) {
99784
99824
  const queryIdx = src.indexOf("?");
99785
99825
  const hashIdx = src.indexOf("#");
@@ -100026,7 +100066,7 @@ function replaceImageWithVideo(input2) {
100026
100066
  return video;
100027
100067
  }
100028
100068
  async function prepareAnimatedGifInputs(html, options) {
100029
- const outputDir = options.outputDir ?? join30(options.downloadDir, PREPARED_GIF_SUBDIR);
100069
+ const outputDir = options.outputDir ?? join31(options.downloadDir, PREPARED_GIF_SUBDIR);
100030
100070
  const outputSrcPrefix = normalizeRelPath(options.outputSrcPrefix ?? PREPARED_GIF_SUBDIR);
100031
100071
  const cacheDir = options.cacheDir ?? outputDir;
100032
100072
  const { document: document2 } = parseHTML(html);
@@ -100048,8 +100088,8 @@ async function prepareAnimatedGifInputs(html, options) {
100048
100088
  const { loopIterations, padSeconds } = resolvePreparedPlayback(metadata, loop, windowSeconds);
100049
100089
  const hash2 = computePreparedGifHash(bytes, loopIterations, padSeconds);
100050
100090
  const filename = `${CACHE_SCHEMA}-${hash2.slice(0, 24)}.webm`;
100051
- const cachePath2 = join30(cacheDir, filename);
100052
- const outputPath = join30(outputDir, filename);
100091
+ const cachePath2 = join31(cacheDir, filename);
100092
+ const outputPath = join31(outputDir, filename);
100053
100093
  const outputSrc = `${outputSrcPrefix}/${filename}`;
100054
100094
  await ensurePreparedWebm({
100055
100095
  sourcePath,
@@ -100192,7 +100232,7 @@ import { serve as serve2 } from "@hono/node-server";
100192
100232
  import { existsSync as existsSync36, realpathSync as realpathSync4, statSync as statSync11, createReadStream } from "fs";
100193
100233
  import { readFile as readFile2 } from "fs/promises";
100194
100234
  import { Readable as Readable2 } from "stream";
100195
- import { join as join31, extname as extname9, resolve as resolve23, sep as sep5 } from "path";
100235
+ import { join as join33, extname as extname9, resolve as resolve23, sep as sep5 } from "path";
100196
100236
  function isPathInside2(child, parent, options = {}) {
100197
100237
  const { resolveSymlinks = false, pathModule } = options;
100198
100238
  const resolveFn = pathModule?.resolve ?? resolve23;
@@ -100536,13 +100576,13 @@ function createFileServer2(options) {
100536
100576
  }).join("/");
100537
100577
  let filePath = null;
100538
100578
  if (compiledDir) {
100539
- const candidate = join31(compiledDir, relativePath);
100579
+ const candidate = join33(compiledDir, relativePath);
100540
100580
  if (existsSync36(candidate) && isPathInside2(candidate, compiledDir) && statSync11(candidate).isFile()) {
100541
100581
  filePath = candidate;
100542
100582
  }
100543
100583
  }
100544
100584
  if (!filePath) {
100545
- const candidate = join31(projectDir, relativePath);
100585
+ const candidate = join33(projectDir, relativePath);
100546
100586
  if (existsSync36(candidate) && isPathInside2(candidate, projectDir) && statSync11(candidate).isFile()) {
100547
100587
  filePath = candidate;
100548
100588
  }
@@ -100767,7 +100807,7 @@ var init_fileServer2 = __esm({
100767
100807
  // ../producer/src/utils/paths.ts
100768
100808
  import {
100769
100809
  basename as basename5,
100770
- join as join33,
100810
+ join as join34,
100771
100811
  resolve as nodeResolve,
100772
100812
  relative as nodeRelative,
100773
100813
  isAbsolute as nodeIsAbsolute
@@ -100802,7 +100842,7 @@ function formatExportFrameName(index, ext) {
100802
100842
  function resolveRenderPaths(projectDir, outputPath, rendersDir = DEFAULT_RENDERS_DIR) {
100803
100843
  const absoluteProjectDir = nodeResolve(projectDir);
100804
100844
  const projectName = basename5(absoluteProjectDir);
100805
- const resolvedOutputPath = outputPath ?? join33(rendersDir, `${projectName}.mp4`);
100845
+ const resolvedOutputPath = outputPath ?? join34(rendersDir, `${projectName}.mp4`);
100806
100846
  const absoluteOutputPath = nodeResolve(resolvedOutputPath);
100807
100847
  return { absoluteProjectDir, absoluteOutputPath };
100808
100848
  }
@@ -100818,7 +100858,7 @@ var init_paths = __esm({
100818
100858
 
100819
100859
  // ../producer/src/services/render/shared.ts
100820
100860
  import { copyFileSync as copyFileSync4, cpSync as cpSync2, existsSync as existsSync37, mkdirSync as mkdirSync18, symlinkSync as symlinkSync2, writeFileSync as writeFileSync13 } from "fs";
100821
- import { basename as basename6, dirname as dirname15, isAbsolute as isAbsolute11, join as join34, relative as relative8, resolve as resolve24 } from "path";
100861
+ import { basename as basename6, dirname as dirname15, isAbsolute as isAbsolute11, join as join35, relative as relative8, resolve as resolve24 } from "path";
100822
100862
  function writeFileExclusiveSync(path2, data2) {
100823
100863
  try {
100824
100864
  writeFileSync13(path2, data2, { flag: "wx", mode: 384 });
@@ -100846,16 +100886,16 @@ function resolveDeviceScaleFactor(input2) {
100846
100886
  return target.width / input2.compositionWidth;
100847
100887
  }
100848
100888
  function writeCompiledArtifacts(compiled, workDir, includeSummary) {
100849
- const compileDir = join34(workDir, "compiled");
100889
+ const compileDir = join35(workDir, "compiled");
100850
100890
  mkdirSync18(compileDir, { recursive: true });
100851
- writeFileSync13(join34(compileDir, "index.html"), compiled.html, "utf-8");
100891
+ writeFileSync13(join35(compileDir, "index.html"), compiled.html, "utf-8");
100852
100892
  for (const [srcPath, html] of compiled.subCompositions) {
100853
- const outPath = join34(compileDir, srcPath);
100893
+ const outPath = join35(compileDir, srcPath);
100854
100894
  mkdirSync18(dirname15(outPath), { recursive: true });
100855
100895
  writeFileSync13(outPath, html, "utf-8");
100856
100896
  }
100857
100897
  for (const [relativePath, absolutePath] of compiled.externalAssets) {
100858
- const outPath = resolve24(join34(compileDir, relativePath));
100898
+ const outPath = resolve24(join35(compileDir, relativePath));
100859
100899
  if (!isPathInside3(outPath, compileDir)) {
100860
100900
  console.warn(`[Render] Skipping external asset with unsafe path: ${relativePath}`);
100861
100901
  continue;
@@ -100886,7 +100926,7 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
100886
100926
  renderModeHints: compiled.renderModeHints,
100887
100927
  hasShaderTransitions: compiled.hasShaderTransitions
100888
100928
  };
100889
- writeFileSync13(join34(compileDir, "summary.json"), JSON.stringify(summary, null, 2), "utf-8");
100929
+ writeFileSync13(join35(compileDir, "summary.json"), JSON.stringify(summary, null, 2), "utf-8");
100890
100930
  }
100891
100931
  }
100892
100932
  function applyRenderModeHints(alreadyForced, compiled, log2 = defaultLogger) {
@@ -100977,7 +101017,7 @@ var init_shared = __esm({
100977
101017
  BROWSER_MEDIA_EPSILON = 1e-4;
100978
101018
  materializePathModule = {
100979
101019
  resolve: resolve24,
100980
- join: join34,
101020
+ join: join35,
100981
101021
  dirname: dirname15,
100982
101022
  basename: basename6,
100983
101023
  relative: relative8,
@@ -101351,7 +101391,7 @@ var init_captureBeyondViewport = __esm({
101351
101391
  });
101352
101392
 
101353
101393
  // ../producer/src/services/render/captureCost.ts
101354
- import { join as join35 } from "path";
101394
+ import { join as join36 } from "path";
101355
101395
  function estimateCaptureCostMultiplier(compiled) {
101356
101396
  let multiplier = 1;
101357
101397
  const reasons = [];
@@ -101578,7 +101618,7 @@ async function runCaptureCalibration(input2) {
101578
101618
  });
101579
101619
  let calibration;
101580
101620
  try {
101581
- calibration = await runOneCalibration(join35(workDir, "capture-calibration"), calibrationCfg);
101621
+ calibration = await runOneCalibration(join36(workDir, "capture-calibration"), calibrationCfg);
101582
101622
  } catch (error) {
101583
101623
  const shouldFallback = !forceScreenshot && shouldFallbackToScreenshotAfterCalibrationError(error);
101584
101624
  if (!shouldFallback) {
@@ -101611,7 +101651,7 @@ async function runCaptureCalibration(input2) {
101611
101651
  const screenshotCfg = createCaptureCalibrationConfig({ ...cfg, forceScreenshot: true });
101612
101652
  try {
101613
101653
  calibration = await runOneCalibration(
101614
- join35(workDir, "capture-calibration-screenshot"),
101654
+ join36(workDir, "capture-calibration-screenshot"),
101615
101655
  screenshotCfg
101616
101656
  );
101617
101657
  } catch (fallbackError) {
@@ -102178,7 +102218,7 @@ var init_manualEditsRenderScript = __esm({
102178
102218
 
102179
102219
  // ../producer/src/services/htmlCompiler.ts
102180
102220
  import { readFileSync as readFileSync24, existsSync as existsSync38, mkdirSync as mkdirSync19 } from "fs";
102181
- import { join as join36, dirname as dirname16, resolve as resolve25, basename as basename7 } from "path";
102221
+ import { join as join37, dirname as dirname16, resolve as resolve25, basename as basename7 } from "path";
102182
102222
  function parseSubCompHtmlForValidity(html) {
102183
102223
  return parseHTML(html).document;
102184
102224
  }
@@ -102294,7 +102334,7 @@ async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagNa
102294
102334
  return { duration: 0, resolvedPath: src };
102295
102335
  }
102296
102336
  } else if (!filePath.startsWith("/")) {
102297
- filePath = join36(baseDir, filePath);
102337
+ filePath = join37(baseDir, filePath);
102298
102338
  }
102299
102339
  if (!existsSync38(filePath)) {
102300
102340
  return { duration: 0, resolvedPath: filePath };
@@ -102815,7 +102855,7 @@ async function localizeRemoteMediaSources(html, downloadDir) {
102815
102855
  return downloadAndRewriteUrls(
102816
102856
  urlSet,
102817
102857
  html,
102818
- join36(downloadDir, REMOTE_MEDIA_SUBDIR),
102858
+ join37(downloadDir, REMOTE_MEDIA_SUBDIR),
102819
102859
  "Remote media download failed for",
102820
102860
  "Localized remote media source(s)"
102821
102861
  );
@@ -102830,7 +102870,7 @@ async function localizeRemoteImageSources(html, downloadDir) {
102830
102870
  return downloadAndRewriteUrls(
102831
102871
  urlSet,
102832
102872
  html,
102833
- join36(downloadDir, REMOTE_MEDIA_SUBDIR),
102873
+ join37(downloadDir, REMOTE_MEDIA_SUBDIR),
102834
102874
  "Remote image download failed for",
102835
102875
  "Localized remote image source(s)"
102836
102876
  );
@@ -102979,7 +103019,7 @@ async function localizeRemoteFontFaces(html, downloadDir) {
102979
103019
  return downloadAndRewriteUrls(
102980
103020
  urlSet,
102981
103021
  processed,
102982
- join36(downloadDir, REMOTE_MEDIA_SUBDIR),
103022
+ join37(downloadDir, REMOTE_MEDIA_SUBDIR),
102983
103023
  "Remote font download failed for",
102984
103024
  "Localized remote font face(s)",
102985
103025
  (h3, url, relPath) => h3.replaceAll(`url(${url})`, `url("${relPath}")`)
@@ -103441,7 +103481,7 @@ Check that each file referenced by data-composition-src contains valid HTML with
103441
103481
  });
103442
103482
 
103443
103483
  // ../producer/src/services/render/stages/compileStage.ts
103444
- import { join as join37 } from "path";
103484
+ import { join as join38 } from "path";
103445
103485
  async function runCompileStage(input2) {
103446
103486
  const {
103447
103487
  projectDir,
@@ -103457,11 +103497,11 @@ async function runCompileStage(input2) {
103457
103497
  allowSystemFontCapture
103458
103498
  } = input2;
103459
103499
  const compileStart = Date.now();
103460
- const compiled = await compileForRender(projectDir, htmlPath, join37(workDir, "downloads"), {
103500
+ const compiled = await compileForRender(projectDir, htmlPath, join38(workDir, "downloads"), {
103461
103501
  log: log2,
103462
103502
  failClosedFontFetch: failClosedFontFetch === true,
103463
103503
  allowSystemFontCapture,
103464
- animatedGifCacheDir: cfg.extractCacheDir ? join37(cfg.extractCacheDir, "animated-gif") : void 0,
103504
+ animatedGifCacheDir: cfg.extractCacheDir ? join38(cfg.extractCacheDir, "animated-gif") : void 0,
103465
103505
  ffmpegProcessTimeout: cfg.ffmpegProcessTimeout
103466
103506
  });
103467
103507
  assertNotAborted();
@@ -103526,7 +103566,7 @@ var init_compileStage = __esm({
103526
103566
  });
103527
103567
 
103528
103568
  // ../producer/src/services/render/stages/probeStage.ts
103529
- import { join as join38 } from "path";
103569
+ import { join as join39 } from "path";
103530
103570
  function hasScriptedAudioVolumeAutomation(html, audioCount) {
103531
103571
  if (audioCount <= 0) return false;
103532
103572
  const { document: document2 } = parseHTML(html);
@@ -103574,7 +103614,7 @@ async function runProbeStage(input2) {
103574
103614
  });
103575
103615
  fileServer = await createFileServer2({
103576
103616
  projectDir,
103577
- compiledDir: join38(workDir, "compiled"),
103617
+ compiledDir: join39(workDir, "compiled"),
103578
103618
  port: 0,
103579
103619
  preHeadScripts: [VIRTUAL_TIME_SHIM],
103580
103620
  fps: job.config.fps
@@ -103595,7 +103635,7 @@ async function runProbeStage(input2) {
103595
103635
  log2.info("Creating capture session...", { attempt, maxAttempts: PROBE_MAX_ATTEMPTS });
103596
103636
  probeSession = await createCaptureSession(
103597
103637
  fileServer.url,
103598
- join38(workDir, "probe"),
103638
+ join39(workDir, "probe"),
103599
103639
  captureOpts,
103600
103640
  null,
103601
103641
  probeCfg
@@ -103675,7 +103715,7 @@ async function runProbeStage(input2) {
103675
103715
  compiled,
103676
103716
  resolutions,
103677
103717
  projectDir,
103678
- join38(workDir, "downloads")
103718
+ join39(workDir, "downloads")
103679
103719
  );
103680
103720
  assertNotAborted();
103681
103721
  composition.videos = compiled.videos;
@@ -103893,7 +103933,7 @@ var init_probeStage = __esm({
103893
103933
 
103894
103934
  // ../producer/src/services/render/stages/extractVideosStage.ts
103895
103935
  import { existsSync as existsSync39 } from "fs";
103896
- import { isAbsolute as isAbsolute12, join as join39 } from "path";
103936
+ import { isAbsolute as isAbsolute12, join as join40 } from "path";
103897
103937
  async function runExtractVideosStage(input2) {
103898
103938
  const {
103899
103939
  projectDir,
@@ -103936,7 +103976,7 @@ async function runExtractVideosStage(input2) {
103936
103976
  composition.images.map(async (img) => {
103937
103977
  let imgPath = img.src;
103938
103978
  if (!imgPath.startsWith("/")) {
103939
- const fromCompiled = existsSync39(join39(compiledDir, imgPath)) ? join39(compiledDir, imgPath) : join39(projectDir, imgPath);
103979
+ const fromCompiled = existsSync39(join40(compiledDir, imgPath)) ? join40(compiledDir, imgPath) : join40(projectDir, imgPath);
103940
103980
  imgPath = fromCompiled;
103941
103981
  }
103942
103982
  if (!existsSync39(imgPath)) return null;
@@ -103966,7 +104006,7 @@ async function runExtractVideosStage(input2) {
103966
104006
  // output framerate exact.
103967
104007
  {
103968
104008
  fps: fpsToNumber(job.config.fps),
103969
- outputDir: join39(compiledDir, "__hyperframes_video_frames"),
104009
+ outputDir: join40(compiledDir, "__hyperframes_video_frames"),
103970
104010
  format: job.config.videoFrameFormat ?? "auto"
103971
104011
  },
103972
104012
  abortSignal,
@@ -104032,18 +104072,18 @@ var init_extractVideosStage = __esm({
104032
104072
  });
104033
104073
 
104034
104074
  // ../producer/src/services/render/stages/audioStage.ts
104035
- import { join as join40 } from "path";
104075
+ import { join as join41 } from "path";
104036
104076
  async function runAudioStage(input2) {
104037
104077
  const { projectDir, workDir, compiledDir, duration, audios, abortSignal, assertNotAborted } = input2;
104038
104078
  const stage3Start = Date.now();
104039
- const audioOutputPath = join40(workDir, "audio.aac");
104079
+ const audioOutputPath = join41(workDir, "audio.aac");
104040
104080
  let hasAudio = false;
104041
104081
  let audioError;
104042
104082
  if (audios.length > 0) {
104043
104083
  const audioResult = await processCompositionAudio(
104044
104084
  audios,
104045
104085
  projectDir,
104046
- join40(workDir, "audio-work"),
104086
+ join41(workDir, "audio-work"),
104047
104087
  audioOutputPath,
104048
104088
  duration,
104049
104089
  abortSignal,
@@ -104206,7 +104246,7 @@ var init_captureStage = __esm({
104206
104246
 
104207
104247
  // ../producer/src/services/hdrCompositor.ts
104208
104248
  import { readSync as readSync2, closeSync as closeSync3 } from "fs";
104209
- import { join as join41 } from "path";
104249
+ import { join as join43 } from "path";
104210
104250
  function countNonZeroAlpha(rgba) {
104211
104251
  let n2 = 0;
104212
104252
  for (let p2 = 3; p2 < rgba.length; p2 += 4) {
@@ -104600,7 +104640,7 @@ async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter,
104600
104640
  if (shouldLog && debugDumpDir) {
104601
104641
  const after2 = countNonZeroRgb48(canvas);
104602
104642
  const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
104603
- const dumpPath = join41(debugDumpDir, dumpName);
104643
+ const dumpPath = join43(debugDumpDir, dumpName);
104604
104644
  writeFileExclusiveSync(dumpPath, domPng);
104605
104645
  log2.info("[diag] dom layer blit", {
104606
104646
  frame: debugFrameIndex,
@@ -105144,14 +105184,14 @@ var init_hdrImageTransferCache = __esm({
105144
105184
  // ../producer/src/services/render/stages/captureHdrResources.ts
105145
105185
  import {
105146
105186
  closeSync as closeSync4,
105147
- constants as constants2,
105187
+ constants as constants3,
105148
105188
  fstatSync as fstatSync2,
105149
105189
  mkdirSync as mkdirSync20,
105150
105190
  mkdtempSync as mkdtempSync3,
105151
105191
  openSync as openSync3,
105152
105192
  readFileSync as readFileSync25
105153
105193
  } from "fs";
105154
- import { join as join43 } from "path";
105194
+ import { join as join44 } from "path";
105155
105195
  function tempDirSafePrefix(id) {
105156
105196
  const safe = id.replace(/[^A-Za-z0-9_.-]/g, "_").slice(0, 80);
105157
105197
  return safe || "video";
@@ -105164,8 +105204,8 @@ function planHdrResources(args) {
105164
105204
  if (!hdrVideoIds.includes(v2.id)) continue;
105165
105205
  let srcPath = v2.src;
105166
105206
  if (!srcPath.startsWith("/")) {
105167
- const fromCompiled = join43(compiledDir, srcPath);
105168
- srcPath = args.existsSync(fromCompiled) ? fromCompiled : join43(projectDir, srcPath);
105207
+ const fromCompiled = join44(compiledDir, srcPath);
105208
+ srcPath = args.existsSync(fromCompiled) ? fromCompiled : join44(projectDir, srcPath);
105169
105209
  }
105170
105210
  hdrVideoSrcPaths.set(v2.id, srcPath);
105171
105211
  }
@@ -105239,10 +105279,10 @@ async function extractHdrVideoFrames(args) {
105239
105279
  const video = composition.videos.find((v2) => v2.id === videoId);
105240
105280
  if (!video) continue;
105241
105281
  mkdirSync20(framesDir, { recursive: true });
105242
- const frameDir = mkdtempSync3(join43(framesDir, `hdr_${tempDirSafePrefix(videoId)}-`));
105282
+ const frameDir = mkdtempSync3(join44(framesDir, `hdr_${tempDirSafePrefix(videoId)}-`));
105243
105283
  const duration = video.end - video.start;
105244
105284
  const dims = prep.hdrExtractionDims.get(videoId) ?? { width, height };
105245
- const rawPath = join43(frameDir, "frames.rgb48le");
105285
+ const rawPath = join44(frameDir, "frames.rgb48le");
105246
105286
  const ffmpegArgs = [
105247
105287
  "-ss",
105248
105288
  String(video.mediaStart),
@@ -105274,7 +105314,7 @@ async function extractHdrVideoFrames(args) {
105274
105314
  );
105275
105315
  }
105276
105316
  const frameSize = dims.width * dims.height * 6;
105277
- const fd = openSync3(rawPath, constants2.O_RDONLY | NO_FOLLOW_FLAG);
105317
+ const fd = openSync3(rawPath, constants3.O_RDONLY | NO_FOLLOW_FLAG);
105278
105318
  let handedOff = false;
105279
105319
  try {
105280
105320
  const frameCount = Math.floor(fstatSync2(fd).size / frameSize);
@@ -105348,12 +105388,12 @@ var init_captureHdrResources = __esm({
105348
105388
  "use strict";
105349
105389
  init_src();
105350
105390
  init_dist3();
105351
- NO_FOLLOW_FLAG = constants2.O_NOFOLLOW ?? 0;
105391
+ NO_FOLLOW_FLAG = constants3.O_NOFOLLOW ?? 0;
105352
105392
  }
105353
105393
  });
105354
105394
 
105355
105395
  // ../producer/src/services/render/stages/captureHdrSequentialLoop.ts
105356
- import { join as join44 } from "path";
105396
+ import { join as join45 } from "path";
105357
105397
  async function runSequentialLayeredFrameLoop(input2) {
105358
105398
  const {
105359
105399
  job,
@@ -105474,7 +105514,7 @@ async function runSequentialLayeredFrameLoop(input2) {
105474
105514
  );
105475
105515
  if (debugDumpEnabled && debugDumpDir && i2 % 30 === 0) {
105476
105516
  writeFileExclusiveSync(
105477
- join44(debugDumpDir, `frame_${String(i2).padStart(4, "0")}_final_rgb48le.bin`),
105517
+ join45(debugDumpDir, `frame_${String(i2).padStart(4, "0")}_final_rgb48le.bin`),
105478
105518
  normalCanvas
105479
105519
  );
105480
105520
  }
@@ -105521,7 +105561,7 @@ var init_captureHdrSequentialLoop = __esm({
105521
105561
  // ../producer/src/services/shaderTransitionWorkerPool.ts
105522
105562
  import { Worker } from "worker_threads";
105523
105563
  import { fileURLToPath as fileURLToPath4, pathToFileURL } from "url";
105524
- import { dirname as dirname17, join as join45 } from "path";
105564
+ import { dirname as dirname17, join as join46 } from "path";
105525
105565
  import { createRequire } from "module";
105526
105566
  import { existsSync as existsSync40 } from "fs";
105527
105567
  import { cpus as cpus3 } from "os";
@@ -105535,9 +105575,9 @@ function resolveWorkerEntry(explicit) {
105535
105575
  return { path: override, isTs };
105536
105576
  }
105537
105577
  const moduleDir = dirname17(fileURLToPath4(import.meta.url));
105538
- const jsPath = join45(moduleDir, "shaderTransitionWorker.js");
105578
+ const jsPath = join46(moduleDir, "shaderTransitionWorker.js");
105539
105579
  if (existsSync40(jsPath)) return { path: jsPath, isTs: false };
105540
- const tsPath = join45(moduleDir, "shaderTransitionWorker.ts");
105580
+ const tsPath = join46(moduleDir, "shaderTransitionWorker.ts");
105541
105581
  return { path: tsPath, isTs: true };
105542
105582
  }
105543
105583
  function buildExecArgv(entryIsTs) {
@@ -105720,7 +105760,7 @@ var init_shaderTransitionWorkerPool = __esm({
105720
105760
  });
105721
105761
 
105722
105762
  // ../producer/src/services/render/stages/captureHdrHybridLoop.ts
105723
- import { join as join46 } from "path";
105763
+ import { join as join47 } from "path";
105724
105764
  async function runHybridLayeredFrameLoop(input2) {
105725
105765
  const {
105726
105766
  job,
@@ -105913,7 +105953,7 @@ async function runHybridLayeredFrameLoop(input2) {
105913
105953
  );
105914
105954
  if (debugDumpEnabled && debugDumpDir && i2 % 30 === 0) {
105915
105955
  writeFileExclusiveSync(
105916
- join46(debugDumpDir, `frame_${String(i2).padStart(4, "0")}_final_rgb48le.bin`),
105956
+ join47(debugDumpDir, `frame_${String(i2).padStart(4, "0")}_final_rgb48le.bin`),
105917
105957
  canvas
105918
105958
  );
105919
105959
  }
@@ -105958,7 +105998,7 @@ var init_captureHdrHybridLoop = __esm({
105958
105998
 
105959
105999
  // ../producer/src/services/render/stages/captureHdrStage.ts
105960
106000
  import { existsSync as existsSync41, mkdirSync as mkdirSync21 } from "fs";
105961
- import { join as join47 } from "path";
106001
+ import { join as join48 } from "path";
105962
106002
  async function runCaptureHdrStage(input2) {
105963
106003
  const {
105964
106004
  job,
@@ -106117,7 +106157,7 @@ async function runCaptureHdrStage(input2) {
106117
106157
  if (hdrVideoFrameSources.has(v2.id)) hdrVideoEndTimes.set(v2.id, v2.end);
106118
106158
  }
106119
106159
  const debugDumpEnabled = process.env.KEEP_TEMP === "1";
106120
- const debugDumpDir = debugDumpEnabled ? join47(framesDir, "debug-composite") : null;
106160
+ const debugDumpDir = debugDumpEnabled ? join48(framesDir, "debug-composite") : null;
106121
106161
  if (debugDumpDir && !existsSync41(debugDumpDir)) {
106122
106162
  mkdirSync21(debugDumpDir, { recursive: true });
106123
106163
  }
@@ -106279,7 +106319,7 @@ var init_captureHdrStage = __esm({
106279
106319
  });
106280
106320
 
106281
106321
  // ../producer/src/services/render/stages/gifEncodeArgs.ts
106282
- import { join as join48 } from "path";
106322
+ import { join as join49 } from "path";
106283
106323
  function fpsToFfmpegArg2(fps) {
106284
106324
  return fps.den === 1 ? String(fps.num) : `${fps.num}/${fps.den}`;
106285
106325
  }
@@ -106290,7 +106330,7 @@ function buildGifPalettegenArgs(input2) {
106290
106330
  "-framerate",
106291
106331
  fpsArg,
106292
106332
  "-i",
106293
- join48(input2.framesDir, input2.framePattern),
106333
+ join49(input2.framesDir, input2.framePattern),
106294
106334
  "-vf",
106295
106335
  `fps=${fpsArg},palettegen=stats_mode=diff`,
106296
106336
  input2.palettePath
@@ -106303,7 +106343,7 @@ function buildGifPaletteuseArgs(input2) {
106303
106343
  "-framerate",
106304
106344
  fpsArg,
106305
106345
  "-i",
106306
- join48(input2.framesDir, input2.framePattern),
106346
+ join49(input2.framesDir, input2.framePattern),
106307
106347
  "-i",
106308
106348
  input2.palettePath,
106309
106349
  "-lavfi",
@@ -106321,7 +106361,7 @@ var init_gifEncodeArgs = __esm({
106321
106361
 
106322
106362
  // ../producer/src/services/render/stages/encodeStage.ts
106323
106363
  import { copyFileSync as copyFileSync5, existsSync as existsSync43, mkdirSync as mkdirSync23, readdirSync as readdirSync14, rmSync as rmSync11, statSync as statSync12 } from "fs";
106324
- import { dirname as dirname18, join as join49 } from "path";
106364
+ import { dirname as dirname18, join as join50 } from "path";
106325
106365
  function resolveGifLoop(loop) {
106326
106366
  const resolved = loop ?? 0;
106327
106367
  if (!Number.isInteger(resolved) || resolved < 0 || resolved > 65535) {
@@ -106426,11 +106466,11 @@ async function runEncodeStage(input2) {
106426
106466
  );
106427
106467
  }
106428
106468
  captured.forEach((name, i2) => {
106429
- const dst = join49(outputPath, formatExportFrameName(i2, "png"));
106430
- copyFileSync5(join49(framesDir, name), dst);
106469
+ const dst = join50(outputPath, formatExportFrameName(i2, "png"));
106470
+ copyFileSync5(join50(framesDir, name), dst);
106431
106471
  });
106432
106472
  if (hasAudio && audioOutputPath && existsSync43(audioOutputPath)) {
106433
- copyFileSync5(audioOutputPath, join49(outputPath, "audio.aac"));
106473
+ copyFileSync5(audioOutputPath, join50(outputPath, "audio.aac"));
106434
106474
  log2.info(`[Render] png-sequence: audio.aac sidecar written to ${outputPath}/audio.aac`);
106435
106475
  }
106436
106476
  return { encodeMs: Date.now() - stage5Start };
@@ -106446,7 +106486,7 @@ async function runEncodeStage(input2) {
106446
106486
  const encodeResult2 = await encodeGifFromDir(framesDir, framePattern2, outputPath, {
106447
106487
  fps: job.config.fps,
106448
106488
  loop,
106449
- palettePath: join49(dirname18(videoOnlyPath), "gif-palette.png"),
106489
+ palettePath: join50(dirname18(videoOnlyPath), "gif-palette.png"),
106450
106490
  signal: abortSignal,
106451
106491
  timeout: engineCfg.ffmpegEncodeTimeout
106452
106492
  });
@@ -106572,7 +106612,7 @@ import {
106572
106612
  copyFileSync as copyFileSync6,
106573
106613
  appendFileSync
106574
106614
  } from "fs";
106575
- import { join as join50, dirname as dirname19, resolve as resolve26 } from "path";
106615
+ import { join as join51, dirname as dirname19, resolve as resolve26 } from "path";
106576
106616
  import { randomUUID as randomUUID4 } from "crypto";
106577
106617
  import { fileURLToPath as fileURLToPath5 } from "url";
106578
106618
  function sampleDirectoryBytes(dir) {
@@ -106588,7 +106628,7 @@ function sampleDirectoryBytes(dir) {
106588
106628
  continue;
106589
106629
  }
106590
106630
  for (const name of entries2) {
106591
- const full2 = join50(current2, name);
106631
+ const full2 = join51(current2, name);
106592
106632
  try {
106593
106633
  const st3 = statSync13(full2);
106594
106634
  if (st3.isDirectory()) {
@@ -106677,7 +106717,7 @@ function findMissingFrameRanges(totalFrames, framesDir, frameExt) {
106677
106717
  const ranges = [];
106678
106718
  let rangeStart = null;
106679
106719
  for (let frameIndex = 0; frameIndex < totalFrames; frameIndex++) {
106680
- const framePath = join50(framesDir, formatCaptureFrameName(frameIndex, frameExt));
106720
+ const framePath = join51(framesDir, formatCaptureFrameName(frameIndex, frameExt));
106681
106721
  const missing = !existsSync44(framePath);
106682
106722
  if (missing && rangeStart === null) {
106683
106723
  rangeStart = frameIndex;
@@ -106700,7 +106740,7 @@ function buildMissingFrameRetryBatches(ranges, maxWorkers, workDir, attempt, ran
106700
106740
  workerId,
106701
106741
  startFrame: rangeStart + range.startFrame,
106702
106742
  endFrame: rangeStart + range.endFrame,
106703
- outputDir: join50(workDir, `retry-${attempt}-batch-${batchIndex}-worker-${workerId}`),
106743
+ outputDir: join51(workDir, `retry-${attempt}-batch-${batchIndex}-worker-${workerId}`),
106704
106744
  outputFrameOffset: rangeStart
106705
106745
  }));
106706
106746
  batches.push(batch);
@@ -106733,7 +106773,7 @@ The composition is too large for the available memory. To reduce memory pressure
106733
106773
  function countCapturedFrames(totalFrames, framesDir, frameExt) {
106734
106774
  let captured = 0;
106735
106775
  for (let frameIndex = 0; frameIndex < totalFrames; frameIndex++) {
106736
- const framePath = join50(framesDir, formatCaptureFrameName(frameIndex, frameExt));
106776
+ const framePath = join51(framesDir, formatCaptureFrameName(frameIndex, frameExt));
106737
106777
  if (existsSync44(framePath)) captured++;
106738
106778
  }
106739
106779
  return captured;
@@ -106758,7 +106798,7 @@ async function executeDiskCaptureWithAdaptiveRetry(options) {
106758
106798
  reason: attempt === 0 ? "initial" : pendingTransientRetry ? "transient-retry" : "retry"
106759
106799
  });
106760
106800
  pendingTransientRetry = false;
106761
- const attemptWorkDir = join50(options.workDir, `capture-attempt-${attempt}`);
106801
+ const attemptWorkDir = join51(options.workDir, `capture-attempt-${attempt}`);
106762
106802
  const batches = missingRanges ? buildMissingFrameRetryBatches(
106763
106803
  missingRanges,
106764
106804
  currentWorkers,
@@ -106943,10 +106983,10 @@ function extractStandaloneEntryFromIndex(indexHtml, entryFile) {
106943
106983
  async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSignal) {
106944
106984
  const moduleDir = dirname19(fileURLToPath5(import.meta.url));
106945
106985
  const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve26(process.env.PRODUCER_RENDERS_DIR, "..") : resolve26(moduleDir, "../..");
106946
- const debugDir = join50(producerRoot, ".debug");
106986
+ const debugDir = join51(producerRoot, ".debug");
106947
106987
  const outputDir = dirname19(outputPath);
106948
106988
  if (!existsSync44(outputDir)) mkdirSync24(outputDir, { recursive: true });
106949
- const workDir = job.config.debug ? join50(debugDir, job.id) : mkdtempSync4(join50(outputDir, `work-${job.id}-`));
106989
+ const workDir = job.config.debug ? join51(debugDir, job.id) : mkdtempSync4(join51(outputDir, `work-${job.id}-`));
106950
106990
  const pipelineStart = Date.now();
106951
106991
  const log2 = job.config.logger ?? defaultLogger;
106952
106992
  let fileServer = null;
@@ -106962,7 +107002,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
106962
107002
  imageDecodeFailures: 0
106963
107003
  };
106964
107004
  let hdrPerf;
106965
- const perfOutputPath = join50(workDir, "perf-summary.json");
107005
+ const perfOutputPath = join51(workDir, "perf-summary.json");
106966
107006
  const cfg = { ...job.config.producerConfig ?? resolveConfig() };
106967
107007
  const observability = new RenderObservabilityRecorder({
106968
107008
  pipelineStartMs: pipelineStart,
@@ -107009,7 +107049,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
107009
107049
  assertConfiguredFfmpegBinariesExist();
107010
107050
  if (!existsSync44(workDir)) mkdirSync24(workDir, { recursive: true });
107011
107051
  if (job.config.debug) {
107012
- const logPath = join50(workDir, "render.log");
107052
+ const logPath = join51(workDir, "render.log");
107013
107053
  restoreLogger = installDebugLogger(logPath, log2);
107014
107054
  log2.info("[Render] Debug artifacts enabled", { workDir, logPath });
107015
107055
  }
@@ -107038,15 +107078,15 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
107038
107078
  requestedWorkers: job.config.workers ?? "auto"
107039
107079
  });
107040
107080
  const entryFile = job.config.entryFile || "index.html";
107041
- let htmlPath = join50(projectDir, entryFile);
107081
+ let htmlPath = join51(projectDir, entryFile);
107042
107082
  if (!existsSync44(htmlPath)) {
107043
107083
  throw new Error(`Entry file not found: ${htmlPath}`);
107044
107084
  }
107045
107085
  assertNotAborted();
107046
107086
  const rawEntry = readFileSync26(htmlPath, "utf-8");
107047
107087
  if (entryFile !== "index.html" && rawEntry.trimStart().startsWith("<template")) {
107048
- const wrapperPath = join50(workDir, "standalone-entry.html");
107049
- const projectIndexPath = join50(projectDir, "index.html");
107088
+ const wrapperPath = join51(workDir, "standalone-entry.html");
107089
+ const projectIndexPath = join51(projectDir, "index.html");
107050
107090
  if (!existsSync44(projectIndexPath)) {
107051
107091
  throw new Error(
107052
107092
  `Template entry file "${entryFile}" requires a project index.html to extract its render shell.`
@@ -107169,7 +107209,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
107169
107209
  compositionHash
107170
107210
  });
107171
107211
  updateJobStatus(job, "preprocessing", "Extracting video frames", 10, onProgress);
107172
- const compiledDir = join50(workDir, "compiled");
107212
+ const compiledDir = join51(workDir, "compiled");
107173
107213
  const extractResult = await observeRenderStage(
107174
107214
  observability,
107175
107215
  "video_extract",
@@ -107253,7 +107293,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
107253
107293
  try {
107254
107294
  fileServer = await createFileServer2({
107255
107295
  projectDir,
107256
- compiledDir: join50(workDir, "compiled"),
107296
+ compiledDir: join51(workDir, "compiled"),
107257
107297
  port: 0,
107258
107298
  preHeadScripts: [VIRTUAL_TIME_SHIM],
107259
107299
  fps: job.config.fps
@@ -107271,7 +107311,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
107271
107311
  if (!activeFileServer) {
107272
107312
  throw new Error("File server failed to initialize before frame capture");
107273
107313
  }
107274
- const framesDir = join50(workDir, "captured-frames");
107314
+ const framesDir = join51(workDir, "captured-frames");
107275
107315
  if (!existsSync44(framesDir)) mkdirSync24(framesDir, { recursive: true });
107276
107316
  const resolvedBrowserGpuMode = await resolveBrowserGpuMode(cfg.browserGpuMode, {
107277
107317
  chromePath: resolveHeadlessShellPath(cfg),
@@ -107381,7 +107421,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
107381
107421
  gif: ".gif"
107382
107422
  };
107383
107423
  const videoExt = FORMAT_EXT3[outputFormat] ?? ".mp4";
107384
- const videoOnlyPath = join50(workDir, `video-only${videoExt}`);
107424
+ const videoOnlyPath = join51(workDir, `video-only${videoExt}`);
107385
107425
  const nativeHdrIds = /* @__PURE__ */ new Set([...nativeHdrVideoIds, ...nativeHdrImageIds]);
107386
107426
  const hasHdrContent = Boolean(effectiveHdr && nativeHdrIds.size > 0);
107387
107427
  const usePageSideCompositingForTransitions = (cfg.enablePageSideCompositing || isGif) && compiled.hasShaderTransitions && !hasHdrContent && !isPngSequence && !needsAlpha;
@@ -107701,7 +107741,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
107701
107741
  }
107702
107742
  if (job.config.debug) {
107703
107743
  if (!isPngSequence && existsSync44(outputPath)) {
107704
- const debugOutput = join50(workDir, `output${videoExt}`);
107744
+ const debugOutput = join51(workDir, `output${videoExt}`);
107705
107745
  copyFileSync6(outputPath, debugOutput);
107706
107746
  }
107707
107747
  } else if (process.env.KEEP_TEMP === "1") {
@@ -107863,7 +107903,7 @@ var init_config3 = __esm({
107863
107903
 
107864
107904
  // ../producer/src/services/hyperframeLint.ts
107865
107905
  import { existsSync as existsSync45, readFileSync as readFileSync27, statSync as statSync14 } from "fs";
107866
- import { resolve as resolve27, join as join51 } from "path";
107906
+ import { resolve as resolve27, join as join53 } from "path";
107867
107907
  function isStringRecord2(value) {
107868
107908
  if (!value || typeof value !== "object" || Array.isArray(value)) {
107869
107909
  return false;
@@ -107911,7 +107951,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
107911
107951
  }
107912
107952
  }
107913
107953
  return {
107914
- error: `No HTML entry file found in project directory: ${join51(absProjectDir, preferredEntryFile || "index.html")}`
107954
+ error: `No HTML entry file found in project directory: ${join53(absProjectDir, preferredEntryFile || "index.html")}`
107915
107955
  };
107916
107956
  }
107917
107957
  function prepareHyperframeLintBody(body) {
@@ -107960,7 +108000,7 @@ var init_hyperframeLint = __esm({
107960
108000
  // ../producer/src/services/healthWorker.ts
107961
108001
  import { Worker as Worker2 } from "worker_threads";
107962
108002
  import { fileURLToPath as fileURLToPath6 } from "url";
107963
- import { dirname as dirname20, join as join53 } from "path";
108003
+ import { dirname as dirname20, join as join54 } from "path";
107964
108004
  import { existsSync as existsSync46 } from "fs";
107965
108005
  async function startHealthWorker(options = {}) {
107966
108006
  const log2 = options.logger ?? defaultLogger2();
@@ -108035,7 +108075,7 @@ function defaultLogger2() {
108035
108075
  }
108036
108076
  function resolveWorkerEntry2() {
108037
108077
  const here = dirname20(fileURLToPath6(import.meta.url));
108038
- const candidates = [join53(here, "healthWorkerThread.js"), join53(here, "healthWorkerThread.ts")];
108078
+ const candidates = [join54(here, "healthWorkerThread.js"), join54(here, "healthWorkerThread.ts")];
108039
108079
  for (const candidate of candidates) {
108040
108080
  if (existsSync46(candidate)) return candidate;
108041
108081
  }
@@ -108100,7 +108140,7 @@ import {
108100
108140
  rmSync as rmSync13,
108101
108141
  createReadStream as createReadStream2
108102
108142
  } from "fs";
108103
- import { resolve as resolve28, dirname as dirname21, join as join54 } from "path";
108143
+ import { resolve as resolve28, dirname as dirname21, join as join55 } from "path";
108104
108144
  import { tmpdir as tmpdir5 } from "os";
108105
108145
  import { parseArgs as parseArgs2 } from "util";
108106
108146
  import crypto2 from "crypto";
@@ -108220,8 +108260,8 @@ async function prepareRenderBody(body) {
108220
108260
  }
108221
108261
  }
108222
108262
  const tempRoot = process.env.PRODUCER_TMP_PROJECT_DIR || tmpdir5();
108223
- const tempProjectDir = mkdtempSync5(join54(tempRoot, "producer-project-"));
108224
- writeFileSync15(join54(tempProjectDir, "index.html"), htmlContent, "utf-8");
108263
+ const tempProjectDir = mkdtempSync5(join55(tempRoot, "producer-project-"));
108264
+ writeFileSync15(join55(tempProjectDir, "index.html"), htmlContent, "utf-8");
108225
108265
  return {
108226
108266
  prepared: {
108227
108267
  input: {
@@ -108702,7 +108742,7 @@ var init_planHash = __esm({
108702
108742
 
108703
108743
  // ../producer/src/services/render/stages/freezePlan.ts
108704
108744
  import { existsSync as existsSync48, mkdirSync as mkdirSync26, readFileSync as readFileSync28, readdirSync as readdirSync16, writeFileSync as writeFileSync16 } from "fs";
108705
- import { join as join55, relative as relative9, resolve as resolve29 } from "path";
108745
+ import { join as join56, relative as relative9, resolve as resolve29 } from "path";
108706
108746
  function stripUndefined(value) {
108707
108747
  if (Array.isArray(value)) return value.map(stripUndefined);
108708
108748
  if (value !== null && typeof value === "object") {
@@ -108723,7 +108763,7 @@ function listPlanFiles(planDir) {
108723
108763
  function walk(dir) {
108724
108764
  const entries2 = readdirSync16(dir, { withFileTypes: true });
108725
108765
  for (const entry of entries2) {
108726
- const full2 = join55(dir, entry.name);
108766
+ const full2 = join56(dir, entry.name);
108727
108767
  if (entry.isDirectory()) {
108728
108768
  walk(full2);
108729
108769
  } else if (entry.isFile()) {
@@ -108759,8 +108799,8 @@ function collectPlanAssetShas(planDir) {
108759
108799
  return { compositionHtml, assets };
108760
108800
  }
108761
108801
  function recomputePlanHashFromPlanDir(planDir) {
108762
- const planJsonPath = join55(planDir, "plan.json");
108763
- const encoderJsonPath = join55(planDir, "meta", "encoder.json");
108802
+ const planJsonPath = join56(planDir, "plan.json");
108803
+ const encoderJsonPath = join56(planDir, "meta", "encoder.json");
108764
108804
  if (!existsSync48(planJsonPath)) {
108765
108805
  throw new Error(`[freezePlan] plan.json missing: ${planJsonPath}`);
108766
108806
  }
@@ -108796,18 +108836,18 @@ async function freezePlan(input2) {
108796
108836
  if (!existsSync48(planDir)) {
108797
108837
  throw new Error(`[freezePlan] planDir does not exist: ${planDir}`);
108798
108838
  }
108799
- const metaDir = join55(planDir, "meta");
108839
+ const metaDir = join56(planDir, "meta");
108800
108840
  if (!existsSync48(metaDir)) mkdirSync26(metaDir, { recursive: true });
108801
108841
  writeFileSync16(
108802
- join55(metaDir, "composition.json"),
108842
+ join56(metaDir, "composition.json"),
108803
108843
  `${JSON.stringify(composition, null, 2)}
108804
108844
  `,
108805
108845
  "utf-8"
108806
108846
  );
108807
108847
  const encoderForCanonical = stripUndefined(encoder);
108808
108848
  const encoderConfigCanonicalJson = canonicalJsonStringify(encoderForCanonical);
108809
- writeFileSync16(join55(metaDir, "encoder.json"), encoderConfigCanonicalJson, "utf-8");
108810
- writeFileSync16(join55(metaDir, "chunks.json"), `${JSON.stringify(chunks, null, 2)}
108849
+ writeFileSync16(join56(metaDir, "encoder.json"), encoderConfigCanonicalJson, "utf-8");
108850
+ writeFileSync16(join56(metaDir, "chunks.json"), `${JSON.stringify(chunks, null, 2)}
108811
108851
  `, "utf-8");
108812
108852
  const { compositionHtml, assets } = collectPlanAssetShas(planDir);
108813
108853
  const planHash = computePlanHash({
@@ -108830,7 +108870,7 @@ async function freezePlan(input2) {
108830
108870
  duration: durationSeconds,
108831
108871
  hasAudio
108832
108872
  };
108833
- const planJsonPath = join55(planDir, "plan.json");
108873
+ const planJsonPath = join56(planDir, "plan.json");
108834
108874
  writeFileSync16(planJsonPath, `${JSON.stringify(planJson, null, 2)}
108835
108875
  `, "utf-8");
108836
108876
  return { planJsonPath, planHash };
@@ -108953,7 +108993,7 @@ var init_runtimeEnvSnapshot = __esm({
108953
108993
 
108954
108994
  // ../producer/src/services/distributed/shared.ts
108955
108995
  import { execFile as execFileCallback } from "child_process";
108956
- import { dirname as dirname22, join as join56 } from "path";
108996
+ import { dirname as dirname22, join as join57 } from "path";
108957
108997
  import { existsSync as existsSync49, readFileSync as readFileSync29 } from "fs";
108958
108998
  import { fileURLToPath as fileURLToPath7 } from "url";
108959
108999
  import { promisify as promisify3 } from "util";
@@ -108992,7 +109032,7 @@ function readProducerVersion() {
108992
109032
  const startDir = dirname22(fileURLToPath7(import.meta.url));
108993
109033
  let current2 = startDir;
108994
109034
  for (let i2 = 0; i2 < 10; i2++) {
108995
- const candidate = join56(current2, "package.json");
109035
+ const candidate = join57(current2, "package.json");
108996
109036
  if (existsSync49(candidate)) {
108997
109037
  try {
108998
109038
  const pkg = JSON.parse(readFileSync29(candidate, "utf-8"));
@@ -109034,7 +109074,7 @@ import {
109034
109074
  statSync as statSync16,
109035
109075
  writeFileSync as writeFileSync17
109036
109076
  } from "fs";
109037
- import { join as join57, relative as relative10, sep as sep6 } from "path";
109077
+ import { join as join58, relative as relative10, sep as sep6 } from "path";
109038
109078
  function formatBytes2(bytes) {
109039
109079
  if (bytes < 1024) return `${bytes} B`;
109040
109080
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KiB`;
@@ -109059,7 +109099,7 @@ function measurePlanDirBytes(planDir) {
109059
109099
  return;
109060
109100
  }
109061
109101
  for (const entry of entries2) {
109062
- const full2 = join57(dir, entry.name);
109102
+ const full2 = join58(dir, entry.name);
109063
109103
  if (entry.isDirectory()) {
109064
109104
  walk(full2);
109065
109105
  } else if (entry.isFile()) {
@@ -109227,13 +109267,13 @@ async function plan(projectDir, config, planDir) {
109227
109267
  producerConfig: config.producerConfig
109228
109268
  });
109229
109269
  const entryFile = config.entryFile ?? "index.html";
109230
- const htmlPath = join57(projectDir, entryFile);
109270
+ const htmlPath = join58(projectDir, entryFile);
109231
109271
  if (!existsSync50(htmlPath)) {
109232
109272
  throw new Error(`[plan] entry file not found: ${htmlPath}`);
109233
109273
  }
109234
- const workDir = join57(planDir, ".plan-work");
109274
+ const workDir = join58(planDir, ".plan-work");
109235
109275
  if (!existsSync50(workDir)) mkdirSync27(workDir, { recursive: true });
109236
- const compiledDir = join57(workDir, "compiled");
109276
+ const compiledDir = join58(workDir, "compiled");
109237
109277
  mkdirSync27(compiledDir, { recursive: true });
109238
109278
  cpSync3(projectDir, compiledDir, {
109239
109279
  recursive: true,
@@ -109245,7 +109285,7 @@ async function plan(projectDir, config, planDir) {
109245
109285
  return firstSegment === void 0 || !PLAN_PROJECT_DIR_SKIP_SEGMENTS.has(firstSegment);
109246
109286
  }
109247
109287
  });
109248
- const finalCompiledDir = join57(planDir, "compiled");
109288
+ const finalCompiledDir = join58(planDir, "compiled");
109249
109289
  const needsAlpha = config.format === "png-sequence" || config.format === "mov" || config.format === "webm";
109250
109290
  const compileResult = await runCompileStage({
109251
109291
  projectDir,
@@ -109330,8 +109370,8 @@ async function plan(projectDir, config, planDir) {
109330
109370
  if (audioResult.audioError) {
109331
109371
  log2.warn(`[Render] Audio mix failed \u2014 output will be video-only: ${audioResult.audioError}`);
109332
109372
  }
109333
- const stagedVideoFrames = join57(compiledDir, "__hyperframes_video_frames");
109334
- const videoFramesDst = join57(planDir, "video-frames");
109373
+ const stagedVideoFrames = join58(compiledDir, "__hyperframes_video_frames");
109374
+ const videoFramesDst = join58(planDir, "video-frames");
109335
109375
  if (existsSync50(videoFramesDst)) rmSync14(videoFramesDst, { recursive: true, force: true });
109336
109376
  if (existsSync50(stagedVideoFrames)) {
109337
109377
  renameSync6(stagedVideoFrames, videoFramesDst);
@@ -109351,13 +109391,13 @@ async function plan(projectDir, config, planDir) {
109351
109391
  metadata: ext.metadata
109352
109392
  }))
109353
109393
  };
109354
- mkdirSync27(join57(planDir, "meta"), { recursive: true });
109394
+ mkdirSync27(join58(planDir, "meta"), { recursive: true });
109355
109395
  writeFileSync17(
109356
- join57(planDir, PLAN_VIDEOS_META_RELATIVE_PATH),
109396
+ join58(planDir, PLAN_VIDEOS_META_RELATIVE_PATH),
109357
109397
  JSON.stringify(planVideosJson, null, 2),
109358
109398
  "utf-8"
109359
109399
  );
109360
- const planAudioPath = join57(planDir, "audio.aac");
109400
+ const planAudioPath = join58(planDir, "audio.aac");
109361
109401
  if (audioResult.hasAudio && existsSync50(audioResult.audioOutputPath)) {
109362
109402
  renameSync6(audioResult.audioOutputPath, planAudioPath);
109363
109403
  }
@@ -109502,11 +109542,11 @@ var init_plan = __esm({
109502
109542
  // ../producer/src/services/distributed/renderChunk.ts
109503
109543
  import { randomBytes as randomBytes2 } from "crypto";
109504
109544
  import { existsSync as existsSync51, mkdirSync as mkdirSync28, readFileSync as readFileSync30, readdirSync as readdirSync18, rmSync as rmSync15, writeFileSync as writeFileSync18 } from "fs";
109505
- import { extname as extname10, join as join58 } from "path";
109545
+ import { extname as extname10, join as join59 } from "path";
109506
109546
  function rebuildExtractedFramesFromPlanDir(planDir, videos) {
109507
109547
  const result = [];
109508
109548
  for (const v2 of videos) {
109509
- const outputDir = join58(planDir, "video-frames", v2.videoId);
109549
+ const outputDir = join59(planDir, "video-frames", v2.videoId);
109510
109550
  if (!existsSync51(outputDir)) {
109511
109551
  throw new Error(
109512
109552
  `[renderChunk] planDir missing extracted video frames for ${JSON.stringify(v2.videoId)}: ${outputDir} not present. plan() should have written frames here; the planDir is malformed.`
@@ -109518,7 +109558,7 @@ function rebuildExtractedFramesFromPlanDir(planDir, videos) {
109518
109558
  for (let i2 = 0; i2 < frames.length; i2++) {
109519
109559
  const frameName = frames[i2];
109520
109560
  if (!frameName) continue;
109521
- framePaths.set(i2, join58(outputDir, frameName));
109561
+ framePaths.set(i2, join59(outputDir, frameName));
109522
109562
  }
109523
109563
  result.push({
109524
109564
  videoId: v2.videoId,
@@ -109543,7 +109583,7 @@ function hashChunkOutput(outputPath, kind) {
109543
109583
  if (kind === "file") return sha256Hex(readFileSync30(outputPath));
109544
109584
  const entries2 = readdirSync18(outputPath).filter((name) => /\.(png|jpg|jpeg)$/i.test(name)).sort();
109545
109585
  const lines = entries2.map(
109546
- (name) => `${name}\0${sha256Hex(readFileSync30(join58(outputPath, name)))}`
109586
+ (name) => `${name}\0${sha256Hex(readFileSync30(join59(outputPath, name)))}`
109547
109587
  );
109548
109588
  return sha256Hex(lines.join("\0"));
109549
109589
  }
@@ -109560,9 +109600,9 @@ function resolveLockedVp9CpuUsed(lockedEncoder) {
109560
109600
  async function renderChunk(planDir, chunkIndex, outputChunkPath) {
109561
109601
  const start = Date.now();
109562
109602
  const log2 = defaultLogger;
109563
- const planJsonPath = join58(planDir, "plan.json");
109564
- const encoderJsonPath = join58(planDir, "meta", "encoder.json");
109565
- const chunksJsonPath = join58(planDir, "meta", "chunks.json");
109603
+ const planJsonPath = join59(planDir, "plan.json");
109604
+ const encoderJsonPath = join59(planDir, "meta", "encoder.json");
109605
+ const chunksJsonPath = join59(planDir, "meta", "chunks.json");
109566
109606
  for (const required of [planJsonPath, encoderJsonPath, chunksJsonPath]) {
109567
109607
  if (!existsSync51(required)) {
109568
109608
  throw new RenderChunkValidationError(
@@ -109574,7 +109614,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
109574
109614
  const plan2 = JSON.parse(readFileSync30(planJsonPath, "utf-8"));
109575
109615
  const encoder = JSON.parse(readFileSync30(encoderJsonPath, "utf-8"));
109576
109616
  const chunks = JSON.parse(readFileSync30(chunksJsonPath, "utf-8"));
109577
- const videosJsonPath = join58(planDir, PLAN_VIDEOS_META_RELATIVE_PATH);
109617
+ const videosJsonPath = join59(planDir, PLAN_VIDEOS_META_RELATIVE_PATH);
109578
109618
  let planVideos = null;
109579
109619
  if (existsSync51(videosJsonPath)) {
109580
109620
  try {
@@ -109603,7 +109643,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
109603
109643
  `[renderChunk] chunk ${chunkIndex} has non-positive frame count: ${framesInChunk}`
109604
109644
  );
109605
109645
  }
109606
- const compiledDir = join58(planDir, "compiled");
109646
+ const compiledDir = join59(planDir, "compiled");
109607
109647
  if (!existsSync51(compiledDir)) {
109608
109648
  throw new RenderChunkValidationError(
109609
109649
  MISSING_PLAN_ARTIFACT,
@@ -109668,7 +109708,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
109668
109708
  );
109669
109709
  const workDir = `${outputChunkPath}.work.${process.pid}.${randomBytes2(4).toString("hex")}`;
109670
109710
  mkdirSync28(workDir, { recursive: true });
109671
- const framesDir = join58(workDir, "captured-frames");
109711
+ const framesDir = join59(workDir, "captured-frames");
109672
109712
  mkdirSync28(framesDir, { recursive: true });
109673
109713
  const fileServer = await createFileServer2({
109674
109714
  projectDir: compiledDir,
@@ -109750,7 +109790,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
109750
109790
  if (isPngSequence) {
109751
109791
  if (!existsSync51(outputChunkPath)) mkdirSync28(outputChunkPath, { recursive: true });
109752
109792
  } else {
109753
- const outDir = join58(outputChunkPath, "..");
109793
+ const outDir = join59(outputChunkPath, "..");
109754
109794
  if (!existsSync51(outDir)) mkdirSync28(outDir, { recursive: true });
109755
109795
  }
109756
109796
  const encodeStarted = Date.now();
@@ -110197,14 +110237,14 @@ import {
110197
110237
  statSync as statSync17,
110198
110238
  writeFileSync as writeFileSync19
110199
110239
  } from "fs";
110200
- import { dirname as dirname23, join as join59 } from "path";
110240
+ import { dirname as dirname23, join as join60 } from "path";
110201
110241
  async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
110202
110242
  const start = Date.now();
110203
110243
  const log2 = options?.logger ?? defaultLogger;
110204
110244
  const abortSignal = options?.abortSignal;
110205
110245
  const cfr = options?.cfr === true;
110206
- const planJsonPath = join59(planDir, "plan.json");
110207
- const chunksJsonPath = join59(planDir, "meta", "chunks.json");
110246
+ const planJsonPath = join60(planDir, "plan.json");
110247
+ const chunksJsonPath = join60(planDir, "meta", "chunks.json");
110208
110248
  if (!existsSync53(planJsonPath)) {
110209
110249
  throw new Error(`[assemble] planDir missing plan.json: ${planJsonPath}`);
110210
110250
  }
@@ -110233,7 +110273,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
110233
110273
  if (existsSync53(workDir)) rmSync17(workDir, { recursive: true, force: true });
110234
110274
  mkdirSync29(workDir, { recursive: true });
110235
110275
  try {
110236
- const concatOutputPath = join59(workDir, `concat.${plan2.dimensions.format}`);
110276
+ const concatOutputPath = join60(workDir, `concat.${plan2.dimensions.format}`);
110237
110277
  const fpsArg = fpsToFfmpegArg({
110238
110278
  num: plan2.dimensions.fpsNum,
110239
110279
  den: plan2.dimensions.fpsDen
@@ -110247,7 +110287,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
110247
110287
  );
110248
110288
  }
110249
110289
  } else {
110250
- const concatListPath = join59(workDir, "concat-list.txt");
110290
+ const concatListPath = join60(workDir, "concat-list.txt");
110251
110291
  const concatBody = chunkPaths.map((path2) => `file '${path2.replace(/'/g, "'\\''")}'`).join("\n");
110252
110292
  writeFileSync19(concatListPath, `${concatBody}
110253
110293
  `, "utf-8");
@@ -110279,7 +110319,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
110279
110319
  `[assemble] cfr=true is only supported for format="mp4" (got "${plan2.dimensions.format}"). Stream-copy paths for webm and mov already produce exact avg_frame_rate; cfr re-encode is not needed.`
110280
110320
  );
110281
110321
  }
110282
- const encoderJsonPath = join59(planDir, "meta", "encoder.json");
110322
+ const encoderJsonPath = join60(planDir, "meta", "encoder.json");
110283
110323
  if (!existsSync53(encoderJsonPath)) {
110284
110324
  throw new Error(`[assemble] planDir missing meta/encoder.json: ${encoderJsonPath}`);
110285
110325
  }
@@ -110289,7 +110329,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
110289
110329
  `[assemble] cfr=true is not yet supported with codec: "h265". The cfr re-encode pass uses libx264 and would silently transcode the h265 chunks. Either disable cfr or render with codec: "h264".`
110290
110330
  );
110291
110331
  }
110292
- const cfrOutputPath = join59(workDir, `cfr.${plan2.dimensions.format}`);
110332
+ const cfrOutputPath = join60(workDir, `cfr.${plan2.dimensions.format}`);
110293
110333
  const cfrArgs = [
110294
110334
  "-i",
110295
110335
  concatOutputPath,
@@ -110323,7 +110363,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
110323
110363
  }
110324
110364
  let audioForMux = null;
110325
110365
  if (audioPath !== null && existsSync53(audioPath)) {
110326
- const paddedAudioPath = join59(workDir, "audio-padded.aac");
110366
+ const paddedAudioPath = join60(workDir, "audio-padded.aac");
110327
110367
  const padTrimResult = await padOrTrimAudioToVideoFrameCount({
110328
110368
  videoPath: postConcatPath,
110329
110369
  audioPath,
@@ -110339,7 +110379,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
110339
110379
  sourceDurationSeconds: padTrimResult.sourceDurationSeconds
110340
110380
  });
110341
110381
  }
110342
- const muxOutputPath = audioForMux !== null ? join59(workDir, `mux.${plan2.dimensions.format}`) : postConcatPath;
110382
+ const muxOutputPath = audioForMux !== null ? join60(workDir, `mux.${plan2.dimensions.format}`) : postConcatPath;
110343
110383
  if (audioForMux !== null) {
110344
110384
  const muxResult = await muxVideoWithAudio(
110345
110385
  postConcatPath,
@@ -110399,8 +110439,8 @@ function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, start
110399
110439
  throw new Error(`[assemble] png-sequence chunk has no frames: ${chunkDir}`);
110400
110440
  }
110401
110441
  for (const frame of frames) {
110402
- const dst = join59(outputPath, formatExportFrameName(globalIdx, "png"));
110403
- cpSync4(join59(chunkDir, frame), dst);
110442
+ const dst = join60(outputPath, formatExportFrameName(globalIdx, "png"));
110443
+ cpSync4(join60(chunkDir, frame), dst);
110404
110444
  globalIdx += 1;
110405
110445
  }
110406
110446
  }
@@ -110410,13 +110450,13 @@ function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, start
110410
110450
  );
110411
110451
  }
110412
110452
  if (audioPath !== null && existsSync53(audioPath)) {
110413
- const sidecar = join59(outputPath, "audio.aac");
110453
+ const sidecar = join60(outputPath, "audio.aac");
110414
110454
  cpSync4(audioPath, sidecar);
110415
110455
  }
110416
110456
  let fileSize = 0;
110417
110457
  for (const name of readdirSync19(outputPath)) {
110418
110458
  try {
110419
- fileSize += statSync17(join59(outputPath, name)).size;
110459
+ fileSize += statSync17(join60(outputPath, name)).size;
110420
110460
  } catch {
110421
110461
  }
110422
110462
  }
@@ -110449,7 +110489,7 @@ var init_renderConfigValidation = __esm({
110449
110489
  // ../producer/src/services/distributed/projectHash.ts
110450
110490
  import { readdirSync as readdirSync20, readFileSync as readFileSync33 } from "fs";
110451
110491
  import { createHash as createHash11 } from "crypto";
110452
- import { join as join60, relative as relative11 } from "path";
110492
+ import { join as join61, relative as relative11 } from "path";
110453
110493
  var init_projectHash = __esm({
110454
110494
  "../producer/src/services/distributed/projectHash.ts"() {
110455
110495
  "use strict";
@@ -110531,7 +110571,7 @@ __export(studioServer_exports, {
110531
110571
  import { Hono as Hono5 } from "hono";
110532
110572
  import { streamSSE as streamSSE3 } from "hono/streaming";
110533
110573
  import { existsSync as existsSync54, readFileSync as readFileSync34, writeFileSync as writeFileSync20, statSync as statSync18 } from "fs";
110534
- import { resolve as resolve30, join as join61, basename as basename8 } from "path";
110574
+ import { resolve as resolve30, join as join63, basename as basename8 } from "path";
110535
110575
  function resolveDistDir() {
110536
110576
  return resolveStudioBundle().dir;
110537
110577
  }
@@ -110576,7 +110616,7 @@ function resolveRuntimePath() {
110576
110616
  return builtPath;
110577
110617
  }
110578
110618
  function readStudioManualEditManifestContent(projectDir) {
110579
- const manifestPath2 = join61(projectDir, STUDIO_MANUAL_EDITS_PATH2);
110619
+ const manifestPath2 = join63(projectDir, STUDIO_MANUAL_EDITS_PATH2);
110580
110620
  if (!existsSync54(manifestPath2)) return "";
110581
110621
  try {
110582
110622
  return readFileSync34(manifestPath2, "utf-8");
@@ -110682,7 +110722,7 @@ async function loadPreviewServerBuildSignature() {
110682
110722
  ]);
110683
110723
  }
110684
110724
  function rewriteWrittenToHostViewport(projectDir, written) {
110685
- const indexPath2 = join61(projectDir, "index.html");
110725
+ const indexPath2 = join63(projectDir, "index.html");
110686
110726
  if (!existsSync54(indexPath2)) return;
110687
110727
  const indexHtml = readFileSync34(indexPath2, "utf-8");
110688
110728
  const hostW = indexHtml.match(/data-width="(\d+)"/)?.[1];
@@ -110739,8 +110779,8 @@ function createStudioServer(options) {
110739
110779
  const { injectDeterministicFontFaces: injectDeterministicFontFaces2 } = await Promise.resolve().then(() => (init_deterministicFonts(), deterministicFonts_exports));
110740
110780
  const { prepareAnimatedGifInputs: prepareAnimatedGifInputs2 } = await Promise.resolve().then(() => (init_animatedGifPrep(), animatedGifPrep_exports));
110741
110781
  const { downloadToTemp: downloadToTemp2 } = await Promise.resolve().then(() => (init_urlDownloader2(), urlDownloader_exports));
110742
- const gifOutputDir = join61(project2.dir, ".hyperframes", "prepared-assets", "gif");
110743
- const gifDownloadDir = join61(project2.dir, ".hyperframes", "prepared-assets", "downloads");
110782
+ const gifOutputDir = join63(project2.dir, ".hyperframes", "prepared-assets", "gif");
110783
+ const gifDownloadDir = join63(project2.dir, ".hyperframes", "prepared-assets", "downloads");
110744
110784
  const prepared = await prepareAnimatedGifInputs2(html, {
110745
110785
  projectDir: project2.dir,
110746
110786
  downloadDir: gifDownloadDir,
@@ -110761,7 +110801,7 @@ function createStudioServer(options) {
110761
110801
  return await lintHyperframeHtml2(html, opts);
110762
110802
  },
110763
110803
  runtimeUrl: "/api/runtime.js",
110764
- rendersDir: () => join61(projectDir, "renders"),
110804
+ rendersDir: () => join63(projectDir, "renders"),
110765
110805
  startRender(opts) {
110766
110806
  const state = {
110767
110807
  id: opts.jobId,
@@ -111098,7 +111138,7 @@ __export(preview_exports, {
111098
111138
  });
111099
111139
  import { spawn as spawn12 } from "child_process";
111100
111140
  import { existsSync as existsSync55, lstatSync as lstatSync4, symlinkSync as symlinkSync3, unlinkSync as unlinkSync4, readlinkSync, mkdirSync as mkdirSync30 } from "fs";
111101
- import { resolve as resolve31, dirname as dirname24, basename as basename9, join as join63 } from "path";
111141
+ import { resolve as resolve31, dirname as dirname24, basename as basename9, join as join64 } from "path";
111102
111142
  import { fileURLToPath as fileURLToPath8 } from "url";
111103
111143
  import { createRequire as createRequire2 } from "module";
111104
111144
  function previewBaseUrl(port, host = "127.0.0.1") {
@@ -111404,7 +111444,7 @@ function printStudioSummary(projectName, url, opts = {}) {
111404
111444
  console.log();
111405
111445
  }
111406
111446
  function linkProjectIntoStudioData(dir, projectsDir, projectName) {
111407
- const symlinkPath = join63(projectsDir, projectName);
111447
+ const symlinkPath = join64(projectsDir, projectName);
111408
111448
  mkdirSync30(projectsDir, { recursive: true });
111409
111449
  let createdSymlink = false;
111410
111450
  if (dir !== symlinkPath) {
@@ -111467,13 +111507,13 @@ function attachStudioReadyHandler(child, spinner, projectName, options) {
111467
111507
  async function runDevMode(dir, options) {
111468
111508
  const thisFile = fileURLToPath8(import.meta.url);
111469
111509
  const repoRoot2 = resolve31(dirname24(thisFile), "..", "..", "..", "..");
111470
- const projectsDir = join63(repoRoot2, "packages", "studio", "data", "projects");
111510
+ const projectsDir = join64(repoRoot2, "packages", "studio", "data", "projects");
111471
111511
  const pName = options?.projectName ?? basename9(dir);
111472
111512
  const { symlinkPath, createdSymlink } = linkProjectIntoStudioData(dir, projectsDir, pName);
111473
111513
  ge(c.bold("hyperframes preview"));
111474
111514
  const s2 = ft();
111475
111515
  s2.start("Starting studio...");
111476
- const studioPkgDir = join63(repoRoot2, "packages", "studio");
111516
+ const studioPkgDir = join64(repoRoot2, "packages", "studio");
111477
111517
  const child = spawn12("bun", ["run", "dev"], {
111478
111518
  cwd: studioPkgDir,
111479
111519
  stdio: ["ignore", "pipe", "pipe"]
@@ -111485,7 +111525,7 @@ async function runDevMode(dir, options) {
111485
111525
  }
111486
111526
  function hasLocalStudio(dir) {
111487
111527
  try {
111488
- const req = createRequire2(join63(dir, "package.json"));
111528
+ const req = createRequire2(join64(dir, "package.json"));
111489
111529
  req.resolve("@hyperframes/studio/package.json");
111490
111530
  return true;
111491
111531
  } catch {
@@ -111493,10 +111533,10 @@ function hasLocalStudio(dir) {
111493
111533
  }
111494
111534
  }
111495
111535
  async function runLocalStudioMode(dir, options) {
111496
- const req = createRequire2(join63(dir, "package.json"));
111536
+ const req = createRequire2(join64(dir, "package.json"));
111497
111537
  const studioPkgPath = dirname24(req.resolve("@hyperframes/studio/package.json"));
111498
111538
  const pName = options?.projectName ?? basename9(dir);
111499
- const projectsDir = join63(studioPkgPath, "data", "projects");
111539
+ const projectsDir = join64(studioPkgPath, "data", "projects");
111500
111540
  const { symlinkPath, createdSymlink } = linkProjectIntoStudioData(dir, projectsDir, pName);
111501
111541
  ge(c.bold("hyperframes preview") + c.dim(" (local studio)"));
111502
111542
  const s2 = ft();
@@ -111859,7 +111899,7 @@ import {
111859
111899
  readFileSync as readFileSync35,
111860
111900
  readdirSync as readdirSync21
111861
111901
  } from "fs";
111862
- import { resolve as resolve33, basename as basename10, join as join64, dirname as dirname25 } from "path";
111902
+ import { resolve as resolve33, basename as basename10, join as join65, dirname as dirname25 } from "path";
111863
111903
  import { fileURLToPath as fileURLToPath9 } from "url";
111864
111904
  import { execFileSync as execFileSync7, spawn as spawn13 } from "child_process";
111865
111905
  function probeVideo(filePath) {
@@ -111993,7 +112033,7 @@ function listHtmlFiles(dir) {
111993
112033
  const ignoredDirs = /* @__PURE__ */ new Set([".git", "dist", "node_modules"]);
111994
112034
  function walk(currentDir) {
111995
112035
  for (const entry of readdirSync21(currentDir, { withFileTypes: true })) {
111996
- const entryPath = join64(currentDir, entry.name);
112036
+ const entryPath = join65(currentDir, entry.name);
111997
112037
  if (entry.isDirectory()) {
111998
112038
  if (!ignoredDirs.has(entry.name)) walk(entryPath);
111999
112039
  continue;
@@ -112038,7 +112078,7 @@ function writeTailwindSupport(destDir) {
112038
112078
  }
112039
112079
  }
112040
112080
  function patchVideoSrc(dir, videoFilename, durationSeconds) {
112041
- const htmlFiles = readdirSync21(dir, { withFileTypes: true, recursive: true }).filter((e3) => e3.isFile() && e3.name.endsWith(".html")).map((e3) => join64(e3.parentPath, e3.name));
112081
+ const htmlFiles = readdirSync21(dir, { withFileTypes: true, recursive: true }).filter((e3) => e3.isFile() && e3.name.endsWith(".html")).map((e3) => join65(e3.parentPath, e3.name));
112042
112082
  for (const file of htmlFiles) {
112043
112083
  let content = readFileSync35(file, "utf-8");
112044
112084
  if (videoFilename) {
@@ -112193,7 +112233,7 @@ function applyResolutionPreset(destDir, resolution) {
112193
112233
  async function scaffoldProject(destDir, name, templateId, localVideoName, durationSeconds, tailwind = false, resolution) {
112194
112234
  mkdirSync31(destDir, { recursive: true });
112195
112235
  const templateDir = getStaticTemplateDir(templateId);
112196
- if (existsSync56(join64(templateDir, "index.html"))) {
112236
+ if (existsSync56(join65(templateDir, "index.html"))) {
112197
112237
  cpSync5(templateDir, destDir, { recursive: true });
112198
112238
  } else {
112199
112239
  await fetchRemoteTemplate(templateId, destDir);
@@ -112222,7 +112262,7 @@ async function scaffoldProject(destDir, name, templateId, localVideoName, durati
112222
112262
  const sharedDir = getSharedTemplateDir();
112223
112263
  if (existsSync56(sharedDir)) {
112224
112264
  for (const entry of readdirSync21(sharedDir, { withFileTypes: true })) {
112225
- const src = join64(sharedDir, entry.name);
112265
+ const src = join65(sharedDir, entry.name);
112226
112266
  const dest = resolve33(destDir, entry.name);
112227
112267
  if (entry.isFile() || entry.isSymbolicLink()) {
112228
112268
  copyFileSync7(src, dest);
@@ -113726,7 +113766,7 @@ var init_present = __esm({
113726
113766
  });
113727
113767
 
113728
113768
  // src/utils/publishProject.ts
113729
- import { basename as basename11, dirname as dirname27, join as join65, posix as posix4, relative as relative13, resolve as resolve39 } from "path";
113769
+ import { basename as basename11, dirname as dirname27, join as join66, posix as posix4, relative as relative13, resolve as resolve39 } from "path";
113730
113770
  import { existsSync as existsSync61, readdirSync as readdirSync23, readFileSync as readFileSync38, statSync as statSync19 } from "fs";
113731
113771
  import AdmZip from "adm-zip";
113732
113772
  function isRecord3(value) {
@@ -113827,7 +113867,7 @@ function shouldIgnoreSegment(segment) {
113827
113867
  function collectProjectFiles(rootDir, currentDir, paths) {
113828
113868
  for (const entry of readdirSync23(currentDir, { withFileTypes: true })) {
113829
113869
  if (shouldIgnoreSegment(entry.name)) continue;
113830
- const absolutePath = join65(currentDir, entry.name);
113870
+ const absolutePath = join66(currentDir, entry.name);
113831
113871
  const relativePath = relative13(rootDir, absolutePath).replaceAll("\\", "/");
113832
113872
  if (!relativePath) continue;
113833
113873
  if (entry.isDirectory()) {
@@ -113957,7 +113997,7 @@ function createPublishArchive(projectDir) {
113957
113997
  }
113958
113998
  const fileContents = /* @__PURE__ */ new Map();
113959
113999
  for (const filePath of filePaths) {
113960
- fileContents.set(filePath, readFileSync38(join65(absProjectDir, filePath)));
114000
+ fileContents.set(filePath, readFileSync38(join66(absProjectDir, filePath)));
113961
114001
  }
113962
114002
  localizeExternalAssets(absProjectDir, fileContents);
113963
114003
  const archive = new AdmZip();
@@ -114090,7 +114130,7 @@ __export(publish_exports, {
114090
114130
  });
114091
114131
  import { resolve as resolve40 } from "path";
114092
114132
  import { existsSync as existsSync63 } from "fs";
114093
- import { join as join66 } from "path";
114133
+ import { join as join67 } from "path";
114094
114134
  var examples8, publish_default;
114095
114135
  var init_publish = __esm({
114096
114136
  "src/commands/publish.ts"() {
@@ -114129,7 +114169,7 @@ var init_publish = __esm({
114129
114169
  async run({ args }) {
114130
114170
  const rawArg = args.dir;
114131
114171
  const dir = resolve40(rawArg ?? ".");
114132
- const indexPath2 = join66(dir, "index.html");
114172
+ const indexPath2 = join67(dir, "index.html");
114133
114173
  if (existsSync63(indexPath2)) {
114134
114174
  const lintResult = await lintProject(dir);
114135
114175
  if (lintResult.totalErrors > 0 || lintResult.totalWarnings > 0) {
@@ -114891,7 +114931,7 @@ __export(batchRender_exports, {
114891
114931
  runBatchRender: () => runBatchRender
114892
114932
  });
114893
114933
  import { mkdirSync as mkdirSync33, readFileSync as readFileSync40, writeFileSync as writeFileSync23 } from "fs";
114894
- import { dirname as dirname28, join as join67, resolve as resolve43, sep as sep8 } from "path";
114934
+ import { dirname as dirname28, join as join68, resolve as resolve43, sep as sep8 } from "path";
114895
114935
  function isRecord4(value) {
114896
114936
  return value !== null && typeof value === "object" && !Array.isArray(value);
114897
114937
  }
@@ -115027,7 +115067,7 @@ function prepareBatchRender(options) {
115027
115067
  variables,
115028
115068
  outputPath: resolve43(resolveOutputTemplate(options.outputTemplate, variables, index))
115029
115069
  }));
115030
- const manifestPath2 = join67(
115070
+ const manifestPath2 = join68(
115031
115071
  commonOutputDirectory(rows.map((row) => row.outputPath)),
115032
115072
  "manifest.json"
115033
115073
  );
@@ -115240,7 +115280,7 @@ __export(render_exports, {
115240
115280
  });
115241
115281
  import { mkdirSync as mkdirSync34, readdirSync as readdirSync24, readFileSync as readFileSync41, statSync as statSync20, writeFileSync as writeFileSync24, rmSync as rmSync18 } from "fs";
115242
115282
  import { cpus as cpus4, freemem as freemem5, tmpdir as tmpdir6 } from "os";
115243
- import { resolve as resolve44, dirname as dirname29, join as join68, basename as basename12 } from "path";
115283
+ import { resolve as resolve44, dirname as dirname29, join as join69, basename as basename12 } from "path";
115244
115284
  import { execFileSync as execFileSync9, spawn as spawn14 } from "child_process";
115245
115285
  function formatFpsParseError(input2, reason) {
115246
115286
  switch (reason) {
@@ -115332,9 +115372,9 @@ function ensureDockerImage(version2, platform10, quiet) {
115332
115372
  }
115333
115373
  if (!quiet) console.log(c.dim(` Building Docker image: ${tag} (${platform10})...`));
115334
115374
  const dockerfilePath = resolveDockerfilePath();
115335
- const tmpDir = join68(tmpdir6(), `hyperframes-docker-${Date.now()}`);
115375
+ const tmpDir = join69(tmpdir6(), `hyperframes-docker-${Date.now()}`);
115336
115376
  mkdirSync34(tmpDir, { recursive: true });
115337
- writeFileSync24(join68(tmpDir, "Dockerfile"), readFileSync41(dockerfilePath));
115377
+ writeFileSync24(join69(tmpDir, "Dockerfile"), readFileSync41(dockerfilePath));
115338
115378
  const targetArch = platform10 === "linux/arm64" ? "arm64" : "amd64";
115339
115379
  try {
115340
115380
  execFileSync9(
@@ -115738,7 +115778,7 @@ function printRenderComplete(outputPath, elapsedMs, quiet, outputDurationSeconds
115738
115778
  for (const entry of readdirSync24(outputPath, { withFileTypes: true })) {
115739
115779
  if (!entry.isFile()) continue;
115740
115780
  try {
115741
- total += statSync20(join68(outputPath, entry.name)).size;
115781
+ total += statSync20(join69(outputPath, entry.name)).size;
115742
115782
  } catch {
115743
115783
  }
115744
115784
  }
@@ -116156,8 +116196,8 @@ var init_render = __esm({
116156
116196
  const now = /* @__PURE__ */ new Date();
116157
116197
  const datePart = now.toISOString().slice(0, 10);
116158
116198
  const timePart = now.toTimeString().slice(0, 8).replace(/:/g, "-");
116159
- const batchOutputTemplate = args.output ? args.output : join68(rendersDir, `${project.name}_${datePart}_${timePart}_{index}${ext}`);
116160
- const outputPath = args.output ? resolve44(args.output) : join68(rendersDir, `${project.name}_${datePart}_${timePart}${ext}`);
116199
+ const batchOutputTemplate = args.output ? args.output : join69(rendersDir, `${project.name}_${datePart}_${timePart}_{index}${ext}`);
116200
+ const outputPath = args.output ? resolve44(args.output) : join69(rendersDir, `${project.name}_${datePart}_${timePart}${ext}`);
116161
116201
  if (!batchPath) mkdirSync34(dirname29(outputPath), { recursive: true });
116162
116202
  const useDocker = args.docker ?? false;
116163
116203
  const useGpu = args.gpu ?? false;
@@ -116650,16 +116690,16 @@ var init_beats = __esm({
116650
116690
  // src/beats/headlessAnalyzer.ts
116651
116691
  import { existsSync as existsSync65, readFileSync as readFileSync43 } from "fs";
116652
116692
  import { createRequire as createRequire3 } from "module";
116653
- import { dirname as dirname30, join as join69 } from "path";
116693
+ import { dirname as dirname30, join as join70 } from "path";
116654
116694
  import { fileURLToPath as fileURLToPath11 } from "url";
116655
116695
  function findPrebuiltBundle() {
116656
116696
  const here = dirname30(fileURLToPath11(import.meta.url));
116657
116697
  const candidates = [
116658
- join69(here, "beat-analyzer.global.js"),
116698
+ join70(here, "beat-analyzer.global.js"),
116659
116699
  // dist root (tsup-bundled cli)
116660
- join69(here, "../beat-analyzer.global.js"),
116700
+ join70(here, "../beat-analyzer.global.js"),
116661
116701
  // dist/beats → dist
116662
- join69(here, "../dist/beat-analyzer.global.js")
116702
+ join70(here, "../dist/beat-analyzer.global.js")
116663
116703
  ];
116664
116704
  for (const p2 of candidates) {
116665
116705
  if (existsSync65(p2)) return p2;
@@ -116669,7 +116709,7 @@ function findPrebuiltBundle() {
116669
116709
  async function buildFromCoreSource() {
116670
116710
  const esbuild = await import("esbuild");
116671
116711
  const coreRoot = dirname30(require2.resolve("@hyperframes/core/package.json"));
116672
- const entry = join69(coreRoot, "src/beats/beatDetection.ts");
116712
+ const entry = join70(coreRoot, "src/beats/beatDetection.ts");
116673
116713
  const result = await esbuild.build({
116674
116714
  stdin: {
116675
116715
  contents: `import { analyzeMusicFromBuffer } from ${JSON.stringify(entry)};
@@ -116770,7 +116810,7 @@ __export(beats_exports, {
116770
116810
  examples: () => examples11
116771
116811
  });
116772
116812
  import { existsSync as existsSync66, readFileSync as readFileSync44, mkdirSync as mkdirSync35, writeFileSync as writeFileSync25 } from "fs";
116773
- import { resolve as resolve45, join as join70, dirname as dirname31 } from "path";
116813
+ import { resolve as resolve45, join as join71, dirname as dirname31 } from "path";
116774
116814
  function fail(message) {
116775
116815
  console.error(c.error(message));
116776
116816
  process.exit(1);
@@ -116840,7 +116880,7 @@ var init_beats2 = __esm({
116840
116880
  if (result.beatTimes.length === 0) {
116841
116881
  fail(`No beats detected in ${rel} \u2014 nothing written. (Track may be silent/ambient.)`);
116842
116882
  }
116843
- const outPath = join70(project.dir, "beats", `${rel}.json`);
116883
+ const outPath = join71(project.dir, "beats", `${rel}.json`);
116844
116884
  mkdirSync35(dirname31(outPath), { recursive: true });
116845
116885
  writeFileSync25(outPath, serializeBeats(result.beatTimes, result.beatStrengths, rel));
116846
116886
  report(`beats/${rel}.json`, result, Boolean(args.json));
@@ -117301,7 +117341,7 @@ var init_motionAudit = __esm({
117301
117341
 
117302
117342
  // src/utils/motionSpec.ts
117303
117343
  import { existsSync as existsSync68, readFileSync as readFileSync45, readdirSync as readdirSync25 } from "fs";
117304
- import { basename as basename13, join as join71 } from "path";
117344
+ import { basename as basename13, join as join73 } from "path";
117305
117345
  function isObject2(value) {
117306
117346
  return typeof value === "object" && value !== null && !Array.isArray(value);
117307
117347
  }
@@ -117347,7 +117387,7 @@ function findMotionSpec(projectDir) {
117347
117387
  const entries2 = readdirSync25(projectDir);
117348
117388
  const sidecars = entries2.filter((name) => name.endsWith(".motion.json")).sort();
117349
117389
  if (!sidecars[0]) return null;
117350
- if (sidecars.length === 1) return join71(projectDir, sidecars[0]);
117390
+ if (sidecars.length === 1) return join73(projectDir, sidecars[0]);
117351
117391
  const htmlBases = new Set(
117352
117392
  entries2.filter((name) => name.endsWith(".html")).map((name) => basename13(name, ".html"))
117353
117393
  );
@@ -117357,7 +117397,7 @@ function findMotionSpec(projectDir) {
117357
117397
  `ambiguous motion sidecars in ${projectDir}: ${matched.join(", ")} each match a composition \u2014 remove the sidecars you do not need, or use one composition per project`
117358
117398
  );
117359
117399
  }
117360
- return join71(projectDir, matched[0] ?? sidecars[0]);
117400
+ return join73(projectDir, matched[0] ?? sidecars[0]);
117361
117401
  }
117362
117402
  function readMotionSpec(path2) {
117363
117403
  let raw;
@@ -117414,7 +117454,7 @@ __export(layout_exports, {
117414
117454
  examples: () => examples12
117415
117455
  });
117416
117456
  import { existsSync as existsSync69, readFileSync as readFileSync46 } from "fs";
117417
- import { dirname as dirname32, join as join73 } from "path";
117457
+ import { dirname as dirname32, join as join74 } from "path";
117418
117458
  import { fileURLToPath as fileURLToPath12 } from "url";
117419
117459
  function buildMotionSampleTimes(duration) {
117420
117460
  if (!Number.isFinite(duration) || duration <= 0) return [];
@@ -117599,7 +117639,7 @@ async function runLayoutAudit(projectDir, opts) {
117599
117639
  }
117600
117640
  }
117601
117641
  function loadBrowserScript(name) {
117602
- const candidates = [join73(__dirname2, name), join73(__dirname2, "commands", name)];
117642
+ const candidates = [join74(__dirname2, name), join74(__dirname2, "commands", name)];
117603
117643
  for (const candidate of candidates) {
117604
117644
  if (existsSync69(candidate)) return readFileSync46(candidate, "utf-8");
117605
117645
  }
@@ -120750,7 +120790,7 @@ __export(info_exports, {
120750
120790
  orientation: () => orientation
120751
120791
  });
120752
120792
  import { readFileSync as readFileSync48, readdirSync as readdirSync26, statSync as statSync24 } from "fs";
120753
- import { join as join74 } from "path";
120793
+ import { join as join75 } from "path";
120754
120794
  function orientation(width, height) {
120755
120795
  if (width > height) return "landscape";
120756
120796
  if (height > width) return "portrait";
@@ -120764,7 +120804,7 @@ function durationFromHtml(html, fallback) {
120764
120804
  function totalSize(dir) {
120765
120805
  let total = 0;
120766
120806
  for (const entry of readdirSync26(dir, { withFileTypes: true })) {
120767
- const path2 = join74(dir, entry.name);
120807
+ const path2 = join75(dir, entry.name);
120768
120808
  if (entry.isDirectory()) {
120769
120809
  total += totalSize(path2);
120770
120810
  } else {
@@ -121032,7 +121072,7 @@ __export(benchmark_exports, {
121032
121072
  examples: () => examples17
121033
121073
  });
121034
121074
  import { existsSync as existsSync73, statSync as statSync25 } from "fs";
121035
- import { resolve as resolve49, join as join75 } from "path";
121075
+ import { resolve as resolve49, join as join76 } from "path";
121036
121076
  var examples17, FPS_30, FPS_60, DEFAULT_CONFIGS, benchmark_default;
121037
121077
  var init_benchmark = __esm({
121038
121078
  "src/commands/benchmark.ts"() {
@@ -121110,7 +121150,7 @@ var init_benchmark = __esm({
121110
121150
  s2?.start(`Benchmarking ${config.label}...`);
121111
121151
  for (let i2 = 0; i2 < runsPerConfig; i2++) {
121112
121152
  s2?.message(`${config.label} \u2014 run ${i2 + 1}/${runsPerConfig}`);
121113
- const outputPath = join75(
121153
+ const outputPath = join76(
121114
121154
  benchDir,
121115
121155
  `${config.label.replace(/[^a-zA-Z0-9]/g, "_")}_run${i2}.mp4`
121116
121156
  );
@@ -121396,7 +121436,7 @@ __export(manager_exports3, {
121396
121436
  });
121397
121437
  import { existsSync as existsSync74, mkdirSync as mkdirSync36 } from "fs";
121398
121438
  import { homedir as homedir11, platform as platform8, arch } from "os";
121399
- import { join as join76 } from "path";
121439
+ import { join as join77 } from "path";
121400
121440
  function isDevice(value) {
121401
121441
  return typeof value === "string" && DEVICES.includes(value);
121402
121442
  }
@@ -121436,7 +121476,7 @@ function listAvailableProviders() {
121436
121476
  return out;
121437
121477
  }
121438
121478
  function modelPath(model = DEFAULT_MODEL2) {
121439
- return join76(MODELS_DIR2, `${model}.onnx`);
121479
+ return join77(MODELS_DIR2, `${model}.onnx`);
121440
121480
  }
121441
121481
  async function ensureModel2(model = DEFAULT_MODEL2, options) {
121442
121482
  const dest = modelPath(model);
@@ -121454,7 +121494,7 @@ var init_manager3 = __esm({
121454
121494
  "src/background-removal/manager.ts"() {
121455
121495
  "use strict";
121456
121496
  init_download();
121457
- MODELS_DIR2 = join76(homedir11(), ".cache", "hyperframes", "background-removal", "models");
121497
+ MODELS_DIR2 = join77(homedir11(), ".cache", "hyperframes", "background-removal", "models");
121458
121498
  DEFAULT_MODEL2 = "u2net_human_seg";
121459
121499
  MODEL_URLS = {
121460
121500
  u2net_human_seg: "https://github.com/danielgatis/rembg/releases/download/v0.0.0/u2net_human_seg.onnx"
@@ -122165,7 +122205,7 @@ __export(transcribe_exports2, {
122165
122205
  examples: () => examples20
122166
122206
  });
122167
122207
  import { existsSync as existsSync76, writeFileSync as writeFileSync27 } from "fs";
122168
- import { resolve as resolve51, join as join77, extname as extname12, dirname as dirname35 } from "path";
122208
+ import { resolve as resolve51, join as join78, extname as extname12, dirname as dirname35 } from "path";
122169
122209
  function failWith(message, json) {
122170
122210
  trackCommandFailure("transcribe", message);
122171
122211
  if (json) {
@@ -122188,7 +122228,7 @@ async function importTranscript(inputPath, dir, json) {
122188
122228
  const { loadTranscript: loadTranscript2, patchCaptionHtml: patchCaptionHtml2 } = await Promise.resolve().then(() => (init_normalize(), normalize_exports));
122189
122229
  const { words, format } = loadTranscript2(inputPath);
122190
122230
  if (words.length === 0) exitNoWords(json);
122191
- const outPath = join77(dir, "transcript.json");
122231
+ const outPath = join78(dir, "transcript.json");
122192
122232
  writeFileSync27(outPath, JSON.stringify(words, null, 2));
122193
122233
  patchCaptionHtml2(dir, words);
122194
122234
  if (json) {
@@ -122206,7 +122246,7 @@ async function exportTranscript(inputPath, dir, to, output, json, preserveCues)
122206
122246
  const { words, format } = loadTranscript2(inputPath);
122207
122247
  if (words.length === 0) exitNoWords(json);
122208
122248
  const preGrouped = preserveCues || format === "srt" || format === "vtt" || void 0;
122209
- const outPath = resolve51(output ?? join77(dir, `transcript.${to}`));
122249
+ const outPath = resolve51(output ?? join78(dir, `transcript.${to}`));
122210
122250
  const content = to === "srt" ? formatSrt2(words, { preGrouped }) : formatVtt2(words, { preGrouped });
122211
122251
  writeFileSync27(outPath, content);
122212
122252
  if (json) {
@@ -122395,7 +122435,7 @@ var init_transcribe2 = __esm({
122395
122435
  // src/tts/manager.ts
122396
122436
  import { existsSync as existsSync77, mkdirSync as mkdirSync37 } from "fs";
122397
122437
  import { homedir as homedir12 } from "os";
122398
- import { join as join78 } from "path";
122438
+ import { join as join79 } from "path";
122399
122439
  function inferLangFromVoiceId(voiceId) {
122400
122440
  const first = voiceId.charAt(0).toLowerCase();
122401
122441
  return VOICE_PREFIX_LANG[first] ?? "en-us";
@@ -122404,7 +122444,7 @@ function isSupportedLang(value) {
122404
122444
  return SUPPORTED_LANGS.includes(value);
122405
122445
  }
122406
122446
  async function ensureModel3(model = DEFAULT_MODEL3, options) {
122407
- const modelPath2 = join78(MODELS_DIR3, `${model}.onnx`);
122447
+ const modelPath2 = join79(MODELS_DIR3, `${model}.onnx`);
122408
122448
  if (existsSync77(modelPath2)) return modelPath2;
122409
122449
  const url = MODEL_URLS2[model];
122410
122450
  if (!url) {
@@ -122421,7 +122461,7 @@ async function ensureModel3(model = DEFAULT_MODEL3, options) {
122421
122461
  return modelPath2;
122422
122462
  }
122423
122463
  async function ensureVoices(options) {
122424
- const voicesPath = join78(VOICES_DIR, "voices-v1.0.bin");
122464
+ const voicesPath = join79(VOICES_DIR, "voices-v1.0.bin");
122425
122465
  if (existsSync77(voicesPath)) return voicesPath;
122426
122466
  mkdirSync37(VOICES_DIR, { recursive: true });
122427
122467
  options?.onProgress?.("Downloading voice data (~27 MB)...");
@@ -122436,9 +122476,9 @@ var init_manager4 = __esm({
122436
122476
  "src/tts/manager.ts"() {
122437
122477
  "use strict";
122438
122478
  init_download();
122439
- CACHE_DIR3 = join78(homedir12(), ".cache", "hyperframes", "tts");
122440
- MODELS_DIR3 = join78(CACHE_DIR3, "models");
122441
- VOICES_DIR = join78(CACHE_DIR3, "voices");
122479
+ CACHE_DIR3 = join79(homedir12(), ".cache", "hyperframes", "tts");
122480
+ MODELS_DIR3 = join79(CACHE_DIR3, "models");
122481
+ VOICES_DIR = join79(CACHE_DIR3, "voices");
122442
122482
  DEFAULT_MODEL3 = "kokoro-v1.0";
122443
122483
  MODEL_URLS2 = {
122444
122484
  "kokoro-v1.0": "https://github.com/thewh1teagle/kokoro-onnx/releases/download/model-files-v1.0/kokoro-v1.0.onnx"
@@ -122556,7 +122596,7 @@ __export(synthesize_exports, {
122556
122596
  });
122557
122597
  import { execFileSync as execFileSync11 } from "child_process";
122558
122598
  import { existsSync as existsSync78, writeFileSync as writeFileSync28, mkdirSync as mkdirSync38, readdirSync as readdirSync27, unlinkSync as unlinkSync5 } from "fs";
122559
- import { join as join79, dirname as dirname36, basename as basename15 } from "path";
122599
+ import { join as join80, dirname as dirname36, basename as basename15 } from "path";
122560
122600
  import { homedir as homedir13 } from "os";
122561
122601
  function ensureSynthScript() {
122562
122602
  if (!existsSync78(SCRIPT_PATH)) {
@@ -122567,7 +122607,7 @@ function ensureSynthScript() {
122567
122607
  for (const entry of readdirSync27(SCRIPT_DIR)) {
122568
122608
  if (entry !== currentName && /^synth(-v\d+)?\.py$/.test(entry)) {
122569
122609
  try {
122570
- unlinkSync5(join79(SCRIPT_DIR, entry));
122610
+ unlinkSync5(join80(SCRIPT_DIR, entry));
122571
122611
  } catch {
122572
122612
  }
122573
122613
  }
@@ -122678,8 +122718,8 @@ print(json.dumps({
122678
122718
  "langApplied": bool(lang and supports_lang),
122679
122719
  }))
122680
122720
  `;
122681
- SCRIPT_DIR = join79(homedir13(), ".cache", "hyperframes", "tts");
122682
- SCRIPT_PATH = join79(SCRIPT_DIR, "synth-v2.py");
122721
+ SCRIPT_DIR = join80(homedir13(), ".cache", "hyperframes", "tts");
122722
+ SCRIPT_PATH = join80(SCRIPT_DIR, "synth-v2.py");
122683
122723
  }
122684
122724
  });
122685
122725
 
@@ -122893,7 +122933,7 @@ __export(docs_exports, {
122893
122933
  examples: () => examples22
122894
122934
  });
122895
122935
  import { readFileSync as readFileSync51, existsSync as existsSync80 } from "fs";
122896
- import { resolve as resolve53, dirname as dirname37, join as join80 } from "path";
122936
+ import { resolve as resolve53, dirname as dirname37, join as join81 } from "path";
122897
122937
  import { fileURLToPath as fileURLToPath13 } from "url";
122898
122938
  function docsDir() {
122899
122939
  const thisFile = fileURLToPath13(import.meta.url);
@@ -122997,7 +123037,7 @@ var init_docs = __esm({
122997
123037
  }
122998
123038
  process.exit(1);
122999
123039
  }
123000
- const filePath = join80(docsDir(), entry.file);
123040
+ const filePath = join81(docsDir(), entry.file);
123001
123041
  if (!existsSync80(filePath)) {
123002
123042
  console.error(c.error(`Doc file not found: ${filePath}`));
123003
123043
  process.exit(1);
@@ -123828,7 +123868,7 @@ __export(validate_exports, {
123828
123868
  waitForPreferredSeekTarget: () => waitForPreferredSeekTarget
123829
123869
  });
123830
123870
  import { existsSync as existsSync81, readFileSync as readFileSync53 } from "fs";
123831
- import { join as join81, dirname as dirname38 } from "path";
123871
+ import { join as join83, dirname as dirname38 } from "path";
123832
123872
  import { fileURLToPath as fileURLToPath14 } from "url";
123833
123873
  function resolveNavigationTimeoutMs(optTimeout) {
123834
123874
  return Math.max(NAV_TIMEOUT_FLOOR_MS, optTimeout ?? 0);
@@ -123986,8 +124026,8 @@ async function runContrastAudit(page) {
123986
124026
  }
123987
124027
  function loadContrastAuditScript() {
123988
124028
  const candidates = [
123989
- join81(__dirname3, "contrast-audit.browser.js"),
123990
- join81(__dirname3, "commands", "contrast-audit.browser.js")
124029
+ join83(__dirname3, "contrast-audit.browser.js"),
124030
+ join83(__dirname3, "commands", "contrast-audit.browser.js")
123991
124031
  ];
123992
124032
  for (const candidate of candidates) {
123993
124033
  if (existsSync81(candidate)) return readFileSync53(candidate, "utf-8");
@@ -124222,7 +124262,7 @@ __export(contactSheet_exports, {
124222
124262
  });
124223
124263
  import sharp from "sharp";
124224
124264
  import { readdirSync as readdirSync28, readFileSync as readFileSync54, writeFileSync as writeFileSync29, unlinkSync as unlinkSync6, existsSync as existsSync83 } from "fs";
124225
- import { join as join83, extname as extname14, basename as basename16, dirname as dirname39 } from "path";
124265
+ import { join as join84, extname as extname14, basename as basename16, dirname as dirname39 } from "path";
124226
124266
  async function createContactSheet(imagePaths, outputPath, opts = {}) {
124227
124267
  const {
124228
124268
  cols = 3,
@@ -124304,7 +124344,7 @@ async function createScrollContactSheet(screenshotsDir, outputPath) {
124304
124344
  if (!existsSync83(screenshotsDir)) return [];
124305
124345
  const scrollFiles = readdirSync28(screenshotsDir).filter((f3) => f3.startsWith("scroll-") && f3.endsWith(".png")).sort();
124306
124346
  if (scrollFiles.length === 0) return [];
124307
- const paths = scrollFiles.map((f3) => join83(screenshotsDir, f3));
124347
+ const paths = scrollFiles.map((f3) => join84(screenshotsDir, f3));
124308
124348
  const labels = scrollFiles.map((f3) => {
124309
124349
  const m2 = f3.match(/scroll-(\d+)\.png/);
124310
124350
  return m2 ? `${m2[1]}% scroll` : f3;
@@ -124321,7 +124361,7 @@ async function createSnapshotContactSheet(snapshotsDir, outputPath) {
124321
124361
  if (!existsSync83(snapshotsDir)) return [];
124322
124362
  const snapshotFiles = readdirSync28(snapshotsDir).filter((f3) => f3.startsWith("frame-") && f3.endsWith(".png")).sort();
124323
124363
  if (snapshotFiles.length === 0) return [];
124324
- const paths = snapshotFiles.map((f3) => join83(snapshotsDir, f3));
124364
+ const paths = snapshotFiles.map((f3) => join84(snapshotsDir, f3));
124325
124365
  const labels = snapshotFiles.map((f3) => {
124326
124366
  const m2 = f3.match(/at-([\d.]+)s/);
124327
124367
  return m2 ? `${m2[1]}s` : f3;
@@ -124339,7 +124379,7 @@ async function createAssetContactSheet(assetsDir, outputPath) {
124339
124379
  const imageExts = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".webp"]);
124340
124380
  const assetFiles = readdirSync28(assetsDir).filter((f3) => imageExts.has(extname14(f3).toLowerCase()) && !f3.includes("contact-sheet")).sort();
124341
124381
  if (assetFiles.length === 0) return [];
124342
- const paths = assetFiles.map((f3) => join83(assetsDir, f3));
124382
+ const paths = assetFiles.map((f3) => join84(assetsDir, f3));
124343
124383
  return createContactSheetPages(paths, outputPath, {
124344
124384
  cols: 4,
124345
124385
  cellWidth: 480,
@@ -124358,7 +124398,7 @@ async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir) {
124358
124398
  for (const f3 of readdirSync28(dir).filter((f4) => f4.endsWith(".svg")).sort()) {
124359
124399
  if (!seen.has(f3)) {
124360
124400
  seen.add(f3);
124361
- svgPaths.push(join83(dir, f3));
124401
+ svgPaths.push(join84(dir, f3));
124362
124402
  }
124363
124403
  }
124364
124404
  }
@@ -124370,7 +124410,7 @@ async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir) {
124370
124410
  const labels = [];
124371
124411
  for (let i2 = 0; i2 < svgPaths.length; i2++) {
124372
124412
  const svgPath = svgPaths[i2];
124373
- const tmpPath = join83(tmpDir, `.thumb-${i2}.png`);
124413
+ const tmpPath = join84(tmpDir, `.thumb-${i2}.png`);
124374
124414
  try {
124375
124415
  const svgBuf = readFileSync54(svgPath);
124376
124416
  const thumb = await sharp(svgBuf).resize(thumbSize, thumbSize, {
@@ -155728,10 +155768,10 @@ function iterBinaryChunks(iterator) {
155728
155768
  }
155729
155769
  });
155730
155770
  }
155731
- function partition(str, delimiter) {
155732
- const index = str.indexOf(delimiter);
155771
+ function partition(str, delimiter2) {
155772
+ const index = str.indexOf(delimiter2);
155733
155773
  if (index !== -1) {
155734
- return [str.substring(0, index), delimiter, str.substring(index + delimiter.length)];
155774
+ return [str.substring(0, index), delimiter2, str.substring(index + delimiter2.length)];
155735
155775
  }
155736
155776
  return [str, "", ""];
155737
155777
  }
@@ -159532,11 +159572,11 @@ var init_node4 = __esm({
159532
159572
  while (true) {
159533
159573
  delimiterIndex = -1;
159534
159574
  delimiterLength = 0;
159535
- for (const delimiter of delimiters) {
159536
- const index = buffer.indexOf(delimiter);
159575
+ for (const delimiter2 of delimiters) {
159576
+ const index = buffer.indexOf(delimiter2);
159537
159577
  if (index !== -1 && (delimiterIndex === -1 || index < delimiterIndex)) {
159538
159578
  delimiterIndex = index;
159539
- delimiterLength = delimiter.length;
159579
+ delimiterLength = delimiter2.length;
159540
159580
  }
159541
159581
  }
159542
159582
  if (delimiterIndex === -1) {
@@ -164154,7 +164194,7 @@ __export(snapshot_exports, {
164154
164194
  import { spawn as spawn16 } from "child_process";
164155
164195
  import { existsSync as existsSync84, mkdtempSync as mkdtempSync6, readFileSync as readFileSync55, mkdirSync as mkdirSync39, rmSync as rmSync19, writeFileSync as writeFileSync30 } from "fs";
164156
164196
  import { tmpdir as tmpdir7 } from "os";
164157
- import { resolve as resolve55, join as join84, relative as relative15, isAbsolute as isAbsolute14, basename as basename19 } from "path";
164197
+ import { resolve as resolve55, join as join85, relative as relative15, isAbsolute as isAbsolute14, basename as basename19 } from "path";
164158
164198
  function orbitStageSource() {
164159
164199
  return `function(cam) {
164160
164200
  var root = document.querySelector("[data-composition-id]")
@@ -164177,8 +164217,8 @@ function orbitStageSource() {
164177
164217
  }`;
164178
164218
  }
164179
164219
  async function extractVideoFrameToBuffer(videoPath, timeSeconds, useVp9AlphaDecoder = false) {
164180
- const tmp = mkdtempSync6(join84(tmpdir7(), "hf-snapshot-frame-"));
164181
- const outPath = join84(tmp, "frame.png");
164220
+ const tmp = mkdtempSync6(join85(tmpdir7(), "hf-snapshot-frame-"));
164221
+ const outPath = join85(tmp, "frame.png");
164182
164222
  try {
164183
164223
  const ffmpegPath = findFFmpeg();
164184
164224
  if (!ffmpegPath) return null;
@@ -164353,13 +164393,13 @@ async function captureSnapshots(projectDir, opts) {
164353
164393
  );
164354
164394
  }
164355
164395
  const cameraExpr = opts.angle && (opts.angle.yaw !== 0 || opts.angle.pitch !== 0) ? `(${orbitStageSource()})(${JSON.stringify(opts.angle)})` : null;
164356
- const snapshotDir = opts.outputDir ?? join84(projectDir, "snapshots");
164396
+ const snapshotDir = opts.outputDir ?? join85(projectDir, "snapshots");
164357
164397
  mkdirSync39(snapshotDir, { recursive: true });
164358
164398
  try {
164359
164399
  const { readdirSync: readdirSync35 } = await import("fs");
164360
164400
  for (const file of readdirSync35(snapshotDir)) {
164361
164401
  if (/\.(png|jpg|jpeg)$/i.test(file)) {
164362
- rmSync19(join84(snapshotDir, file), { force: true });
164402
+ rmSync19(join85(snapshotDir, file), { force: true });
164363
164403
  }
164364
164404
  }
164365
164405
  } catch {
@@ -164476,7 +164516,7 @@ async function captureSnapshots(projectDir, opts) {
164476
164516
  }
164477
164517
  const timeLabel = `${time.toFixed(1)}s`;
164478
164518
  const filename = `frame-${String(i2).padStart(2, "0")}-at-${timeLabel}.png`;
164479
- const framePath = join84(snapshotDir, filename);
164519
+ const framePath = join85(snapshotDir, filename);
164480
164520
  await page.screenshot({ path: framePath, type: "png" });
164481
164521
  const rel = relative15(projectDir, framePath);
164482
164522
  savedPaths.push(rel.startsWith("..") || isAbsolute14(rel) ? framePath : rel);
@@ -164562,7 +164602,7 @@ var init_snapshot = __esm({
164562
164602
  const angleLabel = camera && (camera.yaw !== 0 || camera.pitch !== 0) ? ` ${c.dim(`(angle yaw ${camera.yaw}\xB0 pitch ${camera.pitch}\xB0)`)}` : "";
164563
164603
  console.log(`${c.accent("\u25C6")} Capturing ${label2} from ${c.accent(project.name)}${angleLabel}`);
164564
164604
  try {
164565
- const snapshotDir = args.output ? resolve55(String(args.output)) : join84(project.dir, "snapshots");
164605
+ const snapshotDir = args.output ? resolve55(String(args.output)) : join85(project.dir, "snapshots");
164566
164606
  const paths = await captureSnapshots(project.dir, {
164567
164607
  frames,
164568
164608
  timeout,
@@ -164589,7 +164629,7 @@ ${c.success("\u25C7")} ${paths.length} snapshots saved to ${args.output ? snaps
164589
164629
  const { createSnapshotContactSheet: createSnapshotContactSheet2 } = await Promise.resolve().then(() => (init_contactSheet(), contactSheet_exports));
164590
164630
  const sheets = await createSnapshotContactSheet2(
164591
164631
  snapshotDir,
164592
- join84(snapshotDir, "contact-sheet.jpg")
164632
+ join85(snapshotDir, "contact-sheet.jpg")
164593
164633
  );
164594
164634
  if (sheets.length > 0) {
164595
164635
  const label3 = sheets.length === 1 ? "contact-sheet.jpg" : `contact-sheet-1..${sheets.length}.jpg`;
@@ -164625,7 +164665,7 @@ ${c.success("\u25C7")} ${paths.length} snapshots saved to ${args.output ? snaps
164625
164665
  const results = await Promise.allSettled(
164626
164666
  paths.map(async (p2) => {
164627
164667
  const filename = basename19(p2);
164628
- const filePath = join84(snapshotDir, filename);
164668
+ const filePath = join85(snapshotDir, filename);
164629
164669
  if (!existsSync84(filePath)) return { filename, desc: "file not found" };
164630
164670
  const raw = readFileSync55(filePath);
164631
164671
  let imageData;
@@ -164663,7 +164703,7 @@ ${c.success("\u25C7")} ${paths.length} snapshots saved to ${args.output ? snaps
164663
164703
  descriptions.push(`## (error)`, `Gemini call failed: ${errMsg.slice(0, 120)}`, ``);
164664
164704
  }
164665
164705
  }
164666
- const descPath = join84(snapshotDir, "descriptions.md");
164706
+ const descPath = join85(snapshotDir, "descriptions.md");
164667
164707
  writeFileSync30(descPath, descriptions.join("\n"));
164668
164708
  console.log(` ${c.dim("descriptions.md")} (Gemini frame analysis)`);
164669
164709
  }
@@ -164685,18 +164725,18 @@ ${c.error("\u2717")} Snapshot failed: ${msg}`);
164685
164725
 
164686
164726
  // src/capture/assetDownloader.ts
164687
164727
  import { writeFileSync as writeFileSync31, mkdirSync as mkdirSync40 } from "fs";
164688
- import { join as join85, extname as extname15 } from "path";
164728
+ import { join as join86, extname as extname15 } from "path";
164689
164729
  import { createHash as createHash12 } from "crypto";
164690
164730
  function svgContentHashSlug(svgSource, isLogo) {
164691
164731
  const hash2 = createHash12("sha1").update(svgSource).digest("hex").slice(0, 8);
164692
164732
  return isLogo ? `logo-${hash2}` : `svg-${hash2}`;
164693
164733
  }
164694
164734
  async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks) {
164695
- const assetsDir = join85(outputDir, "assets");
164735
+ const assetsDir = join86(outputDir, "assets");
164696
164736
  mkdirSync40(assetsDir, { recursive: true });
164697
164737
  const assets = [];
164698
164738
  const downloadedUrls = /* @__PURE__ */ new Set();
164699
- mkdirSync40(join85(outputDir, "assets", "svgs"), { recursive: true });
164739
+ mkdirSync40(join86(outputDir, "assets", "svgs"), { recursive: true });
164700
164740
  const usedSvgNames = /* @__PURE__ */ new Set();
164701
164741
  for (let i2 = 0; i2 < tokens.svgs.length && i2 < 30; i2++) {
164702
164742
  const svg = tokens.svgs[i2];
@@ -164712,7 +164752,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks)
164712
164752
  const name = `${finalSlug}.svg`;
164713
164753
  const localPath = `assets/svgs/${name}`;
164714
164754
  try {
164715
- writeFileSync31(join85(outputDir, localPath), svg.outerHTML, "utf-8");
164755
+ writeFileSync31(join86(outputDir, localPath), svg.outerHTML, "utf-8");
164716
164756
  assets.push({ url: "", localPath, type: "svg" });
164717
164757
  } catch {
164718
164758
  }
@@ -164725,7 +164765,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks)
164725
164765
  const localPath = `assets/${name}`;
164726
164766
  const buffer = await fetchBuffer(icon.href);
164727
164767
  if (buffer) {
164728
- writeFileSync31(join85(outputDir, localPath), buffer);
164768
+ writeFileSync31(join86(outputDir, localPath), buffer);
164729
164769
  assets.push({ url: icon.href, localPath, type: "favicon" });
164730
164770
  break;
164731
164771
  }
@@ -164790,7 +164830,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks)
164790
164830
  const name = `${slug}${ext}`;
164791
164831
  usedNames.add(slug);
164792
164832
  const localPath = `assets/${name}`;
164793
- writeFileSync31(join85(outputDir, localPath), buffer);
164833
+ writeFileSync31(join86(outputDir, localPath), buffer);
164794
164834
  assets.push({ url, localPath, type: "image" });
164795
164835
  imgIdx++;
164796
164836
  } catch {
@@ -164803,7 +164843,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks)
164803
164843
  const localPath = `assets/og-image${ext}`;
164804
164844
  const buffer = await fetchBuffer(tokens.ogImage);
164805
164845
  if (buffer && buffer.length > 5e3) {
164806
- writeFileSync31(join85(outputDir, localPath), buffer);
164846
+ writeFileSync31(join86(outputDir, localPath), buffer);
164807
164847
  assets.push({ url: tokens.ogImage, localPath, type: "image" });
164808
164848
  }
164809
164849
  } catch {
@@ -164826,7 +164866,7 @@ function normalizeUrl(u) {
164826
164866
  }
164827
164867
  }
164828
164868
  async function downloadAndRewriteFonts(css, outputDir) {
164829
- const assetsDir = join85(outputDir, "assets", "fonts");
164869
+ const assetsDir = join86(outputDir, "assets", "fonts");
164830
164870
  mkdirSync40(assetsDir, { recursive: true });
164831
164871
  const fontUrlRegex = /url\(['"]?(https?:\/\/[^'")\s]+\.(?:woff2?|ttf|otf)[^'")\s]*?)['"]?\)/g;
164832
164872
  const fontUrls = /* @__PURE__ */ new Set();
@@ -164862,7 +164902,7 @@ async function downloadAndRewriteFonts(css, outputDir) {
164862
164902
  try {
164863
164903
  const urlObj = new URL(fontUrl);
164864
164904
  const filename = urlObj.pathname.split("/").pop() || `font-${count}.woff2`;
164865
- const localPath = join85(assetsDir, filename);
164905
+ const localPath = join86(assetsDir, filename);
164866
164906
  const relativePath = `assets/fonts/${filename}`;
164867
164907
  const buffer = await fetchBuffer(fontUrl);
164868
164908
  if (buffer) {
@@ -165021,7 +165061,7 @@ __export(video_exports, {
165021
165061
  safeFilename: () => safeFilename
165022
165062
  });
165023
165063
  import { createWriteStream as createWriteStream4, existsSync as existsSync85, mkdirSync as mkdirSync41, readFileSync as readFileSync56, unlinkSync as unlinkSync7 } from "fs";
165024
- import { resolve as resolve56, join as join86, basename as basename20 } from "path";
165064
+ import { resolve as resolve56, join as join87, basename as basename20 } from "path";
165025
165065
  async function streamToFile(url, destPath) {
165026
165066
  const r2 = await safeFetch(url, {
165027
165067
  signal: AbortSignal.timeout(12e4),
@@ -165140,8 +165180,8 @@ function pickManifestEntry(manifest, args) {
165140
165180
  }
165141
165181
  async function runVideoMode(args) {
165142
165182
  const projectDir = resolve56(args.project);
165143
- const directPath = join86(projectDir, "extracted", "video-manifest.json");
165144
- const w2hPath = join86(projectDir, "capture", "extracted", "video-manifest.json");
165183
+ const directPath = join87(projectDir, "extracted", "video-manifest.json");
165184
+ const w2hPath = join87(projectDir, "capture", "extracted", "video-manifest.json");
165145
165185
  const manifestPath2 = existsSync85(directPath) ? directPath : w2hPath;
165146
165186
  const isW2hLayout = manifestPath2 === w2hPath;
165147
165187
  if (!existsSync85(manifestPath2)) {
@@ -165195,10 +165235,10 @@ async function runVideoMode(args) {
165195
165235
  process.exitCode = 1;
165196
165236
  return;
165197
165237
  }
165198
- const outDir = isW2hLayout ? join86(projectDir, "capture", "assets", "videos") : join86(projectDir, "assets", "videos");
165238
+ const outDir = isW2hLayout ? join87(projectDir, "capture", "assets", "videos") : join87(projectDir, "assets", "videos");
165199
165239
  mkdirSync41(outDir, { recursive: true });
165200
165240
  const fname = safeFilename(entry.filename || basename20(entry.url));
165201
- const outPath = join86(outDir, fname);
165241
+ const outPath = join87(outDir, fname);
165202
165242
  const relPath = isW2hLayout ? `capture/assets/videos/${fname}` : `assets/videos/${fname}`;
165203
165243
  console.log(
165204
165244
  `${c.accent("\u25B8")} downloading [${entry.index}] ${entry.filename} (${entry.sourceWidth || entry.width}\xD7${entry.sourceHeight || entry.height})`
@@ -166442,7 +166482,7 @@ var init_designStyleExtractor = __esm({
166442
166482
 
166443
166483
  // src/capture/fontMetadataExtractor.ts
166444
166484
  import { readdirSync as readdirSync29, readFileSync as readFileSync57, writeFileSync as writeFileSync33, existsSync as existsSync86 } from "fs";
166445
- import { join as join87 } from "path";
166485
+ import { join as join88 } from "path";
166446
166486
  import * as fontkit from "fontkit";
166447
166487
  function isFontCollection(value) {
166448
166488
  return value.type === "TTC" || value.type === "DFont";
@@ -166453,7 +166493,7 @@ function extractFontMetadata(fontsDir, outputPath) {
166453
166493
  if (existsSync86(fontsDir)) {
166454
166494
  const fontFiles = readdirSync29(fontsDir).filter((f3) => /\.(woff2?|ttf|otf)$/i.test(f3));
166455
166495
  for (const filename of fontFiles) {
166456
- const fullPath = join87(fontsDir, filename);
166496
+ const fullPath = join88(fontsDir, filename);
166457
166497
  const meta = readSingleFont(fullPath, filename);
166458
166498
  if (meta.identified) {
166459
166499
  files.push(meta);
@@ -166765,7 +166805,7 @@ var init_animationCataloger = __esm({
166765
166805
 
166766
166806
  // src/capture/mediaCapture.ts
166767
166807
  import { mkdirSync as mkdirSync43, writeFileSync as writeFileSync34, readdirSync as readdirSync30, readFileSync as readFileSync58, statSync as statSync27 } from "fs";
166768
- import { join as join88, extname as extname16 } from "path";
166808
+ import { join as join89, extname as extname16 } from "path";
166769
166809
  async function saveLottieAnimations(discoveredLotties, lottieDir) {
166770
166810
  let savedCount = 0;
166771
166811
  const savedHashes = /* @__PURE__ */ new Set();
@@ -166797,7 +166837,7 @@ async function saveLottieAnimations(discoveredLotties, lottieDir) {
166797
166837
  const hash2 = buf.toString("base64").slice(0, 100);
166798
166838
  if (savedHashes.has(hash2)) continue;
166799
166839
  savedHashes.add(hash2);
166800
- writeFileSync34(join88(lottieDir, `animation-${savedCount}.lottie`), buf);
166840
+ writeFileSync34(join89(lottieDir, `animation-${savedCount}.lottie`), buf);
166801
166841
  savedCount++;
166802
166842
  continue;
166803
166843
  }
@@ -166815,7 +166855,7 @@ async function saveLottieAnimations(discoveredLotties, lottieDir) {
166815
166855
  } catch {
166816
166856
  continue;
166817
166857
  }
166818
- writeFileSync34(join88(lottieDir, `animation-${savedCount}.json`), jsonData, "utf-8");
166858
+ writeFileSync34(join89(lottieDir, `animation-${savedCount}.json`), jsonData, "utf-8");
166819
166859
  savedCount++;
166820
166860
  }
166821
166861
  } catch {
@@ -166825,22 +166865,22 @@ async function saveLottieAnimations(discoveredLotties, lottieDir) {
166825
166865
  }
166826
166866
  async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir) {
166827
166867
  const manifest = [];
166828
- const previewDir = join88(lottieDir, "previews");
166868
+ const previewDir = join89(lottieDir, "previews");
166829
166869
  mkdirSync43(previewDir, { recursive: true });
166830
166870
  for (const file of readdirSync30(lottieDir)) {
166831
166871
  if (!file.endsWith(".json")) continue;
166832
166872
  try {
166833
- const raw = JSON.parse(readFileSync58(join88(lottieDir, file), "utf-8"));
166873
+ const raw = JSON.parse(readFileSync58(join89(lottieDir, file), "utf-8"));
166834
166874
  const fr = raw.fr || 30;
166835
166875
  const dur = ((raw.op || 0) - (raw.ip || 0)) / fr;
166836
166876
  const previewName = file.replace(".json", "-preview.png");
166837
- const fileSize = statSync27(join88(lottieDir, file)).size;
166877
+ const fileSize = statSync27(join89(lottieDir, file)).size;
166838
166878
  if (fileSize > 2e6) continue;
166839
166879
  let previewPage;
166840
166880
  try {
166841
166881
  previewPage = await chromeBrowser.newPage();
166842
166882
  await previewPage.setViewport({ width: 400, height: 400 });
166843
- const animData = JSON.parse(readFileSync58(join88(lottieDir, file), "utf-8"));
166883
+ const animData = JSON.parse(readFileSync58(join89(lottieDir, file), "utf-8"));
166844
166884
  const midFrame = Math.floor(((raw.op || 0) - (raw.ip || 0)) * 0.3);
166845
166885
  await previewPage.setContent(
166846
166886
  `<!DOCTYPE html>
@@ -166870,7 +166910,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir) {
166870
166910
  await previewPage.waitForFunction(() => window.__READY === true, { timeout: 5e3 }).catch(() => {
166871
166911
  });
166872
166912
  await previewPage.screenshot({
166873
- path: join88(previewDir, previewName),
166913
+ path: join89(previewDir, previewName),
166874
166914
  type: "png",
166875
166915
  omitBackground: true
166876
166916
  });
@@ -166894,7 +166934,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir) {
166894
166934
  }
166895
166935
  if (manifest.length > 0) {
166896
166936
  writeFileSync34(
166897
- join88(outputDir, "extracted", "lottie-manifest.json"),
166937
+ join89(outputDir, "extracted", "lottie-manifest.json"),
166898
166938
  JSON.stringify(manifest, null, 2),
166899
166939
  "utf-8"
166900
166940
  );
@@ -166929,7 +166969,7 @@ async function downloadVideoBody(srcUrl, filename, videosDir) {
166929
166969
  }
166930
166970
  if (total < 1024) return null;
166931
166971
  const safe = /\.[a-z0-9]+$/i.test(filename) ? filename.replace(/[^\w.-]/g, "_") : `video${ext}`;
166932
- writeFileSync34(join88(videosDir, safe), Buffer.concat(chunks));
166972
+ writeFileSync34(join89(videosDir, safe), Buffer.concat(chunks));
166933
166973
  return `assets/videos/${safe}`;
166934
166974
  } catch {
166935
166975
  return null;
@@ -166991,9 +167031,9 @@ async function captureVideoManifest(page, outputDir, progress, opts) {
166991
167031
  }
166992
167032
  const merged = [...byKey.values()];
166993
167033
  if (merged.length === 0) return;
166994
- const videoManifestDir = join88(outputDir, "assets", "videos");
167034
+ const videoManifestDir = join89(outputDir, "assets", "videos");
166995
167035
  mkdirSync43(videoManifestDir, { recursive: true });
166996
- const previewDir = join88(videoManifestDir, "previews");
167036
+ const previewDir = join89(videoManifestDir, "previews");
166997
167037
  mkdirSync43(previewDir, { recursive: true });
166998
167038
  const videoManifest = [];
166999
167039
  const dlStart = Date.now();
@@ -167016,7 +167056,7 @@ async function captureVideoManifest(page, outputDir, progress, opts) {
167016
167056
  if (rect && rect.width >= 10) {
167017
167057
  await new Promise((r2) => setTimeout(r2, 200));
167018
167058
  await page.screenshot({
167019
- path: join88(previewDir, previewName),
167059
+ path: join89(previewDir, previewName),
167020
167060
  clip: {
167021
167061
  x: Math.max(0, rect.x),
167022
167062
  y: Math.max(0, rect.y),
@@ -167048,7 +167088,7 @@ async function captureVideoManifest(page, outputDir, progress, opts) {
167048
167088
  }
167049
167089
  if (videoManifest.length > 0) {
167050
167090
  writeFileSync34(
167051
- join88(outputDir, "extracted", "video-manifest.json"),
167091
+ join89(outputDir, "extracted", "video-manifest.json"),
167052
167092
  JSON.stringify(videoManifest, null, 2),
167053
167093
  "utf-8"
167054
167094
  );
@@ -167117,7 +167157,7 @@ var init_mediaCapture = __esm({
167117
167157
 
167118
167158
  // src/capture/contentExtractor.ts
167119
167159
  import { existsSync as existsSync87, readdirSync as readdirSync31, statSync as statSync28, readFileSync as readFileSync59 } from "fs";
167120
- import { basename as basename21, join as join89 } from "path";
167160
+ import { basename as basename21, join as join90 } from "path";
167121
167161
  async function detectLibraries(page, capturedShaders) {
167122
167162
  let detectedLibraries = [];
167123
167163
  try {
@@ -167284,7 +167324,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
167284
167324
  return response.text?.trim() || "";
167285
167325
  };
167286
167326
  }
167287
- const imageFiles = readdirSync31(join89(outputDir, "assets")).filter(
167327
+ const imageFiles = readdirSync31(join90(outputDir, "assets")).filter(
167288
167328
  (f3) => /\.(png|jpg|jpeg|webp|gif)$/i.test(f3)
167289
167329
  );
167290
167330
  const BATCH_SIZE = 20;
@@ -167292,7 +167332,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
167292
167332
  const batch = imageFiles.slice(i2, i2 + BATCH_SIZE);
167293
167333
  const results = await Promise.allSettled(
167294
167334
  batch.map(async (file) => {
167295
- const filePath = join89(outputDir, "assets", file);
167335
+ const filePath = join90(outputDir, "assets", file);
167296
167336
  const stat3 = statSync28(filePath);
167297
167337
  if (stat3.size > 4e6) return { file, caption: "" };
167298
167338
  const buffer = readFileSync59(filePath);
@@ -167326,11 +167366,11 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
167326
167366
  `${Object.keys(geminiCaptions).length} images captioned with ${providerName}`
167327
167367
  );
167328
167368
  const svgFiles = [];
167329
- const assetsDir = join89(outputDir, "assets");
167369
+ const assetsDir = join90(outputDir, "assets");
167330
167370
  for (const f3 of readdirSync31(assetsDir)) {
167331
167371
  if (/\.svg$/i.test(f3)) svgFiles.push({ file: f3, relPath: f3 });
167332
167372
  }
167333
- const svgsSubdir = join89(assetsDir, "svgs");
167373
+ const svgsSubdir = join90(assetsDir, "svgs");
167334
167374
  if (existsSync87(svgsSubdir)) {
167335
167375
  for (const f3 of readdirSync31(svgsSubdir)) {
167336
167376
  if (/\.svg$/i.test(f3)) svgFiles.push({ file: f3, relPath: `svgs/${f3}` });
@@ -167354,7 +167394,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
167354
167394
  const batch = svgFiles.slice(i2, i2 + SVG_BATCH);
167355
167395
  const results = await Promise.allSettled(
167356
167396
  batch.map(async ({ relPath }) => {
167357
- const filePath = join89(assetsDir, relPath);
167397
+ const filePath = join90(assetsDir, relPath);
167358
167398
  let pngBase64;
167359
167399
  try {
167360
167400
  const svgSource = readFileSync59(filePath, "utf-8");
@@ -167412,11 +167452,11 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
167412
167452
  const uncaptionedLines = [];
167413
167453
  const svgLines = [];
167414
167454
  const fontLines = [];
167415
- const assetsPath = join89(outputDir, "assets");
167455
+ const assetsPath = join90(outputDir, "assets");
167416
167456
  try {
167417
167457
  for (const file of readdirSync31(assetsPath)) {
167418
167458
  if (file === "svgs" || file === "fonts" || file === "lottie" || file === "videos") continue;
167419
- const filePath = join89(assetsPath, file);
167459
+ const filePath = join90(assetsPath, file);
167420
167460
  const stat3 = statSync28(filePath);
167421
167461
  if (!stat3.isFile()) continue;
167422
167462
  const sizeKb = Math.round(stat3.size / 1024);
@@ -167445,7 +167485,7 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
167445
167485
  } catch {
167446
167486
  }
167447
167487
  try {
167448
- const svgsPath = join89(assetsPath, "svgs");
167488
+ const svgsPath = join90(assetsPath, "svgs");
167449
167489
  for (const file of readdirSync31(svgsPath)) {
167450
167490
  if (!file.endsWith(".svg")) continue;
167451
167491
  const svgMatch = tokens.svgs.find(
@@ -167464,7 +167504,7 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
167464
167504
  } catch {
167465
167505
  }
167466
167506
  try {
167467
- const fontsPath = join89(assetsPath, "fonts");
167507
+ const fontsPath = join90(assetsPath, "fonts");
167468
167508
  for (const file of readdirSync31(fontsPath)) {
167469
167509
  fontLines.push(`fonts/${file} \u2014 font file`);
167470
167510
  }
@@ -167473,7 +167513,7 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
167473
167513
  const videoLines = [];
167474
167514
  try {
167475
167515
  const manifest = JSON.parse(
167476
- readFileSync59(join89(outputDir, "extracted", "video-manifest.json"), "utf-8")
167516
+ readFileSync59(join90(outputDir, "extracted", "video-manifest.json"), "utf-8")
167477
167517
  );
167478
167518
  for (const v2 of manifest) {
167479
167519
  if (!v2.localPath) continue;
@@ -167501,7 +167541,7 @@ __export(agentPromptGenerator_exports, {
167501
167541
  generateAgentPrompt: () => generateAgentPrompt
167502
167542
  });
167503
167543
  import { writeFileSync as writeFileSync35, readdirSync as readdirSync33, existsSync as existsSync88 } from "fs";
167504
- import { join as join90 } from "path";
167544
+ import { join as join91 } from "path";
167505
167545
  function inferColorRole(hex) {
167506
167546
  const r2 = parseInt(hex.slice(1, 3), 16) / 255;
167507
167547
  const g = parseInt(hex.slice(3, 5), 16) / 255;
@@ -167520,9 +167560,9 @@ function inferColorRole(hex) {
167520
167560
  }
167521
167561
  function generateAgentPrompt(outputDir, url, tokens, _animations, hasScreenshot, hasLottie, hasShaders, _catalogedAssets, _detectedLibraries) {
167522
167562
  const prompt = buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShaders);
167523
- writeFileSync35(join90(outputDir, "AGENTS.md"), prompt, "utf-8");
167524
- writeFileSync35(join90(outputDir, "CLAUDE.md"), prompt, "utf-8");
167525
- writeFileSync35(join90(outputDir, ".cursorrules"), prompt, "utf-8");
167563
+ writeFileSync35(join91(outputDir, "AGENTS.md"), prompt, "utf-8");
167564
+ writeFileSync35(join91(outputDir, "CLAUDE.md"), prompt, "utf-8");
167565
+ writeFileSync35(join91(outputDir, ".cursorrules"), prompt, "utf-8");
167526
167566
  }
167527
167567
  function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShaders) {
167528
167568
  const title = tokens.title || new URL(url).hostname.replace(/^www\./, "");
@@ -167531,7 +167571,7 @@ function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShader
167531
167571
  (f3) => f3.family + (f3.variable && f3.weightRange ? ` (${f3.weightRange[0]}-${f3.weightRange[1]} variable)` : f3.weights.length > 0 ? ` (${f3.weights.join(",")})` : "")
167532
167572
  ).join(", ") || "none detected";
167533
167573
  function contactSheetRows(dir, baseFile, label2) {
167534
- const fullDir = join90(outputDir, dir);
167574
+ const fullDir = join91(outputDir, dir);
167535
167575
  if (!existsSync88(fullDir)) return [];
167536
167576
  const baseName = baseFile.replace(/\.jpg$/, "");
167537
167577
  const escapedBase = baseName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -167564,7 +167604,7 @@ function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShader
167564
167604
  tableRows.push(
167565
167605
  `| \`extracted/tokens.json\` | Design tokens: ${tokens.colors.length} colors, ${tokens.fonts.length} fonts, ${tokens.headings?.length ?? 0} headings, ${tokens.ctas?.length ?? 0} CTAs |`
167566
167606
  );
167567
- if (existsSync88(join90(outputDir, "extracted", "design-styles.json"))) {
167607
+ if (existsSync88(join91(outputDir, "extracted", "design-styles.json"))) {
167568
167608
  tableRows.push(
167569
167609
  "| `extracted/design-styles.json` | Computed styles from live DOM: typography hierarchy, button/card/nav styles, spacing scale, border-radius, box shadows. Primary data source for DESIGN.md. |"
167570
167610
  );
@@ -167636,7 +167676,7 @@ var init_agentPromptGenerator = __esm({
167636
167676
 
167637
167677
  // src/capture/scaffolding.ts
167638
167678
  import { existsSync as existsSync89, writeFileSync as writeFileSync36, readFileSync as readFileSync60 } from "fs";
167639
- import { join as join91, resolve as resolve57 } from "path";
167679
+ import { join as join93, resolve as resolve57 } from "path";
167640
167680
  function loadEnvFile(startDir) {
167641
167681
  try {
167642
167682
  let dir = resolve57(startDir);
@@ -167662,7 +167702,7 @@ function loadEnvFile(startDir) {
167662
167702
  }
167663
167703
  }
167664
167704
  async function generateProjectScaffold(outputDir, url, tokens, animationCatalog, hasScreenshots, hasLotties, hasShaders, catalogedAssets, progress, warnings, detectedLibraries) {
167665
- const metaPath = join91(outputDir, "meta.json");
167705
+ const metaPath = join93(outputDir, "meta.json");
167666
167706
  if (!existsSync89(metaPath)) {
167667
167707
  const hostname = new URL(url).hostname.replace(/^www\./, "");
167668
167708
  writeFileSync36(
@@ -167701,9 +167741,9 @@ __export(screenshotCapture_exports, {
167701
167741
  captureScrollScreenshots: () => captureScrollScreenshots
167702
167742
  });
167703
167743
  import { writeFileSync as writeFileSync37, mkdirSync as mkdirSync44 } from "fs";
167704
- import { join as join93 } from "path";
167744
+ import { join as join94 } from "path";
167705
167745
  async function captureScrollScreenshots(page, outputDir) {
167706
- const screenshotsDir = join93(outputDir, "screenshots");
167746
+ const screenshotsDir = join94(outputDir, "screenshots");
167707
167747
  mkdirSync44(screenshotsDir, { recursive: true });
167708
167748
  const MAX_SCREENSHOTS = 20;
167709
167749
  const filePaths = [];
@@ -167795,7 +167835,7 @@ async function captureScrollScreenshots(page, outputDir) {
167795
167835
  finalPositions[i2] / Math.max(1, scrollHeight - viewportHeight) * 100
167796
167836
  );
167797
167837
  const filename = `scroll-${String(Math.min(pct, 100)).padStart(3, "0")}.png`;
167798
- const filePath = join93(screenshotsDir, filename);
167838
+ const filePath = join94(screenshotsDir, filename);
167799
167839
  const buffer = await page.screenshot({ type: "png" });
167800
167840
  writeFileSync37(filePath, buffer);
167801
167841
  filePaths.push(`screenshots/${filename}`);
@@ -168145,7 +168185,7 @@ __export(capture_exports, {
168145
168185
  captureWebsite: () => captureWebsite
168146
168186
  });
168147
168187
  import { mkdirSync as mkdirSync45, writeFileSync as writeFileSync38, existsSync as existsSync90 } from "fs";
168148
- import { join as join94 } from "path";
168188
+ import { join as join95 } from "path";
168149
168189
  async function captureWebsite(opts, onProgress) {
168150
168190
  const {
168151
168191
  url,
@@ -168162,9 +168202,9 @@ async function captureWebsite(opts, onProgress) {
168162
168202
  onProgress?.(stage, detail);
168163
168203
  };
168164
168204
  loadEnvFile(outputDir);
168165
- mkdirSync45(join94(outputDir, "extracted"), { recursive: true });
168166
- mkdirSync45(join94(outputDir, "screenshots"), { recursive: true });
168167
- mkdirSync45(join94(outputDir, "assets"), { recursive: true });
168205
+ mkdirSync45(join95(outputDir, "extracted"), { recursive: true });
168206
+ mkdirSync45(join95(outputDir, "screenshots"), { recursive: true });
168207
+ mkdirSync45(join95(outputDir, "assets"), { recursive: true });
168168
168208
  progress("browser", "Launching headless Chrome...");
168169
168209
  const { ensureBrowser: ensureBrowser2 } = await Promise.resolve().then(() => (init_manager2(), manager_exports2));
168170
168210
  const browser = await ensureBrowser2();
@@ -168324,7 +168364,7 @@ async function captureWebsite(opts, onProgress) {
168324
168364
  } catch {
168325
168365
  }
168326
168366
  if (discoveredLotties.length > 0) {
168327
- const lottieDir = join94(outputDir, "assets", "lottie");
168367
+ const lottieDir = join95(outputDir, "assets", "lottie");
168328
168368
  mkdirSync45(lottieDir, { recursive: true });
168329
168369
  const savedCount = await saveLottieAnimations(discoveredLotties, lottieDir);
168330
168370
  if (savedCount > 0) {
@@ -168344,7 +168384,7 @@ async function captureWebsite(opts, onProgress) {
168344
168384
  });
168345
168385
  capturedShaders = unique;
168346
168386
  writeFileSync38(
168347
- join94(outputDir, "extracted", "shaders.json"),
168387
+ join95(outputDir, "extracted", "shaders.json"),
168348
168388
  JSON.stringify(unique, null, 2),
168349
168389
  "utf-8"
168350
168390
  );
@@ -168359,7 +168399,7 @@ async function captureWebsite(opts, onProgress) {
168359
168399
  svgs: tokens.svgs.map(({ outerHTML: _, ...rest }) => rest)
168360
168400
  };
168361
168401
  writeFileSync38(
168362
- join94(outputDir, "extracted", "tokens.json"),
168402
+ join95(outputDir, "extracted", "tokens.json"),
168363
168403
  JSON.stringify(tokensForDisk, null, 2),
168364
168404
  "utf-8"
168365
168405
  );
@@ -168367,7 +168407,7 @@ async function captureWebsite(opts, onProgress) {
168367
168407
  try {
168368
168408
  const designStyles = await extractDesignStyles(page1);
168369
168409
  writeFileSync38(
168370
- join94(outputDir, "extracted", "design-styles.json"),
168410
+ join95(outputDir, "extracted", "design-styles.json"),
168371
168411
  JSON.stringify(designStyles, null, 2),
168372
168412
  "utf-8"
168373
168413
  );
@@ -168446,8 +168486,8 @@ ${err.stack}` : normalizeErrorMessage(err);
168446
168486
  extracted.headHtml = await downloadAndRewriteFonts(extracted.headHtml, outputDir);
168447
168487
  try {
168448
168488
  const fontsManifest = extractFontMetadata(
168449
- join94(outputDir, "assets", "fonts"),
168450
- join94(outputDir, "extracted", "fonts-manifest.json")
168489
+ join95(outputDir, "assets", "fonts"),
168490
+ join95(outputDir, "extracted", "fonts-manifest.json")
168451
168491
  );
168452
168492
  if (fontsManifest.families.length > 0) {
168453
168493
  const summary = fontsManifest.families.map((f3) => `${f3.family}${f3.variable ? " (variable)" : ""} \xD7 ${f3.fileCount}`).join(", ");
@@ -168474,7 +168514,7 @@ ${err.stack}` : normalizeErrorMessage(err);
168474
168514
  representativeAnimations: representativeAnims
168475
168515
  };
168476
168516
  writeFileSync38(
168477
- join94(outputDir, "extracted", "animations.json"),
168517
+ join95(outputDir, "extracted", "animations.json"),
168478
168518
  JSON.stringify(leanCatalog, null, 2),
168479
168519
  "utf-8"
168480
168520
  );
@@ -168505,7 +168545,7 @@ ${err.stack}` : normalizeErrorMessage(err);
168505
168545
  svgs: tokens.svgs.map(({ outerHTML: _, ...rest }) => rest)
168506
168546
  };
168507
168547
  writeFileSync38(
168508
- join94(outputDir, "extracted", "tokens.json"),
168548
+ join95(outputDir, "extracted", "tokens.json"),
168509
168549
  JSON.stringify(tokensForDisk2, null, 2),
168510
168550
  "utf-8"
168511
168551
  );
@@ -168521,12 +168561,12 @@ ${extracted.bodyHtml}
168521
168561
  </body>
168522
168562
  </html>
168523
168563
  `;
168524
- writeFileSync38(join94(outputDir, "extracted", "page.html"), pageHtml, "utf-8");
168564
+ writeFileSync38(join95(outputDir, "extracted", "page.html"), pageHtml, "utf-8");
168525
168565
  } catch (err) {
168526
168566
  warnings.push(`page.html write failed: ${err}`);
168527
168567
  }
168528
168568
  if (visibleTextContent) {
168529
- writeFileSync38(join94(outputDir, "extracted", "visible-text.txt"), visibleTextContent, "utf-8");
168569
+ writeFileSync38(join95(outputDir, "extracted", "visible-text.txt"), visibleTextContent, "utf-8");
168530
168570
  }
168531
168571
  const geminiCaptions = await captionImagesWithGemini(outputDir, progress, warnings);
168532
168572
  progress("design", "Generating asset descriptions...");
@@ -168536,7 +168576,7 @@ ${extracted.bodyHtml}
168536
168576
  const hasGeminiKey = !!(process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY);
168537
168577
  const header = hasGeminiKey ? "# Asset Descriptions\n\nOne line per file. Read this instead of opening every image individually.\n\nTo find a specific brand or icon, **grep this file for the brand name in the description text** (e.g. `grep -i 'autodesk' asset-descriptions.md`). The Gemini Vision captions identify what's actually in each file \u2014 that's the agent's selector.\n\nThe `logo-<hash>.svg` filename prefix is a cheap structural hint (DOM said this SVG was inside a `<header>`, home-link `<a>`, or had an aria-label matching the page brand). It is NOT a content claim \u2014 many `logo-*` files are nav icons or decorative shapes. Trust the captions, not the filename prefix.\n\n" : "# Asset Descriptions\n\n\u26A0\uFE0F GEMINI_API_KEY not set \u2014 descriptions below are catalog-derived (alt text, headings, section context, filename) instead of Vision-generated. To get richer Vision descriptions on the next capture, set GEMINI_API_KEY (or GOOGLE_API_KEY) and re-run.\n\nThe `logo-<hash>.svg` filename prefix is a structural hint (DOM said this SVG was inside a `<header>`, home-link `<a>`, or had an aria-label matching the page brand). To pick the actual brand logo without Vision, open the `logo-*` candidates in a previewer or rasterize them with `sharp` before referencing \u2014 composing a fake logo ships off-brand in the final video.\n\n";
168538
168578
  writeFileSync38(
168539
- join94(outputDir, "extracted", "asset-descriptions.md"),
168579
+ join95(outputDir, "extracted", "asset-descriptions.md"),
168540
168580
  header + lines.map((l) => "- " + l).join("\n") + "\n",
168541
168581
  "utf-8"
168542
168582
  );
@@ -168551,19 +168591,19 @@ ${extracted.bodyHtml}
168551
168591
  try {
168552
168592
  const { createScrollContactSheet: createScrollContactSheet2, createAssetContactSheet: createAssetContactSheet2, createSvgContactSheet: createSvgContactSheet2 } = await Promise.resolve().then(() => (init_contactSheet(), contactSheet_exports));
168553
168593
  const scrollSheets = await createScrollContactSheet2(
168554
- join94(outputDir, "screenshots"),
168555
- join94(outputDir, "screenshots", "contact-sheet.jpg")
168594
+ join95(outputDir, "screenshots"),
168595
+ join95(outputDir, "screenshots", "contact-sheet.jpg")
168556
168596
  );
168557
168597
  if (scrollSheets.length > 0)
168558
168598
  progress(
168559
168599
  "design",
168560
168600
  `Screenshot contact sheet generated (${scrollSheets.length} page${scrollSheets.length > 1 ? "s" : ""})`
168561
168601
  );
168562
- const assetsImgDir = join94(outputDir, "assets");
168602
+ const assetsImgDir = join95(outputDir, "assets");
168563
168603
  if (existsSync90(assetsImgDir)) {
168564
168604
  const assetSheets = await createAssetContactSheet2(
168565
168605
  assetsImgDir,
168566
- join94(outputDir, "assets", "contact-sheet.jpg")
168606
+ join95(outputDir, "assets", "contact-sheet.jpg")
168567
168607
  );
168568
168608
  if (assetSheets.length > 0)
168569
168609
  progress(
@@ -168571,9 +168611,9 @@ ${extracted.bodyHtml}
168571
168611
  `Asset contact sheet generated (${assetSheets.length} page${assetSheets.length > 1 ? "s" : ""})`
168572
168612
  );
168573
168613
  }
168574
- const svgsDir = join94(outputDir, "assets", "svgs");
168575
- const assetsRootDir = join94(outputDir, "assets");
168576
- const svgOutputPath = existsSync90(svgsDir) ? join94(outputDir, "assets", "svgs", "contact-sheet.jpg") : join94(outputDir, "assets", "contact-sheet-svgs.jpg");
168614
+ const svgsDir = join95(outputDir, "assets", "svgs");
168615
+ const assetsRootDir = join95(outputDir, "assets");
168616
+ const svgOutputPath = existsSync90(svgsDir) ? join95(outputDir, "assets", "svgs", "contact-sheet.jpg") : join95(outputDir, "assets", "contact-sheet-svgs.jpg");
168577
168617
  const svgSheets = await createSvgContactSheet2(svgsDir, svgOutputPath, assetsRootDir);
168578
168618
  if (svgSheets.length > 0)
168579
168619
  progress(
@@ -168589,7 +168629,7 @@ ${extracted.bodyHtml}
168589
168629
  animationCatalog,
168590
168630
  screenshots.length > 0,
168591
168631
  discoveredLotties.length > 0,
168592
- existsSync90(join94(outputDir, "extracted", "shaders.json")),
168632
+ existsSync90(join95(outputDir, "extracted", "shaders.json")),
168593
168633
  catalogedAssets,
168594
168634
  progress,
168595
168635
  warnings,
@@ -168875,9 +168915,9 @@ __export(state_exports, {
168875
168915
  writeStackOutputs: () => writeStackOutputs
168876
168916
  });
168877
168917
  import { existsSync as existsSync91, mkdirSync as mkdirSync46, readdirSync as readdirSync34, readFileSync as readFileSync61, rmSync as rmSync20, writeFileSync as writeFileSync39 } from "fs";
168878
- import { dirname as dirname40, join as join95 } from "path";
168918
+ import { dirname as dirname40, join as join96 } from "path";
168879
168919
  function stateFilePath(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
168880
- return join95(cwd, STATE_DIR_NAME, `${STATE_FILE_PREFIX}${stackName}.json`);
168920
+ return join96(cwd, STATE_DIR_NAME, `${STATE_FILE_PREFIX}${stackName}.json`);
168881
168921
  }
168882
168922
  function writeStackOutputs(outputs, cwd = process.cwd()) {
168883
168923
  const path2 = stateFilePath(outputs.stackName, cwd);
@@ -168899,7 +168939,7 @@ function deleteStackOutputs(stackName = DEFAULT_STACK_NAME, cwd = process.cwd())
168899
168939
  if (existsSync91(path2)) rmSync20(path2);
168900
168940
  }
168901
168941
  function listStackNames(cwd = process.cwd()) {
168902
- const dir = join95(cwd, STATE_DIR_NAME);
168942
+ const dir = join96(cwd, STATE_DIR_NAME);
168903
168943
  if (!existsSync91(dir)) return [];
168904
168944
  return readdirSync34(dir).filter((f3) => f3.startsWith(STATE_FILE_PREFIX) && f3.endsWith(".json")).map((f3) => f3.slice(STATE_FILE_PREFIX.length, -".json".length));
168905
168945
  }
@@ -168931,7 +168971,7 @@ var init_state = __esm({
168931
168971
  // src/commands/lambda/sam.ts
168932
168972
  import { execFileSync as execFileSync13, spawnSync as spawnSync4 } from "child_process";
168933
168973
  import { existsSync as existsSync92 } from "fs";
168934
- import { join as join96 } from "path";
168974
+ import { join as join97 } from "path";
168935
168975
  function assertSamAvailable() {
168936
168976
  try {
168937
168977
  execFileSync13("sam", ["--version"], { stdio: "ignore" });
@@ -168951,7 +168991,7 @@ function assertAwsCliAvailable() {
168951
168991
  }
168952
168992
  }
168953
168993
  function locateSamTemplate(repoRoot2) {
168954
- const candidate = join96(repoRoot2, "examples", "aws-lambda", "template.yaml");
168994
+ const candidate = join97(repoRoot2, "examples", "aws-lambda", "template.yaml");
168955
168995
  if (!existsSync92(candidate)) {
168956
168996
  throw new Error(
168957
168997
  `[lambda] SAM template not found at ${candidate}. If you're running from an installed package, point --sam-template at your local copy of examples/aws-lambda/template.yaml.`
@@ -168985,7 +169025,7 @@ function samDeploy(opts) {
168985
169025
  if (opts.awsProfile) {
168986
169026
  args.push("--profile", opts.awsProfile);
168987
169027
  }
168988
- const samDir = join96(opts.repoRoot, "examples", "aws-lambda");
169028
+ const samDir = join97(opts.repoRoot, "examples", "aws-lambda");
168989
169029
  const result = spawnSync4("sam", args, { cwd: samDir, stdio: opts.stdio ?? "inherit" });
168990
169030
  if (result.status !== 0) {
168991
169031
  throw new Error(`[lambda] sam deploy exited with code ${result.status ?? "unknown"}`);
@@ -168997,7 +169037,7 @@ function samDelete(opts) {
168997
169037
  if (opts.awsProfile) {
168998
169038
  args.push("--profile", opts.awsProfile);
168999
169039
  }
169000
- const samDir = join96(opts.repoRoot, "examples", "aws-lambda");
169040
+ const samDir = join97(opts.repoRoot, "examples", "aws-lambda");
169001
169041
  const result = spawnSync4("sam", args, { cwd: samDir, stdio: opts.stdio ?? "inherit" });
169002
169042
  if (result.status !== 0) {
169003
169043
  throw new Error(`[lambda] sam delete exited with code ${result.status ?? "unknown"}`);
@@ -169081,7 +169121,7 @@ __export(deploy_exports, {
169081
169121
  });
169082
169122
  import { spawnSync as spawnSync5 } from "child_process";
169083
169123
  import { existsSync as existsSync94 } from "fs";
169084
- import { join as join97, resolve as resolve60 } from "path";
169124
+ import { join as join98, resolve as resolve60 } from "path";
169085
169125
  async function runDeploy(args = {}) {
169086
169126
  const resolved = {
169087
169127
  stackName: args.stackName ?? DEFAULT_STACK_NAME,
@@ -169098,7 +169138,7 @@ async function runDeploy(args = {}) {
169098
169138
  console.log(c.dim("\u2192 Building handler ZIP"));
169099
169139
  buildHandlerZip(root);
169100
169140
  } else {
169101
- const zip = join97(root, "packages", "aws-lambda", "dist", "handler.zip");
169141
+ const zip = join98(root, "packages", "aws-lambda", "dist", "handler.zip");
169102
169142
  if (!existsSync94(zip)) {
169103
169143
  throw new Error(
169104
169144
  `--skip-build set but ${zip} does not exist. Run \`bun run --cwd packages/aws-lambda build:zip\` first or drop --skip-build.`
@@ -169142,7 +169182,7 @@ async function runDeploy(args = {}) {
169142
169182
  function buildHandlerZip(root) {
169143
169183
  const result = spawnSync5(
169144
169184
  "bun",
169145
- ["run", "--cwd", join97(root, "packages", "aws-lambda"), "build:zip"],
169185
+ ["run", "--cwd", join98(root, "packages", "aws-lambda"), "build:zip"],
169146
169186
  { stdio: "inherit" }
169147
169187
  );
169148
169188
  if (result.status !== 0) {
@@ -169212,13 +169252,13 @@ var init_sites = __esm({
169212
169252
 
169213
169253
  // src/commands/lambda/_dimensions.ts
169214
169254
  import { readFileSync as readFileSync63 } from "fs";
169215
- import { join as join98 } from "path";
169255
+ import { join as join99 } from "path";
169216
169256
  function warnOnDimensionMismatch(args) {
169217
169257
  if (args.quiet) return;
169218
169258
  if (args.outputResolution) return;
169219
169259
  let html;
169220
169260
  try {
169221
- html = readFileSync63(join98(args.projectDir, "index.html"), "utf-8");
169261
+ html = readFileSync63(join99(args.projectDir, "index.html"), "utf-8");
169222
169262
  } catch {
169223
169263
  return;
169224
169264
  }
@@ -169247,7 +169287,7 @@ __export(render_exports2, {
169247
169287
  runRender: () => runRender
169248
169288
  });
169249
169289
  import { existsSync as existsSync95 } from "fs";
169250
- import { join as join99, resolve as resolvePath2 } from "path";
169290
+ import { join as join100, resolve as resolvePath2 } from "path";
169251
169291
  async function loadSDK2() {
169252
169292
  return import("@hyperframes/aws-lambda/sdk");
169253
169293
  }
@@ -169263,7 +169303,7 @@ async function runRender(args) {
169263
169303
  });
169264
169304
  const variables = resolveVariablesArg(args.variables, args.variablesFile);
169265
169305
  if (variables && Object.keys(variables).length > 0) {
169266
- const indexPath2 = join99(projectDir, "index.html");
169306
+ const indexPath2 = join100(projectDir, "index.html");
169267
169307
  if (existsSync95(indexPath2)) {
169268
169308
  const issues = validateVariablesAgainstProject(indexPath2, variables);
169269
169309
  reportVariableIssues(issues, { strict: args.strictVariables ?? false, quiet: args.json });
@@ -169389,7 +169429,7 @@ __export(render_batch_exports, {
169389
169429
  runWithConcurrencyLimit: () => runWithConcurrencyLimit
169390
169430
  });
169391
169431
  import { existsSync as existsSync96, readFileSync as readFileSync64 } from "fs";
169392
- import { join as join100, resolve as resolvePath3 } from "path";
169432
+ import { join as join101, resolve as resolvePath3 } from "path";
169393
169433
  async function loadSDK3() {
169394
169434
  return import("@hyperframes/aws-lambda/sdk");
169395
169435
  }
@@ -169413,7 +169453,7 @@ async function runRenderBatch(args) {
169413
169453
  outputResolution: args.outputResolution,
169414
169454
  quiet: args.json
169415
169455
  });
169416
- const schema = loadProjectVariableSchema(join100(projectDir, "index.html"));
169456
+ const schema = loadProjectVariableSchema(join101(projectDir, "index.html"));
169417
169457
  const strict = args.strictVariables ?? false;
169418
169458
  let hadStrictIssue = false;
169419
169459
  for (const { entry, lineNumber } of entries2) {
@@ -170436,12 +170476,12 @@ import { spawnSync as spawnSync6 } from "child_process";
170436
170476
  import { createRequire as createRequire4 } from "module";
170437
170477
  import { existsSync as existsSync97, mkdirSync as mkdirSync47, readFileSync as readFileSync66, writeFileSync as writeFileSync40 } from "fs";
170438
170478
  import { homedir as homedir14 } from "os";
170439
- import { dirname as dirname42, join as join101, resolve as resolve61 } from "path";
170479
+ import { dirname as dirname42, join as join103, resolve as resolve61 } from "path";
170440
170480
  function stateDir() {
170441
- return join101(homedir14(), ".hyperframes");
170481
+ return join103(homedir14(), ".hyperframes");
170442
170482
  }
170443
170483
  function statePath() {
170444
- return join101(stateDir(), "cloudrun-state.json");
170484
+ return join103(stateDir(), "cloudrun-state.json");
170445
170485
  }
170446
170486
  function writeState(state) {
170447
170487
  mkdirSync47(stateDir(), { recursive: true });
@@ -170475,7 +170515,7 @@ function stripUndefined2(o) {
170475
170515
  function terraformDir() {
170476
170516
  const require3 = createRequire4(import.meta.url);
170477
170517
  const pkgJson = require3.resolve("@hyperframes/gcp-cloud-run/package.json");
170478
- return join101(dirname42(pkgJson), "terraform");
170518
+ return join103(dirname42(pkgJson), "terraform");
170479
170519
  }
170480
170520
  function run(cmd, cmdArgs, opts = {}) {
170481
170521
  const res = spawnSync6(cmd, cmdArgs, { stdio: "inherit", cwd: opts.cwd });
@@ -170602,11 +170642,11 @@ function machineVars(args, project, region, image) {
170602
170642
  }
170603
170643
  function findRepoRoot(tfDir) {
170604
170644
  const candidate = resolve61(tfDir, "..", "..", "..");
170605
- if (existsSync97(join101(candidate, "packages", "gcp-cloud-run", "Dockerfile"))) return candidate;
170645
+ if (existsSync97(join103(candidate, "packages", "gcp-cloud-run", "Dockerfile"))) return candidate;
170606
170646
  return null;
170607
170647
  }
170608
170648
  function writeCloudBuildConfig(image) {
170609
- const cfgPath = join101(stateDir(), "cloudrun-cloudbuild.yaml");
170649
+ const cfgPath = join103(stateDir(), "cloudrun-cloudbuild.yaml");
170610
170650
  mkdirSync47(stateDir(), { recursive: true });
170611
170651
  writeFileSync40(
170612
170652
  cfgPath,
@@ -170892,7 +170932,7 @@ function resolveAndValidateVariables(args, projectDir) {
170892
170932
  args["variables-file"]
170893
170933
  );
170894
170934
  if (variables && Object.keys(variables).length > 0) {
170895
- const indexPath2 = join101(projectDir, "index.html");
170935
+ const indexPath2 = join103(projectDir, "index.html");
170896
170936
  if (existsSync97(indexPath2)) {
170897
170937
  const issues = validateVariablesAgainstProject(indexPath2, variables);
170898
170938
  reportVariableIssues(issues, {
@@ -171907,14 +171947,14 @@ var init_browser2 = __esm({
171907
171947
 
171908
171948
  // src/auth/paths.ts
171909
171949
  import { homedir as homedir15 } from "os";
171910
- import { join as join103 } from "path";
171950
+ import { join as join104 } from "path";
171911
171951
  function configDir() {
171912
171952
  const override = process.env["HEYGEN_CONFIG_DIR"];
171913
171953
  if (override && override.length > 0) return override;
171914
- return join103(homedir15(), ".heygen");
171954
+ return join104(homedir15(), ".heygen");
171915
171955
  }
171916
171956
  function credentialPath() {
171917
- return join103(configDir(), CREDENTIAL_FILENAME);
171957
+ return join104(configDir(), CREDENTIAL_FILENAME);
171918
171958
  }
171919
171959
  var CREDENTIAL_FILENAME;
171920
171960
  var init_paths2 = __esm({
@@ -174613,15 +174653,15 @@ var init_jsonl = __esm({
174613
174653
 
174614
174654
  // ../core/dist/figma/manifest.js
174615
174655
  import { appendFileSync as appendFileSync2, existsSync as existsSync100, mkdirSync as mkdirSync50, readFileSync as readFileSync69, writeFileSync as writeFileSync43 } from "fs";
174616
- import { join as join104 } from "path";
174656
+ import { join as join105 } from "path";
174617
174657
  function mediaDir(projectDir) {
174618
- return join104(projectDir, ".media");
174658
+ return join105(projectDir, ".media");
174619
174659
  }
174620
174660
  function manifestPath(projectDir) {
174621
- return join104(mediaDir(projectDir), MANIFEST_FILE2);
174661
+ return join105(mediaDir(projectDir), MANIFEST_FILE2);
174622
174662
  }
174623
174663
  function typeDirPath(projectDir, type) {
174624
- return join104(mediaDir(projectDir), TYPE_DIRS[type]);
174664
+ return join105(mediaDir(projectDir), TYPE_DIRS[type]);
174625
174665
  }
174626
174666
  function isFigmaManifestRecord(value) {
174627
174667
  if (typeof value !== "object" || value === null)
@@ -174708,12 +174748,12 @@ var init_manifest = __esm({
174708
174748
 
174709
174749
  // ../core/dist/figma/mediaIndex.js
174710
174750
  import { mkdirSync as mkdirSync51, writeFileSync as writeFileSync44 } from "fs";
174711
- import { dirname as dirname46, join as join105 } from "path";
174751
+ import { dirname as dirname46, join as join106 } from "path";
174712
174752
  function isRow(value) {
174713
174753
  return typeof value === "object" && value !== null;
174714
174754
  }
174715
174755
  function indexPath(projectDir) {
174716
- return join105(mediaDir(projectDir), "index.md");
174756
+ return join106(mediaDir(projectDir), "index.md");
174717
174757
  }
174718
174758
  function pad(str, len2) {
174719
174759
  return String(str ?? "").padEnd(len2);
@@ -174825,9 +174865,9 @@ var init_sanitizeSvg = __esm({
174825
174865
 
174826
174866
  // ../core/dist/figma/bindings.js
174827
174867
  import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync53, writeFileSync as writeFileSync45 } from "fs";
174828
- import { join as join106 } from "path";
174868
+ import { join as join107 } from "path";
174829
174869
  function bindingsPath(projectDir) {
174830
- return join106(mediaDir(projectDir), BINDINGS_FILE);
174870
+ return join107(mediaDir(projectDir), BINDINGS_FILE);
174831
174871
  }
174832
174872
  function isRecord6(value) {
174833
174873
  return typeof value === "object" && value !== null;
@@ -175382,7 +175422,7 @@ __export(asset_exports, {
175382
175422
  runAssetImport: () => runAssetImport
175383
175423
  });
175384
175424
  import { existsSync as existsSync101 } from "fs";
175385
- import { join as join107, relative as relative16 } from "path";
175425
+ import { join as join108, relative as relative16 } from "path";
175386
175426
  async function runAssetImport(refInput, opts, deps) {
175387
175427
  const ref2 = parseFigmaRef(refInput);
175388
175428
  if (!ref2.nodeId)
@@ -175393,7 +175433,7 @@ async function runAssetImport(refInput, opts, deps) {
175393
175433
  const description = normalizeMeta(opts.description);
175394
175434
  const entity = normalizeMeta(opts.entity);
175395
175435
  const existing = findAllByFigmaNode(deps.projectDir, ref2.fileKey, ref2.nodeId).find(
175396
- (r2) => r2.provenance.format === opts.format && (r2.provenance.scale ?? 1) === (opts.scale ?? 1) && r2.provenance.version === version2 && existsSync101(join107(deps.projectDir, r2.path))
175436
+ (r2) => r2.provenance.format === opts.format && (r2.provenance.scale ?? 1) === (opts.scale ?? 1) && r2.provenance.version === version2 && existsSync101(join108(deps.projectDir, r2.path))
175397
175437
  );
175398
175438
  if (existing) {
175399
175439
  let record2 = existing;
@@ -175417,7 +175457,7 @@ async function runAssetImport(refInput, opts, deps) {
175417
175457
  bytes = new TextEncoder().encode(sanitizeSvg(new TextDecoder().decode(bytes)));
175418
175458
  }
175419
175459
  const id = nextId(deps.projectDir, "image");
175420
- const destAbs = join107(typeDirPath(deps.projectDir, "image"), `${id}.${rendered.ext}`);
175460
+ const destAbs = join108(typeDirPath(deps.projectDir, "image"), `${id}.${rendered.ext}`);
175421
175461
  freezeBytes(bytes, destAbs);
175422
175462
  const record = {
175423
175463
  id,
@@ -175514,11 +175554,11 @@ __export(tokens_exports, {
175514
175554
  runTokensImport: () => runTokensImport
175515
175555
  });
175516
175556
  import { writeFileSync as writeFileSync46 } from "fs";
175517
- import { join as join108 } from "path";
175557
+ import { join as join109 } from "path";
175518
175558
  async function runTokensImport(refInput, deps) {
175519
175559
  const { fileKey } = parseFigmaRef(refInput);
175520
175560
  const { version: version2 } = await deps.client.fileVersion(fileKey);
175521
- const sidecarPath = join108(deps.projectDir, "figma-tokens.json");
175561
+ const sidecarPath = join109(deps.projectDir, "figma-tokens.json");
175522
175562
  let vars = null;
175523
175563
  try {
175524
175564
  vars = await deps.client.variables(fileKey);
@@ -175585,7 +175625,7 @@ __export(component_exports, {
175585
175625
  runComponentImport: () => runComponentImport
175586
175626
  });
175587
175627
  import { existsSync as existsSync102, mkdirSync as mkdirSync54, writeFileSync as writeFileSync47 } from "fs";
175588
- import { join as join109, relative as relative17 } from "path";
175628
+ import { join as join110, relative as relative17 } from "path";
175589
175629
  function escapeAttr2(value) {
175590
175630
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
175591
175631
  }
@@ -175596,7 +175636,7 @@ async function runComponentImport(refInput, deps) {
175596
175636
  const bindings = resolveBindings(tree, readBindings(deps.projectDir));
175597
175637
  const mapped = nodeToHtml(tree, bindings);
175598
175638
  const name = slugify2(tree.name);
175599
- const componentDir = join109(deps.projectDir, "compositions", "components", name);
175639
+ const componentDir = join110(deps.projectDir, "compositions", "components", name);
175600
175640
  if (existsSync102(componentDir))
175601
175641
  console.warn(
175602
175642
  `component dir compositions/components/${name} already exists \u2014 overwriting (rename the figma frame for a separate import)`
@@ -175611,7 +175651,7 @@ async function runComponentImport(refInput, deps) {
175611
175651
  { projectDir: deps.projectDir, client: deps.client, download: deps.download }
175612
175652
  );
175613
175653
  frozenAssets.push(asset.record.path);
175614
- const srcRel = relative17(componentDir, join109(deps.projectDir, asset.record.path)).replaceAll(
175654
+ const srcRel = relative17(componentDir, join110(deps.projectDir, asset.record.path)).replaceAll(
175615
175655
  "\\",
175616
175656
  "/"
175617
175657
  );
@@ -175621,7 +175661,7 @@ async function runComponentImport(refInput, deps) {
175621
175661
  `data-figma-rasterize="${emittedId}" src="${escapeAttr2(srcRel)}" `
175622
175662
  );
175623
175663
  }
175624
- const htmlFile = join109(componentDir, `${name}.html`);
175664
+ const htmlFile = join110(componentDir, `${name}.html`);
175625
175665
  writeFileSync47(htmlFile, html + "\n");
175626
175666
  const registryItem = {
175627
175667
  name,
@@ -175643,7 +175683,7 @@ async function runComponentImport(refInput, deps) {
175643
175683
  ]
175644
175684
  };
175645
175685
  writeFileSync47(
175646
- join109(componentDir, "registry-item.json"),
175686
+ join110(componentDir, "registry-item.json"),
175647
175687
  JSON.stringify(registryItem, null, 2) + "\n"
175648
175688
  );
175649
175689
  return {
@@ -175885,7 +175925,7 @@ __export(autoUpdate_exports, {
175885
175925
  import { spawn as spawn17 } from "child_process";
175886
175926
  import { appendFileSync as appendFileSync4, mkdirSync as mkdirSync55, openSync as openSync4 } from "fs";
175887
175927
  import { homedir as homedir16 } from "os";
175888
- import { join as join110 } from "path";
175928
+ import { join as join111 } from "path";
175889
175929
  import { compareVersions as compareVersions3 } from "compare-versions";
175890
175930
  function isAutoInstallDisabled() {
175891
175931
  if (isDevMode()) return true;
@@ -175908,7 +175948,7 @@ function log(line2) {
175908
175948
  }
175909
175949
  function launchDetachedInstall(installCommand, version2) {
175910
175950
  mkdirSync55(CONFIG_DIR2, { recursive: true, mode: 448 });
175911
- const configFile = join110(CONFIG_DIR2, "config.json");
175951
+ const configFile = join111(CONFIG_DIR2, "config.json");
175912
175952
  const nodeScript = `
175913
175953
  const { exec } = require("node:child_process");
175914
175954
  const { readFileSync, renameSync, writeFileSync } = require("node:fs");
@@ -176027,8 +176067,8 @@ var init_autoUpdate = __esm({
176027
176067
  init_config();
176028
176068
  init_env();
176029
176069
  init_installerDetection();
176030
- CONFIG_DIR2 = join110(homedir16(), ".hyperframes");
176031
- LOG_FILE = join110(CONFIG_DIR2, "auto-update.log");
176070
+ CONFIG_DIR2 = join111(homedir16(), ".hyperframes");
176071
+ LOG_FILE = join111(CONFIG_DIR2, "auto-update.log");
176032
176072
  PENDING_TIMEOUT_MS = 10 * 60 * 1e3;
176033
176073
  }
176034
176074
  });
@@ -176276,7 +176316,7 @@ var init_help = __esm({
176276
176316
  // src/cli.ts
176277
176317
  init_version();
176278
176318
  init_dist();
176279
- import { dirname as dirname47, join as join111 } from "path";
176319
+ import { dirname as dirname47, join as join113 } from "path";
176280
176320
  import { fileURLToPath as fileURLToPath16 } from "url";
176281
176321
  import { existsSync as existsSync103 } from "fs";
176282
176322
 
@@ -176321,7 +176361,7 @@ for (const stream of [process.stdout, process.stderr]) {
176321
176361
  }
176322
176362
  (() => {
176323
176363
  const here = dirname47(fileURLToPath16(import.meta.url));
176324
- const shader = join111(here, "shaderTransitionWorker.js");
176364
+ const shader = join113(here, "shaderTransitionWorker.js");
176325
176365
  if (!process.env.HF_SHADER_WORKER_ENTRY && existsSync103(shader)) {
176326
176366
  process.env.HF_SHADER_WORKER_ENTRY = shader;
176327
176367
  }