hyperframes 0.6.35 → 0.6.37
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 +778 -539
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -54,7 +54,7 @@ var VERSION;
|
|
|
54
54
|
var init_version = __esm({
|
|
55
55
|
"src/version.ts"() {
|
|
56
56
|
"use strict";
|
|
57
|
-
VERSION = true ? "0.6.
|
|
57
|
+
VERSION = true ? "0.6.37" : "0.0.0-dev";
|
|
58
58
|
}
|
|
59
59
|
});
|
|
60
60
|
|
|
@@ -2792,6 +2792,12 @@ var init_banner = __esm({
|
|
|
2792
2792
|
});
|
|
2793
2793
|
|
|
2794
2794
|
// ../core/src/core.types.ts
|
|
2795
|
+
function toFps(input) {
|
|
2796
|
+
if (typeof input === "number") {
|
|
2797
|
+
return { num: input, den: 1 };
|
|
2798
|
+
}
|
|
2799
|
+
return input;
|
|
2800
|
+
}
|
|
2795
2801
|
function fpsToNumber(fps) {
|
|
2796
2802
|
return fps.num / fps.den;
|
|
2797
2803
|
}
|
|
@@ -10985,6 +10991,7 @@ __export(src_exports, {
|
|
|
10985
10991
|
rewriteCssAssetUrls: () => rewriteCssAssetUrls,
|
|
10986
10992
|
serializeGsapAnimations: () => serializeGsapAnimations,
|
|
10987
10993
|
shouldClampMediaDuration: () => shouldClampMediaDuration,
|
|
10994
|
+
toFps: () => toFps,
|
|
10988
10995
|
updateAnimationInScript: () => updateAnimationInScript,
|
|
10989
10996
|
updateElementInHtml: () => updateElementInHtml,
|
|
10990
10997
|
validateCompositionGsap: () => validateCompositionGsap,
|
|
@@ -11358,9 +11365,173 @@ var init_env = __esm({
|
|
|
11358
11365
|
}
|
|
11359
11366
|
});
|
|
11360
11367
|
|
|
11368
|
+
// src/telemetry/platform.ts
|
|
11369
|
+
import { platform, release } from "os";
|
|
11370
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
11371
|
+
function detectWSL() {
|
|
11372
|
+
if (platform() !== "linux") return false;
|
|
11373
|
+
try {
|
|
11374
|
+
const osRelease = release().toLowerCase();
|
|
11375
|
+
if (osRelease.includes("microsoft") || osRelease.includes("wsl")) return true;
|
|
11376
|
+
const procVersion = readFileSync4("/proc/version", "utf-8").toLowerCase();
|
|
11377
|
+
return procVersion.includes("microsoft") || procVersion.includes("wsl");
|
|
11378
|
+
} catch {
|
|
11379
|
+
return false;
|
|
11380
|
+
}
|
|
11381
|
+
}
|
|
11382
|
+
var init_platform = __esm({
|
|
11383
|
+
"src/telemetry/platform.ts"() {
|
|
11384
|
+
"use strict";
|
|
11385
|
+
}
|
|
11386
|
+
});
|
|
11387
|
+
|
|
11388
|
+
// src/telemetry/agent_runtime.ts
|
|
11389
|
+
import { existsSync as existsSync4, readFileSync as readFileSync5 } from "fs";
|
|
11390
|
+
import { platform as platform2, release as release2 } from "os";
|
|
11391
|
+
function detectSandboxRuntime() {
|
|
11392
|
+
if (platform2() === "win32") return null;
|
|
11393
|
+
if (detectWSL()) return "wsl";
|
|
11394
|
+
if (isGVisor()) return "gvisor";
|
|
11395
|
+
if (isDocker()) return "docker";
|
|
11396
|
+
if (isFirecracker()) return "firecracker";
|
|
11397
|
+
if (isKVM()) return "kvm";
|
|
11398
|
+
return null;
|
|
11399
|
+
}
|
|
11400
|
+
function detectAgentRuntime() {
|
|
11401
|
+
for (const rule of VENDOR_RULES) {
|
|
11402
|
+
if (rule.check(process.env)) return rule.name;
|
|
11403
|
+
}
|
|
11404
|
+
return null;
|
|
11405
|
+
}
|
|
11406
|
+
function isGVisor() {
|
|
11407
|
+
const kernel = release2();
|
|
11408
|
+
if (kernel.includes("gvisor")) return true;
|
|
11409
|
+
if (platform2() !== "linux") return false;
|
|
11410
|
+
try {
|
|
11411
|
+
const procVersion = readFileSync5("/proc/version", "utf-8");
|
|
11412
|
+
return procVersion.includes("gVisor");
|
|
11413
|
+
} catch {
|
|
11414
|
+
return false;
|
|
11415
|
+
}
|
|
11416
|
+
}
|
|
11417
|
+
function isDocker() {
|
|
11418
|
+
if (existsSync4("/.dockerenv")) return true;
|
|
11419
|
+
if (platform2() !== "linux") return false;
|
|
11420
|
+
try {
|
|
11421
|
+
const cgroup = readFileSync5("/proc/1/cgroup", "utf-8");
|
|
11422
|
+
return cgroup.includes("docker") || cgroup.includes("containerd");
|
|
11423
|
+
} catch {
|
|
11424
|
+
return false;
|
|
11425
|
+
}
|
|
11426
|
+
}
|
|
11427
|
+
function isFirecracker() {
|
|
11428
|
+
if (platform2() !== "linux") return false;
|
|
11429
|
+
if (!existsSync4("/dev/vsock")) return false;
|
|
11430
|
+
try {
|
|
11431
|
+
const sysVendor = readFileSync5("/sys/class/dmi/id/sys_vendor", "utf-8").trim();
|
|
11432
|
+
if (sysVendor !== "Amazon EC2") return false;
|
|
11433
|
+
const productName = readFileSync5("/sys/class/dmi/id/product_name", "utf-8").trim();
|
|
11434
|
+
return productName.toLowerCase().includes("firecracker");
|
|
11435
|
+
} catch {
|
|
11436
|
+
return false;
|
|
11437
|
+
}
|
|
11438
|
+
}
|
|
11439
|
+
function isKVM() {
|
|
11440
|
+
if (platform2() !== "linux") return false;
|
|
11441
|
+
try {
|
|
11442
|
+
const sysVendor = readFileSync5("/sys/class/dmi/id/sys_vendor", "utf-8").trim();
|
|
11443
|
+
return sysVendor === "QEMU" || sysVendor.includes("KVM");
|
|
11444
|
+
} catch {
|
|
11445
|
+
return false;
|
|
11446
|
+
}
|
|
11447
|
+
}
|
|
11448
|
+
var VENDOR_RULES;
|
|
11449
|
+
var init_agent_runtime = __esm({
|
|
11450
|
+
"src/telemetry/agent_runtime.ts"() {
|
|
11451
|
+
"use strict";
|
|
11452
|
+
init_platform();
|
|
11453
|
+
VENDOR_RULES = [
|
|
11454
|
+
// Anthropic Claude Code — sets CLAUDECODE=1 on every Bash/PowerShell tool
|
|
11455
|
+
// spawn (Shell.ts:321) and CLAUDE_CODE_ENTRYPOINT at startup, inherited by
|
|
11456
|
+
// every child (main.tsx:527). Both propagate to spawned subprocesses.
|
|
11457
|
+
// Source: confirmed by @magi from Claude Code internal source.
|
|
11458
|
+
{
|
|
11459
|
+
name: "claude_code",
|
|
11460
|
+
check: (env) => typeof env["CLAUDECODE"] === "string" || typeof env["CLAUDE_CODE_ENTRYPOINT"] === "string"
|
|
11461
|
+
},
|
|
11462
|
+
// OpenAI Codex (https://github.com/openai/codex).
|
|
11463
|
+
// - CODEX_THREAD_ID — set unconditionally on every spawned shell command
|
|
11464
|
+
// (codex-rs/protocol/src/shell_environment.rs:6 constant, set by
|
|
11465
|
+
// codex-rs/core/src/unified_exec/process_manager.rs:1010 and
|
|
11466
|
+
// codex-rs/core/src/tools/runtimes/mod.rs:164).
|
|
11467
|
+
// - CODEX_CI — hardcoded in the UNIFIED_EXEC_ENV array, always set on
|
|
11468
|
+
// every unified-exec child (process_manager.rs:70).
|
|
11469
|
+
// - CODEX_SANDBOX_NETWORK_DISABLED — set when network sandbox is active
|
|
11470
|
+
// (codex-rs/core/src/sandboxing/mod.rs:135-138, default-on).
|
|
11471
|
+
// CODEX_HOME is deliberately NOT used — it's a config override read at
|
|
11472
|
+
// Codex startup, not propagated to spawned subprocesses.
|
|
11473
|
+
{
|
|
11474
|
+
name: "codex",
|
|
11475
|
+
check: (env) => typeof env["CODEX_THREAD_ID"] === "string" || typeof env["CODEX_CI"] === "string" || typeof env["CODEX_SANDBOX_NETWORK_DISABLED"] === "string"
|
|
11476
|
+
},
|
|
11477
|
+
// Cursor IDE integrated terminal — exports TERM_PROGRAM=cursor.
|
|
11478
|
+
// Cursor Background Agent env vars are not publicly documented; if a
|
|
11479
|
+
// canonical marker is identified later, add it here.
|
|
11480
|
+
{
|
|
11481
|
+
name: "cursor",
|
|
11482
|
+
check: (env) => env["TERM_PROGRAM"] === "cursor"
|
|
11483
|
+
},
|
|
11484
|
+
// GitHub Copilot Coding Agent — runs inside GitHub Actions and the
|
|
11485
|
+
// workflow injects an additional marker to distinguish from generic CI.
|
|
11486
|
+
// Not yet verified from a public-source citation in this audit; the var
|
|
11487
|
+
// names below match GitHub Copilot Coding Agent documentation but
|
|
11488
|
+
// should be confirmed before relying on attribution.
|
|
11489
|
+
{
|
|
11490
|
+
name: "copilot_agent",
|
|
11491
|
+
check: (env) => env["GITHUB_ACTIONS"] === "true" && (typeof env["COPILOT_AGENT_ID"] === "string" || env["RUNNER_NAME"] === "Copilot")
|
|
11492
|
+
},
|
|
11493
|
+
// Replit — REPL_ID and REPLIT_USER are long-documented environment
|
|
11494
|
+
// variables exposed inside every Replit workspace.
|
|
11495
|
+
// Source: https://docs.replit.com/replit-workspace/configuring-the-environment
|
|
11496
|
+
{
|
|
11497
|
+
name: "replit",
|
|
11498
|
+
check: (env) => typeof env["REPL_ID"] === "string" || typeof env["REPLIT_USER"] === "string"
|
|
11499
|
+
},
|
|
11500
|
+
// Nous Research Hermes Agent — cli.py:50 unconditionally executes
|
|
11501
|
+
// os.environ["HERMES_QUIET"] = "1"
|
|
11502
|
+
// at module load, so the marker propagates via os.environ to every
|
|
11503
|
+
// subprocess spawned by Hermes. Keying on existence (not the literal
|
|
11504
|
+
// "1") so we still match if Hermes ever changes the value.
|
|
11505
|
+
// Source: https://github.com/NousResearch/hermes-agent (cli.py:50)
|
|
11506
|
+
{
|
|
11507
|
+
name: "hermes",
|
|
11508
|
+
check: (env) => typeof env["HERMES_QUIET"] === "string"
|
|
11509
|
+
},
|
|
11510
|
+
// openclaw — multi-channel AI gateway. When openclaw spawns a CLI
|
|
11511
|
+
// subprocess it builds the child env with OPENCLAW_STATE_DIR /
|
|
11512
|
+
// OPENCLAW_CONFIG_PATH / OPENCLAW_DISABLE_AUTO_UPDATE set explicitly
|
|
11513
|
+
// (extensions/qa-matrix/src/runners/contract/scenario-runtime-cli.ts:344-351).
|
|
11514
|
+
// We key on OPENCLAW_STATE_DIR since it's a path scope-bound to openclaw.
|
|
11515
|
+
// Source: https://github.com/openclaw/openclaw
|
|
11516
|
+
{
|
|
11517
|
+
name: "openclaw",
|
|
11518
|
+
check: (env) => typeof env["OPENCLAW_STATE_DIR"] === "string" || typeof env["OPENCLAW_CONFIG_PATH"] === "string"
|
|
11519
|
+
},
|
|
11520
|
+
// Pi coding agent (https://pi.dev, https://github.com/earendil-works/pi).
|
|
11521
|
+
// packages/coding-agent/src/cli.ts:13 unconditionally executes
|
|
11522
|
+
// process.env.PI_CODING_AGENT = "true";
|
|
11523
|
+
// at module entry, so every subprocess Pi spawns sees this marker.
|
|
11524
|
+
{
|
|
11525
|
+
name: "pi",
|
|
11526
|
+
check: (env) => typeof env["PI_CODING_AGENT"] === "string"
|
|
11527
|
+
}
|
|
11528
|
+
];
|
|
11529
|
+
}
|
|
11530
|
+
});
|
|
11531
|
+
|
|
11361
11532
|
// src/telemetry/system.ts
|
|
11362
|
-
import { cpus, totalmem, platform, release } from "os";
|
|
11363
|
-
import { existsSync as
|
|
11533
|
+
import { cpus, totalmem, platform as platform3, release as release3 } from "os";
|
|
11534
|
+
import { existsSync as existsSync5, readFileSync as readFileSync6, statfsSync } from "fs";
|
|
11364
11535
|
function bytesToMb(bytes) {
|
|
11365
11536
|
return Math.trunc(bytes / (1024 * 1024));
|
|
11366
11537
|
}
|
|
@@ -11369,7 +11540,7 @@ function getSystemMeta() {
|
|
|
11369
11540
|
const cpuInfo = cpus();
|
|
11370
11541
|
const firstCpu = cpuInfo[0] ?? null;
|
|
11371
11542
|
cached = {
|
|
11372
|
-
os_release:
|
|
11543
|
+
os_release: release3(),
|
|
11373
11544
|
cpu_count: cpuInfo.length,
|
|
11374
11545
|
cpu_model: firstCpu?.model?.trim() ?? null,
|
|
11375
11546
|
cpu_speed: firstCpu?.speed ?? null,
|
|
@@ -11378,47 +11549,39 @@ function getSystemMeta() {
|
|
|
11378
11549
|
is_ci: detectCI(),
|
|
11379
11550
|
ci_name: getCIName(),
|
|
11380
11551
|
is_wsl: detectWSL(),
|
|
11381
|
-
is_tty: Boolean(process.stdout?.isTTY)
|
|
11552
|
+
is_tty: Boolean(process.stdout?.isTTY),
|
|
11553
|
+
sandbox_runtime: detectSandboxRuntime(),
|
|
11554
|
+
agent_runtime: detectAgentRuntime()
|
|
11382
11555
|
};
|
|
11383
11556
|
return cached;
|
|
11384
11557
|
}
|
|
11385
11558
|
function detectDocker() {
|
|
11386
11559
|
try {
|
|
11387
|
-
if (
|
|
11388
|
-
if (
|
|
11389
|
-
const cgroup =
|
|
11560
|
+
if (existsSync5("/.dockerenv")) return true;
|
|
11561
|
+
if (platform3() === "linux") {
|
|
11562
|
+
const cgroup = readFileSync6("/proc/1/cgroup", "utf-8");
|
|
11390
11563
|
if (cgroup.includes("docker") || cgroup.includes("containerd")) return true;
|
|
11391
11564
|
}
|
|
11392
11565
|
} catch {
|
|
11393
11566
|
}
|
|
11394
11567
|
return false;
|
|
11395
11568
|
}
|
|
11569
|
+
function matchesProvider(p2) {
|
|
11570
|
+
const v2 = process.env[p2.envVar];
|
|
11571
|
+
if (p2.mode === "presence") return v2 != null;
|
|
11572
|
+
return v2 === "true" || v2 === "1";
|
|
11573
|
+
}
|
|
11396
11574
|
function detectCI() {
|
|
11397
|
-
return
|
|
11575
|
+
return CI_PROVIDERS.some(matchesProvider);
|
|
11398
11576
|
}
|
|
11399
11577
|
function getCIName() {
|
|
11400
|
-
|
|
11401
|
-
|
|
11402
|
-
if (process.env["CIRCLECI"] === "true") return "circleci";
|
|
11403
|
-
if (process.env["JENKINS_URL"] != null) return "jenkins";
|
|
11404
|
-
if (process.env["BUILDKITE"] === "true") return "buildkite";
|
|
11405
|
-
if (process.env["TRAVIS"] === "true") return "travis";
|
|
11406
|
-
if (detectCI()) return "unknown";
|
|
11407
|
-
return null;
|
|
11408
|
-
}
|
|
11409
|
-
function detectWSL() {
|
|
11410
|
-
if (platform() !== "linux") return false;
|
|
11411
|
-
try {
|
|
11412
|
-
const osRelease = release().toLowerCase();
|
|
11413
|
-
if (osRelease.includes("microsoft") || osRelease.includes("wsl")) return true;
|
|
11414
|
-
const procVersion = readFileSync4("/proc/version", "utf-8").toLowerCase();
|
|
11415
|
-
return procVersion.includes("microsoft") || procVersion.includes("wsl");
|
|
11416
|
-
} catch {
|
|
11417
|
-
return false;
|
|
11578
|
+
for (const provider of CI_PROVIDERS) {
|
|
11579
|
+
if (provider.name && matchesProvider(provider)) return provider.name;
|
|
11418
11580
|
}
|
|
11581
|
+
return detectCI() ? "unknown" : null;
|
|
11419
11582
|
}
|
|
11420
11583
|
function getShmSizeMb() {
|
|
11421
|
-
if (
|
|
11584
|
+
if (platform3() !== "linux") return null;
|
|
11422
11585
|
try {
|
|
11423
11586
|
const stats = statfsSync("/dev/shm");
|
|
11424
11587
|
return bytesToMb(stats.bsize * stats.blocks);
|
|
@@ -11434,11 +11597,23 @@ function getFreeDiskMb(path2 = ".") {
|
|
|
11434
11597
|
return null;
|
|
11435
11598
|
}
|
|
11436
11599
|
}
|
|
11437
|
-
var cached;
|
|
11600
|
+
var cached, CI_PROVIDERS;
|
|
11438
11601
|
var init_system = __esm({
|
|
11439
11602
|
"src/telemetry/system.ts"() {
|
|
11440
11603
|
"use strict";
|
|
11604
|
+
init_agent_runtime();
|
|
11605
|
+
init_platform();
|
|
11441
11606
|
cached = null;
|
|
11607
|
+
CI_PROVIDERS = [
|
|
11608
|
+
{ name: "github_actions", envVar: "GITHUB_ACTIONS", mode: "truthy" },
|
|
11609
|
+
{ name: "gitlab_ci", envVar: "GITLAB_CI", mode: "truthy" },
|
|
11610
|
+
{ name: "circleci", envVar: "CIRCLECI", mode: "truthy" },
|
|
11611
|
+
{ name: "jenkins", envVar: "JENKINS_URL", mode: "presence" },
|
|
11612
|
+
{ name: "buildkite", envVar: "BUILDKITE", mode: "truthy" },
|
|
11613
|
+
{ name: "travis", envVar: "TRAVIS", mode: "truthy" },
|
|
11614
|
+
{ name: null, envVar: "CONTINUOUS_INTEGRATION", mode: "truthy" },
|
|
11615
|
+
{ name: null, envVar: "CI", mode: "truthy" }
|
|
11616
|
+
];
|
|
11442
11617
|
}
|
|
11443
11618
|
});
|
|
11444
11619
|
|
|
@@ -11481,32 +11656,35 @@ function trackEvent(event, properties = {}) {
|
|
|
11481
11656
|
is_ci: sys.is_ci,
|
|
11482
11657
|
ci_name: sys.ci_name ?? void 0,
|
|
11483
11658
|
is_wsl: sys.is_wsl,
|
|
11484
|
-
is_tty: sys.is_tty
|
|
11659
|
+
is_tty: sys.is_tty,
|
|
11660
|
+
sandbox_runtime: sys.sandbox_runtime ?? void 0,
|
|
11661
|
+
agent_runtime: sys.agent_runtime ?? void 0
|
|
11485
11662
|
},
|
|
11486
11663
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
11487
11664
|
});
|
|
11488
11665
|
}
|
|
11489
|
-
|
|
11490
|
-
if (eventQueue.length === 0)
|
|
11491
|
-
return;
|
|
11492
|
-
}
|
|
11666
|
+
function drainQueueToPayload() {
|
|
11667
|
+
if (eventQueue.length === 0) return null;
|
|
11493
11668
|
const config = readConfig();
|
|
11494
11669
|
const batch = eventQueue.map((e3) => ({
|
|
11495
11670
|
event: e3.event,
|
|
11496
|
-
// $ip: null tells PostHog to not record the request IP for this event.
|
|
11497
|
-
// Server-side "Discard client IP data" is also enabled in project settings.
|
|
11498
11671
|
properties: { ...e3.properties, $ip: null },
|
|
11499
11672
|
distinct_id: config.anonymousId,
|
|
11500
11673
|
timestamp: e3.timestamp
|
|
11501
11674
|
}));
|
|
11502
11675
|
eventQueue = [];
|
|
11676
|
+
return JSON.stringify({ api_key: POSTHOG_API_KEY, batch });
|
|
11677
|
+
}
|
|
11678
|
+
async function flush() {
|
|
11679
|
+
const payload = drainQueueToPayload();
|
|
11680
|
+
if (payload == null) return;
|
|
11503
11681
|
const controller = new AbortController();
|
|
11504
11682
|
const timeout = setTimeout(() => controller.abort(), FLUSH_TIMEOUT_MS);
|
|
11505
11683
|
try {
|
|
11506
11684
|
await fetch(`${POSTHOG_HOST}/batch/`, {
|
|
11507
11685
|
method: "POST",
|
|
11508
11686
|
headers: { "Content-Type": "application/json", Connection: "close" },
|
|
11509
|
-
body:
|
|
11687
|
+
body: payload,
|
|
11510
11688
|
signal: controller.signal
|
|
11511
11689
|
});
|
|
11512
11690
|
} catch {
|
|
@@ -11515,18 +11693,8 @@ async function flush() {
|
|
|
11515
11693
|
}
|
|
11516
11694
|
}
|
|
11517
11695
|
function flushSync() {
|
|
11518
|
-
|
|
11519
|
-
|
|
11520
|
-
}
|
|
11521
|
-
const config = readConfig();
|
|
11522
|
-
const batch = eventQueue.map((e3) => ({
|
|
11523
|
-
event: e3.event,
|
|
11524
|
-
properties: { ...e3.properties, $ip: null },
|
|
11525
|
-
distinct_id: config.anonymousId,
|
|
11526
|
-
timestamp: e3.timestamp
|
|
11527
|
-
}));
|
|
11528
|
-
eventQueue = [];
|
|
11529
|
-
const payload = JSON.stringify({ api_key: POSTHOG_API_KEY, batch });
|
|
11696
|
+
const payload = drainQueueToPayload();
|
|
11697
|
+
if (payload == null) return;
|
|
11530
11698
|
try {
|
|
11531
11699
|
const { spawn: spawn17 } = __require("child_process");
|
|
11532
11700
|
const child = spawn17(
|
|
@@ -11701,8 +11869,8 @@ __export(manager_exports, {
|
|
|
11701
11869
|
hasFFprobe: () => hasFFprobe
|
|
11702
11870
|
});
|
|
11703
11871
|
import { execFileSync } from "child_process";
|
|
11704
|
-
import { existsSync as
|
|
11705
|
-
import { homedir as homedir3, platform as
|
|
11872
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync3, rmSync } from "fs";
|
|
11873
|
+
import { homedir as homedir3, platform as platform4 } from "os";
|
|
11706
11874
|
import { join as join5 } from "path";
|
|
11707
11875
|
function getModelUrl(model) {
|
|
11708
11876
|
return `https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-${model}.bin`;
|
|
@@ -11723,7 +11891,7 @@ function whichBinary(name) {
|
|
|
11723
11891
|
}
|
|
11724
11892
|
function findFromEnv() {
|
|
11725
11893
|
const envPath = process.env["HYPERFRAMES_WHISPER_PATH"];
|
|
11726
|
-
if (envPath &&
|
|
11894
|
+
if (envPath && existsSync6(envPath)) {
|
|
11727
11895
|
return { executablePath: envPath, source: "env" };
|
|
11728
11896
|
}
|
|
11729
11897
|
return void 0;
|
|
@@ -11733,9 +11901,9 @@ function findFromSystem() {
|
|
|
11733
11901
|
const path2 = whichBinary(name);
|
|
11734
11902
|
if (path2) return { executablePath: path2, source: "system" };
|
|
11735
11903
|
}
|
|
11736
|
-
if (
|
|
11904
|
+
if (platform4() === "darwin") {
|
|
11737
11905
|
for (const p2 of ["/opt/homebrew/bin/whisper-cli", "/usr/local/bin/whisper-cli"]) {
|
|
11738
|
-
if (
|
|
11906
|
+
if (existsSync6(p2)) return { executablePath: p2, source: "system" };
|
|
11739
11907
|
}
|
|
11740
11908
|
}
|
|
11741
11909
|
return void 0;
|
|
@@ -11745,15 +11913,15 @@ function findBuiltBinary() {
|
|
|
11745
11913
|
join5(BUILD_DIR, "build", "bin", "whisper-cli"),
|
|
11746
11914
|
join5(BUILD_DIR, "build", "whisper-cli")
|
|
11747
11915
|
]) {
|
|
11748
|
-
if (
|
|
11916
|
+
if (existsSync6(p2)) return { executablePath: p2, source: "build" };
|
|
11749
11917
|
}
|
|
11750
11918
|
return void 0;
|
|
11751
11919
|
}
|
|
11752
11920
|
function buildFromSource(onProgress) {
|
|
11753
|
-
if (
|
|
11921
|
+
if (existsSync6(BUILD_DIR) && !findBuiltBinary()) {
|
|
11754
11922
|
rmSync(BUILD_DIR, { recursive: true, force: true });
|
|
11755
11923
|
}
|
|
11756
|
-
if (!
|
|
11924
|
+
if (!existsSync6(BUILD_DIR)) {
|
|
11757
11925
|
onProgress?.("Downloading whisper.cpp...");
|
|
11758
11926
|
mkdirSync3(join5(homedir3(), ".cache", "hyperframes", "whisper"), {
|
|
11759
11927
|
recursive: true
|
|
@@ -11796,7 +11964,7 @@ function findWhisper() {
|
|
|
11796
11964
|
return findFromEnv() ?? findFromSystem() ?? findBuiltBinary();
|
|
11797
11965
|
}
|
|
11798
11966
|
function getInstallInstructions() {
|
|
11799
|
-
if (
|
|
11967
|
+
if (platform4() === "darwin") {
|
|
11800
11968
|
return "brew install whisper-cpp";
|
|
11801
11969
|
}
|
|
11802
11970
|
return "See https://github.com/ggml-org/whisper.cpp#building";
|
|
@@ -11813,7 +11981,7 @@ function hasCmake() {
|
|
|
11813
11981
|
async function ensureWhisper(options) {
|
|
11814
11982
|
const existing = findWhisper();
|
|
11815
11983
|
if (existing) return existing;
|
|
11816
|
-
if (
|
|
11984
|
+
if (platform4() === "darwin" && hasBrew()) {
|
|
11817
11985
|
options?.onProgress?.("Installing whisper-cpp via Homebrew...");
|
|
11818
11986
|
try {
|
|
11819
11987
|
execFileSync("brew", ["install", "whisper-cpp"], {
|
|
@@ -11835,11 +12003,11 @@ async function ensureWhisper(options) {
|
|
|
11835
12003
|
}
|
|
11836
12004
|
async function ensureModel(model = DEFAULT_MODEL, options) {
|
|
11837
12005
|
const modelPath2 = join5(MODELS_DIR, `ggml-${model}.bin`);
|
|
11838
|
-
if (
|
|
12006
|
+
if (existsSync6(modelPath2)) return modelPath2;
|
|
11839
12007
|
mkdirSync3(MODELS_DIR, { recursive: true });
|
|
11840
12008
|
options?.onProgress?.(`Downloading model ${model}...`);
|
|
11841
12009
|
await downloadFile(getModelUrl(model), modelPath2);
|
|
11842
|
-
if (!
|
|
12010
|
+
if (!existsSync6(modelPath2)) {
|
|
11843
12011
|
throw new Error(`Model download failed: ${model}`);
|
|
11844
12012
|
}
|
|
11845
12013
|
return modelPath2;
|
|
@@ -11878,13 +12046,13 @@ __export(normalize_exports, {
|
|
|
11878
12046
|
patchCaptionHtml: () => patchCaptionHtml,
|
|
11879
12047
|
stripBeforeOnset: () => stripBeforeOnset
|
|
11880
12048
|
});
|
|
11881
|
-
import { readFileSync as
|
|
12049
|
+
import { readFileSync as readFileSync7, readdirSync, writeFileSync as writeFileSync4 } from "fs";
|
|
11882
12050
|
import { extname, join as join6 } from "path";
|
|
11883
12051
|
function detectFormat(filePath) {
|
|
11884
12052
|
const ext = extname(filePath).toLowerCase();
|
|
11885
12053
|
if (ext === ".srt") return "srt";
|
|
11886
12054
|
if (ext === ".vtt") return "vtt";
|
|
11887
|
-
if (ext === ".json") return detectJsonFormat(JSON.parse(
|
|
12055
|
+
if (ext === ".json") return detectJsonFormat(JSON.parse(readFileSync7(filePath, "utf-8")));
|
|
11888
12056
|
throw new Error(`Unsupported transcript file extension: ${ext}. Use .json, .srt, or .vtt`);
|
|
11889
12057
|
}
|
|
11890
12058
|
function detectJsonFormat(raw) {
|
|
@@ -12034,7 +12202,7 @@ function round3(n) {
|
|
|
12034
12202
|
}
|
|
12035
12203
|
function loadTranscript(filePath) {
|
|
12036
12204
|
const ext = extname(filePath).toLowerCase();
|
|
12037
|
-
const content =
|
|
12205
|
+
const content = readFileSync7(filePath, "utf-8");
|
|
12038
12206
|
if (ext === ".srt") {
|
|
12039
12207
|
const words2 = parseSrt(content).map((w3, i2) => ({ ...w3, id: w3.id ?? `w${i2}` }));
|
|
12040
12208
|
return { words: words2, format: "srt" };
|
|
@@ -12066,7 +12234,7 @@ function patchCaptionHtml(dir, words) {
|
|
|
12066
12234
|
return;
|
|
12067
12235
|
}
|
|
12068
12236
|
for (const file of htmlFiles) {
|
|
12069
|
-
let content =
|
|
12237
|
+
let content = readFileSync7(file, "utf-8");
|
|
12070
12238
|
const scriptBlocks = content.match(/<script>[\s\S]*?<\/script>/g) ?? [];
|
|
12071
12239
|
let scriptMatch = null;
|
|
12072
12240
|
let transcriptMatch = null;
|
|
@@ -12099,7 +12267,7 @@ __export(projectConfig_exports, {
|
|
|
12099
12267
|
readProjectConfig: () => readProjectConfig,
|
|
12100
12268
|
writeProjectConfig: () => writeProjectConfig
|
|
12101
12269
|
});
|
|
12102
|
-
import { readFileSync as
|
|
12270
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "fs";
|
|
12103
12271
|
import { join as join7, resolve as resolve4 } from "path";
|
|
12104
12272
|
function projectConfigPath(projectDir) {
|
|
12105
12273
|
return join7(resolve4(projectDir), PROJECT_CONFIG_FILENAME);
|
|
@@ -12107,7 +12275,7 @@ function projectConfigPath(projectDir) {
|
|
|
12107
12275
|
function readProjectConfig(projectDir) {
|
|
12108
12276
|
const path2 = projectConfigPath(projectDir);
|
|
12109
12277
|
try {
|
|
12110
|
-
const parsed = JSON.parse(
|
|
12278
|
+
const parsed = JSON.parse(readFileSync8(path2, "utf-8"));
|
|
12111
12279
|
return normalizeConfig(parsed);
|
|
12112
12280
|
} catch {
|
|
12113
12281
|
return void 0;
|
|
@@ -12157,7 +12325,7 @@ __export(transcribe_exports, {
|
|
|
12157
12325
|
transcribe: () => transcribe
|
|
12158
12326
|
});
|
|
12159
12327
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
12160
|
-
import { existsSync as
|
|
12328
|
+
import { existsSync as existsSync7, readFileSync as readFileSync9, mkdirSync as mkdirSync4, unlinkSync as unlinkSync2 } from "fs";
|
|
12161
12329
|
import { join as join8, extname as extname2 } from "path";
|
|
12162
12330
|
import { tmpdir } from "os";
|
|
12163
12331
|
function detectLanguage(whisperPath, modelPath2, wavPath) {
|
|
@@ -12193,7 +12361,7 @@ function detectSpeechOnset(wavPath) {
|
|
|
12193
12361
|
const SILENCE_THRESHOLD_RATIO = 0.6;
|
|
12194
12362
|
const MIN_INTRO_SECONDS = 3;
|
|
12195
12363
|
try {
|
|
12196
|
-
const buf =
|
|
12364
|
+
const buf = readFileSync9(wavPath);
|
|
12197
12365
|
const dataChunk = findWavDataChunk(buf);
|
|
12198
12366
|
if (!dataChunk) return null;
|
|
12199
12367
|
const pcm = new Int16Array(buf.buffer, buf.byteOffset + dataChunk.offset, dataChunk.size / 2);
|
|
@@ -12331,10 +12499,10 @@ async function transcribe(inputPath, outputDir, options) {
|
|
|
12331
12499
|
whisperArgs.push(wavPath);
|
|
12332
12500
|
execFileSync2(whisper.executablePath, whisperArgs, { stdio: "ignore", timeout: 3e5 });
|
|
12333
12501
|
const transcriptPath = `${outputBase}.json`;
|
|
12334
|
-
if (!
|
|
12502
|
+
if (!existsSync7(transcriptPath)) {
|
|
12335
12503
|
throw new Error("Whisper did not produce output. Check the input file.");
|
|
12336
12504
|
}
|
|
12337
|
-
const transcript = JSON.parse(
|
|
12505
|
+
const transcript = JSON.parse(readFileSync9(transcriptPath, "utf-8"));
|
|
12338
12506
|
const segments = transcript.transcription ?? [];
|
|
12339
12507
|
let wordCount = 0;
|
|
12340
12508
|
let maxEnd = 0;
|
|
@@ -12485,7 +12653,7 @@ var init_lint = __esm({
|
|
|
12485
12653
|
});
|
|
12486
12654
|
|
|
12487
12655
|
// src/utils/lintProject.ts
|
|
12488
|
-
import { existsSync as
|
|
12656
|
+
import { existsSync as existsSync8, readFileSync as readFileSync10, readdirSync as readdirSync2 } from "fs";
|
|
12489
12657
|
import { dirname as dirname4, join as join9, resolve as resolve5, extname as extname3 } from "path";
|
|
12490
12658
|
function readHtmlAttr(tag, name) {
|
|
12491
12659
|
const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -12507,8 +12675,8 @@ function collectExternalStyles(projectDir, html, compSrcPath) {
|
|
|
12507
12675
|
if (!isLocalStylesheetHref(href)) continue;
|
|
12508
12676
|
const rootRelative = compSrcPath ? join9(dirname4(compSrcPath), href) : href;
|
|
12509
12677
|
const resolved = resolve5(projectDir, rootRelative);
|
|
12510
|
-
if (!
|
|
12511
|
-
styles.push({ href, content:
|
|
12678
|
+
if (!existsSync8(resolved)) continue;
|
|
12679
|
+
styles.push({ href, content: readFileSync10(resolved, "utf-8") });
|
|
12512
12680
|
}
|
|
12513
12681
|
return styles;
|
|
12514
12682
|
}
|
|
@@ -12529,8 +12697,8 @@ function collectCssSources(projectDir, html, compSrcPath) {
|
|
|
12529
12697
|
if (!isLocalStylesheetHref(href)) continue;
|
|
12530
12698
|
const rootRelativePath = compSrcPath ? join9(dirname4(compSrcPath), href) : href;
|
|
12531
12699
|
const resolved = resolve5(projectDir, rootRelativePath);
|
|
12532
|
-
if (!
|
|
12533
|
-
sources.push({ content:
|
|
12700
|
+
if (!existsSync8(resolved)) continue;
|
|
12701
|
+
sources.push({ content: readFileSync10(resolved, "utf-8"), rootRelativePath });
|
|
12534
12702
|
}
|
|
12535
12703
|
let tagMatch;
|
|
12536
12704
|
const tagPattern = new RegExp(OPEN_TAG_RE.source, OPEN_TAG_RE.flags);
|
|
@@ -12559,7 +12727,7 @@ function lintProject(project) {
|
|
|
12559
12727
|
let totalErrors = 0;
|
|
12560
12728
|
let totalWarnings = 0;
|
|
12561
12729
|
let totalInfos = 0;
|
|
12562
|
-
const rootHtml =
|
|
12730
|
+
const rootHtml = readFileSync10(project.indexPath, "utf-8");
|
|
12563
12731
|
const rootResult = lintHyperframeHtml(rootHtml, {
|
|
12564
12732
|
filePath: project.indexPath,
|
|
12565
12733
|
externalStyles: collectExternalStyles(project.dir, rootHtml)
|
|
@@ -12570,11 +12738,11 @@ function lintProject(project) {
|
|
|
12570
12738
|
totalInfos += rootResult.infoCount;
|
|
12571
12739
|
const allHtmlSources = [{ html: rootHtml }];
|
|
12572
12740
|
const compositionsDir = resolve5(project.dir, "compositions");
|
|
12573
|
-
if (
|
|
12741
|
+
if (existsSync8(compositionsDir)) {
|
|
12574
12742
|
const files = readdirSync2(compositionsDir).filter((f3) => f3.endsWith(".html"));
|
|
12575
12743
|
for (const file of files) {
|
|
12576
12744
|
const filePath = join9(compositionsDir, file);
|
|
12577
|
-
const html =
|
|
12745
|
+
const html = readFileSync10(filePath, "utf-8");
|
|
12578
12746
|
const compSrcPath = `compositions/${file}`;
|
|
12579
12747
|
allHtmlSources.push({ html, compSrcPath });
|
|
12580
12748
|
const result = lintHyperframeHtml(html, {
|
|
@@ -12647,7 +12815,7 @@ function lintAudioSrcNotFound(projectDir, htmlSources) {
|
|
|
12647
12815
|
if (/^__[A-Z_]+__$/.test(src)) continue;
|
|
12648
12816
|
const rootRelative = compSrcPath ? rewriteAssetPath(compSrcPath, src) : src;
|
|
12649
12817
|
const resolved = resolve5(projectDir, rootRelative);
|
|
12650
|
-
if (!
|
|
12818
|
+
if (!existsSync8(resolved)) {
|
|
12651
12819
|
missingSrcs.push(src);
|
|
12652
12820
|
}
|
|
12653
12821
|
}
|
|
@@ -12680,7 +12848,7 @@ function lintTextureMaskAssetNotFound(projectDir, htmlSources) {
|
|
|
12680
12848
|
compSrcPath,
|
|
12681
12849
|
cssSource.rootRelativePath
|
|
12682
12850
|
);
|
|
12683
|
-
if (
|
|
12851
|
+
if (existsSync8(resolved)) continue;
|
|
12684
12852
|
missing.set(url, resolved);
|
|
12685
12853
|
}
|
|
12686
12854
|
}
|
|
@@ -12702,7 +12870,7 @@ function lintMultipleRootCompositions(projectDir) {
|
|
|
12702
12870
|
const rootHtmlFiles = readdirSync2(projectDir).filter((f3) => f3.endsWith(".html"));
|
|
12703
12871
|
const rootCompositions = [];
|
|
12704
12872
|
for (const file of rootHtmlFiles) {
|
|
12705
|
-
const content =
|
|
12873
|
+
const content = readFileSync10(join9(projectDir, file), "utf-8");
|
|
12706
12874
|
if (/data-composition-id/i.test(content)) {
|
|
12707
12875
|
rootCompositions.push(file);
|
|
12708
12876
|
}
|
|
@@ -13125,13 +13293,13 @@ var init_fileWatcher = __esm({
|
|
|
13125
13293
|
});
|
|
13126
13294
|
|
|
13127
13295
|
// src/server/runtimeSource.ts
|
|
13128
|
-
import { existsSync as
|
|
13296
|
+
import { existsSync as existsSync9, readFileSync as readFileSync11 } from "fs";
|
|
13129
13297
|
import { resolve as resolve7, dirname as dirname5 } from "path";
|
|
13130
13298
|
async function loadRuntimeSource() {
|
|
13131
13299
|
return await buildFromSource2() ?? await getInlinedRuntime() ?? readPrebuiltArtifact();
|
|
13132
13300
|
}
|
|
13133
13301
|
async function buildFromSource2() {
|
|
13134
|
-
if (!
|
|
13302
|
+
if (!existsSync9(ENTRY_TS)) return null;
|
|
13135
13303
|
try {
|
|
13136
13304
|
const mod = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
13137
13305
|
if (typeof mod.loadHyperframeRuntimeSource === "function") {
|
|
@@ -13158,7 +13326,7 @@ function readPrebuiltArtifact() {
|
|
|
13158
13326
|
function readFromDir(dir) {
|
|
13159
13327
|
for (const name of ARTIFACT_NAMES) {
|
|
13160
13328
|
const path2 = resolve7(dir, name);
|
|
13161
|
-
if (
|
|
13329
|
+
if (existsSync9(path2)) return readFileSync11(path2, "utf-8");
|
|
13162
13330
|
}
|
|
13163
13331
|
return null;
|
|
13164
13332
|
}
|
|
@@ -13376,7 +13544,7 @@ var init_mime = __esm({
|
|
|
13376
13544
|
|
|
13377
13545
|
// ../core/src/studio-api/helpers/waveform.ts
|
|
13378
13546
|
import { spawn as spawn3 } from "child_process";
|
|
13379
|
-
import { existsSync as
|
|
13547
|
+
import { existsSync as existsSync10, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5 } from "fs";
|
|
13380
13548
|
import { join as join11 } from "path";
|
|
13381
13549
|
function buildWaveformCacheKey(assetPath) {
|
|
13382
13550
|
return `${WAVEFORM_CACHE_VERSION}_${assetPath.replace(/[/\\]/g, "_")}.json`;
|
|
@@ -13438,10 +13606,10 @@ function decodeAudioPeaks(audioPath) {
|
|
|
13438
13606
|
}
|
|
13439
13607
|
async function generateWaveformCache(projectDir, assetPath) {
|
|
13440
13608
|
const audioPath = join11(projectDir, assetPath);
|
|
13441
|
-
if (!
|
|
13609
|
+
if (!existsSync10(audioPath)) return;
|
|
13442
13610
|
const cacheDir = join11(projectDir, ".waveform-cache");
|
|
13443
13611
|
const cachePath2 = join11(cacheDir, buildWaveformCacheKey(assetPath));
|
|
13444
|
-
if (
|
|
13612
|
+
if (existsSync10(cachePath2)) return;
|
|
13445
13613
|
const peaks = await decodeAudioPeaks(audioPath);
|
|
13446
13614
|
mkdirSync5(cacheDir, { recursive: true });
|
|
13447
13615
|
writeFileSync6(cachePath2, JSON.stringify(peaks));
|
|
@@ -26296,8 +26464,8 @@ var init_sourceMutation = __esm({
|
|
|
26296
26464
|
// ../core/src/studio-api/routes/files.ts
|
|
26297
26465
|
import { bodyLimit } from "hono/body-limit";
|
|
26298
26466
|
import {
|
|
26299
|
-
existsSync as
|
|
26300
|
-
readFileSync as
|
|
26467
|
+
existsSync as existsSync11,
|
|
26468
|
+
readFileSync as readFileSync12,
|
|
26301
26469
|
writeFileSync as writeFileSync8,
|
|
26302
26470
|
mkdirSync as mkdirSync6,
|
|
26303
26471
|
unlinkSync as unlinkSync3,
|
|
@@ -26321,14 +26489,14 @@ async function resolveProjectFile(c3, adapter2, opts) {
|
|
|
26321
26489
|
if (!isSafePath(project.dir, absPath)) {
|
|
26322
26490
|
return { error: c3.json({ error: "forbidden" }, 403) };
|
|
26323
26491
|
}
|
|
26324
|
-
if (opts?.mustExist && !
|
|
26492
|
+
if (opts?.mustExist && !existsSync11(absPath)) {
|
|
26325
26493
|
return { error: c3.json({ error: "not found" }, 404) };
|
|
26326
26494
|
}
|
|
26327
26495
|
return { project, filePath, absPath };
|
|
26328
26496
|
}
|
|
26329
26497
|
function ensureDir(filePath) {
|
|
26330
26498
|
const dir = dirname6(filePath);
|
|
26331
|
-
if (!
|
|
26499
|
+
if (!existsSync11(dir)) mkdirSync6(dir, { recursive: true });
|
|
26332
26500
|
}
|
|
26333
26501
|
function generateCopyPath(projectDir, originalPath) {
|
|
26334
26502
|
const ext = originalPath.includes(".") ? "." + originalPath.split(".").pop() : "";
|
|
@@ -26337,7 +26505,7 @@ function generateCopyPath(projectDir, originalPath) {
|
|
|
26337
26505
|
const cleanBase = copyMatch ? base.slice(0, -copyMatch[0].length) : base;
|
|
26338
26506
|
let num = copyMatch ? copyMatch[1] ? parseInt(copyMatch[1]) + 1 : 2 : 1;
|
|
26339
26507
|
let candidate = num === 1 ? `${cleanBase} (copy)${ext}` : `${cleanBase} (copy ${num})${ext}`;
|
|
26340
|
-
while (
|
|
26508
|
+
while (existsSync11(resolve9(projectDir, candidate))) {
|
|
26341
26509
|
num++;
|
|
26342
26510
|
candidate = `${cleanBase} (copy ${num})${ext}`;
|
|
26343
26511
|
}
|
|
@@ -26364,7 +26532,7 @@ function updateReferences(projectDir, oldPath, newPath) {
|
|
|
26364
26532
|
);
|
|
26365
26533
|
let updatedCount = 0;
|
|
26366
26534
|
for (const file of textFiles) {
|
|
26367
|
-
const content =
|
|
26535
|
+
const content = readFileSync12(file, "utf-8");
|
|
26368
26536
|
if (!content.includes(oldPath)) continue;
|
|
26369
26537
|
const updated = content.split(oldPath).join(newPath);
|
|
26370
26538
|
if (updated !== content) {
|
|
@@ -26378,13 +26546,13 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26378
26546
|
api.get("/projects/:id/files/*", async (c3) => {
|
|
26379
26547
|
const res = await resolveProjectFile(c3, adapter2);
|
|
26380
26548
|
if ("error" in res) return res.error;
|
|
26381
|
-
if (!
|
|
26549
|
+
if (!existsSync11(res.absPath)) {
|
|
26382
26550
|
if (c3.req.query("optional") === "1") {
|
|
26383
26551
|
return c3.json({ filename: res.filePath, content: "" });
|
|
26384
26552
|
}
|
|
26385
26553
|
return c3.json({ error: "not found" }, 404);
|
|
26386
26554
|
}
|
|
26387
|
-
const content =
|
|
26555
|
+
const content = readFileSync12(res.absPath, "utf-8");
|
|
26388
26556
|
return c3.json({ filename: res.filePath, content });
|
|
26389
26557
|
});
|
|
26390
26558
|
api.put("/projects/:id/files/*", async (c3) => {
|
|
@@ -26398,7 +26566,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26398
26566
|
api.post("/projects/:id/files/*", async (c3) => {
|
|
26399
26567
|
const res = await resolveProjectFile(c3, adapter2);
|
|
26400
26568
|
if ("error" in res) return res.error;
|
|
26401
|
-
if (
|
|
26569
|
+
if (existsSync11(res.absPath)) {
|
|
26402
26570
|
return c3.json({ error: "already exists" }, 409);
|
|
26403
26571
|
}
|
|
26404
26572
|
ensureDir(res.absPath);
|
|
@@ -26431,14 +26599,14 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26431
26599
|
if (!isSafePath(project.dir, absPath)) {
|
|
26432
26600
|
return c3.json({ error: "forbidden" }, 403);
|
|
26433
26601
|
}
|
|
26434
|
-
if (!
|
|
26602
|
+
if (!existsSync11(absPath)) {
|
|
26435
26603
|
return c3.json({ error: "not found" }, 404);
|
|
26436
26604
|
}
|
|
26437
26605
|
const body = await c3.req.json().catch(() => null);
|
|
26438
26606
|
if (!body?.target) {
|
|
26439
26607
|
return c3.json({ error: "target required" }, 400);
|
|
26440
26608
|
}
|
|
26441
|
-
const originalContent =
|
|
26609
|
+
const originalContent = readFileSync12(absPath, "utf-8");
|
|
26442
26610
|
const patchedContent = removeElementFromHtml2(originalContent, body.target);
|
|
26443
26611
|
if (patchedContent === originalContent) {
|
|
26444
26612
|
return c3.json({ ok: true, changed: false, content: originalContent });
|
|
@@ -26466,7 +26634,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26466
26634
|
}
|
|
26467
26635
|
let originalContent;
|
|
26468
26636
|
try {
|
|
26469
|
-
originalContent =
|
|
26637
|
+
originalContent = readFileSync12(absPath, "utf-8");
|
|
26470
26638
|
} catch {
|
|
26471
26639
|
return c3.json({ error: "not found" }, 404);
|
|
26472
26640
|
}
|
|
@@ -26488,7 +26656,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26488
26656
|
if (!isSafePath(res.project.dir, newAbs)) {
|
|
26489
26657
|
return c3.json({ error: "forbidden" }, 403);
|
|
26490
26658
|
}
|
|
26491
|
-
if (
|
|
26659
|
+
if (existsSync11(newAbs)) {
|
|
26492
26660
|
return c3.json({ error: "already exists" }, 409);
|
|
26493
26661
|
}
|
|
26494
26662
|
ensureDir(newAbs);
|
|
@@ -26504,7 +26672,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26504
26672
|
return c3.json({ error: "path required" }, 400);
|
|
26505
26673
|
}
|
|
26506
26674
|
const srcAbs = resolve9(project.dir, body.path);
|
|
26507
|
-
if (!isSafePath(project.dir, srcAbs) || !
|
|
26675
|
+
if (!isSafePath(project.dir, srcAbs) || !existsSync11(srcAbs)) {
|
|
26508
26676
|
return c3.json({ error: "not found" }, 404);
|
|
26509
26677
|
}
|
|
26510
26678
|
const copyPath = generateCopyPath(project.dir, body.path);
|
|
@@ -26513,7 +26681,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26513
26681
|
return c3.json({ error: "forbidden" }, 403);
|
|
26514
26682
|
}
|
|
26515
26683
|
ensureDir(destAbs);
|
|
26516
|
-
writeFileSync8(destAbs,
|
|
26684
|
+
writeFileSync8(destAbs, readFileSync12(srcAbs));
|
|
26517
26685
|
return c3.json({ ok: true, path: copyPath }, 201);
|
|
26518
26686
|
});
|
|
26519
26687
|
const MAX_UPLOAD_BYTES = 500 * 1024 * 1024;
|
|
@@ -26529,7 +26697,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26529
26697
|
const subDir = c3.req.query("dir") ?? "";
|
|
26530
26698
|
const targetDir = subDir ? resolve9(project.dir, subDir) : project.dir;
|
|
26531
26699
|
if (!isSafePath(project.dir, targetDir)) return c3.json({ error: "forbidden" }, 403);
|
|
26532
|
-
if (subDir && !
|
|
26700
|
+
if (subDir && !existsSync11(targetDir)) mkdirSync6(targetDir, { recursive: true });
|
|
26533
26701
|
const formData = await c3.req.formData();
|
|
26534
26702
|
const uploaded = [];
|
|
26535
26703
|
const skipped = [];
|
|
@@ -26547,12 +26715,12 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26547
26715
|
if (!isSafePath(project.dir, destPath)) continue;
|
|
26548
26716
|
let finalPath = destPath;
|
|
26549
26717
|
let finalName = name;
|
|
26550
|
-
if (
|
|
26718
|
+
if (existsSync11(finalPath)) {
|
|
26551
26719
|
const dotIdx = name.indexOf(".", name.startsWith(".") ? 1 : 0);
|
|
26552
26720
|
const ext = dotIdx > 0 ? name.slice(dotIdx) : "";
|
|
26553
26721
|
const base = dotIdx > 0 ? name.slice(0, dotIdx) : name;
|
|
26554
26722
|
let n = 2;
|
|
26555
|
-
while (n < 1e4 &&
|
|
26723
|
+
while (n < 1e4 && existsSync11(resolve9(targetDir, `${base} (${n})${ext}`))) n++;
|
|
26556
26724
|
if (n >= 1e4) {
|
|
26557
26725
|
skipped.push(name);
|
|
26558
26726
|
continue;
|
|
@@ -26774,7 +26942,7 @@ var init_htmlDocument = __esm({
|
|
|
26774
26942
|
});
|
|
26775
26943
|
|
|
26776
26944
|
// ../core/src/studio-api/helpers/subComposition.ts
|
|
26777
|
-
import { existsSync as
|
|
26945
|
+
import { existsSync as existsSync12, readFileSync as readFileSync13 } from "fs";
|
|
26778
26946
|
import { join as join14 } from "path";
|
|
26779
26947
|
function isFullHtmlDocument(html) {
|
|
26780
26948
|
return /^\s*(?:<!doctype\s|<html[\s>])/i.test(html);
|
|
@@ -26823,8 +26991,8 @@ function extractElementAttrs(el) {
|
|
|
26823
26991
|
}
|
|
26824
26992
|
function buildSubCompositionHtml(projectDir, compPath, runtimeUrl, baseHref) {
|
|
26825
26993
|
const compFile = join14(projectDir, compPath);
|
|
26826
|
-
if (!
|
|
26827
|
-
const rawComp =
|
|
26994
|
+
if (!existsSync12(compFile)) return null;
|
|
26995
|
+
const rawComp = readFileSync13(compFile, "utf-8");
|
|
26828
26996
|
let compHeadContent = "";
|
|
26829
26997
|
let rewrittenContent;
|
|
26830
26998
|
let htmlAttrs = "";
|
|
@@ -26852,8 +27020,8 @@ function buildSubCompositionHtml(projectDir, compPath, runtimeUrl, baseHref) {
|
|
|
26852
27020
|
}
|
|
26853
27021
|
const indexPath = join14(projectDir, "index.html");
|
|
26854
27022
|
let headContent = "";
|
|
26855
|
-
if (
|
|
26856
|
-
const indexHtml =
|
|
27023
|
+
if (existsSync12(indexPath)) {
|
|
27024
|
+
const indexHtml = readFileSync13(indexPath, "utf-8");
|
|
26857
27025
|
const headMatch = indexHtml.match(/<head[^>]*>([\s\S]*?)<\/head>/i);
|
|
26858
27026
|
headContent = headMatch?.[1] ?? "";
|
|
26859
27027
|
}
|
|
@@ -26894,7 +27062,7 @@ var init_subComposition = __esm({
|
|
|
26894
27062
|
|
|
26895
27063
|
// ../core/src/studio-api/helpers/projectSignature.ts
|
|
26896
27064
|
import { createHash } from "crypto";
|
|
26897
|
-
import { lstatSync, readFileSync as
|
|
27065
|
+
import { lstatSync, readFileSync as readFileSync14, readdirSync as readdirSync5 } from "fs";
|
|
26898
27066
|
import { extname as extname4, isAbsolute as isAbsolute2, relative as relative2, resolve as resolve10 } from "path";
|
|
26899
27067
|
function isPathWithin(parentDir, childPath) {
|
|
26900
27068
|
const childRelativePath = relative2(parentDir, childPath);
|
|
@@ -26986,7 +27154,7 @@ function createProjectSignature(projectDir) {
|
|
|
26986
27154
|
hash2.update("\0");
|
|
26987
27155
|
if (entry.textContentEligible) {
|
|
26988
27156
|
try {
|
|
26989
|
-
hash2.update(
|
|
27157
|
+
hash2.update(readFileSync14(entry.file));
|
|
26990
27158
|
} catch {
|
|
26991
27159
|
hash2.update(String(entry.mtimeMs));
|
|
26992
27160
|
}
|
|
@@ -27231,7 +27399,7 @@ var init_studioMotionRenderScript = __esm({
|
|
|
27231
27399
|
});
|
|
27232
27400
|
|
|
27233
27401
|
// ../core/src/studio-api/routes/preview.ts
|
|
27234
|
-
import { existsSync as
|
|
27402
|
+
import { existsSync as existsSync13, readFileSync as readFileSync15, statSync as statSync2 } from "fs";
|
|
27235
27403
|
import { join as join15, resolve as resolve11 } from "path";
|
|
27236
27404
|
function resolveProjectSignature(adapter2, projectDir) {
|
|
27237
27405
|
return adapter2.getProjectSignature?.(projectDir) ?? createProjectSignature(projectDir);
|
|
@@ -27251,9 +27419,9 @@ ${html}`;
|
|
|
27251
27419
|
}
|
|
27252
27420
|
function readStudioMotionManifestContent(projectDir) {
|
|
27253
27421
|
const manifestPath = join15(projectDir, STUDIO_MOTION_PATH);
|
|
27254
|
-
if (!
|
|
27422
|
+
if (!existsSync13(manifestPath)) return "";
|
|
27255
27423
|
try {
|
|
27256
|
-
return
|
|
27424
|
+
return readFileSync15(manifestPath, "utf-8");
|
|
27257
27425
|
} catch {
|
|
27258
27426
|
return "";
|
|
27259
27427
|
}
|
|
@@ -27334,12 +27502,12 @@ async function transformPreviewHtml(html, adapter2, project, activeCompositionPa
|
|
|
27334
27502
|
}
|
|
27335
27503
|
function resolveProjectMainHtml(projectDir, projectId) {
|
|
27336
27504
|
const indexPath = join15(projectDir, "index.html");
|
|
27337
|
-
if (
|
|
27338
|
-
return { html:
|
|
27505
|
+
if (existsSync13(indexPath)) {
|
|
27506
|
+
return { html: readFileSync15(indexPath, "utf-8"), compositionPath: "index.html" };
|
|
27339
27507
|
}
|
|
27340
27508
|
const blockHtmlPath = join15(projectDir, `${projectId}.html`);
|
|
27341
|
-
if (
|
|
27342
|
-
return { html:
|
|
27509
|
+
if (existsSync13(blockHtmlPath)) {
|
|
27510
|
+
return { html: readFileSync15(blockHtmlPath, "utf-8"), compositionPath: `${projectId}.html` };
|
|
27343
27511
|
}
|
|
27344
27512
|
return null;
|
|
27345
27513
|
}
|
|
@@ -27408,7 +27576,7 @@ ${runtimeTag}`;
|
|
|
27408
27576
|
c3.req.path.replace(`/projects/${project.id}/preview/comp/`, "").split("?")[0] ?? ""
|
|
27409
27577
|
);
|
|
27410
27578
|
const compFile = resolve11(project.dir, compPath);
|
|
27411
|
-
if (!isSafePath(project.dir, compFile) || !
|
|
27579
|
+
if (!isSafePath(project.dir, compFile) || !existsSync13(compFile) || !statSync2(compFile).isFile()) {
|
|
27412
27580
|
return c3.text("not found", 404);
|
|
27413
27581
|
}
|
|
27414
27582
|
const etag = `"comp:${compPath}:${signature}"`;
|
|
@@ -27433,7 +27601,7 @@ ${runtimeTag}`;
|
|
|
27433
27601
|
c3.req.path.replace(`/projects/${project.id}/preview/`, "").split("?")[0] ?? ""
|
|
27434
27602
|
);
|
|
27435
27603
|
const file = resolve11(project.dir, subPath);
|
|
27436
|
-
const stat3 =
|
|
27604
|
+
const stat3 = existsSync13(file) ? statSync2(file) : null;
|
|
27437
27605
|
if (!isSafePath(project.dir, file) || !stat3?.isFile()) {
|
|
27438
27606
|
return c3.text("not found", 404);
|
|
27439
27607
|
}
|
|
@@ -27447,7 +27615,7 @@ ${runtimeTag}`;
|
|
|
27447
27615
|
return new Response(null, { status: 304, headers: cacheHeaders });
|
|
27448
27616
|
}
|
|
27449
27617
|
}
|
|
27450
|
-
const buffer = isText2 ? Buffer.from(
|
|
27618
|
+
const buffer = isText2 ? Buffer.from(readFileSync15(file, "utf-8"), "utf-8") : readFileSync15(file);
|
|
27451
27619
|
const totalSize2 = buffer.length;
|
|
27452
27620
|
const rangeHeader = c3.req.header("Range");
|
|
27453
27621
|
if (rangeHeader) {
|
|
@@ -27517,7 +27685,7 @@ var init_preview = __esm({
|
|
|
27517
27685
|
});
|
|
27518
27686
|
|
|
27519
27687
|
// ../core/src/studio-api/routes/lint.ts
|
|
27520
|
-
import { readFileSync as
|
|
27688
|
+
import { readFileSync as readFileSync16 } from "fs";
|
|
27521
27689
|
import { join as join16 } from "path";
|
|
27522
27690
|
function registerLintRoutes(api, adapter2) {
|
|
27523
27691
|
api.get("/projects/:id/lint", async (c3) => {
|
|
@@ -27527,7 +27695,7 @@ function registerLintRoutes(api, adapter2) {
|
|
|
27527
27695
|
const htmlFiles = walkDir(project.dir).filter((f3) => f3.endsWith(".html"));
|
|
27528
27696
|
const allFindings = [];
|
|
27529
27697
|
for (const file of htmlFiles) {
|
|
27530
|
-
const content =
|
|
27698
|
+
const content = readFileSync16(join16(project.dir, file), "utf-8");
|
|
27531
27699
|
const result = await adapter2.lint(content, { filePath: file });
|
|
27532
27700
|
if (result?.findings) {
|
|
27533
27701
|
for (const f3 of result.findings) {
|
|
@@ -27551,7 +27719,7 @@ var init_lint2 = __esm({
|
|
|
27551
27719
|
|
|
27552
27720
|
// ../core/src/studio-api/routes/render.ts
|
|
27553
27721
|
import { streamSSE } from "hono/streaming";
|
|
27554
|
-
import { existsSync as
|
|
27722
|
+
import { existsSync as existsSync14, readFileSync as readFileSync17, mkdirSync as mkdirSync7, unlinkSync as unlinkSync4, readdirSync as readdirSync6, statSync as statSync3 } from "fs";
|
|
27555
27723
|
import { join as join17, resolve as resolve12, sep as sep2 } from "path";
|
|
27556
27724
|
function registerRenderRoutes(api, adapter2) {
|
|
27557
27725
|
const renderJobs = /* @__PURE__ */ new Map();
|
|
@@ -27603,7 +27771,7 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
27603
27771
|
const timePart = now.toTimeString().slice(0, 8).replace(/:/g, "-");
|
|
27604
27772
|
const jobId = `${project.id}_${datePart}_${timePart}`;
|
|
27605
27773
|
const rendersDir = adapter2.rendersDir(project);
|
|
27606
|
-
if (!
|
|
27774
|
+
if (!existsSync14(rendersDir)) mkdirSync7(rendersDir, { recursive: true });
|
|
27607
27775
|
const ext = FORMAT_EXT2[format] ?? ".mp4";
|
|
27608
27776
|
const outputPath = join17(rendersDir, `${jobId}${ext}`);
|
|
27609
27777
|
const jobState = adapter2.startRender({
|
|
@@ -27656,12 +27824,12 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
27656
27824
|
api.get("/render/:jobId/view", (c3) => {
|
|
27657
27825
|
const { jobId } = c3.req.param();
|
|
27658
27826
|
const job = renderJobs.get(jobId);
|
|
27659
|
-
if (!job?.outputPath || !
|
|
27827
|
+
if (!job?.outputPath || !existsSync14(job.outputPath)) {
|
|
27660
27828
|
return c3.json({ error: "not found" }, 404);
|
|
27661
27829
|
}
|
|
27662
27830
|
const contentType = renderContentType(job.outputPath);
|
|
27663
27831
|
const filename = job.outputPath.split("/").pop() ?? `render.mp4`;
|
|
27664
|
-
const content =
|
|
27832
|
+
const content = readFileSync17(job.outputPath);
|
|
27665
27833
|
return new Response(content, {
|
|
27666
27834
|
headers: {
|
|
27667
27835
|
"Content-Type": contentType,
|
|
@@ -27674,12 +27842,12 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
27674
27842
|
api.get("/render/:jobId/download", (c3) => {
|
|
27675
27843
|
const { jobId } = c3.req.param();
|
|
27676
27844
|
const job = renderJobs.get(jobId);
|
|
27677
|
-
if (!job?.outputPath || !
|
|
27845
|
+
if (!job?.outputPath || !existsSync14(job.outputPath)) {
|
|
27678
27846
|
return c3.json({ error: "not found" }, 404);
|
|
27679
27847
|
}
|
|
27680
27848
|
const contentType = renderContentType(job.outputPath);
|
|
27681
27849
|
const filename = job.outputPath.split("/").pop() ?? `render.mp4`;
|
|
27682
|
-
const content =
|
|
27850
|
+
const content = readFileSync17(job.outputPath);
|
|
27683
27851
|
return new Response(content, {
|
|
27684
27852
|
headers: {
|
|
27685
27853
|
"Content-Type": contentType,
|
|
@@ -27694,7 +27862,7 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
27694
27862
|
const dir = state.outputPath.replace(/\/[^/]+$/, "");
|
|
27695
27863
|
for (const ext of [".mp4", ".webm", ".mov", ".meta.json"]) {
|
|
27696
27864
|
const fp = join17(dir, `${jobId}${ext}`);
|
|
27697
|
-
if (
|
|
27865
|
+
if (existsSync14(fp)) unlinkSync4(fp);
|
|
27698
27866
|
}
|
|
27699
27867
|
break;
|
|
27700
27868
|
}
|
|
@@ -27709,9 +27877,9 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
27709
27877
|
if (!filename) return c3.json({ error: "missing filename" }, 400);
|
|
27710
27878
|
const rendersDir = adapter2.rendersDir(project);
|
|
27711
27879
|
const fp = join17(rendersDir, filename);
|
|
27712
|
-
if (!
|
|
27880
|
+
if (!existsSync14(fp)) return c3.json({ error: "not found" }, 404);
|
|
27713
27881
|
const contentType = renderContentType(fp);
|
|
27714
|
-
const content =
|
|
27882
|
+
const content = readFileSync17(fp);
|
|
27715
27883
|
return new Response(content, {
|
|
27716
27884
|
headers: {
|
|
27717
27885
|
"Content-Type": contentType,
|
|
@@ -27725,7 +27893,7 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
27725
27893
|
const project = await adapter2.resolveProject(c3.req.param("id"));
|
|
27726
27894
|
if (!project) return c3.json({ error: "not found" }, 404);
|
|
27727
27895
|
const rendersDir = adapter2.rendersDir(project);
|
|
27728
|
-
if (!
|
|
27896
|
+
if (!existsSync14(rendersDir)) return c3.json({ renders: [] });
|
|
27729
27897
|
const files = readdirSync6(rendersDir).filter((f3) => f3.endsWith(".mp4") || f3.endsWith(".webm") || f3.endsWith(".mov")).map((f3) => {
|
|
27730
27898
|
const fp = join17(rendersDir, f3);
|
|
27731
27899
|
const stat3 = statSync3(fp);
|
|
@@ -27733,9 +27901,9 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
27733
27901
|
const metaPath = join17(rendersDir, `${rid}.meta.json`);
|
|
27734
27902
|
let status = "complete";
|
|
27735
27903
|
let durationMs;
|
|
27736
|
-
if (
|
|
27904
|
+
if (existsSync14(metaPath)) {
|
|
27737
27905
|
try {
|
|
27738
|
-
const meta = JSON.parse(
|
|
27906
|
+
const meta = JSON.parse(readFileSync17(metaPath, "utf-8"));
|
|
27739
27907
|
if (meta.status === "failed") status = "failed";
|
|
27740
27908
|
if (meta.durationMs) durationMs = meta.durationMs;
|
|
27741
27909
|
} catch {
|
|
@@ -28358,7 +28526,7 @@ var init_manualEditsRenderScript = __esm({
|
|
|
28358
28526
|
});
|
|
28359
28527
|
|
|
28360
28528
|
// ../core/src/studio-api/routes/thumbnail.ts
|
|
28361
|
-
import { existsSync as
|
|
28529
|
+
import { existsSync as existsSync15, readFileSync as readFileSync18, writeFileSync as writeFileSync9, mkdirSync as mkdirSync8, statSync as statSync4 } from "fs";
|
|
28362
28530
|
import { join as join18 } from "path";
|
|
28363
28531
|
import { createHash as createHash2 } from "crypto";
|
|
28364
28532
|
function registerThumbnailRoutes(api, adapter2) {
|
|
@@ -28389,9 +28557,9 @@ function registerThumbnailRoutes(api, adapter2) {
|
|
|
28389
28557
|
let sourceMtime = 0;
|
|
28390
28558
|
if (!vpWidth) {
|
|
28391
28559
|
const htmlFile = join18(project.dir, compPath);
|
|
28392
|
-
if (
|
|
28560
|
+
if (existsSync15(htmlFile)) {
|
|
28393
28561
|
sourceMtime = Math.round(statSync4(htmlFile).mtimeMs);
|
|
28394
|
-
const html =
|
|
28562
|
+
const html = readFileSync18(htmlFile, "utf-8");
|
|
28395
28563
|
const wMatch = html.match(/data-width=["'](\d+)["']/);
|
|
28396
28564
|
const hMatch = html.match(/data-height=["'](\d+)["']/);
|
|
28397
28565
|
if (wMatch?.[1]) compW = parseInt(wMatch[1]);
|
|
@@ -28400,15 +28568,15 @@ function registerThumbnailRoutes(api, adapter2) {
|
|
|
28400
28568
|
}
|
|
28401
28569
|
const manualEditsFile = join18(project.dir, STUDIO_MANUAL_EDITS_PATH);
|
|
28402
28570
|
let manualEditsKey = "";
|
|
28403
|
-
if (
|
|
28404
|
-
const manualEditsContent =
|
|
28571
|
+
if (existsSync15(manualEditsFile)) {
|
|
28572
|
+
const manualEditsContent = readFileSync18(manualEditsFile, "utf-8");
|
|
28405
28573
|
manualEditsKey = `_${createHash2("sha1").update(manualEditsContent).digest("hex").slice(0, 16)}`;
|
|
28406
28574
|
sourceMtime = Math.max(sourceMtime, Math.round(statSync4(manualEditsFile).mtimeMs));
|
|
28407
28575
|
}
|
|
28408
28576
|
const motionFile = join18(project.dir, STUDIO_MOTION_PATH);
|
|
28409
28577
|
let motionKey = "";
|
|
28410
|
-
if (
|
|
28411
|
-
const motionContent =
|
|
28578
|
+
if (existsSync15(motionFile)) {
|
|
28579
|
+
const motionContent = readFileSync18(motionFile, "utf-8");
|
|
28412
28580
|
motionKey = `_${createHash2("sha1").update(motionContent).digest("hex").slice(0, 16)}`;
|
|
28413
28581
|
sourceMtime = Math.max(sourceMtime, Math.round(statSync4(motionFile).mtimeMs));
|
|
28414
28582
|
}
|
|
@@ -28418,8 +28586,8 @@ function registerThumbnailRoutes(api, adapter2) {
|
|
|
28418
28586
|
const urlVersionKey = urlVersion ? `_${urlVersion.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 32)}` : "";
|
|
28419
28587
|
const cacheKey = `${THUMBNAIL_CACHE_VERSION}${urlVersionKey}${manualEditsKey}${motionKey}_${format}_${compPath.replace(/\//g, "_")}_${compW}x${compH}_${sourceMtime}_${seekTime.toFixed(2)}${selectorKey}.${format === "png" ? "png" : "jpg"}`;
|
|
28420
28588
|
const cachePath2 = join18(cacheDir, cacheKey);
|
|
28421
|
-
if (
|
|
28422
|
-
return new Response(new Uint8Array(
|
|
28589
|
+
if (existsSync15(cachePath2)) {
|
|
28590
|
+
return new Response(new Uint8Array(readFileSync18(cachePath2)), {
|
|
28423
28591
|
headers: { "Content-Type": contentType, "Cache-Control": "public, max-age=60" }
|
|
28424
28592
|
});
|
|
28425
28593
|
}
|
|
@@ -28441,7 +28609,7 @@ function registerThumbnailRoutes(api, adapter2) {
|
|
|
28441
28609
|
500
|
|
28442
28610
|
);
|
|
28443
28611
|
}
|
|
28444
|
-
if (!
|
|
28612
|
+
if (!existsSync15(cacheDir)) mkdirSync8(cacheDir, { recursive: true });
|
|
28445
28613
|
writeFileSync9(cachePath2, buffer);
|
|
28446
28614
|
return new Response(new Uint8Array(buffer), {
|
|
28447
28615
|
headers: { "Content-Type": contentType, "Cache-Control": "public, max-age=60" }
|
|
@@ -28463,7 +28631,7 @@ var init_thumbnail = __esm({
|
|
|
28463
28631
|
});
|
|
28464
28632
|
|
|
28465
28633
|
// ../core/src/studio-api/routes/waveform.ts
|
|
28466
|
-
import { existsSync as
|
|
28634
|
+
import { existsSync as existsSync16, readFileSync as readFileSync19, writeFileSync as writeFileSync10, mkdirSync as mkdirSync9 } from "fs";
|
|
28467
28635
|
import { join as join19 } from "path";
|
|
28468
28636
|
function registerWaveformRoutes(api, adapter2) {
|
|
28469
28637
|
api.get("/projects/:id/waveform/*", async (c3) => {
|
|
@@ -28473,12 +28641,12 @@ function registerWaveformRoutes(api, adapter2) {
|
|
|
28473
28641
|
c3.req.path.replace(`/projects/${project.id}/waveform/`, "").split("?")[0] ?? ""
|
|
28474
28642
|
);
|
|
28475
28643
|
const audioPath = join19(project.dir, assetPath);
|
|
28476
|
-
if (!
|
|
28644
|
+
if (!existsSync16(audioPath)) return c3.json({ error: "file not found" }, 404);
|
|
28477
28645
|
const cacheDir = join19(project.dir, ".waveform-cache");
|
|
28478
28646
|
const cachePath2 = join19(cacheDir, buildWaveformCacheKey(assetPath));
|
|
28479
|
-
if (
|
|
28647
|
+
if (existsSync16(cachePath2)) {
|
|
28480
28648
|
try {
|
|
28481
|
-
const peaks2 = JSON.parse(
|
|
28649
|
+
const peaks2 = JSON.parse(readFileSync19(cachePath2, "utf-8"));
|
|
28482
28650
|
return c3.json({ peaks: peaks2 });
|
|
28483
28651
|
} catch {
|
|
28484
28652
|
}
|
|
@@ -28506,15 +28674,15 @@ var init_waveform2 = __esm({
|
|
|
28506
28674
|
|
|
28507
28675
|
// ../core/src/studio-api/routes/fonts.ts
|
|
28508
28676
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
28509
|
-
import { existsSync as
|
|
28510
|
-
import { homedir as homedir4, platform as
|
|
28677
|
+
import { existsSync as existsSync17, readdirSync as readdirSync7, statSync as statSync5 } from "fs";
|
|
28678
|
+
import { homedir as homedir4, platform as platform5 } from "os";
|
|
28511
28679
|
import { join as join20 } from "path";
|
|
28512
28680
|
function isRecord(value) {
|
|
28513
28681
|
return typeof value === "object" && value !== null;
|
|
28514
28682
|
}
|
|
28515
28683
|
function fontDirectories() {
|
|
28516
28684
|
const home = homedir4();
|
|
28517
|
-
if (
|
|
28685
|
+
if (platform5() === "darwin") {
|
|
28518
28686
|
return [
|
|
28519
28687
|
join20(home, "Library", "Fonts"),
|
|
28520
28688
|
"/Library/Fonts",
|
|
@@ -28522,7 +28690,7 @@ function fontDirectories() {
|
|
|
28522
28690
|
"/System/Library/Fonts/Supplemental"
|
|
28523
28691
|
];
|
|
28524
28692
|
}
|
|
28525
|
-
if (
|
|
28693
|
+
if (platform5() === "win32") {
|
|
28526
28694
|
return [join20(process.env.WINDIR || "C:\\Windows", "Fonts")];
|
|
28527
28695
|
}
|
|
28528
28696
|
return [
|
|
@@ -28544,7 +28712,7 @@ function toFamilyName(fileName) {
|
|
|
28544
28712
|
return family.length >= 2 ? family : null;
|
|
28545
28713
|
}
|
|
28546
28714
|
function collectMacSystemProfilerFonts() {
|
|
28547
|
-
if (
|
|
28715
|
+
if (platform5() !== "darwin") return [];
|
|
28548
28716
|
let parsed;
|
|
28549
28717
|
try {
|
|
28550
28718
|
const raw = execFileSync4("system_profiler", ["SPFontsDataType", "-json"], {
|
|
@@ -28579,7 +28747,7 @@ function collectMacSystemProfilerFonts() {
|
|
|
28579
28747
|
return fonts;
|
|
28580
28748
|
}
|
|
28581
28749
|
function collectFontsFromDir(dir, depth = 0) {
|
|
28582
|
-
if (!
|
|
28750
|
+
if (!existsSync17(dir) || depth > 2) return [];
|
|
28583
28751
|
const fonts = [];
|
|
28584
28752
|
for (const entry of readdirSync7(dir, { withFileTypes: true })) {
|
|
28585
28753
|
const fullPath = join20(dir, entry.name);
|
|
@@ -28851,7 +29019,7 @@ __export(manager_exports2, {
|
|
|
28851
29019
|
isLinuxArm: () => isLinuxArm
|
|
28852
29020
|
});
|
|
28853
29021
|
import { execSync, spawnSync as spawnSync2 } from "child_process";
|
|
28854
|
-
import { existsSync as
|
|
29022
|
+
import { existsSync as existsSync18, readdirSync as readdirSync8, rmSync as rmSync4 } from "fs";
|
|
28855
29023
|
import { basename as basename2 } from "path";
|
|
28856
29024
|
import { homedir as homedir5 } from "os";
|
|
28857
29025
|
import { join as join21 } from "path";
|
|
@@ -28872,7 +29040,7 @@ function whichBinary2(name) {
|
|
|
28872
29040
|
}
|
|
28873
29041
|
function findFromEnv2() {
|
|
28874
29042
|
const envPath = process.env["HYPERFRAMES_BROWSER_PATH"];
|
|
28875
|
-
if (envPath &&
|
|
29043
|
+
if (envPath && existsSync18(envPath)) {
|
|
28876
29044
|
return { executablePath: envPath, source: "env" };
|
|
28877
29045
|
}
|
|
28878
29046
|
return void 0;
|
|
@@ -28882,7 +29050,7 @@ async function findFromCache() {
|
|
|
28882
29050
|
if (fromPuppeteer) {
|
|
28883
29051
|
return fromPuppeteer;
|
|
28884
29052
|
}
|
|
28885
|
-
if (
|
|
29053
|
+
if (existsSync18(CACHE_DIR2)) {
|
|
28886
29054
|
const installed = await getInstalledBrowsers({ cacheDir: CACHE_DIR2 });
|
|
28887
29055
|
const match = installed.find((b2) => b2.browser === Browser.CHROMEHEADLESSSHELL);
|
|
28888
29056
|
if (match) {
|
|
@@ -28920,7 +29088,7 @@ function compareVersionDirsDescending(a, b2) {
|
|
|
28920
29088
|
return 0;
|
|
28921
29089
|
}
|
|
28922
29090
|
function findFromPuppeteerCache() {
|
|
28923
|
-
if (!
|
|
29091
|
+
if (!existsSync18(PUPPETEER_CACHE_DIR)) return void 0;
|
|
28924
29092
|
let versions;
|
|
28925
29093
|
try {
|
|
28926
29094
|
versions = [...readdirSync8(PUPPETEER_CACHE_DIR)].sort(compareVersionDirsDescending);
|
|
@@ -28945,7 +29113,7 @@ function findFromPuppeteerCache() {
|
|
|
28945
29113
|
)
|
|
28946
29114
|
];
|
|
28947
29115
|
for (const binary of candidates) {
|
|
28948
|
-
if (
|
|
29116
|
+
if (existsSync18(binary)) {
|
|
28949
29117
|
return { executablePath: binary, source: "cache" };
|
|
28950
29118
|
}
|
|
28951
29119
|
}
|
|
@@ -28972,7 +29140,7 @@ function _resetSystemFallbackWarnForTests() {
|
|
|
28972
29140
|
}
|
|
28973
29141
|
function findFromSystem2() {
|
|
28974
29142
|
for (const p2 of SYSTEM_CHROME_PATHS) {
|
|
28975
|
-
if (
|
|
29143
|
+
if (existsSync18(p2)) {
|
|
28976
29144
|
return { executablePath: p2, source: "system" };
|
|
28977
29145
|
}
|
|
28978
29146
|
}
|
|
@@ -28997,7 +29165,7 @@ async function ensureLinuxArmBrowser(options) {
|
|
|
28997
29165
|
void options;
|
|
28998
29166
|
const existing = await findBrowser();
|
|
28999
29167
|
if (existing) return existing;
|
|
29000
|
-
const hasApt =
|
|
29168
|
+
const hasApt = existsSync18("/usr/bin/apt-get");
|
|
29001
29169
|
if (hasApt) {
|
|
29002
29170
|
console.error(
|
|
29003
29171
|
"\n\u{1F50D} Linux ARM64 detected \u2014 Chrome Headless Shell is not available for this platform."
|
|
@@ -29035,8 +29203,8 @@ Then re-run your command. The HYPERFRAMES_BROWSER_PATH env var persists for the
|
|
|
29035
29203
|
async function ensureBrowser(options) {
|
|
29036
29204
|
const existing = await findBrowser();
|
|
29037
29205
|
if (existing) return existing;
|
|
29038
|
-
const
|
|
29039
|
-
if (!
|
|
29206
|
+
const platform9 = detectBrowserPlatform();
|
|
29207
|
+
if (!platform9) {
|
|
29040
29208
|
throw new Error(`Unsupported platform: ${process.platform} ${process.arch}`);
|
|
29041
29209
|
}
|
|
29042
29210
|
if (isLinuxArm()) {
|
|
@@ -29046,13 +29214,13 @@ async function ensureBrowser(options) {
|
|
|
29046
29214
|
cacheDir: CACHE_DIR2,
|
|
29047
29215
|
browser: Browser.CHROMEHEADLESSSHELL,
|
|
29048
29216
|
buildId: CHROME_VERSION,
|
|
29049
|
-
platform:
|
|
29217
|
+
platform: platform9,
|
|
29050
29218
|
downloadProgressCallback: options?.onProgress
|
|
29051
29219
|
});
|
|
29052
29220
|
return { executablePath: installed.executablePath, source: "download" };
|
|
29053
29221
|
}
|
|
29054
29222
|
function clearBrowser() {
|
|
29055
|
-
if (!
|
|
29223
|
+
if (!existsSync18(CACHE_DIR2)) {
|
|
29056
29224
|
return false;
|
|
29057
29225
|
}
|
|
29058
29226
|
rmSync4(CACHE_DIR2, { recursive: true, force: true });
|
|
@@ -29223,7 +29391,7 @@ var init_config2 = __esm({
|
|
|
29223
29391
|
});
|
|
29224
29392
|
|
|
29225
29393
|
// ../engine/src/services/browserManager.ts
|
|
29226
|
-
import { existsSync as
|
|
29394
|
+
import { existsSync as existsSync19, readdirSync as readdirSync9 } from "fs";
|
|
29227
29395
|
import { join as join22 } from "path";
|
|
29228
29396
|
import { homedir as homedir6 } from "os";
|
|
29229
29397
|
async function getPuppeteer() {
|
|
@@ -29246,7 +29414,7 @@ function resolveHeadlessShellPath(config) {
|
|
|
29246
29414
|
return process.env.PRODUCER_HEADLESS_SHELL_PATH;
|
|
29247
29415
|
}
|
|
29248
29416
|
const baseDir = join22(homedir6(), ".cache", "puppeteer", "chrome-headless-shell");
|
|
29249
|
-
if (!
|
|
29417
|
+
if (!existsSync19(baseDir)) return void 0;
|
|
29250
29418
|
try {
|
|
29251
29419
|
const versions = readdirSync9(baseDir).sort().reverse();
|
|
29252
29420
|
for (const version of versions) {
|
|
@@ -29257,7 +29425,7 @@ function resolveHeadlessShellPath(config) {
|
|
|
29257
29425
|
join22(baseDir, version, "chrome-headless-shell-win64", "chrome-headless-shell.exe")
|
|
29258
29426
|
];
|
|
29259
29427
|
for (const binary of candidates) {
|
|
29260
|
-
if (
|
|
29428
|
+
if (existsSync19(binary)) return binary;
|
|
29261
29429
|
}
|
|
29262
29430
|
}
|
|
29263
29431
|
} catch {
|
|
@@ -29296,7 +29464,7 @@ function resolveBrowserGpuMode(mode, options = {}) {
|
|
|
29296
29464
|
if (mode !== "auto") return Promise.resolve(mode);
|
|
29297
29465
|
if (_autoBrowserGpuModeCache) return _autoBrowserGpuModeCache;
|
|
29298
29466
|
_autoBrowserGpuModeCache = (async () => {
|
|
29299
|
-
const
|
|
29467
|
+
const platform9 = options.platform ?? process.platform;
|
|
29300
29468
|
const browserTimeout = options.browserTimeout ?? DEFAULT_CONFIG2.browserTimeout;
|
|
29301
29469
|
const executablePath = options.chromePath ?? resolveHeadlessShellPath({});
|
|
29302
29470
|
const probeArgs = [
|
|
@@ -29305,7 +29473,7 @@ function resolveBrowserGpuMode(mode, options = {}) {
|
|
|
29305
29473
|
"--disable-dev-shm-usage",
|
|
29306
29474
|
"--enable-webgl",
|
|
29307
29475
|
"--ignore-gpu-blocklist",
|
|
29308
|
-
...getBrowserGpuArgs("hardware",
|
|
29476
|
+
...getBrowserGpuArgs("hardware", platform9)
|
|
29309
29477
|
];
|
|
29310
29478
|
const ppt = await getPuppeteer().catch(() => null);
|
|
29311
29479
|
if (!ppt) {
|
|
@@ -29498,7 +29666,7 @@ async function drainBrowserPool() {
|
|
|
29498
29666
|
}
|
|
29499
29667
|
}
|
|
29500
29668
|
function buildChromeArgs(options, config) {
|
|
29501
|
-
const
|
|
29669
|
+
const platform9 = options.platform ?? process.platform;
|
|
29502
29670
|
const gpuDisabled = config?.disableGpu ?? DEFAULT_CONFIG2.disableGpu;
|
|
29503
29671
|
const browserGpuMode = gpuDisabled ? "software" : config?.browserGpuMode ?? DEFAULT_CONFIG2.browserGpuMode;
|
|
29504
29672
|
const chromeArgs = [
|
|
@@ -29508,7 +29676,7 @@ function buildChromeArgs(options, config) {
|
|
|
29508
29676
|
CANVAS_DRAW_ELEMENT_FEATURE_FLAG,
|
|
29509
29677
|
"--enable-webgl",
|
|
29510
29678
|
"--ignore-gpu-blocklist",
|
|
29511
|
-
...getBrowserGpuArgs(browserGpuMode,
|
|
29679
|
+
...getBrowserGpuArgs(browserGpuMode, platform9),
|
|
29512
29680
|
"--font-render-hinting=none",
|
|
29513
29681
|
"--force-color-profile=srgb",
|
|
29514
29682
|
`--window-size=${options.width},${options.height}`,
|
|
@@ -29556,14 +29724,14 @@ function buildChromeArgs(options, config) {
|
|
|
29556
29724
|
}
|
|
29557
29725
|
return chromeArgs;
|
|
29558
29726
|
}
|
|
29559
|
-
function getBrowserGpuArgs(mode,
|
|
29727
|
+
function getBrowserGpuArgs(mode, platform9) {
|
|
29560
29728
|
if (mode === "software") {
|
|
29561
29729
|
return ["--use-gl=angle", "--use-angle=swiftshader", "--enable-unsafe-swiftshader"];
|
|
29562
29730
|
}
|
|
29563
29731
|
if (mode === "auto") {
|
|
29564
29732
|
return ["--use-gl=angle", "--use-angle=swiftshader", "--enable-unsafe-swiftshader"];
|
|
29565
29733
|
}
|
|
29566
|
-
switch (
|
|
29734
|
+
switch (platform9) {
|
|
29567
29735
|
case "darwin":
|
|
29568
29736
|
return ["--use-gl=angle", "--use-angle=metal", "--enable-gpu-rasterization"];
|
|
29569
29737
|
case "win32":
|
|
@@ -29886,7 +30054,7 @@ var init_screenshotService = __esm({
|
|
|
29886
30054
|
});
|
|
29887
30055
|
|
|
29888
30056
|
// ../engine/src/services/frameCapture.ts
|
|
29889
|
-
import { existsSync as
|
|
30057
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync10, writeFileSync as writeFileSync11 } from "fs";
|
|
29890
30058
|
import { join as join23 } from "path";
|
|
29891
30059
|
async function driveWarmupTicks(options, state) {
|
|
29892
30060
|
const sleep3 = options.sleep ?? realSleep;
|
|
@@ -29923,7 +30091,7 @@ async function waitForCloseWithTimeout(promise) {
|
|
|
29923
30091
|
return !timedOut;
|
|
29924
30092
|
}
|
|
29925
30093
|
async function createCaptureSession(serverUrl, outputDir, options, onBeforeCapture = null, config) {
|
|
29926
|
-
if (!
|
|
30094
|
+
if (!existsSync20(outputDir)) mkdirSync10(outputDir, { recursive: true });
|
|
29927
30095
|
const headlessShell = resolveHeadlessShellPath(config);
|
|
29928
30096
|
const isLinux = process.platform === "linux";
|
|
29929
30097
|
const forceScreenshot = config?.forceScreenshot ?? DEFAULT_CONFIG2.forceScreenshot;
|
|
@@ -30269,7 +30437,7 @@ async function initializeSession(session) {
|
|
|
30269
30437
|
async function captureFrameErrorDiagnostics(session, frameIndex, time, error) {
|
|
30270
30438
|
try {
|
|
30271
30439
|
const diagnosticsDir = join23(session.outputDir, "diagnostics");
|
|
30272
|
-
if (!
|
|
30440
|
+
if (!existsSync20(diagnosticsDir)) mkdirSync10(diagnosticsDir, { recursive: true });
|
|
30273
30441
|
const base = join23(diagnosticsDir, `frame-error-${frameIndex}`);
|
|
30274
30442
|
await session.page.screenshot({ path: `${base}.png`, type: "png", fullPage: true });
|
|
30275
30443
|
const html = await session.page.content();
|
|
@@ -30432,7 +30600,7 @@ async function closeCaptureSession(session) {
|
|
|
30432
30600
|
session.isInitialized = false;
|
|
30433
30601
|
}
|
|
30434
30602
|
function prepareCaptureSessionForReuse(session, outputDir, onBeforeCapture) {
|
|
30435
|
-
if (!
|
|
30603
|
+
if (!existsSync20(outputDir)) {
|
|
30436
30604
|
mkdirSync10(outputDir, { recursive: true });
|
|
30437
30605
|
}
|
|
30438
30606
|
session.outputDir = outputDir;
|
|
@@ -30673,7 +30841,7 @@ var init_runFfmpeg = __esm({
|
|
|
30673
30841
|
|
|
30674
30842
|
// ../engine/src/services/chunkEncoder.ts
|
|
30675
30843
|
import { spawn as spawn6 } from "child_process";
|
|
30676
|
-
import { copyFileSync, existsSync as
|
|
30844
|
+
import { copyFileSync, existsSync as existsSync21, mkdirSync as mkdirSync11, readdirSync as readdirSync10, statSync as statSync6, writeFileSync as writeFileSync12 } from "fs";
|
|
30677
30845
|
import { join as join24, dirname as dirname7 } from "path";
|
|
30678
30846
|
function getEncoderPreset(quality, format = "mp4", hdr) {
|
|
30679
30847
|
const base = ENCODER_PRESETS[quality];
|
|
@@ -30885,7 +31053,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
|
|
|
30885
31053
|
async function encodeFramesFromDir(framesDir, framePattern, outputPath, options, signal, config) {
|
|
30886
31054
|
const startTime = Date.now();
|
|
30887
31055
|
const outputDir = dirname7(outputPath);
|
|
30888
|
-
if (!
|
|
31056
|
+
if (!existsSync21(outputDir)) mkdirSync11(outputDir, { recursive: true });
|
|
30889
31057
|
const files = readdirSync10(framesDir).filter((f3) => f3.match(/\.(jpg|jpeg|png)$/i));
|
|
30890
31058
|
const frameCount = files.length;
|
|
30891
31059
|
if (frameCount === 0) {
|
|
@@ -30951,7 +31119,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
|
|
|
30951
31119
|
});
|
|
30952
31120
|
return;
|
|
30953
31121
|
}
|
|
30954
|
-
const fileSize =
|
|
31122
|
+
const fileSize = existsSync21(outputPath) ? statSync6(outputPath).size : 0;
|
|
30955
31123
|
resolve46({ success: true, outputPath, durationMs, framesEncoded: frameCount, fileSize });
|
|
30956
31124
|
});
|
|
30957
31125
|
ffmpeg.on("error", (err) => {
|
|
@@ -30984,7 +31152,7 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
|
|
|
30984
31152
|
const chunkSize = Math.max(30, Math.floor(chunkSizeFrames));
|
|
30985
31153
|
const chunkCount = Math.ceil(files.length / chunkSize);
|
|
30986
31154
|
const chunkDir = join24(dirname7(outputPath), "chunk-encode");
|
|
30987
|
-
if (!
|
|
31155
|
+
if (!existsSync21(chunkDir)) mkdirSync11(chunkDir, { recursive: true });
|
|
30988
31156
|
const chunkPaths = [];
|
|
30989
31157
|
for (let i2 = 0; i2 < chunkCount; i2++) {
|
|
30990
31158
|
if (signal?.aborted) {
|
|
@@ -31080,7 +31248,7 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
|
|
|
31080
31248
|
error: concatResult.error
|
|
31081
31249
|
};
|
|
31082
31250
|
}
|
|
31083
|
-
const fileSize =
|
|
31251
|
+
const fileSize = existsSync21(outputPath) ? statSync6(outputPath).size : 0;
|
|
31084
31252
|
return {
|
|
31085
31253
|
success: true,
|
|
31086
31254
|
outputPath,
|
|
@@ -31091,7 +31259,7 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
|
|
|
31091
31259
|
}
|
|
31092
31260
|
async function muxVideoWithAudio(videoPath, audioPath, outputPath, signal, config) {
|
|
31093
31261
|
const outputDir = dirname7(outputPath);
|
|
31094
|
-
if (!
|
|
31262
|
+
if (!existsSync21(outputDir)) mkdirSync11(outputDir, { recursive: true });
|
|
31095
31263
|
const isWebm = outputPath.endsWith(".webm");
|
|
31096
31264
|
const isMov = outputPath.endsWith(".mov");
|
|
31097
31265
|
const args = ["-i", videoPath, "-i", audioPath, "-c:v", "copy"];
|
|
@@ -31164,7 +31332,7 @@ var init_chunkEncoder = __esm({
|
|
|
31164
31332
|
|
|
31165
31333
|
// ../engine/src/services/streamingEncoder.ts
|
|
31166
31334
|
import { spawn as spawn7 } from "child_process";
|
|
31167
|
-
import { existsSync as
|
|
31335
|
+
import { existsSync as existsSync22, mkdirSync as mkdirSync12, statSync as statSync7 } from "fs";
|
|
31168
31336
|
import { dirname as dirname8 } from "path";
|
|
31169
31337
|
function createFrameReorderBuffer(startFrame, endFrame) {
|
|
31170
31338
|
let cursor = startFrame;
|
|
@@ -31366,7 +31534,7 @@ function buildStreamingArgs(options, outputPath, gpuEncoder = null) {
|
|
|
31366
31534
|
}
|
|
31367
31535
|
async function spawnStreamingEncoder(outputPath, options, signal, config) {
|
|
31368
31536
|
const outputDir = dirname8(outputPath);
|
|
31369
|
-
if (!
|
|
31537
|
+
if (!existsSync22(outputDir)) mkdirSync12(outputDir, { recursive: true });
|
|
31370
31538
|
let gpuEncoder = null;
|
|
31371
31539
|
if (options.useGpu) {
|
|
31372
31540
|
gpuEncoder = await getCachedGpuEncoder();
|
|
@@ -31462,7 +31630,7 @@ Process error: ${err.message}`;
|
|
|
31462
31630
|
error: formatFfmpegError(exitCode, stderr)
|
|
31463
31631
|
};
|
|
31464
31632
|
}
|
|
31465
|
-
const fileSize =
|
|
31633
|
+
const fileSize = existsSync22(outputPath) ? statSync7(outputPath).size : 0;
|
|
31466
31634
|
return { success: true, durationMs, fileSize };
|
|
31467
31635
|
},
|
|
31468
31636
|
getExitStatus: () => exitStatus
|
|
@@ -31482,7 +31650,7 @@ var init_streamingEncoder = __esm({
|
|
|
31482
31650
|
|
|
31483
31651
|
// ../engine/src/utils/ffprobe.ts
|
|
31484
31652
|
import { spawn as spawn8 } from "child_process";
|
|
31485
|
-
import { readFileSync as
|
|
31653
|
+
import { readFileSync as readFileSync20 } from "fs";
|
|
31486
31654
|
import { extname as extname5 } from "path";
|
|
31487
31655
|
function runFfprobe(args) {
|
|
31488
31656
|
return new Promise((resolve46, reject) => {
|
|
@@ -31576,7 +31744,7 @@ function extractPngMetadataFromBuffer(buf) {
|
|
|
31576
31744
|
function extractStillImageMetadata(filePath) {
|
|
31577
31745
|
if (extname5(filePath).toLowerCase() !== ".png") return null;
|
|
31578
31746
|
try {
|
|
31579
|
-
return extractPngMetadataFromBuffer(
|
|
31747
|
+
return extractPngMetadataFromBuffer(readFileSync20(filePath));
|
|
31580
31748
|
} catch {
|
|
31581
31749
|
return null;
|
|
31582
31750
|
}
|
|
@@ -31763,7 +31931,7 @@ var init_ffprobe = __esm({
|
|
|
31763
31931
|
});
|
|
31764
31932
|
|
|
31765
31933
|
// ../engine/src/utils/urlDownloader.ts
|
|
31766
|
-
import { createWriteStream as createWriteStream2, existsSync as
|
|
31934
|
+
import { createWriteStream as createWriteStream2, existsSync as existsSync23, mkdirSync as mkdirSync13 } from "fs";
|
|
31767
31935
|
import { createHash as createHash3 } from "crypto";
|
|
31768
31936
|
import { join as join25, extname as extname6 } from "path";
|
|
31769
31937
|
import { Readable } from "stream";
|
|
@@ -31776,19 +31944,19 @@ function getFilenameFromUrl(url) {
|
|
|
31776
31944
|
}
|
|
31777
31945
|
async function downloadToTemp(url, destDir, timeoutMs = 3e5) {
|
|
31778
31946
|
const cachedPath = downloadPathCache.get(url);
|
|
31779
|
-
if (cachedPath &&
|
|
31947
|
+
if (cachedPath && existsSync23(cachedPath)) {
|
|
31780
31948
|
return cachedPath;
|
|
31781
31949
|
}
|
|
31782
31950
|
const inFlight = inFlightDownloads.get(url);
|
|
31783
31951
|
if (inFlight) {
|
|
31784
31952
|
return inFlight;
|
|
31785
31953
|
}
|
|
31786
|
-
if (!
|
|
31954
|
+
if (!existsSync23(destDir)) {
|
|
31787
31955
|
mkdirSync13(destDir, { recursive: true });
|
|
31788
31956
|
}
|
|
31789
31957
|
const filename = getFilenameFromUrl(url);
|
|
31790
31958
|
const localPath = join25(destDir, filename);
|
|
31791
|
-
if (
|
|
31959
|
+
if (existsSync23(localPath)) {
|
|
31792
31960
|
downloadPathCache.set(url, localPath);
|
|
31793
31961
|
return localPath;
|
|
31794
31962
|
}
|
|
@@ -32544,7 +32712,7 @@ var init_inlineSubCompositions = __esm({
|
|
|
32544
32712
|
});
|
|
32545
32713
|
|
|
32546
32714
|
// ../core/src/compiler/htmlBundler.ts
|
|
32547
|
-
import { readFileSync as
|
|
32715
|
+
import { readFileSync as readFileSync21, existsSync as existsSync24 } from "fs";
|
|
32548
32716
|
import { join as join26, resolve as resolve14, relative as relative3, dirname as dirname9, isAbsolute as isAbsolute3, sep as sep3 } from "path";
|
|
32549
32717
|
import { transformSync } from "esbuild";
|
|
32550
32718
|
function safePath(projectDir, relativePath) {
|
|
@@ -32592,9 +32760,9 @@ function isRelativeUrl(url) {
|
|
|
32592
32760
|
return !url.startsWith("http://") && !url.startsWith("https://") && !url.startsWith("//") && !url.startsWith("data:") && !isAbsolute3(url);
|
|
32593
32761
|
}
|
|
32594
32762
|
function safeReadFile(filePath) {
|
|
32595
|
-
if (!
|
|
32763
|
+
if (!existsSync24(filePath)) return null;
|
|
32596
32764
|
try {
|
|
32597
|
-
return
|
|
32765
|
+
return readFileSync21(filePath, "utf-8");
|
|
32598
32766
|
} catch {
|
|
32599
32767
|
return null;
|
|
32600
32768
|
}
|
|
@@ -32664,9 +32832,9 @@ ${inlined}
|
|
|
32664
32832
|
return rebased;
|
|
32665
32833
|
}
|
|
32666
32834
|
function safeReadFileBuffer(filePath) {
|
|
32667
|
-
if (!
|
|
32835
|
+
if (!existsSync24(filePath)) return null;
|
|
32668
32836
|
try {
|
|
32669
|
-
return
|
|
32837
|
+
return readFileSync21(filePath);
|
|
32670
32838
|
} catch {
|
|
32671
32839
|
return null;
|
|
32672
32840
|
}
|
|
@@ -32968,8 +33136,8 @@ function stripJsCommentsParserSafe(source) {
|
|
|
32968
33136
|
}
|
|
32969
33137
|
async function bundleToSingleHtml(projectDir, options) {
|
|
32970
33138
|
const indexPath = join26(projectDir, "index.html");
|
|
32971
|
-
if (!
|
|
32972
|
-
const rawHtml =
|
|
33139
|
+
if (!existsSync24(indexPath)) throw new Error("index.html not found in project directory");
|
|
33140
|
+
const rawHtml = readFileSync21(indexPath, "utf-8");
|
|
32973
33141
|
const compiled = await compileHtml(rawHtml, projectDir, options?.probeMediaDuration);
|
|
32974
33142
|
const staticGuard = validateHyperframeHtmlContract(compiled);
|
|
32975
33143
|
if (!staticGuard.isValid) {
|
|
@@ -33322,7 +33490,7 @@ var init_htmlTemplate = __esm({
|
|
|
33322
33490
|
// ../engine/src/services/extractionCache.ts
|
|
33323
33491
|
import { createHash as createHash4 } from "crypto";
|
|
33324
33492
|
import { mkdirSync as mkdirSync14, readdirSync as readdirSync11, statSync as statSync8, writeFileSync as writeFileSync13 } from "fs";
|
|
33325
|
-
import { existsSync as
|
|
33493
|
+
import { existsSync as existsSync25 } from "fs";
|
|
33326
33494
|
import { join as join27 } from "path";
|
|
33327
33495
|
function readKeyStat(videoPath) {
|
|
33328
33496
|
try {
|
|
@@ -33353,7 +33521,7 @@ function cacheEntryDirName(keyHash) {
|
|
|
33353
33521
|
function lookupCacheEntry(rootDir, input) {
|
|
33354
33522
|
const keyHash = computeCacheKey(input);
|
|
33355
33523
|
const dir = join27(rootDir, cacheEntryDirName(keyHash));
|
|
33356
|
-
const complete =
|
|
33524
|
+
const complete = existsSync25(join27(dir, COMPLETE_SENTINEL));
|
|
33357
33525
|
return { entry: { dir, keyHash }, hit: complete };
|
|
33358
33526
|
}
|
|
33359
33527
|
function ensureCacheEntryDir(entry) {
|
|
@@ -33394,7 +33562,7 @@ var init_extractionCache = __esm({
|
|
|
33394
33562
|
|
|
33395
33563
|
// ../engine/src/services/videoFrameExtractor.ts
|
|
33396
33564
|
import { spawn as spawn9 } from "child_process";
|
|
33397
|
-
import { existsSync as
|
|
33565
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync15, readdirSync as readdirSync12, rmSync as rmSync5 } from "fs";
|
|
33398
33566
|
import { isAbsolute as isAbsolute4, join as join28, posix as posix2, resolve as resolve15, sep as sep4 } from "path";
|
|
33399
33567
|
function parseVideoElements(html) {
|
|
33400
33568
|
const videos = [];
|
|
@@ -33466,7 +33634,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
33466
33634
|
const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
|
|
33467
33635
|
const { fps, outputDir, quality = 95 } = options;
|
|
33468
33636
|
const videoOutputDir = outputDirOverride ?? join28(outputDir, videoId);
|
|
33469
|
-
if (!
|
|
33637
|
+
if (!existsSync26(videoOutputDir)) mkdirSync15(videoOutputDir, { recursive: true });
|
|
33470
33638
|
const metadata = await extractMediaMetadata(videoPath);
|
|
33471
33639
|
const format = resolveFrameFormat(metadata, options.format);
|
|
33472
33640
|
const framePattern = `${FRAME_FILENAME_PREFIX}%05d.${format}`;
|
|
@@ -33654,7 +33822,7 @@ function resolveProjectRelativeSrc(src, baseDir, compiledDir) {
|
|
|
33654
33822
|
candidates.push(join28(baseDir, stripped));
|
|
33655
33823
|
}
|
|
33656
33824
|
}
|
|
33657
|
-
return candidates.find(
|
|
33825
|
+
return candidates.find(existsSync26) ?? fromBase;
|
|
33658
33826
|
}
|
|
33659
33827
|
async function extractAllVideoFrames(videos, baseDir, options, signal, config, compiledDir) {
|
|
33660
33828
|
const startTime = Date.now();
|
|
@@ -33688,7 +33856,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
|
|
|
33688
33856
|
mkdirSync15(downloadDir, { recursive: true });
|
|
33689
33857
|
videoPath = await downloadToTemp(videoPath, downloadDir);
|
|
33690
33858
|
}
|
|
33691
|
-
if (!
|
|
33859
|
+
if (!existsSync26(videoPath)) {
|
|
33692
33860
|
if (!warnedSrcs.has(video.src)) {
|
|
33693
33861
|
warnedSrcs.add(video.src);
|
|
33694
33862
|
process.stderr.write(
|
|
@@ -34057,7 +34225,7 @@ var init_videoFrameExtractor = __esm({
|
|
|
34057
34225
|
cleanup() {
|
|
34058
34226
|
for (const video of this.videos.values()) {
|
|
34059
34227
|
if (video.extracted.ownedByLookup) continue;
|
|
34060
|
-
if (
|
|
34228
|
+
if (existsSync26(video.extracted.outputDir)) {
|
|
34061
34229
|
rmSync5(video.extracted.outputDir, { recursive: true, force: true });
|
|
34062
34230
|
}
|
|
34063
34231
|
}
|
|
@@ -34461,7 +34629,7 @@ var init_videoFrameInjector = __esm({
|
|
|
34461
34629
|
});
|
|
34462
34630
|
|
|
34463
34631
|
// ../engine/src/services/audioMixer.ts
|
|
34464
|
-
import { existsSync as
|
|
34632
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync16, rmSync as rmSync6 } from "fs";
|
|
34465
34633
|
import { isAbsolute as isAbsolute5, join as join29, dirname as dirname10 } from "path";
|
|
34466
34634
|
function parseAudioElements(html) {
|
|
34467
34635
|
const elements = [];
|
|
@@ -34513,7 +34681,7 @@ function parseAudioElements(html) {
|
|
|
34513
34681
|
async function extractAudioFromVideo(videoPath, outputPath, options, signal, config) {
|
|
34514
34682
|
const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
|
|
34515
34683
|
const outputDir = dirname10(outputPath);
|
|
34516
|
-
if (!
|
|
34684
|
+
if (!existsSync27(outputDir)) mkdirSync16(outputDir, { recursive: true });
|
|
34517
34685
|
const args = ["-i", videoPath];
|
|
34518
34686
|
if (options?.startTime !== void 0) args.push("-ss", String(options.startTime));
|
|
34519
34687
|
if (options?.duration !== void 0) args.push("-t", String(options.duration));
|
|
@@ -34540,7 +34708,7 @@ async function extractAudioFromVideo(videoPath, outputPath, options, signal, con
|
|
|
34540
34708
|
async function prepareAudioTrack(srcPath, outputPath, mediaStart, duration, signal, config) {
|
|
34541
34709
|
const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
|
|
34542
34710
|
const outputDir = dirname10(outputPath);
|
|
34543
|
-
if (!
|
|
34711
|
+
if (!existsSync27(outputDir)) mkdirSync16(outputDir, { recursive: true });
|
|
34544
34712
|
const args = [
|
|
34545
34713
|
"-ss",
|
|
34546
34714
|
String(mediaStart),
|
|
@@ -34576,7 +34744,7 @@ async function prepareAudioTrack(srcPath, outputPath, mediaStart, duration, sign
|
|
|
34576
34744
|
async function generateSilence(outputPath, duration, signal, config) {
|
|
34577
34745
|
const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
|
|
34578
34746
|
const outputDir = dirname10(outputPath);
|
|
34579
|
-
if (!
|
|
34747
|
+
if (!existsSync27(outputDir)) mkdirSync16(outputDir, { recursive: true });
|
|
34580
34748
|
const args = [
|
|
34581
34749
|
"-f",
|
|
34582
34750
|
"lavfi",
|
|
@@ -34619,7 +34787,7 @@ async function mixAudioTracks(tracks, outputPath, totalDuration, signal, config)
|
|
|
34619
34787
|
};
|
|
34620
34788
|
}
|
|
34621
34789
|
const outputDir = dirname10(outputPath);
|
|
34622
|
-
if (!
|
|
34790
|
+
if (!existsSync27(outputDir)) mkdirSync16(outputDir, { recursive: true });
|
|
34623
34791
|
const inputs = [];
|
|
34624
34792
|
const filterParts = [];
|
|
34625
34793
|
tracks.forEach((track, i2) => {
|
|
@@ -34680,7 +34848,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
34680
34848
|
const startMs = Date.now();
|
|
34681
34849
|
const tracks = [];
|
|
34682
34850
|
const errors = [];
|
|
34683
|
-
if (!
|
|
34851
|
+
if (!existsSync27(workDir)) mkdirSync16(workDir, { recursive: true });
|
|
34684
34852
|
await Promise.all(
|
|
34685
34853
|
elements.map(async (element) => {
|
|
34686
34854
|
if (signal?.aborted) {
|
|
@@ -34702,7 +34870,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
34702
34870
|
return;
|
|
34703
34871
|
}
|
|
34704
34872
|
}
|
|
34705
|
-
if (!
|
|
34873
|
+
if (!existsSync27(srcPath)) {
|
|
34706
34874
|
errors.push(`Source not found: ${element.id} (${element.src})`);
|
|
34707
34875
|
return;
|
|
34708
34876
|
}
|
|
@@ -34866,7 +35034,7 @@ var init_readWebGlVendorInfoFromCanvas = __esm({
|
|
|
34866
35034
|
|
|
34867
35035
|
// ../engine/src/services/parallelCoordinator.ts
|
|
34868
35036
|
import { cpus as cpus2, freemem as freemem2, totalmem as totalmem2 } from "os";
|
|
34869
|
-
import { existsSync as
|
|
35037
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync17, readdirSync as readdirSync13 } from "fs";
|
|
34870
35038
|
import { copyFile, rename } from "fs/promises";
|
|
34871
35039
|
import { join as join30 } from "path";
|
|
34872
35040
|
function defaultSafeMaxWorkers() {
|
|
@@ -34933,7 +35101,7 @@ function shouldVerifyWorkerGpu(workerId, config) {
|
|
|
34933
35101
|
async function executeWorkerTask(task, serverUrl, captureOptions, createBeforeCaptureHook, signal, onFrameCaptured, onFrameBuffer, config) {
|
|
34934
35102
|
const startTime = Date.now();
|
|
34935
35103
|
let framesCaptured = 0;
|
|
34936
|
-
if (!
|
|
35104
|
+
if (!existsSync28(task.outputDir)) mkdirSync17(task.outputDir, { recursive: true });
|
|
34937
35105
|
let session = null;
|
|
34938
35106
|
let perf;
|
|
34939
35107
|
try {
|
|
@@ -35028,11 +35196,11 @@ async function executeParallelCapture(serverUrl, workDir, tasks, captureOptions,
|
|
|
35028
35196
|
return results;
|
|
35029
35197
|
}
|
|
35030
35198
|
async function mergeWorkerFrames(workDir, tasks, outputDir) {
|
|
35031
|
-
if (!
|
|
35199
|
+
if (!existsSync28(outputDir)) mkdirSync17(outputDir, { recursive: true });
|
|
35032
35200
|
let totalFrames = 0;
|
|
35033
35201
|
const sortedTasks = [...tasks].sort((a, b2) => a.startFrame - b2.startFrame);
|
|
35034
35202
|
for (const task of sortedTasks) {
|
|
35035
|
-
if (!
|
|
35203
|
+
if (!existsSync28(task.outputDir)) {
|
|
35036
35204
|
continue;
|
|
35037
35205
|
}
|
|
35038
35206
|
const files = readdirSync13(task.outputDir).filter((f3) => f3.startsWith("frame_") && (f3.endsWith(".jpg") || f3.endsWith(".png"))).sort();
|
|
@@ -35076,7 +35244,7 @@ var init_parallelCoordinator = __esm({
|
|
|
35076
35244
|
// ../engine/src/services/fileServer.ts
|
|
35077
35245
|
import { Hono as Hono2 } from "hono";
|
|
35078
35246
|
import { serve } from "@hono/node-server";
|
|
35079
|
-
import { readFileSync as
|
|
35247
|
+
import { readFileSync as readFileSync22, existsSync as existsSync29, statSync as statSync9 } from "fs";
|
|
35080
35248
|
import { join as join31, extname as extname7 } from "path";
|
|
35081
35249
|
function createFileServer(options) {
|
|
35082
35250
|
const { projectDir, compiledDir, port = 0, stripEmbeddedRuntime = true } = options;
|
|
@@ -35089,20 +35257,20 @@ function createFileServer(options) {
|
|
|
35089
35257
|
const relativePath = requestPath.replace(/^\//, "");
|
|
35090
35258
|
const compiledPath = compiledDir ? join31(compiledDir, relativePath) : null;
|
|
35091
35259
|
const hasCompiledFile = Boolean(
|
|
35092
|
-
compiledPath &&
|
|
35260
|
+
compiledPath && existsSync29(compiledPath) && statSync9(compiledPath).isFile()
|
|
35093
35261
|
);
|
|
35094
35262
|
const filePath = hasCompiledFile ? compiledPath : join31(projectDir, relativePath);
|
|
35095
|
-
if (!
|
|
35263
|
+
if (!existsSync29(filePath) || !statSync9(filePath).isFile()) {
|
|
35096
35264
|
return c3.text("Not found", 404);
|
|
35097
35265
|
}
|
|
35098
35266
|
const ext = extname7(filePath).toLowerCase();
|
|
35099
35267
|
const contentType = MIME_TYPES2[ext] || "application/octet-stream";
|
|
35100
35268
|
if (ext === ".html") {
|
|
35101
|
-
const rawHtml =
|
|
35269
|
+
const rawHtml = readFileSync22(filePath, "utf-8");
|
|
35102
35270
|
const html = relativePath === "index.html" ? injectScriptsIntoHtml(rawHtml, headScripts, bodyScripts, stripEmbeddedRuntime) : rawHtml;
|
|
35103
35271
|
return c3.text(html, 200, { "Content-Type": contentType });
|
|
35104
35272
|
}
|
|
35105
|
-
const content =
|
|
35273
|
+
const content = readFileSync22(filePath);
|
|
35106
35274
|
return new Response(content, {
|
|
35107
35275
|
status: 200,
|
|
35108
35276
|
headers: { "Content-Type": contentType }
|
|
@@ -36405,7 +36573,7 @@ var init_shaderTransitions = __esm({
|
|
|
36405
36573
|
});
|
|
36406
36574
|
|
|
36407
36575
|
// ../engine/src/services/hdrCapture.ts
|
|
36408
|
-
import { existsSync as
|
|
36576
|
+
import { existsSync as existsSync30, readdirSync as readdirSync14 } from "fs";
|
|
36409
36577
|
import { join as join32 } from "path";
|
|
36410
36578
|
import { homedir as homedir7 } from "os";
|
|
36411
36579
|
function linearToPQ(L2) {
|
|
@@ -36523,7 +36691,7 @@ function float16ToPqRgb(rawBuffer, bytesPerRow, width, height) {
|
|
|
36523
36691
|
}
|
|
36524
36692
|
function resolveHeadedChromePath() {
|
|
36525
36693
|
const baseDir = join32(homedir7(), ".cache", "puppeteer", "chrome");
|
|
36526
|
-
if (!
|
|
36694
|
+
if (!existsSync30(baseDir)) return void 0;
|
|
36527
36695
|
const versions = readdirSync14(baseDir).sort().reverse();
|
|
36528
36696
|
for (const version of versions) {
|
|
36529
36697
|
const candidates = [
|
|
@@ -36549,7 +36717,7 @@ function resolveHeadedChromePath() {
|
|
|
36549
36717
|
join32(baseDir, version, "chrome-win64", "chrome.exe")
|
|
36550
36718
|
];
|
|
36551
36719
|
for (const binary of candidates) {
|
|
36552
|
-
if (
|
|
36720
|
+
if (existsSync30(binary)) return binary;
|
|
36553
36721
|
}
|
|
36554
36722
|
}
|
|
36555
36723
|
return void 0;
|
|
@@ -36818,7 +36986,7 @@ __export(deterministicFonts_exports, {
|
|
|
36818
36986
|
iterateFontFamilyDeclarations: () => iterateFontFamilyDeclarations,
|
|
36819
36987
|
parseFontFamilyValue: () => parseFontFamilyValue
|
|
36820
36988
|
});
|
|
36821
|
-
import { existsSync as
|
|
36989
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync18, readFileSync as readFileSync23, writeFileSync as writeFileSync14 } from "fs";
|
|
36822
36990
|
import { homedir as homedir8, tmpdir as tmpdir3 } from "os";
|
|
36823
36991
|
import { join as join33 } from "path";
|
|
36824
36992
|
function parseFontFamilyValue(value) {
|
|
@@ -36947,7 +37115,7 @@ function fontSlug(familyName) {
|
|
|
36947
37115
|
}
|
|
36948
37116
|
function fontCacheDir(slug) {
|
|
36949
37117
|
const dir = join33(GOOGLE_FONTS_CACHE_DIR, slug);
|
|
36950
|
-
if (!
|
|
37118
|
+
if (!existsSync31(dir)) {
|
|
36951
37119
|
mkdirSync18(dir, { recursive: true });
|
|
36952
37120
|
}
|
|
36953
37121
|
return dir;
|
|
@@ -36991,7 +37159,7 @@ async function fetchGoogleFont(familyName, options) {
|
|
|
36991
37159
|
const woff2Url = match[3] || "";
|
|
36992
37160
|
if (!woff2Url) continue;
|
|
36993
37161
|
const cachePath2 = cachedWoff2Path(slug, weight, style);
|
|
36994
|
-
if (!
|
|
37162
|
+
if (!existsSync31(cachePath2)) {
|
|
36995
37163
|
const woff2What = `Google Fonts woff2 (${weight}/${style})`;
|
|
36996
37164
|
try {
|
|
36997
37165
|
const fontRes = await options.fetchImpl(woff2Url);
|
|
@@ -37011,7 +37179,7 @@ async function fetchGoogleFont(familyName, options) {
|
|
|
37011
37179
|
continue;
|
|
37012
37180
|
}
|
|
37013
37181
|
}
|
|
37014
|
-
const fontBytes =
|
|
37182
|
+
const fontBytes = readFileSync23(cachePath2);
|
|
37015
37183
|
const dataUri = `data:font/woff2;base64,${fontBytes.toString("base64")}`;
|
|
37016
37184
|
faces.push({ weight, style, dataUri });
|
|
37017
37185
|
}
|
|
@@ -37211,7 +37379,7 @@ var init_deterministicFonts = __esm({
|
|
|
37211
37379
|
|
|
37212
37380
|
// ../producer/src/services/hyperframeRuntimeLoader.ts
|
|
37213
37381
|
import { createHash as createHash5 } from "crypto";
|
|
37214
|
-
import { existsSync as
|
|
37382
|
+
import { existsSync as existsSync32, readFileSync as readFileSync24 } from "fs";
|
|
37215
37383
|
import { dirname as dirname11, resolve as resolve16 } from "path";
|
|
37216
37384
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
37217
37385
|
function resolveHyperframeManifestPath() {
|
|
@@ -37224,7 +37392,7 @@ function resolveHyperframeManifestPath() {
|
|
|
37224
37392
|
MODULE_RELATIVE_MANIFEST_PATH
|
|
37225
37393
|
];
|
|
37226
37394
|
for (const candidate of candidates) {
|
|
37227
|
-
if (
|
|
37395
|
+
if (existsSync32(candidate)) {
|
|
37228
37396
|
return candidate;
|
|
37229
37397
|
}
|
|
37230
37398
|
}
|
|
@@ -37235,12 +37403,12 @@ function getVerifiedHyperframeRuntimeSource() {
|
|
|
37235
37403
|
}
|
|
37236
37404
|
function resolveVerifiedHyperframeRuntime() {
|
|
37237
37405
|
const manifestPath = resolveHyperframeManifestPath();
|
|
37238
|
-
if (!
|
|
37406
|
+
if (!existsSync32(manifestPath)) {
|
|
37239
37407
|
throw new Error(
|
|
37240
37408
|
`[HyperframeRuntimeLoader] Missing manifest at ${manifestPath}. Build core runtime artifacts before rendering.`
|
|
37241
37409
|
);
|
|
37242
37410
|
}
|
|
37243
|
-
const manifestRaw =
|
|
37411
|
+
const manifestRaw = readFileSync24(manifestPath, "utf8");
|
|
37244
37412
|
const manifest = JSON.parse(manifestRaw);
|
|
37245
37413
|
const runtimeFileName = manifest.artifacts?.iife;
|
|
37246
37414
|
if (!runtimeFileName || !manifest.sha256) {
|
|
@@ -37249,10 +37417,10 @@ function resolveVerifiedHyperframeRuntime() {
|
|
|
37249
37417
|
);
|
|
37250
37418
|
}
|
|
37251
37419
|
const runtimePath = resolve16(dirname11(manifestPath), runtimeFileName);
|
|
37252
|
-
if (!
|
|
37420
|
+
if (!existsSync32(runtimePath)) {
|
|
37253
37421
|
throw new Error(`[HyperframeRuntimeLoader] Missing runtime artifact at ${runtimePath}.`);
|
|
37254
37422
|
}
|
|
37255
|
-
const runtimeSource =
|
|
37423
|
+
const runtimeSource = readFileSync24(runtimePath, "utf8");
|
|
37256
37424
|
const runtimeSha = createHash5("sha256").update(runtimeSource, "utf8").digest("hex");
|
|
37257
37425
|
if (runtimeSha !== manifest.sha256) {
|
|
37258
37426
|
throw new Error(
|
|
@@ -37291,7 +37459,7 @@ var init_hyperframeRuntimeLoader = __esm({
|
|
|
37291
37459
|
// ../producer/src/services/fileServer.ts
|
|
37292
37460
|
import { Hono as Hono3 } from "hono";
|
|
37293
37461
|
import { serve as serve2 } from "@hono/node-server";
|
|
37294
|
-
import { readFileSync as
|
|
37462
|
+
import { readFileSync as readFileSync25, existsSync as existsSync33, realpathSync, statSync as statSync10 } from "fs";
|
|
37295
37463
|
import { join as join34, extname as extname8, resolve as resolve17, sep as sep5 } from "path";
|
|
37296
37464
|
function isPathInside(child, parent, options = {}) {
|
|
37297
37465
|
const { resolveSymlinks = false, pathModule } = options;
|
|
@@ -37299,8 +37467,8 @@ function isPathInside(child, parent, options = {}) {
|
|
|
37299
37467
|
const separator = pathModule?.sep ?? sep5;
|
|
37300
37468
|
const resolvedChild = resolveFn(child);
|
|
37301
37469
|
const resolvedParent = resolveFn(parent);
|
|
37302
|
-
const normalizedChild = resolveSymlinks &&
|
|
37303
|
-
const normalizedParent = resolveSymlinks &&
|
|
37470
|
+
const normalizedChild = resolveSymlinks && existsSync33(resolvedChild) ? realpathSync.native(resolvedChild) : resolvedChild;
|
|
37471
|
+
const normalizedParent = resolveSymlinks && existsSync33(resolvedParent) ? realpathSync.native(resolvedParent) : resolvedParent;
|
|
37304
37472
|
if (normalizedChild === normalizedParent) return true;
|
|
37305
37473
|
const parentWithSep = normalizedParent.endsWith(separator) ? normalizedParent : normalizedParent + separator;
|
|
37306
37474
|
return normalizedChild.startsWith(parentWithSep);
|
|
@@ -37467,13 +37635,13 @@ function createFileServer2(options) {
|
|
|
37467
37635
|
let filePath = null;
|
|
37468
37636
|
if (compiledDir) {
|
|
37469
37637
|
const candidate = join34(compiledDir, relativePath);
|
|
37470
|
-
if (
|
|
37638
|
+
if (existsSync33(candidate) && isPathInside(candidate, compiledDir) && statSync10(candidate).isFile()) {
|
|
37471
37639
|
filePath = candidate;
|
|
37472
37640
|
}
|
|
37473
37641
|
}
|
|
37474
37642
|
if (!filePath) {
|
|
37475
37643
|
const candidate = join34(projectDir, relativePath);
|
|
37476
|
-
if (
|
|
37644
|
+
if (existsSync33(candidate) && isPathInside(candidate, projectDir) && statSync10(candidate).isFile()) {
|
|
37477
37645
|
filePath = candidate;
|
|
37478
37646
|
}
|
|
37479
37647
|
}
|
|
@@ -37486,7 +37654,7 @@ function createFileServer2(options) {
|
|
|
37486
37654
|
const ext = extname8(filePath).toLowerCase();
|
|
37487
37655
|
const contentType = MIME_TYPES3[ext] || "application/octet-stream";
|
|
37488
37656
|
if (ext === ".html") {
|
|
37489
|
-
const rawHtml =
|
|
37657
|
+
const rawHtml = readFileSync25(filePath, "utf-8");
|
|
37490
37658
|
const isIndex = relativePath === "index.html";
|
|
37491
37659
|
let html = rawHtml;
|
|
37492
37660
|
if (preHeadScripts.length > 0) {
|
|
@@ -37495,7 +37663,7 @@ function createFileServer2(options) {
|
|
|
37495
37663
|
html = isIndex ? injectScriptsIntoHtml(html, headScripts, bodyScripts, stripEmbeddedRuntime) : html;
|
|
37496
37664
|
return c3.text(html, 200, { "Content-Type": contentType });
|
|
37497
37665
|
}
|
|
37498
|
-
const content =
|
|
37666
|
+
const content = readFileSync25(filePath);
|
|
37499
37667
|
return new Response(content, {
|
|
37500
37668
|
status: 200,
|
|
37501
37669
|
headers: { "Content-Type": contentType }
|
|
@@ -37840,7 +38008,7 @@ var init_paths = __esm({
|
|
|
37840
38008
|
});
|
|
37841
38009
|
|
|
37842
38010
|
// ../producer/src/services/render/shared.ts
|
|
37843
|
-
import { copyFileSync as copyFileSync2, cpSync, existsSync as
|
|
38011
|
+
import { copyFileSync as copyFileSync2, cpSync, existsSync as existsSync34, mkdirSync as mkdirSync19, symlinkSync, writeFileSync as writeFileSync15 } from "fs";
|
|
37844
38012
|
import { basename as basename4, dirname as dirname12, isAbsolute as isAbsolute6, join as join36, relative as relative4, resolve as resolve18 } from "path";
|
|
37845
38013
|
function projectBrowserEndToCompositionTimeline(existingStart, browserStart, browserEnd) {
|
|
37846
38014
|
return browserEnd + (existingStart - browserStart);
|
|
@@ -38027,7 +38195,7 @@ var init_shared = __esm({
|
|
|
38027
38195
|
isAbsolute: isAbsolute6
|
|
38028
38196
|
};
|
|
38029
38197
|
materializeFileSystem = {
|
|
38030
|
-
existsSync:
|
|
38198
|
+
existsSync: existsSync34,
|
|
38031
38199
|
mkdirSync: mkdirSync19,
|
|
38032
38200
|
symlinkSync,
|
|
38033
38201
|
cpSync
|
|
@@ -38563,7 +38731,7 @@ var init_urlDownloader2 = __esm({
|
|
|
38563
38731
|
});
|
|
38564
38732
|
|
|
38565
38733
|
// ../producer/src/services/htmlCompiler.ts
|
|
38566
|
-
import { readFileSync as
|
|
38734
|
+
import { readFileSync as readFileSync26, existsSync as existsSync35, mkdirSync as mkdirSync20 } from "fs";
|
|
38567
38735
|
import { join as join38, dirname as dirname13, resolve as resolve19 } from "path";
|
|
38568
38736
|
function dedupeElementsById(elements) {
|
|
38569
38737
|
const deduped = /* @__PURE__ */ new Map();
|
|
@@ -38625,7 +38793,7 @@ function detectShaderTransitionUsage(html) {
|
|
|
38625
38793
|
async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagName19) {
|
|
38626
38794
|
let filePath = src;
|
|
38627
38795
|
if (isHttpUrl(src)) {
|
|
38628
|
-
if (!
|
|
38796
|
+
if (!existsSync35(downloadDir)) mkdirSync20(downloadDir, { recursive: true });
|
|
38629
38797
|
try {
|
|
38630
38798
|
filePath = await downloadToTemp(src, downloadDir);
|
|
38631
38799
|
} catch {
|
|
@@ -38634,7 +38802,7 @@ async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagNa
|
|
|
38634
38802
|
} else if (!filePath.startsWith("/")) {
|
|
38635
38803
|
filePath = join38(baseDir, filePath);
|
|
38636
38804
|
}
|
|
38637
|
-
if (!
|
|
38805
|
+
if (!existsSync35(filePath)) {
|
|
38638
38806
|
return { duration: 0, resolvedPath: filePath };
|
|
38639
38807
|
}
|
|
38640
38808
|
let metadata;
|
|
@@ -38712,10 +38880,10 @@ async function parseSubCompositions(html, projectDir, downloadDir, parentOffset
|
|
|
38712
38880
|
if (visited.has(filePath)) {
|
|
38713
38881
|
continue;
|
|
38714
38882
|
}
|
|
38715
|
-
if (!
|
|
38883
|
+
if (!existsSync35(filePath)) {
|
|
38716
38884
|
continue;
|
|
38717
38885
|
}
|
|
38718
|
-
const rawSubHtml =
|
|
38886
|
+
const rawSubHtml = readFileSync26(filePath, "utf-8");
|
|
38719
38887
|
const nestedVisited = new Set(visited);
|
|
38720
38888
|
nestedVisited.add(filePath);
|
|
38721
38889
|
workItems.push({ srcPath, absoluteStart, absoluteEnd, filePath, rawSubHtml, nestedVisited });
|
|
@@ -38900,8 +39068,8 @@ function inlineSubCompositions2(html, subCompositions, projectDir) {
|
|
|
38900
39068
|
let compHtml = subCompositions.get(srcPath) || null;
|
|
38901
39069
|
if (!compHtml) {
|
|
38902
39070
|
const filePath = resolve19(projectDir, srcPath);
|
|
38903
|
-
if (
|
|
38904
|
-
compHtml =
|
|
39071
|
+
if (existsSync35(filePath)) {
|
|
39072
|
+
compHtml = readFileSync26(filePath, "utf-8");
|
|
38905
39073
|
}
|
|
38906
39074
|
}
|
|
38907
39075
|
return compHtml;
|
|
@@ -39058,7 +39226,7 @@ function collectExternalAssets(html, projectDir) {
|
|
|
39058
39226
|
if (isPathInside2(absPath, absProjectDir)) {
|
|
39059
39227
|
return null;
|
|
39060
39228
|
}
|
|
39061
|
-
if (!
|
|
39229
|
+
if (!existsSync35(absPath)) return null;
|
|
39062
39230
|
const safeKey = toExternalAssetKey(absPath);
|
|
39063
39231
|
externalAssets.set(safeKey, absPath);
|
|
39064
39232
|
return safeKey;
|
|
@@ -39108,7 +39276,7 @@ function rewriteUnresolvableGsapToCdn(html, projectDir) {
|
|
|
39108
39276
|
(full, prefix, src, file, suffix) => {
|
|
39109
39277
|
if (/^https?:\/\//i.test(src)) return full;
|
|
39110
39278
|
const absPath = resolve19(projectDir, src);
|
|
39111
|
-
if (
|
|
39279
|
+
if (existsSync35(absPath)) return full;
|
|
39112
39280
|
console.log(
|
|
39113
39281
|
`[Compiler] Rewriting missing gsap script to CDN: ${src} \u2192 ${GSAP_CDN_BASE}${file}`
|
|
39114
39282
|
);
|
|
@@ -39117,7 +39285,7 @@ function rewriteUnresolvableGsapToCdn(html, projectDir) {
|
|
|
39117
39285
|
);
|
|
39118
39286
|
}
|
|
39119
39287
|
async function compileForRender(projectDir, htmlPath, downloadDir, options = {}) {
|
|
39120
|
-
const rawHtml = rewriteUnresolvableGsapToCdn(
|
|
39288
|
+
const rawHtml = rewriteUnresolvableGsapToCdn(readFileSync26(htmlPath, "utf-8"), projectDir);
|
|
39121
39289
|
const { html: compiledHtml, unresolvedCompositions } = await compileHtmlFile(
|
|
39122
39290
|
rawHtml,
|
|
39123
39291
|
projectDir,
|
|
@@ -39739,7 +39907,7 @@ var init_probeStage = __esm({
|
|
|
39739
39907
|
});
|
|
39740
39908
|
|
|
39741
39909
|
// ../producer/src/services/render/stages/extractVideosStage.ts
|
|
39742
|
-
import { existsSync as
|
|
39910
|
+
import { existsSync as existsSync36 } from "fs";
|
|
39743
39911
|
import { isAbsolute as isAbsolute7, join as join41 } from "path";
|
|
39744
39912
|
async function runExtractVideosStage(input) {
|
|
39745
39913
|
const {
|
|
@@ -39763,7 +39931,7 @@ async function runExtractVideosStage(input) {
|
|
|
39763
39931
|
await Promise.all(
|
|
39764
39932
|
composition.videos.map(async (v2) => {
|
|
39765
39933
|
const videoPath = isAbsolute7(v2.src) ? v2.src : resolveProjectRelativeSrc(v2.src, projectDir, compiledDir);
|
|
39766
|
-
if (!
|
|
39934
|
+
if (!existsSync36(videoPath)) return;
|
|
39767
39935
|
const meta = await extractMediaMetadata(videoPath);
|
|
39768
39936
|
if (isHdrColorSpace(meta.colorSpace)) {
|
|
39769
39937
|
nativeHdrVideoIds.add(v2.id);
|
|
@@ -39781,10 +39949,10 @@ async function runExtractVideosStage(input) {
|
|
|
39781
39949
|
composition.images.map(async (img) => {
|
|
39782
39950
|
let imgPath = img.src;
|
|
39783
39951
|
if (!imgPath.startsWith("/")) {
|
|
39784
|
-
const fromCompiled =
|
|
39952
|
+
const fromCompiled = existsSync36(join41(compiledDir, imgPath)) ? join41(compiledDir, imgPath) : join41(projectDir, imgPath);
|
|
39785
39953
|
imgPath = fromCompiled;
|
|
39786
39954
|
}
|
|
39787
|
-
if (!
|
|
39955
|
+
if (!existsSync36(imgPath)) return null;
|
|
39788
39956
|
const meta = await extractMediaMetadata(imgPath);
|
|
39789
39957
|
if (isHdrColorSpace(meta.colorSpace)) {
|
|
39790
39958
|
nativeHdrImageIds.add(img.id);
|
|
@@ -40259,7 +40427,7 @@ var init_hdrImageTransferCache = __esm({
|
|
|
40259
40427
|
});
|
|
40260
40428
|
|
|
40261
40429
|
// ../producer/src/services/render/stages/captureHdrResources.ts
|
|
40262
|
-
import { mkdirSync as mkdirSync21, openSync, readFileSync as
|
|
40430
|
+
import { mkdirSync as mkdirSync21, openSync, readFileSync as readFileSync27, statSync as statSync11 } from "fs";
|
|
40263
40431
|
import { join as join43 } from "path";
|
|
40264
40432
|
function planHdrResources(args) {
|
|
40265
40433
|
const { composition, nativeHdrVideoIds, nativeHdrImageIds, projectDir, compiledDir } = args;
|
|
@@ -40404,7 +40572,7 @@ function decodeHdrImageBuffers(args) {
|
|
|
40404
40572
|
const out = /* @__PURE__ */ new Map();
|
|
40405
40573
|
for (const [imageId, srcPath] of hdrImageSrcPaths) {
|
|
40406
40574
|
try {
|
|
40407
|
-
const decoded = decodePngToRgb48le(
|
|
40575
|
+
const decoded = decodePngToRgb48le(readFileSync27(srcPath));
|
|
40408
40576
|
const layout2 = prep.hdrExtractionDims.get(imageId);
|
|
40409
40577
|
const fitInfo = prep.hdrImageFitInfo.get(imageId);
|
|
40410
40578
|
if (layout2 && (layout2.width !== decoded.width || layout2.height !== decoded.height)) {
|
|
@@ -40842,7 +41010,7 @@ import { Worker } from "worker_threads";
|
|
|
40842
41010
|
import { fileURLToPath as fileURLToPath3, pathToFileURL } from "url";
|
|
40843
41011
|
import { dirname as dirname14, join as join45 } from "path";
|
|
40844
41012
|
import { createRequire } from "module";
|
|
40845
|
-
import { existsSync as
|
|
41013
|
+
import { existsSync as existsSync37 } from "fs";
|
|
40846
41014
|
import { cpus as cpus3 } from "os";
|
|
40847
41015
|
function resolveWorkerEntry(explicit) {
|
|
40848
41016
|
if (explicit && explicit.length > 0) {
|
|
@@ -40855,7 +41023,7 @@ function resolveWorkerEntry(explicit) {
|
|
|
40855
41023
|
}
|
|
40856
41024
|
const moduleDir = dirname14(fileURLToPath3(import.meta.url));
|
|
40857
41025
|
const jsPath = join45(moduleDir, "shaderTransitionWorker.js");
|
|
40858
|
-
if (
|
|
41026
|
+
if (existsSync37(jsPath)) return { path: jsPath, isTs: false };
|
|
40859
41027
|
const tsPath = join45(moduleDir, "shaderTransitionWorker.ts");
|
|
40860
41028
|
return { path: tsPath, isTs: true };
|
|
40861
41029
|
}
|
|
@@ -41264,7 +41432,7 @@ var init_captureHdrHybridLoop = __esm({
|
|
|
41264
41432
|
});
|
|
41265
41433
|
|
|
41266
41434
|
// ../producer/src/services/render/stages/captureHdrStage.ts
|
|
41267
|
-
import { existsSync as
|
|
41435
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync22 } from "fs";
|
|
41268
41436
|
import { join as join47 } from "path";
|
|
41269
41437
|
async function runCaptureHdrStage(input) {
|
|
41270
41438
|
const {
|
|
@@ -41321,7 +41489,7 @@ async function runCaptureHdrStage(input) {
|
|
|
41321
41489
|
nativeHdrImageIds,
|
|
41322
41490
|
projectDir,
|
|
41323
41491
|
compiledDir,
|
|
41324
|
-
existsSync:
|
|
41492
|
+
existsSync: existsSync38
|
|
41325
41493
|
});
|
|
41326
41494
|
const domSession = await createCaptureSession(
|
|
41327
41495
|
fileServer.url,
|
|
@@ -41425,7 +41593,7 @@ async function runCaptureHdrStage(input) {
|
|
|
41425
41593
|
}
|
|
41426
41594
|
const debugDumpEnabled = process.env.KEEP_TEMP === "1";
|
|
41427
41595
|
const debugDumpDir = debugDumpEnabled ? join47(framesDir, "debug-composite") : null;
|
|
41428
|
-
if (debugDumpDir && !
|
|
41596
|
+
if (debugDumpDir && !existsSync38(debugDumpDir)) {
|
|
41429
41597
|
mkdirSync22(debugDumpDir, { recursive: true });
|
|
41430
41598
|
}
|
|
41431
41599
|
const compositeTransfer = resolveCompositeTransfer(hasHdrContent, effectiveHdr);
|
|
@@ -41581,7 +41749,7 @@ var init_captureHdrStage = __esm({
|
|
|
41581
41749
|
});
|
|
41582
41750
|
|
|
41583
41751
|
// ../producer/src/services/render/stages/encodeStage.ts
|
|
41584
|
-
import { copyFileSync as copyFileSync3, existsSync as
|
|
41752
|
+
import { copyFileSync as copyFileSync3, existsSync as existsSync39, mkdirSync as mkdirSync23, readdirSync as readdirSync15 } from "fs";
|
|
41585
41753
|
import { join as join48 } from "path";
|
|
41586
41754
|
async function runEncodeStage(input) {
|
|
41587
41755
|
const {
|
|
@@ -41608,7 +41776,7 @@ async function runEncodeStage(input) {
|
|
|
41608
41776
|
const stage5Start = Date.now();
|
|
41609
41777
|
if (isPngSequence) {
|
|
41610
41778
|
updateJobStatus(job, "encoding", "Writing PNG sequence", 75, onProgress);
|
|
41611
|
-
if (!
|
|
41779
|
+
if (!existsSync39(outputPath)) mkdirSync23(outputPath, { recursive: true });
|
|
41612
41780
|
const captured = readdirSync15(framesDir).filter((name) => name.endsWith(".png")).sort();
|
|
41613
41781
|
if (captured.length === 0) {
|
|
41614
41782
|
throw new Error(
|
|
@@ -41619,7 +41787,7 @@ async function runEncodeStage(input) {
|
|
|
41619
41787
|
const dst = join48(outputPath, `frame_${String(i2 + 1).padStart(6, "0")}.png`);
|
|
41620
41788
|
copyFileSync3(join48(framesDir, name), dst);
|
|
41621
41789
|
});
|
|
41622
|
-
if (hasAudio && audioOutputPath &&
|
|
41790
|
+
if (hasAudio && audioOutputPath && existsSync39(audioOutputPath)) {
|
|
41623
41791
|
copyFileSync3(audioOutputPath, join48(outputPath, "audio.aac"));
|
|
41624
41792
|
log2.info(`[Render] png-sequence: audio.aac sidecar written to ${outputPath}/audio.aac`);
|
|
41625
41793
|
}
|
|
@@ -41711,9 +41879,9 @@ var init_assembleStage = __esm({
|
|
|
41711
41879
|
|
|
41712
41880
|
// ../producer/src/services/renderOrchestrator.ts
|
|
41713
41881
|
import {
|
|
41714
|
-
existsSync as
|
|
41882
|
+
existsSync as existsSync40,
|
|
41715
41883
|
mkdirSync as mkdirSync24,
|
|
41716
|
-
readFileSync as
|
|
41884
|
+
readFileSync as readFileSync28,
|
|
41717
41885
|
readSync,
|
|
41718
41886
|
closeSync,
|
|
41719
41887
|
readdirSync as readdirSync16,
|
|
@@ -41826,7 +41994,7 @@ function findMissingFrameRanges(totalFrames, framesDir, frameExt) {
|
|
|
41826
41994
|
let rangeStart = null;
|
|
41827
41995
|
for (let frameIndex = 0; frameIndex < totalFrames; frameIndex++) {
|
|
41828
41996
|
const framePath = join49(framesDir, `frame_${String(frameIndex).padStart(6, "0")}.${frameExt}`);
|
|
41829
|
-
const missing = !
|
|
41997
|
+
const missing = !existsSync40(framePath);
|
|
41830
41998
|
if (missing && rangeStart === null) {
|
|
41831
41999
|
rangeStart = frameIndex;
|
|
41832
42000
|
} else if (!missing && rangeStart !== null) {
|
|
@@ -41868,7 +42036,7 @@ function countCapturedFrames(totalFrames, framesDir, frameExt) {
|
|
|
41868
42036
|
let captured = 0;
|
|
41869
42037
|
for (let frameIndex = 0; frameIndex < totalFrames; frameIndex++) {
|
|
41870
42038
|
const framePath = join49(framesDir, `frame_${String(frameIndex).padStart(6, "0")}.${frameExt}`);
|
|
41871
|
-
if (
|
|
42039
|
+
if (existsSync40(framePath)) captured++;
|
|
41872
42040
|
}
|
|
41873
42041
|
return captured;
|
|
41874
42042
|
}
|
|
@@ -42354,7 +42522,7 @@ async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter,
|
|
|
42354
42522
|
function createRenderJob(config) {
|
|
42355
42523
|
return {
|
|
42356
42524
|
id: randomUUID2(),
|
|
42357
|
-
config,
|
|
42525
|
+
config: { ...config, fps: toFps(config.fps) },
|
|
42358
42526
|
status: "queued",
|
|
42359
42527
|
progress: 0,
|
|
42360
42528
|
currentStage: "Queued",
|
|
@@ -42439,28 +42607,28 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
42439
42607
|
};
|
|
42440
42608
|
job.startedAt = /* @__PURE__ */ new Date();
|
|
42441
42609
|
assertNotAborted();
|
|
42442
|
-
if (!
|
|
42610
|
+
if (!existsSync40(workDir)) mkdirSync24(workDir, { recursive: true });
|
|
42443
42611
|
if (job.config.debug) {
|
|
42444
42612
|
const logPath = join49(workDir, "render.log");
|
|
42445
42613
|
restoreLogger = installDebugLogger(logPath, log2);
|
|
42446
42614
|
}
|
|
42447
42615
|
const entryFile = job.config.entryFile || "index.html";
|
|
42448
42616
|
let htmlPath = join49(projectDir, entryFile);
|
|
42449
|
-
if (!
|
|
42617
|
+
if (!existsSync40(htmlPath)) {
|
|
42450
42618
|
throw new Error(`Entry file not found: ${htmlPath}`);
|
|
42451
42619
|
}
|
|
42452
42620
|
assertNotAborted();
|
|
42453
|
-
const rawEntry =
|
|
42621
|
+
const rawEntry = readFileSync28(htmlPath, "utf-8");
|
|
42454
42622
|
if (entryFile !== "index.html" && rawEntry.trimStart().startsWith("<template")) {
|
|
42455
42623
|
const wrapperPath = join49(workDir, "standalone-entry.html");
|
|
42456
42624
|
const projectIndexPath = join49(projectDir, "index.html");
|
|
42457
|
-
if (!
|
|
42625
|
+
if (!existsSync40(projectIndexPath)) {
|
|
42458
42626
|
throw new Error(
|
|
42459
42627
|
`Template entry file "${entryFile}" requires a project index.html to extract its render shell.`
|
|
42460
42628
|
);
|
|
42461
42629
|
}
|
|
42462
42630
|
const standaloneHtml = extractStandaloneEntryFromIndex(
|
|
42463
|
-
|
|
42631
|
+
readFileSync28(projectIndexPath, "utf-8"),
|
|
42464
42632
|
entryFile
|
|
42465
42633
|
);
|
|
42466
42634
|
if (!standaloneHtml) {
|
|
@@ -42571,7 +42739,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
42571
42739
|
assertNotAborted();
|
|
42572
42740
|
}
|
|
42573
42741
|
const framesDir = join49(workDir, "captured-frames");
|
|
42574
|
-
if (!
|
|
42742
|
+
if (!existsSync40(framesDir)) mkdirSync24(framesDir, { recursive: true });
|
|
42575
42743
|
const captureOptions = {
|
|
42576
42744
|
width,
|
|
42577
42745
|
height,
|
|
@@ -42826,7 +42994,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
42826
42994
|
job.outputPath = outputPath;
|
|
42827
42995
|
updateJobStatus(job, "complete", "Render complete", 100, onProgress);
|
|
42828
42996
|
const totalElapsed = Date.now() - pipelineStart;
|
|
42829
|
-
const tmpPeakBytes =
|
|
42997
|
+
const tmpPeakBytes = existsSync40(workDir) ? sampleDirectoryBytes(workDir) : 0;
|
|
42830
42998
|
const perfSummary = buildRenderPerfSummary({
|
|
42831
42999
|
job,
|
|
42832
43000
|
workerCount,
|
|
@@ -42861,7 +43029,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
42861
43029
|
}
|
|
42862
43030
|
}
|
|
42863
43031
|
if (job.config.debug) {
|
|
42864
|
-
if (!isPngSequence &&
|
|
43032
|
+
if (!isPngSequence && existsSync40(outputPath)) {
|
|
42865
43033
|
const debugOutput = join49(workDir, `output${videoExt}`);
|
|
42866
43034
|
copyFileSync4(outputPath, debugOutput);
|
|
42867
43035
|
}
|
|
@@ -42929,6 +43097,7 @@ var init_renderOrchestrator = __esm({
|
|
|
42929
43097
|
"../producer/src/services/renderOrchestrator.ts"() {
|
|
42930
43098
|
"use strict";
|
|
42931
43099
|
init_esm10();
|
|
43100
|
+
init_src();
|
|
42932
43101
|
init_src2();
|
|
42933
43102
|
init_fileServer2();
|
|
42934
43103
|
init_logger();
|
|
@@ -42987,7 +43156,7 @@ var init_config3 = __esm({
|
|
|
42987
43156
|
});
|
|
42988
43157
|
|
|
42989
43158
|
// ../producer/src/services/hyperframeLint.ts
|
|
42990
|
-
import { existsSync as
|
|
43159
|
+
import { existsSync as existsSync41, readFileSync as readFileSync29, statSync as statSync13 } from "fs";
|
|
42991
43160
|
import { resolve as resolve21, join as join50 } from "path";
|
|
42992
43161
|
function isStringRecord(value) {
|
|
42993
43162
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
@@ -43016,7 +43185,7 @@ function pickEntryFile(files, preferredEntryFile) {
|
|
|
43016
43185
|
}
|
|
43017
43186
|
function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
43018
43187
|
const absProjectDir = resolve21(projectDir);
|
|
43019
|
-
if (!
|
|
43188
|
+
if (!existsSync41(absProjectDir) || !statSync13(absProjectDir).isDirectory()) {
|
|
43020
43189
|
return { error: `Project directory not found: ${absProjectDir}` };
|
|
43021
43190
|
}
|
|
43022
43191
|
const entryCandidates = [preferredEntryFile, "index.html", "src/index.html"].filter(
|
|
@@ -43027,10 +43196,10 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
|
43027
43196
|
if (!absoluteEntryPath.startsWith(absProjectDir)) {
|
|
43028
43197
|
return { error: `Entry file must stay inside project directory: ${entryFile}` };
|
|
43029
43198
|
}
|
|
43030
|
-
if (
|
|
43199
|
+
if (existsSync41(absoluteEntryPath) && statSync13(absoluteEntryPath).isFile()) {
|
|
43031
43200
|
return {
|
|
43032
43201
|
entryFile,
|
|
43033
|
-
html:
|
|
43202
|
+
html: readFileSync29(absoluteEntryPath, "utf-8"),
|
|
43034
43203
|
source: "projectDir"
|
|
43035
43204
|
};
|
|
43036
43205
|
}
|
|
@@ -43125,7 +43294,7 @@ var init_semaphore = __esm({
|
|
|
43125
43294
|
|
|
43126
43295
|
// ../producer/src/server.ts
|
|
43127
43296
|
import {
|
|
43128
|
-
existsSync as
|
|
43297
|
+
existsSync as existsSync42,
|
|
43129
43298
|
mkdirSync as mkdirSync25,
|
|
43130
43299
|
statSync as statSync14,
|
|
43131
43300
|
mkdtempSync as mkdtempSync2,
|
|
@@ -43158,11 +43327,11 @@ async function prepareRenderBody(body) {
|
|
|
43158
43327
|
const projectDir = typeof body.projectDir === "string" ? body.projectDir : void 0;
|
|
43159
43328
|
if (projectDir) {
|
|
43160
43329
|
const absProjectDir = resolve22(projectDir);
|
|
43161
|
-
if (!
|
|
43330
|
+
if (!existsSync42(absProjectDir) || !statSync14(absProjectDir).isDirectory()) {
|
|
43162
43331
|
return { error: `Project directory not found: ${absProjectDir}` };
|
|
43163
43332
|
}
|
|
43164
43333
|
const entry = options.entryFile || "index.html";
|
|
43165
|
-
if (!
|
|
43334
|
+
if (!existsSync42(resolve22(absProjectDir, entry))) {
|
|
43166
43335
|
return { error: `Entry file "${entry}" not found in project directory: ${absProjectDir}` };
|
|
43167
43336
|
}
|
|
43168
43337
|
return { prepared: { input: { projectDir: absProjectDir, ...options } } };
|
|
@@ -43311,8 +43480,8 @@ function createRenderHandlers(options = {}) {
|
|
|
43311
43480
|
log2
|
|
43312
43481
|
);
|
|
43313
43482
|
const outputDir = dirname16(absoluteOutputPath);
|
|
43314
|
-
if (!
|
|
43315
|
-
const
|
|
43483
|
+
if (!existsSync42(outputDir)) mkdirSync25(outputDir, { recursive: true });
|
|
43484
|
+
const release4 = await renderSemaphore.acquire();
|
|
43316
43485
|
log2.info("render started", {
|
|
43317
43486
|
requestId,
|
|
43318
43487
|
projectDir: input.projectDir,
|
|
@@ -43338,7 +43507,7 @@ function createRenderHandlers(options = {}) {
|
|
|
43338
43507
|
log2.info(`render progress ${pct}%`, { requestId, stage: j3.currentStage, message });
|
|
43339
43508
|
}
|
|
43340
43509
|
});
|
|
43341
|
-
const fileSize =
|
|
43510
|
+
const fileSize = existsSync42(absoluteOutputPath) ? statSync14(absoluteOutputPath).size : 0;
|
|
43342
43511
|
const durationMs = Date.now() - t0;
|
|
43343
43512
|
const outputToken = store.register(absoluteOutputPath);
|
|
43344
43513
|
const outputUrl = `${outputUrlPrefix}/${outputToken}`;
|
|
@@ -43380,7 +43549,7 @@ function createRenderHandlers(options = {}) {
|
|
|
43380
43549
|
500
|
|
43381
43550
|
);
|
|
43382
43551
|
} finally {
|
|
43383
|
-
|
|
43552
|
+
release4();
|
|
43384
43553
|
cleanupTempDir(cleanupProjectDir, log2);
|
|
43385
43554
|
}
|
|
43386
43555
|
};
|
|
@@ -43422,7 +43591,7 @@ function createRenderHandlers(options = {}) {
|
|
|
43422
43591
|
log2
|
|
43423
43592
|
);
|
|
43424
43593
|
const outputDir = dirname16(absoluteOutputPath);
|
|
43425
|
-
if (!
|
|
43594
|
+
if (!existsSync42(outputDir)) mkdirSync25(outputDir, { recursive: true });
|
|
43426
43595
|
log2.info("render-stream started", { requestId, projectDir: input.projectDir });
|
|
43427
43596
|
const job = createRenderJob({
|
|
43428
43597
|
fps: input.fps,
|
|
@@ -43446,7 +43615,7 @@ function createRenderHandlers(options = {}) {
|
|
|
43446
43615
|
})
|
|
43447
43616
|
});
|
|
43448
43617
|
}
|
|
43449
|
-
const
|
|
43618
|
+
const release4 = await renderSemaphore.acquire();
|
|
43450
43619
|
try {
|
|
43451
43620
|
await executeRenderJob(
|
|
43452
43621
|
job,
|
|
@@ -43467,7 +43636,7 @@ function createRenderHandlers(options = {}) {
|
|
|
43467
43636
|
},
|
|
43468
43637
|
abortController.signal
|
|
43469
43638
|
);
|
|
43470
|
-
const fileSize =
|
|
43639
|
+
const fileSize = existsSync42(absoluteOutputPath) ? statSync14(absoluteOutputPath).size : 0;
|
|
43471
43640
|
const outputToken = store.register(absoluteOutputPath);
|
|
43472
43641
|
const outputUrl = `${outputUrlPrefix}/${outputToken}`;
|
|
43473
43642
|
log2.info("render-stream completed", { requestId, fileSize, perf: job.perfSummary ?? null });
|
|
@@ -43514,7 +43683,7 @@ function createRenderHandlers(options = {}) {
|
|
|
43514
43683
|
})
|
|
43515
43684
|
});
|
|
43516
43685
|
} finally {
|
|
43517
|
-
|
|
43686
|
+
release4();
|
|
43518
43687
|
c3.req.raw.signal.removeEventListener("abort", onRequestAbort);
|
|
43519
43688
|
cleanupTempDir(cleanupProjectDir, log2);
|
|
43520
43689
|
}
|
|
@@ -43526,7 +43695,7 @@ function createRenderHandlers(options = {}) {
|
|
|
43526
43695
|
if (!artifact) {
|
|
43527
43696
|
return c3.json({ success: false, error: "Output artifact not found or expired" }, 404);
|
|
43528
43697
|
}
|
|
43529
|
-
if (!
|
|
43698
|
+
if (!existsSync42(artifact.path)) {
|
|
43530
43699
|
store.delete(token);
|
|
43531
43700
|
return c3.json({ success: false, error: "Output artifact file missing" }, 404);
|
|
43532
43701
|
}
|
|
@@ -43680,7 +43849,7 @@ var init_planHash = __esm({
|
|
|
43680
43849
|
});
|
|
43681
43850
|
|
|
43682
43851
|
// ../producer/src/services/render/stages/freezePlan.ts
|
|
43683
|
-
import { existsSync as
|
|
43852
|
+
import { existsSync as existsSync43, mkdirSync as mkdirSync26, readFileSync as readFileSync30, readdirSync as readdirSync17, writeFileSync as writeFileSync20 } from "fs";
|
|
43684
43853
|
import { join as join52, relative as relative5, resolve as resolve23 } from "path";
|
|
43685
43854
|
function stripUndefined(value) {
|
|
43686
43855
|
if (Array.isArray(value)) return value.map(stripUndefined);
|
|
@@ -43723,11 +43892,11 @@ function collectPlanAssetShas(planDir) {
|
|
|
43723
43892
|
const assets = [];
|
|
43724
43893
|
for (const file of files) {
|
|
43725
43894
|
if (file.planRelativePath === COMPILED_INDEX_RELATIVE_PATH) {
|
|
43726
|
-
compositionHtml =
|
|
43895
|
+
compositionHtml = readFileSync30(file.absolutePath);
|
|
43727
43896
|
continue;
|
|
43728
43897
|
}
|
|
43729
43898
|
if (HASH_EXCLUDED_PLAN_FILES.has(file.planRelativePath)) continue;
|
|
43730
|
-
const bytes =
|
|
43899
|
+
const bytes = readFileSync30(file.absolutePath);
|
|
43731
43900
|
assets.push({ path: file.planRelativePath, sha256: sha256Hex(bytes) });
|
|
43732
43901
|
}
|
|
43733
43902
|
if (compositionHtml === null) {
|
|
@@ -43740,14 +43909,14 @@ function collectPlanAssetShas(planDir) {
|
|
|
43740
43909
|
function recomputePlanHashFromPlanDir(planDir) {
|
|
43741
43910
|
const planJsonPath = join52(planDir, "plan.json");
|
|
43742
43911
|
const encoderJsonPath = join52(planDir, "meta", "encoder.json");
|
|
43743
|
-
if (!
|
|
43912
|
+
if (!existsSync43(planJsonPath)) {
|
|
43744
43913
|
throw new Error(`[freezePlan] plan.json missing: ${planJsonPath}`);
|
|
43745
43914
|
}
|
|
43746
|
-
if (!
|
|
43915
|
+
if (!existsSync43(encoderJsonPath)) {
|
|
43747
43916
|
throw new Error(`[freezePlan] meta/encoder.json missing: ${encoderJsonPath}`);
|
|
43748
43917
|
}
|
|
43749
|
-
const planJson = JSON.parse(
|
|
43750
|
-
const encoderConfigCanonicalJson =
|
|
43918
|
+
const planJson = JSON.parse(readFileSync30(planJsonPath, "utf-8"));
|
|
43919
|
+
const encoderConfigCanonicalJson = readFileSync30(encoderJsonPath, "utf-8");
|
|
43751
43920
|
const { compositionHtml, assets } = collectPlanAssetShas(planDir);
|
|
43752
43921
|
return computePlanHash({
|
|
43753
43922
|
compositionHtml,
|
|
@@ -43772,11 +43941,11 @@ async function freezePlan(input) {
|
|
|
43772
43941
|
totalFrames,
|
|
43773
43942
|
hasAudio
|
|
43774
43943
|
} = input;
|
|
43775
|
-
if (!
|
|
43944
|
+
if (!existsSync43(planDir)) {
|
|
43776
43945
|
throw new Error(`[freezePlan] planDir does not exist: ${planDir}`);
|
|
43777
43946
|
}
|
|
43778
43947
|
const metaDir = join52(planDir, "meta");
|
|
43779
|
-
if (!
|
|
43948
|
+
if (!existsSync43(metaDir)) mkdirSync26(metaDir, { recursive: true });
|
|
43780
43949
|
writeFileSync20(
|
|
43781
43950
|
join52(metaDir, "composition.json"),
|
|
43782
43951
|
`${JSON.stringify(composition, null, 2)}
|
|
@@ -43918,7 +44087,7 @@ var init_runtimeEnvSnapshot = __esm({
|
|
|
43918
44087
|
// ../producer/src/services/distributed/shared.ts
|
|
43919
44088
|
import { execFile as execFileCallback } from "child_process";
|
|
43920
44089
|
import { dirname as dirname17, join as join53 } from "path";
|
|
43921
|
-
import { existsSync as
|
|
44090
|
+
import { existsSync as existsSync44, readFileSync as readFileSync31 } from "fs";
|
|
43922
44091
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
43923
44092
|
import { promisify as promisify2 } from "util";
|
|
43924
44093
|
async function readFfmpegVersion() {
|
|
@@ -43956,9 +44125,9 @@ function readProducerVersion() {
|
|
|
43956
44125
|
let current = startDir;
|
|
43957
44126
|
for (let i2 = 0; i2 < 10; i2++) {
|
|
43958
44127
|
const candidate = join53(current, "package.json");
|
|
43959
|
-
if (
|
|
44128
|
+
if (existsSync44(candidate)) {
|
|
43960
44129
|
try {
|
|
43961
|
-
const pkg = JSON.parse(
|
|
44130
|
+
const pkg = JSON.parse(readFileSync31(candidate, "utf-8"));
|
|
43962
44131
|
if (pkg.name === "@hyperframes/producer" && typeof pkg.version === "string") {
|
|
43963
44132
|
cachedProducerVersion = pkg.version;
|
|
43964
44133
|
return pkg.version;
|
|
@@ -43989,7 +44158,7 @@ var init_shared2 = __esm({
|
|
|
43989
44158
|
// ../producer/src/services/distributed/plan.ts
|
|
43990
44159
|
import {
|
|
43991
44160
|
cpSync as cpSync2,
|
|
43992
|
-
existsSync as
|
|
44161
|
+
existsSync as existsSync45,
|
|
43993
44162
|
mkdirSync as mkdirSync27,
|
|
43994
44163
|
readdirSync as readdirSync18,
|
|
43995
44164
|
renameSync as renameSync3,
|
|
@@ -44154,7 +44323,7 @@ async function plan(projectDir, config, planDir) {
|
|
|
44154
44323
|
useGpu: false,
|
|
44155
44324
|
browserGpuMode: "software"
|
|
44156
44325
|
});
|
|
44157
|
-
if (!
|
|
44326
|
+
if (!existsSync45(planDir)) mkdirSync27(planDir, { recursive: true });
|
|
44158
44327
|
const log2 = config.logger ?? defaultLogger;
|
|
44159
44328
|
const abortSignal = config.abortSignal;
|
|
44160
44329
|
const assertNotAborted = () => {
|
|
@@ -44183,11 +44352,11 @@ async function plan(projectDir, config, planDir) {
|
|
|
44183
44352
|
});
|
|
44184
44353
|
const entryFile = config.entryFile ?? "index.html";
|
|
44185
44354
|
const htmlPath = join54(projectDir, entryFile);
|
|
44186
|
-
if (!
|
|
44355
|
+
if (!existsSync45(htmlPath)) {
|
|
44187
44356
|
throw new Error(`[plan] entry file not found: ${htmlPath}`);
|
|
44188
44357
|
}
|
|
44189
44358
|
const workDir = join54(planDir, ".plan-work");
|
|
44190
|
-
if (!
|
|
44359
|
+
if (!existsSync45(workDir)) mkdirSync27(workDir, { recursive: true });
|
|
44191
44360
|
const compiledDir = join54(workDir, "compiled");
|
|
44192
44361
|
mkdirSync27(compiledDir, { recursive: true });
|
|
44193
44362
|
cpSync2(projectDir, compiledDir, {
|
|
@@ -44273,13 +44442,13 @@ async function plan(projectDir, config, planDir) {
|
|
|
44273
44442
|
});
|
|
44274
44443
|
const stagedVideoFrames = join54(compiledDir, "__hyperframes_video_frames");
|
|
44275
44444
|
const videoFramesDst = join54(planDir, "video-frames");
|
|
44276
|
-
if (
|
|
44277
|
-
if (
|
|
44445
|
+
if (existsSync45(videoFramesDst)) rmSync11(videoFramesDst, { recursive: true, force: true });
|
|
44446
|
+
if (existsSync45(stagedVideoFrames)) {
|
|
44278
44447
|
renameSync3(stagedVideoFrames, videoFramesDst);
|
|
44279
44448
|
} else {
|
|
44280
44449
|
mkdirSync27(videoFramesDst, { recursive: true });
|
|
44281
44450
|
}
|
|
44282
|
-
if (
|
|
44451
|
+
if (existsSync45(finalCompiledDir)) rmSync11(finalCompiledDir, { recursive: true, force: true });
|
|
44283
44452
|
renameSync3(compiledDir, finalCompiledDir);
|
|
44284
44453
|
const planVideosJson = {
|
|
44285
44454
|
videos: composition.videos,
|
|
@@ -44299,7 +44468,7 @@ async function plan(projectDir, config, planDir) {
|
|
|
44299
44468
|
"utf-8"
|
|
44300
44469
|
);
|
|
44301
44470
|
const planAudioPath = join54(planDir, "audio.aac");
|
|
44302
|
-
if (audioResult.hasAudio &&
|
|
44471
|
+
if (audioResult.hasAudio && existsSync45(audioResult.audioOutputPath)) {
|
|
44303
44472
|
renameSync3(audioResult.audioOutputPath, planAudioPath);
|
|
44304
44473
|
}
|
|
44305
44474
|
const maxParallel = config.maxParallelChunks ?? DEFAULT_MAX_PARALLEL_CHUNKS;
|
|
@@ -44438,13 +44607,13 @@ var init_plan = __esm({
|
|
|
44438
44607
|
|
|
44439
44608
|
// ../producer/src/services/distributed/renderChunk.ts
|
|
44440
44609
|
import { randomBytes } from "crypto";
|
|
44441
|
-
import { existsSync as
|
|
44610
|
+
import { existsSync as existsSync46, mkdirSync as mkdirSync28, readFileSync as readFileSync32, readdirSync as readdirSync19, rmSync as rmSync12, writeFileSync as writeFileSync22 } from "fs";
|
|
44442
44611
|
import { extname as extname9, join as join55 } from "path";
|
|
44443
44612
|
function rebuildExtractedFramesFromPlanDir(planDir, videos) {
|
|
44444
44613
|
const result = [];
|
|
44445
44614
|
for (const v2 of videos) {
|
|
44446
44615
|
const outputDir = join55(planDir, "video-frames", v2.videoId);
|
|
44447
|
-
if (!
|
|
44616
|
+
if (!existsSync46(outputDir)) {
|
|
44448
44617
|
throw new Error(
|
|
44449
44618
|
`[renderChunk] planDir missing extracted video frames for ${JSON.stringify(v2.videoId)}: ${outputDir} not present. plan() should have written frames here; the planDir is malformed.`
|
|
44450
44619
|
);
|
|
@@ -44477,10 +44646,10 @@ function rebuildExtractedFramesFromPlanDir(planDir, videos) {
|
|
|
44477
44646
|
return result;
|
|
44478
44647
|
}
|
|
44479
44648
|
function hashChunkOutput(outputPath, kind) {
|
|
44480
|
-
if (kind === "file") return sha256Hex(
|
|
44649
|
+
if (kind === "file") return sha256Hex(readFileSync32(outputPath));
|
|
44481
44650
|
const entries2 = readdirSync19(outputPath).filter((name) => /\.(png|jpg|jpeg)$/i.test(name)).sort();
|
|
44482
44651
|
const lines = entries2.map(
|
|
44483
|
-
(name) => `${name}\0${sha256Hex(
|
|
44652
|
+
(name) => `${name}\0${sha256Hex(readFileSync32(join55(outputPath, name)))}`
|
|
44484
44653
|
);
|
|
44485
44654
|
return sha256Hex(lines.join("\0"));
|
|
44486
44655
|
}
|
|
@@ -44497,21 +44666,21 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
44497
44666
|
const encoderJsonPath = join55(planDir, "meta", "encoder.json");
|
|
44498
44667
|
const chunksJsonPath = join55(planDir, "meta", "chunks.json");
|
|
44499
44668
|
for (const required of [planJsonPath, encoderJsonPath, chunksJsonPath]) {
|
|
44500
|
-
if (!
|
|
44669
|
+
if (!existsSync46(required)) {
|
|
44501
44670
|
throw new RenderChunkValidationError(
|
|
44502
44671
|
MISSING_PLAN_ARTIFACT,
|
|
44503
44672
|
`[renderChunk] planDir is missing required artifact: ${required}`
|
|
44504
44673
|
);
|
|
44505
44674
|
}
|
|
44506
44675
|
}
|
|
44507
|
-
const plan2 = JSON.parse(
|
|
44508
|
-
const encoder = JSON.parse(
|
|
44509
|
-
const chunks = JSON.parse(
|
|
44676
|
+
const plan2 = JSON.parse(readFileSync32(planJsonPath, "utf-8"));
|
|
44677
|
+
const encoder = JSON.parse(readFileSync32(encoderJsonPath, "utf-8"));
|
|
44678
|
+
const chunks = JSON.parse(readFileSync32(chunksJsonPath, "utf-8"));
|
|
44510
44679
|
const videosJsonPath = join55(planDir, PLAN_VIDEOS_META_RELATIVE_PATH);
|
|
44511
44680
|
let planVideos = null;
|
|
44512
|
-
if (
|
|
44681
|
+
if (existsSync46(videosJsonPath)) {
|
|
44513
44682
|
try {
|
|
44514
|
-
planVideos = JSON.parse(
|
|
44683
|
+
planVideos = JSON.parse(readFileSync32(videosJsonPath, "utf-8"));
|
|
44515
44684
|
} catch (err) {
|
|
44516
44685
|
throw new RenderChunkValidationError(
|
|
44517
44686
|
MISSING_PLAN_ARTIFACT,
|
|
@@ -44537,7 +44706,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
44537
44706
|
);
|
|
44538
44707
|
}
|
|
44539
44708
|
const compiledDir = join55(planDir, "compiled");
|
|
44540
|
-
if (!
|
|
44709
|
+
if (!existsSync46(compiledDir)) {
|
|
44541
44710
|
throw new RenderChunkValidationError(
|
|
44542
44711
|
MISSING_PLAN_ARTIFACT,
|
|
44543
44712
|
`[renderChunk] planDir missing compiled/ directory: ${compiledDir}`
|
|
@@ -44661,10 +44830,10 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
44661
44830
|
const effectiveBitrate = encoder.crf != null ? void 0 : encoder.bitrate;
|
|
44662
44831
|
const videoOnlyPath = outputChunkPath;
|
|
44663
44832
|
if (isPngSequence) {
|
|
44664
|
-
if (!
|
|
44833
|
+
if (!existsSync46(outputChunkPath)) mkdirSync28(outputChunkPath, { recursive: true });
|
|
44665
44834
|
} else {
|
|
44666
44835
|
const outDir = join55(outputChunkPath, "..");
|
|
44667
|
-
if (!
|
|
44836
|
+
if (!existsSync46(outDir)) mkdirSync28(outDir, { recursive: true });
|
|
44668
44837
|
}
|
|
44669
44838
|
await runEncodeStage({
|
|
44670
44839
|
job,
|
|
@@ -44985,9 +45154,9 @@ var init_audioPadTrim = __esm({
|
|
|
44985
45154
|
// ../producer/src/services/distributed/assemble.ts
|
|
44986
45155
|
import {
|
|
44987
45156
|
cpSync as cpSync3,
|
|
44988
|
-
existsSync as
|
|
45157
|
+
existsSync as existsSync47,
|
|
44989
45158
|
mkdirSync as mkdirSync29,
|
|
44990
|
-
readFileSync as
|
|
45159
|
+
readFileSync as readFileSync33,
|
|
44991
45160
|
readdirSync as readdirSync20,
|
|
44992
45161
|
rmSync as rmSync13,
|
|
44993
45162
|
statSync as statSync16,
|
|
@@ -45000,32 +45169,32 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
45000
45169
|
const abortSignal = options?.abortSignal;
|
|
45001
45170
|
const planJsonPath = join56(planDir, "plan.json");
|
|
45002
45171
|
const chunksJsonPath = join56(planDir, "meta", "chunks.json");
|
|
45003
|
-
if (!
|
|
45172
|
+
if (!existsSync47(planJsonPath)) {
|
|
45004
45173
|
throw new Error(`[assemble] planDir missing plan.json: ${planJsonPath}`);
|
|
45005
45174
|
}
|
|
45006
|
-
if (!
|
|
45175
|
+
if (!existsSync47(chunksJsonPath)) {
|
|
45007
45176
|
throw new Error(`[assemble] planDir missing meta/chunks.json: ${chunksJsonPath}`);
|
|
45008
45177
|
}
|
|
45009
|
-
const plan2 = JSON.parse(
|
|
45010
|
-
const chunks = JSON.parse(
|
|
45178
|
+
const plan2 = JSON.parse(readFileSync33(planJsonPath, "utf-8"));
|
|
45179
|
+
const chunks = JSON.parse(readFileSync33(chunksJsonPath, "utf-8"));
|
|
45011
45180
|
if (chunkPaths.length !== chunks.length) {
|
|
45012
45181
|
throw new Error(
|
|
45013
45182
|
`[assemble] chunkPaths length (${chunkPaths.length}) does not match chunks.json length (${chunks.length}). Adapters must pass one path per chunk, ordered by index.`
|
|
45014
45183
|
);
|
|
45015
45184
|
}
|
|
45016
45185
|
for (const path2 of chunkPaths) {
|
|
45017
|
-
if (!
|
|
45186
|
+
if (!existsSync47(path2)) {
|
|
45018
45187
|
throw new Error(`[assemble] chunk path does not exist: ${path2}`);
|
|
45019
45188
|
}
|
|
45020
45189
|
}
|
|
45021
45190
|
if (plan2.dimensions.format === "png-sequence") {
|
|
45022
45191
|
return mergePngFrameDirs(chunkPaths, outputPath, plan2.totalFrames, audioPath, start);
|
|
45023
45192
|
}
|
|
45024
|
-
if (!
|
|
45193
|
+
if (!existsSync47(dirname18(outputPath))) {
|
|
45025
45194
|
mkdirSync29(dirname18(outputPath), { recursive: true });
|
|
45026
45195
|
}
|
|
45027
45196
|
const workDir = `${outputPath}.assemble-work`;
|
|
45028
|
-
if (
|
|
45197
|
+
if (existsSync47(workDir)) rmSync13(workDir, { recursive: true, force: true });
|
|
45029
45198
|
mkdirSync29(workDir, { recursive: true });
|
|
45030
45199
|
try {
|
|
45031
45200
|
const concatListPath = join56(workDir, "concat-list.txt");
|
|
@@ -45052,7 +45221,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
45052
45221
|
);
|
|
45053
45222
|
}
|
|
45054
45223
|
let audioForMux = null;
|
|
45055
|
-
if (audioPath !== null &&
|
|
45224
|
+
if (audioPath !== null && existsSync47(audioPath)) {
|
|
45056
45225
|
const paddedAudioPath = join56(workDir, "audio-padded.aac");
|
|
45057
45226
|
const padTrimResult = await padOrTrimAudioToVideoFrameCount({
|
|
45058
45227
|
videoPath: concatOutputPath,
|
|
@@ -45095,7 +45264,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
45095
45264
|
});
|
|
45096
45265
|
}
|
|
45097
45266
|
}
|
|
45098
|
-
const fileSize =
|
|
45267
|
+
const fileSize = existsSync47(outputPath) ? statSync16(outputPath).size : 0;
|
|
45099
45268
|
return {
|
|
45100
45269
|
outputPath,
|
|
45101
45270
|
durationMs: Date.now() - start,
|
|
@@ -45104,7 +45273,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
45104
45273
|
};
|
|
45105
45274
|
}
|
|
45106
45275
|
function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, startTimeMs) {
|
|
45107
|
-
if (
|
|
45276
|
+
if (existsSync47(outputPath)) rmSync13(outputPath, { recursive: true, force: true });
|
|
45108
45277
|
mkdirSync29(outputPath, { recursive: true });
|
|
45109
45278
|
let globalIdx = 0;
|
|
45110
45279
|
for (const chunkDir of chunkPaths) {
|
|
@@ -45128,7 +45297,7 @@ function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, start
|
|
|
45128
45297
|
`[assemble] png-sequence frame count mismatch: merged ${globalIdx} frames vs plan.totalFrames=${totalFrames}. Using on-disk count.`
|
|
45129
45298
|
);
|
|
45130
45299
|
}
|
|
45131
|
-
if (audioPath !== null &&
|
|
45300
|
+
if (audioPath !== null && existsSync47(audioPath)) {
|
|
45132
45301
|
const sidecar = join56(outputPath, "audio.aac");
|
|
45133
45302
|
cpSync3(audioPath, sidecar);
|
|
45134
45303
|
}
|
|
@@ -45221,7 +45390,7 @@ __export(studioServer_exports, {
|
|
|
45221
45390
|
});
|
|
45222
45391
|
import { Hono as Hono5 } from "hono";
|
|
45223
45392
|
import { streamSSE as streamSSE3 } from "hono/streaming";
|
|
45224
|
-
import { existsSync as
|
|
45393
|
+
import { existsSync as existsSync48, readFileSync as readFileSync34, writeFileSync as writeFileSync24, statSync as statSync17 } from "fs";
|
|
45225
45394
|
import { resolve as resolve24, join as join57, basename as basename5 } from "path";
|
|
45226
45395
|
function resolveDistDir() {
|
|
45227
45396
|
return resolveStudioBundle().dir;
|
|
@@ -45229,12 +45398,12 @@ function resolveDistDir() {
|
|
|
45229
45398
|
function resolveStudioBundle() {
|
|
45230
45399
|
const builtPath = resolve24(__dirname, "studio");
|
|
45231
45400
|
const builtIndex = resolve24(builtPath, "index.html");
|
|
45232
|
-
if (
|
|
45401
|
+
if (existsSync48(builtIndex)) {
|
|
45233
45402
|
return { dir: builtPath, indexPath: builtIndex, available: true, checkedPaths: [builtIndex] };
|
|
45234
45403
|
}
|
|
45235
45404
|
const devPath = resolve24(__dirname, "..", "..", "..", "studio", "dist");
|
|
45236
45405
|
const devIndex = resolve24(devPath, "index.html");
|
|
45237
|
-
if (
|
|
45406
|
+
if (existsSync48(devIndex)) {
|
|
45238
45407
|
return {
|
|
45239
45408
|
dir: devPath,
|
|
45240
45409
|
indexPath: devIndex,
|
|
@@ -45251,9 +45420,9 @@ function resolveStudioBundle() {
|
|
|
45251
45420
|
}
|
|
45252
45421
|
function resolveRuntimePath() {
|
|
45253
45422
|
const builtPath = resolve24(__dirname, "hyperframe-runtime.js");
|
|
45254
|
-
if (
|
|
45423
|
+
if (existsSync48(builtPath)) return builtPath;
|
|
45255
45424
|
const iifePath = resolve24(__dirname, "hyperframe.runtime.iife.js");
|
|
45256
|
-
if (
|
|
45425
|
+
if (existsSync48(iifePath)) return iifePath;
|
|
45257
45426
|
const devPath = resolve24(
|
|
45258
45427
|
__dirname,
|
|
45259
45428
|
"..",
|
|
@@ -45263,14 +45432,14 @@ function resolveRuntimePath() {
|
|
|
45263
45432
|
"dist",
|
|
45264
45433
|
"hyperframe.runtime.iife.js"
|
|
45265
45434
|
);
|
|
45266
|
-
if (
|
|
45435
|
+
if (existsSync48(devPath)) return devPath;
|
|
45267
45436
|
return builtPath;
|
|
45268
45437
|
}
|
|
45269
45438
|
function readStudioManualEditManifestContent(projectDir) {
|
|
45270
45439
|
const manifestPath = join57(projectDir, STUDIO_MANUAL_EDITS_PATH2);
|
|
45271
|
-
if (!
|
|
45440
|
+
if (!existsSync48(manifestPath)) return "";
|
|
45272
45441
|
try {
|
|
45273
|
-
return
|
|
45442
|
+
return readFileSync34(manifestPath, "utf-8");
|
|
45274
45443
|
} catch {
|
|
45275
45444
|
return "";
|
|
45276
45445
|
}
|
|
@@ -45511,19 +45680,19 @@ function createStudioServer(options) {
|
|
|
45511
45680
|
async installRegistryBlock(opts) {
|
|
45512
45681
|
const { resolveItem: resolveItem2 } = await Promise.resolve().then(() => (init_resolver(), resolver_exports));
|
|
45513
45682
|
const { installItem: installItem2 } = await Promise.resolve().then(() => (init_installer(), installer_exports));
|
|
45514
|
-
const { readFileSync:
|
|
45515
|
-
const { join:
|
|
45683
|
+
const { readFileSync: readFileSync57, writeFileSync: writeFileSync39, existsSync: existsSync81 } = await import("fs");
|
|
45684
|
+
const { join: join90 } = await import("path");
|
|
45516
45685
|
const item = await resolveItem2(opts.blockName);
|
|
45517
45686
|
const { written } = await installItem2(item, { destDir: opts.project.dir });
|
|
45518
|
-
const indexPath =
|
|
45519
|
-
if (
|
|
45520
|
-
const indexHtml =
|
|
45687
|
+
const indexPath = join90(opts.project.dir, "index.html");
|
|
45688
|
+
if (existsSync81(indexPath)) {
|
|
45689
|
+
const indexHtml = readFileSync57(indexPath, "utf-8");
|
|
45521
45690
|
const hostW = indexHtml.match(/data-width="(\d+)"/)?.[1];
|
|
45522
45691
|
const hostH = indexHtml.match(/data-height="(\d+)"/)?.[1];
|
|
45523
45692
|
if (hostW && hostH) {
|
|
45524
45693
|
for (const absPath of written) {
|
|
45525
45694
|
if (!absPath.endsWith(".html")) continue;
|
|
45526
|
-
let content =
|
|
45695
|
+
let content = readFileSync57(absPath, "utf-8");
|
|
45527
45696
|
content = content.replace(
|
|
45528
45697
|
/(<meta\s+name="viewport"\s+content="width=)\d+(,\s*height=)\d+/i,
|
|
45529
45698
|
`$1${hostW}$2${hostH}`
|
|
@@ -45559,7 +45728,7 @@ function createStudioServer(options) {
|
|
|
45559
45728
|
});
|
|
45560
45729
|
app.get("/api/runtime.js", (c3) => {
|
|
45561
45730
|
const serve4 = async () => {
|
|
45562
|
-
const runtimeSource = await loadRuntimeSource() ?? (
|
|
45731
|
+
const runtimeSource = await loadRuntimeSource() ?? (existsSync48(runtimePath) ? readFileSync34(runtimePath, "utf-8") : null);
|
|
45563
45732
|
if (!runtimeSource) return c3.text("runtime not available", 404);
|
|
45564
45733
|
return c3.body(runtimeSource, 200, {
|
|
45565
45734
|
"Content-Type": "text/javascript",
|
|
@@ -45595,8 +45764,8 @@ function createStudioServer(options) {
|
|
|
45595
45764
|
});
|
|
45596
45765
|
const serveStudioStaticFile = (c3) => {
|
|
45597
45766
|
const filePath = resolve24(studioDir, c3.req.path.slice(1));
|
|
45598
|
-
if (!
|
|
45599
|
-
const content =
|
|
45767
|
+
if (!existsSync48(filePath) || !statSync17(filePath).isFile()) return c3.text("not found", 404);
|
|
45768
|
+
const content = readFileSync34(filePath);
|
|
45600
45769
|
return new Response(content, {
|
|
45601
45770
|
headers: { "Content-Type": getMimeType(filePath), "Cache-Control": "no-store" }
|
|
45602
45771
|
});
|
|
@@ -45616,7 +45785,7 @@ function createStudioServer(options) {
|
|
|
45616
45785
|
}
|
|
45617
45786
|
app.get("*", (c3) => {
|
|
45618
45787
|
const indexPath = resolve24(studioDir, "index.html");
|
|
45619
|
-
if (!
|
|
45788
|
+
if (!existsSync48(indexPath)) {
|
|
45620
45789
|
return c3.html(
|
|
45621
45790
|
`<!doctype html>
|
|
45622
45791
|
<html>
|
|
@@ -45672,7 +45841,7 @@ function createStudioServer(options) {
|
|
|
45672
45841
|
500
|
|
45673
45842
|
);
|
|
45674
45843
|
}
|
|
45675
|
-
let html =
|
|
45844
|
+
let html = readFileSync34(indexPath, "utf-8");
|
|
45676
45845
|
const envScript = buildRuntimeEnvScript();
|
|
45677
45846
|
if (envScript) {
|
|
45678
45847
|
html = html.replace("<head>", `<head>${envScript}`);
|
|
@@ -45704,7 +45873,7 @@ __export(preview_exports, {
|
|
|
45704
45873
|
examples: () => examples
|
|
45705
45874
|
});
|
|
45706
45875
|
import { spawn as spawn11 } from "child_process";
|
|
45707
|
-
import { existsSync as
|
|
45876
|
+
import { existsSync as existsSync49, lstatSync as lstatSync2, symlinkSync as symlinkSync2, unlinkSync as unlinkSync5, readlinkSync, mkdirSync as mkdirSync30 } from "fs";
|
|
45708
45877
|
import { resolve as resolve25, dirname as dirname19, basename as basename6, join as join58 } from "path";
|
|
45709
45878
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
45710
45879
|
import { createRequire as createRequire2 } from "module";
|
|
@@ -45717,7 +45886,7 @@ async function runDevMode(dir, options) {
|
|
|
45717
45886
|
mkdirSync30(projectsDir, { recursive: true });
|
|
45718
45887
|
let createdSymlink = false;
|
|
45719
45888
|
if (dir !== symlinkPath) {
|
|
45720
|
-
if (
|
|
45889
|
+
if (existsSync49(symlinkPath)) {
|
|
45721
45890
|
try {
|
|
45722
45891
|
const stat3 = lstatSync2(symlinkPath);
|
|
45723
45892
|
if (stat3.isSymbolicLink()) {
|
|
@@ -45729,7 +45898,7 @@ async function runDevMode(dir, options) {
|
|
|
45729
45898
|
} catch {
|
|
45730
45899
|
}
|
|
45731
45900
|
}
|
|
45732
|
-
if (!
|
|
45901
|
+
if (!existsSync49(symlinkPath)) {
|
|
45733
45902
|
symlinkSync2(dir, symlinkPath, "dir");
|
|
45734
45903
|
createdSymlink = true;
|
|
45735
45904
|
}
|
|
@@ -45775,7 +45944,7 @@ async function runDevMode(dir, options) {
|
|
|
45775
45944
|
if (createdSymlink) {
|
|
45776
45945
|
process.on("exit", () => {
|
|
45777
45946
|
try {
|
|
45778
|
-
if (
|
|
45947
|
+
if (existsSync49(symlinkPath)) unlinkSync5(symlinkPath);
|
|
45779
45948
|
} catch {
|
|
45780
45949
|
}
|
|
45781
45950
|
});
|
|
@@ -45802,12 +45971,12 @@ async function runLocalStudioMode(dir, options) {
|
|
|
45802
45971
|
mkdirSync30(projectsDir, { recursive: true });
|
|
45803
45972
|
let createdSymlink = false;
|
|
45804
45973
|
if (dir !== symlinkPath) {
|
|
45805
|
-
if (
|
|
45974
|
+
if (existsSync49(symlinkPath) && lstatSync2(symlinkPath).isSymbolicLink()) {
|
|
45806
45975
|
if (resolve25(readlinkSync(symlinkPath)) !== resolve25(dir)) {
|
|
45807
45976
|
unlinkSync5(symlinkPath);
|
|
45808
45977
|
}
|
|
45809
45978
|
}
|
|
45810
|
-
if (!
|
|
45979
|
+
if (!existsSync49(symlinkPath)) {
|
|
45811
45980
|
symlinkSync2(dir, symlinkPath, "dir");
|
|
45812
45981
|
createdSymlink = true;
|
|
45813
45982
|
}
|
|
@@ -45850,7 +46019,7 @@ async function runLocalStudioMode(dir, options) {
|
|
|
45850
46019
|
if (createdSymlink) {
|
|
45851
46020
|
process.on("exit", () => {
|
|
45852
46021
|
try {
|
|
45853
|
-
if (
|
|
46022
|
+
if (existsSync49(symlinkPath)) unlinkSync5(symlinkPath);
|
|
45854
46023
|
} catch {
|
|
45855
46024
|
}
|
|
45856
46025
|
});
|
|
@@ -46051,7 +46220,7 @@ var init_preview2 = __esm({
|
|
|
46051
46220
|
const isImplicitCwd = !rawArg || rawArg === "." || rawArg === "./";
|
|
46052
46221
|
const projectName = isImplicitCwd ? basename6(process.env.PWD ?? dir) : basename6(dir);
|
|
46053
46222
|
const indexPath = join58(dir, "index.html");
|
|
46054
|
-
if (
|
|
46223
|
+
if (existsSync49(indexPath)) {
|
|
46055
46224
|
const project = { dir, name: projectName, indexPath };
|
|
46056
46225
|
const lintResult = lintProject(project);
|
|
46057
46226
|
if (lintResult.totalErrors > 0 || lintResult.totalWarnings > 0) {
|
|
@@ -46096,12 +46265,12 @@ __export(init_exports, {
|
|
|
46096
46265
|
injectTailwindBrowserScript: () => injectTailwindBrowserScript
|
|
46097
46266
|
});
|
|
46098
46267
|
import {
|
|
46099
|
-
existsSync as
|
|
46268
|
+
existsSync as existsSync50,
|
|
46100
46269
|
mkdirSync as mkdirSync31,
|
|
46101
46270
|
copyFileSync as copyFileSync5,
|
|
46102
46271
|
cpSync as cpSync4,
|
|
46103
46272
|
writeFileSync as writeFileSync25,
|
|
46104
|
-
readFileSync as
|
|
46273
|
+
readFileSync as readFileSync35,
|
|
46105
46274
|
readdirSync as readdirSync21
|
|
46106
46275
|
} from "fs";
|
|
46107
46276
|
import { resolve as resolve26, basename as basename7, join as join59, dirname as dirname20 } from "path";
|
|
@@ -46176,7 +46345,7 @@ function resolveAssetDir(devSegments, builtSegments) {
|
|
|
46176
46345
|
const base = dirname20(fileURLToPath7(import.meta.url));
|
|
46177
46346
|
const devPath = resolve26(base, ...devSegments);
|
|
46178
46347
|
const builtPath = resolve26(base, ...builtSegments);
|
|
46179
|
-
return
|
|
46348
|
+
return existsSync50(devPath) ? devPath : builtPath;
|
|
46180
46349
|
}
|
|
46181
46350
|
function getStaticTemplateDir(templateId) {
|
|
46182
46351
|
return resolveAssetDir(["..", "templates", templateId], ["templates", templateId]);
|
|
@@ -46204,7 +46373,7 @@ function buildPackageScripts() {
|
|
|
46204
46373
|
}
|
|
46205
46374
|
function writeDefaultPackageJson(destDir, projectName) {
|
|
46206
46375
|
const packageJsonPath = resolve26(destDir, "package.json");
|
|
46207
|
-
if (
|
|
46376
|
+
if (existsSync50(packageJsonPath)) return;
|
|
46208
46377
|
writeFileSync25(
|
|
46209
46378
|
packageJsonPath,
|
|
46210
46379
|
`${JSON.stringify(
|
|
@@ -46266,14 +46435,14 @@ ${html}`;
|
|
|
46266
46435
|
}
|
|
46267
46436
|
function writeTailwindSupport(destDir) {
|
|
46268
46437
|
for (const file of listHtmlFiles(destDir)) {
|
|
46269
|
-
const html =
|
|
46438
|
+
const html = readFileSync35(file, "utf-8");
|
|
46270
46439
|
writeFileSync25(file, injectTailwindBrowserScript(html), "utf-8");
|
|
46271
46440
|
}
|
|
46272
46441
|
}
|
|
46273
46442
|
function patchVideoSrc(dir, videoFilename, durationSeconds) {
|
|
46274
46443
|
const htmlFiles = readdirSync21(dir, { withFileTypes: true, recursive: true }).filter((e3) => e3.isFile() && e3.name.endsWith(".html")).map((e3) => join59(e3.parentPath, e3.name));
|
|
46275
46444
|
for (const file of htmlFiles) {
|
|
46276
|
-
let content =
|
|
46445
|
+
let content = readFileSync35(file, "utf-8");
|
|
46277
46446
|
if (videoFilename) {
|
|
46278
46447
|
content = content.replaceAll("__VIDEO_SRC__", videoFilename);
|
|
46279
46448
|
} else {
|
|
@@ -46378,7 +46547,7 @@ async function handleVideoFile(videoPath, destDir, interactive) {
|
|
|
46378
46547
|
function applyResolutionPreset(destDir, resolution) {
|
|
46379
46548
|
const { width, height } = CANVAS_DIMENSIONS[resolution];
|
|
46380
46549
|
for (const file of listHtmlFiles(destDir)) {
|
|
46381
|
-
let html =
|
|
46550
|
+
let html = readFileSync35(file, "utf-8");
|
|
46382
46551
|
let changed = false;
|
|
46383
46552
|
const dataWidthRe = /(data-width=)["'](\d+)["']/g;
|
|
46384
46553
|
if (dataWidthRe.test(html)) {
|
|
@@ -46426,7 +46595,7 @@ function applyResolutionPreset(destDir, resolution) {
|
|
|
46426
46595
|
async function scaffoldProject(destDir, name, templateId, localVideoName, durationSeconds, tailwind = false, resolution) {
|
|
46427
46596
|
mkdirSync31(destDir, { recursive: true });
|
|
46428
46597
|
const templateDir = getStaticTemplateDir(templateId);
|
|
46429
|
-
if (
|
|
46598
|
+
if (existsSync50(join59(templateDir, "index.html"))) {
|
|
46430
46599
|
cpSync4(templateDir, destDir, { recursive: true });
|
|
46431
46600
|
} else {
|
|
46432
46601
|
await fetchRemoteTemplate(templateId, destDir);
|
|
@@ -46447,13 +46616,13 @@ async function scaffoldProject(destDir, name, templateId, localVideoName, durati
|
|
|
46447
46616
|
),
|
|
46448
46617
|
"utf-8"
|
|
46449
46618
|
);
|
|
46450
|
-
if (!
|
|
46619
|
+
if (!existsSync50(resolve26(destDir, "hyperframes.json"))) {
|
|
46451
46620
|
const { writeProjectConfig: writeProjectConfig2, DEFAULT_PROJECT_CONFIG: DEFAULT_PROJECT_CONFIG2 } = await Promise.resolve().then(() => (init_projectConfig(), projectConfig_exports));
|
|
46452
46621
|
writeProjectConfig2(destDir, DEFAULT_PROJECT_CONFIG2);
|
|
46453
46622
|
}
|
|
46454
46623
|
writeDefaultPackageJson(destDir, name);
|
|
46455
46624
|
const sharedDir = getSharedTemplateDir();
|
|
46456
|
-
if (
|
|
46625
|
+
if (existsSync50(sharedDir)) {
|
|
46457
46626
|
for (const entry of readdirSync21(sharedDir, { withFileTypes: true })) {
|
|
46458
46627
|
const src = join59(sharedDir, entry.name);
|
|
46459
46628
|
const dest = resolve26(destDir, entry.name);
|
|
@@ -46613,7 +46782,7 @@ var init_init = __esm({
|
|
|
46613
46782
|
const templateId2 = exampleFlag ?? "blank";
|
|
46614
46783
|
const name2 = args.name ?? "my-video";
|
|
46615
46784
|
const destDir2 = resolve26(name2);
|
|
46616
|
-
if (
|
|
46785
|
+
if (existsSync50(destDir2) && readdirSync21(destDir2).length > 0) {
|
|
46617
46786
|
console.error(c2.error(`Directory already exists and is not empty: ${name2}`));
|
|
46618
46787
|
process.exit(1);
|
|
46619
46788
|
}
|
|
@@ -46627,7 +46796,7 @@ var init_init = __esm({
|
|
|
46627
46796
|
}
|
|
46628
46797
|
if (videoFlag) {
|
|
46629
46798
|
const videoPath = resolve26(videoFlag);
|
|
46630
|
-
if (!
|
|
46799
|
+
if (!existsSync50(videoPath)) {
|
|
46631
46800
|
console.error(c2.error(`Video file not found: ${videoFlag}`));
|
|
46632
46801
|
process.exit(1);
|
|
46633
46802
|
}
|
|
@@ -46641,7 +46810,7 @@ var init_init = __esm({
|
|
|
46641
46810
|
}
|
|
46642
46811
|
if (audioFlag) {
|
|
46643
46812
|
const audioPath = resolve26(audioFlag);
|
|
46644
|
-
if (!
|
|
46813
|
+
if (!existsSync50(audioPath)) {
|
|
46645
46814
|
console.error(c2.error(`Audio file not found: ${audioFlag}`));
|
|
46646
46815
|
process.exit(1);
|
|
46647
46816
|
}
|
|
@@ -46689,7 +46858,7 @@ var init_init = __esm({
|
|
|
46689
46858
|
}
|
|
46690
46859
|
trackInitTemplate(templateId2, { tailwind });
|
|
46691
46860
|
const transcriptFile2 = resolve26(destDir2, "transcript.json");
|
|
46692
|
-
if (
|
|
46861
|
+
if (existsSync50(transcriptFile2)) {
|
|
46693
46862
|
await patchTranscript(destDir2, transcriptFile2);
|
|
46694
46863
|
}
|
|
46695
46864
|
console.log(c2.success(`Created ${c2.accent(name2 + "/")}`));
|
|
@@ -46744,7 +46913,7 @@ var init_init = __esm({
|
|
|
46744
46913
|
name = nameResult;
|
|
46745
46914
|
}
|
|
46746
46915
|
const destDir = resolve26(name);
|
|
46747
|
-
if (
|
|
46916
|
+
if (existsSync50(destDir) && readdirSync21(destDir).length > 0) {
|
|
46748
46917
|
const overwrite = await ue({
|
|
46749
46918
|
message: `Directory ${c2.accent(name)} already exists and is not empty. Overwrite?`,
|
|
46750
46919
|
initialValue: false
|
|
@@ -46759,7 +46928,7 @@ var init_init = __esm({
|
|
|
46759
46928
|
let videoDuration;
|
|
46760
46929
|
if (videoFlag) {
|
|
46761
46930
|
const videoPath = resolve26(videoFlag);
|
|
46762
|
-
if (!
|
|
46931
|
+
if (!existsSync50(videoPath)) {
|
|
46763
46932
|
R2.error(`File not found: ${videoFlag}`);
|
|
46764
46933
|
me("Setup cancelled.");
|
|
46765
46934
|
process.exit(1);
|
|
@@ -46771,7 +46940,7 @@ var init_init = __esm({
|
|
|
46771
46940
|
videoDuration = result.meta.durationSeconds;
|
|
46772
46941
|
} else if (audioFlag) {
|
|
46773
46942
|
const audioPath = resolve26(audioFlag);
|
|
46774
|
-
if (!
|
|
46943
|
+
if (!existsSync50(audioPath)) {
|
|
46775
46944
|
R2.error(`File not found: ${audioFlag}`);
|
|
46776
46945
|
me("Setup cancelled.");
|
|
46777
46946
|
process.exit(1);
|
|
@@ -46872,7 +47041,7 @@ ${c2.dim("Use --example blank for offline use.")}`
|
|
|
46872
47041
|
}
|
|
46873
47042
|
trackInitTemplate(templateId, { tailwind });
|
|
46874
47043
|
const transcriptFile = resolve26(destDir, "transcript.json");
|
|
46875
|
-
if (
|
|
47044
|
+
if (existsSync50(transcriptFile)) {
|
|
46876
47045
|
await patchTranscript(destDir, transcriptFile);
|
|
46877
47046
|
}
|
|
46878
47047
|
const files = readdirSync21(destDir);
|
|
@@ -46904,9 +47073,9 @@ ${c2.dim("Use --example blank for offline use.")}`
|
|
|
46904
47073
|
|
|
46905
47074
|
// src/utils/clipboard.ts
|
|
46906
47075
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
46907
|
-
import { platform as
|
|
47076
|
+
import { platform as platform6 } from "os";
|
|
46908
47077
|
function detectProvider() {
|
|
46909
|
-
const os =
|
|
47078
|
+
const os = platform6();
|
|
46910
47079
|
if (os === "darwin") {
|
|
46911
47080
|
return { cmd: "pbcopy", args: [] };
|
|
46912
47081
|
}
|
|
@@ -46958,7 +47127,7 @@ __export(add_exports, {
|
|
|
46958
47127
|
remapTarget: () => remapTarget,
|
|
46959
47128
|
runAdd: () => runAdd
|
|
46960
47129
|
});
|
|
46961
|
-
import { existsSync as
|
|
47130
|
+
import { existsSync as existsSync51 } from "fs";
|
|
46962
47131
|
import { resolve as resolve27, relative as relative7 } from "path";
|
|
46963
47132
|
function remapTarget(item, originalTarget, paths) {
|
|
46964
47133
|
if (item.type === "hyperframes:block") {
|
|
@@ -46984,8 +47153,8 @@ function buildSnippet(item, relativeTarget) {
|
|
|
46984
47153
|
async function runAdd(opts) {
|
|
46985
47154
|
const projectDir = resolve27(opts.projectDir);
|
|
46986
47155
|
let config = loadProjectConfig(projectDir);
|
|
46987
|
-
const hasConfig =
|
|
46988
|
-
if (!hasConfig &&
|
|
47156
|
+
const hasConfig = existsSync51(projectConfigPath(projectDir));
|
|
47157
|
+
if (!hasConfig && existsSync51(resolve27(projectDir, "index.html"))) {
|
|
46989
47158
|
writeProjectConfig(projectDir, DEFAULT_PROJECT_CONFIG);
|
|
46990
47159
|
config = DEFAULT_PROJECT_CONFIG;
|
|
46991
47160
|
}
|
|
@@ -47087,10 +47256,10 @@ var init_add = __esm({
|
|
|
47087
47256
|
const projectDir = resolve27(args.dir ?? process.cwd());
|
|
47088
47257
|
const json = args.json === true;
|
|
47089
47258
|
const skipClipboard = args["no-clipboard"] === true;
|
|
47090
|
-
const hasConfigBefore =
|
|
47259
|
+
const hasConfigBefore = existsSync51(projectConfigPath(projectDir));
|
|
47091
47260
|
try {
|
|
47092
47261
|
const result = await runAdd({ name: args.name, projectDir, skipClipboard });
|
|
47093
|
-
const wroteConfig = !hasConfigBefore &&
|
|
47262
|
+
const wroteConfig = !hasConfigBefore && existsSync51(projectConfigPath(projectDir));
|
|
47094
47263
|
if (json) {
|
|
47095
47264
|
console.log(JSON.stringify(result));
|
|
47096
47265
|
return;
|
|
@@ -47120,7 +47289,7 @@ var init_add = __esm({
|
|
|
47120
47289
|
process.exit(1);
|
|
47121
47290
|
}
|
|
47122
47291
|
let config = loadProjectConfig(projectDir);
|
|
47123
|
-
if (!
|
|
47292
|
+
if (!existsSync51(projectConfigPath(projectDir)) && existsSync51(resolve27(projectDir, "index.html"))) {
|
|
47124
47293
|
writeProjectConfig(projectDir, DEFAULT_PROJECT_CONFIG);
|
|
47125
47294
|
config = DEFAULT_PROJECT_CONFIG;
|
|
47126
47295
|
}
|
|
@@ -47340,17 +47509,17 @@ var init_format = __esm({
|
|
|
47340
47509
|
});
|
|
47341
47510
|
|
|
47342
47511
|
// src/utils/project.ts
|
|
47343
|
-
import { existsSync as
|
|
47512
|
+
import { existsSync as existsSync52, statSync as statSync18 } from "fs";
|
|
47344
47513
|
import { resolve as resolve29, basename as basename8 } from "path";
|
|
47345
47514
|
function resolveProject(dirArg) {
|
|
47346
47515
|
const dir = resolve29(dirArg ?? ".");
|
|
47347
47516
|
const name = basename8(dir);
|
|
47348
47517
|
const indexPath = resolve29(dir, "index.html");
|
|
47349
|
-
if (!
|
|
47518
|
+
if (!existsSync52(dir) || !statSync18(dir).isDirectory()) {
|
|
47350
47519
|
errorBox("Not a directory: " + dir);
|
|
47351
47520
|
process.exit(1);
|
|
47352
47521
|
}
|
|
47353
|
-
if (!
|
|
47522
|
+
if (!existsSync52(indexPath)) {
|
|
47354
47523
|
errorBox(
|
|
47355
47524
|
"No composition found in " + dir,
|
|
47356
47525
|
"No index.html file found.",
|
|
@@ -47373,7 +47542,7 @@ __export(play_exports, {
|
|
|
47373
47542
|
default: () => play_default,
|
|
47374
47543
|
examples: () => examples5
|
|
47375
47544
|
});
|
|
47376
|
-
import { existsSync as
|
|
47545
|
+
import { existsSync as existsSync53, readFileSync as readFileSync36 } from "fs";
|
|
47377
47546
|
import { resolve as resolve30, dirname as dirname21 } from "path";
|
|
47378
47547
|
function commandDir() {
|
|
47379
47548
|
return dirname21(new URL(import.meta.url).pathname);
|
|
@@ -47388,7 +47557,7 @@ function resolveRuntimePath2() {
|
|
|
47388
47557
|
resolve30(d2, "..", "..", "..", "core", "dist", "hyperframe.runtime.iife.js")
|
|
47389
47558
|
];
|
|
47390
47559
|
for (const p2 of candidates) {
|
|
47391
|
-
if (
|
|
47560
|
+
if (existsSync53(p2)) return p2;
|
|
47392
47561
|
}
|
|
47393
47562
|
return null;
|
|
47394
47563
|
}
|
|
@@ -47402,7 +47571,7 @@ function resolvePlayerPath() {
|
|
|
47402
47571
|
resolve30(d2, "..", "hyperframes-player.global.js")
|
|
47403
47572
|
];
|
|
47404
47573
|
for (const p2 of candidates) {
|
|
47405
|
-
if (
|
|
47574
|
+
if (existsSync53(p2)) return p2;
|
|
47406
47575
|
}
|
|
47407
47576
|
return null;
|
|
47408
47577
|
}
|
|
@@ -47512,13 +47681,13 @@ var init_play = __esm({
|
|
|
47512
47681
|
const { createAdaptorServer } = await import("@hono/node-server");
|
|
47513
47682
|
const app = new Hono6();
|
|
47514
47683
|
app.get("/player.js", (ctx) => {
|
|
47515
|
-
return ctx.body(
|
|
47684
|
+
return ctx.body(readFileSync36(playerPath, "utf-8"), 200, {
|
|
47516
47685
|
"Content-Type": "application/javascript",
|
|
47517
47686
|
"Cache-Control": "no-cache"
|
|
47518
47687
|
});
|
|
47519
47688
|
});
|
|
47520
47689
|
app.get("/runtime.js", (ctx) => {
|
|
47521
|
-
return ctx.body(
|
|
47690
|
+
return ctx.body(readFileSync36(runtimePath, "utf-8"), 200, {
|
|
47522
47691
|
"Content-Type": "application/javascript",
|
|
47523
47692
|
"Cache-Control": "no-cache"
|
|
47524
47693
|
});
|
|
@@ -47527,8 +47696,8 @@ var init_play = __esm({
|
|
|
47527
47696
|
const reqPath = ctx.req.path.replace("/composition/", "");
|
|
47528
47697
|
const filePath = resolve30(project.dir, reqPath);
|
|
47529
47698
|
if (!filePath.startsWith(project.dir)) return ctx.text("Forbidden", 403);
|
|
47530
|
-
if (!
|
|
47531
|
-
const content =
|
|
47699
|
+
if (!existsSync53(filePath)) return ctx.text("Not found", 404);
|
|
47700
|
+
const content = readFileSync36(filePath, "utf-8");
|
|
47532
47701
|
if (filePath.endsWith(".html")) {
|
|
47533
47702
|
const injected = injectRuntime(content);
|
|
47534
47703
|
return ctx.html(injected);
|
|
@@ -47547,7 +47716,7 @@ var init_play = __esm({
|
|
|
47547
47716
|
mp3: "audio/mpeg",
|
|
47548
47717
|
wav: "audio/wav"
|
|
47549
47718
|
};
|
|
47550
|
-
return ctx.body(
|
|
47719
|
+
return ctx.body(readFileSync36(filePath), 200, {
|
|
47551
47720
|
"Content-Type": types3[ext] ?? "application/octet-stream"
|
|
47552
47721
|
});
|
|
47553
47722
|
});
|
|
@@ -47608,7 +47777,7 @@ var init_play = __esm({
|
|
|
47608
47777
|
|
|
47609
47778
|
// src/utils/publishProject.ts
|
|
47610
47779
|
import { basename as basename9, join as join60, relative as relative8 } from "path";
|
|
47611
|
-
import { readdirSync as readdirSync22, readFileSync as
|
|
47780
|
+
import { readdirSync as readdirSync22, readFileSync as readFileSync37, statSync as statSync19 } from "fs";
|
|
47612
47781
|
import AdmZip from "adm-zip";
|
|
47613
47782
|
function isRecord2(value) {
|
|
47614
47783
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -47727,7 +47896,7 @@ function createPublishArchive(projectDir) {
|
|
|
47727
47896
|
}
|
|
47728
47897
|
const archive = new AdmZip();
|
|
47729
47898
|
for (const filePath of filePaths) {
|
|
47730
|
-
archive.addFile(filePath,
|
|
47899
|
+
archive.addFile(filePath, readFileSync37(join60(projectDir, filePath)));
|
|
47731
47900
|
}
|
|
47732
47901
|
return {
|
|
47733
47902
|
buffer: archive.toBuffer(),
|
|
@@ -47848,7 +48017,7 @@ __export(publish_exports, {
|
|
|
47848
48017
|
examples: () => examples6
|
|
47849
48018
|
});
|
|
47850
48019
|
import { basename as basename10, resolve as resolve31 } from "path";
|
|
47851
|
-
import { existsSync as
|
|
48020
|
+
import { existsSync as existsSync54 } from "fs";
|
|
47852
48021
|
import { join as join61 } from "path";
|
|
47853
48022
|
var examples6, publish_default;
|
|
47854
48023
|
var init_publish = __esm({
|
|
@@ -47885,7 +48054,7 @@ var init_publish = __esm({
|
|
|
47885
48054
|
const isImplicitCwd = !rawArg || rawArg === "." || rawArg === "./";
|
|
47886
48055
|
const projectName = isImplicitCwd ? basename10(process.env["PWD"] ?? dir) : basename10(dir);
|
|
47887
48056
|
const indexPath = join61(dir, "index.html");
|
|
47888
|
-
if (
|
|
48057
|
+
if (existsSync54(indexPath)) {
|
|
47889
48058
|
const lintResult = lintProject({ dir, name: projectName, indexPath });
|
|
47890
48059
|
if (lintResult.totalErrors > 0 || lintResult.totalWarnings > 0) {
|
|
47891
48060
|
console.log();
|
|
@@ -47955,9 +48124,9 @@ var init_dom = __esm({
|
|
|
47955
48124
|
});
|
|
47956
48125
|
|
|
47957
48126
|
// src/utils/variables.ts
|
|
47958
|
-
import { readFileSync as
|
|
48127
|
+
import { readFileSync as readFileSync38 } from "fs";
|
|
47959
48128
|
import { resolve as resolve32 } from "path";
|
|
47960
|
-
function parseVariablesArg(inline, filePath, readFile = (p2) =>
|
|
48129
|
+
function parseVariablesArg(inline, filePath, readFile = (p2) => readFileSync38(resolve32(p2), "utf8")) {
|
|
47961
48130
|
if (inline != null && filePath != null) {
|
|
47962
48131
|
return { ok: false, error: { kind: "conflict" } };
|
|
47963
48132
|
}
|
|
@@ -48040,7 +48209,7 @@ function validateVariablesAgainstProject(indexPath, values) {
|
|
|
48040
48209
|
function loadProjectVariableSchema(indexPath) {
|
|
48041
48210
|
let html;
|
|
48042
48211
|
try {
|
|
48043
|
-
html =
|
|
48212
|
+
html = readFileSync38(indexPath, "utf8");
|
|
48044
48213
|
} catch {
|
|
48045
48214
|
return [];
|
|
48046
48215
|
}
|
|
@@ -48207,7 +48376,7 @@ __export(render_exports, {
|
|
|
48207
48376
|
renderLocal: () => renderLocal,
|
|
48208
48377
|
resolveBrowserGpuForCli: () => resolveBrowserGpuForCli
|
|
48209
48378
|
});
|
|
48210
|
-
import { mkdirSync as mkdirSync32, readdirSync as readdirSync23, readFileSync as
|
|
48379
|
+
import { mkdirSync as mkdirSync32, readdirSync as readdirSync23, readFileSync as readFileSync39, statSync as statSync20, writeFileSync as writeFileSync26, rmSync as rmSync14 } from "fs";
|
|
48211
48380
|
import { cpus as cpus4, freemem as freemem4, tmpdir as tmpdir5 } from "os";
|
|
48212
48381
|
import { resolve as resolve33, dirname as dirname22, join as join62, basename as basename11 } from "path";
|
|
48213
48382
|
import { execFileSync as execFileSync6, spawn as spawn13 } from "child_process";
|
|
@@ -48268,7 +48437,7 @@ function ensureDockerImage(version, quiet) {
|
|
|
48268
48437
|
const dockerfilePath = resolveDockerfilePath();
|
|
48269
48438
|
const tmpDir = join62(tmpdir5(), `hyperframes-docker-${Date.now()}`);
|
|
48270
48439
|
mkdirSync32(tmpDir, { recursive: true });
|
|
48271
|
-
writeFileSync26(join62(tmpDir, "Dockerfile"),
|
|
48440
|
+
writeFileSync26(join62(tmpDir, "Dockerfile"), readFileSync39(dockerfilePath));
|
|
48272
48441
|
try {
|
|
48273
48442
|
execFileSync6(
|
|
48274
48443
|
"docker",
|
|
@@ -49127,7 +49296,7 @@ var init_lint3 = __esm({
|
|
|
49127
49296
|
|
|
49128
49297
|
// src/utils/staticProjectServer.ts
|
|
49129
49298
|
import { createServer } from "http";
|
|
49130
|
-
import { existsSync as
|
|
49299
|
+
import { existsSync as existsSync55, readFileSync as readFileSync40 } from "fs";
|
|
49131
49300
|
import { isAbsolute as isAbsolute8, relative as relative9, resolve as resolve34 } from "path";
|
|
49132
49301
|
async function serveStaticProjectHtml(projectDir, html, bindErrorMessage = "Failed to bind local HTTP server") {
|
|
49133
49302
|
const server = createServer((req, res) => {
|
|
@@ -49144,9 +49313,9 @@ async function serveStaticProjectHtml(projectDir, html, bindErrorMessage = "Fail
|
|
|
49144
49313
|
res.end();
|
|
49145
49314
|
return;
|
|
49146
49315
|
}
|
|
49147
|
-
if (
|
|
49316
|
+
if (existsSync55(filePath)) {
|
|
49148
49317
|
res.writeHead(200, { "Content-Type": getMimeType(filePath) });
|
|
49149
|
-
res.end(
|
|
49318
|
+
res.end(readFileSync40(filePath));
|
|
49150
49319
|
return;
|
|
49151
49320
|
}
|
|
49152
49321
|
res.writeHead(404);
|
|
@@ -49322,7 +49491,7 @@ __export(layout_exports, {
|
|
|
49322
49491
|
default: () => layout_default,
|
|
49323
49492
|
examples: () => examples9
|
|
49324
49493
|
});
|
|
49325
|
-
import { existsSync as
|
|
49494
|
+
import { existsSync as existsSync56, readFileSync as readFileSync41 } from "fs";
|
|
49326
49495
|
import { dirname as dirname23, join as join63 } from "path";
|
|
49327
49496
|
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
49328
49497
|
async function getCompositionDuration2(page) {
|
|
@@ -49473,7 +49642,7 @@ function loadLayoutAuditScript() {
|
|
|
49473
49642
|
join63(__dirname2, "commands", "layout-audit.browser.js")
|
|
49474
49643
|
];
|
|
49475
49644
|
for (const candidate of candidates) {
|
|
49476
|
-
if (
|
|
49645
|
+
if (existsSync56(candidate)) return readFileSync41(candidate, "utf-8");
|
|
49477
49646
|
}
|
|
49478
49647
|
throw new Error("Missing layout audit browser script");
|
|
49479
49648
|
}
|
|
@@ -49681,7 +49850,7 @@ __export(info_exports, {
|
|
|
49681
49850
|
default: () => info_default,
|
|
49682
49851
|
examples: () => examples11
|
|
49683
49852
|
});
|
|
49684
|
-
import { readFileSync as
|
|
49853
|
+
import { readFileSync as readFileSync42, readdirSync as readdirSync24, statSync as statSync21 } from "fs";
|
|
49685
49854
|
import { join as join64 } from "path";
|
|
49686
49855
|
function totalSize(dir) {
|
|
49687
49856
|
let total = 0;
|
|
@@ -49718,7 +49887,7 @@ var init_info = __esm({
|
|
|
49718
49887
|
},
|
|
49719
49888
|
async run({ args }) {
|
|
49720
49889
|
const project = resolveProject(args.dir);
|
|
49721
|
-
const html =
|
|
49890
|
+
const html = readFileSync42(project.indexPath, "utf-8");
|
|
49722
49891
|
ensureDOMParser();
|
|
49723
49892
|
const parsed = parseHtml(html);
|
|
49724
49893
|
const tracks = new Set(parsed.elements.map((el) => el.zIndex));
|
|
@@ -49776,7 +49945,7 @@ __export(compositions_exports, {
|
|
|
49776
49945
|
examples: () => examples12,
|
|
49777
49946
|
parseSubComposition: () => parseSubComposition
|
|
49778
49947
|
});
|
|
49779
|
-
import { existsSync as
|
|
49948
|
+
import { existsSync as existsSync57, readFileSync as readFileSync43 } from "fs";
|
|
49780
49949
|
import { resolve as resolve35, dirname as dirname24 } from "path";
|
|
49781
49950
|
function countRenderableDescendants(root) {
|
|
49782
49951
|
return Array.from(root.querySelectorAll("*")).filter(
|
|
@@ -49810,8 +49979,8 @@ function parseCompositions(html, baseDir) {
|
|
|
49810
49979
|
const compositionSrc = div.getAttribute("data-composition-src");
|
|
49811
49980
|
if (compositionSrc) {
|
|
49812
49981
|
const subPath = resolve35(baseDir, compositionSrc);
|
|
49813
|
-
if (
|
|
49814
|
-
const subHtml =
|
|
49982
|
+
if (existsSync57(subPath)) {
|
|
49983
|
+
const subHtml = readFileSync43(subPath, "utf-8");
|
|
49815
49984
|
const subInfo = parseSubComposition(subHtml, id, width, height);
|
|
49816
49985
|
compositions.push({ ...subInfo, source: compositionSrc });
|
|
49817
49986
|
return;
|
|
@@ -49914,7 +50083,7 @@ var init_compositions = __esm({
|
|
|
49914
50083
|
},
|
|
49915
50084
|
async run({ args }) {
|
|
49916
50085
|
const project = resolveProject(args.dir);
|
|
49917
|
-
const html =
|
|
50086
|
+
const html = readFileSync43(project.indexPath, "utf-8");
|
|
49918
50087
|
ensureDOMParser();
|
|
49919
50088
|
const compositions = parseCompositions(html, dirname24(project.indexPath));
|
|
49920
50089
|
if (compositions.length === 0) {
|
|
@@ -49952,7 +50121,7 @@ __export(benchmark_exports, {
|
|
|
49952
50121
|
default: () => benchmark_default,
|
|
49953
50122
|
examples: () => examples13
|
|
49954
50123
|
});
|
|
49955
|
-
import { existsSync as
|
|
50124
|
+
import { existsSync as existsSync58, statSync as statSync22 } from "fs";
|
|
49956
50125
|
import { resolve as resolve36, join as join65 } from "path";
|
|
49957
50126
|
var examples13, FPS_30, FPS_60, DEFAULT_CONFIGS, benchmark_default;
|
|
49958
50127
|
var init_benchmark = __esm({
|
|
@@ -50045,7 +50214,7 @@ var init_benchmark = __esm({
|
|
|
50045
50214
|
await producer.executeRenderJob(job, project.dir, outputPath);
|
|
50046
50215
|
const elapsedMs = Date.now() - startTime;
|
|
50047
50216
|
let fileSize = null;
|
|
50048
|
-
if (
|
|
50217
|
+
if (existsSync58(outputPath)) {
|
|
50049
50218
|
const stat3 = statSync22(outputPath);
|
|
50050
50219
|
fileSize = stat3.size;
|
|
50051
50220
|
}
|
|
@@ -50299,8 +50468,8 @@ __export(manager_exports3, {
|
|
|
50299
50468
|
modelPath: () => modelPath,
|
|
50300
50469
|
selectProviders: () => selectProviders
|
|
50301
50470
|
});
|
|
50302
|
-
import { existsSync as
|
|
50303
|
-
import { homedir as homedir9, platform as
|
|
50471
|
+
import { existsSync as existsSync59, mkdirSync as mkdirSync33 } from "fs";
|
|
50472
|
+
import { homedir as homedir9, platform as platform7, arch } from "os";
|
|
50304
50473
|
import { join as join66 } from "path";
|
|
50305
50474
|
function isDevice(value) {
|
|
50306
50475
|
return typeof value === "string" && DEVICES.includes(value);
|
|
@@ -50326,7 +50495,7 @@ function selectProviders(device = "auto") {
|
|
|
50326
50495
|
}
|
|
50327
50496
|
return { providers: ["cuda", "cpu"], label: "CUDA" };
|
|
50328
50497
|
}
|
|
50329
|
-
if (hasCoreML &&
|
|
50498
|
+
if (hasCoreML && platform7() === "darwin" && arch() === "arm64") {
|
|
50330
50499
|
return { providers: ["coreml", "cpu"], label: "CoreML" };
|
|
50331
50500
|
}
|
|
50332
50501
|
if (hasCUDA) return { providers: ["cuda", "cpu"], label: "CUDA" };
|
|
@@ -50335,7 +50504,7 @@ function selectProviders(device = "auto") {
|
|
|
50335
50504
|
function listAvailableProviders() {
|
|
50336
50505
|
if (_cachedProviders) return _cachedProviders;
|
|
50337
50506
|
const out = ["cpu"];
|
|
50338
|
-
if (
|
|
50507
|
+
if (platform7() === "darwin" && arch() === "arm64") out.push("coreml");
|
|
50339
50508
|
if (process.env["HYPERFRAMES_CUDA"] === "1") out.push("cuda");
|
|
50340
50509
|
_cachedProviders = out;
|
|
50341
50510
|
return out;
|
|
@@ -50345,11 +50514,11 @@ function modelPath(model = DEFAULT_MODEL2) {
|
|
|
50345
50514
|
}
|
|
50346
50515
|
async function ensureModel2(model = DEFAULT_MODEL2, options) {
|
|
50347
50516
|
const dest = modelPath(model);
|
|
50348
|
-
if (
|
|
50517
|
+
if (existsSync59(dest)) return dest;
|
|
50349
50518
|
mkdirSync33(MODELS_DIR2, { recursive: true });
|
|
50350
50519
|
options?.onProgress?.(`Downloading ${model} weights (~168 MB)...`);
|
|
50351
50520
|
await downloadFile(MODEL_URLS[model], dest);
|
|
50352
|
-
if (!
|
|
50521
|
+
if (!existsSync59(dest)) {
|
|
50353
50522
|
throw new Error(`Model download failed: ${model}`);
|
|
50354
50523
|
}
|
|
50355
50524
|
return dest;
|
|
@@ -50830,12 +50999,12 @@ __export(remove_background_exports, {
|
|
|
50830
50999
|
examples: () => examples15
|
|
50831
51000
|
});
|
|
50832
51001
|
import { resolve as resolve37 } from "path";
|
|
50833
|
-
import { existsSync as
|
|
51002
|
+
import { existsSync as existsSync60 } from "fs";
|
|
50834
51003
|
async function showInfo(json) {
|
|
50835
51004
|
const { selectProviders: selectProviders2, listAvailableProviders: listAvailableProviders2, DEFAULT_MODEL: DEFAULT_MODEL4, MODEL_MEMORY_MB: MODEL_MEMORY_MB2, modelPath: modelPath2 } = await Promise.resolve().then(() => (init_manager3(), manager_exports3));
|
|
50836
51005
|
const providers = listAvailableProviders2();
|
|
50837
51006
|
const auto = selectProviders2("auto");
|
|
50838
|
-
const cached2 =
|
|
51007
|
+
const cached2 = existsSync60(modelPath2());
|
|
50839
51008
|
if (json) {
|
|
50840
51009
|
console.log(
|
|
50841
51010
|
JSON.stringify({
|
|
@@ -51042,7 +51211,7 @@ __export(transcribe_exports2, {
|
|
|
51042
51211
|
default: () => transcribe_default,
|
|
51043
51212
|
examples: () => examples16
|
|
51044
51213
|
});
|
|
51045
|
-
import { existsSync as
|
|
51214
|
+
import { existsSync as existsSync61, writeFileSync as writeFileSync27 } from "fs";
|
|
51046
51215
|
import { resolve as resolve38, join as join67, extname as extname11, dirname as dirname25 } from "path";
|
|
51047
51216
|
async function importTranscript(inputPath, dir, json) {
|
|
51048
51217
|
const { loadTranscript: loadTranscript2, patchCaptionHtml: patchCaptionHtml2 } = await Promise.resolve().then(() => (init_normalize(), normalize_exports));
|
|
@@ -51168,7 +51337,7 @@ var init_transcribe2 = __esm({
|
|
|
51168
51337
|
},
|
|
51169
51338
|
async run({ args }) {
|
|
51170
51339
|
const inputPath = resolve38(args.input);
|
|
51171
|
-
if (!
|
|
51340
|
+
if (!existsSync61(inputPath)) {
|
|
51172
51341
|
console.error(c2.error(`File not found: ${args.input}`));
|
|
51173
51342
|
process.exit(1);
|
|
51174
51343
|
}
|
|
@@ -51189,7 +51358,7 @@ var init_transcribe2 = __esm({
|
|
|
51189
51358
|
});
|
|
51190
51359
|
|
|
51191
51360
|
// src/tts/manager.ts
|
|
51192
|
-
import { existsSync as
|
|
51361
|
+
import { existsSync as existsSync62, mkdirSync as mkdirSync34 } from "fs";
|
|
51193
51362
|
import { homedir as homedir10 } from "os";
|
|
51194
51363
|
import { join as join68 } from "path";
|
|
51195
51364
|
function inferLangFromVoiceId(voiceId) {
|
|
@@ -51201,7 +51370,7 @@ function isSupportedLang(value) {
|
|
|
51201
51370
|
}
|
|
51202
51371
|
async function ensureModel3(model = DEFAULT_MODEL3, options) {
|
|
51203
51372
|
const modelPath2 = join68(MODELS_DIR3, `${model}.onnx`);
|
|
51204
|
-
if (
|
|
51373
|
+
if (existsSync62(modelPath2)) return modelPath2;
|
|
51205
51374
|
const url = MODEL_URLS2[model];
|
|
51206
51375
|
if (!url) {
|
|
51207
51376
|
throw new Error(
|
|
@@ -51211,18 +51380,18 @@ async function ensureModel3(model = DEFAULT_MODEL3, options) {
|
|
|
51211
51380
|
mkdirSync34(MODELS_DIR3, { recursive: true });
|
|
51212
51381
|
options?.onProgress?.(`Downloading TTS model ${model} (~311 MB)...`);
|
|
51213
51382
|
await downloadFile(url, modelPath2);
|
|
51214
|
-
if (!
|
|
51383
|
+
if (!existsSync62(modelPath2)) {
|
|
51215
51384
|
throw new Error(`Model download failed: ${model}`);
|
|
51216
51385
|
}
|
|
51217
51386
|
return modelPath2;
|
|
51218
51387
|
}
|
|
51219
51388
|
async function ensureVoices(options) {
|
|
51220
51389
|
const voicesPath = join68(VOICES_DIR, "voices-v1.0.bin");
|
|
51221
|
-
if (
|
|
51390
|
+
if (existsSync62(voicesPath)) return voicesPath;
|
|
51222
51391
|
mkdirSync34(VOICES_DIR, { recursive: true });
|
|
51223
51392
|
options?.onProgress?.("Downloading voice data (~27 MB)...");
|
|
51224
51393
|
await downloadFile(VOICES_URL, voicesPath);
|
|
51225
|
-
if (!
|
|
51394
|
+
if (!existsSync62(voicesPath)) {
|
|
51226
51395
|
throw new Error("Voice data download failed");
|
|
51227
51396
|
}
|
|
51228
51397
|
return voicesPath;
|
|
@@ -51295,7 +51464,7 @@ __export(synthesize_exports, {
|
|
|
51295
51464
|
synthesize: () => synthesize
|
|
51296
51465
|
});
|
|
51297
51466
|
import { execFileSync as execFileSync7 } from "child_process";
|
|
51298
|
-
import { existsSync as
|
|
51467
|
+
import { existsSync as existsSync63, writeFileSync as writeFileSync28, mkdirSync as mkdirSync35, readdirSync as readdirSync25, unlinkSync as unlinkSync6 } from "fs";
|
|
51299
51468
|
import { join as join69, dirname as dirname26, basename as basename12 } from "path";
|
|
51300
51469
|
import { homedir as homedir11 } from "os";
|
|
51301
51470
|
function findPython() {
|
|
@@ -51332,7 +51501,7 @@ function hasPythonPackage(python, pkg) {
|
|
|
51332
51501
|
}
|
|
51333
51502
|
}
|
|
51334
51503
|
function ensureSynthScript() {
|
|
51335
|
-
if (!
|
|
51504
|
+
if (!existsSync63(SCRIPT_PATH)) {
|
|
51336
51505
|
mkdirSync35(SCRIPT_DIR, { recursive: true });
|
|
51337
51506
|
writeFileSync28(SCRIPT_PATH, SYNTH_SCRIPT);
|
|
51338
51507
|
const currentName = basename12(SCRIPT_PATH);
|
|
@@ -51386,7 +51555,7 @@ async function synthesize(text, outputPath, options) {
|
|
|
51386
51555
|
stdio: ["pipe", "pipe", "pipe"]
|
|
51387
51556
|
}
|
|
51388
51557
|
);
|
|
51389
|
-
if (!
|
|
51558
|
+
if (!existsSync63(outputPath)) {
|
|
51390
51559
|
throw new Error("Synthesis completed but no output file was created");
|
|
51391
51560
|
}
|
|
51392
51561
|
const lines = stdout2.trim().split("\n");
|
|
@@ -51399,7 +51568,7 @@ async function synthesize(text, outputPath, options) {
|
|
|
51399
51568
|
langApplied: result.langApplied
|
|
51400
51569
|
};
|
|
51401
51570
|
} catch (err) {
|
|
51402
|
-
if (err instanceof SyntaxError &&
|
|
51571
|
+
if (err instanceof SyntaxError && existsSync63(outputPath)) {
|
|
51403
51572
|
throw new Error(
|
|
51404
51573
|
"Speech was generated but metadata could not be read. Check the output file manually."
|
|
51405
51574
|
);
|
|
@@ -51461,7 +51630,7 @@ __export(tts_exports, {
|
|
|
51461
51630
|
default: () => tts_default,
|
|
51462
51631
|
examples: () => examples17
|
|
51463
51632
|
});
|
|
51464
|
-
import { existsSync as
|
|
51633
|
+
import { existsSync as existsSync64, readFileSync as readFileSync44 } from "fs";
|
|
51465
51634
|
import { resolve as resolve39, extname as extname12 } from "path";
|
|
51466
51635
|
function listVoices(json) {
|
|
51467
51636
|
const rows = BUNDLED_VOICES.map((v2) => ({ ...v2, defaultLang: inferLangFromVoiceId(v2.id) }));
|
|
@@ -51571,8 +51740,8 @@ var init_tts = __esm({
|
|
|
51571
51740
|
}
|
|
51572
51741
|
let text;
|
|
51573
51742
|
const maybeFile = resolve39(args.input);
|
|
51574
|
-
if (
|
|
51575
|
-
text =
|
|
51743
|
+
if (existsSync64(maybeFile) && extname12(maybeFile).toLowerCase() === ".txt") {
|
|
51744
|
+
text = readFileSync44(maybeFile, "utf-8").trim();
|
|
51576
51745
|
if (!text) {
|
|
51577
51746
|
console.error(c2.error("File is empty."));
|
|
51578
51747
|
process.exit(1);
|
|
@@ -51664,7 +51833,7 @@ __export(docs_exports, {
|
|
|
51664
51833
|
default: () => docs_default,
|
|
51665
51834
|
examples: () => examples18
|
|
51666
51835
|
});
|
|
51667
|
-
import { readFileSync as
|
|
51836
|
+
import { readFileSync as readFileSync45, existsSync as existsSync65 } from "fs";
|
|
51668
51837
|
import { resolve as resolve40, dirname as dirname27, join as join70 } from "path";
|
|
51669
51838
|
import { fileURLToPath as fileURLToPath9 } from "url";
|
|
51670
51839
|
function docsDir() {
|
|
@@ -51672,7 +51841,7 @@ function docsDir() {
|
|
|
51672
51841
|
const dir = dirname27(thisFile);
|
|
51673
51842
|
const devPath = resolve40(dir, "..", "docs");
|
|
51674
51843
|
const builtPath = resolve40(dir, "docs");
|
|
51675
|
-
return
|
|
51844
|
+
return existsSync65(devPath) ? devPath : builtPath;
|
|
51676
51845
|
}
|
|
51677
51846
|
function formatInlineCode(line) {
|
|
51678
51847
|
return line.replace(/`([^`]+)`/g, (_match, code) => c2.accent(code));
|
|
@@ -51770,11 +51939,11 @@ var init_docs = __esm({
|
|
|
51770
51939
|
process.exit(1);
|
|
51771
51940
|
}
|
|
51772
51941
|
const filePath = join70(docsDir(), entry.file);
|
|
51773
|
-
if (!
|
|
51942
|
+
if (!existsSync65(filePath)) {
|
|
51774
51943
|
console.error(c2.error(`Doc file not found: ${filePath}`));
|
|
51775
51944
|
process.exit(1);
|
|
51776
51945
|
}
|
|
51777
|
-
const content =
|
|
51946
|
+
const content = readFileSync45(filePath, "utf-8");
|
|
51778
51947
|
console.log();
|
|
51779
51948
|
renderMarkdown(content);
|
|
51780
51949
|
}
|
|
@@ -51791,7 +51960,7 @@ __export(doctor_exports, {
|
|
|
51791
51960
|
redactHome: () => redactHome
|
|
51792
51961
|
});
|
|
51793
51962
|
import { execSync as execSync3 } from "child_process";
|
|
51794
|
-
import { freemem as freemem5, platform as
|
|
51963
|
+
import { freemem as freemem5, platform as platform8 } from "os";
|
|
51795
51964
|
function checkFFmpeg() {
|
|
51796
51965
|
const path2 = findFFmpeg();
|
|
51797
51966
|
if (path2) {
|
|
@@ -51980,7 +52149,7 @@ var init_doctor = __esm({
|
|
|
51980
52149
|
{ name: "Memory", run: checkMemory },
|
|
51981
52150
|
{ name: "Disk", run: checkDisk }
|
|
51982
52151
|
];
|
|
51983
|
-
if (
|
|
52152
|
+
if (platform8() === "linux") {
|
|
51984
52153
|
checks.push({ name: "/dev/shm", run: checkShm });
|
|
51985
52154
|
}
|
|
51986
52155
|
checks.push(
|
|
@@ -52238,16 +52407,18 @@ function parseViewportDimension(value) {
|
|
|
52238
52407
|
if (!Number.isFinite(parsed) || parsed <= 0) return null;
|
|
52239
52408
|
return Math.min(parsed, MAX_VIEWPORT_DIMENSION);
|
|
52240
52409
|
}
|
|
52241
|
-
function
|
|
52410
|
+
function findCompositionDimensions(html) {
|
|
52242
52411
|
ensureDOMParser();
|
|
52243
52412
|
const doc = new DOMParser().parseFromString(html, "text/html");
|
|
52244
52413
|
const root = doc.querySelector("[data-composition-id][data-width][data-height]");
|
|
52245
|
-
|
|
52246
|
-
const
|
|
52247
|
-
|
|
52248
|
-
|
|
52249
|
-
|
|
52250
|
-
|
|
52414
|
+
if (!root) return null;
|
|
52415
|
+
const width = parseViewportDimension(root.getAttribute("data-width"));
|
|
52416
|
+
const height = parseViewportDimension(root.getAttribute("data-height"));
|
|
52417
|
+
if (width === null || height === null) return null;
|
|
52418
|
+
return { width, height };
|
|
52419
|
+
}
|
|
52420
|
+
function resolveCompositionViewportFromHtml(html) {
|
|
52421
|
+
return findCompositionDimensions(html) ?? DEFAULT_VIEWPORT;
|
|
52251
52422
|
}
|
|
52252
52423
|
var DEFAULT_VIEWPORT, MAX_VIEWPORT_DIMENSION;
|
|
52253
52424
|
var init_compositionViewport = __esm({
|
|
@@ -52265,7 +52436,7 @@ __export(validate_exports, {
|
|
|
52265
52436
|
default: () => validate_default,
|
|
52266
52437
|
shouldIgnoreRequestFailure: () => shouldIgnoreRequestFailure
|
|
52267
52438
|
});
|
|
52268
|
-
import { existsSync as
|
|
52439
|
+
import { existsSync as existsSync66, readFileSync as readFileSync46 } from "fs";
|
|
52269
52440
|
import { join as join71, dirname as dirname28 } from "path";
|
|
52270
52441
|
import { fileURLToPath as fileURLToPath10 } from "url";
|
|
52271
52442
|
function shouldIgnoreRequestFailure(url, errorText) {
|
|
@@ -52322,7 +52493,7 @@ function loadContrastAuditScript() {
|
|
|
52322
52493
|
join71(__dirname3, "commands", "contrast-audit.browser.js")
|
|
52323
52494
|
];
|
|
52324
52495
|
for (const candidate of candidates) {
|
|
52325
|
-
if (
|
|
52496
|
+
if (existsSync66(candidate)) return readFileSync46(candidate, "utf-8");
|
|
52326
52497
|
}
|
|
52327
52498
|
throw new Error("Missing contrast audit browser script");
|
|
52328
52499
|
}
|
|
@@ -52340,9 +52511,9 @@ async function validateInBrowser(projectDir, opts) {
|
|
|
52340
52511
|
return;
|
|
52341
52512
|
}
|
|
52342
52513
|
const filePath = join71(projectDir, decodeURIComponent(url));
|
|
52343
|
-
if (
|
|
52514
|
+
if (existsSync66(filePath)) {
|
|
52344
52515
|
res.writeHead(200, { "Content-Type": getMimeType2(filePath) });
|
|
52345
|
-
res.end(
|
|
52516
|
+
res.end(readFileSync46(filePath));
|
|
52346
52517
|
return;
|
|
52347
52518
|
}
|
|
52348
52519
|
res.writeHead(404);
|
|
@@ -52544,7 +52715,7 @@ __export(contactSheet_exports, {
|
|
|
52544
52715
|
createSvgContactSheet: () => createSvgContactSheet
|
|
52545
52716
|
});
|
|
52546
52717
|
import sharp from "sharp";
|
|
52547
|
-
import { readdirSync as readdirSync26, readFileSync as
|
|
52718
|
+
import { readdirSync as readdirSync26, readFileSync as readFileSync47, writeFileSync as writeFileSync29, unlinkSync as unlinkSync7, existsSync as existsSync67 } from "fs";
|
|
52548
52719
|
import { join as join72, extname as extname13, basename as basename13, dirname as dirname29 } from "path";
|
|
52549
52720
|
async function createContactSheet(imagePaths, outputPath, opts = {}) {
|
|
52550
52721
|
const {
|
|
@@ -52624,7 +52795,7 @@ async function createContactSheetPages(imagePaths, outputBasePath, opts = {}, la
|
|
|
52624
52795
|
return results;
|
|
52625
52796
|
}
|
|
52626
52797
|
async function createScrollContactSheet(screenshotsDir, outputPath) {
|
|
52627
|
-
if (!
|
|
52798
|
+
if (!existsSync67(screenshotsDir)) return [];
|
|
52628
52799
|
const scrollFiles = readdirSync26(screenshotsDir).filter((f3) => f3.startsWith("scroll-") && f3.endsWith(".png")).sort();
|
|
52629
52800
|
if (scrollFiles.length === 0) return [];
|
|
52630
52801
|
const paths = scrollFiles.map((f3) => join72(screenshotsDir, f3));
|
|
@@ -52641,7 +52812,7 @@ async function createScrollContactSheet(screenshotsDir, outputPath) {
|
|
|
52641
52812
|
);
|
|
52642
52813
|
}
|
|
52643
52814
|
async function createSnapshotContactSheet(snapshotsDir, outputPath) {
|
|
52644
|
-
if (!
|
|
52815
|
+
if (!existsSync67(snapshotsDir)) return [];
|
|
52645
52816
|
const snapshotFiles = readdirSync26(snapshotsDir).filter((f3) => f3.startsWith("frame-") && f3.endsWith(".png")).sort();
|
|
52646
52817
|
if (snapshotFiles.length === 0) return [];
|
|
52647
52818
|
const paths = snapshotFiles.map((f3) => join72(snapshotsDir, f3));
|
|
@@ -52658,7 +52829,7 @@ async function createSnapshotContactSheet(snapshotsDir, outputPath) {
|
|
|
52658
52829
|
);
|
|
52659
52830
|
}
|
|
52660
52831
|
async function createAssetContactSheet(assetsDir, outputPath) {
|
|
52661
|
-
if (!
|
|
52832
|
+
if (!existsSync67(assetsDir)) return [];
|
|
52662
52833
|
const imageExts = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".webp"]);
|
|
52663
52834
|
const assetFiles = readdirSync26(assetsDir).filter((f3) => imageExts.has(extname13(f3).toLowerCase()) && !f3.includes("contact-sheet")).sort();
|
|
52664
52835
|
if (assetFiles.length === 0) return [];
|
|
@@ -52672,7 +52843,7 @@ async function createAssetContactSheet(assetsDir, outputPath) {
|
|
|
52672
52843
|
}
|
|
52673
52844
|
async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir) {
|
|
52674
52845
|
const dirsToScan = [svgsDir, assetsRootDir].filter(
|
|
52675
|
-
(d2) => d2 !== void 0 &&
|
|
52846
|
+
(d2) => d2 !== void 0 && existsSync67(d2)
|
|
52676
52847
|
);
|
|
52677
52848
|
if (dirsToScan.length === 0) return [];
|
|
52678
52849
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -52695,7 +52866,7 @@ async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir) {
|
|
|
52695
52866
|
const svgPath = svgPaths[i2];
|
|
52696
52867
|
const tmpPath = join72(tmpDir, `.thumb-${i2}.png`);
|
|
52697
52868
|
try {
|
|
52698
|
-
const svgBuf =
|
|
52869
|
+
const svgBuf = readFileSync47(svgPath);
|
|
52699
52870
|
const thumb = await sharp(svgBuf).resize(thumbSize, thumbSize, {
|
|
52700
52871
|
fit: "contain",
|
|
52701
52872
|
background: { r: 245, g: 245, b: 245, alpha: 1 }
|
|
@@ -93253,7 +93424,7 @@ __export(snapshot_exports, {
|
|
|
93253
93424
|
examples: () => examples22
|
|
93254
93425
|
});
|
|
93255
93426
|
import { spawn as spawn15 } from "child_process";
|
|
93256
|
-
import { existsSync as
|
|
93427
|
+
import { existsSync as existsSync68, mkdtempSync as mkdtempSync3, readFileSync as readFileSync48, mkdirSync as mkdirSync36, rmSync as rmSync15, writeFileSync as writeFileSync30 } from "fs";
|
|
93257
93428
|
import { tmpdir as tmpdir6 } from "os";
|
|
93258
93429
|
import { resolve as resolve41, join as join73, relative as relative10, isAbsolute as isAbsolute9 } from "path";
|
|
93259
93430
|
async function extractVideoFrameToBuffer(videoPath, timeSeconds, useVp9AlphaDecoder = false) {
|
|
@@ -93298,8 +93469,8 @@ async function extractVideoFrameToBuffer(videoPath, timeSeconds, useVp9AlphaDeco
|
|
|
93298
93469
|
});
|
|
93299
93470
|
}
|
|
93300
93471
|
);
|
|
93301
|
-
if (result.code !== 0 || result.timedOut || !
|
|
93302
|
-
return
|
|
93472
|
+
if (result.code !== 0 || result.timedOut || !existsSync68(outPath)) return null;
|
|
93473
|
+
return readFileSync48(outPath);
|
|
93303
93474
|
} finally {
|
|
93304
93475
|
try {
|
|
93305
93476
|
rmSync15(tmp, { recursive: true, force: true });
|
|
@@ -93497,7 +93668,7 @@ async function captureSnapshots(projectDir, opts) {
|
|
|
93497
93668
|
const decodedPath = decodeURIComponent(url.pathname).replace(/^\//, "");
|
|
93498
93669
|
const candidate = resolve41(projectDir, decodedPath);
|
|
93499
93670
|
const rel = relative10(projectDir, candidate);
|
|
93500
|
-
if (!rel.startsWith("..") && !isAbsolute9(rel) &&
|
|
93671
|
+
if (!rel.startsWith("..") && !isAbsolute9(rel) && existsSync68(candidate)) {
|
|
93501
93672
|
filePath = candidate;
|
|
93502
93673
|
}
|
|
93503
93674
|
} catch {
|
|
@@ -93648,8 +93819,8 @@ ${c2.success("\u25C7")} ${paths.length} snapshots saved to snapshots/`);
|
|
|
93648
93819
|
paths.map(async (p2) => {
|
|
93649
93820
|
const filename = p2.replace("snapshots/", "");
|
|
93650
93821
|
const filePath = join73(snapshotDir, filename);
|
|
93651
|
-
if (!
|
|
93652
|
-
const raw =
|
|
93822
|
+
if (!existsSync68(filePath)) return { filename, desc: "file not found" };
|
|
93823
|
+
const raw = readFileSync48(filePath);
|
|
93653
93824
|
let imageData;
|
|
93654
93825
|
let mimeType = "image/png";
|
|
93655
93826
|
if (sharpFn) {
|
|
@@ -94843,7 +95014,7 @@ var init_designStyleExtractor = __esm({
|
|
|
94843
95014
|
});
|
|
94844
95015
|
|
|
94845
95016
|
// src/capture/fontMetadataExtractor.ts
|
|
94846
|
-
import { readdirSync as readdirSync27, readFileSync as
|
|
95017
|
+
import { readdirSync as readdirSync27, readFileSync as readFileSync49, writeFileSync as writeFileSync32, existsSync as existsSync69 } from "fs";
|
|
94847
95018
|
import { join as join75 } from "path";
|
|
94848
95019
|
import * as fontkit from "fontkit";
|
|
94849
95020
|
function isFontCollection(value) {
|
|
@@ -94852,7 +95023,7 @@ function isFontCollection(value) {
|
|
|
94852
95023
|
function extractFontMetadata(fontsDir, outputPath) {
|
|
94853
95024
|
const files = [];
|
|
94854
95025
|
const unidentified = [];
|
|
94855
|
-
if (
|
|
95026
|
+
if (existsSync69(fontsDir)) {
|
|
94856
95027
|
const fontFiles = readdirSync27(fontsDir).filter((f3) => /\.(woff2?|ttf|otf)$/i.test(f3));
|
|
94857
95028
|
for (const filename of fontFiles) {
|
|
94858
95029
|
const fullPath = join75(fontsDir, filename);
|
|
@@ -94893,7 +95064,7 @@ function readSingleFont(fullPath, filename) {
|
|
|
94893
95064
|
identified: false
|
|
94894
95065
|
};
|
|
94895
95066
|
try {
|
|
94896
|
-
const buf =
|
|
95067
|
+
const buf = readFileSync49(fullPath);
|
|
94897
95068
|
const created = fontkit.create(buf);
|
|
94898
95069
|
const font = isFontCollection(created) ? created.fonts[0] : created;
|
|
94899
95070
|
if (!font) return empty;
|
|
@@ -95149,7 +95320,7 @@ var init_animationCataloger = __esm({
|
|
|
95149
95320
|
});
|
|
95150
95321
|
|
|
95151
95322
|
// src/capture/mediaCapture.ts
|
|
95152
|
-
import { mkdirSync as mkdirSync38, writeFileSync as writeFileSync33, readdirSync as readdirSync28, readFileSync as
|
|
95323
|
+
import { mkdirSync as mkdirSync38, writeFileSync as writeFileSync33, readdirSync as readdirSync28, readFileSync as readFileSync50, statSync as statSync24 } from "fs";
|
|
95153
95324
|
import { join as join76 } from "path";
|
|
95154
95325
|
async function saveLottieAnimations(discoveredLotties, lottieDir) {
|
|
95155
95326
|
let savedCount = 0;
|
|
@@ -95216,7 +95387,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir) {
|
|
|
95216
95387
|
for (const file of readdirSync28(lottieDir)) {
|
|
95217
95388
|
if (!file.endsWith(".json")) continue;
|
|
95218
95389
|
try {
|
|
95219
|
-
const raw = JSON.parse(
|
|
95390
|
+
const raw = JSON.parse(readFileSync50(join76(lottieDir, file), "utf-8"));
|
|
95220
95391
|
const fr = raw.fr || 30;
|
|
95221
95392
|
const dur = ((raw.op || 0) - (raw.ip || 0)) / fr;
|
|
95222
95393
|
const previewName = file.replace(".json", "-preview.png");
|
|
@@ -95226,7 +95397,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir) {
|
|
|
95226
95397
|
try {
|
|
95227
95398
|
previewPage = await chromeBrowser.newPage();
|
|
95228
95399
|
await previewPage.setViewport({ width: 400, height: 400 });
|
|
95229
|
-
const animData = JSON.parse(
|
|
95400
|
+
const animData = JSON.parse(readFileSync50(join76(lottieDir, file), "utf-8"));
|
|
95230
95401
|
const midFrame = Math.floor(((raw.op || 0) - (raw.ip || 0)) * 0.3);
|
|
95231
95402
|
await previewPage.setContent(
|
|
95232
95403
|
`<!DOCTYPE html>
|
|
@@ -95405,7 +95576,7 @@ var init_mediaCapture = __esm({
|
|
|
95405
95576
|
});
|
|
95406
95577
|
|
|
95407
95578
|
// src/capture/contentExtractor.ts
|
|
95408
|
-
import { existsSync as
|
|
95579
|
+
import { existsSync as existsSync70, readdirSync as readdirSync29, statSync as statSync25, readFileSync as readFileSync51 } from "fs";
|
|
95409
95580
|
import { join as join77 } from "path";
|
|
95410
95581
|
async function detectLibraries(page, capturedShaders) {
|
|
95411
95582
|
let detectedLibraries = [];
|
|
@@ -95538,7 +95709,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
|
|
|
95538
95709
|
const filePath = join77(outputDir, "assets", file);
|
|
95539
95710
|
const stat3 = statSync25(filePath);
|
|
95540
95711
|
if (stat3.size > 4e6) return { file, caption: "" };
|
|
95541
|
-
const buffer =
|
|
95712
|
+
const buffer = readFileSync51(filePath);
|
|
95542
95713
|
const base64 = buffer.toString("base64");
|
|
95543
95714
|
const ext = file.split(".").pop()?.toLowerCase() || "png";
|
|
95544
95715
|
const mimeType = ext === "jpg" ? "image/jpeg" : `image/${ext}`;
|
|
@@ -95580,7 +95751,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
|
|
|
95580
95751
|
if (/\.svg$/i.test(f3)) svgFiles.push({ file: f3, relPath: f3 });
|
|
95581
95752
|
}
|
|
95582
95753
|
const svgsSubdir = join77(assetsDir, "svgs");
|
|
95583
|
-
if (
|
|
95754
|
+
if (existsSync70(svgsSubdir)) {
|
|
95584
95755
|
for (const f3 of readdirSync29(svgsSubdir)) {
|
|
95585
95756
|
if (/\.svg$/i.test(f3)) svgFiles.push({ file: f3, relPath: `svgs/${f3}` });
|
|
95586
95757
|
}
|
|
@@ -95594,7 +95765,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
|
|
|
95594
95765
|
const results = await Promise.allSettled(
|
|
95595
95766
|
batch.map(async ({ relPath }) => {
|
|
95596
95767
|
const filePath = join77(assetsDir, relPath);
|
|
95597
|
-
let svgText =
|
|
95768
|
+
let svgText = readFileSync51(filePath, "utf-8");
|
|
95598
95769
|
if (svgText.length > MAX_SVG_CHARS) {
|
|
95599
95770
|
svgText = svgText.slice(0, MAX_SVG_CHARS) + "\n<!-- truncated -->";
|
|
95600
95771
|
}
|
|
@@ -95712,7 +95883,7 @@ var agentPromptGenerator_exports = {};
|
|
|
95712
95883
|
__export(agentPromptGenerator_exports, {
|
|
95713
95884
|
generateAgentPrompt: () => generateAgentPrompt
|
|
95714
95885
|
});
|
|
95715
|
-
import { writeFileSync as writeFileSync34, readdirSync as readdirSync30, existsSync as
|
|
95886
|
+
import { writeFileSync as writeFileSync34, readdirSync as readdirSync30, existsSync as existsSync71 } from "fs";
|
|
95716
95887
|
import { join as join78 } from "path";
|
|
95717
95888
|
function inferColorRole(hex) {
|
|
95718
95889
|
const r2 = parseInt(hex.slice(1, 3), 16) / 255;
|
|
@@ -95744,7 +95915,7 @@ function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShader
|
|
|
95744
95915
|
).join(", ") || "none detected";
|
|
95745
95916
|
function contactSheetRows(dir, baseFile, label2) {
|
|
95746
95917
|
const fullDir = join78(outputDir, dir);
|
|
95747
|
-
if (!
|
|
95918
|
+
if (!existsSync71(fullDir)) return [];
|
|
95748
95919
|
const baseName = baseFile.replace(/\.jpg$/, "");
|
|
95749
95920
|
const escapedBase = baseName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
95750
95921
|
const paginatedRe = new RegExp(`^${escapedBase}(?:-(\\d+))?\\.jpg$`);
|
|
@@ -95776,7 +95947,7 @@ function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShader
|
|
|
95776
95947
|
tableRows.push(
|
|
95777
95948
|
`| \`extracted/tokens.json\` | Design tokens: ${tokens.colors.length} colors, ${tokens.fonts.length} fonts, ${tokens.headings?.length ?? 0} headings, ${tokens.ctas?.length ?? 0} CTAs |`
|
|
95778
95949
|
);
|
|
95779
|
-
if (
|
|
95950
|
+
if (existsSync71(join78(outputDir, "extracted", "design-styles.json"))) {
|
|
95780
95951
|
tableRows.push(
|
|
95781
95952
|
"| `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. |"
|
|
95782
95953
|
);
|
|
@@ -95847,7 +96018,7 @@ var init_agentPromptGenerator = __esm({
|
|
|
95847
96018
|
});
|
|
95848
96019
|
|
|
95849
96020
|
// src/capture/scaffolding.ts
|
|
95850
|
-
import { existsSync as
|
|
96021
|
+
import { existsSync as existsSync72, writeFileSync as writeFileSync35, readFileSync as readFileSync52 } from "fs";
|
|
95851
96022
|
import { join as join79, resolve as resolve42 } from "path";
|
|
95852
96023
|
function loadEnvFile(startDir) {
|
|
95853
96024
|
try {
|
|
@@ -95855,7 +96026,7 @@ function loadEnvFile(startDir) {
|
|
|
95855
96026
|
for (let i2 = 0; i2 < 5; i2++) {
|
|
95856
96027
|
const envPath = resolve42(dir, ".env");
|
|
95857
96028
|
try {
|
|
95858
|
-
const envContent =
|
|
96029
|
+
const envContent = readFileSync52(envPath, "utf-8");
|
|
95859
96030
|
for (const line of envContent.split("\n")) {
|
|
95860
96031
|
const trimmed = line.trim();
|
|
95861
96032
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
@@ -95875,7 +96046,7 @@ function loadEnvFile(startDir) {
|
|
|
95875
96046
|
}
|
|
95876
96047
|
async function generateProjectScaffold(outputDir, url, tokens, animationCatalog, hasScreenshots, hasLotties, hasShaders, catalogedAssets, progress, warnings, detectedLibraries) {
|
|
95877
96048
|
const metaPath = join79(outputDir, "meta.json");
|
|
95878
|
-
if (!
|
|
96049
|
+
if (!existsSync72(metaPath)) {
|
|
95879
96050
|
const hostname = new URL(url).hostname.replace(/^www\./, "");
|
|
95880
96051
|
writeFileSync35(
|
|
95881
96052
|
metaPath,
|
|
@@ -96282,7 +96453,7 @@ var capture_exports = {};
|
|
|
96282
96453
|
__export(capture_exports, {
|
|
96283
96454
|
captureWebsite: () => captureWebsite
|
|
96284
96455
|
});
|
|
96285
|
-
import { mkdirSync as mkdirSync40, writeFileSync as writeFileSync37, existsSync as
|
|
96456
|
+
import { mkdirSync as mkdirSync40, writeFileSync as writeFileSync37, existsSync as existsSync73 } from "fs";
|
|
96286
96457
|
import { join as join81 } from "path";
|
|
96287
96458
|
async function captureWebsite(opts, onProgress) {
|
|
96288
96459
|
const {
|
|
@@ -96645,7 +96816,7 @@ ${err.stack}` : String(err);
|
|
|
96645
96816
|
`Screenshot contact sheet generated (${scrollSheets.length} page${scrollSheets.length > 1 ? "s" : ""})`
|
|
96646
96817
|
);
|
|
96647
96818
|
const assetsImgDir = join81(outputDir, "assets");
|
|
96648
|
-
if (
|
|
96819
|
+
if (existsSync73(assetsImgDir)) {
|
|
96649
96820
|
const assetSheets = await createAssetContactSheet2(
|
|
96650
96821
|
assetsImgDir,
|
|
96651
96822
|
join81(outputDir, "assets", "contact-sheet.jpg")
|
|
@@ -96658,7 +96829,7 @@ ${err.stack}` : String(err);
|
|
|
96658
96829
|
}
|
|
96659
96830
|
const svgsDir = join81(outputDir, "assets", "svgs");
|
|
96660
96831
|
const assetsRootDir = join81(outputDir, "assets");
|
|
96661
|
-
const svgOutputPath =
|
|
96832
|
+
const svgOutputPath = existsSync73(svgsDir) ? join81(outputDir, "assets", "svgs", "contact-sheet.jpg") : join81(outputDir, "assets", "contact-sheet-svgs.jpg");
|
|
96662
96833
|
const svgSheets = await createSvgContactSheet2(svgsDir, svgOutputPath, assetsRootDir);
|
|
96663
96834
|
if (svgSheets.length > 0)
|
|
96664
96835
|
progress(
|
|
@@ -96674,7 +96845,7 @@ ${err.stack}` : String(err);
|
|
|
96674
96845
|
animationCatalog,
|
|
96675
96846
|
screenshots.length > 0,
|
|
96676
96847
|
discoveredLotties.length > 0,
|
|
96677
|
-
|
|
96848
|
+
existsSync73(join81(outputDir, "extracted", "shaders.json")),
|
|
96678
96849
|
catalogedAssets,
|
|
96679
96850
|
progress,
|
|
96680
96851
|
warnings,
|
|
@@ -96902,7 +97073,7 @@ __export(state_exports, {
|
|
|
96902
97073
|
stateFilePath: () => stateFilePath,
|
|
96903
97074
|
writeStackOutputs: () => writeStackOutputs
|
|
96904
97075
|
});
|
|
96905
|
-
import { existsSync as
|
|
97076
|
+
import { existsSync as existsSync74, mkdirSync as mkdirSync41, readdirSync as readdirSync31, readFileSync as readFileSync53, rmSync as rmSync16, writeFileSync as writeFileSync38 } from "fs";
|
|
96906
97077
|
import { dirname as dirname30, join as join82 } from "path";
|
|
96907
97078
|
function stateFilePath(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
96908
97079
|
return join82(cwd, STATE_DIR_NAME, `${STATE_FILE_PREFIX}${stackName}.json`);
|
|
@@ -96915,20 +97086,20 @@ function writeStackOutputs(outputs, cwd = process.cwd()) {
|
|
|
96915
97086
|
}
|
|
96916
97087
|
function readStackOutputs(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
96917
97088
|
const path2 = stateFilePath(stackName, cwd);
|
|
96918
|
-
if (!
|
|
97089
|
+
if (!existsSync74(path2)) return null;
|
|
96919
97090
|
try {
|
|
96920
|
-
return JSON.parse(
|
|
97091
|
+
return JSON.parse(readFileSync53(path2, "utf-8"));
|
|
96921
97092
|
} catch {
|
|
96922
97093
|
return null;
|
|
96923
97094
|
}
|
|
96924
97095
|
}
|
|
96925
97096
|
function deleteStackOutputs(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
96926
97097
|
const path2 = stateFilePath(stackName, cwd);
|
|
96927
|
-
if (
|
|
97098
|
+
if (existsSync74(path2)) rmSync16(path2);
|
|
96928
97099
|
}
|
|
96929
97100
|
function listStackNames(cwd = process.cwd()) {
|
|
96930
97101
|
const dir = join82(cwd, STATE_DIR_NAME);
|
|
96931
|
-
if (!
|
|
97102
|
+
if (!existsSync74(dir)) return [];
|
|
96932
97103
|
return readdirSync31(dir).filter((f3) => f3.startsWith(STATE_FILE_PREFIX) && f3.endsWith(".json")).map((f3) => f3.slice(STATE_FILE_PREFIX.length, -".json".length));
|
|
96933
97104
|
}
|
|
96934
97105
|
function requireStack(stackName, cwd = process.cwd()) {
|
|
@@ -96958,7 +97129,7 @@ var init_state = __esm({
|
|
|
96958
97129
|
|
|
96959
97130
|
// src/commands/lambda/sam.ts
|
|
96960
97131
|
import { execFileSync as execFileSync9, spawnSync as spawnSync4 } from "child_process";
|
|
96961
|
-
import { existsSync as
|
|
97132
|
+
import { existsSync as existsSync75 } from "fs";
|
|
96962
97133
|
import { join as join83 } from "path";
|
|
96963
97134
|
function assertSamAvailable() {
|
|
96964
97135
|
try {
|
|
@@ -96980,7 +97151,7 @@ function assertAwsCliAvailable() {
|
|
|
96980
97151
|
}
|
|
96981
97152
|
function locateSamTemplate(repoRoot2) {
|
|
96982
97153
|
const candidate = join83(repoRoot2, "examples", "aws-lambda", "template.yaml");
|
|
96983
|
-
if (!
|
|
97154
|
+
if (!existsSync75(candidate)) {
|
|
96984
97155
|
throw new Error(
|
|
96985
97156
|
`[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.`
|
|
96986
97157
|
);
|
|
@@ -97075,17 +97246,17 @@ var init_sam = __esm({
|
|
|
97075
97246
|
});
|
|
97076
97247
|
|
|
97077
97248
|
// src/commands/lambda/repoRoot.ts
|
|
97078
|
-
import { existsSync as
|
|
97249
|
+
import { existsSync as existsSync76 } from "fs";
|
|
97079
97250
|
import { dirname as dirname31, resolve as resolve44 } from "path";
|
|
97080
97251
|
import { fileURLToPath as fileURLToPath11 } from "url";
|
|
97081
97252
|
function repoRoot() {
|
|
97082
97253
|
const override = process.env.HYPERFRAMES_REPO_ROOT;
|
|
97083
|
-
if (override &&
|
|
97254
|
+
if (override && existsSync76(resolve44(override, "packages", "aws-lambda", "package.json"))) {
|
|
97084
97255
|
return override;
|
|
97085
97256
|
}
|
|
97086
97257
|
let dir = dirname31(fileURLToPath11(import.meta.url));
|
|
97087
97258
|
for (let depth = 0; depth < 12; depth++) {
|
|
97088
|
-
if (
|
|
97259
|
+
if (existsSync76(resolve44(dir, "packages", "aws-lambda", "package.json"))) {
|
|
97089
97260
|
return dir;
|
|
97090
97261
|
}
|
|
97091
97262
|
const parent = dirname31(dir);
|
|
@@ -97108,7 +97279,7 @@ __export(deploy_exports, {
|
|
|
97108
97279
|
runDeploy: () => runDeploy
|
|
97109
97280
|
});
|
|
97110
97281
|
import { spawnSync as spawnSync5 } from "child_process";
|
|
97111
|
-
import { existsSync as
|
|
97282
|
+
import { existsSync as existsSync77 } from "fs";
|
|
97112
97283
|
import { join as join84, resolve as resolve45 } from "path";
|
|
97113
97284
|
async function runDeploy(args = {}) {
|
|
97114
97285
|
const resolved = {
|
|
@@ -97127,7 +97298,7 @@ async function runDeploy(args = {}) {
|
|
|
97127
97298
|
buildHandlerZip(root);
|
|
97128
97299
|
} else {
|
|
97129
97300
|
const zip = join84(root, "packages", "aws-lambda", "dist", "handler.zip");
|
|
97130
|
-
if (!
|
|
97301
|
+
if (!existsSync77(zip)) {
|
|
97131
97302
|
throw new Error(
|
|
97132
97303
|
`--skip-build set but ${zip} does not exist. Run \`bun run --cwd packages/aws-lambda build:zip\` first or drop --skip-build.`
|
|
97133
97304
|
);
|
|
@@ -97238,23 +97409,61 @@ var init_sites = __esm({
|
|
|
97238
97409
|
}
|
|
97239
97410
|
});
|
|
97240
97411
|
|
|
97412
|
+
// src/commands/lambda/_dimensions.ts
|
|
97413
|
+
import { readFileSync as readFileSync54 } from "fs";
|
|
97414
|
+
import { join as join85 } from "path";
|
|
97415
|
+
function warnOnDimensionMismatch(args) {
|
|
97416
|
+
if (args.quiet) return;
|
|
97417
|
+
if (args.outputResolution) return;
|
|
97418
|
+
let html;
|
|
97419
|
+
try {
|
|
97420
|
+
html = readFileSync54(join85(args.projectDir, "index.html"), "utf-8");
|
|
97421
|
+
} catch {
|
|
97422
|
+
return;
|
|
97423
|
+
}
|
|
97424
|
+
const composition = findCompositionDimensions(html);
|
|
97425
|
+
if (!composition) return;
|
|
97426
|
+
if (composition.width === args.cliWidth && composition.height === args.cliHeight) return;
|
|
97427
|
+
console.warn(
|
|
97428
|
+
c2.warn(
|
|
97429
|
+
`--width/--height (${args.cliWidth}\xD7${args.cliHeight}) disagrees with the composition's data-width/data-height (${composition.width}\xD7${composition.height}). The runtime lays out the page at the composition's authored dimensions, so your output will be ${composition.width}\xD7${composition.height}, not ${args.cliWidth}\xD7${args.cliHeight}.
|
|
97430
|
+
To supersample to a higher resolution, pass --output-resolution (e.g. \`--output-resolution=4k\`).
|
|
97431
|
+
To truly change layout dimensions, edit the composition's data-width/data-height in index.html.`
|
|
97432
|
+
)
|
|
97433
|
+
);
|
|
97434
|
+
}
|
|
97435
|
+
var init_dimensions = __esm({
|
|
97436
|
+
"src/commands/lambda/_dimensions.ts"() {
|
|
97437
|
+
"use strict";
|
|
97438
|
+
init_colors();
|
|
97439
|
+
init_compositionViewport();
|
|
97440
|
+
}
|
|
97441
|
+
});
|
|
97442
|
+
|
|
97241
97443
|
// src/commands/lambda/render.ts
|
|
97242
97444
|
var render_exports2 = {};
|
|
97243
97445
|
__export(render_exports2, {
|
|
97244
97446
|
runRender: () => runRender
|
|
97245
97447
|
});
|
|
97246
|
-
import { existsSync as
|
|
97247
|
-
import { join as
|
|
97448
|
+
import { existsSync as existsSync78 } from "fs";
|
|
97449
|
+
import { join as join86, resolve as resolvePath2 } from "path";
|
|
97248
97450
|
async function loadSDK2() {
|
|
97249
97451
|
return import("@hyperframes/aws-lambda/sdk");
|
|
97250
97452
|
}
|
|
97251
97453
|
async function runRender(args) {
|
|
97252
97454
|
const stack = requireStack(args.stackName);
|
|
97253
97455
|
const projectDir = resolvePath2(args.projectDir);
|
|
97456
|
+
warnOnDimensionMismatch({
|
|
97457
|
+
projectDir,
|
|
97458
|
+
cliWidth: args.width,
|
|
97459
|
+
cliHeight: args.height,
|
|
97460
|
+
outputResolution: args.outputResolution,
|
|
97461
|
+
quiet: args.json
|
|
97462
|
+
});
|
|
97254
97463
|
const variables = resolveVariablesArg(args.variables, args.variablesFile);
|
|
97255
97464
|
if (variables && Object.keys(variables).length > 0) {
|
|
97256
|
-
const indexPath =
|
|
97257
|
-
if (
|
|
97465
|
+
const indexPath = join86(projectDir, "index.html");
|
|
97466
|
+
if (existsSync78(indexPath)) {
|
|
97258
97467
|
const issues = validateVariablesAgainstProject(indexPath, variables);
|
|
97259
97468
|
reportVariableIssues(issues, { strict: args.strictVariables ?? false, quiet: args.json });
|
|
97260
97469
|
} else if (args.strictVariables && !args.json) {
|
|
@@ -97269,6 +97478,7 @@ async function runRender(args) {
|
|
|
97269
97478
|
fps: args.fps,
|
|
97270
97479
|
width: args.width,
|
|
97271
97480
|
height: args.height,
|
|
97481
|
+
outputResolution: args.outputResolution,
|
|
97272
97482
|
format: args.format,
|
|
97273
97483
|
codec: args.codec,
|
|
97274
97484
|
quality: args.quality,
|
|
@@ -97364,6 +97574,7 @@ var init_render3 = __esm({
|
|
|
97364
97574
|
"use strict";
|
|
97365
97575
|
init_colors();
|
|
97366
97576
|
init_variables();
|
|
97577
|
+
init_dimensions();
|
|
97367
97578
|
init_state();
|
|
97368
97579
|
}
|
|
97369
97580
|
});
|
|
@@ -97375,8 +97586,8 @@ __export(render_batch_exports, {
|
|
|
97375
97586
|
runRenderBatch: () => runRenderBatch,
|
|
97376
97587
|
runWithConcurrencyLimit: () => runWithConcurrencyLimit
|
|
97377
97588
|
});
|
|
97378
|
-
import { existsSync as
|
|
97379
|
-
import { join as
|
|
97589
|
+
import { existsSync as existsSync79, readFileSync as readFileSync55 } from "fs";
|
|
97590
|
+
import { join as join87, resolve as resolvePath3 } from "path";
|
|
97380
97591
|
async function loadSDK3() {
|
|
97381
97592
|
return import("@hyperframes/aws-lambda/sdk");
|
|
97382
97593
|
}
|
|
@@ -97384,7 +97595,7 @@ async function runRenderBatch(args) {
|
|
|
97384
97595
|
const projectDir = resolvePath3(args.projectDir);
|
|
97385
97596
|
const stack = requireStack(args.stackName);
|
|
97386
97597
|
const batchPath = resolvePath3(args.batch);
|
|
97387
|
-
if (!
|
|
97598
|
+
if (!existsSync79(batchPath)) {
|
|
97388
97599
|
errorBox("Batch file not found", `No such file: ${batchPath}`);
|
|
97389
97600
|
process.exit(1);
|
|
97390
97601
|
}
|
|
@@ -97393,7 +97604,14 @@ async function runRenderBatch(args) {
|
|
|
97393
97604
|
errorBox("Empty batch", `${batchPath} contains zero entries (every line was blank).`);
|
|
97394
97605
|
process.exit(1);
|
|
97395
97606
|
}
|
|
97396
|
-
|
|
97607
|
+
warnOnDimensionMismatch({
|
|
97608
|
+
projectDir,
|
|
97609
|
+
cliWidth: args.width,
|
|
97610
|
+
cliHeight: args.height,
|
|
97611
|
+
outputResolution: args.outputResolution,
|
|
97612
|
+
quiet: args.json
|
|
97613
|
+
});
|
|
97614
|
+
const schema = loadProjectVariableSchema(join87(projectDir, "index.html"));
|
|
97397
97615
|
const strict = args.strictVariables ?? false;
|
|
97398
97616
|
let hadStrictIssue = false;
|
|
97399
97617
|
for (const { entry, lineNumber } of entries2) {
|
|
@@ -97418,6 +97636,7 @@ async function runRenderBatch(args) {
|
|
|
97418
97636
|
fps: args.fps,
|
|
97419
97637
|
width: args.width,
|
|
97420
97638
|
height: args.height,
|
|
97639
|
+
outputResolution: args.outputResolution,
|
|
97421
97640
|
format: args.format,
|
|
97422
97641
|
codec: args.codec,
|
|
97423
97642
|
quality: args.quality,
|
|
@@ -97519,7 +97738,7 @@ function makePlaceholderSiteHandle(siteId, bucketName) {
|
|
|
97519
97738
|
};
|
|
97520
97739
|
}
|
|
97521
97740
|
function parseBatchFile(path2) {
|
|
97522
|
-
const raw =
|
|
97741
|
+
const raw = readFileSync55(path2, "utf8");
|
|
97523
97742
|
const lines = raw.split(/\r?\n/);
|
|
97524
97743
|
const out = [];
|
|
97525
97744
|
for (let i2 = 0; i2 < lines.length; i2++) {
|
|
@@ -97600,6 +97819,7 @@ var init_render_batch = __esm({
|
|
|
97600
97819
|
init_colors();
|
|
97601
97820
|
init_format();
|
|
97602
97821
|
init_variables();
|
|
97822
|
+
init_dimensions();
|
|
97603
97823
|
init_state();
|
|
97604
97824
|
DEFAULT_MAX_CONCURRENT = 50;
|
|
97605
97825
|
}
|
|
@@ -97712,7 +97932,7 @@ __export(policies_exports, {
|
|
|
97712
97932
|
runPolicies: () => runPolicies,
|
|
97713
97933
|
validatePolicy: () => validatePolicy
|
|
97714
97934
|
});
|
|
97715
|
-
import { readFileSync as
|
|
97935
|
+
import { readFileSync as readFileSync56 } from "fs";
|
|
97716
97936
|
function allRequiredActions() {
|
|
97717
97937
|
const set = /* @__PURE__ */ new Set();
|
|
97718
97938
|
for (const group of Object.values(REQUIRED_ACTIONS)) {
|
|
@@ -97818,7 +98038,7 @@ async function runPolicies(args) {
|
|
|
97818
98038
|
}
|
|
97819
98039
|
}
|
|
97820
98040
|
function validatePolicy(policyPath) {
|
|
97821
|
-
const raw =
|
|
98041
|
+
const raw = readFileSync56(policyPath, "utf-8");
|
|
97822
98042
|
const parsed = JSON.parse(raw);
|
|
97823
98043
|
const statements = Array.isArray(parsed.Statement) ? parsed.Statement : parsed.Statement ? [
|
|
97824
98044
|
parsed.Statement
|
|
@@ -98006,11 +98226,20 @@ function parseEnum(raw, allowed, errorPrefix, defaultValue) {
|
|
|
98006
98226
|
if (allowed.includes(s2)) return s2;
|
|
98007
98227
|
throw new Error(`${errorPrefix} must be ${allowed.join("|")}; got ${s2}`);
|
|
98008
98228
|
}
|
|
98229
|
+
function parseOutputResolution(raw) {
|
|
98230
|
+
if (raw == null || raw === "") return void 0;
|
|
98231
|
+
const normalized = normalizeResolutionFlag(String(raw));
|
|
98232
|
+
if (normalized) return normalized;
|
|
98233
|
+
throw new Error(
|
|
98234
|
+
`[lambda render] --output-resolution must be one of ${VALID_CANVAS_RESOLUTIONS.join("|")} (or an alias: 1080p, 4k, uhd, hd, 1080p-portrait, portrait-1080p, 4k-portrait, 1080p-square, square-1080p, 4k-square); got ${String(raw)}`
|
|
98235
|
+
);
|
|
98236
|
+
}
|
|
98009
98237
|
var examples24, HELP, lambda_default, FORMATS, CODECS, QUALITIES2, CHROME_SOURCES, parseFormat, parseCodec, parseQuality, parseChromeSource;
|
|
98010
98238
|
var init_lambda = __esm({
|
|
98011
98239
|
"src/commands/lambda.ts"() {
|
|
98012
98240
|
"use strict";
|
|
98013
98241
|
init_dist();
|
|
98242
|
+
init_src();
|
|
98014
98243
|
init_colors();
|
|
98015
98244
|
examples24 = [
|
|
98016
98245
|
["Deploy the Lambda render stack to AWS", "hyperframes lambda deploy"],
|
|
@@ -98022,6 +98251,10 @@ var init_lambda = __esm({
|
|
|
98022
98251
|
"Render and stream progress until done",
|
|
98023
98252
|
"hyperframes lambda render ./my-project --width 1920 --height 1080 --wait"
|
|
98024
98253
|
],
|
|
98254
|
+
[
|
|
98255
|
+
"Supersample a 1080p composition to 4K via Chrome deviceScaleFactor",
|
|
98256
|
+
"hyperframes lambda render ./my-project --width 1920 --height 1080 --output-resolution 4k --wait"
|
|
98257
|
+
],
|
|
98025
98258
|
[
|
|
98026
98259
|
"Render with composition variables (personalised template)",
|
|
98027
98260
|
`hyperframes lambda render ./my-template --site-id abc1234deadbeef0 --width 1920 --height 1080 --variables '{"title":"Hello Alice","accent":"#ff0000"}'`
|
|
@@ -98106,6 +98339,10 @@ ${c2.bold("REQUIREMENTS:")}
|
|
|
98106
98339
|
"site-id": { type: "string", description: "Explicit site id (overrides content hash)" },
|
|
98107
98340
|
width: { type: "string", description: "Render width in pixels" },
|
|
98108
98341
|
height: { type: "string", description: "Render height in pixels" },
|
|
98342
|
+
"output-resolution": {
|
|
98343
|
+
type: "string",
|
|
98344
|
+
description: "Output resolution preset that engages Chrome deviceScaleFactor supersampling. Accepts canonical names (landscape, landscape-4k, portrait, portrait-4k, square, square-4k) and aliases (1080p, 4k, uhd, hd). When set, the composition's authored data-width/data-height is supersampled to the target preset without changing the layout."
|
|
98345
|
+
},
|
|
98109
98346
|
fps: { type: "string", description: "Render fps (24 | 30 | 60)" },
|
|
98110
98347
|
format: { type: "string", description: "mp4 | mov | png-sequence | webm (default: mp4)" },
|
|
98111
98348
|
codec: { type: "string", description: "h264 | h265 (mp4 only)" },
|
|
@@ -98260,6 +98497,7 @@ Or, for an opt-in dev setup:
|
|
|
98260
98497
|
fps: fpsRaw,
|
|
98261
98498
|
width,
|
|
98262
98499
|
height,
|
|
98500
|
+
outputResolution: parseOutputResolution(args["output-resolution"]),
|
|
98263
98501
|
format: parseFormat(args.format),
|
|
98264
98502
|
codec: parseCodec(args.codec),
|
|
98265
98503
|
quality: parseQuality(args.quality),
|
|
@@ -98311,6 +98549,7 @@ Or, for an opt-in dev setup:
|
|
|
98311
98549
|
fps: fpsRaw,
|
|
98312
98550
|
width,
|
|
98313
98551
|
height,
|
|
98552
|
+
outputResolution: parseOutputResolution(args["output-resolution"]),
|
|
98314
98553
|
format: parseFormat(args.format),
|
|
98315
98554
|
codec: parseCodec(args.codec),
|
|
98316
98555
|
quality: parseQuality(args.quality),
|
|
@@ -98513,7 +98752,7 @@ __export(autoUpdate_exports, {
|
|
|
98513
98752
|
import { spawn as spawn16 } from "child_process";
|
|
98514
98753
|
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync42, openSync as openSync2 } from "fs";
|
|
98515
98754
|
import { homedir as homedir12 } from "os";
|
|
98516
|
-
import { join as
|
|
98755
|
+
import { join as join88 } from "path";
|
|
98517
98756
|
import { compareVersions as compareVersions2 } from "compare-versions";
|
|
98518
98757
|
function isAutoInstallDisabled() {
|
|
98519
98758
|
if (isDevMode()) return true;
|
|
@@ -98536,7 +98775,7 @@ function log(line) {
|
|
|
98536
98775
|
}
|
|
98537
98776
|
function launchDetachedInstall(installCommand, version) {
|
|
98538
98777
|
mkdirSync42(CONFIG_DIR2, { recursive: true, mode: 448 });
|
|
98539
|
-
const configFile =
|
|
98778
|
+
const configFile = join88(CONFIG_DIR2, "config.json");
|
|
98540
98779
|
const nodeScript = `
|
|
98541
98780
|
const { exec } = require("node:child_process");
|
|
98542
98781
|
const { readFileSync, renameSync, writeFileSync } = require("node:fs");
|
|
@@ -98655,8 +98894,8 @@ var init_autoUpdate = __esm({
|
|
|
98655
98894
|
init_config();
|
|
98656
98895
|
init_env();
|
|
98657
98896
|
init_installerDetection();
|
|
98658
|
-
CONFIG_DIR2 =
|
|
98659
|
-
LOG_FILE =
|
|
98897
|
+
CONFIG_DIR2 = join88(homedir12(), ".hyperframes");
|
|
98898
|
+
LOG_FILE = join88(CONFIG_DIR2, "auto-update.log");
|
|
98660
98899
|
PENDING_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
98661
98900
|
}
|
|
98662
98901
|
});
|
|
@@ -98844,17 +99083,17 @@ var init_help = __esm({
|
|
|
98844
99083
|
// src/cli.ts
|
|
98845
99084
|
init_version();
|
|
98846
99085
|
init_dist();
|
|
98847
|
-
import { dirname as dirname32, join as
|
|
99086
|
+
import { dirname as dirname32, join as join89 } from "path";
|
|
98848
99087
|
import { fileURLToPath as fileURLToPath12 } from "url";
|
|
98849
|
-
import { existsSync as
|
|
99088
|
+
import { existsSync as existsSync80 } from "fs";
|
|
98850
99089
|
(() => {
|
|
98851
99090
|
const here = dirname32(fileURLToPath12(import.meta.url));
|
|
98852
|
-
const shader =
|
|
98853
|
-
const png =
|
|
98854
|
-
if (!process.env.HF_SHADER_WORKER_ENTRY &&
|
|
99091
|
+
const shader = join89(here, "shaderTransitionWorker.js");
|
|
99092
|
+
const png = join89(here, "pngDecodeBlitWorker.js");
|
|
99093
|
+
if (!process.env.HF_SHADER_WORKER_ENTRY && existsSync80(shader)) {
|
|
98855
99094
|
process.env.HF_SHADER_WORKER_ENTRY = shader;
|
|
98856
99095
|
}
|
|
98857
|
-
if (!process.env.HF_PNG_DECODE_BLIT_WORKER_ENTRY &&
|
|
99096
|
+
if (!process.env.HF_PNG_DECODE_BLIT_WORKER_ENTRY && existsSync80(png)) {
|
|
98858
99097
|
process.env.HF_PNG_DECODE_BLIT_WORKER_ENTRY = png;
|
|
98859
99098
|
}
|
|
98860
99099
|
})();
|
|
@@ -98866,10 +99105,10 @@ if (rootVersionRequested) {
|
|
|
98866
99105
|
process.exit(0);
|
|
98867
99106
|
}
|
|
98868
99107
|
try {
|
|
98869
|
-
const { readFileSync:
|
|
99108
|
+
const { readFileSync: readFileSync57 } = await import("fs");
|
|
98870
99109
|
const { resolve: resolve46 } = await import("path");
|
|
98871
99110
|
const envPath = resolve46(process.cwd(), ".env");
|
|
98872
|
-
const envContent =
|
|
99111
|
+
const envContent = readFileSync57(envPath, "utf-8");
|
|
98873
99112
|
for (const rawLine of envContent.split("\n")) {
|
|
98874
99113
|
let line = rawLine.trim();
|
|
98875
99114
|
if (!line || line.startsWith("#")) continue;
|