hyperframes 0.8.15 → 0.8.16
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 +891 -722
- package/dist/fontLocalizeCli.js +409 -270
- package/dist/hyperframe-runtime.js +25 -25
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +25 -25
- package/dist/hyperframes-player.global.js +2 -2
- package/dist/studio/assets/hyperframes-player-iAIHATIw.js +459 -0
- package/dist/studio/assets/{index-CVtYYTnA.js → index-Cf-mbMRL.js} +1 -1
- package/dist/studio/assets/{index-DKoZIpw1.js → index-D8o3ZIo2.js} +163 -163
- package/dist/studio/assets/{index-CtDg2lB7.js → index-YmetcS6L.js} +1 -1
- package/dist/studio/index.d.ts +8 -12
- package/dist/studio/index.html +1 -1
- package/dist/studio/index.js +24 -6
- package/dist/studio/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/studio/assets/hyperframes-player-BlIp1Y-b.js +0 -459
package/dist/fontLocalizeCli.js
CHANGED
|
@@ -17022,7 +17022,7 @@ var require_util = __commonJS({
|
|
|
17022
17022
|
return path;
|
|
17023
17023
|
}
|
|
17024
17024
|
exports.normalize = normalize;
|
|
17025
|
-
function
|
|
17025
|
+
function join56(aRoot, aPath) {
|
|
17026
17026
|
if (aRoot === "") {
|
|
17027
17027
|
aRoot = ".";
|
|
17028
17028
|
}
|
|
@@ -17054,7 +17054,7 @@ var require_util = __commonJS({
|
|
|
17054
17054
|
}
|
|
17055
17055
|
return joined;
|
|
17056
17056
|
}
|
|
17057
|
-
exports.join =
|
|
17057
|
+
exports.join = join56;
|
|
17058
17058
|
exports.isAbsolute = function(aPath) {
|
|
17059
17059
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
17060
17060
|
};
|
|
@@ -17227,7 +17227,7 @@ var require_util = __commonJS({
|
|
|
17227
17227
|
parsed.path = parsed.path.substring(0, index + 1);
|
|
17228
17228
|
}
|
|
17229
17229
|
}
|
|
17230
|
-
sourceURL =
|
|
17230
|
+
sourceURL = join56(urlGenerate(parsed), sourceURL);
|
|
17231
17231
|
}
|
|
17232
17232
|
return normalize(sourceURL);
|
|
17233
17233
|
}
|
|
@@ -50798,7 +50798,7 @@ function compileTag(tag, isVideo, generateId) {
|
|
|
50798
50798
|
result = injectAttr(result, "data-hf-auto-start", "");
|
|
50799
50799
|
startStr = "0";
|
|
50800
50800
|
}
|
|
50801
|
-
const start =
|
|
50801
|
+
const start = parseNumeric(startStr);
|
|
50802
50802
|
const attrReader = { getAttribute: (name) => getAttr(result, name) };
|
|
50803
50803
|
const mediaStart = readMediaStart(attrReader);
|
|
50804
50804
|
const playbackRate = readElementPlaybackRate(attrReader);
|
|
@@ -50806,14 +50806,15 @@ function compileTag(tag, isVideo, generateId) {
|
|
|
50806
50806
|
const durationStr = getAttr(result, "data-duration");
|
|
50807
50807
|
const duration = parseStrictFiniteTimingNumber(durationStr);
|
|
50808
50808
|
if (duration != null) {
|
|
50809
|
-
|
|
50810
|
-
|
|
50809
|
+
if (start != null) {
|
|
50810
|
+
result = injectAttr(result, "data-end", String(start + duration));
|
|
50811
|
+
}
|
|
50811
50812
|
} else if (id) {
|
|
50812
50813
|
unresolved = {
|
|
50813
50814
|
id,
|
|
50814
50815
|
tagName: isVideo ? "video" : "audio",
|
|
50815
50816
|
src: getAttr(result, "src") ?? void 0,
|
|
50816
|
-
start,
|
|
50817
|
+
start: start ?? 0,
|
|
50817
50818
|
mediaStart,
|
|
50818
50819
|
playbackRate
|
|
50819
50820
|
};
|
|
@@ -50854,7 +50855,7 @@ function compileTimingAttrs(html) {
|
|
|
50854
50855
|
unresolved.push({
|
|
50855
50856
|
id,
|
|
50856
50857
|
tagName: "div",
|
|
50857
|
-
start:
|
|
50858
|
+
start: parseNumeric(startStr) ?? 0,
|
|
50858
50859
|
mediaStart: 0,
|
|
50859
50860
|
playbackRate: 1,
|
|
50860
50861
|
compositionSrc: compositionSrc ?? void 0
|
|
@@ -50873,9 +50874,10 @@ function injectDurations(html, resolutions) {
|
|
|
50873
50874
|
result = setAttr(result, "data-duration", String(duration));
|
|
50874
50875
|
}
|
|
50875
50876
|
if (!hasAttr(result, "data-end")) {
|
|
50876
|
-
const
|
|
50877
|
-
|
|
50878
|
-
|
|
50877
|
+
const start = parseNumeric(getAttr(result, "data-start"));
|
|
50878
|
+
if (start != null) {
|
|
50879
|
+
result = injectAttr(result, "data-end", String(start + duration));
|
|
50880
|
+
}
|
|
50879
50881
|
}
|
|
50880
50882
|
return result;
|
|
50881
50883
|
});
|
|
@@ -50906,7 +50908,7 @@ function extractResolvedMedia(html) {
|
|
|
50906
50908
|
id,
|
|
50907
50909
|
tagName: isVideo ? "video" : "audio",
|
|
50908
50910
|
src: getAttr(tag, "src") ?? void 0,
|
|
50909
|
-
start:
|
|
50911
|
+
start: parseNumeric(startStr) ?? 0,
|
|
50910
50912
|
duration,
|
|
50911
50913
|
mediaStart: readMediaStart(attrReader),
|
|
50912
50914
|
playbackRate: readElementPlaybackRate(attrReader),
|
|
@@ -50920,9 +50922,10 @@ function clampDurations(html, clamps) {
|
|
|
50920
50922
|
const idPattern = new RegExp(`(<[^>]*id=["']${escapeRegex2(id)}["'][^>]*>)`, "gi");
|
|
50921
50923
|
html = html.replace(idPattern, (tag) => {
|
|
50922
50924
|
tag = tag.replace(/data-duration=["'][^"']*["']/, `data-duration="${duration}"`);
|
|
50923
|
-
const
|
|
50924
|
-
|
|
50925
|
-
|
|
50925
|
+
const start = parseNumeric(getAttr(tag, "data-start"));
|
|
50926
|
+
if (start != null) {
|
|
50927
|
+
tag = tag.replace(/data-end=["'][^"']*["']/, `data-end="${start + duration}"`);
|
|
50928
|
+
}
|
|
50926
50929
|
return tag;
|
|
50927
50930
|
});
|
|
50928
50931
|
}
|
|
@@ -50932,6 +50935,7 @@ var MEDIA_DURATION_CLAMP_EPSILON_SECONDS, INERT_REGION_RE;
|
|
|
50932
50935
|
var init_timingCompiler = __esm({
|
|
50933
50936
|
"../core/dist/compiler/timingCompiler.js"() {
|
|
50934
50937
|
"use strict";
|
|
50938
|
+
init_compositionContract();
|
|
50935
50939
|
init_playbackRate();
|
|
50936
50940
|
MEDIA_DURATION_CLAMP_EPSILON_SECONDS = 0.05;
|
|
50937
50941
|
INERT_REGION_RE = /<!--[\s\S]*?-->|<script\b[\s\S]*?<\/script\s*>|<style\b[\s\S]*?<\/style\s*>/gi;
|
|
@@ -56094,7 +56098,12 @@ async function captureDrawElementFrame(page, width, height, format = "jpeg", qua
|
|
|
56094
56098
|
}) => {
|
|
56095
56099
|
const canvas = document.getElementById("__hf_de_canvas");
|
|
56096
56100
|
const root = document.querySelector("[data-composition-id]");
|
|
56097
|
-
if (!
|
|
56101
|
+
if (!root) {
|
|
56102
|
+
throw new Error("HF_DE_COMPOSITION_ROOT_MISSING: drawElement composition root not found");
|
|
56103
|
+
}
|
|
56104
|
+
if (!canvas) {
|
|
56105
|
+
throw new Error("HF_DE_CANVAS_NOT_INITIALIZED: drawElement canvas not initialized");
|
|
56106
|
+
}
|
|
56098
56107
|
const ctx = canvas.getContext("2d");
|
|
56099
56108
|
if (!ctx) throw new Error("drawElement: 2d context unavailable");
|
|
56100
56109
|
const aw = window;
|
|
@@ -56341,7 +56350,12 @@ async function produceDrawElementFrame(page, width, height, quality = 80, syncTo
|
|
|
56341
56350
|
({ w, h, q, sync, fid }) => {
|
|
56342
56351
|
const canvas = document.getElementById("__hf_de_canvas");
|
|
56343
56352
|
const root = document.querySelector("[data-composition-id]");
|
|
56344
|
-
if (!
|
|
56353
|
+
if (!root) {
|
|
56354
|
+
throw new Error("HF_DE_COMPOSITION_ROOT_MISSING: drawElement composition root not found");
|
|
56355
|
+
}
|
|
56356
|
+
if (!canvas) {
|
|
56357
|
+
throw new Error("HF_DE_CANVAS_NOT_INITIALIZED: drawElement canvas not initialized");
|
|
56358
|
+
}
|
|
56345
56359
|
const ctx = canvas.getContext("2d");
|
|
56346
56360
|
if (!ctx) throw new Error("drawElement: 2d context unavailable");
|
|
56347
56361
|
const aw = window;
|
|
@@ -56508,7 +56522,18 @@ async function produceDrawElementFrameBatch(page, times, width, height, quality
|
|
|
56508
56522
|
}) => {
|
|
56509
56523
|
const canvas = document.getElementById("__hf_de_canvas");
|
|
56510
56524
|
const root = document.querySelector("[data-composition-id]");
|
|
56511
|
-
if (!
|
|
56525
|
+
if (!root) {
|
|
56526
|
+
return {
|
|
56527
|
+
failedAt: 0,
|
|
56528
|
+
error: "HF_DE_COMPOSITION_ROOT_MISSING: drawElement composition root not found"
|
|
56529
|
+
};
|
|
56530
|
+
}
|
|
56531
|
+
if (!canvas) {
|
|
56532
|
+
return {
|
|
56533
|
+
failedAt: 0,
|
|
56534
|
+
error: "HF_DE_CANVAS_NOT_INITIALIZED: drawElement canvas not initialized"
|
|
56535
|
+
};
|
|
56536
|
+
}
|
|
56512
56537
|
const ctx = canvas.getContext("2d");
|
|
56513
56538
|
if (!ctx) return { failedAt: 0, error: "drawElement: 2d context unavailable" };
|
|
56514
56539
|
const aw = window;
|
|
@@ -56647,10 +56672,11 @@ async function produceDrawElementFrameBatch(page, times, width, height, quality
|
|
|
56647
56672
|
}
|
|
56648
56673
|
return { encodeResults, failedAt: outcome.failedAt, error: outcome.error };
|
|
56649
56674
|
}
|
|
56650
|
-
var workerEncodeStates, workerEncodeBoundPages;
|
|
56675
|
+
var DE_CANVAS_NOT_INITIALIZED_CODE, workerEncodeStates, workerEncodeBoundPages;
|
|
56651
56676
|
var init_drawElementService = __esm({
|
|
56652
56677
|
"../engine/src/services/drawElementService.ts"() {
|
|
56653
56678
|
"use strict";
|
|
56679
|
+
DE_CANVAS_NOT_INITIALIZED_CODE = "HF_DE_CANVAS_NOT_INITIALIZED";
|
|
56654
56680
|
workerEncodeStates = /* @__PURE__ */ new WeakMap();
|
|
56655
56681
|
workerEncodeBoundPages = /* @__PURE__ */ new WeakSet();
|
|
56656
56682
|
}
|
|
@@ -59417,7 +59443,14 @@ async function computeTimelineAtRiskFrames(page, fps) {
|
|
|
59417
59443
|
}
|
|
59418
59444
|
function isNoCachedPaintRecordError(err) {
|
|
59419
59445
|
const msg = err instanceof Error ? err.message : String(err);
|
|
59420
|
-
return msg.includes("No cached paint record");
|
|
59446
|
+
return msg.includes("No cached paint record for element");
|
|
59447
|
+
}
|
|
59448
|
+
function isCanvasNotInitializedError(err) {
|
|
59449
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
59450
|
+
return msg.includes(DE_CANVAS_NOT_INITIALIZED_CODE);
|
|
59451
|
+
}
|
|
59452
|
+
function isRecoverableDrawElementError(err) {
|
|
59453
|
+
return isNoCachedPaintRecordError(err) || isCanvasNotInitializedError(err);
|
|
59421
59454
|
}
|
|
59422
59455
|
async function captureFrameCore(session, frameIndex, time) {
|
|
59423
59456
|
const { page, options } = session;
|
|
@@ -59491,10 +59524,11 @@ async function captureFrameCore(session, frameIndex, time) {
|
|
|
59491
59524
|
}
|
|
59492
59525
|
}
|
|
59493
59526
|
} catch (err) {
|
|
59494
|
-
if (
|
|
59527
|
+
if (isRecoverableDrawElementError(err)) {
|
|
59495
59528
|
session.deNcprFallbacks = (session.deNcprFallbacks ?? 0) + 1;
|
|
59529
|
+
const reason = isCanvasNotInitializedError(err) ? "drawElement canvas not initialized" : "No cached paint record";
|
|
59496
59530
|
console.log(
|
|
59497
|
-
`[engine] fast capture: frame ${frameIndex} \u2014
|
|
59531
|
+
`[engine] fast capture: frame ${frameIndex} \u2014 ${reason}; screenshot fallback for this frame (see fast-capture-limitations.md)`
|
|
59498
59532
|
);
|
|
59499
59533
|
screenshotBuffer = await pageScreenshotCapture(page, options);
|
|
59500
59534
|
} else {
|
|
@@ -59611,10 +59645,11 @@ async function captureFrameToBufferPipelined(session, frameIndex, time) {
|
|
|
59611
59645
|
}
|
|
59612
59646
|
return { encodeResult, captureTimeMs };
|
|
59613
59647
|
} catch (captureError) {
|
|
59614
|
-
if (
|
|
59648
|
+
if (isRecoverableDrawElementError(captureError)) {
|
|
59615
59649
|
session.deNcprFallbacks = (session.deNcprFallbacks ?? 0) + 1;
|
|
59650
|
+
const reason = isCanvasNotInitializedError(captureError) ? "drawElement canvas not initialized" : "No cached paint record";
|
|
59616
59651
|
console.log(
|
|
59617
|
-
`[engine] fast capture: frame ${frameIndex} \u2014
|
|
59652
|
+
`[engine] fast capture: frame ${frameIndex} \u2014 ${reason}; screenshot fallback for this frame (see fast-capture-limitations.md)`
|
|
59618
59653
|
);
|
|
59619
59654
|
const buffer = await pageScreenshotCapture(page, options);
|
|
59620
59655
|
return { encodeResult: Promise.resolve(buffer), captureTimeMs: Date.now() - startTime };
|
|
@@ -59677,15 +59712,36 @@ async function captureFramesBatchPipelined(session, frameIndices, times) {
|
|
|
59677
59712
|
results.push({ frameIndex, encodeResult });
|
|
59678
59713
|
}
|
|
59679
59714
|
if (failedAt !== null) {
|
|
59680
|
-
|
|
59681
|
-
|
|
59682
|
-
|
|
59683
|
-
|
|
59684
|
-
|
|
59685
|
-
|
|
59686
|
-
|
|
59687
|
-
|
|
59688
|
-
|
|
59715
|
+
if (isRecoverableDrawElementError(error)) {
|
|
59716
|
+
const reason = isCanvasNotInitializedError(error) ? "drawElement canvas not initialized" : "No cached paint record";
|
|
59717
|
+
console.log(
|
|
59718
|
+
`[engine] fast capture: batch produce failed at frame ${frameIndices[failedAt] ?? "?"} (${reason}); screenshot fallback for ${frameIndices.length - failedAt} frame(s) (see fast-capture-limitations.md)`
|
|
59719
|
+
);
|
|
59720
|
+
for (let i = failedAt; i < frameIndices.length; i++) {
|
|
59721
|
+
const frameIndex = frameIndices[i];
|
|
59722
|
+
const time = times[i];
|
|
59723
|
+
if (frameIndex === void 0 || time === void 0) break;
|
|
59724
|
+
session.deNcprFallbacks = (session.deNcprFallbacks ?? 0) + 1;
|
|
59725
|
+
await prepareFrameForCapture(session, frameIndex, time);
|
|
59726
|
+
const buffer = await pageScreenshotCapture(page, options);
|
|
59727
|
+
const encodeResult = Promise.resolve(buffer);
|
|
59728
|
+
if (session.staticFrames) {
|
|
59729
|
+
session.lastEncodeResult = encodeResult;
|
|
59730
|
+
session.lastEncodeResultFrame = frameIndex;
|
|
59731
|
+
}
|
|
59732
|
+
results.push({ frameIndex, encodeResult });
|
|
59733
|
+
}
|
|
59734
|
+
} else {
|
|
59735
|
+
console.log(
|
|
59736
|
+
`[engine] fast capture: batch produce failed at frame ${frameIndices[failedAt] ?? "?"} (${error ?? "?"}); re-capturing ${frameIndices.length - failedAt} frame(s) per-frame`
|
|
59737
|
+
);
|
|
59738
|
+
for (let i = failedAt; i < frameIndices.length; i++) {
|
|
59739
|
+
const frameIndex = frameIndices[i];
|
|
59740
|
+
const time = times[i];
|
|
59741
|
+
if (frameIndex === void 0 || time === void 0) break;
|
|
59742
|
+
const { encodeResult } = await captureFrameToBufferPipelined(session, frameIndex, time);
|
|
59743
|
+
results.push({ frameIndex, encodeResult });
|
|
59744
|
+
}
|
|
59689
59745
|
}
|
|
59690
59746
|
}
|
|
59691
59747
|
const last = results[results.length - 1];
|
|
@@ -59843,6 +59899,13 @@ function percentileOf(samples, p) {
|
|
|
59843
59899
|
}
|
|
59844
59900
|
function getCapturePerfSummary(session) {
|
|
59845
59901
|
const frames = Math.max(1, session.capturePerf.frames);
|
|
59902
|
+
const ncprFallbacks = session.deNcprFallbacks ?? 0;
|
|
59903
|
+
if (frames > 0 && ncprFallbacks / frames > DE_FALLBACK_RATIO_WARN_THRESHOLD) {
|
|
59904
|
+
const pct = Math.round(ncprFallbacks / frames * 100);
|
|
59905
|
+
console.warn(
|
|
59906
|
+
`[engine] fast capture: ${ncprFallbacks}/${frames} frame(s) (${pct}%) fell back to screenshot capture (canvas-not-initialized / no-cached-paint-record) \u2014 drawElement likely failed to engage for this render rather than recovering a few edge-case frames; see fast-capture-limitations.md.`
|
|
59907
|
+
);
|
|
59908
|
+
}
|
|
59846
59909
|
return {
|
|
59847
59910
|
frames: session.capturePerf.frames,
|
|
59848
59911
|
avgTotalMs: Math.round(session.capturePerf.totalMs / frames),
|
|
@@ -59881,10 +59944,10 @@ function getCapturePerfSummary(session) {
|
|
|
59881
59944
|
deVerifyArmed: session.deVerifyFrames?.size ?? 0,
|
|
59882
59945
|
deVerifyInitMs: session.deVerifyInitMs ?? 0,
|
|
59883
59946
|
deBoundaryFrames: session.clipBoundaryFrames?.size ?? 0,
|
|
59884
|
-
deNcprFallbacks:
|
|
59947
|
+
deNcprFallbacks: ncprFallbacks
|
|
59885
59948
|
};
|
|
59886
59949
|
}
|
|
59887
|
-
var DrawElementVerificationError, BROWSER_CONSOLE_BUFFER_SIZE, CAPTURE_SESSION_CLOSE_TIMEOUT_MS, LOCKED_WARMUP_TICKS, realSleep, BEGIN_FRAME_CAPTURE_HEADROOM_INTERVALS, BEGIN_FRAME_COMMIT_LEAD_INTERVALS, BEGIN_FRAME_PROBE_LEAD_INTERVALS, HF_READY_DIAGNOSTIC_EXPR, LIVE_MAP_MARKERS, MAX_STATIC_DEDUP_ANALYSIS_FRAMES, STATIC_VERIFY_REFERENCE_STRIDE, STATIC_VERIFY_MAX_MS, STATIC_VERIFY_MIN_SCREENSHOT_CAP, STATIC_VERIFY_SAMPLE_CAP_MULTIPLIER, STATIC_VERIFY_MAX_GLOBAL_SAMPLE_FLOOR;
|
|
59950
|
+
var DrawElementVerificationError, BROWSER_CONSOLE_BUFFER_SIZE, CAPTURE_SESSION_CLOSE_TIMEOUT_MS, LOCKED_WARMUP_TICKS, realSleep, BEGIN_FRAME_CAPTURE_HEADROOM_INTERVALS, BEGIN_FRAME_COMMIT_LEAD_INTERVALS, BEGIN_FRAME_PROBE_LEAD_INTERVALS, HF_READY_DIAGNOSTIC_EXPR, LIVE_MAP_MARKERS, MAX_STATIC_DEDUP_ANALYSIS_FRAMES, STATIC_VERIFY_REFERENCE_STRIDE, STATIC_VERIFY_MAX_MS, STATIC_VERIFY_MIN_SCREENSHOT_CAP, STATIC_VERIFY_SAMPLE_CAP_MULTIPLIER, STATIC_VERIFY_MAX_GLOBAL_SAMPLE_FLOOR, DE_FALLBACK_RATIO_WARN_THRESHOLD;
|
|
59888
59951
|
var init_frameCapture = __esm({
|
|
59889
59952
|
"../engine/src/services/frameCapture.ts"() {
|
|
59890
59953
|
"use strict";
|
|
@@ -59952,6 +60015,7 @@ var init_frameCapture = __esm({
|
|
|
59952
60015
|
STATIC_VERIFY_MIN_SCREENSHOT_CAP = 400;
|
|
59953
60016
|
STATIC_VERIFY_SAMPLE_CAP_MULTIPLIER = 8;
|
|
59954
60017
|
STATIC_VERIFY_MAX_GLOBAL_SAMPLE_FLOOR = STATIC_VERIFY_MIN_SCREENSHOT_CAP / STATIC_VERIFY_SAMPLE_CAP_MULTIPLIER;
|
|
60018
|
+
DE_FALLBACK_RATIO_WARN_THRESHOLD = 0.5;
|
|
59955
60019
|
}
|
|
59956
60020
|
});
|
|
59957
60021
|
|
|
@@ -61517,8 +61581,6 @@ async function muxVideoWithAudio(videoPath, audioPath, outputPath, signal, confi
|
|
|
61517
61581
|
args.push("-c:a", "aac", "-b:a", "192k", "-movflags", "+faststart");
|
|
61518
61582
|
}
|
|
61519
61583
|
}
|
|
61520
|
-
const copiesContainerizedAac = !isWebm && shouldCopyAudio && config?.preserveAudioPrimingEditList === true;
|
|
61521
|
-
if (!copiesContainerizedAac) args.push("-avoid_negative_ts", "make_zero");
|
|
61522
61584
|
appendRenderProvenanceArgs(args, outputPath);
|
|
61523
61585
|
if (fps !== void 0) {
|
|
61524
61586
|
args.push("-r", fpsToFfmpegArg(fps));
|
|
@@ -69775,6 +69837,14 @@ function hasAttrName(tagSource, attr) {
|
|
|
69775
69837
|
const attrs = tagSource.replace(/^<\s*[a-z][\w:-]*/i, "");
|
|
69776
69838
|
return new RegExp(`(?:^|\\s)${escaped}(?:\\s*=|\\s|/?>)`, "i").test(attrs);
|
|
69777
69839
|
}
|
|
69840
|
+
function mediaHasResolvableSrc(tag, tags) {
|
|
69841
|
+
if (readAttr(tag.raw, "src")) return true;
|
|
69842
|
+
const end = tag.closeIndex ?? tag.endIndex;
|
|
69843
|
+
if (end == null) return false;
|
|
69844
|
+
return tags.some(
|
|
69845
|
+
(child) => child.name === "source" && child.index > tag.index && child.index < end && Boolean(readAttr(child.raw, "src"))
|
|
69846
|
+
);
|
|
69847
|
+
}
|
|
69778
69848
|
function classNamesFromAttr(classAttr) {
|
|
69779
69849
|
if (!classAttr) return [];
|
|
69780
69850
|
return classAttr.split(/\s+/).filter(Boolean);
|
|
@@ -71707,7 +71777,7 @@ var init_dist3 = __esm({
|
|
|
71707
71777
|
if (tag.name !== "video" && tag.name !== "audio") continue;
|
|
71708
71778
|
const hasDataStart = readAttr(tag.raw, "data-start");
|
|
71709
71779
|
const hasId = readAttr(tag.raw, "id");
|
|
71710
|
-
const hasSrc =
|
|
71780
|
+
const hasSrc = mediaHasResolvableSrc(tag, tags);
|
|
71711
71781
|
if (hasSrc && !hasDataStart) {
|
|
71712
71782
|
findings.push({
|
|
71713
71783
|
code: "media_missing_data_start",
|
|
@@ -71742,9 +71812,9 @@ var init_dist3 = __esm({
|
|
|
71742
71812
|
findings.push({
|
|
71743
71813
|
code: "media_missing_src",
|
|
71744
71814
|
severity: "error",
|
|
71745
|
-
message: `<${tag.name} id="${hasId}"> has data-start but no src
|
|
71815
|
+
message: `<${tag.name} id="${hasId}"> has data-start but no src (on the element or a <source> child). The renderer cannot load this media.`,
|
|
71746
71816
|
elementId: hasId,
|
|
71747
|
-
fixHint: `Add
|
|
71817
|
+
fixHint: `Add src on the <${tag.name}> element, or a <source src="..."> child.`,
|
|
71748
71818
|
snippet: truncateSnippet(tag.raw)
|
|
71749
71819
|
});
|
|
71750
71820
|
}
|
|
@@ -74507,20 +74577,73 @@ var init_htmlTemplate = __esm({
|
|
|
74507
74577
|
}
|
|
74508
74578
|
});
|
|
74509
74579
|
|
|
74580
|
+
// ../engine/src/services/extractedFrameIndex.ts
|
|
74581
|
+
import { readdirSync as readdirSync4 } from "fs";
|
|
74582
|
+
import { join as join9 } from "path";
|
|
74583
|
+
function extractedFrameIndex(file, format) {
|
|
74584
|
+
const match = new RegExp(`^${FRAME_FILENAME_PREFIX}(\\d+)\\.${format}$`).exec(file);
|
|
74585
|
+
if (!match) {
|
|
74586
|
+
throw new ExtractedFrameSequenceError(`Invalid extracted frame filename: ${file}`);
|
|
74587
|
+
}
|
|
74588
|
+
const ordinal = Number.parseInt(match[1], 10);
|
|
74589
|
+
if (!Number.isSafeInteger(ordinal) || ordinal < 1) {
|
|
74590
|
+
throw new ExtractedFrameSequenceError(`Invalid extracted frame ordinal: ${file}`);
|
|
74591
|
+
}
|
|
74592
|
+
return ordinal - 1;
|
|
74593
|
+
}
|
|
74594
|
+
function framePathsFromDirectory(outputDir, format) {
|
|
74595
|
+
const suffix = `.${format}`;
|
|
74596
|
+
const indexed = /* @__PURE__ */ new Map();
|
|
74597
|
+
for (const file of readdirSync4(outputDir)) {
|
|
74598
|
+
if (!file.startsWith(FRAME_FILENAME_PREFIX) || !file.endsWith(suffix)) continue;
|
|
74599
|
+
const index = extractedFrameIndex(file, format);
|
|
74600
|
+
if (indexed.has(index)) {
|
|
74601
|
+
throw new ExtractedFrameSequenceError(
|
|
74602
|
+
`Duplicate extracted frame index ${index}: ${indexed.get(index)} and ${file}`
|
|
74603
|
+
);
|
|
74604
|
+
}
|
|
74605
|
+
indexed.set(index, join9(outputDir, file));
|
|
74606
|
+
}
|
|
74607
|
+
const ordered = /* @__PURE__ */ new Map();
|
|
74608
|
+
for (let index = 0; index < indexed.size; index += 1) {
|
|
74609
|
+
const path = indexed.get(index);
|
|
74610
|
+
if (!path) {
|
|
74611
|
+
throw new ExtractedFrameSequenceError(
|
|
74612
|
+
`Missing extracted frame index ${index} in ${outputDir}`
|
|
74613
|
+
);
|
|
74614
|
+
}
|
|
74615
|
+
ordered.set(index, path);
|
|
74616
|
+
}
|
|
74617
|
+
return ordered;
|
|
74618
|
+
}
|
|
74619
|
+
var FRAME_FILENAME_PREFIX, ExtractedFrameSequenceError;
|
|
74620
|
+
var init_extractedFrameIndex = __esm({
|
|
74621
|
+
"../engine/src/services/extractedFrameIndex.ts"() {
|
|
74622
|
+
"use strict";
|
|
74623
|
+
FRAME_FILENAME_PREFIX = "frame_";
|
|
74624
|
+
ExtractedFrameSequenceError = class extends Error {
|
|
74625
|
+
constructor(message) {
|
|
74626
|
+
super(message);
|
|
74627
|
+
this.name = "ExtractedFrameSequenceError";
|
|
74628
|
+
}
|
|
74629
|
+
};
|
|
74630
|
+
}
|
|
74631
|
+
});
|
|
74632
|
+
|
|
74510
74633
|
// ../engine/src/services/extractionCache.ts
|
|
74511
74634
|
import { createHash as createHash2, randomUUID as randomUUID2 } from "crypto";
|
|
74512
74635
|
import {
|
|
74513
74636
|
existsSync as existsSync9,
|
|
74514
74637
|
lstatSync as lstatSync2,
|
|
74515
74638
|
mkdirSync as mkdirSync5,
|
|
74516
|
-
readdirSync as
|
|
74639
|
+
readdirSync as readdirSync5,
|
|
74517
74640
|
renameSync,
|
|
74518
74641
|
rmSync as rmSync2,
|
|
74519
74642
|
statSync as statSync5,
|
|
74520
74643
|
utimesSync,
|
|
74521
74644
|
writeFileSync as writeFileSync3
|
|
74522
74645
|
} from "fs";
|
|
74523
|
-
import { join as
|
|
74646
|
+
import { join as join10 } from "path";
|
|
74524
74647
|
function readKeyStat(videoPath) {
|
|
74525
74648
|
try {
|
|
74526
74649
|
const stat = statSync5(videoPath);
|
|
@@ -74549,10 +74672,17 @@ function computeCacheKey(input) {
|
|
|
74549
74672
|
function cacheEntryDirName(keyHash) {
|
|
74550
74673
|
return SCHEMA_PREFIX + keyHash.slice(0, KEY_HEX_CHARS);
|
|
74551
74674
|
}
|
|
74675
|
+
function hasFrameFiles(dir) {
|
|
74676
|
+
try {
|
|
74677
|
+
return readdirSync5(dir).some((file) => file.startsWith(FRAME_FILENAME_PREFIX));
|
|
74678
|
+
} catch {
|
|
74679
|
+
return false;
|
|
74680
|
+
}
|
|
74681
|
+
}
|
|
74552
74682
|
function lookupCacheEntry(rootDir, input) {
|
|
74553
74683
|
const keyHash = computeCacheKey(input);
|
|
74554
|
-
const dir =
|
|
74555
|
-
const complete = existsSync9(
|
|
74684
|
+
const dir = join10(rootDir, cacheEntryDirName(keyHash));
|
|
74685
|
+
const complete = existsSync9(join10(dir, COMPLETE_SENTINEL)) && hasFrameFiles(dir);
|
|
74556
74686
|
return { entry: { dir, keyHash }, hit: complete };
|
|
74557
74687
|
}
|
|
74558
74688
|
function partialCacheEntryDir(entry) {
|
|
@@ -74563,13 +74693,13 @@ function isTargetExistsRenameError(err) {
|
|
|
74563
74693
|
return code === "EEXIST" || code === "ENOTEMPTY" || code === "EPERM";
|
|
74564
74694
|
}
|
|
74565
74695
|
function adoptPublishedWinner(entry, partialDir) {
|
|
74566
|
-
if (!existsSync9(
|
|
74696
|
+
if (!existsSync9(join10(entry.dir, COMPLETE_SENTINEL))) return null;
|
|
74567
74697
|
removeDir(partialDir);
|
|
74568
74698
|
return { dir: entry.dir, published: true };
|
|
74569
74699
|
}
|
|
74570
74700
|
function publishCacheEntry(entry, partialDir) {
|
|
74571
74701
|
try {
|
|
74572
|
-
writeFileSync3(
|
|
74702
|
+
writeFileSync3(join10(partialDir, COMPLETE_SENTINEL), "", "utf-8");
|
|
74573
74703
|
} catch {
|
|
74574
74704
|
return { dir: partialDir, published: false };
|
|
74575
74705
|
}
|
|
@@ -74596,7 +74726,7 @@ function publishCacheEntry(entry, partialDir) {
|
|
|
74596
74726
|
function touchCacheEntry(entry) {
|
|
74597
74727
|
try {
|
|
74598
74728
|
const now = /* @__PURE__ */ new Date();
|
|
74599
|
-
utimesSync(
|
|
74729
|
+
utimesSync(join10(entry.dir, COMPLETE_SENTINEL), now, now);
|
|
74600
74730
|
} catch {
|
|
74601
74731
|
}
|
|
74602
74732
|
}
|
|
@@ -74616,12 +74746,12 @@ function directorySizeBytes(path) {
|
|
|
74616
74746
|
let total = 0;
|
|
74617
74747
|
let children;
|
|
74618
74748
|
try {
|
|
74619
|
-
children =
|
|
74749
|
+
children = readdirSync5(path);
|
|
74620
74750
|
} catch {
|
|
74621
74751
|
return 0;
|
|
74622
74752
|
}
|
|
74623
74753
|
for (const child of children) {
|
|
74624
|
-
const childPath =
|
|
74754
|
+
const childPath = join10(path, child);
|
|
74625
74755
|
try {
|
|
74626
74756
|
const stat = lstatSync2(childPath);
|
|
74627
74757
|
if (stat.isDirectory()) {
|
|
@@ -74650,7 +74780,7 @@ function collectGcEntry(dir, name, now, minAgeMs, stats) {
|
|
|
74650
74780
|
}
|
|
74651
74781
|
let lastUseMs = dirStat.mtimeMs;
|
|
74652
74782
|
try {
|
|
74653
|
-
lastUseMs = statSync5(
|
|
74783
|
+
lastUseMs = statSync5(join10(dir, COMPLETE_SENTINEL)).mtimeMs;
|
|
74654
74784
|
} catch {
|
|
74655
74785
|
}
|
|
74656
74786
|
return { dir, size: directorySizeBytes(dir), lastUseMs, ageMs: now - lastUseMs };
|
|
@@ -74660,7 +74790,7 @@ function collectGcEntry(dir, name, now, minAgeMs, stats) {
|
|
|
74660
74790
|
}
|
|
74661
74791
|
function gcSweepDue(rootDir, maxAgeMs) {
|
|
74662
74792
|
try {
|
|
74663
|
-
return Date.now() - statSync5(
|
|
74793
|
+
return Date.now() - statSync5(join10(rootDir, GC_MARKER)).mtimeMs > maxAgeMs;
|
|
74664
74794
|
} catch {
|
|
74665
74795
|
return true;
|
|
74666
74796
|
}
|
|
@@ -74668,16 +74798,16 @@ function gcSweepDue(rootDir, maxAgeMs) {
|
|
|
74668
74798
|
function gcExtractionCache(rootDir, opts) {
|
|
74669
74799
|
const stats = { evictedEntries: 0, evictedBytes: 0, agedPartialsRemoved: 0 };
|
|
74670
74800
|
try {
|
|
74671
|
-
writeFileSync3(
|
|
74801
|
+
writeFileSync3(join10(rootDir, GC_MARKER), "", "utf-8");
|
|
74672
74802
|
} catch {
|
|
74673
74803
|
}
|
|
74674
74804
|
try {
|
|
74675
74805
|
const now = Date.now();
|
|
74676
74806
|
const entries2 = [];
|
|
74677
|
-
for (const child of
|
|
74807
|
+
for (const child of readdirSync5(rootDir, { withFileTypes: true })) {
|
|
74678
74808
|
if (!child.isDirectory() || !isCacheLikeChild(child.name)) continue;
|
|
74679
74809
|
const entry = collectGcEntry(
|
|
74680
|
-
|
|
74810
|
+
join10(rootDir, child.name),
|
|
74681
74811
|
child.name,
|
|
74682
74812
|
now,
|
|
74683
74813
|
opts.minAgeMs,
|
|
@@ -74702,12 +74832,7 @@ function gcExtractionCache(rootDir, opts) {
|
|
|
74702
74832
|
}
|
|
74703
74833
|
function rehydrateCacheEntry(entry, options) {
|
|
74704
74834
|
const framePattern = `${FRAME_FILENAME_PREFIX}%05d.${options.format}`;
|
|
74705
|
-
const framePaths =
|
|
74706
|
-
const suffix = `.${options.format}`;
|
|
74707
|
-
const files = readdirSync4(entry.dir).filter((f) => f.startsWith(FRAME_FILENAME_PREFIX) && f.endsWith(suffix)).sort();
|
|
74708
|
-
files.forEach((file, idx) => {
|
|
74709
|
-
framePaths.set(idx, join9(entry.dir, file));
|
|
74710
|
-
});
|
|
74835
|
+
const framePaths = framePathsFromDirectory(entry.dir, options.format);
|
|
74711
74836
|
return {
|
|
74712
74837
|
videoId: options.videoId,
|
|
74713
74838
|
srcPath: options.srcPath,
|
|
@@ -74719,11 +74844,12 @@ function rehydrateCacheEntry(entry, options) {
|
|
|
74719
74844
|
framePaths
|
|
74720
74845
|
};
|
|
74721
74846
|
}
|
|
74722
|
-
var
|
|
74847
|
+
var COMPLETE_SENTINEL, GC_MARKER, SCHEMA_PREFIX, KEY_HEX_CHARS, CACHE_GENERATION_PREFIX;
|
|
74723
74848
|
var init_extractionCache = __esm({
|
|
74724
74849
|
"../engine/src/services/extractionCache.ts"() {
|
|
74725
74850
|
"use strict";
|
|
74726
|
-
|
|
74851
|
+
init_extractedFrameIndex();
|
|
74852
|
+
init_extractedFrameIndex();
|
|
74727
74853
|
COMPLETE_SENTINEL = ".hf-complete";
|
|
74728
74854
|
GC_MARKER = ".hf-last-gc";
|
|
74729
74855
|
SCHEMA_PREFIX = "hfcache-v4-";
|
|
@@ -74733,8 +74859,8 @@ var init_extractionCache = __esm({
|
|
|
74733
74859
|
});
|
|
74734
74860
|
|
|
74735
74861
|
// ../engine/src/services/videoFrameExtractor.ts
|
|
74736
|
-
import { copyFileSync as copyFileSync2, existsSync as existsSync10, linkSync as linkSync2, mkdirSync as mkdirSync6,
|
|
74737
|
-
import { isAbsolute, join as
|
|
74862
|
+
import { copyFileSync as copyFileSync2, existsSync as existsSync10, linkSync as linkSync2, mkdirSync as mkdirSync6, rmSync as rmSync3 } from "fs";
|
|
74863
|
+
import { isAbsolute, join as join11, posix as posix2, resolve as resolve5, sep as sep2 } from "path";
|
|
74738
74864
|
function isVideoFrameFormat(value) {
|
|
74739
74865
|
return typeof value === "string" && VIDEO_FRAME_FORMATS.includes(value);
|
|
74740
74866
|
}
|
|
@@ -74956,15 +75082,27 @@ async function runVideoExtractionWithRetry(operation, options = {}) {
|
|
|
74956
75082
|
}
|
|
74957
75083
|
}
|
|
74958
75084
|
}
|
|
75085
|
+
function resolveMediaElementSrc(el) {
|
|
75086
|
+
const direct = el.getAttribute("src");
|
|
75087
|
+
if (direct) return direct;
|
|
75088
|
+
let remote = null;
|
|
75089
|
+
for (const source of el.querySelectorAll("source")) {
|
|
75090
|
+
const src = source.getAttribute("src");
|
|
75091
|
+
if (!src) continue;
|
|
75092
|
+
if (!/^https?:\/\//i.test(src)) return src;
|
|
75093
|
+
remote ??= src;
|
|
75094
|
+
}
|
|
75095
|
+
return remote;
|
|
75096
|
+
}
|
|
74959
75097
|
function parseVideoElements(html) {
|
|
74960
75098
|
const videos = [];
|
|
74961
75099
|
const { document: document2 } = parseHTML(unwrapTemplate(html));
|
|
74962
75100
|
const startCache = /* @__PURE__ */ new Map();
|
|
74963
75101
|
const visiting = /* @__PURE__ */ new Set();
|
|
74964
|
-
const videoEls = document2.querySelectorAll("video
|
|
75102
|
+
const videoEls = document2.querySelectorAll("video");
|
|
74965
75103
|
let autoIdCounter = 0;
|
|
74966
75104
|
for (const el of videoEls) {
|
|
74967
|
-
const src = el
|
|
75105
|
+
const src = resolveMediaElementSrc(el);
|
|
74968
75106
|
if (!src) continue;
|
|
74969
75107
|
const id = el.getAttribute(MEDIA_RENDER_ID_ATTR) || el.getAttribute("id") || `hf-video-${autoIdCounter++}`;
|
|
74970
75108
|
if (!el.getAttribute("id")) {
|
|
@@ -75040,7 +75178,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
75040
75178
|
const normalizedFps = toFps(options.fps);
|
|
75041
75179
|
const fps = fpsToNumber(normalizedFps);
|
|
75042
75180
|
const ffmpegFps = fpsToFfmpegArg(normalizedFps);
|
|
75043
|
-
const videoOutputDir = outputDirOverride ??
|
|
75181
|
+
const videoOutputDir = outputDirOverride ?? join11(outputDir, videoId);
|
|
75044
75182
|
if (!existsSync10(videoOutputDir)) mkdirSync6(videoOutputDir, { recursive: true });
|
|
75045
75183
|
let metadata;
|
|
75046
75184
|
try {
|
|
@@ -75067,7 +75205,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
75067
75205
|
}
|
|
75068
75206
|
const format = resolveFrameFormat(metadata, options.format);
|
|
75069
75207
|
const framePattern = `${FRAME_FILENAME_PREFIX}%05d.${format}`;
|
|
75070
|
-
const outputPattern =
|
|
75208
|
+
const outputPattern = join11(videoOutputDir, framePattern);
|
|
75071
75209
|
const isHdr = isHdrColorSpace(metadata.colorSpace);
|
|
75072
75210
|
const isMacOS = process.platform === "darwin";
|
|
75073
75211
|
const args = [];
|
|
@@ -75129,11 +75267,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
75129
75267
|
diagnostic
|
|
75130
75268
|
);
|
|
75131
75269
|
}
|
|
75132
|
-
const framePaths =
|
|
75133
|
-
const files = readdirSync5(videoOutputDir).filter((f) => f.startsWith(FRAME_FILENAME_PREFIX) && f.endsWith(`.${format}`)).sort();
|
|
75134
|
-
files.forEach((file, index) => {
|
|
75135
|
-
framePaths.set(index, join10(videoOutputDir, file));
|
|
75136
|
-
});
|
|
75270
|
+
const framePaths = framePathsFromDirectory(videoOutputDir, format);
|
|
75137
75271
|
if (framePaths.size === 0 && duration > 0) {
|
|
75138
75272
|
throw new VideoSourceExtractionError(
|
|
75139
75273
|
"zero_output",
|
|
@@ -75323,16 +75457,9 @@ function resolveFrameFormat(metadata, requested) {
|
|
|
75323
75457
|
if (requested === "png" || requested === "jpg") return requested;
|
|
75324
75458
|
return "jpg";
|
|
75325
75459
|
}
|
|
75326
|
-
function extractedFrameFileNames(outputDir, format) {
|
|
75327
|
-
const suffix = `.${format}`;
|
|
75328
|
-
return readdirSync5(outputDir).filter((file) => file.startsWith(FRAME_FILENAME_PREFIX) && file.endsWith(suffix)).sort();
|
|
75329
|
-
}
|
|
75330
75460
|
function extractedFramesFromDirectory(work, outputDir, srcPath, fps) {
|
|
75331
75461
|
const framePattern = `${FRAME_FILENAME_PREFIX}%05d.${work.format}`;
|
|
75332
|
-
const framePaths =
|
|
75333
|
-
extractedFrameFileNames(outputDir, work.format).forEach((file, index) => {
|
|
75334
|
-
framePaths.set(index, join10(outputDir, file));
|
|
75335
|
-
});
|
|
75462
|
+
const framePaths = framePathsFromDirectory(outputDir, work.format);
|
|
75336
75463
|
return {
|
|
75337
75464
|
videoId: work.video.id,
|
|
75338
75465
|
srcPath,
|
|
@@ -75452,7 +75579,7 @@ function sliceSupersetMember(member, superset, outputDir, fps, configuredFps) {
|
|
|
75452
75579
|
for (let i = 0; i < frameCount; i += 1) {
|
|
75453
75580
|
const sourceFrame = superset.framePaths.get(member.offsetFrames + i);
|
|
75454
75581
|
if (!sourceFrame) throw new Error(`superset frame ${member.offsetFrames + i} missing`);
|
|
75455
|
-
linkOrCopyFrame(sourceFrame,
|
|
75582
|
+
linkOrCopyFrame(sourceFrame, join11(outputDir, frameFileName(i + 1, work.format)));
|
|
75456
75583
|
}
|
|
75457
75584
|
return extractedFramesFromDirectory(work, outputDir, work.videoPath, fps);
|
|
75458
75585
|
}
|
|
@@ -75465,22 +75592,22 @@ function resolveProjectRelativeSrc(src, baseDir, compiledDir) {
|
|
|
75465
75592
|
if (!candidates.includes(candidate)) candidates.push(candidate);
|
|
75466
75593
|
};
|
|
75467
75594
|
for (const variant of decodeUrlPathVariants(cleanSrc)) {
|
|
75468
|
-
const fromCompiled = compiledDir ?
|
|
75469
|
-
const fromBase =
|
|
75595
|
+
const fromCompiled = compiledDir ? join11(compiledDir, variant) : null;
|
|
75596
|
+
const fromBase = join11(baseDir, variant);
|
|
75470
75597
|
const baseAbs = resolve5(baseDir);
|
|
75471
75598
|
const fromBaseAbs = resolve5(fromBase);
|
|
75472
75599
|
if (!fromBaseAbs.startsWith(baseAbs + sep2) && fromBaseAbs !== baseAbs) {
|
|
75473
75600
|
const normalized = posix2.normalize(variant.replace(/\\/g, "/"));
|
|
75474
75601
|
const stripped = normalized.replace(/^(\.\.\/)+/, "");
|
|
75475
75602
|
if (stripped && stripped !== variant && !stripped.startsWith("..")) {
|
|
75476
|
-
if (compiledDir) addCandidate(
|
|
75477
|
-
addCandidate(
|
|
75603
|
+
if (compiledDir) addCandidate(join11(compiledDir, stripped));
|
|
75604
|
+
addCandidate(join11(baseDir, stripped));
|
|
75478
75605
|
}
|
|
75479
75606
|
}
|
|
75480
75607
|
if (fromCompiled) addCandidate(fromCompiled);
|
|
75481
75608
|
addCandidate(fromBase);
|
|
75482
75609
|
}
|
|
75483
|
-
return candidates.find(existsSync10) ??
|
|
75610
|
+
return candidates.find(existsSync10) ?? join11(baseDir, cleanSrc);
|
|
75484
75611
|
}
|
|
75485
75612
|
async function extractAllVideoFrames(videos, baseDir, options, signal, config, compiledDir) {
|
|
75486
75613
|
if (options.timelineEnd !== void 0 && !Number.isFinite(options.timelineEnd)) {
|
|
@@ -75527,7 +75654,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
|
|
|
75527
75654
|
videoPath = resolveProjectRelativeSrc(video.src, baseDir, compiledDir);
|
|
75528
75655
|
}
|
|
75529
75656
|
if (isHttpUrl(videoPath)) {
|
|
75530
|
-
const downloadDir =
|
|
75657
|
+
const downloadDir = join11(options.outputDir, "_downloads");
|
|
75531
75658
|
mkdirSync6(downloadDir, { recursive: true });
|
|
75532
75659
|
videoPath = await downloadToTemp(
|
|
75533
75660
|
videoPath,
|
|
@@ -75735,7 +75862,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
|
|
|
75735
75862
|
async function extractDirectMiss(miss, maxTransientRetries = options.maxTransientRetries ?? 0) {
|
|
75736
75863
|
const { work, cacheTarget } = miss;
|
|
75737
75864
|
if (!cacheTarget) {
|
|
75738
|
-
const outputDir =
|
|
75865
|
+
const outputDir = join11(options.outputDir, work.video.id);
|
|
75739
75866
|
const attempted2 = await runVideoExtractionWithRetry(
|
|
75740
75867
|
() => extractVideoFramesRange(
|
|
75741
75868
|
work.videoPath,
|
|
@@ -75803,7 +75930,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
|
|
|
75803
75930
|
return sliceSupersetMember(
|
|
75804
75931
|
member,
|
|
75805
75932
|
superset,
|
|
75806
|
-
|
|
75933
|
+
join11(options.outputDir, work.video.id),
|
|
75807
75934
|
fps,
|
|
75808
75935
|
configuredFps
|
|
75809
75936
|
);
|
|
@@ -75820,7 +75947,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
|
|
|
75820
75947
|
async function executeSupersetGroup(group) {
|
|
75821
75948
|
const first = group.members[0]?.miss.work;
|
|
75822
75949
|
if (!first) return [];
|
|
75823
|
-
const tempDir = cacheRootDir ?
|
|
75950
|
+
const tempDir = cacheRootDir ? join11(cacheRootDir, `${group.groupId}.partial-${process.pid}`) : join11(options.outputDir, group.groupId);
|
|
75824
75951
|
try {
|
|
75825
75952
|
rmSync3(tempDir, { recursive: true, force: true });
|
|
75826
75953
|
const superset = await extractVideoFramesRange(
|
|
@@ -76051,6 +76178,7 @@ var init_videoFrameExtractor = __esm({
|
|
|
76051
76178
|
init_config();
|
|
76052
76179
|
init_htmlTemplate();
|
|
76053
76180
|
init_extractionCache();
|
|
76181
|
+
init_extractedFrameIndex();
|
|
76054
76182
|
VIDEO_FRAME_FORMATS = ["auto", "jpg", "png"];
|
|
76055
76183
|
EXTRACT_CACHE_MIN_AGE_MS = 60 * 60 * 1e3;
|
|
76056
76184
|
GC_STALENESS_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -76884,7 +77012,7 @@ var init_audio_fx_runtime_inline = __esm({
|
|
|
76884
77012
|
// ../engine/src/services/audioFxRender.ts
|
|
76885
77013
|
import { existsSync as existsSync11, mkdtempSync as mkdtempSync2, readFileSync as readFileSync4, rmSync as rmSync4, writeFileSync as writeFileSync5 } from "fs";
|
|
76886
77014
|
import { tmpdir as tmpdir2 } from "os";
|
|
76887
|
-
import { join as
|
|
77015
|
+
import { join as join12 } from "path";
|
|
76888
77016
|
import { pathToFileURL } from "url";
|
|
76889
77017
|
function readWavChunks(buf) {
|
|
76890
77018
|
const head = { format: 1, channels: 1, sampleRate: 48e3, bits: 16 };
|
|
@@ -76997,7 +77125,7 @@ async function applyAudioFxChain(inputWav, chain, outputWav, options) {
|
|
|
76997
77125
|
const { samples, sampleRate, channels, float } = readWav(inputWav);
|
|
76998
77126
|
const planes = deinterleave(samples, channels);
|
|
76999
77127
|
if ((planes[0]?.length ?? 0) === 0) return { path: inputWav, envelopeBaked: false };
|
|
77000
|
-
const hostDir = mkdtempSync2(
|
|
77128
|
+
const hostDir = mkdtempSync2(join12(tmpdir2(), "hf-fx-host-"));
|
|
77001
77129
|
let lease = null;
|
|
77002
77130
|
try {
|
|
77003
77131
|
if (options.signal?.aborted) {
|
|
@@ -77006,7 +77134,7 @@ async function applyAudioFxChain(inputWav, chain, outputWav, options) {
|
|
|
77006
77134
|
lease = await acquireBrowser(["--no-sandbox", "--autoplay-policy=no-user-gesture-required"]);
|
|
77007
77135
|
const page = await lease.browser.newPage();
|
|
77008
77136
|
try {
|
|
77009
|
-
const hostPage =
|
|
77137
|
+
const hostPage = join12(hostDir, "audio-fx.html");
|
|
77010
77138
|
writeFileSync5(hostPage, "<!doctype html><meta charset=utf-8><title>audio fx</title>");
|
|
77011
77139
|
await page.goto(pathToFileURL(hostPage).href, { waitUntil: "domcontentloaded" });
|
|
77012
77140
|
await page.addScriptTag({ content: getAudioFxRuntimeScript() });
|
|
@@ -77143,7 +77271,7 @@ var init_audioFxRender = __esm({
|
|
|
77143
77271
|
|
|
77144
77272
|
// ../engine/src/services/audioMixer.ts
|
|
77145
77273
|
import { closeSync as closeSync2, existsSync as existsSync12, mkdirSync as mkdirSync7, mkdtempSync as mkdtempSync3, openSync as openSync2, rmSync as rmSync5, writeFileSync as writeFileSync6 } from "fs";
|
|
77146
|
-
import { join as
|
|
77274
|
+
import { join as join13, dirname as dirname7 } from "path";
|
|
77147
77275
|
function memberGroupKey(el) {
|
|
77148
77276
|
return el.getAttribute(AUDIO_GROUP_RENDER_ID_ATTR) ?? el.getAttribute(HF_AUDIO_GROUP_ATTR);
|
|
77149
77277
|
}
|
|
@@ -77394,7 +77522,7 @@ function parseAudioElements(html) {
|
|
|
77394
77522
|
const groupId = memberGroupKey(el);
|
|
77395
77523
|
return groupId ? groupsById.get(groupId)?.hidden ?? false : false;
|
|
77396
77524
|
};
|
|
77397
|
-
const build = (el, id, type) => {
|
|
77525
|
+
const build = (el, id, src, type) => {
|
|
77398
77526
|
const playbackRateAttr = el.getAttribute("data-playback-rate");
|
|
77399
77527
|
const layerAttr = el.getAttribute("data-layer");
|
|
77400
77528
|
const volumeAttr = el.getAttribute("data-volume");
|
|
@@ -77404,7 +77532,7 @@ function parseAudioElements(html) {
|
|
|
77404
77532
|
const group = groupId ? groupsById.get(groupId) : void 0;
|
|
77405
77533
|
return {
|
|
77406
77534
|
id,
|
|
77407
|
-
src
|
|
77535
|
+
src,
|
|
77408
77536
|
start: resolveStart2(el),
|
|
77409
77537
|
end: parseEnd(el.getAttribute("data-end")),
|
|
77410
77538
|
mediaStart: readMediaStart(el),
|
|
@@ -77425,17 +77553,19 @@ function parseAudioElements(html) {
|
|
|
77425
77553
|
};
|
|
77426
77554
|
};
|
|
77427
77555
|
const trackId = (el) => el.getAttribute(MEDIA_RENDER_ID_ATTR) || el.getAttribute("id");
|
|
77428
|
-
for (const el of document2.querySelectorAll("audio[id]
|
|
77556
|
+
for (const el of document2.querySelectorAll("audio[id]")) {
|
|
77429
77557
|
const id = trackId(el);
|
|
77430
|
-
|
|
77558
|
+
const src = resolveMediaElementSrc(el);
|
|
77559
|
+
if (!id || !src || isHidden(el) || memberGroupHidden(el)) continue;
|
|
77431
77560
|
if (isKnownInactiveTimelineWindow(el, resolveStart2(el))) continue;
|
|
77432
|
-
elements.push(build(el, id, "audio"));
|
|
77561
|
+
elements.push(build(el, id, src, "audio"));
|
|
77433
77562
|
}
|
|
77434
|
-
for (const el of document2.querySelectorAll('video[id][
|
|
77563
|
+
for (const el of document2.querySelectorAll('video[id][data-has-audio="true"]')) {
|
|
77435
77564
|
const id = trackId(el);
|
|
77436
|
-
|
|
77565
|
+
const src = resolveMediaElementSrc(el);
|
|
77566
|
+
if (!id || !src || isHidden(el)) continue;
|
|
77437
77567
|
if (isKnownInactiveTimelineWindow(el, resolveStart2(el))) continue;
|
|
77438
|
-
elements.push(build(el, `${id}-audio`, "video"));
|
|
77568
|
+
elements.push(build(el, `${id}-audio`, src, "video"));
|
|
77439
77569
|
}
|
|
77440
77570
|
return elements;
|
|
77441
77571
|
}
|
|
@@ -77607,8 +77737,8 @@ async function mixAudioTracks(tracks, outputPath, totalDuration, signal, config)
|
|
|
77607
77737
|
const runMix = async (ignoreAutomation) => {
|
|
77608
77738
|
const inputs = [];
|
|
77609
77739
|
tracks.forEach((track) => inputs.push("-i", track.srcPath));
|
|
77610
|
-
const scriptDir = mkdtempSync3(
|
|
77611
|
-
const scriptPath =
|
|
77740
|
+
const scriptDir = mkdtempSync3(join13(outputDir, ".filter-complex-"));
|
|
77741
|
+
const scriptPath = join13(scriptDir, "graph.txt");
|
|
77612
77742
|
const fd = openSync2(scriptPath, "wx", 384);
|
|
77613
77743
|
try {
|
|
77614
77744
|
writeFileSync6(fd, buildFilterComplex(ignoreAutomation));
|
|
@@ -77714,8 +77844,8 @@ async function mixGroupMembers(memberTracks, outputPath, totalDuration, signal,
|
|
|
77714
77844
|
`${mixInputs}amix=inputs=${memberTracks.length}:duration=longest:dropout_transition=0[mixed];[mixed]volume=${formatFilterNumber(memberTracks.length)}[out]`
|
|
77715
77845
|
);
|
|
77716
77846
|
const filterComplex = [...inputFilters, mixFilter].join(";");
|
|
77717
|
-
const scriptDir = mkdtempSync3(
|
|
77718
|
-
const scriptPath =
|
|
77847
|
+
const scriptDir = mkdtempSync3(join13(outputDir, ".group-filter-complex-"));
|
|
77848
|
+
const scriptPath = join13(scriptDir, "graph.txt");
|
|
77719
77849
|
const fd = openSync2(scriptPath, "wx", 384);
|
|
77720
77850
|
try {
|
|
77721
77851
|
writeFileSync6(fd, filterComplex);
|
|
@@ -77865,7 +77995,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
77865
77995
|
}
|
|
77866
77996
|
let audioSrcPath = srcPath;
|
|
77867
77997
|
if (element.type === "video") {
|
|
77868
|
-
const extractedPath =
|
|
77998
|
+
const extractedPath = join13(workDir, `${element.id}-extracted.wav`);
|
|
77869
77999
|
const extractResult = await extractAudioFromVideo(
|
|
77870
78000
|
srcPath,
|
|
77871
78001
|
extractedPath,
|
|
@@ -77892,7 +78022,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
77892
78022
|
}
|
|
77893
78023
|
audioSrcPath = extractedPath;
|
|
77894
78024
|
} else {
|
|
77895
|
-
const trimmedPath =
|
|
78025
|
+
const trimmedPath = join13(workDir, `${element.id}-trimmed.wav`);
|
|
77896
78026
|
const prepResult = await prepareAudioTrack(
|
|
77897
78027
|
srcPath,
|
|
77898
78028
|
trimmedPath,
|
|
@@ -77936,7 +78066,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
77936
78066
|
const fxResult = await applyAudioFxChain(
|
|
77937
78067
|
audioSrcPath,
|
|
77938
78068
|
chain,
|
|
77939
|
-
|
|
78069
|
+
join13(workDir, `${element.id}-fx.wav`),
|
|
77940
78070
|
{
|
|
77941
78071
|
trackId: element.id,
|
|
77942
78072
|
signal: effectiveSignal,
|
|
@@ -78027,7 +78157,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
78027
78157
|
const meta = groupMeta.get(groupId);
|
|
78028
78158
|
if (!meta) continue;
|
|
78029
78159
|
const pathId = safePathSegment(groupId, groupIndex);
|
|
78030
|
-
const groupWavPath =
|
|
78160
|
+
const groupWavPath = join13(workDir, `group-${pathId}.wav`);
|
|
78031
78161
|
try {
|
|
78032
78162
|
const subMix = await mixGroupMembers(
|
|
78033
78163
|
memberTracks,
|
|
@@ -78063,7 +78193,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
78063
78193
|
const fxResult = await applyAudioFxChain(
|
|
78064
78194
|
groupSrcPath,
|
|
78065
78195
|
chain,
|
|
78066
|
-
|
|
78196
|
+
join13(workDir, `group-${pathId}-fx.wav`),
|
|
78067
78197
|
{
|
|
78068
78198
|
trackId: groupId,
|
|
78069
78199
|
signal: effectiveSignal,
|
|
@@ -78161,14 +78291,14 @@ var init_audioMixer = __esm({
|
|
|
78161
78291
|
import { execFile as execFile2 } from "child_process";
|
|
78162
78292
|
import { mkdtemp, rm, writeFile } from "fs/promises";
|
|
78163
78293
|
import { tmpdir as tmpdir3 } from "os";
|
|
78164
|
-
import { join as
|
|
78294
|
+
import { join as join14 } from "path";
|
|
78165
78295
|
import { promisify as promisify2 } from "util";
|
|
78166
78296
|
async function psnrDb(a, b) {
|
|
78167
78297
|
const execFileP = promisify2(execFile2);
|
|
78168
|
-
const dir = await mkdtemp(
|
|
78298
|
+
const dir = await mkdtemp(join14(tmpdir3(), "hf-de-verify-"));
|
|
78169
78299
|
try {
|
|
78170
|
-
const pa =
|
|
78171
|
-
const pb =
|
|
78300
|
+
const pa = join14(dir, "a.jpg");
|
|
78301
|
+
const pb = join14(dir, "b.jpg");
|
|
78172
78302
|
await Promise.all([writeFile(pa, a), writeFile(pb, b)]);
|
|
78173
78303
|
const { stderr } = await execFileP(
|
|
78174
78304
|
getFfmpegBinary(),
|
|
@@ -78279,7 +78409,7 @@ var init_readWebGlVendorInfoFromCanvas = __esm({
|
|
|
78279
78409
|
import { cpus, freemem } from "os";
|
|
78280
78410
|
import { existsSync as existsSync13, mkdirSync as mkdirSync8, readdirSync as readdirSync6 } from "fs";
|
|
78281
78411
|
import { copyFile, readFile, rename } from "fs/promises";
|
|
78282
|
-
import { join as
|
|
78412
|
+
import { join as join15 } from "path";
|
|
78283
78413
|
import { getHeapStatistics } from "v8";
|
|
78284
78414
|
function defaultSafeMaxWorkers() {
|
|
78285
78415
|
return Math.max(6, Math.min(16, Math.floor(cpus().length / 8)));
|
|
@@ -78408,7 +78538,7 @@ function distributeFrames(totalFrames, workerCount, workDir, rangeStart = 0) {
|
|
|
78408
78538
|
workerId: i,
|
|
78409
78539
|
startFrame,
|
|
78410
78540
|
endFrame,
|
|
78411
|
-
outputDir:
|
|
78541
|
+
outputDir: join15(workDir, `worker-${i}`),
|
|
78412
78542
|
outputFrameOffset: rangeStart
|
|
78413
78543
|
});
|
|
78414
78544
|
}
|
|
@@ -78422,7 +78552,7 @@ function distributeFramesInterleaved(totalFrames, workerCount, workDir, rangeSta
|
|
|
78422
78552
|
startFrame: rangeStart + i,
|
|
78423
78553
|
endFrame: rangeStart + totalFrames,
|
|
78424
78554
|
frameStride: workerCount,
|
|
78425
|
-
outputDir:
|
|
78555
|
+
outputDir: join15(workDir, `worker-${i}`),
|
|
78426
78556
|
outputFrameOffset: rangeStart
|
|
78427
78557
|
});
|
|
78428
78558
|
}
|
|
@@ -78580,7 +78710,7 @@ async function verifyDiskDrawElementSamples(session, task, streaming) {
|
|
|
78580
78710
|
for (const idx of selectVerifySampleIndicesForTask(truths.keys(), task)) {
|
|
78581
78711
|
const truth = truths.get(idx);
|
|
78582
78712
|
if (!truth) continue;
|
|
78583
|
-
const framePath =
|
|
78713
|
+
const framePath = join15(task.outputDir, `frame_${String(idx - offset2).padStart(6, "0")}.${ext}`);
|
|
78584
78714
|
const db = await psnrForDiskSample(framePath, truth, task.workerId, idx);
|
|
78585
78715
|
if (db === null) continue;
|
|
78586
78716
|
assertDiskSampleAboveFloor(db, verifyMinDb, idx, task.workerId);
|
|
@@ -78746,8 +78876,8 @@ async function mergeWorkerFrames(workDir, tasks, outputDir) {
|
|
|
78746
78876
|
}
|
|
78747
78877
|
const files = readdirSync6(task.outputDir).filter((f) => f.startsWith("frame_") && (f.endsWith(".jpg") || f.endsWith(".png"))).sort();
|
|
78748
78878
|
const copyTasks = files.map(async (file) => {
|
|
78749
|
-
const sourcePath =
|
|
78750
|
-
const targetPath =
|
|
78879
|
+
const sourcePath = join15(task.outputDir, file);
|
|
78880
|
+
const targetPath = join15(outputDir, file);
|
|
78751
78881
|
try {
|
|
78752
78882
|
await rename(sourcePath, targetPath);
|
|
78753
78883
|
} catch {
|
|
@@ -78793,7 +78923,7 @@ var init_parallelCoordinator = __esm({
|
|
|
78793
78923
|
import { Hono } from "hono";
|
|
78794
78924
|
import { serve } from "@hono/node-server";
|
|
78795
78925
|
import { readFileSync as readFileSync5, existsSync as existsSync14, statSync as statSync6 } from "fs";
|
|
78796
|
-
import { join as
|
|
78926
|
+
import { join as join16, extname as extname3 } from "path";
|
|
78797
78927
|
function createFileServer(options) {
|
|
78798
78928
|
const { projectDir, compiledDir, port = 0, stripEmbeddedRuntime = true } = options;
|
|
78799
78929
|
const headScripts = options.headScripts ?? [];
|
|
@@ -78803,11 +78933,11 @@ function createFileServer(options) {
|
|
|
78803
78933
|
let requestPath = c.req.path;
|
|
78804
78934
|
if (requestPath === "/") requestPath = "/index.html";
|
|
78805
78935
|
const relativePath = requestPath.replace(/^\//, "");
|
|
78806
|
-
const compiledPath = compiledDir ?
|
|
78936
|
+
const compiledPath = compiledDir ? join16(compiledDir, relativePath) : null;
|
|
78807
78937
|
const hasCompiledFile = Boolean(
|
|
78808
78938
|
compiledPath && existsSync14(compiledPath) && statSync6(compiledPath).isFile()
|
|
78809
78939
|
);
|
|
78810
|
-
const filePath = hasCompiledFile ? compiledPath :
|
|
78940
|
+
const filePath = hasCompiledFile ? compiledPath : join16(projectDir, relativePath);
|
|
78811
78941
|
if (!existsSync14(filePath) || !statSync6(filePath).isFile()) {
|
|
78812
78942
|
return c.text("Not found", 404);
|
|
78813
78943
|
}
|
|
@@ -80260,7 +80390,7 @@ var init_shaderTransitions = __esm({
|
|
|
80260
80390
|
|
|
80261
80391
|
// ../engine/src/services/hdrCapture.ts
|
|
80262
80392
|
import { existsSync as existsSync15, readdirSync as readdirSync7 } from "fs";
|
|
80263
|
-
import { join as
|
|
80393
|
+
import { join as join17 } from "path";
|
|
80264
80394
|
import { homedir as homedir2 } from "os";
|
|
80265
80395
|
function linearToPQ(L) {
|
|
80266
80396
|
const Lp = Math.max(0, L * SDR_NITS / PQ_MAX_NITS);
|
|
@@ -80376,12 +80506,12 @@ function float16ToPqRgb(rawBuffer, bytesPerRow, width, height) {
|
|
|
80376
80506
|
return output;
|
|
80377
80507
|
}
|
|
80378
80508
|
function resolveHeadedChromePath() {
|
|
80379
|
-
const baseDir =
|
|
80509
|
+
const baseDir = join17(homedir2(), ".cache", "puppeteer", "chrome");
|
|
80380
80510
|
if (!existsSync15(baseDir)) return void 0;
|
|
80381
80511
|
const versions = readdirSync7(baseDir).sort().reverse();
|
|
80382
80512
|
for (const version2 of versions) {
|
|
80383
80513
|
const candidates = [
|
|
80384
|
-
|
|
80514
|
+
join17(
|
|
80385
80515
|
baseDir,
|
|
80386
80516
|
version2,
|
|
80387
80517
|
"chrome-mac-arm64",
|
|
@@ -80390,7 +80520,7 @@ function resolveHeadedChromePath() {
|
|
|
80390
80520
|
"MacOS",
|
|
80391
80521
|
"Google Chrome for Testing"
|
|
80392
80522
|
),
|
|
80393
|
-
|
|
80523
|
+
join17(
|
|
80394
80524
|
baseDir,
|
|
80395
80525
|
version2,
|
|
80396
80526
|
"chrome-mac-x64",
|
|
@@ -80399,8 +80529,8 @@ function resolveHeadedChromePath() {
|
|
|
80399
80529
|
"MacOS",
|
|
80400
80530
|
"Google Chrome for Testing"
|
|
80401
80531
|
),
|
|
80402
|
-
|
|
80403
|
-
|
|
80532
|
+
join17(baseDir, version2, "chrome-linux64", "chrome"),
|
|
80533
|
+
join17(baseDir, version2, "chrome-win64", "chrome.exe")
|
|
80404
80534
|
];
|
|
80405
80535
|
for (const binary of candidates) {
|
|
80406
80536
|
if (existsSync15(binary)) return binary;
|
|
@@ -80643,6 +80773,7 @@ __export(src_exports, {
|
|
|
80643
80773
|
resolveHeadlessShellPath: () => resolveHeadlessShellPath,
|
|
80644
80774
|
resolvePlayableVideoDuration: () => resolvePlayableVideoDuration,
|
|
80645
80775
|
resolveProjectRelativeSrc: () => resolveProjectRelativeSrc,
|
|
80776
|
+
resolveReferencedStart: () => resolveReferencedStart,
|
|
80646
80777
|
resolveTimelineExtractionWindow: () => resolveTimelineExtractionWindow,
|
|
80647
80778
|
resolveVideoExtractionDuration: () => resolveVideoExtractionDuration,
|
|
80648
80779
|
resolveVideoExtractionWindow: () => resolveVideoExtractionWindow,
|
|
@@ -80680,6 +80811,7 @@ var init_src = __esm({
|
|
|
80680
80811
|
init_chunkEncoder();
|
|
80681
80812
|
init_streamingEncoder();
|
|
80682
80813
|
init_videoFrameExtractor();
|
|
80814
|
+
init_referenceResolver();
|
|
80683
80815
|
init_videoFrameInjector();
|
|
80684
80816
|
init_audioMixer();
|
|
80685
80817
|
init_captureWarning();
|
|
@@ -83875,7 +84007,7 @@ __export(fontCompression_exports, {
|
|
|
83875
84007
|
import { createHash as createHash6 } from "crypto";
|
|
83876
84008
|
import { existsSync as existsSync21, mkdirSync as mkdirSync10, readFileSync as readFileSync7, renameSync as renameSync4, rmSync as rmSync8, writeFileSync as writeFileSync8 } from "fs";
|
|
83877
84009
|
import { homedir as homedir4, tmpdir as tmpdir4 } from "os";
|
|
83878
|
-
import { dirname as dirname11, join as
|
|
84010
|
+
import { dirname as dirname11, join as join24 } from "path";
|
|
83879
84011
|
async function compressToWoff2(input) {
|
|
83880
84012
|
return Buffer.from(await compress(input));
|
|
83881
84013
|
}
|
|
@@ -83883,12 +84015,12 @@ function rawMimeType(format) {
|
|
|
83883
84015
|
return RAW_MIME_TYPES[format] ?? "font/ttf";
|
|
83884
84016
|
}
|
|
83885
84017
|
function defaultCacheDir() {
|
|
83886
|
-
const root = process.env.HYPERFRAMES_FONT_CACHE_DIR ?? (process.env.AWS_LAMBDA_FUNCTION_NAME ?
|
|
83887
|
-
return
|
|
84018
|
+
const root = process.env.HYPERFRAMES_FONT_CACHE_DIR ?? (process.env.AWS_LAMBDA_FUNCTION_NAME ? join24(tmpdir4(), "hyperframes", "fonts") : join24(homedir4(), ".cache", "hyperframes", "fonts"));
|
|
84019
|
+
return join24(root, "local-compression-v1");
|
|
83888
84020
|
}
|
|
83889
84021
|
function cachedCompressionPath(input, originalFormat, cacheDir) {
|
|
83890
84022
|
const digest = createHash6("sha256").update("hyperframes-local-font-compression-v1\0").update(originalFormat).update("\0").update(input).digest("hex");
|
|
83891
|
-
return
|
|
84023
|
+
return join24(cacheDir, `${digest}.woff2`);
|
|
83892
84024
|
}
|
|
83893
84025
|
function readCachedCompression(path) {
|
|
83894
84026
|
try {
|
|
@@ -83968,7 +84100,7 @@ import {
|
|
|
83968
84100
|
appendFileSync
|
|
83969
84101
|
} from "fs";
|
|
83970
84102
|
import { tmpdir as tmpdir7 } from "os";
|
|
83971
|
-
import { join as
|
|
84103
|
+
import { join as join41, dirname as dirname16, resolve as resolve13 } from "path";
|
|
83972
84104
|
import { totalmem as totalmem3 } from "os";
|
|
83973
84105
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
83974
84106
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
@@ -83981,7 +84113,7 @@ import { serve as serve2 } from "@hono/node-server";
|
|
|
83981
84113
|
import { existsSync as existsSync17, realpathSync as realpathSync2, statSync as statSync7, createReadStream as createReadStream3 } from "fs";
|
|
83982
84114
|
import { readFile as readFile2 } from "fs/promises";
|
|
83983
84115
|
import { Readable as Readable2 } from "stream";
|
|
83984
|
-
import { join as
|
|
84116
|
+
import { join as join18, extname as extname4, resolve as resolve7, sep as sep3 } from "path";
|
|
83985
84117
|
|
|
83986
84118
|
// ../producer/src/services/hyperframeRuntimeLoader.ts
|
|
83987
84119
|
import { createHash as createHash4 } from "crypto";
|
|
@@ -84571,13 +84703,13 @@ function createFileServer2(options) {
|
|
|
84571
84703
|
}).join("/");
|
|
84572
84704
|
let filePath = null;
|
|
84573
84705
|
if (compiledDir) {
|
|
84574
|
-
const candidate =
|
|
84706
|
+
const candidate = join18(compiledDir, relativePath);
|
|
84575
84707
|
if (existsSync17(candidate) && isPathInside2(candidate, compiledDir) && statSync7(candidate).isFile()) {
|
|
84576
84708
|
filePath = candidate;
|
|
84577
84709
|
}
|
|
84578
84710
|
}
|
|
84579
84711
|
if (!filePath) {
|
|
84580
|
-
const candidate =
|
|
84712
|
+
const candidate = join18(projectDir, relativePath);
|
|
84581
84713
|
if (existsSync17(candidate) && isPathInside2(candidate, projectDir) && statSync7(candidate).isFile()) {
|
|
84582
84714
|
filePath = candidate;
|
|
84583
84715
|
}
|
|
@@ -84682,12 +84814,12 @@ import {
|
|
|
84682
84814
|
symlinkSync,
|
|
84683
84815
|
writeFileSync as writeFileSync7
|
|
84684
84816
|
} from "fs";
|
|
84685
|
-
import { basename as basename4, dirname as dirname9, isAbsolute as isAbsolute2, join as
|
|
84817
|
+
import { basename as basename4, dirname as dirname9, isAbsolute as isAbsolute2, join as join20, relative, resolve as resolve8 } from "path";
|
|
84686
84818
|
|
|
84687
84819
|
// ../producer/src/utils/paths.ts
|
|
84688
84820
|
import {
|
|
84689
84821
|
basename as basename3,
|
|
84690
|
-
join as
|
|
84822
|
+
join as join19,
|
|
84691
84823
|
resolve as nodeResolve,
|
|
84692
84824
|
relative as nodeRelative,
|
|
84693
84825
|
isAbsolute as nodeIsAbsolute
|
|
@@ -84725,7 +84857,7 @@ function formatExportFrameName(index, ext) {
|
|
|
84725
84857
|
function resolveRenderPaths(projectDir, outputPath, rendersDir = DEFAULT_RENDERS_DIR) {
|
|
84726
84858
|
const absoluteProjectDir = nodeResolve(projectDir);
|
|
84727
84859
|
const projectName = basename3(absoluteProjectDir);
|
|
84728
|
-
const resolvedOutputPath = outputPath ??
|
|
84860
|
+
const resolvedOutputPath = outputPath ?? join19(rendersDir, `${projectName}.mp4`);
|
|
84729
84861
|
const absoluteOutputPath = nodeResolve(resolvedOutputPath);
|
|
84730
84862
|
return { absoluteProjectDir, absoluteOutputPath };
|
|
84731
84863
|
}
|
|
@@ -84762,16 +84894,16 @@ function resolveDeviceScaleFactor(input) {
|
|
|
84762
84894
|
return target.width / input.compositionWidth;
|
|
84763
84895
|
}
|
|
84764
84896
|
function writeCompiledArtifacts(compiled, workDir, includeSummary) {
|
|
84765
|
-
const compileDir =
|
|
84897
|
+
const compileDir = join20(workDir, "compiled");
|
|
84766
84898
|
mkdirSync9(compileDir, { recursive: true });
|
|
84767
|
-
writeFileSync7(
|
|
84899
|
+
writeFileSync7(join20(compileDir, "index.html"), compiled.html, "utf-8");
|
|
84768
84900
|
for (const [srcPath, html] of compiled.subCompositions) {
|
|
84769
|
-
const outPath =
|
|
84901
|
+
const outPath = join20(compileDir, srcPath);
|
|
84770
84902
|
mkdirSync9(dirname9(outPath), { recursive: true });
|
|
84771
84903
|
writeFileSync7(outPath, html, "utf-8");
|
|
84772
84904
|
}
|
|
84773
84905
|
for (const [relativePath, absolutePath] of compiled.externalAssets) {
|
|
84774
|
-
const outPath = resolve8(
|
|
84906
|
+
const outPath = resolve8(join20(compileDir, relativePath));
|
|
84775
84907
|
if (!isPathInside3(outPath, compileDir)) {
|
|
84776
84908
|
console.warn(`[Render] Skipping external asset with unsafe path: ${relativePath}`);
|
|
84777
84909
|
continue;
|
|
@@ -84802,7 +84934,7 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
|
|
|
84802
84934
|
renderModeHints: compiled.renderModeHints,
|
|
84803
84935
|
hasShaderTransitions: compiled.hasShaderTransitions
|
|
84804
84936
|
};
|
|
84805
|
-
writeFileSync7(
|
|
84937
|
+
writeFileSync7(join20(compileDir, "summary.json"), JSON.stringify(summary, null, 2), "utf-8");
|
|
84806
84938
|
}
|
|
84807
84939
|
}
|
|
84808
84940
|
function applyRenderModeHints(alreadyForced, compiled, log = defaultLogger) {
|
|
@@ -84829,7 +84961,7 @@ function updateJobStatus(job, status, stage, progress, onProgress) {
|
|
|
84829
84961
|
}
|
|
84830
84962
|
var materializePathModule = {
|
|
84831
84963
|
resolve: resolve8,
|
|
84832
|
-
join:
|
|
84964
|
+
join: join20,
|
|
84833
84965
|
dirname: dirname9,
|
|
84834
84966
|
basename: basename4,
|
|
84835
84967
|
relative,
|
|
@@ -85097,7 +85229,7 @@ import {
|
|
|
85097
85229
|
renameSync as renameSync3,
|
|
85098
85230
|
rmSync as rmSync7
|
|
85099
85231
|
} from "fs";
|
|
85100
|
-
import { basename as basename5, dirname as dirname10, extname as extname5, join as
|
|
85232
|
+
import { basename as basename5, dirname as dirname10, extname as extname5, join as join21, resolve as resolve9 } from "path";
|
|
85101
85233
|
var defaultFileSystem = {
|
|
85102
85234
|
existsSync: existsSync19,
|
|
85103
85235
|
renameSync: renameSync3,
|
|
@@ -85107,7 +85239,7 @@ function createSiblingTransactionDirectory(destination) {
|
|
|
85107
85239
|
const parent = dirname10(destination);
|
|
85108
85240
|
const extension = extname5(destination);
|
|
85109
85241
|
const stem = extension ? basename5(destination, extension) : basename5(destination);
|
|
85110
|
-
return mkdtempSync4(
|
|
85242
|
+
return mkdtempSync4(join21(parent, `.${stem}.hf-transaction-`));
|
|
85111
85243
|
}
|
|
85112
85244
|
function assertReadableNonEmptyFile(path) {
|
|
85113
85245
|
const fd = openSync3(path, "r");
|
|
@@ -85125,7 +85257,7 @@ function collectDirectoryFiles(root) {
|
|
|
85125
85257
|
const files = [];
|
|
85126
85258
|
const visit = (directory) => {
|
|
85127
85259
|
for (const entry of readdirSync8(directory, { withFileTypes: true })) {
|
|
85128
|
-
const path =
|
|
85260
|
+
const path = join21(directory, entry.name);
|
|
85129
85261
|
if (entry.isDirectory()) visit(path);
|
|
85130
85262
|
else if (entry.isFile()) files.push(path);
|
|
85131
85263
|
}
|
|
@@ -85139,8 +85271,8 @@ var ArtifactTransaction = class {
|
|
|
85139
85271
|
this.fileSystem = fileSystem;
|
|
85140
85272
|
this.destinationPath = resolve9(destinationPath);
|
|
85141
85273
|
this.transactionDirectory = createSiblingTransactionDirectory(this.destinationPath);
|
|
85142
|
-
this.stagingPath =
|
|
85143
|
-
this.backupPath =
|
|
85274
|
+
this.stagingPath = join21(this.transactionDirectory, basename5(this.destinationPath));
|
|
85275
|
+
this.backupPath = join21(this.transactionDirectory, "backup");
|
|
85144
85276
|
}
|
|
85145
85277
|
kind;
|
|
85146
85278
|
fileSystem;
|
|
@@ -85676,7 +85808,7 @@ function resolveVideoCaptureBeyondViewport(videoCount) {
|
|
|
85676
85808
|
// ../producer/src/services/render/captureCost.ts
|
|
85677
85809
|
init_dist2();
|
|
85678
85810
|
init_src();
|
|
85679
|
-
import { join as
|
|
85811
|
+
import { join as join22 } from "path";
|
|
85680
85812
|
var CAPTURE_CALIBRATION_TARGET_MS = 600;
|
|
85681
85813
|
var MAX_MEASURED_CAPTURE_COST_MULTIPLIER = 8;
|
|
85682
85814
|
var CAPTURE_CALIBRATION_PROTOCOL_TIMEOUT_MS = 3e4;
|
|
@@ -85912,7 +86044,7 @@ async function runCaptureCalibration(input) {
|
|
|
85912
86044
|
});
|
|
85913
86045
|
let calibration;
|
|
85914
86046
|
try {
|
|
85915
|
-
calibration = await runOneCalibration(
|
|
86047
|
+
calibration = await runOneCalibration(join22(workDir, "capture-calibration"), calibrationCfg);
|
|
85916
86048
|
} catch (error) {
|
|
85917
86049
|
const shouldFallback = !forceScreenshot && shouldFallbackToScreenshotAfterCalibrationError(error);
|
|
85918
86050
|
if (!shouldFallback) {
|
|
@@ -85945,7 +86077,7 @@ async function runCaptureCalibration(input) {
|
|
|
85945
86077
|
const screenshotCfg = createCaptureCalibrationConfig({ ...cfg, forceScreenshot: true });
|
|
85946
86078
|
try {
|
|
85947
86079
|
calibration = await runOneCalibration(
|
|
85948
|
-
|
|
86080
|
+
join22(workDir, "capture-calibration-screenshot"),
|
|
85949
86081
|
screenshotCfg
|
|
85950
86082
|
);
|
|
85951
86083
|
} catch (fallbackError) {
|
|
@@ -86366,7 +86498,7 @@ function countAuthoredTimedClips(html) {
|
|
|
86366
86498
|
|
|
86367
86499
|
// ../producer/src/services/render/stages/compileStage.ts
|
|
86368
86500
|
init_dist2();
|
|
86369
|
-
import { join as
|
|
86501
|
+
import { join as join28 } from "path";
|
|
86370
86502
|
|
|
86371
86503
|
// ../producer/src/services/htmlCompiler.ts
|
|
86372
86504
|
init_esm10();
|
|
@@ -86376,7 +86508,7 @@ init_compiler();
|
|
|
86376
86508
|
init_subCompositionValidity();
|
|
86377
86509
|
init_assetResolution();
|
|
86378
86510
|
import { createReadStream as createReadStream4, existsSync as existsSync25, mkdirSync as mkdirSync13, readFileSync as readFileSync10 } from "fs";
|
|
86379
|
-
import { join as
|
|
86511
|
+
import { join as join27, dirname as dirname13, resolve as resolve12, basename as basename6 } from "path";
|
|
86380
86512
|
|
|
86381
86513
|
// ../producer/src/utils/ffprobe.ts
|
|
86382
86514
|
init_src();
|
|
@@ -86392,7 +86524,7 @@ function parseNumeric2(value) {
|
|
|
86392
86524
|
const parsed = Number.parseFloat(value);
|
|
86393
86525
|
return Number.isFinite(parsed) ? parsed : null;
|
|
86394
86526
|
}
|
|
86395
|
-
function resolveHostWindow(element) {
|
|
86527
|
+
function resolveHostWindow(element, document2, startCache, visiting) {
|
|
86396
86528
|
const hosts = [];
|
|
86397
86529
|
for (let ancestor2 = element.parentElement; ancestor2; ancestor2 = ancestor2.parentElement) {
|
|
86398
86530
|
if (ancestor2.hasAttribute(COMPOSITION_HOST_ATTR)) hosts.push(ancestor2);
|
|
@@ -86401,7 +86533,7 @@ function resolveHostWindow(element) {
|
|
|
86401
86533
|
let offset2 = 0;
|
|
86402
86534
|
let limit = Infinity;
|
|
86403
86535
|
for (const host of hosts.reverse()) {
|
|
86404
|
-
const hostStart =
|
|
86536
|
+
const hostStart = resolveReferencedStart(document2, host, startCache, visiting);
|
|
86405
86537
|
const hostEnd = parseNumeric2(host.getAttribute("data-end"));
|
|
86406
86538
|
if (hostEnd != null) limit = Math.min(limit, offset2 + hostEnd);
|
|
86407
86539
|
offset2 += hostStart;
|
|
@@ -86411,10 +86543,15 @@ function resolveHostWindow(element) {
|
|
|
86411
86543
|
function collectHostWindows(html) {
|
|
86412
86544
|
const { document: document2 } = parseHTML(html);
|
|
86413
86545
|
const windows = /* @__PURE__ */ new Map();
|
|
86546
|
+
const startCache = /* @__PURE__ */ new Map();
|
|
86547
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
86414
86548
|
for (const element of document2.querySelectorAll(`[${MEDIA_RENDER_ID_ATTR}]`)) {
|
|
86415
86549
|
const renderId = element.getAttribute(MEDIA_RENDER_ID_ATTR);
|
|
86416
86550
|
if (!renderId) continue;
|
|
86417
|
-
windows.set(
|
|
86551
|
+
windows.set(
|
|
86552
|
+
renderId,
|
|
86553
|
+
resolveHostWindow(element, document2, startCache, visiting)
|
|
86554
|
+
);
|
|
86418
86555
|
}
|
|
86419
86556
|
return windows;
|
|
86420
86557
|
}
|
|
@@ -86462,7 +86599,7 @@ init_src();
|
|
|
86462
86599
|
import { createHash as createHash7 } from "crypto";
|
|
86463
86600
|
import { existsSync as existsSync22, mkdirSync as mkdirSync11, mkdtempSync as mkdtempSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync9 } from "fs";
|
|
86464
86601
|
import { homedir as homedir5, tmpdir as tmpdir5 } from "os";
|
|
86465
|
-
import { join as
|
|
86602
|
+
import { join as join25 } from "path";
|
|
86466
86603
|
|
|
86467
86604
|
// ../core/dist/fonts/aliases.js
|
|
86468
86605
|
init_dist();
|
|
@@ -86471,7 +86608,7 @@ init_dist();
|
|
|
86471
86608
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
86472
86609
|
import { existsSync as existsSync20, lstatSync as lstatSync3, readdirSync as readdirSync9, realpathSync as realpathSync3 } from "fs";
|
|
86473
86610
|
import { homedir as homedir3, platform as platform2 } from "os";
|
|
86474
|
-
import { join as
|
|
86611
|
+
import { join as join23, resolve as resolve10 } from "path";
|
|
86475
86612
|
var SYSTEM_FONT_SIZE_LIMIT = 5 * 1024 * 1024;
|
|
86476
86613
|
var PROFILER_TIMEOUT_MS = 5e3;
|
|
86477
86614
|
var FONT_EXT_RE = /\.(otf|ttf|ttc|woff2?)$/i;
|
|
@@ -86568,7 +86705,7 @@ function fontDirectories() {
|
|
|
86568
86705
|
const home = homedir3();
|
|
86569
86706
|
if (platform2() === "darwin") {
|
|
86570
86707
|
return [
|
|
86571
|
-
|
|
86708
|
+
join23(home, "Library", "Fonts"),
|
|
86572
86709
|
"/Library/Fonts",
|
|
86573
86710
|
"/System/Library/Fonts",
|
|
86574
86711
|
"/System/Library/Fonts/Supplemental"
|
|
@@ -86576,13 +86713,13 @@ function fontDirectories() {
|
|
|
86576
86713
|
}
|
|
86577
86714
|
if (platform2() === "win32") {
|
|
86578
86715
|
return [
|
|
86579
|
-
|
|
86580
|
-
|
|
86716
|
+
join23(process.env.WINDIR || "C:\\Windows", "Fonts"),
|
|
86717
|
+
join23(process.env.LOCALAPPDATA || join23(homedir3(), "AppData", "Local"), "Microsoft", "Windows", "Fonts")
|
|
86581
86718
|
];
|
|
86582
86719
|
}
|
|
86583
86720
|
return [
|
|
86584
|
-
|
|
86585
|
-
|
|
86721
|
+
join23(home, ".fonts"),
|
|
86722
|
+
join23(home, ".local", "share", "fonts"),
|
|
86586
86723
|
"/usr/local/share/fonts",
|
|
86587
86724
|
"/usr/share/fonts"
|
|
86588
86725
|
];
|
|
@@ -86593,7 +86730,7 @@ function collectFontFileEntries(dir, depth = 0) {
|
|
|
86593
86730
|
const entries2 = [];
|
|
86594
86731
|
try {
|
|
86595
86732
|
for (const entry of readdirSync9(dir, { withFileTypes: true })) {
|
|
86596
|
-
const fullPath =
|
|
86733
|
+
const fullPath = join23(dir, entry.name);
|
|
86597
86734
|
if (entry.isDirectory()) {
|
|
86598
86735
|
entries2.push(...collectFontFileEntries(fullPath, depth + 1));
|
|
86599
86736
|
continue;
|
|
@@ -87241,17 +87378,17 @@ function resolveFontCacheRoot() {
|
|
|
87241
87378
|
return process.env.HYPERFRAMES_FONT_CACHE_DIR;
|
|
87242
87379
|
}
|
|
87243
87380
|
if (process.env.AWS_LAMBDA_FUNCTION_NAME) {
|
|
87244
|
-
lambdaFontCacheRoot ??= mkdtempSync5(
|
|
87381
|
+
lambdaFontCacheRoot ??= mkdtempSync5(join25(tmpdir5(), "hyperframes-fonts-"));
|
|
87245
87382
|
return lambdaFontCacheRoot;
|
|
87246
87383
|
}
|
|
87247
|
-
return
|
|
87384
|
+
return join25(homedir5(), ".cache", "hyperframes", "fonts");
|
|
87248
87385
|
}
|
|
87249
87386
|
var WOFF2_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36";
|
|
87250
87387
|
function fontSlug(familyName) {
|
|
87251
87388
|
return familyName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
87252
87389
|
}
|
|
87253
87390
|
function fontCacheDir(slug) {
|
|
87254
|
-
const dir =
|
|
87391
|
+
const dir = join25(resolveFontCacheRoot(), slug);
|
|
87255
87392
|
if (!existsSync22(dir)) {
|
|
87256
87393
|
mkdirSync11(dir, { recursive: true });
|
|
87257
87394
|
}
|
|
@@ -87261,7 +87398,7 @@ function subsetToken(woff2Url) {
|
|
|
87261
87398
|
return createHash7("sha1").update(woff2Url).digest("hex").slice(0, 12);
|
|
87262
87399
|
}
|
|
87263
87400
|
function cachedWoff2Path(slug, weight, style, subset) {
|
|
87264
|
-
return
|
|
87401
|
+
return join25(fontCacheDir(slug), `${weight}-${style}-${subset}.woff2`);
|
|
87265
87402
|
}
|
|
87266
87403
|
var FONT_FETCH_FAILED = "FONT_FETCH_FAILED";
|
|
87267
87404
|
var FONT_FETCH_UNAVAILABLE = "FONT_FETCH_UNAVAILABLE";
|
|
@@ -87578,7 +87715,7 @@ import {
|
|
|
87578
87715
|
rmSync as rmSync9,
|
|
87579
87716
|
statSync as statSync8
|
|
87580
87717
|
} from "fs";
|
|
87581
|
-
import { dirname as dirname12, isAbsolute as isAbsolute3, join as
|
|
87718
|
+
import { dirname as dirname12, isAbsolute as isAbsolute3, join as join26, resolve as resolve11 } from "path";
|
|
87582
87719
|
var PREPARED_GIF_SUBDIR = "_animated_gif";
|
|
87583
87720
|
var CACHE_SCHEMA = "hfgif-v1";
|
|
87584
87721
|
function splitUrlSuffix(src) {
|
|
@@ -87812,7 +87949,7 @@ function replaceImageWithVideo(input) {
|
|
|
87812
87949
|
return video;
|
|
87813
87950
|
}
|
|
87814
87951
|
async function prepareAnimatedGifInputs(html, options) {
|
|
87815
|
-
const outputDir = options.outputDir ??
|
|
87952
|
+
const outputDir = options.outputDir ?? join26(options.downloadDir, PREPARED_GIF_SUBDIR);
|
|
87816
87953
|
const outputSrcPrefix = normalizeRelPath(options.outputSrcPrefix ?? PREPARED_GIF_SUBDIR);
|
|
87817
87954
|
const cacheDir = options.cacheDir ?? outputDir;
|
|
87818
87955
|
const { document: document2 } = parseHTML(html);
|
|
@@ -87834,8 +87971,8 @@ async function prepareAnimatedGifInputs(html, options) {
|
|
|
87834
87971
|
const { loopIterations, padSeconds } = resolvePreparedPlayback(metadata, loop, windowSeconds);
|
|
87835
87972
|
const hash2 = computePreparedGifHash(bytes, loopIterations, padSeconds);
|
|
87836
87973
|
const filename = `${CACHE_SCHEMA}-${hash2.slice(0, 24)}.webm`;
|
|
87837
|
-
const cachePath =
|
|
87838
|
-
const outputPath =
|
|
87974
|
+
const cachePath = join26(cacheDir, filename);
|
|
87975
|
+
const outputPath = join26(outputDir, filename);
|
|
87839
87976
|
const outputSrc = `${outputSrcPrefix}/${filename}`;
|
|
87840
87977
|
await ensurePreparedWebm({
|
|
87841
87978
|
sourcePath,
|
|
@@ -88504,7 +88641,7 @@ async function resolveMediaDuration(src, mediaStart, playbackRate, baseDir, down
|
|
|
88504
88641
|
return { duration: null, resolvedPath: src };
|
|
88505
88642
|
}
|
|
88506
88643
|
} else if (!filePath.startsWith("/")) {
|
|
88507
|
-
filePath =
|
|
88644
|
+
filePath = join27(baseDir, filePath);
|
|
88508
88645
|
}
|
|
88509
88646
|
if (!existsSync25(filePath)) {
|
|
88510
88647
|
return { duration: null, resolvedPath: filePath };
|
|
@@ -89036,6 +89173,7 @@ function collectExternalAssets(html, projectDir) {
|
|
|
89036
89173
|
}
|
|
89037
89174
|
var REMOTE_MEDIA_SUBDIR = "_remote_media";
|
|
89038
89175
|
var REMOTE_MEDIA_TAG_RE = /<(?:video|audio)\b[^>]*?\bsrc\s*=\s*["'](https?:\/\/[^"']+)["'][^>]*>/gi;
|
|
89176
|
+
var REMOTE_SOURCE_TAG_RE = /<source\b[^>]*?\bsrc\s*=\s*["'](https?:\/\/[^"']+)["'][^>]*>/gi;
|
|
89039
89177
|
var REMOTE_IMG_TAG_RE = /<img\b[^>]*?(?<![\w-])src\s*=\s*["'](https?:\/\/[^"']+)["'][^>]*>/gi;
|
|
89040
89178
|
async function downloadAndRewriteUrls(urlSet, html, remoteDir, warnLabel, logLabel, extraRewrite) {
|
|
89041
89179
|
if (urlSet.size === 0) return { html, remoteMediaAssets: /* @__PURE__ */ new Map() };
|
|
@@ -89076,15 +89214,17 @@ async function downloadAndRewriteUrls(urlSet, html, remoteDir, warnLabel, logLab
|
|
|
89076
89214
|
}
|
|
89077
89215
|
async function localizeRemoteMediaSources(html, downloadDir) {
|
|
89078
89216
|
const urlSet = /* @__PURE__ */ new Set();
|
|
89079
|
-
const
|
|
89080
|
-
|
|
89081
|
-
|
|
89082
|
-
|
|
89217
|
+
for (const tagRe of [REMOTE_MEDIA_TAG_RE, REMOTE_SOURCE_TAG_RE]) {
|
|
89218
|
+
const re = new RegExp(tagRe.source, tagRe.flags);
|
|
89219
|
+
let m;
|
|
89220
|
+
while ((m = re.exec(html)) !== null) {
|
|
89221
|
+
if (m[1]) urlSet.add(m[1]);
|
|
89222
|
+
}
|
|
89083
89223
|
}
|
|
89084
89224
|
return downloadAndRewriteUrls(
|
|
89085
89225
|
urlSet,
|
|
89086
89226
|
html,
|
|
89087
|
-
|
|
89227
|
+
join27(downloadDir, REMOTE_MEDIA_SUBDIR),
|
|
89088
89228
|
"Remote media download failed",
|
|
89089
89229
|
"Localized remote media source(s)"
|
|
89090
89230
|
);
|
|
@@ -89099,7 +89239,7 @@ async function localizeRemoteImageSources(html, downloadDir) {
|
|
|
89099
89239
|
return downloadAndRewriteUrls(
|
|
89100
89240
|
urlSet,
|
|
89101
89241
|
html,
|
|
89102
|
-
|
|
89242
|
+
join27(downloadDir, REMOTE_MEDIA_SUBDIR),
|
|
89103
89243
|
"Remote image download failed",
|
|
89104
89244
|
"Localized remote image source(s)"
|
|
89105
89245
|
);
|
|
@@ -89115,7 +89255,7 @@ async function localizeRemoteBackgroundImages(html, downloadDir) {
|
|
|
89115
89255
|
return downloadAndRewriteUrls(
|
|
89116
89256
|
urlSet,
|
|
89117
89257
|
html,
|
|
89118
|
-
|
|
89258
|
+
join27(downloadDir, REMOTE_MEDIA_SUBDIR),
|
|
89119
89259
|
"Remote background-image download failed",
|
|
89120
89260
|
"Localized remote background-image(s)",
|
|
89121
89261
|
// Quoted url('..')/url("..") are rewritten by downloadAndRewriteUrls' default
|
|
@@ -89250,7 +89390,7 @@ async function localizeRemoteFontFaces(html, downloadDir) {
|
|
|
89250
89390
|
return downloadAndRewriteUrls(
|
|
89251
89391
|
urlSet,
|
|
89252
89392
|
processed,
|
|
89253
|
-
|
|
89393
|
+
join27(downloadDir, REMOTE_MEDIA_SUBDIR),
|
|
89254
89394
|
"Remote font download failed",
|
|
89255
89395
|
"Localized remote font face(s)",
|
|
89256
89396
|
(h, url, relPath) => h.replaceAll(`url(${url})`, `url("${relPath}")`)
|
|
@@ -89828,13 +89968,13 @@ async function runCompileStage(input) {
|
|
|
89828
89968
|
abortSignal
|
|
89829
89969
|
} = input;
|
|
89830
89970
|
const compileStart = Date.now();
|
|
89831
|
-
const compiled = await compileForRender(projectDir, htmlPath,
|
|
89971
|
+
const compiled = await compileForRender(projectDir, htmlPath, join28(workDir, "downloads"), {
|
|
89832
89972
|
log,
|
|
89833
89973
|
failClosedFontFetch: failClosedFontFetch === true,
|
|
89834
89974
|
allowSystemFontCapture,
|
|
89835
89975
|
abortSignal,
|
|
89836
89976
|
variables: input.variables,
|
|
89837
|
-
animatedGifCacheDir: cfg.extractCacheDir ?
|
|
89977
|
+
animatedGifCacheDir: cfg.extractCacheDir ? join28(cfg.extractCacheDir, "animated-gif") : void 0,
|
|
89838
89978
|
ffmpegProcessTimeout: cfg.ffmpegProcessTimeout
|
|
89839
89979
|
});
|
|
89840
89980
|
assertNotAborted();
|
|
@@ -89896,7 +90036,7 @@ async function runCompileStage(input) {
|
|
|
89896
90036
|
};
|
|
89897
90037
|
await preflightCompositionAssetMediaTypes({
|
|
89898
90038
|
projectDir,
|
|
89899
|
-
compiledDir:
|
|
90039
|
+
compiledDir: join28(workDir, "compiled"),
|
|
89900
90040
|
composition,
|
|
89901
90041
|
signal: abortSignal
|
|
89902
90042
|
});
|
|
@@ -89944,7 +90084,7 @@ async function runCompileStage(input) {
|
|
|
89944
90084
|
init_esm10();
|
|
89945
90085
|
init_src();
|
|
89946
90086
|
init_dist2();
|
|
89947
|
-
import { join as
|
|
90087
|
+
import { join as join29 } from "path";
|
|
89948
90088
|
|
|
89949
90089
|
// ../producer/src/services/render/stages/probeFailures.ts
|
|
89950
90090
|
var NETWORK_FAILURE_PATTERN = /404|ERR_NAME_NOT_RESOLVED|ERR_CONNECTION_REFUSED|net::ERR_/i;
|
|
@@ -90045,7 +90185,7 @@ async function runProbeStage(input) {
|
|
|
90045
90185
|
});
|
|
90046
90186
|
fileServer = await createFileServer2({
|
|
90047
90187
|
projectDir,
|
|
90048
|
-
compiledDir:
|
|
90188
|
+
compiledDir: join29(workDir, "compiled"),
|
|
90049
90189
|
port: 0,
|
|
90050
90190
|
preHeadScripts: [VIRTUAL_TIME_SHIM],
|
|
90051
90191
|
fps: job.config.fps
|
|
@@ -90067,7 +90207,7 @@ async function runProbeStage(input) {
|
|
|
90067
90207
|
log.info("Creating capture session...", { attempt, maxAttempts: PROBE_MAX_ATTEMPTS });
|
|
90068
90208
|
probeSession = await createCaptureSession(
|
|
90069
90209
|
fileServer.url,
|
|
90070
|
-
|
|
90210
|
+
join29(workDir, "probe"),
|
|
90071
90211
|
captureOpts,
|
|
90072
90212
|
null,
|
|
90073
90213
|
probeCfg
|
|
@@ -90152,7 +90292,7 @@ async function runProbeStage(input) {
|
|
|
90152
90292
|
});
|
|
90153
90293
|
probeSession = await createCaptureSession(
|
|
90154
90294
|
fileServer.url,
|
|
90155
|
-
|
|
90295
|
+
join29(workDir, "probe-screenshot"),
|
|
90156
90296
|
captureOpts,
|
|
90157
90297
|
null,
|
|
90158
90298
|
{ ...probeCfg, forceScreenshot: true }
|
|
@@ -90188,7 +90328,7 @@ async function runProbeStage(input) {
|
|
|
90188
90328
|
compiled,
|
|
90189
90329
|
resolutions,
|
|
90190
90330
|
projectDir,
|
|
90191
|
-
|
|
90331
|
+
join29(workDir, "downloads")
|
|
90192
90332
|
);
|
|
90193
90333
|
assertNotAborted();
|
|
90194
90334
|
composition.videos = compiled.videos;
|
|
@@ -90359,7 +90499,7 @@ async function runProbeStage(input) {
|
|
|
90359
90499
|
try {
|
|
90360
90500
|
await preflightCompositionAssetMediaTypes({
|
|
90361
90501
|
projectDir,
|
|
90362
|
-
compiledDir:
|
|
90502
|
+
compiledDir: join29(workDir, "compiled"),
|
|
90363
90503
|
composition,
|
|
90364
90504
|
signal: abortSignal
|
|
90365
90505
|
});
|
|
@@ -90487,7 +90627,7 @@ function validateRenderDuration(input) {
|
|
|
90487
90627
|
// ../producer/src/services/render/stages/extractVideosStage.ts
|
|
90488
90628
|
init_src();
|
|
90489
90629
|
import { existsSync as existsSync26 } from "fs";
|
|
90490
|
-
import { join as
|
|
90630
|
+
import { join as join30 } from "path";
|
|
90491
90631
|
function shouldCopyExtractedFrames(platform3) {
|
|
90492
90632
|
return platform3 === "win32";
|
|
90493
90633
|
}
|
|
@@ -90668,7 +90808,7 @@ async function runExtractVideosStage(input) {
|
|
|
90668
90808
|
// because short boundary counts can differ by one frame.
|
|
90669
90809
|
{
|
|
90670
90810
|
fps: job.config.fps,
|
|
90671
|
-
outputDir:
|
|
90811
|
+
outputDir: join30(compiledDir, "__hyperframes_video_frames"),
|
|
90672
90812
|
format: job.config.videoFrameFormat ?? "auto",
|
|
90673
90813
|
timelineEnd: composition.duration,
|
|
90674
90814
|
maxTransientRetries: extractionPolicy.maxTransientRetries,
|
|
@@ -90732,7 +90872,7 @@ function appendAutoDetectedVideoAudio(composition, extracted) {
|
|
|
90732
90872
|
|
|
90733
90873
|
// ../producer/src/services/render/stages/audioStage.ts
|
|
90734
90874
|
init_src();
|
|
90735
|
-
import { join as
|
|
90875
|
+
import { join as join31 } from "path";
|
|
90736
90876
|
async function runAudioStage(input) {
|
|
90737
90877
|
const {
|
|
90738
90878
|
projectDir,
|
|
@@ -90747,7 +90887,7 @@ async function runAudioStage(input) {
|
|
|
90747
90887
|
log
|
|
90748
90888
|
} = input;
|
|
90749
90889
|
const stage3Start = Date.now();
|
|
90750
|
-
const audioOutputPath =
|
|
90890
|
+
const audioOutputPath = join31(workDir, MIXED_AUDIO_FILENAME);
|
|
90751
90891
|
let hasAudio = false;
|
|
90752
90892
|
let audioError;
|
|
90753
90893
|
let audioFailures;
|
|
@@ -90757,7 +90897,7 @@ async function runAudioStage(input) {
|
|
|
90757
90897
|
audioResult = await processCompositionAudio(
|
|
90758
90898
|
audios,
|
|
90759
90899
|
projectDir,
|
|
90760
|
-
|
|
90900
|
+
join31(workDir, "audio-work"),
|
|
90761
90901
|
audioOutputPath,
|
|
90762
90902
|
duration,
|
|
90763
90903
|
abortSignal,
|
|
@@ -90991,7 +91131,7 @@ async function runCaptureStage(input) {
|
|
|
90991
91131
|
init_src();
|
|
90992
91132
|
import { mkdtemp as mkdtemp2, writeFile as writeFile2 } from "fs/promises";
|
|
90993
91133
|
import { tmpdir as tmpdir6 } from "os";
|
|
90994
|
-
import { join as
|
|
91134
|
+
import { join as join34 } from "path";
|
|
90995
91135
|
|
|
90996
91136
|
// ../producer/src/services/render/stages/captureHdrFrameShared.ts
|
|
90997
91137
|
init_src();
|
|
@@ -90999,7 +91139,7 @@ init_src();
|
|
|
90999
91139
|
// ../producer/src/services/hdrCompositor.ts
|
|
91000
91140
|
init_src();
|
|
91001
91141
|
import { readSync as readSync2, closeSync as closeSync4 } from "fs";
|
|
91002
|
-
import { join as
|
|
91142
|
+
import { join as join32 } from "path";
|
|
91003
91143
|
function countNonZeroAlpha(rgba) {
|
|
91004
91144
|
let n = 0;
|
|
91005
91145
|
for (let p = 3; p < rgba.length; p += 4) {
|
|
@@ -91405,7 +91545,7 @@ async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter,
|
|
|
91405
91545
|
if (shouldLog && debugDumpDir) {
|
|
91406
91546
|
const after2 = countNonZeroRgb48(canvas);
|
|
91407
91547
|
const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
|
|
91408
|
-
const dumpPath =
|
|
91548
|
+
const dumpPath = join32(debugDumpDir, dumpName);
|
|
91409
91549
|
writeFileExclusiveSync(dumpPath, domPng);
|
|
91410
91550
|
log.info("[diag] dom layer blit", {
|
|
91411
91551
|
frame: debugFrameIndex,
|
|
@@ -91453,7 +91593,7 @@ import {
|
|
|
91453
91593
|
rmSync as rmSync10,
|
|
91454
91594
|
statfsSync
|
|
91455
91595
|
} from "fs";
|
|
91456
|
-
import { join as
|
|
91596
|
+
import { join as join33 } from "path";
|
|
91457
91597
|
var NO_FOLLOW_FLAG = constants2.O_NOFOLLOW ?? 0;
|
|
91458
91598
|
function tempDirSafePrefix(id) {
|
|
91459
91599
|
const safe = id.replace(/[^A-Za-z0-9_.-]/g, "_").slice(0, 80);
|
|
@@ -91697,10 +91837,10 @@ async function extractHdrVideoFrames(args) {
|
|
|
91697
91837
|
const window3 = extractionWindows.get(videoId);
|
|
91698
91838
|
if (!video || !window3) continue;
|
|
91699
91839
|
mkdirSync14(framesDir, { recursive: true });
|
|
91700
|
-
const frameDir = mkdtempSync6(
|
|
91840
|
+
const frameDir = mkdtempSync6(join33(framesDir, `hdr_${tempDirSafePrefix(videoId)}-`));
|
|
91701
91841
|
createdFrameDirs.add(frameDir);
|
|
91702
91842
|
const dims = prep.hdrExtractionDims.get(videoId) ?? { width, height };
|
|
91703
|
-
const rawPath =
|
|
91843
|
+
const rawPath = join33(frameDir, "frames.rgb48le");
|
|
91704
91844
|
const extractionStart = String(window3.extractionMediaStart ?? window3.mediaStart);
|
|
91705
91845
|
const ffmpegArgs = [];
|
|
91706
91846
|
if (window3.finalFrameOnly) {
|
|
@@ -92161,11 +92301,11 @@ function createDrainFrameGuard(args) {
|
|
|
92161
92301
|
return buf;
|
|
92162
92302
|
}
|
|
92163
92303
|
if (db < verifyMinDb) {
|
|
92164
|
-
const dumpDir = await mkdtemp2(
|
|
92304
|
+
const dumpDir = await mkdtemp2(join34(tmpdir6(), "hf-de-verify-fail-")).catch(() => null);
|
|
92165
92305
|
if (dumpDir) {
|
|
92166
92306
|
await Promise.all([
|
|
92167
|
-
writeFile2(
|
|
92168
|
-
writeFile2(
|
|
92307
|
+
writeFile2(join34(dumpDir, `frame-${idx}-de.jpg`), buf),
|
|
92308
|
+
writeFile2(join34(dumpDir, `frame-${idx}-truth.jpg`), truth)
|
|
92169
92309
|
]).catch(() => {
|
|
92170
92310
|
});
|
|
92171
92311
|
}
|
|
@@ -92560,7 +92700,7 @@ async function runCaptureStreamingStage(input) {
|
|
|
92560
92700
|
init_src();
|
|
92561
92701
|
init_dist2();
|
|
92562
92702
|
import { existsSync as existsSync28, mkdirSync as mkdirSync15 } from "fs";
|
|
92563
|
-
import { join as
|
|
92703
|
+
import { join as join38 } from "path";
|
|
92564
92704
|
|
|
92565
92705
|
// ../producer/src/services/hdrImageTransferCache.ts
|
|
92566
92706
|
init_src();
|
|
@@ -92624,7 +92764,7 @@ function createHdrImageTransferCache(options = {}) {
|
|
|
92624
92764
|
|
|
92625
92765
|
// ../producer/src/services/render/stages/captureHdrSequentialLoop.ts
|
|
92626
92766
|
init_src();
|
|
92627
|
-
import { join as
|
|
92767
|
+
import { join as join35 } from "path";
|
|
92628
92768
|
async function runSequentialLayeredFrameLoop(input) {
|
|
92629
92769
|
const {
|
|
92630
92770
|
job,
|
|
@@ -92745,7 +92885,7 @@ async function runSequentialLayeredFrameLoop(input) {
|
|
|
92745
92885
|
);
|
|
92746
92886
|
if (debugDumpEnabled && debugDumpDir && i % 30 === 0) {
|
|
92747
92887
|
writeFileExclusiveSync(
|
|
92748
|
-
|
|
92888
|
+
join35(debugDumpDir, `frame_${String(i).padStart(4, "0")}_final_rgb48le.bin`),
|
|
92749
92889
|
normalCanvas
|
|
92750
92890
|
);
|
|
92751
92891
|
}
|
|
@@ -92780,12 +92920,12 @@ async function runSequentialLayeredFrameLoop(input) {
|
|
|
92780
92920
|
|
|
92781
92921
|
// ../producer/src/services/render/stages/captureHdrHybridLoop.ts
|
|
92782
92922
|
init_src();
|
|
92783
|
-
import { join as
|
|
92923
|
+
import { join as join37 } from "path";
|
|
92784
92924
|
|
|
92785
92925
|
// ../producer/src/services/shaderTransitionWorkerPool.ts
|
|
92786
92926
|
import { Worker as Worker2 } from "worker_threads";
|
|
92787
92927
|
import { fileURLToPath as fileURLToPath4, pathToFileURL as pathToFileURL2 } from "url";
|
|
92788
|
-
import { dirname as dirname14, join as
|
|
92928
|
+
import { dirname as dirname14, join as join36 } from "path";
|
|
92789
92929
|
import { createRequire as createRequire2 } from "module";
|
|
92790
92930
|
import { existsSync as existsSync27 } from "fs";
|
|
92791
92931
|
import { cpus as cpus3 } from "os";
|
|
@@ -92799,9 +92939,9 @@ function resolveWorkerEntry(explicit) {
|
|
|
92799
92939
|
return { path: override, isTs };
|
|
92800
92940
|
}
|
|
92801
92941
|
const moduleDir = dirname14(fileURLToPath4(import.meta.url));
|
|
92802
|
-
const jsPath =
|
|
92942
|
+
const jsPath = join36(moduleDir, "shaderTransitionWorker.js");
|
|
92803
92943
|
if (existsSync27(jsPath)) return { path: jsPath, isTs: false };
|
|
92804
|
-
const tsPath =
|
|
92944
|
+
const tsPath = join36(moduleDir, "shaderTransitionWorker.ts");
|
|
92805
92945
|
return { path: tsPath, isTs: true };
|
|
92806
92946
|
}
|
|
92807
92947
|
function buildExecArgv(entryIsTs) {
|
|
@@ -93171,7 +93311,7 @@ async function runHybridLayeredFrameLoop(input) {
|
|
|
93171
93311
|
);
|
|
93172
93312
|
if (debugDumpEnabled && debugDumpDir && i % 30 === 0) {
|
|
93173
93313
|
writeFileExclusiveSync(
|
|
93174
|
-
|
|
93314
|
+
join37(debugDumpDir, `frame_${String(i).padStart(4, "0")}_final_rgb48le.bin`),
|
|
93175
93315
|
canvas
|
|
93176
93316
|
);
|
|
93177
93317
|
}
|
|
@@ -93357,7 +93497,7 @@ async function runCaptureHdrStage(input) {
|
|
|
93357
93497
|
if (hdrVideoFrameSources.has(v.id)) hdrVideoEndTimes.set(v.id, v.end);
|
|
93358
93498
|
}
|
|
93359
93499
|
const debugDumpEnabled = process.env.KEEP_TEMP === "1";
|
|
93360
|
-
const debugDumpDir = debugDumpEnabled ?
|
|
93500
|
+
const debugDumpDir = debugDumpEnabled ? join38(framesDir, "debug-composite") : null;
|
|
93361
93501
|
if (debugDumpDir && !existsSync28(debugDumpDir)) {
|
|
93362
93502
|
mkdirSync15(debugDumpDir, { recursive: true });
|
|
93363
93503
|
}
|
|
@@ -93509,10 +93649,10 @@ async function runCaptureHdrStage(input) {
|
|
|
93509
93649
|
// ../producer/src/services/render/stages/encodeStage.ts
|
|
93510
93650
|
init_src();
|
|
93511
93651
|
import { copyFileSync as copyFileSync5, existsSync as existsSync29, mkdirSync as mkdirSync16, readdirSync as readdirSync10, rmSync as rmSync11, statSync as statSync9 } from "fs";
|
|
93512
|
-
import { dirname as dirname15, join as
|
|
93652
|
+
import { dirname as dirname15, join as join40 } from "path";
|
|
93513
93653
|
|
|
93514
93654
|
// ../producer/src/services/render/stages/gifEncodeArgs.ts
|
|
93515
|
-
import { join as
|
|
93655
|
+
import { join as join39 } from "path";
|
|
93516
93656
|
function fpsToFfmpegArg2(fps) {
|
|
93517
93657
|
return fps.den === 1 ? String(fps.num) : `${fps.num}/${fps.den}`;
|
|
93518
93658
|
}
|
|
@@ -93524,7 +93664,7 @@ function buildGifPalettegenArgs(input) {
|
|
|
93524
93664
|
"-framerate",
|
|
93525
93665
|
fpsArg,
|
|
93526
93666
|
"-i",
|
|
93527
|
-
|
|
93667
|
+
join39(input.framesDir, input.framePattern),
|
|
93528
93668
|
"-vf",
|
|
93529
93669
|
`fps=${fpsArg},palettegen=stats_mode=diff${transparency}`,
|
|
93530
93670
|
input.palettePath
|
|
@@ -93538,7 +93678,7 @@ function buildGifPaletteuseArgs(input) {
|
|
|
93538
93678
|
"-framerate",
|
|
93539
93679
|
fpsArg,
|
|
93540
93680
|
"-i",
|
|
93541
|
-
|
|
93681
|
+
join39(input.framesDir, input.framePattern),
|
|
93542
93682
|
"-i",
|
|
93543
93683
|
input.palettePath,
|
|
93544
93684
|
"-lavfi",
|
|
@@ -93655,11 +93795,11 @@ async function runEncodeStage(input) {
|
|
|
93655
93795
|
);
|
|
93656
93796
|
}
|
|
93657
93797
|
captured.forEach((name, i) => {
|
|
93658
|
-
const dst =
|
|
93659
|
-
copyFileSync5(
|
|
93798
|
+
const dst = join40(outputPath, formatExportFrameName(i, "png"));
|
|
93799
|
+
copyFileSync5(join40(framesDir, name), dst);
|
|
93660
93800
|
});
|
|
93661
93801
|
if (hasAudio && audioOutputPath && existsSync29(audioOutputPath)) {
|
|
93662
|
-
copyFileSync5(audioOutputPath,
|
|
93802
|
+
copyFileSync5(audioOutputPath, join40(outputPath, MIXED_AUDIO_FILENAME));
|
|
93663
93803
|
log.info(
|
|
93664
93804
|
`[Render] png-sequence: ${MIXED_AUDIO_FILENAME} sidecar written to ${outputPath}/${MIXED_AUDIO_FILENAME}`
|
|
93665
93805
|
);
|
|
@@ -93678,7 +93818,7 @@ async function runEncodeStage(input) {
|
|
|
93678
93818
|
const encodeResult2 = await encodeGifFromDir(framesDir, framePattern2, outputPath, {
|
|
93679
93819
|
fps: job.config.fps,
|
|
93680
93820
|
loop,
|
|
93681
|
-
palettePath:
|
|
93821
|
+
palettePath: join40(dirname15(videoOnlyPath), "gif-palette.png"),
|
|
93682
93822
|
preserveAlpha: needsAlpha,
|
|
93683
93823
|
signal: abortSignal,
|
|
93684
93824
|
timeout: engineCfg.ffmpegEncodeTimeout
|
|
@@ -94044,8 +94184,7 @@ async function runAssembleStage(input) {
|
|
|
94044
94184
|
outputPath,
|
|
94045
94185
|
abortSignal,
|
|
94046
94186
|
{
|
|
94047
|
-
audioCodec: "aac"
|
|
94048
|
-
preserveAudioPrimingEditList: normalizeResult.operation !== "copy"
|
|
94187
|
+
audioCodec: "aac"
|
|
94049
94188
|
},
|
|
94050
94189
|
job.config.fps
|
|
94051
94190
|
);
|
|
@@ -94083,7 +94222,7 @@ function sampleDirectoryBytes(dir) {
|
|
|
94083
94222
|
continue;
|
|
94084
94223
|
}
|
|
94085
94224
|
for (const name of entries2) {
|
|
94086
|
-
const full =
|
|
94225
|
+
const full = join41(current2, name);
|
|
94087
94226
|
try {
|
|
94088
94227
|
const st = statSync10(full);
|
|
94089
94228
|
if (st.isDirectory()) {
|
|
@@ -94228,7 +94367,7 @@ function findMissingFrameRanges(totalFrames, framesDir, frameExt) {
|
|
|
94228
94367
|
const ranges = [];
|
|
94229
94368
|
let rangeStart = null;
|
|
94230
94369
|
for (let frameIndex = 0; frameIndex < totalFrames; frameIndex++) {
|
|
94231
|
-
const framePath =
|
|
94370
|
+
const framePath = join41(framesDir, formatCaptureFrameName(frameIndex, frameExt));
|
|
94232
94371
|
const missing = !existsSync30(framePath) || statSync10(framePath).size <= 8;
|
|
94233
94372
|
if (missing && rangeStart === null) {
|
|
94234
94373
|
rangeStart = frameIndex;
|
|
@@ -94251,7 +94390,7 @@ function buildMissingFrameRetryBatches(ranges, maxWorkers, workDir, attempt, ran
|
|
|
94251
94390
|
workerId,
|
|
94252
94391
|
startFrame: rangeStart + range.startFrame,
|
|
94253
94392
|
endFrame: rangeStart + range.endFrame,
|
|
94254
|
-
outputDir:
|
|
94393
|
+
outputDir: join41(workDir, `retry-${attempt}-batch-${batchIndex}-worker-${workerId}`),
|
|
94255
94394
|
outputFrameOffset: rangeStart
|
|
94256
94395
|
}));
|
|
94257
94396
|
batches.push(batch);
|
|
@@ -94274,8 +94413,8 @@ function getNextRetryWorkerCount(currentWorkers) {
|
|
|
94274
94413
|
return Math.max(1, Math.floor(currentWorkers / 2));
|
|
94275
94414
|
}
|
|
94276
94415
|
function resolveRenderWorkDirPrefix(outputPath, jobId, platform3 = process.platform, systemTempDir = tmpdir7()) {
|
|
94277
|
-
if (platform3 === "win32") return
|
|
94278
|
-
return
|
|
94416
|
+
if (platform3 === "win32") return join41(systemTempDir, "hf-render-");
|
|
94417
|
+
return join41(dirname16(outputPath), `work-${jobId}-`);
|
|
94279
94418
|
}
|
|
94280
94419
|
var MAX_TRANSIENT_CAPTURE_RETRIES = 1;
|
|
94281
94420
|
function captureAttemptMadeProgress(attemptTargetFrameCount, remainingFrameCount) {
|
|
@@ -94304,7 +94443,7 @@ The composition is too large for the available memory. To reduce memory pressure
|
|
|
94304
94443
|
function countCapturedFrames(totalFrames, framesDir, frameExt) {
|
|
94305
94444
|
let captured = 0;
|
|
94306
94445
|
for (let frameIndex = 0; frameIndex < totalFrames; frameIndex++) {
|
|
94307
|
-
const framePath =
|
|
94446
|
+
const framePath = join41(framesDir, formatCaptureFrameName(frameIndex, frameExt));
|
|
94308
94447
|
if (existsSync30(framePath)) captured++;
|
|
94309
94448
|
}
|
|
94310
94449
|
return captured;
|
|
@@ -94329,7 +94468,7 @@ async function executeDiskCaptureWithAdaptiveRetry(options) {
|
|
|
94329
94468
|
reason: attempt === 0 ? "initial" : pendingTransientRetry ? "transient-retry" : "retry"
|
|
94330
94469
|
});
|
|
94331
94470
|
pendingTransientRetry = false;
|
|
94332
|
-
const attemptWorkDir =
|
|
94471
|
+
const attemptWorkDir = join41(options.workDir, `capture-attempt-${attempt}`);
|
|
94333
94472
|
const batches = missingRanges ? buildMissingFrameRetryBatches(
|
|
94334
94473
|
missingRanges,
|
|
94335
94474
|
currentWorkers,
|
|
@@ -94668,13 +94807,13 @@ function deVerifyFallbackTelemetry(err) {
|
|
|
94668
94807
|
async function executeRenderJob(job, projectDir, outputPath, progressSink, abortSignal) {
|
|
94669
94808
|
const moduleDir = dirname16(fileURLToPath5(import.meta.url));
|
|
94670
94809
|
const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve13(process.env.PRODUCER_RENDERS_DIR, "..") : resolve13(moduleDir, "../..");
|
|
94671
|
-
const debugDir =
|
|
94810
|
+
const debugDir = join41(producerRoot, ".debug");
|
|
94672
94811
|
const outputDir = dirname16(outputPath);
|
|
94673
94812
|
if (!existsSync30(outputDir)) mkdirSync17(outputDir, { recursive: true });
|
|
94674
|
-
const workDir = job.config.debug ?
|
|
94813
|
+
const workDir = job.config.debug ? join41(debugDir, job.id) : mkdtempSync7(resolveRenderWorkDirPrefix(outputPath, job.id));
|
|
94675
94814
|
const pipelineStart = Date.now();
|
|
94676
94815
|
const baseLog = job.config.logger ?? defaultLogger;
|
|
94677
|
-
const logPath = job.config.debug ?
|
|
94816
|
+
const logPath = job.config.debug ? join41(workDir, "render.log") : null;
|
|
94678
94817
|
const execution = new RenderExecutionContext({
|
|
94679
94818
|
request: { renderJobId: job.id, projectDir, outputPath },
|
|
94680
94819
|
logger: logPath ? createRenderFileLogger(logPath, baseLog) : baseLog,
|
|
@@ -94722,7 +94861,7 @@ async function executeRenderPipeline(input) {
|
|
|
94722
94861
|
imageDecodeFailures: 0
|
|
94723
94862
|
};
|
|
94724
94863
|
let hdrPerf;
|
|
94725
|
-
const perfOutputPath =
|
|
94864
|
+
const perfOutputPath = join41(workDir, "perf-summary.json");
|
|
94726
94865
|
const cfg = { ...job.config.producerConfig ?? resolveConfig() };
|
|
94727
94866
|
const observability = new RenderObservabilityRecorder({
|
|
94728
94867
|
pipelineStartMs: pipelineStart,
|
|
@@ -94814,15 +94953,15 @@ async function executeRenderPipeline(input) {
|
|
|
94814
94953
|
requestedWorkers: job.config.workers ?? "auto"
|
|
94815
94954
|
});
|
|
94816
94955
|
const entryFile = job.config.entryFile || "index.html";
|
|
94817
|
-
let htmlPath =
|
|
94956
|
+
let htmlPath = join41(projectDir, entryFile);
|
|
94818
94957
|
if (!existsSync30(htmlPath)) {
|
|
94819
94958
|
throw new Error(`Entry file not found: ${htmlPath}`);
|
|
94820
94959
|
}
|
|
94821
94960
|
assertNotAborted();
|
|
94822
94961
|
const rawEntry = readFileSync12(htmlPath, "utf-8");
|
|
94823
94962
|
if (entryFile !== "index.html" && rawEntry.trimStart().startsWith("<template")) {
|
|
94824
|
-
const wrapperPath =
|
|
94825
|
-
const projectIndexPath =
|
|
94963
|
+
const wrapperPath = join41(workDir, "standalone-entry.html");
|
|
94964
|
+
const projectIndexPath = join41(projectDir, "index.html");
|
|
94826
94965
|
if (!existsSync30(projectIndexPath)) {
|
|
94827
94966
|
throw new Error(
|
|
94828
94967
|
`Template entry file "${entryFile}" requires a project index.html to extract its render shell.`
|
|
@@ -94977,7 +95116,7 @@ async function executeRenderPipeline(input) {
|
|
|
94977
95116
|
beginFrameStalled: probeResult.beginFrameStalled
|
|
94978
95117
|
});
|
|
94979
95118
|
updateJobStatus(job, "preprocessing", "Extracting video frames", 10, onProgress);
|
|
94980
|
-
const compiledDir =
|
|
95119
|
+
const compiledDir = join41(workDir, "compiled");
|
|
94981
95120
|
const extractResult = await observeRenderStage(
|
|
94982
95121
|
observability,
|
|
94983
95122
|
"video_extract",
|
|
@@ -95097,7 +95236,7 @@ async function executeRenderPipeline(input) {
|
|
|
95097
95236
|
try {
|
|
95098
95237
|
fileServer = await createFileServer2({
|
|
95099
95238
|
projectDir,
|
|
95100
|
-
compiledDir:
|
|
95239
|
+
compiledDir: join41(workDir, "compiled"),
|
|
95101
95240
|
port: 0,
|
|
95102
95241
|
preHeadScripts: [VIRTUAL_TIME_SHIM],
|
|
95103
95242
|
fps: job.config.fps
|
|
@@ -95115,7 +95254,7 @@ async function executeRenderPipeline(input) {
|
|
|
95115
95254
|
if (!activeFileServer) {
|
|
95116
95255
|
throw new Error("File server failed to initialize before frame capture");
|
|
95117
95256
|
}
|
|
95118
|
-
const framesDir =
|
|
95257
|
+
const framesDir = join41(workDir, "captured-frames");
|
|
95119
95258
|
if (!existsSync30(framesDir)) mkdirSync17(framesDir, { recursive: true });
|
|
95120
95259
|
const resolvedBrowserGpuMode = await resolveBrowserGpuMode(cfg.browserGpuMode, {
|
|
95121
95260
|
chromePath: resolveHeadlessShellPath(cfg),
|
|
@@ -95440,7 +95579,7 @@ async function executeRenderPipeline(input) {
|
|
|
95440
95579
|
gif: ".gif"
|
|
95441
95580
|
};
|
|
95442
95581
|
const videoExt = FORMAT_EXT[outputFormat] ?? ".mp4";
|
|
95443
|
-
const videoOnlyPath =
|
|
95582
|
+
const videoOnlyPath = join41(workDir, `video-only${videoExt}`);
|
|
95444
95583
|
const usePageSideCompositingForTransitions = (cfg.enablePageSideCompositing || isGif) && compiled.hasShaderTransitions && !hasHdrContent && outputSupportsPageSideShaderCompositing(outputFormat);
|
|
95445
95584
|
if (usePageSideCompositingForTransitions) {
|
|
95446
95585
|
activeFileServer.addPreHeadScript(HF_PAGE_SIDE_COMPOSITING_STUB);
|
|
@@ -96026,7 +96165,7 @@ async function executeRenderPipeline(input) {
|
|
|
96026
96165
|
}
|
|
96027
96166
|
if (job.config.debug) {
|
|
96028
96167
|
if (!isPngSequence && existsSync30(stagedOutputPath)) {
|
|
96029
|
-
const debugOutput =
|
|
96168
|
+
const debugOutput = join41(workDir, `output${videoExt}`);
|
|
96030
96169
|
copyFileSync6(stagedOutputPath, debugOutput);
|
|
96031
96170
|
}
|
|
96032
96171
|
}
|
|
@@ -96363,7 +96502,7 @@ import {
|
|
|
96363
96502
|
rmSync as rmSync14,
|
|
96364
96503
|
createReadStream as createReadStream5
|
|
96365
96504
|
} from "fs";
|
|
96366
|
-
import { resolve as resolve15, dirname as dirname18, join as
|
|
96505
|
+
import { resolve as resolve15, dirname as dirname18, join as join44 } from "path";
|
|
96367
96506
|
import { tmpdir as tmpdir8 } from "os";
|
|
96368
96507
|
import { parseArgs } from "util";
|
|
96369
96508
|
import crypto from "crypto";
|
|
@@ -96374,7 +96513,7 @@ import { serve as serve3 } from "@hono/node-server";
|
|
|
96374
96513
|
// ../producer/src/services/hyperframeLint.ts
|
|
96375
96514
|
init_dist3();
|
|
96376
96515
|
import { existsSync as existsSync31, readFileSync as readFileSync13, statSync as statSync11 } from "fs";
|
|
96377
|
-
import { resolve as resolve14, join as
|
|
96516
|
+
import { resolve as resolve14, join as join42 } from "path";
|
|
96378
96517
|
function isStringRecord(value) {
|
|
96379
96518
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
96380
96519
|
return false;
|
|
@@ -96422,7 +96561,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
|
96422
96561
|
}
|
|
96423
96562
|
}
|
|
96424
96563
|
return {
|
|
96425
|
-
error: `No HTML entry file found in project directory: ${
|
|
96564
|
+
error: `No HTML entry file found in project directory: ${join42(absProjectDir, preferredEntryFile || "index.html")}`
|
|
96426
96565
|
};
|
|
96427
96566
|
}
|
|
96428
96567
|
function prepareHyperframeLintBody(body) {
|
|
@@ -96465,7 +96604,7 @@ async function runHyperframeLint(prepared) {
|
|
|
96465
96604
|
// ../producer/src/services/healthWorker.ts
|
|
96466
96605
|
import { Worker as Worker3 } from "worker_threads";
|
|
96467
96606
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
96468
|
-
import { dirname as dirname17, join as
|
|
96607
|
+
import { dirname as dirname17, join as join43 } from "path";
|
|
96469
96608
|
import { existsSync as existsSync32 } from "fs";
|
|
96470
96609
|
var DEFAULT_HEALTH_PORT = 9848;
|
|
96471
96610
|
async function startHealthWorker(options = {}) {
|
|
@@ -96541,7 +96680,7 @@ function defaultLogger2() {
|
|
|
96541
96680
|
}
|
|
96542
96681
|
function resolveWorkerEntry2() {
|
|
96543
96682
|
const here = dirname17(fileURLToPath6(import.meta.url));
|
|
96544
|
-
const candidates = [
|
|
96683
|
+
const candidates = [join43(here, "healthWorkerThread.js"), join43(here, "healthWorkerThread.ts")];
|
|
96545
96684
|
for (const candidate of candidates) {
|
|
96546
96685
|
if (existsSync32(candidate)) return candidate;
|
|
96547
96686
|
}
|
|
@@ -96743,8 +96882,8 @@ async function resolveInlineRenderHtml(body) {
|
|
|
96743
96882
|
}
|
|
96744
96883
|
function materializeInlineProject(html, options) {
|
|
96745
96884
|
const tempRoot = process.env.PRODUCER_TMP_PROJECT_DIR || tmpdir8();
|
|
96746
|
-
const tempProjectDir = mkdtempSync8(
|
|
96747
|
-
writeFileSync11(
|
|
96885
|
+
const tempProjectDir = mkdtempSync8(join44(tempRoot, "producer-project-"));
|
|
96886
|
+
writeFileSync11(join44(tempProjectDir, "index.html"), html, "utf-8");
|
|
96748
96887
|
return {
|
|
96749
96888
|
prepared: {
|
|
96750
96889
|
input: { projectDir: tempProjectDir, ...options },
|
|
@@ -97193,11 +97332,11 @@ init_src();
|
|
|
97193
97332
|
init_dist2();
|
|
97194
97333
|
init_src();
|
|
97195
97334
|
import { cpSync as cpSync2, existsSync as existsSync36, mkdirSync as mkdirSync20, renameSync as renameSync6, rmSync as rmSync15, writeFileSync as writeFileSync13 } from "fs";
|
|
97196
|
-
import { join as
|
|
97335
|
+
import { join as join48, relative as relative4, sep as sep4 } from "path";
|
|
97197
97336
|
|
|
97198
97337
|
// ../producer/src/services/render/stages/freezePlan.ts
|
|
97199
97338
|
import { existsSync as existsSync34, mkdirSync as mkdirSync19, readFileSync as readFileSync14, readdirSync as readdirSync12, writeFileSync as writeFileSync12 } from "fs";
|
|
97200
|
-
import { join as
|
|
97339
|
+
import { join as join45, relative as relative2, resolve as resolve16 } from "path";
|
|
97201
97340
|
|
|
97202
97341
|
// ../producer/src/services/distributed/planProtocol.ts
|
|
97203
97342
|
var PLAN_SCHEMA_VERSION = 1;
|
|
@@ -97239,7 +97378,7 @@ var FIELD_DELIMITER = Buffer.from([0]);
|
|
|
97239
97378
|
// ../producer/src/services/distributed/shared.ts
|
|
97240
97379
|
init_src();
|
|
97241
97380
|
import { execFile as execFileCallback } from "child_process";
|
|
97242
|
-
import { dirname as dirname19, join as
|
|
97381
|
+
import { dirname as dirname19, join as join46 } from "path";
|
|
97243
97382
|
import { existsSync as existsSync35, readFileSync as readFileSync15 } from "fs";
|
|
97244
97383
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
97245
97384
|
import { promisify as promisify3 } from "util";
|
|
@@ -97249,7 +97388,7 @@ var execFile3 = promisify3(execFileCallback);
|
|
|
97249
97388
|
// ../producer/src/services/distributed/planSize.ts
|
|
97250
97389
|
import { createHash as createHash10 } from "crypto";
|
|
97251
97390
|
import { lstatSync as lstatSync4, readdirSync as readdirSync13 } from "fs";
|
|
97252
|
-
import { extname as extname7, join as
|
|
97391
|
+
import { extname as extname7, join as join47, relative as relative3 } from "path";
|
|
97253
97392
|
var PLAN_ROOT_CATEGORY = {
|
|
97254
97393
|
compiled: "compiled",
|
|
97255
97394
|
[PLAN_AUDIO_RELATIVE_PATH]: "audio",
|
|
@@ -97261,9 +97400,9 @@ var PLAN_ROOT_CATEGORY = {
|
|
|
97261
97400
|
var PLAN_DIR_SIZE_LIMIT_BYTES = 2 * 1024 * 1024 * 1024;
|
|
97262
97401
|
var FREEZE_OWNED_PLAN_FILES = [
|
|
97263
97402
|
"plan.json",
|
|
97264
|
-
|
|
97265
|
-
|
|
97266
|
-
|
|
97403
|
+
join48("meta", "composition.json"),
|
|
97404
|
+
join48("meta", "encoder.json"),
|
|
97405
|
+
join48("meta", "chunks.json")
|
|
97267
97406
|
];
|
|
97268
97407
|
|
|
97269
97408
|
// ../producer/src/services/distributed/planV2.ts
|
|
@@ -97286,7 +97425,7 @@ import {
|
|
|
97286
97425
|
} from "fs";
|
|
97287
97426
|
import { createHash as createHash11 } from "crypto";
|
|
97288
97427
|
import { tmpdir as tmpdir9 } from "os";
|
|
97289
|
-
import { dirname as dirname21, isAbsolute as isAbsolute4, join as
|
|
97428
|
+
import { dirname as dirname21, isAbsolute as isAbsolute4, join as join51, relative as relative5, resolve as resolve17, sep as sep5 } from "path";
|
|
97290
97429
|
|
|
97291
97430
|
// ../producer/src/services/distributed/planV2Publisher.ts
|
|
97292
97431
|
import {
|
|
@@ -97300,15 +97439,15 @@ import {
|
|
|
97300
97439
|
statSync as statSync13,
|
|
97301
97440
|
writeFileSync as writeFileSync14
|
|
97302
97441
|
} from "fs";
|
|
97303
|
-
import { dirname as dirname20, join as
|
|
97442
|
+
import { dirname as dirname20, join as join50 } from "path";
|
|
97304
97443
|
|
|
97305
97444
|
// ../producer/src/services/distributed/planV2Layout.ts
|
|
97306
|
-
import { join as
|
|
97445
|
+
import { join as join49 } from "path";
|
|
97307
97446
|
|
|
97308
97447
|
// ../producer/src/services/distributed/planV2Execution.ts
|
|
97309
97448
|
import { mkdtempSync as mkdtempSync11, rmSync as rmSync20 } from "fs";
|
|
97310
97449
|
import { tmpdir as tmpdir10 } from "os";
|
|
97311
|
-
import { join as
|
|
97450
|
+
import { join as join54 } from "path";
|
|
97312
97451
|
|
|
97313
97452
|
// ../producer/src/services/distributed/assemble.ts
|
|
97314
97453
|
init_src();
|
|
@@ -97323,19 +97462,19 @@ import {
|
|
|
97323
97462
|
statSync as statSync15,
|
|
97324
97463
|
writeFileSync as writeFileSync16
|
|
97325
97464
|
} from "fs";
|
|
97326
|
-
import { dirname as dirname22, join as
|
|
97465
|
+
import { dirname as dirname22, join as join52 } from "path";
|
|
97327
97466
|
|
|
97328
97467
|
// ../producer/src/services/distributed/renderChunk.ts
|
|
97329
97468
|
init_src();
|
|
97330
97469
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
97331
97470
|
import { existsSync as existsSync40, mkdirSync as mkdirSync24, readFileSync as readFileSync18, readdirSync as readdirSync16, rmSync as rmSync19, writeFileSync as writeFileSync17 } from "fs";
|
|
97332
|
-
import { extname as extname8, join as
|
|
97471
|
+
import { extname as extname8, join as join53 } from "path";
|
|
97333
97472
|
init_src();
|
|
97334
97473
|
|
|
97335
97474
|
// ../producer/src/services/distributed/projectHash.ts
|
|
97336
97475
|
import { readdirSync as readdirSync17, readFileSync as readFileSync19 } from "fs";
|
|
97337
97476
|
import { createHash as createHash12 } from "crypto";
|
|
97338
|
-
import { join as
|
|
97477
|
+
import { join as join55, relative as relative6 } from "path";
|
|
97339
97478
|
|
|
97340
97479
|
// src/fontLocalize.ts
|
|
97341
97480
|
function safeVersion(version2) {
|
|
@@ -97376,8 +97515,8 @@ async function runFontLocalize(io, localize) {
|
|
|
97376
97515
|
}
|
|
97377
97516
|
|
|
97378
97517
|
// src/version.ts
|
|
97379
|
-
var VERSION = true ? "0.8.
|
|
97380
|
-
var PRODUCER_VERSION = true ? "0.8.
|
|
97518
|
+
var VERSION = true ? "0.8.16" : "0.0.0-dev";
|
|
97519
|
+
var PRODUCER_VERSION = true ? "0.8.16" : "0.0.0-dev";
|
|
97381
97520
|
|
|
97382
97521
|
// src/fontLocalizeCli.ts
|
|
97383
97522
|
async function readStdin() {
|