hyperframes 0.8.62 → 0.8.63
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 +422 -299
- package/dist/fontLocalizeCli.js +101 -32
- package/dist/hyperframes-player.global.js +1 -1
- package/dist/renderSetupWorker.js +4 -4
- package/dist/skills/media-use/scripts/lib/transcriptCutFade.mjs +21 -0
- package/dist/skills/media-use/scripts/lib/transcriptCutFade.test.mjs +33 -0
- package/dist/skills/media-use/scripts/transcript-cut.mjs +39 -8
- package/dist/skills/media-use/scripts/transcript-cut.test.mjs +117 -0
- package/dist/studio/assets/{hyperframes-player-BMHU9-3w.js → hyperframes-player-FmXtbvEE.js} +1 -1
- package/dist/studio/assets/{index-DS0kLbuM.css → index-BnsYeuxA.css} +1 -1
- package/dist/studio/assets/{index-Ce1SRT2i.js → index-CISQydDK.js} +1 -1
- package/dist/studio/assets/{index-DLYk_vu_.js → index-CjueZL58.js} +149 -149
- package/dist/studio/assets/{index-Dg0Vjj_i.js → index-DCqmNhmi.js} +1 -1
- package/dist/studio/index.d.ts +44 -1
- package/dist/studio/index.html +2 -2
- package/dist/studio/index.js +4941 -4995
- package/dist/studio/index.js.map +1 -1
- package/dist/studio/styles.css +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -50,7 +50,7 @@ var VERSION;
|
|
|
50
50
|
var init_version = __esm({
|
|
51
51
|
"src/version.ts"() {
|
|
52
52
|
"use strict";
|
|
53
|
-
VERSION = true ? "0.8.
|
|
53
|
+
VERSION = true ? "0.8.63" : "0.0.0-dev";
|
|
54
54
|
}
|
|
55
55
|
});
|
|
56
56
|
|
|
@@ -4887,7 +4887,7 @@ var require_util = __commonJS({
|
|
|
4887
4887
|
return path;
|
|
4888
4888
|
}
|
|
4889
4889
|
exports.normalize = normalize3;
|
|
4890
|
-
function
|
|
4890
|
+
function join164(aRoot, aPath) {
|
|
4891
4891
|
if (aRoot === "") {
|
|
4892
4892
|
aRoot = ".";
|
|
4893
4893
|
}
|
|
@@ -4919,7 +4919,7 @@ var require_util = __commonJS({
|
|
|
4919
4919
|
}
|
|
4920
4920
|
return joined;
|
|
4921
4921
|
}
|
|
4922
|
-
exports.join =
|
|
4922
|
+
exports.join = join164;
|
|
4923
4923
|
exports.isAbsolute = function(aPath) {
|
|
4924
4924
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
4925
4925
|
};
|
|
@@ -5092,7 +5092,7 @@ var require_util = __commonJS({
|
|
|
5092
5092
|
parsed.path = parsed.path.substring(0, index + 1);
|
|
5093
5093
|
}
|
|
5094
5094
|
}
|
|
5095
|
-
sourceURL =
|
|
5095
|
+
sourceURL = join164(urlGenerate(parsed), sourceURL);
|
|
5096
5096
|
}
|
|
5097
5097
|
return normalize3(sourceURL);
|
|
5098
5098
|
}
|
|
@@ -60906,8 +60906,8 @@ function redactKnownPaths(value, paths) {
|
|
|
60906
60906
|
for (const path of paths) {
|
|
60907
60907
|
if (typeof path !== "string" || path.length === 0)
|
|
60908
60908
|
continue;
|
|
60909
|
-
const
|
|
60910
|
-
for (const literal2 of [path,
|
|
60909
|
+
const basename35 = path.split(/[\\/]/).pop() ?? "";
|
|
60910
|
+
for (const literal2 of [path, basename35].filter((v2) => v2.length > 2)) {
|
|
60911
60911
|
out = out.split(literal2).join("[path]");
|
|
60912
60912
|
}
|
|
60913
60913
|
}
|
|
@@ -66117,17 +66117,22 @@ var BrowserLeasePool;
|
|
|
66117
66117
|
var init_browserLeasePool = __esm({
|
|
66118
66118
|
"../engine/src/services/browserLeasePool.ts"() {
|
|
66119
66119
|
"use strict";
|
|
66120
|
-
BrowserLeasePool = class {
|
|
66120
|
+
BrowserLeasePool = class _BrowserLeasePool {
|
|
66121
66121
|
constructor(options) {
|
|
66122
66122
|
this.options = options;
|
|
66123
66123
|
}
|
|
66124
66124
|
options;
|
|
66125
|
+
/** Under the CLI's 3s exit watchdog, alongside the render-wait bound it races. */
|
|
66126
|
+
static DRAIN_FORCE_CLOSE_MS = 1e3;
|
|
66125
66127
|
available = /* @__PURE__ */ new Map();
|
|
66126
66128
|
entries = /* @__PURE__ */ new Set();
|
|
66127
66129
|
leasesByBrowser = /* @__PURE__ */ new Map();
|
|
66128
66130
|
drainPromise = null;
|
|
66131
|
+
closed = false;
|
|
66129
66132
|
async acquire(fingerprintInput, pooled) {
|
|
66133
|
+
if (this.closed) throw new Error("Browser pool is closed; no new browsers can be acquired");
|
|
66130
66134
|
if (this.drainPromise) await this.drainPromise;
|
|
66135
|
+
if (this.closed) throw new Error("Browser pool is closed; no new browsers can be acquired");
|
|
66131
66136
|
const fingerprint = freezeFingerprint(fingerprintInput);
|
|
66132
66137
|
const entry = this.reserveEntry(fingerprint, pooled);
|
|
66133
66138
|
return this.issueLease(entry);
|
|
@@ -66186,17 +66191,30 @@ var init_browserLeasePool = __esm({
|
|
|
66186
66191
|
if (this.drainPromise) return this.drainPromise;
|
|
66187
66192
|
const entries2 = [...this.entries];
|
|
66188
66193
|
for (const entry of entries2) this.requestClose(entry, false);
|
|
66189
|
-
|
|
66194
|
+
const settle = Promise.all(entries2.map((entry) => entry.closePromise));
|
|
66195
|
+
const bound = new Promise(
|
|
66196
|
+
(resolve84) => setTimeout(resolve84, _BrowserLeasePool.DRAIN_FORCE_CLOSE_MS).unref()
|
|
66197
|
+
);
|
|
66198
|
+
this.drainPromise = Promise.race([settle, bound]).then(() => {
|
|
66199
|
+
for (const entry of entries2) if (this.entries.has(entry)) this.requestClose(entry, true);
|
|
66200
|
+
return settle;
|
|
66201
|
+
}).then(() => {
|
|
66190
66202
|
this.drainPromise = null;
|
|
66191
66203
|
});
|
|
66192
66204
|
return this.drainPromise;
|
|
66193
66205
|
}
|
|
66206
|
+
/** Terminal: drains every entry and refuses every `acquire()` after. */
|
|
66207
|
+
close() {
|
|
66208
|
+
this.closed = true;
|
|
66209
|
+
return this.drain();
|
|
66210
|
+
}
|
|
66194
66211
|
/** Test-only state reset. Call `drain()` first when entries own real browsers. */
|
|
66195
66212
|
reset() {
|
|
66196
66213
|
this.available.clear();
|
|
66197
66214
|
this.entries.clear();
|
|
66198
66215
|
this.leasesByBrowser.clear();
|
|
66199
66216
|
this.drainPromise = null;
|
|
66217
|
+
this.closed = false;
|
|
66200
66218
|
}
|
|
66201
66219
|
createEntry(key2, fingerprint, pooled) {
|
|
66202
66220
|
const entry = {
|
|
@@ -66730,6 +66748,9 @@ function forceReleaseBrowser(browser) {
|
|
|
66730
66748
|
async function drainBrowserPool() {
|
|
66731
66749
|
await browserLeasePool.drain();
|
|
66732
66750
|
}
|
|
66751
|
+
async function closeBrowserPool() {
|
|
66752
|
+
await browserLeasePool.close();
|
|
66753
|
+
}
|
|
66733
66754
|
function probeNvidiaVramMb() {
|
|
66734
66755
|
if (_cachedVramMb !== null) return _cachedVramMb;
|
|
66735
66756
|
try {
|
|
@@ -73753,11 +73774,19 @@ async function extractMediaMetadata(filePath) {
|
|
|
73753
73774
|
});
|
|
73754
73775
|
return probePromise;
|
|
73755
73776
|
}
|
|
73777
|
+
function resolveStreamWindow(filePath, metadata) {
|
|
73778
|
+
const videoStreamDurationSeconds = metadata.videoStreamDurationSeconds;
|
|
73779
|
+
const candidateStart = metadata.videoStreamStartSeconds ?? 0;
|
|
73780
|
+
const videoStreamStartSeconds = Number.isFinite(candidateStart) ? candidateStart : 0;
|
|
73781
|
+
const cacheKey = `${filePath}\0${String(videoStreamStartSeconds)}\0${String(videoStreamDurationSeconds)}`;
|
|
73782
|
+
return { videoStreamStartSeconds, videoStreamDurationSeconds, cacheKey };
|
|
73783
|
+
}
|
|
73756
73784
|
async function extractFinalVideoFrameTimestamp(filePath, metadata, signal) {
|
|
73757
|
-
const
|
|
73758
|
-
|
|
73759
|
-
|
|
73760
|
-
|
|
73785
|
+
const {
|
|
73786
|
+
videoStreamStartSeconds,
|
|
73787
|
+
videoStreamDurationSeconds: videoDurationSeconds,
|
|
73788
|
+
cacheKey
|
|
73789
|
+
} = resolveStreamWindow(filePath, metadata);
|
|
73761
73790
|
let probeCache = finalVideoFrameTimestampCache;
|
|
73762
73791
|
if (signal) {
|
|
73763
73792
|
probeCache = finalVideoFrameTimestampSignalCaches.get(signal) ?? /* @__PURE__ */ new Map();
|
|
@@ -73860,19 +73889,27 @@ async function extractAudioMetadata(filePath, options) {
|
|
|
73860
73889
|
});
|
|
73861
73890
|
return probePromise;
|
|
73862
73891
|
}
|
|
73863
|
-
async function analyzeKeyframeIntervals(filePath) {
|
|
73864
|
-
const
|
|
73892
|
+
async function analyzeKeyframeIntervals(filePath, metadata) {
|
|
73893
|
+
const { videoStreamStartSeconds, videoStreamDurationSeconds, cacheKey } = resolveStreamWindow(
|
|
73894
|
+
filePath,
|
|
73895
|
+
metadata
|
|
73896
|
+
);
|
|
73897
|
+
const cached3 = keyframeCache.get(cacheKey);
|
|
73865
73898
|
if (cached3) return cached3;
|
|
73866
|
-
const promise = analyzeKeyframeIntervalsUncached(
|
|
73867
|
-
|
|
73899
|
+
const promise = analyzeKeyframeIntervalsUncached(
|
|
73900
|
+
filePath,
|
|
73901
|
+
videoStreamStartSeconds,
|
|
73902
|
+
videoStreamDurationSeconds
|
|
73903
|
+
);
|
|
73904
|
+
keyframeCache.set(cacheKey, promise);
|
|
73868
73905
|
promise.catch(() => {
|
|
73869
|
-
if (keyframeCache.get(
|
|
73870
|
-
keyframeCache.delete(
|
|
73906
|
+
if (keyframeCache.get(cacheKey) === promise) {
|
|
73907
|
+
keyframeCache.delete(cacheKey);
|
|
73871
73908
|
}
|
|
73872
73909
|
});
|
|
73873
73910
|
return promise;
|
|
73874
73911
|
}
|
|
73875
|
-
async function analyzeKeyframeIntervalsUncached(filePath) {
|
|
73912
|
+
async function analyzeKeyframeIntervalsUncached(filePath, videoStreamStartSeconds, videoStreamDurationSeconds) {
|
|
73876
73913
|
const stdout2 = await runFfprobe(filePath, [
|
|
73877
73914
|
"-select_streams",
|
|
73878
73915
|
"v:0",
|
|
@@ -73884,14 +73921,26 @@ async function analyzeKeyframeIntervalsUncached(filePath) {
|
|
|
73884
73921
|
"csv=p=0"
|
|
73885
73922
|
]);
|
|
73886
73923
|
const timestamps = stdout2.split("\n").map((line3) => parseFloat(line3.trim())).filter((t) => Number.isFinite(t));
|
|
73887
|
-
if (timestamps.length
|
|
73924
|
+
if (timestamps.length === 0) {
|
|
73888
73925
|
return {
|
|
73889
73926
|
avgIntervalSeconds: 0,
|
|
73890
73927
|
maxIntervalSeconds: 0,
|
|
73891
|
-
keyframeCount:
|
|
73928
|
+
keyframeCount: 0,
|
|
73892
73929
|
isProblematic: false
|
|
73893
73930
|
};
|
|
73894
73931
|
}
|
|
73932
|
+
if (timestamps.length === 1) {
|
|
73933
|
+
const streamEnd = videoStreamStartSeconds + videoStreamDurationSeconds;
|
|
73934
|
+
const rawInterval = streamEnd - (timestamps[0] ?? videoStreamStartSeconds);
|
|
73935
|
+
const singleGopInterval = Number.isFinite(rawInterval) ? Math.max(rawInterval, 0) : 0;
|
|
73936
|
+
const roundedInterval = Math.round(singleGopInterval * 100) / 100;
|
|
73937
|
+
return {
|
|
73938
|
+
avgIntervalSeconds: roundedInterval,
|
|
73939
|
+
maxIntervalSeconds: roundedInterval,
|
|
73940
|
+
keyframeCount: 1,
|
|
73941
|
+
isProblematic: singleGopInterval > PROBLEMATIC_KEYFRAME_INTERVAL_SECONDS
|
|
73942
|
+
};
|
|
73943
|
+
}
|
|
73895
73944
|
let maxInterval = 0;
|
|
73896
73945
|
let totalInterval = 0;
|
|
73897
73946
|
for (let i = 1; i < timestamps.length; i++) {
|
|
@@ -73904,10 +73953,10 @@ async function analyzeKeyframeIntervalsUncached(filePath) {
|
|
|
73904
73953
|
avgIntervalSeconds: Math.round(avgInterval * 100) / 100,
|
|
73905
73954
|
maxIntervalSeconds: Math.round(maxInterval * 100) / 100,
|
|
73906
73955
|
keyframeCount: timestamps.length,
|
|
73907
|
-
isProblematic: maxInterval >
|
|
73956
|
+
isProblematic: maxInterval > PROBLEMATIC_KEYFRAME_INTERVAL_SECONDS
|
|
73908
73957
|
};
|
|
73909
73958
|
}
|
|
73910
|
-
var FFPROBE_STDERR_MAX_BYTES, FFPROBE_STDOUT_MAX_CHARS, FFPROBE_ERROR_MAX_CHARS, videoMetadataCache, finalVideoFrameTimestampCache, finalVideoFrameTimestampSignalCaches, audioMetadataCache, mediaProbeOutputCache, mediaProbeOutputSignalCaches, MEDIA_PROBE_OUTPUT_CACHE_MAX_ENTRIES, AAC_LC_SAMPLES_PER_PACKET, STILL_IMAGE_DEMUXERS, StructurallyIncompletePngError, extractVideoMetadata, keyframeCache;
|
|
73959
|
+
var FFPROBE_STDERR_MAX_BYTES, FFPROBE_STDOUT_MAX_CHARS, FFPROBE_ERROR_MAX_CHARS, videoMetadataCache, finalVideoFrameTimestampCache, finalVideoFrameTimestampSignalCaches, audioMetadataCache, mediaProbeOutputCache, mediaProbeOutputSignalCaches, MEDIA_PROBE_OUTPUT_CACHE_MAX_ENTRIES, AAC_LC_SAMPLES_PER_PACKET, STILL_IMAGE_DEMUXERS, StructurallyIncompletePngError, extractVideoMetadata, keyframeCache, PROBLEMATIC_KEYFRAME_INTERVAL_SECONDS;
|
|
73911
73960
|
var init_ffprobe = __esm({
|
|
73912
73961
|
"../engine/src/utils/ffprobe.ts"() {
|
|
73913
73962
|
"use strict";
|
|
@@ -73950,6 +73999,7 @@ var init_ffprobe = __esm({
|
|
|
73950
73999
|
};
|
|
73951
74000
|
extractVideoMetadata = extractMediaMetadata;
|
|
73952
74001
|
keyframeCache = /* @__PURE__ */ new Map();
|
|
74002
|
+
PROBLEMATIC_KEYFRAME_INTERVAL_SECONDS = 2;
|
|
73953
74003
|
}
|
|
73954
74004
|
});
|
|
73955
74005
|
|
|
@@ -75140,10 +75190,10 @@ function collectSubCompositionSrcs(html) {
|
|
|
75140
75190
|
function cleanAssetUrl(url) {
|
|
75141
75191
|
return url.trim().split(/[?#]/, 1)[0] ?? "";
|
|
75142
75192
|
}
|
|
75143
|
-
function isWithinProjectRoot(projectDir, candidate) {
|
|
75144
|
-
const projectRoot =
|
|
75145
|
-
const relativePath =
|
|
75146
|
-
return relativePath === "" || !relativePath.startsWith("..") && !
|
|
75193
|
+
function isWithinProjectRoot(projectDir, candidate, pathModule = { resolve: resolve6, relative: relative2, isAbsolute: isAbsolute2 }) {
|
|
75194
|
+
const projectRoot = pathModule.resolve(projectDir);
|
|
75195
|
+
const relativePath = pathModule.relative(projectRoot, candidate);
|
|
75196
|
+
return relativePath === "" || !relativePath.startsWith("..") && !pathModule.isAbsolute(relativePath);
|
|
75147
75197
|
}
|
|
75148
75198
|
function addCandidate(candidates, candidate) {
|
|
75149
75199
|
if (!candidates.includes(candidate)) candidates.push(candidate);
|
|
@@ -95460,6 +95510,14 @@ function readRegularFile(filePath) {
|
|
|
95460
95510
|
closeSync4(fd);
|
|
95461
95511
|
}
|
|
95462
95512
|
}
|
|
95513
|
+
function resolveContainedPaths(projectDir, compiledDir, relativePath) {
|
|
95514
|
+
const projectPath = join20(projectDir, relativePath);
|
|
95515
|
+
if (!isWithinProjectRoot(projectDir, projectPath)) return null;
|
|
95516
|
+
if (!compiledDir) return { projectPath, compiledPath: null };
|
|
95517
|
+
const compiledPath = join20(compiledDir, relativePath);
|
|
95518
|
+
if (!isWithinProjectRoot(compiledDir, compiledPath)) return null;
|
|
95519
|
+
return { projectPath, compiledPath };
|
|
95520
|
+
}
|
|
95463
95521
|
function createFileServer(options) {
|
|
95464
95522
|
const { projectDir, compiledDir, port = 0, stripEmbeddedRuntime = true } = options;
|
|
95465
95523
|
const headScripts = options.headScripts ?? [];
|
|
@@ -95469,8 +95527,9 @@ function createFileServer(options) {
|
|
|
95469
95527
|
let requestPath = c3.req.path;
|
|
95470
95528
|
if (requestPath === "/") requestPath = "/index.html";
|
|
95471
95529
|
const relativePath = requestPath.replace(/^\//, "");
|
|
95472
|
-
const
|
|
95473
|
-
|
|
95530
|
+
const resolved2 = resolveContainedPaths(projectDir, compiledDir, relativePath);
|
|
95531
|
+
if (!resolved2) return c3.text("Not found", 404);
|
|
95532
|
+
const content = (resolved2.compiledPath ? readRegularFile(resolved2.compiledPath) : null) ?? readRegularFile(resolved2.projectPath);
|
|
95474
95533
|
if (content === null) return c3.text("Not found", 404);
|
|
95475
95534
|
const ext = extname4(relativePath).toLowerCase();
|
|
95476
95535
|
const contentType = MIME_TYPES[ext] || "application/octet-stream";
|
|
@@ -95501,6 +95560,7 @@ var init_fileServer = __esm({
|
|
|
95501
95560
|
"../engine/src/services/fileServer.ts"() {
|
|
95502
95561
|
"use strict";
|
|
95503
95562
|
init_compiler();
|
|
95563
|
+
init_assetResolution();
|
|
95504
95564
|
MIME_TYPES = {
|
|
95505
95565
|
".html": "text/html; charset=utf-8",
|
|
95506
95566
|
".css": "text/css; charset=utf-8",
|
|
@@ -96654,6 +96714,7 @@ __export(src_exports, {
|
|
|
96654
96714
|
classifyVideoExtractionError: () => classifyVideoExtractionError,
|
|
96655
96715
|
cloneCaptureWarning: () => cloneCaptureWarning,
|
|
96656
96716
|
cloneCaptureWarnings: () => cloneCaptureWarnings,
|
|
96717
|
+
closeBrowserPool: () => closeBrowserPool,
|
|
96657
96718
|
closeCaptureSession: () => closeCaptureSession,
|
|
96658
96719
|
completeDeferredDrawElementInit: () => completeDeferredDrawElementInit,
|
|
96659
96720
|
compositionRequiresWebGpu: () => compositionRequiresWebGpu,
|
|
@@ -96981,6 +97042,18 @@ var init_agent_runtime = __esm({
|
|
|
96981
97042
|
"use strict";
|
|
96982
97043
|
init_platform();
|
|
96983
97044
|
VENDOR_RULES = [
|
|
97045
|
+
// IBM Bob Shell — both shell execution paths stamp BOBSHELL_CLI=1 onto the
|
|
97046
|
+
// child environment: childProcessFallback's spawn env and executeWithPty's
|
|
97047
|
+
// PTY env. Keep this ahead of other agents because Bob inherits the parent
|
|
97048
|
+
// environment, so a Bob session launched from Codex or Claude can carry both
|
|
97049
|
+
// vendors' markers; BOBSHELL_CLI identifies the immediate executor.
|
|
97050
|
+
// BOBSHELL_API_KEY is deliberately ignored: it is an authentication setting,
|
|
97051
|
+
// not proof that Bob launched the current process.
|
|
97052
|
+
// Source: IBM Bob Shell 1.0.6 bundle (lb.childProcessFallback / executeWithPty).
|
|
97053
|
+
{
|
|
97054
|
+
name: "bob",
|
|
97055
|
+
check: (env) => typeof env["BOBSHELL_CLI"] === "string"
|
|
97056
|
+
},
|
|
96984
97057
|
// Anthropic Claude Code — sets CLAUDECODE=1 on every Bash/PowerShell tool
|
|
96985
97058
|
// spawn (Shell.ts:321) and CLAUDE_CODE_ENTRYPOINT at startup, inherited by
|
|
96986
97059
|
// every child (main.tsx:527). Both propagate to spawned subprocesses.
|
|
@@ -133534,10 +133607,12 @@ var init_videoFrameCoverage = __esm({
|
|
|
133534
133607
|
});
|
|
133535
133608
|
|
|
133536
133609
|
// ../producer/src/services/renderMediaCollector.ts
|
|
133537
|
-
function
|
|
133538
|
-
|
|
133539
|
-
|
|
133540
|
-
|
|
133610
|
+
function resolveHostEnd(host, hostStart) {
|
|
133611
|
+
return resolveAuthoredTimingWindow({
|
|
133612
|
+
start: hostStart,
|
|
133613
|
+
duration: host.getAttribute("data-duration"),
|
|
133614
|
+
end: host.getAttribute("data-end")
|
|
133615
|
+
})?.end ?? null;
|
|
133541
133616
|
}
|
|
133542
133617
|
function resolveHostWindow(element, document2, startCache, visiting) {
|
|
133543
133618
|
const hosts = [];
|
|
@@ -133549,7 +133624,7 @@ function resolveHostWindow(element, document2, startCache, visiting) {
|
|
|
133549
133624
|
let limit = Infinity;
|
|
133550
133625
|
for (const host of hosts.reverse()) {
|
|
133551
133626
|
const hostStart = resolveReferencedStart(document2, host, startCache, visiting);
|
|
133552
|
-
const hostEnd =
|
|
133627
|
+
const hostEnd = resolveHostEnd(host, hostStart);
|
|
133553
133628
|
if (hostEnd != null) limit = Math.min(limit, offset2 + hostEnd);
|
|
133554
133629
|
offset2 += hostStart;
|
|
133555
133630
|
}
|
|
@@ -139555,10 +139630,11 @@ async function compileForRender(projectDir, htmlPath, downloadDir, options = {})
|
|
|
139555
139630
|
if (isHttpUrl(video.src)) continue;
|
|
139556
139631
|
const videoPath = resolve33(projectDir, video.src);
|
|
139557
139632
|
const reencode = `ffmpeg -i "${video.src}" -c:v libx264 -r 30 -g 30 -keyint_min 30 -movflags +faststart -c:a copy output.mp4`;
|
|
139558
|
-
|
|
139559
|
-
withMediaProbeSlot(() =>
|
|
139560
|
-
|
|
139561
|
-
|
|
139633
|
+
(async () => {
|
|
139634
|
+
const metadata = await withMediaProbeSlot(() => extractMediaMetadata(videoPath));
|
|
139635
|
+
const analysis = await withMediaProbeSlot(
|
|
139636
|
+
() => analyzeKeyframeIntervals(videoPath, metadata)
|
|
139637
|
+
);
|
|
139562
139638
|
if (analysis.isProblematic) {
|
|
139563
139639
|
defaultLogger.warn(
|
|
139564
139640
|
`[Compiler] WARNING: Video "${video.id}" has sparse keyframes (max interval: ${analysis.maxIntervalSeconds}s). This causes seek failures and frame freezing. Re-encode with: ${reencode}`
|
|
@@ -139569,7 +139645,7 @@ async function compileForRender(projectDir, htmlPath, downloadDir, options = {})
|
|
|
139569
139645
|
`[Compiler] Video "${video.id}" is variable frame rate (VFR); the engine will normalize it to CFR before frame extraction. If rendering feels slow on this video, pre-encode once with: ${reencode}`
|
|
139570
139646
|
);
|
|
139571
139647
|
}
|
|
139572
|
-
}).catch(() => {
|
|
139648
|
+
})().catch(() => {
|
|
139573
139649
|
});
|
|
139574
139650
|
}
|
|
139575
139651
|
const { document: document2 } = parseHTML(html);
|
|
@@ -151340,7 +151416,6 @@ var init_pipeline = __esm({
|
|
|
151340
151416
|
// src/server/studioServer.ts
|
|
151341
151417
|
var studioServer_exports = {};
|
|
151342
151418
|
__export(studioServer_exports, {
|
|
151343
|
-
closeThumbnailBrowser: () => closeThumbnailBrowser,
|
|
151344
151419
|
createStudioServer: () => createStudioServer,
|
|
151345
151420
|
loadPreviewServerBuildSignature: () => loadPreviewServerBuildSignature,
|
|
151346
151421
|
resolveStudioBundle: () => resolveStudioBundle
|
|
@@ -151448,7 +151523,8 @@ async function downloadRemoteGifImageSources(html, downloadDir, downloadToTemp2)
|
|
|
151448
151523
|
);
|
|
151449
151524
|
return sourceAssets;
|
|
151450
151525
|
}
|
|
151451
|
-
async function getThumbnailBrowser(requestedGpuMode) {
|
|
151526
|
+
async function getThumbnailBrowser(requestedGpuMode, isShuttingDown) {
|
|
151527
|
+
if (isShuttingDown()) return null;
|
|
151452
151528
|
if (_thumbnailBrowserLease?.browser.connected && _thumbnailBrowserModes?.requested === requestedGpuMode) {
|
|
151453
151529
|
return {
|
|
151454
151530
|
browser: _thumbnailBrowserLease.browser,
|
|
@@ -151463,6 +151539,7 @@ async function getThumbnailBrowser(requestedGpuMode) {
|
|
|
151463
151539
|
if (_thumbnailBrowserLease) await closeThumbnailBrowser();
|
|
151464
151540
|
_thumbnailBrowserInitializing = (async () => {
|
|
151465
151541
|
try {
|
|
151542
|
+
if (isShuttingDown()) return null;
|
|
151466
151543
|
const { ensureBrowser: ensureBrowser2 } = await Promise.resolve().then(() => (init_manager2(), manager_exports2));
|
|
151467
151544
|
const { acquireBrowser: acquireBrowser2, buildChromeArgs: buildChromeArgs2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
151468
151545
|
let executablePath;
|
|
@@ -151503,6 +151580,8 @@ async function getThumbnailBrowser(requestedGpuMode) {
|
|
|
151503
151580
|
return _thumbnailBrowserInitializing;
|
|
151504
151581
|
}
|
|
151505
151582
|
async function closeThumbnailBrowser() {
|
|
151583
|
+
if (_thumbnailBrowserInitializing) await _thumbnailBrowserInitializing.catch(() => {
|
|
151584
|
+
});
|
|
151506
151585
|
if (!_thumbnailBrowserLease) return;
|
|
151507
151586
|
const lease = _thumbnailBrowserLease;
|
|
151508
151587
|
_thumbnailBrowserLease = null;
|
|
@@ -151566,6 +151645,8 @@ function createStudioServer(options) {
|
|
|
151566
151645
|
cachedProjectSignature = null;
|
|
151567
151646
|
}
|
|
151568
151647
|
});
|
|
151648
|
+
const inFlightRenders = /* @__PURE__ */ new Map();
|
|
151649
|
+
let shuttingDown = false;
|
|
151569
151650
|
const adapter2 = {
|
|
151570
151651
|
// Explicit option wins (preview's resolved --proxy/--no-proxy + config);
|
|
151571
151652
|
// otherwise honor the project's hyperframes.json media.autoProxy so every
|
|
@@ -151629,6 +151710,15 @@ function createStudioServer(options) {
|
|
|
151629
151710
|
runtimeUrl: "/api/runtime.js",
|
|
151630
151711
|
rendersDir: () => join91(projectDir, "renders"),
|
|
151631
151712
|
startRender(opts) {
|
|
151713
|
+
if (shuttingDown) {
|
|
151714
|
+
return {
|
|
151715
|
+
id: opts.jobId,
|
|
151716
|
+
status: "failed",
|
|
151717
|
+
progress: 0,
|
|
151718
|
+
outputPath: opts.outputPath,
|
|
151719
|
+
error: "Studio server is shutting down"
|
|
151720
|
+
};
|
|
151721
|
+
}
|
|
151632
151722
|
refreshTelemetryPosture();
|
|
151633
151723
|
const abortController = new AbortController();
|
|
151634
151724
|
const state = {
|
|
@@ -151639,7 +151729,7 @@ function createStudioServer(options) {
|
|
|
151639
151729
|
cancel: () => abortController.abort()
|
|
151640
151730
|
};
|
|
151641
151731
|
const startTime = Date.now();
|
|
151642
|
-
(async () => {
|
|
151732
|
+
const run2 = (async () => {
|
|
151643
151733
|
let renderJob;
|
|
151644
151734
|
const removeCancelledOutput = () => {
|
|
151645
151735
|
state.status = "cancelled";
|
|
@@ -151711,6 +151801,9 @@ function createStudioServer(options) {
|
|
|
151711
151801
|
}
|
|
151712
151802
|
}
|
|
151713
151803
|
})();
|
|
151804
|
+
inFlightRenders.set(abortController, run2);
|
|
151805
|
+
const forget = () => void inFlightRenders.delete(abortController);
|
|
151806
|
+
run2.then(forget, forget);
|
|
151714
151807
|
return state;
|
|
151715
151808
|
},
|
|
151716
151809
|
startBackgroundRemoval(opts) {
|
|
@@ -151723,9 +151816,11 @@ function createStudioServer(options) {
|
|
|
151723
151816
|
});
|
|
151724
151817
|
},
|
|
151725
151818
|
async generateThumbnail(opts) {
|
|
151726
|
-
const session = await getThumbnailBrowser(browserGpuMode);
|
|
151819
|
+
const session = await getThumbnailBrowser(browserGpuMode, () => shuttingDown);
|
|
151727
151820
|
if (!session) {
|
|
151728
|
-
|
|
151821
|
+
if (!shuttingDown) {
|
|
151822
|
+
console.warn("[Studio] Thumbnail: no browser available \u2014 Chrome may not be installed");
|
|
151823
|
+
}
|
|
151729
151824
|
return null;
|
|
151730
151825
|
}
|
|
151731
151826
|
const sourcePath = join91(opts.project.dir, opts.compPath);
|
|
@@ -151943,6 +152038,7 @@ function createStudioServer(options) {
|
|
|
151943
152038
|
});
|
|
151944
152039
|
const serveStudioStaticFile = (cacheControl) => (c3) => {
|
|
151945
152040
|
const filePath = resolve39(studioDir, c3.req.path.slice(1));
|
|
152041
|
+
if (!isWithinProjectRoot(studioDir, filePath)) return c3.text("not found", 404);
|
|
151946
152042
|
const content = readBundleFile(filePath);
|
|
151947
152043
|
if (content === null) return c3.text("not found", 404);
|
|
151948
152044
|
return new Response(content, {
|
|
@@ -152028,9 +152124,27 @@ function createStudioServer(options) {
|
|
|
152028
152124
|
}
|
|
152029
152125
|
return c3.html(html, 200, { "Cache-Control": "no-cache" });
|
|
152030
152126
|
});
|
|
152031
|
-
|
|
152127
|
+
const shutdown = async () => {
|
|
152128
|
+
shuttingDown = true;
|
|
152129
|
+
const renders = [...inFlightRenders];
|
|
152130
|
+
for (const [abortController] of renders) abortController.abort();
|
|
152131
|
+
const { killTrackedProcesses: killTrackedProcesses2, closeBrowserPool: closeBrowserPool2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
152132
|
+
killTrackedProcesses2();
|
|
152133
|
+
const closeBrowsers = Promise.allSettled([
|
|
152134
|
+
closeThumbnailBrowser().catch(() => {
|
|
152135
|
+
}),
|
|
152136
|
+
closeBrowserPool2().catch(() => {
|
|
152137
|
+
})
|
|
152138
|
+
]);
|
|
152139
|
+
await Promise.race([
|
|
152140
|
+
Promise.allSettled(renders.map(([, done]) => done)),
|
|
152141
|
+
new Promise((resolve84) => setTimeout(resolve84, RENDER_SHUTDOWN_WAIT_MS).unref())
|
|
152142
|
+
]);
|
|
152143
|
+
await closeBrowsers;
|
|
152144
|
+
};
|
|
152145
|
+
return { app, watcher, adapter: adapter2, shutdown };
|
|
152032
152146
|
}
|
|
152033
|
-
var STUDIO_MANUAL_EDITS_PATH2, IMMUTABLE_CACHE_CONTROL, REMOTE_GIF_IMG_SRC_RE, _thumbnailBrowserLease, _thumbnailBrowserInitializing, _thumbnailBrowserModes;
|
|
152147
|
+
var STUDIO_MANUAL_EDITS_PATH2, RENDER_SHUTDOWN_WAIT_MS, IMMUTABLE_CACHE_CONTROL, REMOTE_GIF_IMG_SRC_RE, _thumbnailBrowserLease, _thumbnailBrowserInitializing, _thumbnailBrowserModes;
|
|
152034
152148
|
var init_studioServer = __esm({
|
|
152035
152149
|
"src/server/studioServer.ts"() {
|
|
152036
152150
|
"use strict";
|
|
@@ -152045,9 +152159,11 @@ var init_studioServer = __esm({
|
|
|
152045
152159
|
init_dist9();
|
|
152046
152160
|
init_projectConfig();
|
|
152047
152161
|
init_screenshotClip();
|
|
152162
|
+
init_assetResolution();
|
|
152048
152163
|
init_captureCompositionFrame();
|
|
152049
152164
|
init_gpuPolicy();
|
|
152050
152165
|
STUDIO_MANUAL_EDITS_PATH2 = ".hyperframes/studio-manual-edits.json";
|
|
152166
|
+
RENDER_SHUTDOWN_WAIT_MS = 2e3;
|
|
152051
152167
|
IMMUTABLE_CACHE_CONTROL = "public, max-age=31536000, immutable";
|
|
152052
152168
|
REMOTE_GIF_IMG_SRC_RE = /<img\b[^>]*?\bsrc\s*=\s*["'](https?:\/\/[^"']+\.gif(?:[?#][^"']*)?)["'][^>]*>/gi;
|
|
152053
152169
|
_thumbnailBrowserLease = null;
|
|
@@ -152756,7 +152872,11 @@ async function runEmbeddedMode(dir, startPort, options) {
|
|
|
152756
152872
|
return;
|
|
152757
152873
|
}
|
|
152758
152874
|
const serverBuildSignature = await loadPreviewServerBuildSignature2();
|
|
152759
|
-
const {
|
|
152875
|
+
const {
|
|
152876
|
+
app,
|
|
152877
|
+
watcher,
|
|
152878
|
+
shutdown: shutdownStudio
|
|
152879
|
+
} = createStudioServer2({
|
|
152760
152880
|
projectDir: dir,
|
|
152761
152881
|
projectName: pName,
|
|
152762
152882
|
autoProxy: options?.autoProxy,
|
|
@@ -152845,28 +152965,17 @@ async function runEmbeddedMode(dir, startPort, options) {
|
|
|
152845
152965
|
const shutdown = () => {
|
|
152846
152966
|
if (shuttingDown) return;
|
|
152847
152967
|
shuttingDown = true;
|
|
152848
|
-
process.off("SIGINT", shutdown);
|
|
152849
|
-
process.off("SIGTERM", shutdown);
|
|
152850
152968
|
rl?.close();
|
|
152851
152969
|
reportPreviewShutdown(Boolean(options?.json));
|
|
152852
152970
|
setTimeout(() => requestCliExit(0), 3e3).unref();
|
|
152853
|
-
|
|
152854
|
-
const { closeThumbnailBrowser: closeThumbnailBrowser2 } = await Promise.resolve().then(() => (init_studioServer(), studioServer_exports));
|
|
152855
|
-
const { drainBrowserPool: drainBrowserPool2, killTrackedProcesses: killTrackedProcesses2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
152856
|
-
killTrackedProcesses2();
|
|
152857
|
-
await closeThumbnailBrowser2().catch(() => {
|
|
152858
|
-
});
|
|
152859
|
-
await drainBrowserPool2().catch(() => {
|
|
152860
|
-
});
|
|
152861
|
-
};
|
|
152862
|
-
cleanup().catch(() => {
|
|
152971
|
+
shutdownStudio().catch(() => {
|
|
152863
152972
|
}).finally(() => {
|
|
152864
152973
|
watcher.close();
|
|
152865
152974
|
result.server.close(() => resolveRun());
|
|
152866
152975
|
});
|
|
152867
152976
|
};
|
|
152868
|
-
process.
|
|
152869
|
-
process.
|
|
152977
|
+
process.on("SIGINT", shutdown);
|
|
152978
|
+
process.on("SIGTERM", shutdown);
|
|
152870
152979
|
Promise.resolve().then(() => (init_src(), src_exports)).then(({ killTrackedProcesses: killTrackedProcesses2 }) => {
|
|
152871
152980
|
process.once("exit", () => {
|
|
152872
152981
|
if (!shuttingDown) killTrackedProcesses2();
|
|
@@ -174692,9 +174801,27 @@ var init_events2 = __esm({
|
|
|
174692
174801
|
});
|
|
174693
174802
|
|
|
174694
174803
|
// src/capture/captureFile.ts
|
|
174695
|
-
|
|
174804
|
+
var captureFile_exports = {};
|
|
174805
|
+
__export(captureFile_exports, {
|
|
174806
|
+
writeCaptureFileSync: () => writeCaptureFileSync
|
|
174807
|
+
});
|
|
174808
|
+
import { mkdtempSync as mkdtempSync24, renameSync as renameSync21, rmSync as rmSync37, writeFileSync as writeFileSync47 } from "fs";
|
|
174809
|
+
import { basename as basename27, dirname as dirname61, join as join126 } from "path";
|
|
174810
|
+
function publishCaptureFileSync(path, data2, options) {
|
|
174811
|
+
const stagingDir = mkdtempSync24(join126(dirname61(path), ".capture-"));
|
|
174812
|
+
try {
|
|
174813
|
+
const staged = join126(stagingDir, basename27(path));
|
|
174814
|
+
writeCaptureFileSync(staged, data2, { ...options, flag: "wx" });
|
|
174815
|
+
renameSync21(staged, path);
|
|
174816
|
+
} finally {
|
|
174817
|
+
rmSync37(stagingDir, { recursive: true, force: true });
|
|
174818
|
+
}
|
|
174819
|
+
}
|
|
174696
174820
|
function writeCaptureFileSync(path, data2, options) {
|
|
174697
174821
|
const normalized2 = typeof options === "string" ? { encoding: options } : options;
|
|
174822
|
+
if (normalized2?.flag === void 0 || normalized2.flag === "w") {
|
|
174823
|
+
return publishCaptureFileSync(path, data2, normalized2);
|
|
174824
|
+
}
|
|
174698
174825
|
writeFileSync47(path, data2, { ...normalized2, mode: 384 });
|
|
174699
174826
|
}
|
|
174700
174827
|
var init_captureFile = __esm({
|
|
@@ -174714,7 +174841,7 @@ __export(contactSheet_exports, {
|
|
|
174714
174841
|
});
|
|
174715
174842
|
import sharp from "sharp";
|
|
174716
174843
|
import { readdirSync as readdirSync39, readFileSync as readFileSync85, unlinkSync as unlinkSync10, existsSync as existsSync111 } from "fs";
|
|
174717
|
-
import { join as
|
|
174844
|
+
import { join as join127, extname as extname19, basename as basename28, dirname as dirname62 } from "path";
|
|
174718
174845
|
async function createContactSheet(imagePaths, outputPath, opts = {}) {
|
|
174719
174846
|
const {
|
|
174720
174847
|
cols = 3,
|
|
@@ -174748,7 +174875,7 @@ async function createContactSheet(imagePaths, outputPath, opts = {}) {
|
|
|
174748
174875
|
overlays.push({ input: resized, left: x2, top: y + labelH });
|
|
174749
174876
|
let labelText = `${i + 1}`;
|
|
174750
174877
|
if (labelMode === "filename") {
|
|
174751
|
-
labelText = `${i + 1}. ${
|
|
174878
|
+
labelText = `${i + 1}. ${basename28(files[i]).replace(extname19(files[i]), "")}`;
|
|
174752
174879
|
} else if (labelMode === "custom" && labels?.[i]) {
|
|
174753
174880
|
labelText = `${i + 1}. ${labels[i]}`;
|
|
174754
174881
|
}
|
|
@@ -174766,11 +174893,8 @@ async function createContactSheet(imagePaths, outputPath, opts = {}) {
|
|
|
174766
174893
|
background: { r: 26, g: 26, b: 26 }
|
|
174767
174894
|
}
|
|
174768
174895
|
}).composite(overlays);
|
|
174769
|
-
|
|
174770
|
-
|
|
174771
|
-
} else {
|
|
174772
|
-
await sheet.jpeg({ quality }).toFile(outputPath);
|
|
174773
|
-
}
|
|
174896
|
+
const encoded = extname19(outputPath).toLowerCase() === ".png" ? await sheet.png().toBuffer() : await sheet.jpeg({ quality }).toBuffer();
|
|
174897
|
+
writeCaptureFileSync(outputPath, encoded);
|
|
174774
174898
|
return outputPath;
|
|
174775
174899
|
}
|
|
174776
174900
|
function escapeXml2(s) {
|
|
@@ -174803,7 +174927,7 @@ async function createScrollContactSheet(screenshotsDir, outputPath, budget = {})
|
|
|
174803
174927
|
if (!existsSync111(screenshotsDir)) return [];
|
|
174804
174928
|
const scrollFiles = readdirSync39(screenshotsDir).filter((f) => f.startsWith("scroll-") && f.endsWith(".png")).sort();
|
|
174805
174929
|
if (scrollFiles.length === 0) return [];
|
|
174806
|
-
const paths = scrollFiles.map((f) =>
|
|
174930
|
+
const paths = scrollFiles.map((f) => join127(screenshotsDir, f));
|
|
174807
174931
|
const labels = scrollFiles.map((f) => {
|
|
174808
174932
|
const m = f.match(/scroll-(\d+)\.png/);
|
|
174809
174933
|
return m ? `${m[1]}% scroll` : f;
|
|
@@ -174820,7 +174944,7 @@ async function createSnapshotContactSheet(snapshotsDir, outputPath, budget = {})
|
|
|
174820
174944
|
if (!existsSync111(snapshotsDir)) return [];
|
|
174821
174945
|
const snapshotFiles = readdirSync39(snapshotsDir).filter((f) => f.startsWith("frame-") && f.endsWith(".png")).sort();
|
|
174822
174946
|
if (snapshotFiles.length === 0) return [];
|
|
174823
|
-
const paths = snapshotFiles.map((f) =>
|
|
174947
|
+
const paths = snapshotFiles.map((f) => join127(snapshotsDir, f));
|
|
174824
174948
|
const labels = snapshotFiles.map((f) => {
|
|
174825
174949
|
const m = f.match(/at-([\d.]+)s/);
|
|
174826
174950
|
return m ? `${m[1]}s` : f;
|
|
@@ -174838,7 +174962,7 @@ async function createAssetContactSheet(assetsDir, outputPath, budget = {}) {
|
|
|
174838
174962
|
const imageExts = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".webp"]);
|
|
174839
174963
|
const assetFiles = readdirSync39(assetsDir).filter((f) => imageExts.has(extname19(f).toLowerCase()) && !f.includes("contact-sheet")).sort();
|
|
174840
174964
|
if (assetFiles.length === 0) return [];
|
|
174841
|
-
const paths = assetFiles.map((f) =>
|
|
174965
|
+
const paths = assetFiles.map((f) => join127(assetsDir, f));
|
|
174842
174966
|
return createContactSheetPages(paths, outputPath, {
|
|
174843
174967
|
cols: 4,
|
|
174844
174968
|
cellWidth: 480,
|
|
@@ -174858,20 +174982,20 @@ async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir, budget
|
|
|
174858
174982
|
for (const f of readdirSync39(dir).filter((f2) => f2.endsWith(".svg")).sort()) {
|
|
174859
174983
|
if (!seen.has(f)) {
|
|
174860
174984
|
seen.add(f);
|
|
174861
|
-
svgPaths.push(
|
|
174985
|
+
svgPaths.push(join127(dir, f));
|
|
174862
174986
|
}
|
|
174863
174987
|
}
|
|
174864
174988
|
}
|
|
174865
174989
|
if (svgPaths.length === 0) return [];
|
|
174866
174990
|
const svgFileNames = svgPaths.map((p2) => p2.split("/").pop());
|
|
174867
174991
|
const thumbSize = 200;
|
|
174868
|
-
const tmpDir =
|
|
174992
|
+
const tmpDir = dirname62(outputPath);
|
|
174869
174993
|
const tmpPaths = [];
|
|
174870
174994
|
const labels = [];
|
|
174871
174995
|
for (let i = 0; i < svgPaths.length; i++) {
|
|
174872
174996
|
if ((budget.remainingMs?.() ?? 1) <= 0) break;
|
|
174873
174997
|
const svgPath = svgPaths[i];
|
|
174874
|
-
const tmpPath =
|
|
174998
|
+
const tmpPath = join127(tmpDir, `.thumb-${i}.png`);
|
|
174875
174999
|
try {
|
|
174876
175000
|
const svgBuf = readFileSync85(svgPath);
|
|
174877
175001
|
const thumb = await sharp(svgBuf).resize(thumbSize, thumbSize, {
|
|
@@ -174930,9 +175054,9 @@ __export(snapshot_exports, {
|
|
|
174930
175054
|
resolveSnapshotVideoRateSpec: () => resolveSnapshotVideoRateSpec,
|
|
174931
175055
|
tailFrameTime: () => tailFrameTime
|
|
174932
175056
|
});
|
|
174933
|
-
import { existsSync as existsSync112, mkdtempSync as
|
|
175057
|
+
import { existsSync as existsSync112, mkdtempSync as mkdtempSync25, readFileSync as readFileSync86, mkdirSync as mkdirSync56, rmSync as rmSync38, writeFileSync as writeFileSync48 } from "fs";
|
|
174934
175058
|
import { tmpdir as tmpdir16 } from "os";
|
|
174935
|
-
import { resolve as resolve72, join as
|
|
175059
|
+
import { resolve as resolve72, join as join128, relative as relative31, isAbsolute as isAbsolute19, basename as basename29, posix as posix6 } from "path";
|
|
174936
175060
|
function orbitStageSource() {
|
|
174937
175061
|
return `function(cam) {
|
|
174938
175062
|
var root = document.querySelector("[data-composition-id]")
|
|
@@ -174986,8 +175110,8 @@ function requireSnapshotFfmpeg(ffmpegPath) {
|
|
|
174986
175110
|
);
|
|
174987
175111
|
}
|
|
174988
175112
|
async function extractVideoFrameToBuffer(videoPath, timeSeconds, useVp9AlphaDecoder = false, accurateSeek = false) {
|
|
174989
|
-
const tmp =
|
|
174990
|
-
const outPath =
|
|
175113
|
+
const tmp = mkdtempSync25(join128(tmpdir16(), "hf-snapshot-frame-"));
|
|
175114
|
+
const outPath = join128(tmp, "frame.png");
|
|
174991
175115
|
try {
|
|
174992
175116
|
const ffmpegPath = requireSnapshotFfmpeg(findFFmpeg());
|
|
174993
175117
|
const args = ["-hide_banner", "-loglevel", "error"];
|
|
@@ -175009,7 +175133,7 @@ async function extractVideoFrameToBuffer(videoPath, timeSeconds, useVp9AlphaDeco
|
|
|
175009
175133
|
return readFileSync86(outPath);
|
|
175010
175134
|
} finally {
|
|
175011
175135
|
try {
|
|
175012
|
-
|
|
175136
|
+
rmSync38(tmp, { recursive: true, force: true });
|
|
175013
175137
|
} catch {
|
|
175014
175138
|
}
|
|
175015
175139
|
}
|
|
@@ -175098,13 +175222,13 @@ async function captureSnapshots(projectDir, opts) {
|
|
|
175098
175222
|
);
|
|
175099
175223
|
}
|
|
175100
175224
|
const cameraExpr = opts.angle && (opts.angle.yaw !== 0 || opts.angle.pitch !== 0) ? `(${orbitStageSource()})(${JSON.stringify(opts.angle)})` : null;
|
|
175101
|
-
const snapshotDir = opts.outputDir ??
|
|
175225
|
+
const snapshotDir = opts.outputDir ?? join128(projectDir, "snapshots");
|
|
175102
175226
|
mkdirSync56(snapshotDir, { recursive: true });
|
|
175103
175227
|
try {
|
|
175104
175228
|
const { readdirSync: readdirSync46 } = await import("fs");
|
|
175105
175229
|
for (const file of readdirSync46(snapshotDir)) {
|
|
175106
175230
|
if (/\.(png|jpg|jpeg)$/i.test(file)) {
|
|
175107
|
-
|
|
175231
|
+
rmSync38(join128(snapshotDir, file), { force: true });
|
|
175108
175232
|
}
|
|
175109
175233
|
}
|
|
175110
175234
|
} catch {
|
|
@@ -175238,7 +175362,7 @@ async function captureSnapshots(projectDir, opts) {
|
|
|
175238
175362
|
const timeLabel = formatSnapshotTimestamp(time);
|
|
175239
175363
|
const index = String(i).padStart(2, "0");
|
|
175240
175364
|
const filename = `frame-${index}-at-${timeLabel}.png`;
|
|
175241
|
-
const framePath =
|
|
175365
|
+
const framePath = join128(snapshotDir, filename);
|
|
175242
175366
|
if (opts.zoom) {
|
|
175243
175367
|
const canvas = await page.evaluate(() => ({
|
|
175244
175368
|
width: window.innerWidth,
|
|
@@ -175267,9 +175391,9 @@ async function captureSnapshots(projectDir, opts) {
|
|
|
175267
175391
|
` ${c.warn("\u26A0")} --against has no frame at ${timeLabel} \u2014 reference pair skipped`
|
|
175268
175392
|
);
|
|
175269
175393
|
} else {
|
|
175270
|
-
const refPath =
|
|
175394
|
+
const refPath = join128(snapshotDir, `ref-${index}-at-${timeLabel}.png`);
|
|
175271
175395
|
writeFileSync48(refPath, refPng);
|
|
175272
|
-
const pairPath =
|
|
175396
|
+
const pairPath = join128(snapshotDir, `pair-${index}-at-${timeLabel}.jpg`);
|
|
175273
175397
|
const { createContactSheet: createContactSheet2 } = await Promise.resolve().then(() => (init_contactSheet(), contactSheet_exports));
|
|
175274
175398
|
await createContactSheet2([framePath, refPath], pairPath, {
|
|
175275
175399
|
cols: 2,
|
|
@@ -175436,7 +175560,7 @@ var init_snapshot = __esm({
|
|
|
175436
175560
|
const angleLabel = camera && (camera.yaw !== 0 || camera.pitch !== 0) ? ` ${c.dim(`(angle yaw ${camera.yaw}\xB0 pitch ${camera.pitch}\xB0)`)}` : "";
|
|
175437
175561
|
console.log(`${c.accent("\u25C6")} Capturing ${label2} from ${c.accent(project.name)}${angleLabel}`);
|
|
175438
175562
|
try {
|
|
175439
|
-
const snapshotDir = args.output ? resolve72(String(args.output)) :
|
|
175563
|
+
const snapshotDir = args.output ? resolve72(String(args.output)) : join128(project.dir, "snapshots");
|
|
175440
175564
|
const paths = await captureSnapshots(project.dir, {
|
|
175441
175565
|
frames,
|
|
175442
175566
|
timeout,
|
|
@@ -175473,7 +175597,7 @@ ${c.success("\u25C7")} ${paths.length} snapshots saved to ${args.output ? snaps
|
|
|
175473
175597
|
const { createSnapshotContactSheet: createSnapshotContactSheet2 } = await Promise.resolve().then(() => (init_contactSheet(), contactSheet_exports));
|
|
175474
175598
|
const sheets = await createSnapshotContactSheet2(
|
|
175475
175599
|
snapshotDir,
|
|
175476
|
-
|
|
175600
|
+
join128(snapshotDir, "contact-sheet.jpg")
|
|
175477
175601
|
);
|
|
175478
175602
|
if (sheets.length > 0) {
|
|
175479
175603
|
const label3 = sheets.length === 1 ? "contact-sheet.jpg" : `contact-sheet-1..${sheets.length}.jpg`;
|
|
@@ -175508,8 +175632,8 @@ ${c.success("\u25C7")} ${paths.length} snapshots saved to ${args.output ? snaps
|
|
|
175508
175632
|
}
|
|
175509
175633
|
const results = await Promise.allSettled(
|
|
175510
175634
|
paths.map(async (p2) => {
|
|
175511
|
-
const filename =
|
|
175512
|
-
const filePath =
|
|
175635
|
+
const filename = basename29(p2);
|
|
175636
|
+
const filePath = join128(snapshotDir, filename);
|
|
175513
175637
|
if (!existsSync112(filePath)) return { filename, desc: "file not found" };
|
|
175514
175638
|
const raw = readFileSync86(filePath);
|
|
175515
175639
|
let imageData;
|
|
@@ -175547,7 +175671,7 @@ ${c.success("\u25C7")} ${paths.length} snapshots saved to ${args.output ? snaps
|
|
|
175547
175671
|
descriptions.push(`## (error)`, `Gemini call failed: ${errMsg.slice(0, 120)}`, ``);
|
|
175548
175672
|
}
|
|
175549
175673
|
}
|
|
175550
|
-
const descPath =
|
|
175674
|
+
const descPath = join128(snapshotDir, "descriptions.md");
|
|
175551
175675
|
writeFileSync48(descPath, descriptions.join("\n"));
|
|
175552
175676
|
console.log(` ${c.dim("descriptions.md")} (Gemini frame analysis)`);
|
|
175553
175677
|
}
|
|
@@ -175601,7 +175725,7 @@ var init_pathArgs = __esm({
|
|
|
175601
175725
|
|
|
175602
175726
|
// ../core/dist/mediaGradeAnalyzer.js
|
|
175603
175727
|
import { execFileSync as execFileSync18 } from "child_process";
|
|
175604
|
-
import { basename as
|
|
175728
|
+
import { basename as basename30, extname as extname20 } from "path";
|
|
175605
175729
|
function clamp2(value, key2) {
|
|
175606
175730
|
const limit = ADJUST_LIMITS2[key2];
|
|
175607
175731
|
if (!Number.isFinite(value))
|
|
@@ -175881,7 +176005,7 @@ __export(media_treatment_exports, {
|
|
|
175881
176005
|
resolveMediaTreatmentSource: () => resolveMediaTreatmentSource
|
|
175882
176006
|
});
|
|
175883
176007
|
import { existsSync as existsSync113, readFileSync as readFileSync87, writeFileSync as writeFileSync49 } from "fs";
|
|
175884
|
-
import { join as
|
|
176008
|
+
import { join as join129, relative as relative34, resolve as resolve74 } from "path";
|
|
175885
176009
|
function getMediaTreatmentCapabilityOverview() {
|
|
175886
176010
|
const capabilities = getHfColorGradingCapabilities();
|
|
175887
176011
|
const family = (id, label2, description) => ({
|
|
@@ -176259,7 +176383,7 @@ function resolveMediaTreatmentSource(projectDir, compositionFile, source) {
|
|
|
176259
176383
|
}
|
|
176260
176384
|
const cleanSource = cleanAssetUrl(sourceUrl);
|
|
176261
176385
|
if (!cleanSource) throw new Error("Selected media has no analyzable local src");
|
|
176262
|
-
const projectRelative = cleanSource.startsWith("/") ? cleanSource : rewriteAssetPath(compositionFile, cleanSource, (path) => existsSync113(
|
|
176386
|
+
const projectRelative = cleanSource.startsWith("/") ? cleanSource : rewriteAssetPath(compositionFile, cleanSource, (path) => existsSync113(join129(projectDir, path)));
|
|
176263
176387
|
const asset = resolveExistingLocalAsset(projectDir, projectRelative);
|
|
176264
176388
|
if (!asset) throw new Error(`Media file not found: ${source}`);
|
|
176265
176389
|
return asset.resolved;
|
|
@@ -176537,13 +176661,13 @@ import {
|
|
|
176537
176661
|
copyFileSync as copyFileSync10,
|
|
176538
176662
|
existsSync as existsSync114,
|
|
176539
176663
|
mkdirSync as mkdirSync57,
|
|
176540
|
-
mkdtempSync as
|
|
176664
|
+
mkdtempSync as mkdtempSync26,
|
|
176541
176665
|
readFileSync as readFileSync88,
|
|
176542
|
-
rmSync as
|
|
176666
|
+
rmSync as rmSync39,
|
|
176543
176667
|
writeFileSync as writeFileSync50
|
|
176544
176668
|
} from "fs";
|
|
176545
176669
|
import { tmpdir as tmpdir17 } from "os";
|
|
176546
|
-
import { basename as
|
|
176670
|
+
import { basename as basename31, dirname as dirname63, extname as extname21, join as join130, resolve as resolve75 } from "path";
|
|
176547
176671
|
import sharp2 from "sharp";
|
|
176548
176672
|
function isRecord15(value) {
|
|
176549
176673
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -176661,7 +176785,7 @@ function resolveLutCells(luts) {
|
|
|
176661
176785
|
throw new Error("--luts must include at least one LUT path");
|
|
176662
176786
|
}
|
|
176663
176787
|
return paths.map(
|
|
176664
|
-
(lutPath) => validateCell(
|
|
176788
|
+
(lutPath) => validateCell(basename31(lutPath, extname21(lutPath)), { lut: { src: lutPath } })
|
|
176665
176789
|
);
|
|
176666
176790
|
}
|
|
176667
176791
|
function prependBaselineCell(cells) {
|
|
@@ -176799,10 +176923,10 @@ function frameFileNameForPath(framePath) {
|
|
|
176799
176923
|
return "frame.png";
|
|
176800
176924
|
}
|
|
176801
176925
|
async function prepareGradeCompareTempProject(opts) {
|
|
176802
|
-
const tempDir =
|
|
176926
|
+
const tempDir = mkdtempSync26(join130(tmpdir17(), "hf-grade-compare-"));
|
|
176803
176927
|
try {
|
|
176804
176928
|
const frameFileName2 = opts.frameFileName ?? frameFileNameForPath(opts.framePath);
|
|
176805
|
-
writeFileSync50(
|
|
176929
|
+
writeFileSync50(join130(tempDir, frameFileName2), opts.frameBuffer);
|
|
176806
176930
|
let lutIndex = 0;
|
|
176807
176931
|
const stagedCells = opts.cells.map((cell) => {
|
|
176808
176932
|
const lutSrc = lutSrcFromGrading(cell.grading);
|
|
@@ -176822,7 +176946,7 @@ async function prepareGradeCompareTempProject(opts) {
|
|
|
176822
176946
|
const lutExt = extname21(sourcePath) || ".cube";
|
|
176823
176947
|
const stagedName = `lut-${lutIndex}${lutExt}`;
|
|
176824
176948
|
lutIndex += 1;
|
|
176825
|
-
copyFileSync10(sourcePath,
|
|
176949
|
+
copyFileSync10(sourcePath, join130(tempDir, stagedName));
|
|
176826
176950
|
return {
|
|
176827
176951
|
label: cell.label,
|
|
176828
176952
|
grading: rewriteGradingLutSrc(cell.grading, stagedName)
|
|
@@ -176834,10 +176958,10 @@ async function prepareGradeCompareTempProject(opts) {
|
|
|
176834
176958
|
frameWidth: opts.frameWidth,
|
|
176835
176959
|
frameHeight: opts.frameHeight
|
|
176836
176960
|
});
|
|
176837
|
-
writeFileSync50(
|
|
176961
|
+
writeFileSync50(join130(tempDir, "index.html"), html);
|
|
176838
176962
|
return { tempDir, html, cells: stagedCells };
|
|
176839
176963
|
} catch (err) {
|
|
176840
|
-
|
|
176964
|
+
rmSync39(tempDir, { recursive: true, force: true });
|
|
176841
176965
|
throw err;
|
|
176842
176966
|
}
|
|
176843
176967
|
}
|
|
@@ -176846,8 +176970,8 @@ function isVideoPath2(filePath) {
|
|
|
176846
176970
|
return [".mp4", ".mov", ".m4v", ".webm", ".mkv", ".avi", ".mpeg", ".mpg", ".ogv"].includes(ext);
|
|
176847
176971
|
}
|
|
176848
176972
|
async function extractVideoFrameToBuffer2(videoPath) {
|
|
176849
|
-
const tmp =
|
|
176850
|
-
const outPath =
|
|
176973
|
+
const tmp = mkdtempSync26(join130(tmpdir17(), "hf-grade-compare-frame-"));
|
|
176974
|
+
const outPath = join130(tmp, "frame.png");
|
|
176851
176975
|
try {
|
|
176852
176976
|
const ffmpegPath = findFFmpeg();
|
|
176853
176977
|
if (!ffmpegPath) return null;
|
|
@@ -176876,7 +177000,7 @@ async function extractVideoFrameToBuffer2(videoPath) {
|
|
|
176876
177000
|
}
|
|
176877
177001
|
return readFileSync88(outPath);
|
|
176878
177002
|
} finally {
|
|
176879
|
-
|
|
177003
|
+
rmSync39(tmp, { recursive: true, force: true });
|
|
176880
177004
|
}
|
|
176881
177005
|
}
|
|
176882
177006
|
async function loadReferenceFrame(framePath) {
|
|
@@ -176902,7 +177026,7 @@ async function captureGradeCompareSheet(projectDir, timeoutMs) {
|
|
|
176902
177026
|
const { bundleToSingleHtml: bundleToSingleHtml2 } = await Promise.resolve().then(() => (init_compiler(), compiler_exports));
|
|
176903
177027
|
const html = await bundleToSingleHtml2(projectDir);
|
|
176904
177028
|
const server = await serveStaticProjectHtml(projectDir, html);
|
|
176905
|
-
const sheetPath =
|
|
177029
|
+
const sheetPath = join130(projectDir, "grade-compare.png");
|
|
176906
177030
|
try {
|
|
176907
177031
|
const {
|
|
176908
177032
|
browser: chromeBrowser,
|
|
@@ -177025,7 +177149,7 @@ var init_grade_compare = __esm({
|
|
|
177025
177149
|
}
|
|
177026
177150
|
if (!parsed.json) {
|
|
177027
177151
|
console.log(
|
|
177028
|
-
`${c.accent("\u25C6")} Rendering ${cells.length} grade candidates from ${c.accent(
|
|
177152
|
+
`${c.accent("\u25C6")} Rendering ${cells.length} grade candidates from ${c.accent(basename31(parsed.framePath))}`
|
|
177029
177153
|
);
|
|
177030
177154
|
}
|
|
177031
177155
|
const frame = await loadReferenceFrame(parsed.framePath);
|
|
@@ -177043,7 +177167,7 @@ var init_grade_compare = __esm({
|
|
|
177043
177167
|
prepared.tempDir,
|
|
177044
177168
|
parsed.timeoutMs
|
|
177045
177169
|
);
|
|
177046
|
-
mkdirSync57(
|
|
177170
|
+
mkdirSync57(dirname63(parsed.outPath), { recursive: true });
|
|
177047
177171
|
copyFileSync10(tempSheet, parsed.outPath);
|
|
177048
177172
|
trackCompareSheet({
|
|
177049
177173
|
command: "grade-compare",
|
|
@@ -177070,7 +177194,7 @@ ${c.error("\u2717")} Grade compare failed: ${message}`);
|
|
|
177070
177194
|
failCommand();
|
|
177071
177195
|
} finally {
|
|
177072
177196
|
if (preparedDir) {
|
|
177073
|
-
|
|
177197
|
+
rmSync39(preparedDir, { recursive: true, force: true });
|
|
177074
177198
|
}
|
|
177075
177199
|
}
|
|
177076
177200
|
}
|
|
@@ -177088,12 +177212,12 @@ __export(compare_exports, {
|
|
|
177088
177212
|
parseCompareArgs: () => parseCompareArgs,
|
|
177089
177213
|
prepareCompareVariantProjects: () => prepareCompareVariantProjects
|
|
177090
177214
|
});
|
|
177091
|
-
import { cpSync as cpSync6, existsSync as existsSync115, mkdirSync as mkdirSync58, mkdtempSync as
|
|
177215
|
+
import { cpSync as cpSync6, existsSync as existsSync115, mkdirSync as mkdirSync58, mkdtempSync as mkdtempSync27, renameSync as renameSync23, rmSync as rmSync40, statSync as statSync43 } from "fs";
|
|
177092
177216
|
import { tmpdir as tmpdir18 } from "os";
|
|
177093
|
-
import { basename as
|
|
177217
|
+
import { basename as basename32, dirname as dirname64, extname as extname23, join as join131 } from "path";
|
|
177094
177218
|
function defaultLabelForPath(input2) {
|
|
177095
|
-
const name =
|
|
177096
|
-
return extname23(name).toLowerCase() === ".html" ?
|
|
177219
|
+
const name = basename32(input2);
|
|
177220
|
+
return extname23(name).toLowerCase() === ".html" ? basename32(name, extname23(name)) : name;
|
|
177097
177221
|
}
|
|
177098
177222
|
function parsePathArgs(args) {
|
|
177099
177223
|
return (args._ ?? []).filter((value) => typeof value === "string").map((value) => value.trim()).filter(Boolean);
|
|
@@ -177189,18 +177313,18 @@ function inputError(variant) {
|
|
|
177189
177313
|
);
|
|
177190
177314
|
}
|
|
177191
177315
|
function stageHtmlVariant(variant) {
|
|
177192
|
-
const stagedDir =
|
|
177316
|
+
const stagedDir = mkdtempSync27(join131(tmpdir18(), "hf-compare-variant-"));
|
|
177193
177317
|
try {
|
|
177194
|
-
cpSync6(
|
|
177318
|
+
cpSync6(dirname64(variant.inputPath), stagedDir, {
|
|
177195
177319
|
recursive: true,
|
|
177196
177320
|
filter: (src) => {
|
|
177197
|
-
const base2 =
|
|
177321
|
+
const base2 = basename32(src);
|
|
177198
177322
|
return base2 !== "node_modules" && base2 !== ".git";
|
|
177199
177323
|
}
|
|
177200
177324
|
});
|
|
177201
|
-
const sourceName =
|
|
177325
|
+
const sourceName = basename32(variant.inputPath);
|
|
177202
177326
|
if (sourceName !== "index.html") {
|
|
177203
|
-
|
|
177327
|
+
renameSync23(join131(stagedDir, sourceName), join131(stagedDir, "index.html"));
|
|
177204
177328
|
}
|
|
177205
177329
|
return {
|
|
177206
177330
|
...variant,
|
|
@@ -177208,7 +177332,7 @@ function stageHtmlVariant(variant) {
|
|
|
177208
177332
|
stagedDir
|
|
177209
177333
|
};
|
|
177210
177334
|
} catch (err) {
|
|
177211
|
-
|
|
177335
|
+
rmSync40(stagedDir, { recursive: true, force: true });
|
|
177212
177336
|
throw err;
|
|
177213
177337
|
}
|
|
177214
177338
|
}
|
|
@@ -177220,7 +177344,7 @@ function prepareCompareVariantProjects(variants) {
|
|
|
177220
177344
|
throw inputError(variant);
|
|
177221
177345
|
}
|
|
177222
177346
|
const stat = statSync43(variant.inputPath);
|
|
177223
|
-
if (stat.isDirectory() && existsSync115(
|
|
177347
|
+
if (stat.isDirectory() && existsSync115(join131(variant.inputPath, "index.html"))) {
|
|
177224
177348
|
prepared.push({
|
|
177225
177349
|
...variant,
|
|
177226
177350
|
projectDir: variant.inputPath
|
|
@@ -177237,7 +177361,7 @@ function prepareCompareVariantProjects(variants) {
|
|
|
177237
177361
|
} catch (err) {
|
|
177238
177362
|
for (const variant of prepared) {
|
|
177239
177363
|
if (variant.stagedDir) {
|
|
177240
|
-
|
|
177364
|
+
rmSync40(variant.stagedDir, { recursive: true, force: true });
|
|
177241
177365
|
}
|
|
177242
177366
|
}
|
|
177243
177367
|
throw err;
|
|
@@ -177246,7 +177370,7 @@ function prepareCompareVariantProjects(variants) {
|
|
|
177246
177370
|
function cleanupPreparedCompareVariants(variants) {
|
|
177247
177371
|
for (const variant of variants) {
|
|
177248
177372
|
if (variant.stagedDir) {
|
|
177249
|
-
|
|
177373
|
+
rmSync40(variant.stagedDir, { recursive: true, force: true });
|
|
177250
177374
|
}
|
|
177251
177375
|
}
|
|
177252
177376
|
}
|
|
@@ -177286,13 +177410,13 @@ async function renderCompareSheet(parsed) {
|
|
|
177286
177410
|
const capResult = capCompareVariants(parsed.variants);
|
|
177287
177411
|
const variants = capResult.variants;
|
|
177288
177412
|
const prepared = prepareCompareVariantProjects(variants);
|
|
177289
|
-
const frameDir =
|
|
177413
|
+
const frameDir = mkdtempSync27(join131(tmpdir18(), "hf-compare-frames-"));
|
|
177290
177414
|
const framePaths = [];
|
|
177291
177415
|
try {
|
|
177292
177416
|
let renderReadyTimedOut = false;
|
|
177293
177417
|
for (let i = 0; i < prepared.length; i++) {
|
|
177294
177418
|
const variant = prepared[i];
|
|
177295
|
-
const framePath =
|
|
177419
|
+
const framePath = join131(frameDir, `variant-${String(i + 1).padStart(2, "0")}.png`);
|
|
177296
177420
|
const rendered = await renderCompareVariant(variant, {
|
|
177297
177421
|
atSeconds: parsed.atSeconds,
|
|
177298
177422
|
framePath,
|
|
@@ -177301,7 +177425,7 @@ async function renderCompareSheet(parsed) {
|
|
|
177301
177425
|
framePaths.push(rendered.framePath);
|
|
177302
177426
|
renderReadyTimedOut = renderReadyTimedOut || rendered.renderReadyTimedOut;
|
|
177303
177427
|
}
|
|
177304
|
-
mkdirSync58(
|
|
177428
|
+
mkdirSync58(dirname64(parsed.outPath), { recursive: true });
|
|
177305
177429
|
await createContactSheet(framePaths, parsed.outPath, {
|
|
177306
177430
|
cols: parsed.cols ?? defaultCompareCols(framePaths.length),
|
|
177307
177431
|
maxImages: framePaths.length,
|
|
@@ -177318,7 +177442,7 @@ async function renderCompareSheet(parsed) {
|
|
|
177318
177442
|
return buildCompareSuccessPayload(parsed.outPath, variants, capResult);
|
|
177319
177443
|
} finally {
|
|
177320
177444
|
cleanupPreparedCompareVariants(prepared);
|
|
177321
|
-
|
|
177445
|
+
rmSync40(frameDir, { recursive: true, force: true });
|
|
177322
177446
|
}
|
|
177323
177447
|
}
|
|
177324
177448
|
function printJson2(payload) {
|
|
@@ -177674,9 +177798,9 @@ function captureFontExtension(bytes) {
|
|
|
177674
177798
|
}
|
|
177675
177799
|
}
|
|
177676
177800
|
function preferredFontFilename(url, extension) {
|
|
177677
|
-
const
|
|
177678
|
-
const dot =
|
|
177679
|
-
const stem = dot > 0 ?
|
|
177801
|
+
const basename35 = new URL(url).pathname.split("/").pop() ?? "";
|
|
177802
|
+
const dot = basename35.lastIndexOf(".");
|
|
177803
|
+
const stem = dot > 0 ? basename35.slice(0, dot) : basename35;
|
|
177680
177804
|
if (/^[a-zA-Z0-9_-][a-zA-Z0-9_.-]{0,119}$/.test(stem) && !/[. ]$/.test(stem) && !/^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i.test(stem)) {
|
|
177681
177805
|
return `${stem}${extension}`;
|
|
177682
177806
|
}
|
|
@@ -177857,7 +177981,7 @@ var init_captureImageValidation = __esm({
|
|
|
177857
177981
|
|
|
177858
177982
|
// src/capture/assetDownloader.ts
|
|
177859
177983
|
import { mkdirSync as mkdirSync59 } from "fs";
|
|
177860
|
-
import { join as
|
|
177984
|
+
import { join as join133, extname as extname24 } from "path";
|
|
177861
177985
|
import { createHash as createHash27 } from "crypto";
|
|
177862
177986
|
function noDrops() {
|
|
177863
177987
|
return { "size-floor": 0, "budget-exhausted": 0, "cap-reached": 0, unavailable: 0 };
|
|
@@ -177919,7 +178043,7 @@ async function fetchAndInspectIcon(icon, rank, stem, outputDir, timeoutMs, byteB
|
|
|
177919
178043
|
const ext = await captureImageExtension(buffer);
|
|
177920
178044
|
if (!ext) return null;
|
|
177921
178045
|
const file = `assets/${stem}${ext}`;
|
|
177922
|
-
writeCaptureFileSync(
|
|
178046
|
+
writeCaptureFileSync(join133(outputDir, file), buffer);
|
|
177923
178047
|
const verdict = await classifyIcon(buffer, ext);
|
|
177924
178048
|
return {
|
|
177925
178049
|
buffer,
|
|
@@ -177941,7 +178065,7 @@ function promoteHeadline(manifest, bytesByFile, outputDir) {
|
|
|
177941
178065
|
)[0];
|
|
177942
178066
|
if (!chosen) return null;
|
|
177943
178067
|
const file = `assets/favicon${extname24(chosen.file)}`;
|
|
177944
|
-
writeCaptureFileSync(
|
|
178068
|
+
writeCaptureFileSync(join133(outputDir, file), bytesByFile.get(chosen.file));
|
|
177945
178069
|
manifest.headline = {
|
|
177946
178070
|
file,
|
|
177947
178071
|
source: chosen.file,
|
|
@@ -177996,13 +178120,13 @@ async function downloadDeclaredIcons(faviconLinks, outputDir, drops, options) {
|
|
|
177996
178120
|
}
|
|
177997
178121
|
async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks, options = {}) {
|
|
177998
178122
|
options = { ...options, byteBudget: options.byteBudget ?? createCaptureDownloadBudget() };
|
|
177999
|
-
const assetsDir =
|
|
178123
|
+
const assetsDir = join133(outputDir, "assets");
|
|
178000
178124
|
mkdirSync59(assetsDir, { recursive: true });
|
|
178001
178125
|
const assets = [];
|
|
178002
178126
|
const drops = noDrops();
|
|
178003
178127
|
const downloadedUrls = /* @__PURE__ */ new Set();
|
|
178004
178128
|
let icons = emptyIconManifest();
|
|
178005
|
-
mkdirSync59(
|
|
178129
|
+
mkdirSync59(join133(outputDir, "assets", "svgs"), { recursive: true });
|
|
178006
178130
|
const usedSvgNames = /* @__PURE__ */ new Set();
|
|
178007
178131
|
const MAX_INLINE_SVGS = 30;
|
|
178008
178132
|
drops["cap-reached"] += Math.max(0, tokens.svgs.length - MAX_INLINE_SVGS);
|
|
@@ -178024,7 +178148,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks,
|
|
|
178024
178148
|
const name = `${finalSlug}.svg`;
|
|
178025
178149
|
const localPath = `assets/svgs/${name}`;
|
|
178026
178150
|
try {
|
|
178027
|
-
writeCaptureFileSync(
|
|
178151
|
+
writeCaptureFileSync(join133(outputDir, localPath), svgFile, "utf-8");
|
|
178028
178152
|
assets.push({ url: "", localPath, type: "svg" });
|
|
178029
178153
|
} catch {
|
|
178030
178154
|
drops.unavailable++;
|
|
@@ -178114,7 +178238,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks,
|
|
|
178114
178238
|
const name = `${slug}${ext}`;
|
|
178115
178239
|
usedNames.add(slug);
|
|
178116
178240
|
const localPath = `assets/${name}`;
|
|
178117
|
-
writeCaptureFileSync(
|
|
178241
|
+
writeCaptureFileSync(join133(outputDir, localPath), buffer);
|
|
178118
178242
|
assets.push({ url, localPath, type: "image" });
|
|
178119
178243
|
imgIdx++;
|
|
178120
178244
|
} catch {
|
|
@@ -178141,7 +178265,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks,
|
|
|
178141
178265
|
drops["size-floor"]++;
|
|
178142
178266
|
} else {
|
|
178143
178267
|
const localPath = `assets/og-image${ext}`;
|
|
178144
|
-
writeCaptureFileSync(
|
|
178268
|
+
writeCaptureFileSync(join133(outputDir, localPath), buffer);
|
|
178145
178269
|
assets.push({ url: tokens.ogImage, localPath, type: "image" });
|
|
178146
178270
|
}
|
|
178147
178271
|
}
|
|
@@ -178167,7 +178291,7 @@ function normalizeUrl(u) {
|
|
|
178167
178291
|
}
|
|
178168
178292
|
async function downloadAndRewriteFonts(css, outputDir, options = {}) {
|
|
178169
178293
|
options = { ...options, byteBudget: options.byteBudget ?? createCaptureDownloadBudget() };
|
|
178170
|
-
const assetsDir =
|
|
178294
|
+
const assetsDir = join133(outputDir, "assets", "fonts");
|
|
178171
178295
|
mkdirSync59(assetsDir, { recursive: true });
|
|
178172
178296
|
const drops = noDrops();
|
|
178173
178297
|
const fontUrlRegex = /url\(['"]?(https?:\/\/[^'")\s]+\.(?:woff2?|ttf|otf)[^'")\s]*?)['"]?\)/g;
|
|
@@ -178225,7 +178349,7 @@ async function downloadAndRewriteFonts(css, outputDir, options = {}) {
|
|
|
178225
178349
|
const extension = buffer && captureFontExtension(buffer);
|
|
178226
178350
|
if (buffer && extension) {
|
|
178227
178351
|
const filename = captureFontFilename(fontUrl, extension, usedFontNames);
|
|
178228
|
-
const localPath =
|
|
178352
|
+
const localPath = join133(assetsDir, filename);
|
|
178229
178353
|
const relativePath = `assets/fonts/${filename}`;
|
|
178230
178354
|
writeCaptureFileSync(localPath, buffer);
|
|
178231
178355
|
rewritten = rewritten.split(fontUrl).join(relativePath);
|
|
@@ -178349,7 +178473,7 @@ __export(video_exports, {
|
|
|
178349
178473
|
safeFilename: () => safeFilename
|
|
178350
178474
|
});
|
|
178351
178475
|
import { createWriteStream as createWriteStream3, existsSync as existsSync116, mkdirSync as mkdirSync60, readFileSync as readFileSync89, unlinkSync as unlinkSync11 } from "fs";
|
|
178352
|
-
import { resolve as resolve76, join as
|
|
178476
|
+
import { resolve as resolve76, join as join134, basename as basename33 } from "path";
|
|
178353
178477
|
async function streamToFile(url, destPath) {
|
|
178354
178478
|
const r = await safeFetch(url, {
|
|
178355
178479
|
signal: AbortSignal.timeout(12e4),
|
|
@@ -178427,9 +178551,9 @@ function safeFilename(name) {
|
|
|
178427
178551
|
return decoded.replace(/[^A-Za-z0-9._-]+/g, "_");
|
|
178428
178552
|
}
|
|
178429
178553
|
function findFilenameCollision(manifest, selected) {
|
|
178430
|
-
const selectedName = safeFilename(selected.filename ||
|
|
178554
|
+
const selectedName = safeFilename(selected.filename || basename33(selected.url));
|
|
178431
178555
|
return manifest.filter(
|
|
178432
|
-
(e2) => e2.index !== selected.index && safeFilename(e2.filename ||
|
|
178556
|
+
(e2) => e2.index !== selected.index && safeFilename(e2.filename || basename33(e2.url)) === selectedName
|
|
178433
178557
|
);
|
|
178434
178558
|
}
|
|
178435
178559
|
function pickManifestEntry(manifest, args) {
|
|
@@ -178468,8 +178592,8 @@ function pickManifestEntry(manifest, args) {
|
|
|
178468
178592
|
}
|
|
178469
178593
|
async function runVideoMode(args) {
|
|
178470
178594
|
const projectDir = resolve76(args.project);
|
|
178471
|
-
const directPath =
|
|
178472
|
-
const w2hPath =
|
|
178595
|
+
const directPath = join134(projectDir, "extracted", "video-manifest.json");
|
|
178596
|
+
const w2hPath = join134(projectDir, "capture", "extracted", "video-manifest.json");
|
|
178473
178597
|
const manifestPath3 = existsSync116(directPath) ? directPath : w2hPath;
|
|
178474
178598
|
const isW2hLayout = manifestPath3 === w2hPath;
|
|
178475
178599
|
if (!existsSync116(manifestPath3)) {
|
|
@@ -178518,15 +178642,15 @@ async function runVideoMode(args) {
|
|
|
178518
178642
|
const collisions = findFilenameCollision(manifest, entry);
|
|
178519
178643
|
if (collisions.length > 0) {
|
|
178520
178644
|
console.error(
|
|
178521
|
-
`${c.error("\u2717")} filename "${safeFilename(entry.filename ||
|
|
178645
|
+
`${c.error("\u2717")} filename "${safeFilename(entry.filename || basename33(entry.url))}" collides with manifest entr${collisions.length === 1 ? "y" : "ies"} ${collisions.map((co) => `[${co.index}]`).join(", ")}. Refusing to download \u2014 the on-disk file's bytes would not match the requested entry.`
|
|
178522
178646
|
);
|
|
178523
178647
|
setCommandExitCode(1);
|
|
178524
178648
|
return;
|
|
178525
178649
|
}
|
|
178526
|
-
const outDir = isW2hLayout ?
|
|
178650
|
+
const outDir = isW2hLayout ? join134(projectDir, "capture", "assets", "videos") : join134(projectDir, "assets", "videos");
|
|
178527
178651
|
mkdirSync60(outDir, { recursive: true });
|
|
178528
|
-
const fname = safeFilename(entry.filename ||
|
|
178529
|
-
const outPath =
|
|
178652
|
+
const fname = safeFilename(entry.filename || basename33(entry.url));
|
|
178653
|
+
const outPath = join134(outDir, fname);
|
|
178530
178654
|
const relPath = isW2hLayout ? `capture/assets/videos/${fname}` : `assets/videos/${fname}`;
|
|
178531
178655
|
console.log(
|
|
178532
178656
|
`${c.accent("\u25B8")} downloading [${entry.index}] ${entry.filename} (${entry.sourceWidth || entry.width}\xD7${entry.sourceHeight || entry.height})`
|
|
@@ -178567,7 +178691,7 @@ var init_video = __esm({
|
|
|
178567
178691
|
|
|
178568
178692
|
// src/capture/partialCapture.ts
|
|
178569
178693
|
import { mkdirSync as mkdirSync61 } from "fs";
|
|
178570
|
-
import { join as
|
|
178694
|
+
import { join as join135 } from "path";
|
|
178571
178695
|
function serializeTokensForCapture(tokens) {
|
|
178572
178696
|
const tokensForDisk = {
|
|
178573
178697
|
...tokens,
|
|
@@ -178616,15 +178740,15 @@ function createPartialCaptureState(opts) {
|
|
|
178616
178740
|
function writePartialCaptureBundle(opts, state, lastPhase) {
|
|
178617
178741
|
const hostname2 = new URL(opts.url).hostname.replace(/^www\./, "");
|
|
178618
178742
|
mkdirSync61(opts.outputDir, { recursive: true });
|
|
178619
|
-
const extractedDir =
|
|
178743
|
+
const extractedDir = join135(opts.outputDir, "extracted");
|
|
178620
178744
|
mkdirSync61(extractedDir, { recursive: true });
|
|
178621
|
-
writeCaptureFileSync(
|
|
178745
|
+
writeCaptureFileSync(join135(extractedDir, "tokens.json"), serializeTokensForCapture(state.tokens));
|
|
178622
178746
|
writeCaptureFileSync(
|
|
178623
|
-
|
|
178747
|
+
join135(extractedDir, "design-styles.json"),
|
|
178624
178748
|
JSON.stringify(state.designStyles, null, 2)
|
|
178625
178749
|
);
|
|
178626
|
-
writeCaptureFileSync(
|
|
178627
|
-
const metaPath =
|
|
178750
|
+
writeCaptureFileSync(join135(extractedDir, "page.html"), state.pageHtml);
|
|
178751
|
+
const metaPath = join135(opts.outputDir, "meta.json");
|
|
178628
178752
|
try {
|
|
178629
178753
|
writeCaptureFileSync(
|
|
178630
178754
|
metaPath,
|
|
@@ -179263,7 +179387,7 @@ __export(agentPromptGenerator_exports, {
|
|
|
179263
179387
|
generateAgentPrompt: () => generateAgentPrompt
|
|
179264
179388
|
});
|
|
179265
179389
|
import { readdirSync as readdirSync40, existsSync as existsSync117 } from "fs";
|
|
179266
|
-
import { join as
|
|
179390
|
+
import { join as join136 } from "path";
|
|
179267
179391
|
function inferColorRole(hex) {
|
|
179268
179392
|
const r = parseInt(hex.slice(1, 3), 16) / 255;
|
|
179269
179393
|
const g = parseInt(hex.slice(3, 5), 16) / 255;
|
|
@@ -179282,9 +179406,9 @@ function inferColorRole(hex) {
|
|
|
179282
179406
|
}
|
|
179283
179407
|
function generateAgentPrompt(outputDir, url, tokens, _animations, hasScreenshot, hasLottie, hasShaders, _catalogedAssets, _detectedLibraries) {
|
|
179284
179408
|
const prompt = buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShaders);
|
|
179285
|
-
writeCaptureFileSync(
|
|
179286
|
-
writeCaptureFileSync(
|
|
179287
|
-
writeCaptureFileSync(
|
|
179409
|
+
writeCaptureFileSync(join136(outputDir, "AGENTS.md"), prompt, "utf-8");
|
|
179410
|
+
writeCaptureFileSync(join136(outputDir, "CLAUDE.md"), prompt, "utf-8");
|
|
179411
|
+
writeCaptureFileSync(join136(outputDir, ".cursorrules"), prompt, "utf-8");
|
|
179288
179412
|
}
|
|
179289
179413
|
function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShaders) {
|
|
179290
179414
|
const title = tokens.title || new URL(url).hostname.replace(/^www\./, "");
|
|
@@ -179293,7 +179417,7 @@ function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShader
|
|
|
179293
179417
|
(f) => f.family + (f.variable && f.weightRange ? ` (${f.weightRange[0]}-${f.weightRange[1]} variable)` : f.weights.length > 0 ? ` (${f.weights.join(",")})` : "")
|
|
179294
179418
|
).join(", ") || "none detected";
|
|
179295
179419
|
function contactSheetRows(dir, baseFile, label2) {
|
|
179296
|
-
const fullDir =
|
|
179420
|
+
const fullDir = join136(outputDir, dir);
|
|
179297
179421
|
if (!existsSync117(fullDir)) return [];
|
|
179298
179422
|
const baseName = baseFile.replace(/\.jpg$/, "");
|
|
179299
179423
|
const escapedBase = baseName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -179326,7 +179450,7 @@ function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShader
|
|
|
179326
179450
|
tableRows.push(
|
|
179327
179451
|
`| \`extracted/tokens.json\` | Design tokens: ${tokens.colors.length} colors, ${tokens.fonts.length} fonts, ${tokens.headings?.length ?? 0} headings, ${tokens.ctas?.length ?? 0} CTAs |`
|
|
179328
179452
|
);
|
|
179329
|
-
if (existsSync117(
|
|
179453
|
+
if (existsSync117(join136(outputDir, "extracted", "design-styles.json"))) {
|
|
179330
179454
|
tableRows.push(
|
|
179331
179455
|
"| `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. |"
|
|
179332
179456
|
);
|
|
@@ -179399,7 +179523,7 @@ var init_agentPromptGenerator = __esm({
|
|
|
179399
179523
|
|
|
179400
179524
|
// src/capture/scaffolding.ts
|
|
179401
179525
|
import { existsSync as existsSync118, readFileSync as readFileSync90 } from "fs";
|
|
179402
|
-
import { join as
|
|
179526
|
+
import { join as join137, resolve as resolve77 } from "path";
|
|
179403
179527
|
function loadEnvFile(startDir) {
|
|
179404
179528
|
try {
|
|
179405
179529
|
let dir = resolve77(startDir);
|
|
@@ -179425,7 +179549,7 @@ function loadEnvFile(startDir) {
|
|
|
179425
179549
|
}
|
|
179426
179550
|
}
|
|
179427
179551
|
async function generateProjectScaffold(outputDir, url, tokens, animationCatalog, hasScreenshots, hasLotties, hasShaders, catalogedAssets, progress, warnings, detectedLibraries) {
|
|
179428
|
-
const metaPath =
|
|
179552
|
+
const metaPath = join137(outputDir, "meta.json");
|
|
179429
179553
|
if (!existsSync118(metaPath)) {
|
|
179430
179554
|
const hostname2 = new URL(url).hostname.replace(/^www\./, "");
|
|
179431
179555
|
writeNewFileSync(
|
|
@@ -179566,10 +179690,10 @@ var init_navigateForCapture = __esm({
|
|
|
179566
179690
|
});
|
|
179567
179691
|
|
|
179568
179692
|
// src/capture/responseRecord.ts
|
|
179569
|
-
import { join as
|
|
179693
|
+
import { join as join138 } from "path";
|
|
179570
179694
|
function writeResponseRecord(extractedDir, record2) {
|
|
179571
179695
|
writeCaptureFileSync(
|
|
179572
|
-
|
|
179696
|
+
join138(extractedDir, RESPONSE_RECORD_FILENAME),
|
|
179573
179697
|
JSON.stringify(record2, null, 2),
|
|
179574
179698
|
"utf-8"
|
|
179575
179699
|
);
|
|
@@ -179584,7 +179708,7 @@ var init_responseRecord = __esm({
|
|
|
179584
179708
|
});
|
|
179585
179709
|
|
|
179586
179710
|
// src/capture/navigationPhase.ts
|
|
179587
|
-
import { join as
|
|
179711
|
+
import { join as join139 } from "path";
|
|
179588
179712
|
async function navigatePage(context) {
|
|
179589
179713
|
let navigation;
|
|
179590
179714
|
try {
|
|
@@ -179638,7 +179762,7 @@ async function checkPageContent(context) {
|
|
|
179638
179762
|
function persistNavigationResult(context, navigationResponse, pageContentCheck) {
|
|
179639
179763
|
context.httpStatus = navigationResponse ? navigationResponse.status() : null;
|
|
179640
179764
|
if (context.canWrite()) {
|
|
179641
|
-
writeResponseRecord(
|
|
179765
|
+
writeResponseRecord(join139(context.outputDir, "extracted"), { status: context.httpStatus });
|
|
179642
179766
|
}
|
|
179643
179767
|
const blockedReason = detectBlockedPage({
|
|
179644
179768
|
httpStatus: context.httpStatus,
|
|
@@ -179683,7 +179807,7 @@ import {
|
|
|
179683
179807
|
fstatSync as fstatSync9,
|
|
179684
179808
|
closeSync as closeSync15
|
|
179685
179809
|
} from "fs";
|
|
179686
|
-
import { basename as
|
|
179810
|
+
import { basename as basename34, join as join140 } from "path";
|
|
179687
179811
|
function resolveVisionPhaseCompletion(outcome, remainingMs) {
|
|
179688
179812
|
if (outcome.budgetExhausted || remainingMs <= 0) {
|
|
179689
179813
|
return { status: "degraded", reason: "budget-exhausted" };
|
|
@@ -179964,7 +180088,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings, options =
|
|
|
179964
180088
|
return response.text?.trim() || "";
|
|
179965
180089
|
};
|
|
179966
180090
|
}
|
|
179967
|
-
const imageFiles = readdirSync41(
|
|
180091
|
+
const imageFiles = readdirSync41(join140(outputDir, "assets")).filter(
|
|
179968
180092
|
(f) => /\.(png|jpg|jpeg|webp|gif)$/i.test(f)
|
|
179969
180093
|
);
|
|
179970
180094
|
const BATCH_SIZE = 20;
|
|
@@ -179992,7 +180116,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings, options =
|
|
|
179992
180116
|
const batch = imageFiles.slice(i, i + BATCH_SIZE);
|
|
179993
180117
|
const results = await Promise.allSettled(
|
|
179994
180118
|
batch.map(async (file) => {
|
|
179995
|
-
const filePath =
|
|
180119
|
+
const filePath = join140(outputDir, "assets", file);
|
|
179996
180120
|
const fd = openSync14(filePath, "r", 384);
|
|
179997
180121
|
let buffer;
|
|
179998
180122
|
try {
|
|
@@ -180031,11 +180155,11 @@ async function captionImagesWithGemini(outputDir, progress, warnings, options =
|
|
|
180031
180155
|
`${Object.keys(geminiCaptions).length} images captioned with ${providerName}`
|
|
180032
180156
|
);
|
|
180033
180157
|
const svgFiles = [];
|
|
180034
|
-
const assetsDir =
|
|
180158
|
+
const assetsDir = join140(outputDir, "assets");
|
|
180035
180159
|
for (const f of readdirSync41(assetsDir)) {
|
|
180036
180160
|
if (/\.svg$/i.test(f)) svgFiles.push({ file: f, relPath: f });
|
|
180037
180161
|
}
|
|
180038
|
-
const svgsSubdir =
|
|
180162
|
+
const svgsSubdir = join140(assetsDir, "svgs");
|
|
180039
180163
|
if (existsSync119(svgsSubdir)) {
|
|
180040
180164
|
for (const f of readdirSync41(svgsSubdir)) {
|
|
180041
180165
|
if (/\.svg$/i.test(f)) svgFiles.push({ file: f, relPath: `svgs/${f}` });
|
|
@@ -180069,7 +180193,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings, options =
|
|
|
180069
180193
|
sharp5.concurrency(1);
|
|
180070
180194
|
try {
|
|
180071
180195
|
for (const { relPath } of batch) {
|
|
180072
|
-
const filePath =
|
|
180196
|
+
const filePath = join140(assetsDir, relPath);
|
|
180073
180197
|
try {
|
|
180074
180198
|
const svgSource = readFileSync91(filePath, "utf-8");
|
|
180075
180199
|
const lightFillHits = (svgSource.match(/fill\s*=\s*["'](#fff(fff)?|white|#[ef][ef][ef]|#[ef]{6})["']/gi) || []).length;
|
|
@@ -180144,11 +180268,11 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
|
|
|
180144
180268
|
const uncaptionedLines = [];
|
|
180145
180269
|
const svgLines = [];
|
|
180146
180270
|
const fontLines = [];
|
|
180147
|
-
const assetsPath =
|
|
180271
|
+
const assetsPath = join140(outputDir, "assets");
|
|
180148
180272
|
try {
|
|
180149
180273
|
for (const file of readdirSync41(assetsPath)) {
|
|
180150
180274
|
if (file === "svgs" || file === "fonts" || file === "lottie" || file === "videos") continue;
|
|
180151
|
-
const filePath =
|
|
180275
|
+
const filePath = join140(assetsPath, file);
|
|
180152
180276
|
const stat = statSync44(filePath);
|
|
180153
180277
|
if (!stat.isFile()) continue;
|
|
180154
180278
|
const sizeKb = Math.round(stat.size / 1024);
|
|
@@ -180177,7 +180301,7 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
|
|
|
180177
180301
|
} catch {
|
|
180178
180302
|
}
|
|
180179
180303
|
try {
|
|
180180
|
-
const svgsPath =
|
|
180304
|
+
const svgsPath = join140(assetsPath, "svgs");
|
|
180181
180305
|
for (const file of readdirSync41(svgsPath)) {
|
|
180182
180306
|
if (!file.endsWith(".svg")) continue;
|
|
180183
180307
|
const svgMatch = tokens.svgs.find(
|
|
@@ -180196,7 +180320,7 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
|
|
|
180196
180320
|
} catch {
|
|
180197
180321
|
}
|
|
180198
180322
|
try {
|
|
180199
|
-
const fontsPath =
|
|
180323
|
+
const fontsPath = join140(assetsPath, "fonts");
|
|
180200
180324
|
for (const file of readdirSync41(fontsPath)) {
|
|
180201
180325
|
fontLines.push(`fonts/${file} \u2014 font file`);
|
|
180202
180326
|
}
|
|
@@ -180205,11 +180329,11 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
|
|
|
180205
180329
|
const videoLines = [];
|
|
180206
180330
|
try {
|
|
180207
180331
|
const manifest = JSON.parse(
|
|
180208
|
-
readFileSync91(
|
|
180332
|
+
readFileSync91(join140(outputDir, "extracted", "video-manifest.json"), "utf-8")
|
|
180209
180333
|
);
|
|
180210
180334
|
for (const v2 of manifest) {
|
|
180211
180335
|
if (!v2.localPath) continue;
|
|
180212
|
-
const base2 =
|
|
180336
|
+
const base2 = basename34(v2.localPath) || v2.filename || "";
|
|
180213
180337
|
if (!base2) continue;
|
|
180214
180338
|
const desc = (v2.caption || v2.heading || "").trim().replace(/\s+/g, " ").slice(0, 140) || "motion clip";
|
|
180215
180339
|
const dimW = v2.sourceWidth || v2.width;
|
|
@@ -181481,7 +181605,7 @@ var init_lottiePreviewRequests = __esm({
|
|
|
181481
181605
|
|
|
181482
181606
|
// src/capture/mediaCapture.ts
|
|
181483
181607
|
import { mkdirSync as mkdirSync63, readdirSync as readdirSync43, readFileSync as readFileSync93, statSync as statSync45 } from "fs";
|
|
181484
|
-
import { join as
|
|
181608
|
+
import { join as join141, extname as extname25 } from "path";
|
|
181485
181609
|
function liveRemainingMs(budget, fallbackMs) {
|
|
181486
181610
|
return budget.remainingMs?.() ?? fallbackMs;
|
|
181487
181611
|
}
|
|
@@ -181519,7 +181643,7 @@ async function saveLottieAnimations(discoveredLotties, lottieDir, budget = {}) {
|
|
|
181519
181643
|
if (savedHashes.has(hash2)) continue;
|
|
181520
181644
|
savedHashes.add(hash2);
|
|
181521
181645
|
if (!validLottieJson(jsonData)) continue;
|
|
181522
|
-
writeCaptureFileSync(
|
|
181646
|
+
writeCaptureFileSync(join141(lottieDir, `animation-${savedCount}.json`), jsonData, "utf-8");
|
|
181523
181647
|
savedCount++;
|
|
181524
181648
|
}
|
|
181525
181649
|
} catch {
|
|
@@ -181529,18 +181653,18 @@ async function saveLottieAnimations(discoveredLotties, lottieDir, budget = {}) {
|
|
|
181529
181653
|
}
|
|
181530
181654
|
async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir, budget = {}) {
|
|
181531
181655
|
const manifest = [];
|
|
181532
|
-
const previewDir =
|
|
181656
|
+
const previewDir = join141(lottieDir, "previews");
|
|
181533
181657
|
mkdirSync63(previewDir, { recursive: true });
|
|
181534
181658
|
for (const file of readdirSync43(lottieDir)) {
|
|
181535
181659
|
if (!file.endsWith(".json")) continue;
|
|
181536
181660
|
if (liveRemainingMs(budget, 1) <= 0) break;
|
|
181537
181661
|
try {
|
|
181538
|
-
const raw = JSON.parse(readFileSync93(
|
|
181662
|
+
const raw = JSON.parse(readFileSync93(join141(lottieDir, file), "utf-8"));
|
|
181539
181663
|
const fr = raw.fr || 30;
|
|
181540
181664
|
const dur = ((raw.op || 0) - (raw.ip || 0)) / fr;
|
|
181541
181665
|
const previewName = file.replace(".json", "-preview.png");
|
|
181542
181666
|
let preview;
|
|
181543
|
-
const fileSize = statSync45(
|
|
181667
|
+
const fileSize = statSync45(join141(lottieDir, file)).size;
|
|
181544
181668
|
if (fileSize > 2e6) continue;
|
|
181545
181669
|
let previewPage;
|
|
181546
181670
|
try {
|
|
@@ -181549,7 +181673,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir, budget
|
|
|
181549
181673
|
if (liveRemainingMs(budget, 1) <= 0) break;
|
|
181550
181674
|
await guardLottiePreviewRequests(previewPage);
|
|
181551
181675
|
await previewPage.setViewport({ width: 400, height: 400 });
|
|
181552
|
-
const animData = JSON.parse(readFileSync93(
|
|
181676
|
+
const animData = JSON.parse(readFileSync93(join141(lottieDir, file), "utf-8"));
|
|
181553
181677
|
const midFrame = Math.floor(((raw.op || 0) - (raw.ip || 0)) * 0.3);
|
|
181554
181678
|
await previewPage.setContent(
|
|
181555
181679
|
`<!DOCTYPE html>
|
|
@@ -181579,11 +181703,8 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir, budget
|
|
|
181579
181703
|
await previewPage.waitForFunction(() => window.__READY === true, { timeout: 5e3 }).catch(() => {
|
|
181580
181704
|
});
|
|
181581
181705
|
if (liveRemainingMs(budget, 1) > 0) {
|
|
181582
|
-
await previewPage.screenshot({
|
|
181583
|
-
|
|
181584
|
-
type: "png",
|
|
181585
|
-
omitBackground: true
|
|
181586
|
-
});
|
|
181706
|
+
const shot = await previewPage.screenshot({ type: "png", omitBackground: true });
|
|
181707
|
+
writeCaptureFileSync(join141(previewDir, previewName), shot);
|
|
181587
181708
|
preview = `assets/lottie/previews/${previewName}`;
|
|
181588
181709
|
}
|
|
181589
181710
|
} catch {
|
|
@@ -181606,7 +181727,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir, budget
|
|
|
181606
181727
|
}
|
|
181607
181728
|
if (manifest.length > 0) {
|
|
181608
181729
|
writeCaptureFileSync(
|
|
181609
|
-
|
|
181730
|
+
join141(outputDir, "extracted", "lottie-manifest.json"),
|
|
181610
181731
|
JSON.stringify(manifest, null, 2),
|
|
181611
181732
|
"utf-8"
|
|
181612
181733
|
);
|
|
@@ -181644,7 +181765,7 @@ async function downloadVideoBody(srcUrl, filename, videosDir, timeoutMs) {
|
|
|
181644
181765
|
}
|
|
181645
181766
|
if (total < 1024) return null;
|
|
181646
181767
|
const safe = /\.[a-z0-9]+$/i.test(filename) ? filename.replace(/[^\w.-]/g, "_") : `video${ext}`;
|
|
181647
|
-
writeCaptureFileSync(
|
|
181768
|
+
writeCaptureFileSync(join141(videosDir, safe), Buffer.concat(chunks));
|
|
181648
181769
|
return `assets/videos/${safe}`;
|
|
181649
181770
|
} catch {
|
|
181650
181771
|
return null;
|
|
@@ -181711,9 +181832,9 @@ async function captureVideoManifest(page, outputDir, progress, opts) {
|
|
|
181711
181832
|
}
|
|
181712
181833
|
const merged = [...byKey.values()];
|
|
181713
181834
|
if (merged.length === 0) return;
|
|
181714
|
-
const videoManifestDir =
|
|
181835
|
+
const videoManifestDir = join141(outputDir, "assets", "videos");
|
|
181715
181836
|
mkdirSync63(videoManifestDir, { recursive: true });
|
|
181716
|
-
const previewDir =
|
|
181837
|
+
const previewDir = join141(videoManifestDir, "previews");
|
|
181717
181838
|
mkdirSync63(previewDir, { recursive: true });
|
|
181718
181839
|
const videoManifest = [];
|
|
181719
181840
|
const dlStart = Date.now();
|
|
@@ -181741,8 +181862,8 @@ async function captureVideoManifest(page, outputDir, progress, opts) {
|
|
|
181741
181862
|
if (rect && rect.width >= 10) {
|
|
181742
181863
|
await new Promise((r) => setTimeout(r, 200));
|
|
181743
181864
|
if (liveRemainingMs(opts ?? {}, 1) > 0) {
|
|
181744
|
-
await page.screenshot({
|
|
181745
|
-
|
|
181865
|
+
const shot = await page.screenshot({
|
|
181866
|
+
type: "png",
|
|
181746
181867
|
clip: {
|
|
181747
181868
|
x: Math.max(0, rect.x),
|
|
181748
181869
|
y: Math.max(0, rect.y),
|
|
@@ -181750,6 +181871,7 @@ async function captureVideoManifest(page, outputDir, progress, opts) {
|
|
|
181750
181871
|
height: Math.min(rect.height, 1080)
|
|
181751
181872
|
}
|
|
181752
181873
|
});
|
|
181874
|
+
writeCaptureFileSync(join141(previewDir, previewName), shot);
|
|
181753
181875
|
preview = `assets/videos/previews/${previewName}`;
|
|
181754
181876
|
}
|
|
181755
181877
|
}
|
|
@@ -181779,7 +181901,7 @@ async function captureVideoManifest(page, outputDir, progress, opts) {
|
|
|
181779
181901
|
}
|
|
181780
181902
|
if (videoManifest.length > 0) {
|
|
181781
181903
|
writeCaptureFileSync(
|
|
181782
|
-
|
|
181904
|
+
join141(outputDir, "extracted", "video-manifest.json"),
|
|
181783
181905
|
JSON.stringify(videoManifest, null, 2),
|
|
181784
181906
|
"utf-8"
|
|
181785
181907
|
);
|
|
@@ -181902,7 +182024,7 @@ __export(screenshotCapture_exports, {
|
|
|
181902
182024
|
pngHeight: () => pngHeight
|
|
181903
182025
|
});
|
|
181904
182026
|
import { mkdirSync as mkdirSync64 } from "fs";
|
|
181905
|
-
import { join as
|
|
182027
|
+
import { join as join143 } from "path";
|
|
181906
182028
|
function pngHeight(buf) {
|
|
181907
182029
|
if (buf.length < 24) return null;
|
|
181908
182030
|
if (buf[12] !== 73 || buf[13] !== 72 || buf[14] !== 68 || buf[15] !== 82) return null;
|
|
@@ -181927,7 +182049,7 @@ async function captureFullPagePlate(page, screenshotsDir, budget = {}) {
|
|
|
181927
182049
|
const buffer = await page.screenshot({ type: "png", fullPage: true });
|
|
181928
182050
|
const produced = pngHeight(buffer);
|
|
181929
182051
|
if (produced != null && produced > MAX_PLATE_HEIGHT_PX) return null;
|
|
181930
|
-
writeCaptureFileSync(
|
|
182052
|
+
writeCaptureFileSync(join143(screenshotsDir, "full-page.png"), buffer);
|
|
181931
182053
|
return "screenshots/full-page.png";
|
|
181932
182054
|
} finally {
|
|
181933
182055
|
try {
|
|
@@ -181942,7 +182064,7 @@ async function captureFullPagePlate(page, screenshotsDir, budget = {}) {
|
|
|
181942
182064
|
}
|
|
181943
182065
|
}
|
|
181944
182066
|
async function captureScrollScreenshots(page, outputDir, budget = {}) {
|
|
181945
|
-
const screenshotsDir =
|
|
182067
|
+
const screenshotsDir = join143(outputDir, "screenshots");
|
|
181946
182068
|
mkdirSync64(screenshotsDir, { recursive: true });
|
|
181947
182069
|
const MAX_SCREENSHOTS = 20;
|
|
181948
182070
|
const filePaths = [];
|
|
@@ -182039,7 +182161,7 @@ async function captureScrollScreenshots(page, outputDir, budget = {}) {
|
|
|
182039
182161
|
finalPositions[i] / Math.max(1, scrollHeight - viewportHeight) * 100
|
|
182040
182162
|
);
|
|
182041
182163
|
const filename = `scroll-${String(Math.min(pct, 100)).padStart(3, "0")}.png`;
|
|
182042
|
-
const filePath =
|
|
182164
|
+
const filePath = join143(screenshotsDir, filename);
|
|
182043
182165
|
if ((budget.remainingMs?.() ?? 1) <= 0) break;
|
|
182044
182166
|
const buffer = await page.screenshot({ type: "png" });
|
|
182045
182167
|
writeCaptureFileSync(filePath, buffer);
|
|
@@ -182397,7 +182519,7 @@ var init_assetCataloger = __esm({
|
|
|
182397
182519
|
|
|
182398
182520
|
// src/capture/coreExtractionPhase.ts
|
|
182399
182521
|
import { mkdirSync as mkdirSync65 } from "fs";
|
|
182400
|
-
import { join as
|
|
182522
|
+
import { join as join144 } from "path";
|
|
182401
182523
|
async function runCoreExtraction(input2) {
|
|
182402
182524
|
let {
|
|
182403
182525
|
page1,
|
|
@@ -182487,7 +182609,7 @@ async function runCoreExtraction(input2) {
|
|
|
182487
182609
|
await collectNetworkLotties();
|
|
182488
182610
|
const saveDiscoveredLotties = async () => {
|
|
182489
182611
|
if (discoveredLotties.length > 0 && remainingMs() > 0) {
|
|
182490
|
-
const lottieDir =
|
|
182612
|
+
const lottieDir = join144(outputDir, "assets", "lottie");
|
|
182491
182613
|
if (!canWrite()) return;
|
|
182492
182614
|
mkdirSync65(lottieDir, { recursive: true });
|
|
182493
182615
|
const lottieBudget = { remainingMs, byteBudget: downloadByteBudget };
|
|
@@ -182514,7 +182636,7 @@ async function runCoreExtraction(input2) {
|
|
|
182514
182636
|
capturedShaders = unique;
|
|
182515
182637
|
if (canWrite()) {
|
|
182516
182638
|
writeCaptureFileSync(
|
|
182517
|
-
|
|
182639
|
+
join144(outputDir, "extracted", "shaders.json"),
|
|
182518
182640
|
JSON.stringify(unique, null, 2),
|
|
182519
182641
|
"utf-8"
|
|
182520
182642
|
);
|
|
@@ -182531,7 +182653,7 @@ async function runCoreExtraction(input2) {
|
|
|
182531
182653
|
state.tokens = tokens;
|
|
182532
182654
|
if (canWrite()) {
|
|
182533
182655
|
writeCaptureFileSync(
|
|
182534
|
-
|
|
182656
|
+
join144(outputDir, "extracted", "tokens.json"),
|
|
182535
182657
|
serializeTokensForCapture(tokens),
|
|
182536
182658
|
"utf-8"
|
|
182537
182659
|
);
|
|
@@ -182542,7 +182664,7 @@ async function runCoreExtraction(input2) {
|
|
|
182542
182664
|
state.designStyles = designStyles;
|
|
182543
182665
|
if (canWrite()) {
|
|
182544
182666
|
writeCaptureFileSync(
|
|
182545
|
-
|
|
182667
|
+
join144(outputDir, "extracted", "design-styles.json"),
|
|
182546
182668
|
JSON.stringify(designStyles, null, 2),
|
|
182547
182669
|
"utf-8"
|
|
182548
182670
|
);
|
|
@@ -182685,7 +182807,7 @@ var init_coreExtractionPhase = __esm({
|
|
|
182685
182807
|
|
|
182686
182808
|
// src/capture/fontMetadataExtractor.ts
|
|
182687
182809
|
import { readdirSync as readdirSync44, readFileSync as readFileSync94, existsSync as existsSync120 } from "fs";
|
|
182688
|
-
import { join as
|
|
182810
|
+
import { join as join145 } from "path";
|
|
182689
182811
|
import * as fontkit from "fontkit";
|
|
182690
182812
|
function isFontCollection(value) {
|
|
182691
182813
|
return value.type === "TTC" || value.type === "DFont";
|
|
@@ -182696,7 +182818,7 @@ function extractFontMetadata(fontsDir, outputPath) {
|
|
|
182696
182818
|
if (existsSync120(fontsDir)) {
|
|
182697
182819
|
const fontFiles = readdirSync44(fontsDir).filter((f) => /\.(woff2?|ttf|otf)$/i.test(f));
|
|
182698
182820
|
for (const filename of fontFiles) {
|
|
182699
|
-
const fullPath =
|
|
182821
|
+
const fullPath = join145(fontsDir, filename);
|
|
182700
182822
|
const meta = readSingleFont(fullPath, filename);
|
|
182701
182823
|
if (meta.identified) {
|
|
182702
182824
|
files.push(meta);
|
|
@@ -182871,7 +182993,7 @@ var init_fontMetadataExtractor = __esm({
|
|
|
182871
182993
|
|
|
182872
182994
|
// src/capture/postExtractionPhase.ts
|
|
182873
182995
|
import { existsSync as existsSync121 } from "fs";
|
|
182874
|
-
import { join as
|
|
182996
|
+
import { join as join146 } from "path";
|
|
182875
182997
|
function hasVisionCredentials(skipVision) {
|
|
182876
182998
|
return Boolean(
|
|
182877
182999
|
!skipVision && (process.env.OPENROUTER_API_KEY || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || process.env.HYPERFRAMES_VERTEX_PROJECT_ID && process.env.HYPERFRAMES_VERTEX_SERVICE_ACCOUNT)
|
|
@@ -182879,7 +183001,7 @@ function hasVisionCredentials(skipVision) {
|
|
|
182879
183001
|
}
|
|
182880
183002
|
function writeAssetDescriptionsFile(outputDir, lines, header2) {
|
|
182881
183003
|
writeCaptureFileSync(
|
|
182882
|
-
|
|
183004
|
+
join146(outputDir, "extracted", "asset-descriptions.md"),
|
|
182883
183005
|
header2 + lines.map((line3) => `- ${line3}`).join("\n") + "\n",
|
|
182884
183006
|
"utf-8"
|
|
182885
183007
|
);
|
|
@@ -182922,8 +183044,8 @@ async function runPostExtraction(input2) {
|
|
|
182922
183044
|
);
|
|
182923
183045
|
try {
|
|
182924
183046
|
const fontsManifest = extractFontMetadata(
|
|
182925
|
-
|
|
182926
|
-
|
|
183047
|
+
join146(outputDir, "assets", "fonts"),
|
|
183048
|
+
join146(outputDir, "extracted", "fonts-manifest.json")
|
|
182927
183049
|
);
|
|
182928
183050
|
if (fontsManifest.families.length > 0) {
|
|
182929
183051
|
const summary = fontsManifest.families.map((f) => `${f.family}${f.variable ? " (variable)" : ""} \xD7 ${f.fileCount}`).join(", ");
|
|
@@ -182954,7 +183076,7 @@ async function runPostExtraction(input2) {
|
|
|
182954
183076
|
};
|
|
182955
183077
|
if (canWrite()) {
|
|
182956
183078
|
writeCaptureFileSync(
|
|
182957
|
-
|
|
183079
|
+
join146(outputDir, "extracted", "animations.json"),
|
|
182958
183080
|
JSON.stringify(leanCatalog, null, 2),
|
|
182959
183081
|
"utf-8"
|
|
182960
183082
|
);
|
|
@@ -182977,7 +183099,7 @@ async function runPostExtraction(input2) {
|
|
|
182977
183099
|
state.assets = assets;
|
|
182978
183100
|
if (canWrite()) {
|
|
182979
183101
|
writeCaptureFileSync(
|
|
182980
|
-
|
|
183102
|
+
join146(outputDir, "extracted", "icons-manifest.json"),
|
|
182981
183103
|
JSON.stringify(assetPass.icons, null, 2),
|
|
182982
183104
|
"utf-8"
|
|
182983
183105
|
);
|
|
@@ -183029,7 +183151,7 @@ async function runPostExtraction(input2) {
|
|
|
183029
183151
|
if (assets.length && Array.isArray(tokens.sections)) {
|
|
183030
183152
|
if (canWrite()) {
|
|
183031
183153
|
writeCaptureFileSync(
|
|
183032
|
-
|
|
183154
|
+
join146(outputDir, "extracted", "tokens.json"),
|
|
183033
183155
|
serializeTokensForCapture(tokens),
|
|
183034
183156
|
"utf-8"
|
|
183035
183157
|
);
|
|
@@ -183052,14 +183174,14 @@ ${extracted.bodyHtml}
|
|
|
183052
183174
|
`;
|
|
183053
183175
|
state.pageHtml = pageHtml;
|
|
183054
183176
|
if (canWrite())
|
|
183055
|
-
writeCaptureFileSync(
|
|
183177
|
+
writeCaptureFileSync(join146(outputDir, "extracted", "page.html"), pageHtml, "utf-8");
|
|
183056
183178
|
} catch (err) {
|
|
183057
183179
|
warnings.push(`page.html write failed: ${err}`);
|
|
183058
183180
|
}
|
|
183059
183181
|
if (visibleTextContent) {
|
|
183060
183182
|
if (canWrite()) {
|
|
183061
183183
|
writeCaptureFileSync(
|
|
183062
|
-
|
|
183184
|
+
join146(outputDir, "extracted", "visible-text.txt"),
|
|
183063
183185
|
visibleTextContent,
|
|
183064
183186
|
"utf-8"
|
|
183065
183187
|
);
|
|
@@ -183121,8 +183243,8 @@ ${extracted.bodyHtml}
|
|
|
183121
183243
|
const contactSheetBudget = { remainingMs };
|
|
183122
183244
|
const runScrollContactSheet = async () => {
|
|
183123
183245
|
const scrollSheets = await createScrollContactSheet2(
|
|
183124
|
-
|
|
183125
|
-
|
|
183246
|
+
join146(outputDir, "screenshots"),
|
|
183247
|
+
join146(outputDir, "screenshots", "contact-sheet.jpg"),
|
|
183126
183248
|
contactSheetBudget
|
|
183127
183249
|
);
|
|
183128
183250
|
if (scrollSheets.length > 0)
|
|
@@ -183133,11 +183255,11 @@ ${extracted.bodyHtml}
|
|
|
183133
183255
|
};
|
|
183134
183256
|
await runScrollContactSheet();
|
|
183135
183257
|
const runAssetContactSheet = async () => {
|
|
183136
|
-
const assetsImgDir =
|
|
183258
|
+
const assetsImgDir = join146(outputDir, "assets");
|
|
183137
183259
|
if (existsSync121(assetsImgDir)) {
|
|
183138
183260
|
const assetSheets = await createAssetContactSheet2(
|
|
183139
183261
|
assetsImgDir,
|
|
183140
|
-
|
|
183262
|
+
join146(outputDir, "assets", "contact-sheet.jpg"),
|
|
183141
183263
|
contactSheetBudget
|
|
183142
183264
|
);
|
|
183143
183265
|
if (assetSheets.length > 0)
|
|
@@ -183149,9 +183271,9 @@ ${extracted.bodyHtml}
|
|
|
183149
183271
|
};
|
|
183150
183272
|
await runAssetContactSheet();
|
|
183151
183273
|
const runSvgContactSheet = async () => {
|
|
183152
|
-
const svgsDir =
|
|
183153
|
-
const assetsRootDir =
|
|
183154
|
-
const svgOutputPath = existsSync121(svgsDir) ?
|
|
183274
|
+
const svgsDir = join146(outputDir, "assets", "svgs");
|
|
183275
|
+
const assetsRootDir = join146(outputDir, "assets");
|
|
183276
|
+
const svgOutputPath = existsSync121(svgsDir) ? join146(outputDir, "assets", "svgs", "contact-sheet.jpg") : join146(outputDir, "assets", "contact-sheet-svgs.jpg");
|
|
183155
183277
|
const svgSheets = await createSvgContactSheet2(
|
|
183156
183278
|
svgsDir,
|
|
183157
183279
|
svgOutputPath,
|
|
@@ -183197,7 +183319,7 @@ var init_postExtractionPhase = __esm({
|
|
|
183197
183319
|
|
|
183198
183320
|
// src/capture/captureAttempt.ts
|
|
183199
183321
|
import { mkdirSync as mkdirSync66, existsSync as existsSync122 } from "fs";
|
|
183200
|
-
import { join as
|
|
183322
|
+
import { join as join147 } from "path";
|
|
183201
183323
|
async function captureWebsiteAttempt(opts, onProgress, disableWebgl, watchdog, state) {
|
|
183202
183324
|
const {
|
|
183203
183325
|
url,
|
|
@@ -183242,9 +183364,9 @@ async function captureWebsiteAttempt(opts, onProgress, disableWebgl, watchdog, s
|
|
|
183242
183364
|
};
|
|
183243
183365
|
phase("browser", "started");
|
|
183244
183366
|
loadEnvFile(outputDir);
|
|
183245
|
-
mkdirSync66(
|
|
183246
|
-
mkdirSync66(
|
|
183247
|
-
mkdirSync66(
|
|
183367
|
+
mkdirSync66(join147(outputDir, "extracted"), { recursive: true });
|
|
183368
|
+
mkdirSync66(join147(outputDir, "screenshots"), { recursive: true });
|
|
183369
|
+
mkdirSync66(join147(outputDir, "assets"), { recursive: true });
|
|
183248
183370
|
progress("browser", "Launching headless Chrome...");
|
|
183249
183371
|
const { ensureBrowser: ensureBrowser2 } = await Promise.resolve().then(() => (init_manager2(), manager_exports2));
|
|
183250
183372
|
const browser = await ensureBrowser2();
|
|
@@ -183411,7 +183533,7 @@ async function captureWebsiteAttempt(opts, onProgress, disableWebgl, watchdog, s
|
|
|
183411
183533
|
animationCatalog,
|
|
183412
183534
|
screenshots.length > 0,
|
|
183413
183535
|
discoveredLotties.length > 0,
|
|
183414
|
-
existsSync122(
|
|
183536
|
+
existsSync122(join147(outputDir, "extracted", "shaders.json")),
|
|
183415
183537
|
catalogedAssets,
|
|
183416
183538
|
progress,
|
|
183417
183539
|
warnings,
|
|
@@ -183765,11 +183887,12 @@ var init_capture2 = __esm({
|
|
|
183765
183887
|
} catch (err) {
|
|
183766
183888
|
const errMsg = normalizeErrorMessage(err);
|
|
183767
183889
|
try {
|
|
183768
|
-
const { mkdirSync: mkdirSync76
|
|
183890
|
+
const { mkdirSync: mkdirSync76 } = await import("fs");
|
|
183769
183891
|
const { formatCaptureFailureReason: formatCaptureFailureReason2 } = await Promise.resolve().then(() => (init_captureTimeout(), captureTimeout_exports));
|
|
183892
|
+
const { writeCaptureFileSync: writeCaptureFileSync2 } = await Promise.resolve().then(() => (init_captureFile(), captureFile_exports));
|
|
183770
183893
|
mkdirSync76(outputDir, { recursive: true });
|
|
183771
183894
|
const reason = formatCaptureFailureReason2(errMsg);
|
|
183772
|
-
|
|
183895
|
+
writeCaptureFileSync2(
|
|
183773
183896
|
`${outputDir}/BLOCKED.md`,
|
|
183774
183897
|
`# Capture Failed
|
|
183775
183898
|
|
|
@@ -183833,14 +183956,14 @@ __export(state_exports, {
|
|
|
183833
183956
|
stateFilePath: () => stateFilePath,
|
|
183834
183957
|
writeStackOutputs: () => writeStackOutputs
|
|
183835
183958
|
});
|
|
183836
|
-
import { existsSync as existsSync123, mkdirSync as mkdirSync67, readdirSync as readdirSync45, readFileSync as readFileSync95, rmSync as
|
|
183837
|
-
import { dirname as
|
|
183959
|
+
import { existsSync as existsSync123, mkdirSync as mkdirSync67, readdirSync as readdirSync45, readFileSync as readFileSync95, rmSync as rmSync41, writeFileSync as writeFileSync51 } from "fs";
|
|
183960
|
+
import { dirname as dirname65, join as join148 } from "path";
|
|
183838
183961
|
function stateFilePath(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
183839
|
-
return
|
|
183962
|
+
return join148(cwd, STATE_DIR_NAME, `${STATE_FILE_PREFIX}${stackName}.json`);
|
|
183840
183963
|
}
|
|
183841
183964
|
function writeStackOutputs(outputs, cwd = process.cwd()) {
|
|
183842
183965
|
const path = stateFilePath(outputs.stackName, cwd);
|
|
183843
|
-
mkdirSync67(
|
|
183966
|
+
mkdirSync67(dirname65(path), { recursive: true });
|
|
183844
183967
|
writeFileSync51(path, JSON.stringify(outputs, null, 2) + "\n");
|
|
183845
183968
|
return path;
|
|
183846
183969
|
}
|
|
@@ -183855,10 +183978,10 @@ function readStackOutputs(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
|
183855
183978
|
}
|
|
183856
183979
|
function deleteStackOutputs(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
183857
183980
|
const path = stateFilePath(stackName, cwd);
|
|
183858
|
-
if (existsSync123(path))
|
|
183981
|
+
if (existsSync123(path)) rmSync41(path);
|
|
183859
183982
|
}
|
|
183860
183983
|
function listStackNames(cwd = process.cwd()) {
|
|
183861
|
-
const dir =
|
|
183984
|
+
const dir = join148(cwd, STATE_DIR_NAME);
|
|
183862
183985
|
if (!existsSync123(dir)) return [];
|
|
183863
183986
|
return readdirSync45(dir).filter((f) => f.startsWith(STATE_FILE_PREFIX) && f.endsWith(".json")).map((f) => f.slice(STATE_FILE_PREFIX.length, -".json".length));
|
|
183864
183987
|
}
|
|
@@ -183891,7 +184014,7 @@ var init_state = __esm({
|
|
|
183891
184014
|
// src/commands/lambda/sam.ts
|
|
183892
184015
|
import { execFileSync as execFileSync19, spawnSync as spawnSync5 } from "child_process";
|
|
183893
184016
|
import { existsSync as existsSync124 } from "fs";
|
|
183894
|
-
import { join as
|
|
184017
|
+
import { join as join149 } from "path";
|
|
183895
184018
|
function assertSamAvailable() {
|
|
183896
184019
|
try {
|
|
183897
184020
|
execFileSync19("sam", ["--version"], { stdio: "ignore" });
|
|
@@ -183911,7 +184034,7 @@ function assertAwsCliAvailable() {
|
|
|
183911
184034
|
}
|
|
183912
184035
|
}
|
|
183913
184036
|
function locateSamTemplate(repoRoot2) {
|
|
183914
|
-
const candidate =
|
|
184037
|
+
const candidate = join149(repoRoot2, "examples", "aws-lambda", "template.yaml");
|
|
183915
184038
|
if (!existsSync124(candidate)) {
|
|
183916
184039
|
throw new Error(
|
|
183917
184040
|
`[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.`
|
|
@@ -183945,7 +184068,7 @@ function samDeploy(opts) {
|
|
|
183945
184068
|
if (opts.awsProfile) {
|
|
183946
184069
|
args.push("--profile", opts.awsProfile);
|
|
183947
184070
|
}
|
|
183948
|
-
const samDir =
|
|
184071
|
+
const samDir = join149(opts.repoRoot, "examples", "aws-lambda");
|
|
183949
184072
|
const result = spawnSync5("sam", args, { cwd: samDir, stdio: opts.stdio ?? "inherit" });
|
|
183950
184073
|
if (result.status !== 0) {
|
|
183951
184074
|
throw new Error(
|
|
@@ -183963,7 +184086,7 @@ function samDelete(opts) {
|
|
|
183963
184086
|
if (opts.awsProfile) {
|
|
183964
184087
|
args.push("--profile", opts.awsProfile);
|
|
183965
184088
|
}
|
|
183966
|
-
const samDir =
|
|
184089
|
+
const samDir = join149(opts.repoRoot, "examples", "aws-lambda");
|
|
183967
184090
|
const result = spawnSync5("sam", args, { cwd: samDir, stdio: opts.stdio ?? "inherit" });
|
|
183968
184091
|
if (result.status !== 0) {
|
|
183969
184092
|
throw new Error(`[lambda] sam delete exited with code ${result.status ?? "unknown"}`);
|
|
@@ -184014,19 +184137,19 @@ var init_sam = __esm({
|
|
|
184014
184137
|
|
|
184015
184138
|
// src/commands/lambda/repoRoot.ts
|
|
184016
184139
|
import { existsSync as existsSync125 } from "fs";
|
|
184017
|
-
import { dirname as
|
|
184140
|
+
import { dirname as dirname66, resolve as resolve79 } from "path";
|
|
184018
184141
|
import { fileURLToPath as fileURLToPath17 } from "url";
|
|
184019
184142
|
function repoRoot() {
|
|
184020
184143
|
const override = process.env.HYPERFRAMES_REPO_ROOT;
|
|
184021
184144
|
if (override && existsSync125(resolve79(override, "packages", "aws-lambda", "package.json"))) {
|
|
184022
184145
|
return override;
|
|
184023
184146
|
}
|
|
184024
|
-
let dir =
|
|
184147
|
+
let dir = dirname66(fileURLToPath17(import.meta.url));
|
|
184025
184148
|
for (let depth = 0; depth < 12; depth++) {
|
|
184026
184149
|
if (existsSync125(resolve79(dir, "packages", "aws-lambda", "package.json"))) {
|
|
184027
184150
|
return dir;
|
|
184028
184151
|
}
|
|
184029
|
-
const parent =
|
|
184152
|
+
const parent = dirname66(dir);
|
|
184030
184153
|
if (parent === dir) break;
|
|
184031
184154
|
dir = parent;
|
|
184032
184155
|
}
|
|
@@ -184047,7 +184170,7 @@ __export(deploy_exports, {
|
|
|
184047
184170
|
});
|
|
184048
184171
|
import { spawnSync as spawnSync6 } from "child_process";
|
|
184049
184172
|
import { existsSync as existsSync126 } from "fs";
|
|
184050
|
-
import { join as
|
|
184173
|
+
import { join as join150, resolve as resolve80 } from "path";
|
|
184051
184174
|
async function runDeploy(args = {}) {
|
|
184052
184175
|
const resolved2 = {
|
|
184053
184176
|
stackName: args.stackName ?? DEFAULT_STACK_NAME,
|
|
@@ -184064,7 +184187,7 @@ async function runDeploy(args = {}) {
|
|
|
184064
184187
|
console.log(c.dim("\u2192 Building handler ZIP"));
|
|
184065
184188
|
buildHandlerZip(root);
|
|
184066
184189
|
} else {
|
|
184067
|
-
const zip =
|
|
184190
|
+
const zip = join150(root, "packages", "aws-lambda", "dist", "handler.zip");
|
|
184068
184191
|
if (!existsSync126(zip)) {
|
|
184069
184192
|
throw new Error(
|
|
184070
184193
|
`--skip-build set but ${zip} does not exist. Run \`bun run --cwd packages/aws-lambda build:zip\` first or drop --skip-build.`
|
|
@@ -184108,7 +184231,7 @@ async function runDeploy(args = {}) {
|
|
|
184108
184231
|
function buildHandlerZip(root) {
|
|
184109
184232
|
const result = spawnSync6(
|
|
184110
184233
|
"bun",
|
|
184111
|
-
["run", "--cwd",
|
|
184234
|
+
["run", "--cwd", join150(root, "packages", "aws-lambda"), "build:zip"],
|
|
184112
184235
|
{ stdio: "inherit" }
|
|
184113
184236
|
);
|
|
184114
184237
|
if (result.status !== 0) {
|
|
@@ -184178,13 +184301,13 @@ var init_sites = __esm({
|
|
|
184178
184301
|
|
|
184179
184302
|
// src/commands/lambda/_dimensions.ts
|
|
184180
184303
|
import { readFileSync as readFileSync96 } from "fs";
|
|
184181
|
-
import { join as
|
|
184304
|
+
import { join as join151 } from "path";
|
|
184182
184305
|
function warnOnDimensionMismatch(args) {
|
|
184183
184306
|
if (args.quiet) return;
|
|
184184
184307
|
if (args.outputResolution) return;
|
|
184185
184308
|
let html;
|
|
184186
184309
|
try {
|
|
184187
|
-
html = readFileSync96(
|
|
184310
|
+
html = readFileSync96(join151(args.projectDir, "index.html"), "utf-8");
|
|
184188
184311
|
} catch {
|
|
184189
184312
|
return;
|
|
184190
184313
|
}
|
|
@@ -184214,7 +184337,7 @@ __export(render_exports2, {
|
|
|
184214
184337
|
runRender: () => runRender
|
|
184215
184338
|
});
|
|
184216
184339
|
import { existsSync as existsSync127 } from "fs";
|
|
184217
|
-
import { join as
|
|
184340
|
+
import { join as join152, resolve as resolvePath2 } from "path";
|
|
184218
184341
|
async function loadSDK2() {
|
|
184219
184342
|
return import("@hyperframes/aws-lambda/sdk");
|
|
184220
184343
|
}
|
|
@@ -184230,7 +184353,7 @@ async function runRender(args) {
|
|
|
184230
184353
|
});
|
|
184231
184354
|
const variables = resolveVariablesArg(args.variables, args.variablesFile);
|
|
184232
184355
|
if (variables && Object.keys(variables).length > 0) {
|
|
184233
|
-
const indexPath2 =
|
|
184356
|
+
const indexPath2 = join152(projectDir, "index.html");
|
|
184234
184357
|
if (existsSync127(indexPath2)) {
|
|
184235
184358
|
const issues = validateVariablesAgainstProject(indexPath2, variables);
|
|
184236
184359
|
reportVariableIssues(issues, { strict: args.strictVariables ?? false, quiet: args.json });
|
|
@@ -184365,7 +184488,7 @@ __export(render_batch_exports, {
|
|
|
184365
184488
|
runWithConcurrencyLimit: () => runWithConcurrencyLimit
|
|
184366
184489
|
});
|
|
184367
184490
|
import { existsSync as existsSync128, readFileSync as readFileSync97 } from "fs";
|
|
184368
|
-
import { join as
|
|
184491
|
+
import { join as join153, resolve as resolvePath3 } from "path";
|
|
184369
184492
|
async function loadSDK3() {
|
|
184370
184493
|
return import("@hyperframes/aws-lambda/sdk");
|
|
184371
184494
|
}
|
|
@@ -184389,7 +184512,7 @@ async function runRenderBatch(args) {
|
|
|
184389
184512
|
outputResolution: args.outputResolution,
|
|
184390
184513
|
quiet: args.json
|
|
184391
184514
|
});
|
|
184392
|
-
const schema = loadProjectVariableSchema(
|
|
184515
|
+
const schema = loadProjectVariableSchema(join153(projectDir, "index.html"));
|
|
184393
184516
|
const strict = args.strictVariables ?? false;
|
|
184394
184517
|
let hadStrictIssue = false;
|
|
184395
184518
|
for (const { entry, lineNumber } of entries2) {
|
|
@@ -185437,7 +185560,7 @@ __export(cloudrun_exports, {
|
|
|
185437
185560
|
import { spawnSync as spawnSync7 } from "child_process";
|
|
185438
185561
|
import { existsSync as existsSync129, mkdirSync as mkdirSync68, readFileSync as readFileSync99, writeFileSync as writeFileSync53 } from "fs";
|
|
185439
185562
|
import { homedir as homedir24 } from "os";
|
|
185440
|
-
import { join as
|
|
185563
|
+
import { join as join154, resolve as resolve81 } from "path";
|
|
185441
185564
|
function loadCloudRunAdapter() {
|
|
185442
185565
|
cloudRunAdapterPromise ??= Promise.all([
|
|
185443
185566
|
import("@hyperframes/gcp-cloud-run/sdk"),
|
|
@@ -185456,10 +185579,10 @@ Or, for an opt-in project setup:
|
|
|
185456
185579
|
${c.accent("npm install @hyperframes/gcp-cloud-run")}`;
|
|
185457
185580
|
}
|
|
185458
185581
|
function stateDir() {
|
|
185459
|
-
return
|
|
185582
|
+
return join154(homedir24(), ".hyperframes");
|
|
185460
185583
|
}
|
|
185461
185584
|
function statePath() {
|
|
185462
|
-
return
|
|
185585
|
+
return join154(stateDir(), "cloudrun-state.json");
|
|
185463
185586
|
}
|
|
185464
185587
|
function writeState2(state) {
|
|
185465
185588
|
mkdirSync68(stateDir(), { recursive: true });
|
|
@@ -185616,11 +185739,11 @@ function machineVars(args, project, region, image) {
|
|
|
185616
185739
|
}
|
|
185617
185740
|
function findRepoRoot(tfDir) {
|
|
185618
185741
|
const candidate = resolve81(tfDir, "..", "..", "..");
|
|
185619
|
-
if (existsSync129(
|
|
185742
|
+
if (existsSync129(join154(candidate, "packages", "gcp-cloud-run", "Dockerfile"))) return candidate;
|
|
185620
185743
|
return null;
|
|
185621
185744
|
}
|
|
185622
185745
|
function writeCloudBuildConfig(image) {
|
|
185623
|
-
const cfgPath =
|
|
185746
|
+
const cfgPath = join154(stateDir(), "cloudrun-cloudbuild.yaml");
|
|
185624
185747
|
mkdirSync68(stateDir(), { recursive: true });
|
|
185625
185748
|
writeFileSync53(
|
|
185626
185749
|
cfgPath,
|
|
@@ -185912,7 +186035,7 @@ function resolveAndValidateVariables(args, projectDir) {
|
|
|
185912
186035
|
args["variables-file"]
|
|
185913
186036
|
);
|
|
185914
186037
|
if (variables && Object.keys(variables).length > 0) {
|
|
185915
|
-
const indexPath2 =
|
|
186038
|
+
const indexPath2 = join154(projectDir, "index.html");
|
|
185916
186039
|
if (existsSync129(indexPath2)) {
|
|
185917
186040
|
const issues = validateVariablesAgainstProject(indexPath2, variables);
|
|
185918
186041
|
reportVariableIssues(issues, {
|
|
@@ -186279,13 +186402,13 @@ import {
|
|
|
186279
186402
|
createWriteStream as createWriteStream4,
|
|
186280
186403
|
lstatSync as lstatSync11,
|
|
186281
186404
|
mkdirSync as mkdirSync69,
|
|
186282
|
-
mkdtempSync as
|
|
186405
|
+
mkdtempSync as mkdtempSync28,
|
|
186283
186406
|
readlinkSync as readlinkSync2,
|
|
186284
|
-
renameSync as
|
|
186285
|
-
rmSync as
|
|
186407
|
+
renameSync as renameSync24,
|
|
186408
|
+
rmSync as rmSync43,
|
|
186286
186409
|
statSync as statSync46
|
|
186287
186410
|
} from "fs";
|
|
186288
|
-
import { dirname as
|
|
186411
|
+
import { dirname as dirname67, join as join155, resolve as resolve82 } from "path";
|
|
186289
186412
|
import { pipeline as pipeline3 } from "stream/promises";
|
|
186290
186413
|
async function downloadToFile(url, destPath, options = {}) {
|
|
186291
186414
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
@@ -186296,14 +186419,14 @@ async function downloadToFile(url, destPath, options = {}) {
|
|
|
186296
186419
|
if (!res.body) {
|
|
186297
186420
|
throw new Error(`Failed to download ${url}: empty response body`);
|
|
186298
186421
|
}
|
|
186299
|
-
mkdirSync69(
|
|
186422
|
+
mkdirSync69(dirname67(destPath), { recursive: true });
|
|
186300
186423
|
const totalHeader = res.headers.get("content-length");
|
|
186301
186424
|
const total = totalHeader ? Number.parseInt(totalHeader, 10) : void 0;
|
|
186302
186425
|
const totalOpt = total !== void 0 && Number.isFinite(total) ? total : void 0;
|
|
186303
186426
|
const destination = resolveDownloadDestination(destPath);
|
|
186304
186427
|
const previous = statSync46(destination, { throwIfNoEntry: false });
|
|
186305
|
-
const stage =
|
|
186306
|
-
const stagedFile =
|
|
186428
|
+
const stage = mkdtempSync28(join155(dirname67(destination), ".hf-download-"));
|
|
186429
|
+
const stagedFile = join155(stage, "download");
|
|
186307
186430
|
let bytes = 0;
|
|
186308
186431
|
try {
|
|
186309
186432
|
await pipeline3(
|
|
@@ -186324,13 +186447,13 @@ async function downloadToFile(url, destPath, options = {}) {
|
|
|
186324
186447
|
);
|
|
186325
186448
|
options.signal?.throwIfAborted();
|
|
186326
186449
|
if (previous?.isFile()) chmodSync2(stagedFile, previous.mode & 511);
|
|
186327
|
-
|
|
186450
|
+
renameSync24(stagedFile, destination);
|
|
186328
186451
|
} catch (error) {
|
|
186329
186452
|
const reason = options.signal?.reason;
|
|
186330
186453
|
if (options.signal?.aborted && reason instanceof Error) throw reason;
|
|
186331
186454
|
throw error;
|
|
186332
186455
|
} finally {
|
|
186333
|
-
|
|
186456
|
+
rmSync43(stage, { recursive: true, force: true });
|
|
186334
186457
|
}
|
|
186335
186458
|
return { path: destPath, bytes };
|
|
186336
186459
|
}
|
|
@@ -186338,7 +186461,7 @@ function resolveDownloadDestination(destPath) {
|
|
|
186338
186461
|
let destination = resolve82(destPath);
|
|
186339
186462
|
for (let hops = 0; hops < 40; hops++) {
|
|
186340
186463
|
if (!lstatSync11(destination, { throwIfNoEntry: false })?.isSymbolicLink()) return destination;
|
|
186341
|
-
destination = resolve82(
|
|
186464
|
+
destination = resolve82(dirname67(destination), readlinkSync2(destination));
|
|
186342
186465
|
}
|
|
186343
186466
|
throw new Error(`Too many symbolic links in download destination: ${destPath}`);
|
|
186344
186467
|
}
|
|
@@ -188939,8 +189062,8 @@ var init_parseFigmaRef = __esm({
|
|
|
188939
189062
|
});
|
|
188940
189063
|
|
|
188941
189064
|
// ../core/dist/figma/freeze.js
|
|
188942
|
-
import { copyFileSync as copyFileSync11, mkdirSync as mkdirSync70, rmSync as
|
|
188943
|
-
import { dirname as
|
|
189065
|
+
import { copyFileSync as copyFileSync11, mkdirSync as mkdirSync70, rmSync as rmSync44, statSync as statSync47, writeFileSync as writeFileSync54 } from "fs";
|
|
189066
|
+
import { dirname as dirname68 } from "path";
|
|
188944
189067
|
function exceedsFreezeCap(byteLength) {
|
|
188945
189068
|
return byteLength > MAX_FREEZE_BYTES;
|
|
188946
189069
|
}
|
|
@@ -188949,13 +189072,13 @@ function freezeBytes(bytes, destPath) {
|
|
|
188949
189072
|
throw new Error("freeze failed: empty bytes");
|
|
188950
189073
|
if (exceedsFreezeCap(bytes.length))
|
|
188951
189074
|
throw new Error(`freeze failed: ${bytes.length} bytes exceeds ${MAX_FREEZE_BYTES} cap`);
|
|
188952
|
-
mkdirSync70(
|
|
189075
|
+
mkdirSync70(dirname68(destPath), { recursive: true });
|
|
188953
189076
|
try {
|
|
188954
189077
|
writeFileSync54(destPath, bytes, { flag: "wx" });
|
|
188955
189078
|
} catch (err) {
|
|
188956
189079
|
if (err.code !== "EEXIST")
|
|
188957
189080
|
throw err;
|
|
188958
|
-
|
|
189081
|
+
rmSync44(destPath);
|
|
188959
189082
|
writeFileSync54(destPath, bytes, { flag: "wx" });
|
|
188960
189083
|
}
|
|
188961
189084
|
return bytes.length;
|
|
@@ -188994,15 +189117,15 @@ var init_jsonl = __esm({
|
|
|
188994
189117
|
|
|
188995
189118
|
// ../core/dist/figma/manifest.js
|
|
188996
189119
|
import { appendFileSync as appendFileSync2, existsSync as existsSync132, mkdirSync as mkdirSync71, readFileSync as readFileSync103, writeFileSync as writeFileSync55 } from "fs";
|
|
188997
|
-
import { join as
|
|
189120
|
+
import { join as join156 } from "path";
|
|
188998
189121
|
function mediaDir(projectDir) {
|
|
188999
|
-
return
|
|
189122
|
+
return join156(projectDir, ".media");
|
|
189000
189123
|
}
|
|
189001
189124
|
function manifestPath2(projectDir) {
|
|
189002
|
-
return
|
|
189125
|
+
return join156(mediaDir(projectDir), MANIFEST_FILE2);
|
|
189003
189126
|
}
|
|
189004
189127
|
function typeDirPath(projectDir, type) {
|
|
189005
|
-
return
|
|
189128
|
+
return join156(mediaDir(projectDir), TYPE_DIRS[type]);
|
|
189006
189129
|
}
|
|
189007
189130
|
function isFigmaManifestRecord(value) {
|
|
189008
189131
|
if (typeof value !== "object" || value === null)
|
|
@@ -189089,12 +189212,12 @@ var init_manifest = __esm({
|
|
|
189089
189212
|
|
|
189090
189213
|
// ../core/dist/figma/mediaIndex.js
|
|
189091
189214
|
import { mkdirSync as mkdirSync72, writeFileSync as writeFileSync56 } from "fs";
|
|
189092
|
-
import { dirname as
|
|
189215
|
+
import { dirname as dirname69, join as join157 } from "path";
|
|
189093
189216
|
function isRow(value) {
|
|
189094
189217
|
return typeof value === "object" && value !== null;
|
|
189095
189218
|
}
|
|
189096
189219
|
function indexPath(projectDir) {
|
|
189097
|
-
return
|
|
189220
|
+
return join157(mediaDir(projectDir), "index.md");
|
|
189098
189221
|
}
|
|
189099
189222
|
function pad(str, len2) {
|
|
189100
189223
|
return String(str ?? "").padEnd(len2);
|
|
@@ -189139,7 +189262,7 @@ function regenerateIndex(projectDir) {
|
|
|
189139
189262
|
const records = readJsonlValues(manifestPath2(projectDir)).filter(isRow);
|
|
189140
189263
|
const content = generateIndexContent(records);
|
|
189141
189264
|
const p2 = indexPath(projectDir);
|
|
189142
|
-
mkdirSync72(
|
|
189265
|
+
mkdirSync72(dirname69(p2), { recursive: true });
|
|
189143
189266
|
writeFileSync56(p2, content);
|
|
189144
189267
|
return content;
|
|
189145
189268
|
}
|
|
@@ -189206,9 +189329,9 @@ var init_sanitizeSvg = __esm({
|
|
|
189206
189329
|
|
|
189207
189330
|
// ../core/dist/figma/bindings.js
|
|
189208
189331
|
import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync73, writeFileSync as writeFileSync57 } from "fs";
|
|
189209
|
-
import { join as
|
|
189332
|
+
import { join as join158 } from "path";
|
|
189210
189333
|
function bindingsPath(projectDir) {
|
|
189211
|
-
return
|
|
189334
|
+
return join158(mediaDir(projectDir), BINDINGS_FILE);
|
|
189212
189335
|
}
|
|
189213
189336
|
function isRecord17(value) {
|
|
189214
189337
|
return typeof value === "object" && value !== null;
|
|
@@ -189809,7 +189932,7 @@ __export(asset_exports, {
|
|
|
189809
189932
|
runAssetImportMany: () => runAssetImportMany
|
|
189810
189933
|
});
|
|
189811
189934
|
import { existsSync as existsSync133 } from "fs";
|
|
189812
|
-
import { join as
|
|
189935
|
+
import { join as join159, relative as relative36 } from "path";
|
|
189813
189936
|
function gatherAssetRefs(positionals) {
|
|
189814
189937
|
return positionals.flatMap((r) => /^https?:/i.test(r.trim()) ? [r] : r.split(",")).map((r) => r.trim()).filter((r) => r.length > 0);
|
|
189815
189938
|
}
|
|
@@ -189823,7 +189946,7 @@ function requireNodeRef(refInput) {
|
|
|
189823
189946
|
}
|
|
189824
189947
|
function reuseExisting(fileKey2, nodeId, opts, version2, deps, description, entity) {
|
|
189825
189948
|
const existing = findAllByFigmaNode(deps.projectDir, fileKey2, nodeId).find(
|
|
189826
|
-
(r) => r.provenance.format === opts.format && (r.provenance.scale ?? 1) === (opts.scale ?? 1) && r.provenance.version === version2 && existsSync133(
|
|
189949
|
+
(r) => r.provenance.format === opts.format && (r.provenance.scale ?? 1) === (opts.scale ?? 1) && r.provenance.version === version2 && existsSync133(join159(deps.projectDir, r.path))
|
|
189827
189950
|
);
|
|
189828
189951
|
if (!existing) return null;
|
|
189829
189952
|
let record2 = existing;
|
|
@@ -189846,7 +189969,7 @@ async function freezeAndRecord(fileKey2, nodeId, url, ext, opts, version2, deps,
|
|
|
189846
189969
|
bytes = new TextEncoder().encode(sanitizeSvg(new TextDecoder().decode(bytes)));
|
|
189847
189970
|
}
|
|
189848
189971
|
const id = nextId(deps.projectDir, "image");
|
|
189849
|
-
const destAbs =
|
|
189972
|
+
const destAbs = join159(typeDirPath(deps.projectDir, "image"), `${id}.${ext}`);
|
|
189850
189973
|
freezeBytes(bytes, destAbs);
|
|
189851
189974
|
const record2 = {
|
|
189852
189975
|
id,
|
|
@@ -190016,11 +190139,11 @@ __export(tokens_exports, {
|
|
|
190016
190139
|
runTokensImport: () => runTokensImport
|
|
190017
190140
|
});
|
|
190018
190141
|
import { writeFileSync as writeFileSync58 } from "fs";
|
|
190019
|
-
import { join as
|
|
190142
|
+
import { join as join160 } from "path";
|
|
190020
190143
|
async function runTokensImport(refInput, deps) {
|
|
190021
190144
|
const { fileKey: fileKey2 } = parseFigmaRef(refInput);
|
|
190022
190145
|
const { version: version2 } = await deps.client.fileVersion(fileKey2);
|
|
190023
|
-
const sidecarPath =
|
|
190146
|
+
const sidecarPath = join160(deps.projectDir, "figma-tokens.json");
|
|
190024
190147
|
let vars = null;
|
|
190025
190148
|
try {
|
|
190026
190149
|
vars = await deps.client.variables(fileKey2);
|
|
@@ -190095,7 +190218,7 @@ __export(component_exports, {
|
|
|
190095
190218
|
runComponentImport: () => runComponentImport
|
|
190096
190219
|
});
|
|
190097
190220
|
import { existsSync as existsSync134, mkdirSync as mkdirSync74, writeFileSync as writeFileSync59 } from "fs";
|
|
190098
|
-
import { join as
|
|
190221
|
+
import { join as join161, relative as relative37 } from "path";
|
|
190099
190222
|
function escapeAttr2(value) {
|
|
190100
190223
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
190101
190224
|
}
|
|
@@ -190106,7 +190229,7 @@ async function runComponentImport(refInput, deps) {
|
|
|
190106
190229
|
const bindings = resolveBindings(tree, readBindings(deps.projectDir));
|
|
190107
190230
|
const mapped = nodeToHtml(tree, bindings, { rootName: deps.name });
|
|
190108
190231
|
const name = slugify(deps.name ?? tree.name);
|
|
190109
|
-
const componentDir =
|
|
190232
|
+
const componentDir = join161(deps.projectDir, "compositions", "components", name);
|
|
190110
190233
|
if (existsSync134(componentDir))
|
|
190111
190234
|
console.warn(
|
|
190112
190235
|
`component dir compositions/components/${name} already exists \u2014 overwriting (rename the figma frame for a separate import)`
|
|
@@ -190118,7 +190241,7 @@ async function runComponentImport(refInput, deps) {
|
|
|
190118
190241
|
componentDir,
|
|
190119
190242
|
deps
|
|
190120
190243
|
);
|
|
190121
|
-
const htmlFile =
|
|
190244
|
+
const htmlFile = join161(componentDir, `${name}.html`);
|
|
190122
190245
|
writeFileSync59(htmlFile, html + "\n");
|
|
190123
190246
|
const registryItem = {
|
|
190124
190247
|
name,
|
|
@@ -190140,7 +190263,7 @@ async function runComponentImport(refInput, deps) {
|
|
|
190140
190263
|
]
|
|
190141
190264
|
};
|
|
190142
190265
|
writeFileSync59(
|
|
190143
|
-
|
|
190266
|
+
join161(componentDir, "registry-item.json"),
|
|
190144
190267
|
JSON.stringify(registryItem, null, 2) + "\n"
|
|
190145
190268
|
);
|
|
190146
190269
|
return {
|
|
@@ -190165,7 +190288,7 @@ async function rasterizeFallback(mapped, fileKey2, componentDir, deps) {
|
|
|
190165
190288
|
continue;
|
|
190166
190289
|
}
|
|
190167
190290
|
frozenAssets.push(asset.record.path);
|
|
190168
|
-
const srcRel = relative37(componentDir,
|
|
190291
|
+
const srcRel = relative37(componentDir, join161(deps.projectDir, asset.record.path)).replaceAll(
|
|
190169
190292
|
"\\",
|
|
190170
190293
|
"/"
|
|
190171
190294
|
);
|
|
@@ -190314,7 +190437,7 @@ __export(autoUpdate_exports, {
|
|
|
190314
190437
|
import { spawn as spawn19 } from "child_process";
|
|
190315
190438
|
import { appendFileSync as appendFileSync4, mkdirSync as mkdirSync75, openSync as openSync15 } from "fs";
|
|
190316
190439
|
import { homedir as homedir25 } from "os";
|
|
190317
|
-
import { join as
|
|
190440
|
+
import { join as join162 } from "path";
|
|
190318
190441
|
import { compareVersions as compareVersions3 } from "compare-versions";
|
|
190319
190442
|
function isAutoInstallDisabled() {
|
|
190320
190443
|
if (isDevMode()) return true;
|
|
@@ -190337,7 +190460,7 @@ function log(line3) {
|
|
|
190337
190460
|
}
|
|
190338
190461
|
function launchDetachedInstall(invocation, displayCommand, version2) {
|
|
190339
190462
|
mkdirSync75(CONFIG_DIR3, { recursive: true, mode: 448 });
|
|
190340
|
-
const configFile =
|
|
190463
|
+
const configFile = join162(CONFIG_DIR3, "config.json");
|
|
190341
190464
|
const nodeScript = `
|
|
190342
190465
|
const { execFile } = require("node:child_process");
|
|
190343
190466
|
const { readFileSync, renameSync, writeFileSync } = require("node:fs");
|
|
@@ -190458,8 +190581,8 @@ var init_autoUpdate = __esm({
|
|
|
190458
190581
|
init_config();
|
|
190459
190582
|
init_env();
|
|
190460
190583
|
init_installerDetection();
|
|
190461
|
-
CONFIG_DIR3 =
|
|
190462
|
-
LOG_FILE =
|
|
190584
|
+
CONFIG_DIR3 = join162(homedir25(), ".hyperframes");
|
|
190585
|
+
LOG_FILE = join162(CONFIG_DIR3, "auto-update.log");
|
|
190463
190586
|
PENDING_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
190464
190587
|
}
|
|
190465
190588
|
});
|
|
@@ -190655,7 +190778,7 @@ var init_help = __esm({
|
|
|
190655
190778
|
init_version();
|
|
190656
190779
|
init_dist();
|
|
190657
190780
|
init_runId();
|
|
190658
|
-
import { dirname as
|
|
190781
|
+
import { dirname as dirname70, join as join163, resolve as resolve83 } from "path";
|
|
190659
190782
|
import { fileURLToPath as fileURLToPath18 } from "url";
|
|
190660
190783
|
import { existsSync as existsSync135 } from "fs";
|
|
190661
190784
|
|
|
@@ -190774,8 +190897,8 @@ for (const stream of [process.stdout, process.stderr]) {
|
|
|
190774
190897
|
});
|
|
190775
190898
|
}
|
|
190776
190899
|
(() => {
|
|
190777
|
-
const here =
|
|
190778
|
-
const shader =
|
|
190900
|
+
const here = dirname70(fileURLToPath18(import.meta.url));
|
|
190901
|
+
const shader = join163(here, "shaderTransitionWorker.js");
|
|
190779
190902
|
if (!process.env.HF_SHADER_WORKER_ENTRY && existsSync135(shader)) {
|
|
190780
190903
|
process.env.HF_SHADER_WORKER_ENTRY = shader;
|
|
190781
190904
|
}
|
|
@@ -190816,7 +190939,7 @@ try {
|
|
|
190816
190939
|
var isHelp = process.argv.includes("--help") || process.argv.includes("-h");
|
|
190817
190940
|
async function assertStudioWorkspaceBuilt() {
|
|
190818
190941
|
if (!isDevMode()) return;
|
|
190819
|
-
const repoRoot2 = resolve83(
|
|
190942
|
+
const repoRoot2 = resolve83(dirname70(fileURLToPath18(import.meta.url)), "..", "..", "..");
|
|
190820
190943
|
const { checkStudioWorkspaceBuild: checkStudioWorkspaceBuild2, formatWorkspaceBuildProblems: formatWorkspaceBuildProblems2 } = await Promise.resolve().then(() => (init_workspaceBuildCheck(), workspaceBuildCheck_exports));
|
|
190821
190944
|
const problems = checkStudioWorkspaceBuild2(repoRoot2);
|
|
190822
190945
|
if (problems.length === 0) return;
|