@hyperframes/producer 0.4.15-alpha.1 → 0.4.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.
@@ -1357,12 +1357,12 @@ var require_CSSValueExpression = __commonJS({
1357
1357
  return false;
1358
1358
  }
1359
1359
  };
1360
- CSSOM.CSSValueExpression.prototype._parseJSString = function(token, idx, sep) {
1361
- var endIdx = this._findMatchedIdx(token, idx, sep), text;
1360
+ CSSOM.CSSValueExpression.prototype._parseJSString = function(token, idx, sep2) {
1361
+ var endIdx = this._findMatchedIdx(token, idx, sep2), text;
1362
1362
  if (endIdx === -1) {
1363
1363
  return false;
1364
1364
  } else {
1365
- text = token.substring(idx, endIdx + sep.length);
1365
+ text = token.substring(idx, endIdx + sep2.length);
1366
1366
  return {
1367
1367
  idx: endIdx,
1368
1368
  text
@@ -1402,15 +1402,15 @@ var require_CSSValueExpression = __commonJS({
1402
1402
  if (!isLegal) {
1403
1403
  return false;
1404
1404
  } else {
1405
- var sep = "/";
1406
- return this._parseJSString(token, idx, sep);
1405
+ var sep2 = "/";
1406
+ return this._parseJSString(token, idx, sep2);
1407
1407
  }
1408
1408
  };
1409
- CSSOM.CSSValueExpression.prototype._findMatchedIdx = function(token, idx, sep) {
1409
+ CSSOM.CSSValueExpression.prototype._findMatchedIdx = function(token, idx, sep2) {
1410
1410
  var startIdx = idx, endIdx;
1411
1411
  var NOT_FOUND = -1;
1412
1412
  while (true) {
1413
- endIdx = token.indexOf(sep, startIdx + 1);
1413
+ endIdx = token.indexOf(sep2, startIdx + 1);
1414
1414
  if (endIdx === -1) {
1415
1415
  endIdx = NOT_FOUND;
1416
1416
  break;
@@ -2149,11 +2149,11 @@ function __extends(d, b) {
2149
2149
  }
2150
2150
  function __awaiter(thisArg, _arguments, P, generator) {
2151
2151
  function adopt(value) {
2152
- return value instanceof P ? value : new P(function(resolve13) {
2153
- resolve13(value);
2152
+ return value instanceof P ? value : new P(function(resolve14) {
2153
+ resolve14(value);
2154
2154
  });
2155
2155
  }
2156
- return new (P || (P = Promise))(function(resolve13, reject) {
2156
+ return new (P || (P = Promise))(function(resolve14, reject) {
2157
2157
  function fulfilled(value) {
2158
2158
  try {
2159
2159
  step(generator.next(value));
@@ -2169,7 +2169,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
2169
2169
  }
2170
2170
  }
2171
2171
  function step(result) {
2172
- result.done ? resolve13(result.value) : adopt(result.value).then(fulfilled, rejected);
2172
+ result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected);
2173
2173
  }
2174
2174
  step((generator = generator.apply(thisArg, _arguments || [])).next());
2175
2175
  });
@@ -2332,14 +2332,14 @@ function __asyncValues(o) {
2332
2332
  }, i);
2333
2333
  function verb(n) {
2334
2334
  i[n] = o[n] && function(v) {
2335
- return new Promise(function(resolve13, reject) {
2336
- v = o[n](v), settle(resolve13, reject, v.done, v.value);
2335
+ return new Promise(function(resolve14, reject) {
2336
+ v = o[n](v), settle(resolve14, reject, v.done, v.value);
2337
2337
  });
2338
2338
  };
2339
2339
  }
2340
- function settle(resolve13, reject, d, v) {
2340
+ function settle(resolve14, reject, d, v) {
2341
2341
  Promise.resolve(v).then(function(v2) {
2342
- resolve13({ value: v2, done: d });
2342
+ resolve14({ value: v2, done: d });
2343
2343
  }, reject);
2344
2344
  }
2345
2345
  }
@@ -2864,7 +2864,7 @@ function of() {
2864
2864
  }
2865
2865
  function lastValueFrom(source2, config2) {
2866
2866
  var hasConfig = typeof config2 === "object";
2867
- return new Promise(function(resolve13, reject) {
2867
+ return new Promise(function(resolve14, reject) {
2868
2868
  var _hasValue = false;
2869
2869
  var _value;
2870
2870
  source2.subscribe({
@@ -2875,9 +2875,9 @@ function lastValueFrom(source2, config2) {
2875
2875
  error: reject,
2876
2876
  complete: function() {
2877
2877
  if (_hasValue) {
2878
- resolve13(_value);
2878
+ resolve14(_value);
2879
2879
  } else if (hasConfig) {
2880
- resolve13(config2.defaultValue);
2880
+ resolve14(config2.defaultValue);
2881
2881
  } else {
2882
2882
  reject(new EmptyError());
2883
2883
  }
@@ -2887,16 +2887,16 @@ function lastValueFrom(source2, config2) {
2887
2887
  }
2888
2888
  function firstValueFrom(source2, config2) {
2889
2889
  var hasConfig = typeof config2 === "object";
2890
- return new Promise(function(resolve13, reject) {
2890
+ return new Promise(function(resolve14, reject) {
2891
2891
  var subscriber = new SafeSubscriber({
2892
2892
  next: function(value) {
2893
- resolve13(value);
2893
+ resolve14(value);
2894
2894
  subscriber.unsubscribe();
2895
2895
  },
2896
2896
  error: reject,
2897
2897
  complete: function() {
2898
2898
  if (hasConfig) {
2899
- resolve13(config2.defaultValue);
2899
+ resolve14(config2.defaultValue);
2900
2900
  } else {
2901
2901
  reject(new EmptyError());
2902
2902
  }
@@ -3935,7 +3935,7 @@ var init_rxjs = __esm({
3935
3935
  Observable2.prototype.forEach = function(next, promiseCtor) {
3936
3936
  var _this = this;
3937
3937
  promiseCtor = getPromiseCtor(promiseCtor);
3938
- return new promiseCtor(function(resolve13, reject) {
3938
+ return new promiseCtor(function(resolve14, reject) {
3939
3939
  var subscriber = new SafeSubscriber({
3940
3940
  next: function(value) {
3941
3941
  try {
@@ -3946,7 +3946,7 @@ var init_rxjs = __esm({
3946
3946
  }
3947
3947
  },
3948
3948
  error: reject,
3949
- complete: resolve13
3949
+ complete: resolve14
3950
3950
  });
3951
3951
  _this.subscribe(subscriber);
3952
3952
  });
@@ -3968,14 +3968,14 @@ var init_rxjs = __esm({
3968
3968
  Observable2.prototype.toPromise = function(promiseCtor) {
3969
3969
  var _this = this;
3970
3970
  promiseCtor = getPromiseCtor(promiseCtor);
3971
- return new promiseCtor(function(resolve13, reject) {
3971
+ return new promiseCtor(function(resolve14, reject) {
3972
3972
  var value;
3973
3973
  _this.subscribe(function(x) {
3974
3974
  return value = x;
3975
3975
  }, function(err) {
3976
3976
  return reject(err);
3977
3977
  }, function() {
3978
- return resolve13(value);
3978
+ return resolve14(value);
3979
3979
  });
3980
3980
  });
3981
3981
  };
@@ -6405,8 +6405,8 @@ var init_Deferred = __esm({
6405
6405
  // SAFETY: This is ensured by #taskPromise.
6406
6406
  #resolve;
6407
6407
  // TODO: Switch to Promise.withResolvers with Node 22
6408
- #taskPromise = new Promise((resolve13) => {
6409
- this.#resolve = resolve13;
6408
+ #taskPromise = new Promise((resolve14) => {
6409
+ this.#resolve = resolve14;
6410
6410
  });
6411
6411
  #timeoutId;
6412
6412
  #timeoutError;
@@ -6496,12 +6496,12 @@ var init_Mutex = __esm({
6496
6496
  return new _Mutex.Guard(this, onRelease);
6497
6497
  }
6498
6498
  release() {
6499
- const resolve13 = this.#acquirers.shift();
6500
- if (!resolve13) {
6499
+ const resolve14 = this.#acquirers.shift();
6500
+ if (!resolve14) {
6501
6501
  this.#locked = false;
6502
6502
  return;
6503
6503
  }
6504
- resolve13();
6504
+ resolve14();
6505
6505
  }
6506
6506
  };
6507
6507
  }
@@ -8516,12 +8516,12 @@ var init_locators = __esm({
8516
8516
  }
8517
8517
  return defer(() => {
8518
8518
  return from(handle.evaluate((element) => {
8519
- return new Promise((resolve13) => {
8519
+ return new Promise((resolve14) => {
8520
8520
  window.requestAnimationFrame(() => {
8521
8521
  const rect1 = element.getBoundingClientRect();
8522
8522
  window.requestAnimationFrame(() => {
8523
8523
  const rect2 = element.getBoundingClientRect();
8524
- resolve13([
8524
+ resolve14([
8525
8525
  {
8526
8526
  x: rect1.x,
8527
8527
  y: rect1.y,
@@ -10260,9 +10260,9 @@ var init_ElementHandle = __esm({
10260
10260
  const handle = await this.#asSVGElementHandle();
10261
10261
  const target = __addDisposableResource6(env_5, handle && await handle.#getOwnerSVGElement(), false);
10262
10262
  return await (target ?? this).evaluate(async (element, threshold) => {
10263
- const visibleRatio = await new Promise((resolve13) => {
10263
+ const visibleRatio = await new Promise((resolve14) => {
10264
10264
  const observer = new IntersectionObserver((entries2) => {
10265
- resolve13(entries2[0].intersectionRatio);
10265
+ resolve14(entries2[0].intersectionRatio);
10266
10266
  observer.disconnect();
10267
10267
  });
10268
10268
  observer.observe(element);
@@ -10908,7 +10908,7 @@ var init_Frame = __esm({
10908
10908
  }
10909
10909
  type = type ?? "text/javascript";
10910
10910
  return await this.mainRealm().transferHandle(await this.isolatedRealm().evaluateHandle(async ({ url, id, type: type2, content: content2 }) => {
10911
- return await new Promise((resolve13, reject) => {
10911
+ return await new Promise((resolve14, reject) => {
10912
10912
  const script = document.createElement("script");
10913
10913
  script.type = type2;
10914
10914
  script.text = content2;
@@ -10921,12 +10921,12 @@ var init_Frame = __esm({
10921
10921
  if (url) {
10922
10922
  script.src = url;
10923
10923
  script.addEventListener("load", () => {
10924
- resolve13(script);
10924
+ resolve14(script);
10925
10925
  }, { once: true });
10926
10926
  document.head.appendChild(script);
10927
10927
  } else {
10928
10928
  document.head.appendChild(script);
10929
- resolve13(script);
10929
+ resolve14(script);
10930
10930
  }
10931
10931
  });
10932
10932
  }, { ...options, type, content }));
@@ -10946,7 +10946,7 @@ var init_Frame = __esm({
10946
10946
  options.content = content;
10947
10947
  }
10948
10948
  return await this.mainRealm().transferHandle(await this.isolatedRealm().evaluateHandle(async ({ url, content: content2 }) => {
10949
- return await new Promise((resolve13, reject) => {
10949
+ return await new Promise((resolve14, reject) => {
10950
10950
  let element;
10951
10951
  if (!url) {
10952
10952
  element = document.createElement("style");
@@ -10958,7 +10958,7 @@ var init_Frame = __esm({
10958
10958
  element = link;
10959
10959
  }
10960
10960
  element.addEventListener("load", () => {
10961
- resolve13(element);
10961
+ resolve14(element);
10962
10962
  }, { once: true });
10963
10963
  element.addEventListener("error", (event) => {
10964
10964
  reject(new Error(event.message ?? "Could not load style"));
@@ -12697,9 +12697,9 @@ var init_Page = __esm({
12697
12697
  ++this.#screencastSessionCount;
12698
12698
  if (!this.#startScreencastPromise) {
12699
12699
  this.#startScreencastPromise = this.mainFrame().client.send("Page.startScreencast", { format: "png" }).then(() => {
12700
- return new Promise((resolve13) => {
12700
+ return new Promise((resolve14) => {
12701
12701
  return this.mainFrame().client.once("Page.screencastFrame", () => {
12702
- return resolve13();
12702
+ return resolve14();
12703
12703
  });
12704
12704
  });
12705
12705
  });
@@ -16017,11 +16017,11 @@ function addPageBinding(type, name, prefix) {
16017
16017
  return value instanceof Node;
16018
16018
  })
16019
16019
  }));
16020
- return new Promise((resolve13, reject) => {
16020
+ return new Promise((resolve14, reject) => {
16021
16021
  callPuppeteer.callbacks.set(seq, {
16022
16022
  resolve(value) {
16023
16023
  callPuppeteer.args.delete(seq);
16024
- resolve13(value);
16024
+ resolve14(value);
16025
16025
  },
16026
16026
  reject(value) {
16027
16027
  callPuppeteer.args.delete(seq);
@@ -19684,8 +19684,8 @@ var init_Input2 = __esm({
19684
19684
  if (typeof delay === "number") {
19685
19685
  await Promise.all(actions);
19686
19686
  actions.length = 0;
19687
- await new Promise((resolve13) => {
19688
- setTimeout(resolve13, delay);
19687
+ await new Promise((resolve14) => {
19688
+ setTimeout(resolve14, delay);
19689
19689
  });
19690
19690
  }
19691
19691
  actions.push(this.up({ ...options, clickCount }));
@@ -19705,9 +19705,9 @@ var init_Input2 = __esm({
19705
19705
  });
19706
19706
  }
19707
19707
  async drag(start, target) {
19708
- const promise = new Promise((resolve13) => {
19708
+ const promise = new Promise((resolve14) => {
19709
19709
  this.#client.once("Input.dragIntercepted", (event) => {
19710
- return resolve13(event.data);
19710
+ return resolve14(event.data);
19711
19711
  });
19712
19712
  });
19713
19713
  await this.move(start.x, start.y);
@@ -19748,8 +19748,8 @@ var init_Input2 = __esm({
19748
19748
  await this.dragEnter(target, data);
19749
19749
  await this.dragOver(target, data);
19750
19750
  if (delay) {
19751
- await new Promise((resolve13) => {
19752
- return setTimeout(resolve13, delay);
19751
+ await new Promise((resolve14) => {
19752
+ return setTimeout(resolve14, delay);
19753
19753
  });
19754
19754
  }
19755
19755
  await this.drop(target, data);
@@ -20633,9 +20633,9 @@ var init_Page2 = __esm({
20633
20633
  async captureHeapSnapshot(options) {
20634
20634
  const { createWriteStream: createWriteStream3 } = environment.value.fs;
20635
20635
  const stream2 = createWriteStream3(options.path);
20636
- const streamPromise = new Promise((resolve13, reject) => {
20636
+ const streamPromise = new Promise((resolve14, reject) => {
20637
20637
  stream2.on("error", reject);
20638
- stream2.on("finish", resolve13);
20638
+ stream2.on("finish", resolve14);
20639
20639
  });
20640
20640
  const client = this.#primaryTargetClient;
20641
20641
  await client.send("HeapProfiler.enable");
@@ -22277,10 +22277,10 @@ var init_BrowserWebSocketTransport = __esm({
22277
22277
  "../../node_modules/.bun/puppeteer-core@24.40.0/node_modules/puppeteer-core/lib/esm/puppeteer/common/BrowserWebSocketTransport.js"() {
22278
22278
  BrowserWebSocketTransport = class _BrowserWebSocketTransport {
22279
22279
  static create(url) {
22280
- return new Promise((resolve13, reject) => {
22280
+ return new Promise((resolve14, reject) => {
22281
22281
  const ws = new WebSocket(url);
22282
22282
  ws.addEventListener("open", () => {
22283
- return resolve13(new _BrowserWebSocketTransport(ws));
22283
+ return resolve14(new _BrowserWebSocketTransport(ws));
22284
22284
  });
22285
22285
  ws.addEventListener("error", reject);
22286
22286
  });
@@ -25202,11 +25202,11 @@ var require_BrowsingContextProcessor = __commonJS({
25202
25202
  }
25203
25203
  const parentCdpClient = context2.cdpTarget.parentCdpClient;
25204
25204
  try {
25205
- const detachedFromTargetPromise = new Promise((resolve13) => {
25205
+ const detachedFromTargetPromise = new Promise((resolve14) => {
25206
25206
  const onContextDestroyed = (event) => {
25207
25207
  if (event.targetId === params.context) {
25208
25208
  parentCdpClient.off("Target.detachedFromTarget", onContextDestroyed);
25209
- resolve13();
25209
+ resolve14();
25210
25210
  }
25211
25211
  };
25212
25212
  parentCdpClient.on("Target.detachedFromTarget", onContextDestroyed);
@@ -26569,7 +26569,7 @@ var require_ActionDispatcher = __commonJS({
26569
26569
  }
26570
26570
  }
26571
26571
  const promises = [
26572
- new Promise((resolve13) => setTimeout(resolve13, this.#tickDuration))
26572
+ new Promise((resolve14) => setTimeout(resolve14, this.#tickDuration))
26573
26573
  ];
26574
26574
  for (const option of options) {
26575
26575
  promises.push(this.#dispatchAction(option));
@@ -27170,8 +27170,8 @@ var require_Mutex = __commonJS({
27170
27170
  acquire() {
27171
27171
  const state = { resolved: false };
27172
27172
  if (this.#locked) {
27173
- return new Promise((resolve13) => {
27174
- this.#acquirers.push(() => resolve13(this.#release.bind(this, state)));
27173
+ return new Promise((resolve14) => {
27174
+ this.#acquirers.push(() => resolve14(this.#release.bind(this, state)));
27175
27175
  });
27176
27176
  }
27177
27177
  this.#locked = true;
@@ -27182,12 +27182,12 @@ var require_Mutex = __commonJS({
27182
27182
  throw new Error("Cannot release more than once.");
27183
27183
  }
27184
27184
  state.resolved = true;
27185
- const resolve13 = this.#acquirers.shift();
27186
- if (!resolve13) {
27185
+ const resolve14 = this.#acquirers.shift();
27186
+ if (!resolve14) {
27187
27187
  this.#locked = false;
27188
27188
  return;
27189
27189
  }
27190
- resolve13();
27190
+ resolve14();
27191
27191
  }
27192
27192
  async run(action) {
27193
27193
  const release = await this.acquire();
@@ -28369,8 +28369,8 @@ var require_ChannelProxy = __commonJS({
28369
28369
  * in the queue.
28370
28370
  */
28371
28371
  async getMessage() {
28372
- const onMessage = queue.length > 0 ? Promise.resolve() : new Promise((resolve13) => {
28373
- queueNonEmptyResolver = resolve13;
28372
+ const onMessage = queue.length > 0 ? Promise.resolve() : new Promise((resolve14) => {
28373
+ queueNonEmptyResolver = resolve14;
28374
28374
  });
28375
28375
  await onMessage;
28376
28376
  return queue.shift();
@@ -28475,7 +28475,7 @@ var require_ChannelProxy = __commonJS({
28475
28475
  functionDeclaration: String((id) => {
28476
28476
  const w = window;
28477
28477
  if (w[id] === void 0) {
28478
- return new Promise((resolve13) => w[id] = resolve13);
28478
+ return new Promise((resolve14) => w[id] = resolve14);
28479
28479
  }
28480
28480
  const channelProxy = w[id];
28481
28481
  delete w[id];
@@ -29976,8 +29976,8 @@ var require_Deferred = __commonJS({
29976
29976
  return this.#result;
29977
29977
  }
29978
29978
  constructor() {
29979
- this.#promise = new Promise((resolve13, reject) => {
29980
- this.#resolve = resolve13;
29979
+ this.#promise = new Promise((resolve14, reject) => {
29980
+ this.#resolve = resolve14;
29981
29981
  this.#reject = reject;
29982
29982
  });
29983
29983
  this.#promise.catch((_error) => {
@@ -34821,11 +34821,11 @@ var require_BrowsingContextStorage = __commonJS({
34821
34821
  if (this.#contexts.has(browsingContextId)) {
34822
34822
  return Promise.resolve(this.getContext(browsingContextId));
34823
34823
  }
34824
- return new Promise((resolve13) => {
34824
+ return new Promise((resolve14) => {
34825
34825
  const listener = (event) => {
34826
34826
  if (event.browsingContext.id === browsingContextId) {
34827
34827
  this.#eventEmitter.off("added", listener);
34828
- resolve13(event.browsingContext);
34828
+ resolve14(event.browsingContext);
34829
34829
  }
34830
34830
  };
34831
34831
  this.#eventEmitter.on("added", listener);
@@ -38407,8 +38407,8 @@ var init_ExposedFunction = __esm({
38407
38407
  const functionDeclaration = stringifyFunction(interpolateFunction((callback) => {
38408
38408
  Object.assign(globalThis, {
38409
38409
  [PLACEHOLDER("name")]: function(...args) {
38410
- return new Promise((resolve13, reject) => {
38411
- callback([resolve13, reject, args]);
38410
+ return new Promise((resolve14, reject) => {
38411
+ callback([resolve14, reject, args]);
38412
38412
  });
38413
38413
  }
38414
38414
  });
@@ -38496,8 +38496,8 @@ var init_ExposedFunction = __esm({
38496
38496
  return;
38497
38497
  }
38498
38498
  try {
38499
- await dataHandle.evaluate(([resolve13], result2) => {
38500
- resolve13(result2);
38499
+ await dataHandle.evaluate(([resolve14], result2) => {
38500
+ resolve14(result2);
38501
38501
  }, result);
38502
38502
  } catch (error) {
38503
38503
  debugError(error);
@@ -46578,7 +46578,7 @@ var init_NodeWebSocketTransport = __esm({
46578
46578
  init_version();
46579
46579
  NodeWebSocketTransport = class _NodeWebSocketTransport {
46580
46580
  static create(url, headers) {
46581
- return new Promise((resolve13, reject) => {
46581
+ return new Promise((resolve14, reject) => {
46582
46582
  const ws = new wrapper_default(url, [], {
46583
46583
  followRedirects: true,
46584
46584
  perMessageDeflate: false,
@@ -46591,7 +46591,7 @@ var init_NodeWebSocketTransport = __esm({
46591
46591
  }
46592
46592
  });
46593
46593
  ws.addEventListener("open", () => {
46594
- return resolve13(new _NodeWebSocketTransport(ws));
46594
+ return resolve14(new _NodeWebSocketTransport(ws));
46595
46595
  });
46596
46596
  ws.addEventListener("error", reject);
46597
46597
  });
@@ -49652,8 +49652,8 @@ var require_helpers = __commonJS({
49652
49652
  function req(url, opts = {}) {
49653
49653
  const href = typeof url === "string" ? url : url.href;
49654
49654
  const req2 = (href.startsWith("https:") ? https2 : http2).request(url, opts);
49655
- const promise = new Promise((resolve13, reject) => {
49656
- req2.once("response", resolve13).once("error", reject).end();
49655
+ const promise = new Promise((resolve14, reject) => {
49656
+ req2.once("response", resolve14).once("error", reject).end();
49657
49657
  });
49658
49658
  req2.then = promise.then.bind(promise);
49659
49659
  return req2;
@@ -50030,7 +50030,7 @@ var require_parse_proxy_response = __commonJS({
50030
50030
  var debug_1 = __importDefault2(require_src());
50031
50031
  var debug6 = (0, debug_1.default)("https-proxy-agent:parse-proxy-response");
50032
50032
  function parseProxyResponse(socket) {
50033
- return new Promise((resolve13, reject) => {
50033
+ return new Promise((resolve14, reject) => {
50034
50034
  let buffersLength = 0;
50035
50035
  const buffers = [];
50036
50036
  function read() {
@@ -50096,7 +50096,7 @@ var require_parse_proxy_response = __commonJS({
50096
50096
  }
50097
50097
  debug6("got proxy server response: %o %o", firstLine, headers);
50098
50098
  cleanup();
50099
- resolve13({
50099
+ resolve14({
50100
50100
  connect: {
50101
50101
  statusCode,
50102
50102
  statusText,
@@ -53354,11 +53354,11 @@ var require_socksclient = __commonJS({
53354
53354
  "use strict";
53355
53355
  var __awaiter3 = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
53356
53356
  function adopt(value) {
53357
- return value instanceof P ? value : new P(function(resolve13) {
53358
- resolve13(value);
53357
+ return value instanceof P ? value : new P(function(resolve14) {
53358
+ resolve14(value);
53359
53359
  });
53360
53360
  }
53361
- return new (P || (P = Promise))(function(resolve13, reject) {
53361
+ return new (P || (P = Promise))(function(resolve14, reject) {
53362
53362
  function fulfilled(value) {
53363
53363
  try {
53364
53364
  step(generator.next(value));
@@ -53374,7 +53374,7 @@ var require_socksclient = __commonJS({
53374
53374
  }
53375
53375
  }
53376
53376
  function step(result) {
53377
- result.done ? resolve13(result.value) : adopt(result.value).then(fulfilled, rejected);
53377
+ result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected);
53378
53378
  }
53379
53379
  step((generator = generator.apply(thisArg, _arguments || [])).next());
53380
53380
  });
@@ -53408,13 +53408,13 @@ var require_socksclient = __commonJS({
53408
53408
  * @returns { Promise }
53409
53409
  */
53410
53410
  static createConnection(options, callback) {
53411
- return new Promise((resolve13, reject) => {
53411
+ return new Promise((resolve14, reject) => {
53412
53412
  try {
53413
53413
  (0, helpers_1.validateSocksClientOptions)(options, ["connect"]);
53414
53414
  } catch (err) {
53415
53415
  if (typeof callback === "function") {
53416
53416
  callback(err);
53417
- return resolve13(err);
53417
+ return resolve14(err);
53418
53418
  } else {
53419
53419
  return reject(err);
53420
53420
  }
@@ -53425,16 +53425,16 @@ var require_socksclient = __commonJS({
53425
53425
  client.removeAllListeners();
53426
53426
  if (typeof callback === "function") {
53427
53427
  callback(null, info);
53428
- resolve13(info);
53428
+ resolve14(info);
53429
53429
  } else {
53430
- resolve13(info);
53430
+ resolve14(info);
53431
53431
  }
53432
53432
  });
53433
53433
  client.once("error", (err) => {
53434
53434
  client.removeAllListeners();
53435
53435
  if (typeof callback === "function") {
53436
53436
  callback(err);
53437
- resolve13(err);
53437
+ resolve14(err);
53438
53438
  } else {
53439
53439
  reject(err);
53440
53440
  }
@@ -53451,13 +53451,13 @@ var require_socksclient = __commonJS({
53451
53451
  * @returns { Promise }
53452
53452
  */
53453
53453
  static createConnectionChain(options, callback) {
53454
- return new Promise((resolve13, reject) => __awaiter3(this, void 0, void 0, function* () {
53454
+ return new Promise((resolve14, reject) => __awaiter3(this, void 0, void 0, function* () {
53455
53455
  try {
53456
53456
  (0, helpers_1.validateSocksClientChainOptions)(options);
53457
53457
  } catch (err) {
53458
53458
  if (typeof callback === "function") {
53459
53459
  callback(err);
53460
- return resolve13(err);
53460
+ return resolve14(err);
53461
53461
  } else {
53462
53462
  return reject(err);
53463
53463
  }
@@ -53483,14 +53483,14 @@ var require_socksclient = __commonJS({
53483
53483
  }
53484
53484
  if (typeof callback === "function") {
53485
53485
  callback(null, { socket: sock });
53486
- resolve13({ socket: sock });
53486
+ resolve14({ socket: sock });
53487
53487
  } else {
53488
- resolve13({ socket: sock });
53488
+ resolve14({ socket: sock });
53489
53489
  }
53490
53490
  } catch (err) {
53491
53491
  if (typeof callback === "function") {
53492
53492
  callback(err);
53493
- resolve13(err);
53493
+ resolve14(err);
53494
53494
  } else {
53495
53495
  reject(err);
53496
53496
  }
@@ -54174,12 +54174,12 @@ var require_dist4 = __commonJS({
54174
54174
  let { host } = opts;
54175
54175
  const { port, lookup: lookupFn = dns.lookup } = opts;
54176
54176
  if (shouldLookup) {
54177
- host = await new Promise((resolve13, reject) => {
54177
+ host = await new Promise((resolve14, reject) => {
54178
54178
  lookupFn(host, {}, (err, res) => {
54179
54179
  if (err) {
54180
54180
  reject(err);
54181
54181
  } else {
54182
- resolve13(res);
54182
+ resolve14(res);
54183
54183
  }
54184
54184
  });
54185
54185
  });
@@ -55364,7 +55364,7 @@ var require_netUtils = __commonJS({
55364
55364
  return `${socket.remoteAddress}:${socket.remotePort}`;
55365
55365
  }
55366
55366
  function upgradeSocket(socket, options) {
55367
- return new Promise((resolve13, reject) => {
55367
+ return new Promise((resolve14, reject) => {
55368
55368
  const tlsOptions = Object.assign({}, options, {
55369
55369
  socket
55370
55370
  });
@@ -55374,7 +55374,7 @@ var require_netUtils = __commonJS({
55374
55374
  reject(tlsSocket.authorizationError);
55375
55375
  } else {
55376
55376
  tlsSocket.removeAllListeners("error");
55377
- resolve13(tlsSocket);
55377
+ resolve14(tlsSocket);
55378
55378
  }
55379
55379
  }).once("error", (error) => {
55380
55380
  reject(error);
@@ -55469,7 +55469,7 @@ var require_transfer = __commonJS({
55469
55469
  };
55470
55470
  }
55471
55471
  function connectForPassiveTransfer(host, port, ftp) {
55472
- return new Promise((resolve13, reject) => {
55472
+ return new Promise((resolve14, reject) => {
55473
55473
  let socket = ftp._newSocket();
55474
55474
  const handleConnErr = function(err) {
55475
55475
  err.message = "Can't open data connection in passive mode: " + err.message;
@@ -55497,7 +55497,7 @@ var require_transfer = __commonJS({
55497
55497
  socket.removeListener("error", handleConnErr);
55498
55498
  socket.removeListener("timeout", handleTimeout);
55499
55499
  ftp.dataSocket = socket;
55500
- resolve13();
55500
+ resolve14();
55501
55501
  });
55502
55502
  });
55503
55503
  }
@@ -57866,7 +57866,7 @@ var require_util2 = __commonJS({
57866
57866
  }
57867
57867
  path12 = url.path;
57868
57868
  }
57869
- var isAbsolute3 = exports.isAbsolute(path12);
57869
+ var isAbsolute5 = exports.isAbsolute(path12);
57870
57870
  var parts = path12.split(/\/+/);
57871
57871
  for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
57872
57872
  part = parts[i];
@@ -57886,7 +57886,7 @@ var require_util2 = __commonJS({
57886
57886
  }
57887
57887
  path12 = parts.join("/");
57888
57888
  if (path12 === "") {
57889
- path12 = isAbsolute3 ? "/" : ".";
57889
+ path12 = isAbsolute5 ? "/" : ".";
57890
57890
  }
57891
57891
  if (url) {
57892
57892
  url.path = path12;
@@ -67966,11 +67966,11 @@ function __metadata(metadataKey, metadataValue) {
67966
67966
  }
67967
67967
  function __awaiter2(thisArg, _arguments, P, generator) {
67968
67968
  function adopt(value) {
67969
- return value instanceof P ? value : new P(function(resolve13) {
67970
- resolve13(value);
67969
+ return value instanceof P ? value : new P(function(resolve14) {
67970
+ resolve14(value);
67971
67971
  });
67972
67972
  }
67973
- return new (P || (P = Promise))(function(resolve13, reject) {
67973
+ return new (P || (P = Promise))(function(resolve14, reject) {
67974
67974
  function fulfilled(value) {
67975
67975
  try {
67976
67976
  step(generator.next(value));
@@ -67986,7 +67986,7 @@ function __awaiter2(thisArg, _arguments, P, generator) {
67986
67986
  }
67987
67987
  }
67988
67988
  function step(result) {
67989
- result.done ? resolve13(result.value) : adopt(result.value).then(fulfilled, rejected);
67989
+ result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected);
67990
67990
  }
67991
67991
  step((generator = generator.apply(thisArg, _arguments || [])).next());
67992
67992
  });
@@ -68177,14 +68177,14 @@ function __asyncValues2(o) {
68177
68177
  }, i);
68178
68178
  function verb(n) {
68179
68179
  i[n] = o[n] && function(v) {
68180
- return new Promise(function(resolve13, reject) {
68181
- v = o[n](v), settle(resolve13, reject, v.done, v.value);
68180
+ return new Promise(function(resolve14, reject) {
68181
+ v = o[n](v), settle(resolve14, reject, v.done, v.value);
68182
68182
  });
68183
68183
  };
68184
68184
  }
68185
- function settle(resolve13, reject, d, v) {
68185
+ function settle(resolve14, reject, d, v) {
68186
68186
  Promise.resolve(v).then(function(v2) {
68187
- resolve13({ value: v2, done: d });
68187
+ resolve14({ value: v2, done: d });
68188
68188
  }, reject);
68189
68189
  }
68190
68190
  }
@@ -71737,12 +71737,12 @@ var require_util3 = __commonJS({
71737
71737
  exports.isGMT = exports.dnsLookup = void 0;
71738
71738
  var dns_1 = __require("dns");
71739
71739
  function dnsLookup(host, opts) {
71740
- return new Promise((resolve13, reject) => {
71740
+ return new Promise((resolve14, reject) => {
71741
71741
  (0, dns_1.lookup)(host, opts, (err, res) => {
71742
71742
  if (err) {
71743
71743
  reject(err);
71744
71744
  } else {
71745
- resolve13(res);
71745
+ resolve14(res);
71746
71746
  }
71747
71747
  });
71748
71748
  });
@@ -72107,10 +72107,10 @@ var require_myIpAddress = __commonJS({
72107
72107
  var ip_1 = require_ip();
72108
72108
  var net_1 = __importDefault2(__require("net"));
72109
72109
  async function myIpAddress() {
72110
- return new Promise((resolve13, reject) => {
72110
+ return new Promise((resolve14, reject) => {
72111
72111
  const socket = net_1.default.connect({ host: "8.8.8.8", port: 53 });
72112
72112
  const onError = () => {
72113
- resolve13(ip_1.ip.address());
72113
+ resolve14(ip_1.ip.address());
72114
72114
  };
72115
72115
  socket.once("error", onError);
72116
72116
  socket.once("connect", () => {
@@ -72118,9 +72118,9 @@ var require_myIpAddress = __commonJS({
72118
72118
  const addr = socket.address();
72119
72119
  socket.destroy();
72120
72120
  if (typeof addr === "string") {
72121
- resolve13(addr);
72121
+ resolve14(addr);
72122
72122
  } else if (addr.address) {
72123
- resolve13(addr.address);
72123
+ resolve14(addr.address);
72124
72124
  } else {
72125
72125
  reject(new Error("Expected a `string`"));
72126
72126
  }
@@ -72698,8 +72698,8 @@ var require_deferred_promise = __commonJS({
72698
72698
  this.context = args.context;
72699
72699
  this.owner = args.context.runtime;
72700
72700
  this.handle = args.promiseHandle;
72701
- this.settled = new Promise((resolve13) => {
72702
- this.onSettled = resolve13;
72701
+ this.settled = new Promise((resolve14) => {
72702
+ this.onSettled = resolve14;
72703
72703
  });
72704
72704
  this.resolveHandle = args.resolveHandle;
72705
72705
  this.rejectHandle = args.rejectHandle;
@@ -73220,13 +73220,13 @@ var require_context = __commonJS({
73220
73220
  if (vmResolveResult.error) {
73221
73221
  return Promise.resolve(vmResolveResult);
73222
73222
  }
73223
- return new Promise((resolve13) => {
73223
+ return new Promise((resolve14) => {
73224
73224
  lifetime_1.Scope.withScope((scope) => {
73225
73225
  const resolveHandle = scope.manage(this.newFunction("resolve", (value) => {
73226
- resolve13({ value: value && value.dup() });
73226
+ resolve14({ value: value && value.dup() });
73227
73227
  }));
73228
73228
  const rejectHandle = scope.manage(this.newFunction("reject", (error) => {
73229
- resolve13({ error: error && error.dup() });
73229
+ resolve14({ error: error && error.dup() });
73230
73230
  }));
73231
73231
  const promiseHandle = scope.manage(vmResolveResult.value);
73232
73232
  const promiseThenHandle = scope.manage(this.getProp(promiseHandle, "then"));
@@ -75601,13 +75601,13 @@ import * as http from "node:http";
75601
75601
  import * as https from "node:https";
75602
75602
  import { URL as URL2, urlToHttpOptions } from "node:url";
75603
75603
  function headHttpRequest(url) {
75604
- return new Promise((resolve13) => {
75604
+ return new Promise((resolve14) => {
75605
75605
  const request3 = httpRequest(url, "HEAD", (response) => {
75606
75606
  response.resume();
75607
- resolve13(response.statusCode === 200);
75607
+ resolve14(response.statusCode === 200);
75608
75608
  }, false);
75609
75609
  request3.on("error", () => {
75610
- resolve13(false);
75610
+ resolve14(false);
75611
75611
  });
75612
75612
  });
75613
75613
  }
@@ -75635,7 +75635,7 @@ function httpRequest(url, method, response, keepAlive = true) {
75635
75635
  return request3;
75636
75636
  }
75637
75637
  function downloadFile(url, destinationPath, progressCallback) {
75638
- return new Promise((resolve13, reject) => {
75638
+ return new Promise((resolve14, reject) => {
75639
75639
  let downloadedBytes = 0;
75640
75640
  let totalBytes = 0;
75641
75641
  function onData(chunk) {
@@ -75651,7 +75651,7 @@ function downloadFile(url, destinationPath, progressCallback) {
75651
75651
  }
75652
75652
  const file = createWriteStream(destinationPath);
75653
75653
  file.on("close", () => {
75654
- return resolve13();
75654
+ return resolve14();
75655
75655
  });
75656
75656
  file.on("error", (error) => {
75657
75657
  return reject(error);
@@ -75676,7 +75676,7 @@ async function getJSON(url) {
75676
75676
  }
75677
75677
  }
75678
75678
  function getText3(url) {
75679
- return new Promise((resolve13, reject) => {
75679
+ return new Promise((resolve14, reject) => {
75680
75680
  const request3 = httpRequest(url, "GET", (response) => {
75681
75681
  let data = "";
75682
75682
  if (response.statusCode && response.statusCode >= 400) {
@@ -75687,7 +75687,7 @@ function getText3(url) {
75687
75687
  });
75688
75688
  response.on("end", () => {
75689
75689
  try {
75690
- return resolve13(String(data));
75690
+ return resolve14(String(data));
75691
75691
  } catch {
75692
75692
  return reject(new Error(`Failed to read text response from ${url}`));
75693
75693
  }
@@ -77079,7 +77079,7 @@ var init_launch = __esm({
77079
77079
  if (opts.onExit) {
77080
77080
  this.#onExitHook = opts.onExit;
77081
77081
  }
77082
- this.#browserProcessExiting = new Promise((resolve13, reject) => {
77082
+ this.#browserProcessExiting = new Promise((resolve14, reject) => {
77083
77083
  this.#browserProcess.once("exit", async () => {
77084
77084
  debugLaunch(`Browser process ${this.#browserProcess.pid} onExit`);
77085
77085
  this.#clearListeners();
@@ -77090,7 +77090,7 @@ var init_launch = __esm({
77090
77090
  reject(err);
77091
77091
  return;
77092
77092
  }
77093
- resolve13();
77093
+ resolve14();
77094
77094
  });
77095
77095
  });
77096
77096
  }
@@ -77206,7 +77206,7 @@ Error cause: ${isErrorLike2(error) ? error.stack : error}`);
77206
77206
  return [...this.#logs];
77207
77207
  }
77208
77208
  waitForLineOutput(regex, timeout2 = 0) {
77209
- return new Promise((resolve13, reject) => {
77209
+ return new Promise((resolve14, reject) => {
77210
77210
  const onClose = (errorOrCode) => {
77211
77211
  cleanup();
77212
77212
  reject(new Error([
@@ -77242,7 +77242,7 @@ Error cause: ${isErrorLike2(error) ? error.stack : error}`);
77242
77242
  return;
77243
77243
  }
77244
77244
  cleanup();
77245
- resolve13(match2[1]);
77245
+ resolve14(match2[1]);
77246
77246
  }
77247
77247
  });
77248
77248
  }
@@ -77711,7 +77711,7 @@ var require_get_stream = __commonJS({
77711
77711
  };
77712
77712
  const { maxBuffer } = options;
77713
77713
  let stream2;
77714
- await new Promise((resolve13, reject) => {
77714
+ await new Promise((resolve14, reject) => {
77715
77715
  const rejectPromise = (error) => {
77716
77716
  if (error && stream2.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
77717
77717
  error.bufferedData = stream2.getBufferedValue();
@@ -77723,7 +77723,7 @@ var require_get_stream = __commonJS({
77723
77723
  rejectPromise(error);
77724
77724
  return;
77725
77725
  }
77726
- resolve13();
77726
+ resolve14();
77727
77727
  });
77728
77728
  stream2.on("data", () => {
77729
77729
  if (stream2.getBufferedLength() > maxBuffer) {
@@ -79012,7 +79012,7 @@ var require_extract_zip = __commonJS({
79012
79012
  debug6("opening", this.zipPath, "with opts", this.opts);
79013
79013
  this.zipfile = await openZip(this.zipPath, { lazyEntries: true });
79014
79014
  this.canceled = false;
79015
- return new Promise((resolve13, reject) => {
79015
+ return new Promise((resolve14, reject) => {
79016
79016
  this.zipfile.on("error", (err) => {
79017
79017
  this.canceled = true;
79018
79018
  reject(err);
@@ -79021,7 +79021,7 @@ var require_extract_zip = __commonJS({
79021
79021
  this.zipfile.on("close", () => {
79022
79022
  if (!this.canceled) {
79023
79023
  debug6("zip extraction complete");
79024
- resolve13();
79024
+ resolve14();
79025
79025
  }
79026
79026
  });
79027
79027
  this.zipfile.on("entry", async (entry) => {
@@ -80278,8 +80278,8 @@ var require_streamx = __commonJS({
80278
80278
  return this;
80279
80279
  },
80280
80280
  next() {
80281
- return new Promise(function(resolve13, reject) {
80282
- promiseResolve = resolve13;
80281
+ return new Promise(function(resolve14, reject) {
80282
+ promiseResolve = resolve14;
80283
80283
  promiseReject = reject;
80284
80284
  const data = stream2.read();
80285
80285
  if (data !== null) ondata(data);
@@ -80309,11 +80309,11 @@ var require_streamx = __commonJS({
80309
80309
  }
80310
80310
  function destroy(err) {
80311
80311
  stream2.destroy(err);
80312
- return new Promise((resolve13, reject) => {
80313
- if (stream2._duplexState & DESTROYED) return resolve13({ value: void 0, done: true });
80312
+ return new Promise((resolve14, reject) => {
80313
+ if (stream2._duplexState & DESTROYED) return resolve14({ value: void 0, done: true });
80314
80314
  stream2.once("close", function() {
80315
80315
  if (err) reject(err);
80316
- else resolve13({ value: void 0, done: true });
80316
+ else resolve14({ value: void 0, done: true });
80317
80317
  });
80318
80318
  });
80319
80319
  }
@@ -80357,8 +80357,8 @@ var require_streamx = __commonJS({
80357
80357
  const writes = pending + (ws._duplexState & WRITE_WRITING ? 1 : 0);
80358
80358
  if (writes === 0) return Promise.resolve(true);
80359
80359
  if (state.drains === null) state.drains = [];
80360
- return new Promise((resolve13) => {
80361
- state.drains.push({ writes, resolve: resolve13 });
80360
+ return new Promise((resolve14) => {
80361
+ state.drains.push({ writes, resolve: resolve14 });
80362
80362
  });
80363
80363
  }
80364
80364
  write(data) {
@@ -80463,10 +80463,10 @@ var require_streamx = __commonJS({
80463
80463
  cb(null);
80464
80464
  }
80465
80465
  function pipelinePromise(...streams) {
80466
- return new Promise((resolve13, reject) => {
80466
+ return new Promise((resolve14, reject) => {
80467
80467
  return pipeline(...streams, (err) => {
80468
80468
  if (err) return reject(err);
80469
- resolve13();
80469
+ resolve14();
80470
80470
  });
80471
80471
  });
80472
80472
  }
@@ -81121,16 +81121,16 @@ var require_extract = __commonJS({
81121
81121
  entryCallback = null;
81122
81122
  cb(err);
81123
81123
  }
81124
- function onnext(resolve13, reject) {
81124
+ function onnext(resolve14, reject) {
81125
81125
  if (error) {
81126
81126
  return reject(error);
81127
81127
  }
81128
81128
  if (entryStream) {
81129
- resolve13({ value: entryStream, done: false });
81129
+ resolve14({ value: entryStream, done: false });
81130
81130
  entryStream = null;
81131
81131
  return;
81132
81132
  }
81133
- promiseResolve = resolve13;
81133
+ promiseResolve = resolve14;
81134
81134
  promiseReject = reject;
81135
81135
  consumeCallback(null);
81136
81136
  if (extract._finished && promiseResolve) {
@@ -81158,11 +81158,11 @@ var require_extract = __commonJS({
81158
81158
  function destroy(err) {
81159
81159
  extract.destroy(err);
81160
81160
  consumeCallback(err);
81161
- return new Promise((resolve13, reject) => {
81162
- if (extract.destroyed) return resolve13({ value: void 0, done: true });
81161
+ return new Promise((resolve14, reject) => {
81162
+ if (extract.destroyed) return resolve14({ value: void 0, done: true });
81163
81163
  extract.once("close", function() {
81164
81164
  if (err) reject(err);
81165
- else resolve13({ value: void 0, done: true });
81165
+ else resolve14({ value: void 0, done: true });
81166
81166
  });
81167
81167
  });
81168
81168
  }
@@ -84931,13 +84931,13 @@ function usage(yargs, shim3) {
84931
84931
  };
84932
84932
  self2.stringifiedValues = function stringifiedValues(values, separator) {
84933
84933
  let string = "";
84934
- const sep = separator || ", ";
84934
+ const sep2 = separator || ", ";
84935
84935
  const array = [].concat(values);
84936
84936
  if (!values || !array.length)
84937
84937
  return string;
84938
84938
  array.forEach((value) => {
84939
84939
  if (string.length)
84940
- string += sep;
84940
+ string += sep2;
84941
84941
  string += JSON.stringify(value);
84942
84942
  });
84943
84943
  return string;
@@ -86138,12 +86138,12 @@ var init_yargs_factory = __esm({
86138
86138
  async getCompletion(args, done) {
86139
86139
  argsert("<array> [function]", [args, done], arguments.length);
86140
86140
  if (!done) {
86141
- return new Promise((resolve13, reject) => {
86141
+ return new Promise((resolve14, reject) => {
86142
86142
  __classPrivateFieldGet2(this, _YargsInstance_completion, "f").getCompletion(args, (err, completions) => {
86143
86143
  if (err)
86144
86144
  reject(err);
86145
86145
  else
86146
- resolve13(completions);
86146
+ resolve14(completions);
86147
86147
  });
86148
86148
  });
86149
86149
  } else {
@@ -88944,8 +88944,8 @@ var init_ScreenRecorder = __esm({
88944
88944
  static {
88945
88945
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
88946
88946
  __esDecorate23(this, _private_writeFrame_descriptor = { value: __setFunctionName6(async function(buffer) {
88947
- const error = await new Promise((resolve13) => {
88948
- this.#process.stdin.write(buffer, resolve13);
88947
+ const error = await new Promise((resolve14) => {
88948
+ this.#process.stdin.write(buffer, resolve14);
88949
88949
  });
88950
88950
  if (error) {
88951
88951
  console.log(`ffmpeg failed to write: ${error.message}.`);
@@ -89135,8 +89135,8 @@ var init_ScreenRecorder = __esm({
89135
89135
  const [buffer, timestamp] = await this.#lastFrame;
89136
89136
  await Promise.all(Array(Math.max(1, Math.round(this.#fps * (performance.now() - timestamp) / 1e3))).fill(buffer).map(this.#writeFrame.bind(this)));
89137
89137
  this.#process.stdin.end();
89138
- await new Promise((resolve13) => {
89139
- this.#process.once("close", resolve13);
89138
+ await new Promise((resolve14) => {
89139
+ this.#process.once("close", resolve14);
89140
89140
  });
89141
89141
  }
89142
89142
  /**
@@ -89426,7 +89426,7 @@ import {
89426
89426
  rmSync as rmSync4,
89427
89427
  createReadStream as createReadStream2
89428
89428
  } from "node:fs";
89429
- import { resolve as resolve12, dirname as dirname11, join as join17 } from "node:path";
89429
+ import { resolve as resolve13, dirname as dirname11, join as join17 } from "node:path";
89430
89430
  import { tmpdir as tmpdir2 } from "node:os";
89431
89431
  import { parseArgs } from "node:util";
89432
89432
  import crypto2 from "node:crypto";
@@ -92061,7 +92061,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
92061
92061
  });
92062
92062
  if (!chunk) {
92063
92063
  if (i === 1) {
92064
- await new Promise((resolve13) => setTimeout(resolve13));
92064
+ await new Promise((resolve14) => setTimeout(resolve14));
92065
92065
  maxReadCount = 3;
92066
92066
  continue;
92067
92067
  }
@@ -95822,8 +95822,8 @@ var CustomElementRegistry = class {
95822
95822
  } : (element) => element.localName === localName;
95823
95823
  registry.set(localName, { Class, check });
95824
95824
  if (waiting.has(localName)) {
95825
- for (const resolve13 of waiting.get(localName))
95826
- resolve13(Class);
95825
+ for (const resolve14 of waiting.get(localName))
95826
+ resolve14(Class);
95827
95827
  waiting.delete(localName);
95828
95828
  }
95829
95829
  ownerDocument.querySelectorAll(
@@ -95863,13 +95863,13 @@ var CustomElementRegistry = class {
95863
95863
  */
95864
95864
  whenDefined(localName) {
95865
95865
  const { registry, waiting } = this;
95866
- return new Promise((resolve13) => {
95866
+ return new Promise((resolve14) => {
95867
95867
  if (registry.has(localName))
95868
- resolve13(registry.get(localName).Class);
95868
+ resolve14(registry.get(localName).Class);
95869
95869
  else {
95870
95870
  if (!waiting.has(localName))
95871
95871
  waiting.set(localName, []);
95872
- waiting.get(localName).push(resolve13);
95872
+ waiting.get(localName).push(resolve14);
95873
95873
  }
95874
95874
  });
95875
95875
  }
@@ -101519,7 +101519,7 @@ function resolveConfig(overrides) {
101519
101519
  hdr: (() => {
101520
101520
  const raw2 = env2("PRODUCER_HDR_TRANSFER");
101521
101521
  if (raw2 === "hlg" || raw2 === "pq") return { transfer: raw2 };
101522
- return void 0;
101522
+ return false;
101523
101523
  })(),
101524
101524
  hdrAutoDetect: envBool("PRODUCER_HDR_AUTO_DETECT", DEFAULT_CONFIG.hdrAutoDetect),
101525
101525
  audioGain: envNum("PRODUCER_AUDIO_GAIN", DEFAULT_CONFIG.audioGain),
@@ -103921,7 +103921,8 @@ async function injectVideoFramesBatch(page, updates) {
103921
103921
  let img = video.nextElementSibling;
103922
103922
  const isNewImage = !img || !img.classList.contains("__render_frame__");
103923
103923
  const computedStyle = window.getComputedStyle(video);
103924
- const computedOpacity = parseFloat(computedStyle.opacity) || 1;
103924
+ const opacityParsed = parseFloat(computedStyle.opacity);
103925
+ const computedOpacity = Number.isNaN(opacityParsed) ? 1 : opacityParsed;
103925
103926
  const sourceIsStatic = !computedStyle.position || computedStyle.position === "static";
103926
103927
  if (isNewImage) {
103927
103928
  img = document.createElement("img");
@@ -103967,7 +103968,6 @@ async function injectVideoFramesBatch(page, updates) {
103967
103968
  img.style.opacity = String(computedOpacity);
103968
103969
  img.style.visibility = "visible";
103969
103970
  video.style.setProperty("visibility", "hidden", "important");
103970
- video.style.setProperty("opacity", "0", "important");
103971
103971
  video.style.setProperty("pointer-events", "none", "important");
103972
103972
  }
103973
103973
  if (pendingDecodes.length > 0) {
@@ -103994,7 +103994,6 @@ async function syncVideoFrameVisibility(page, activeVideoIds) {
103994
103994
  } else {
103995
103995
  video.style.removeProperty("display");
103996
103996
  video.style.setProperty("visibility", "hidden", "important");
103997
- video.style.setProperty("opacity", "0", "important");
103998
103997
  video.style.setProperty("pointer-events", "none", "important");
103999
103998
  if (hasImg) {
104000
103999
  img.style.visibility = "hidden";
@@ -104085,7 +104084,7 @@ async function pollPageExpression(page, expression, timeoutMs, intervalMs = 100)
104085
104084
  while (Date.now() < deadline) {
104086
104085
  const ready = Boolean(await page.evaluate(expression));
104087
104086
  if (ready) return true;
104088
- await new Promise((resolve13) => setTimeout(resolve13, intervalMs));
104087
+ await new Promise((resolve14) => setTimeout(resolve14, intervalMs));
104089
104088
  }
104090
104089
  return Boolean(await page.evaluate(expression));
104091
104090
  }
@@ -104316,9 +104315,15 @@ async function captureFrameToBuffer(session, frameIndex, time) {
104316
104315
  return { buffer, captureTimeMs };
104317
104316
  }
104318
104317
  async function closeCaptureSession(session) {
104319
- if (session.page) await session.page.close().catch(() => {
104320
- });
104321
- if (session.browser) await releaseBrowser(session.browser, session.config);
104318
+ if (!session.pageReleased && session.page) {
104319
+ await session.page.close().catch(() => {
104320
+ });
104321
+ session.pageReleased = true;
104322
+ }
104323
+ if (!session.browserReleased && session.browser) {
104324
+ await releaseBrowser(session.browser, session.config);
104325
+ session.browserReleased = true;
104326
+ }
104322
104327
  session.isInitialized = false;
104323
104328
  }
104324
104329
  function prepareCaptureSessionForReuse(session, outputDir, onBeforeCapture) {
@@ -104362,7 +104367,7 @@ import { join as join6, dirname as dirname5 } from "path";
104362
104367
  // ../engine/src/utils/gpuEncoder.ts
104363
104368
  import { spawn as spawn3 } from "child_process";
104364
104369
  async function detectGpuEncoder() {
104365
- return new Promise((resolve13) => {
104370
+ return new Promise((resolve14) => {
104366
104371
  const ffmpeg = spawn3("ffmpeg", ["-encoders"], {
104367
104372
  stdio: ["pipe", "pipe", "pipe"]
104368
104373
  });
@@ -104371,13 +104376,13 @@ async function detectGpuEncoder() {
104371
104376
  stdout += data.toString();
104372
104377
  });
104373
104378
  ffmpeg.on("close", () => {
104374
- if (stdout.includes("h264_nvenc")) resolve13("nvenc");
104375
- else if (stdout.includes("h264_videotoolbox")) resolve13("videotoolbox");
104376
- else if (stdout.includes("h264_vaapi")) resolve13("vaapi");
104377
- else if (stdout.includes("h264_qsv")) resolve13("qsv");
104378
- else resolve13(null);
104379
+ if (stdout.includes("h264_nvenc")) resolve14("nvenc");
104380
+ else if (stdout.includes("h264_videotoolbox")) resolve14("videotoolbox");
104381
+ else if (stdout.includes("h264_vaapi")) resolve14("vaapi");
104382
+ else if (stdout.includes("h264_qsv")) resolve14("qsv");
104383
+ else resolve14(null);
104379
104384
  });
104380
- ffmpeg.on("error", () => resolve13(null));
104385
+ ffmpeg.on("error", () => resolve14(null));
104381
104386
  });
104382
104387
  }
104383
104388
  var cachedGpuEncoder = void 0;
@@ -104402,16 +104407,93 @@ function getGpuEncoderName(encoder, codec) {
104402
104407
  return codec === "h264" ? "libx264" : "libx265";
104403
104408
  }
104404
104409
  }
104410
+ var NVENC_PRESET_MAP = {
104411
+ ultrafast: "p1",
104412
+ superfast: "p1",
104413
+ veryfast: "p2",
104414
+ faster: "p3",
104415
+ fast: "p4",
104416
+ medium: "p4",
104417
+ slow: "p5",
104418
+ slower: "p6",
104419
+ veryslow: "p7",
104420
+ placebo: "p7"
104421
+ };
104422
+ var QSV_PRESET_MAP = {
104423
+ ultrafast: "veryfast",
104424
+ superfast: "veryfast",
104425
+ placebo: "veryslow"
104426
+ };
104427
+ function mapPresetForGpuEncoder(encoder, preset) {
104428
+ switch (encoder) {
104429
+ case "nvenc":
104430
+ if (/^p[1-7]$/.test(preset)) return preset;
104431
+ return NVENC_PRESET_MAP[preset] ?? "p4";
104432
+ case "qsv":
104433
+ return QSV_PRESET_MAP[preset] ?? preset;
104434
+ default:
104435
+ return preset;
104436
+ }
104437
+ }
104438
+
104439
+ // ../engine/src/utils/hdr.ts
104440
+ function isHdrColorSpace(cs) {
104441
+ if (!cs) return false;
104442
+ return cs.colorPrimaries.includes("bt2020") || cs.colorSpace.includes("bt2020") || cs.colorTransfer === "smpte2084" || cs.colorTransfer === "arib-std-b67";
104443
+ }
104444
+ function detectTransfer(cs) {
104445
+ if (cs?.colorTransfer === "smpte2084") return "pq";
104446
+ return "hlg";
104447
+ }
104448
+ var DEFAULT_HDR10_MASTERING = {
104449
+ masterDisplay: "G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1)",
104450
+ maxCll: "1000,400"
104451
+ };
104452
+ function getHdrEncoderColorParams(transfer, mastering = DEFAULT_HDR10_MASTERING) {
104453
+ const colorTrc = transfer === "pq" ? "smpte2084" : "arib-std-b67";
104454
+ const tagging = `colorprim=bt2020:transfer=${colorTrc}:colormatrix=bt2020nc`;
104455
+ const metadata = `master-display=${mastering.masterDisplay}:max-cll=${mastering.maxCll}`;
104456
+ return {
104457
+ colorPrimaries: "bt2020",
104458
+ colorTrc,
104459
+ colorspace: "bt2020nc",
104460
+ pixelFormat: "yuv420p10le",
104461
+ x265ColorParams: `${tagging}:${metadata}`,
104462
+ mastering
104463
+ };
104464
+ }
104465
+ function analyzeCompositionHdr(colorSpaces) {
104466
+ let hasPq = false;
104467
+ let hasHdr = false;
104468
+ for (const cs of colorSpaces) {
104469
+ if (!isHdrColorSpace(cs)) continue;
104470
+ hasHdr = true;
104471
+ if (cs?.colorTransfer === "smpte2084") hasPq = true;
104472
+ }
104473
+ if (!hasHdr) return { hasHdr: false, dominantTransfer: null };
104474
+ const dominantTransfer = hasPq ? "pq" : "hlg";
104475
+ return { hasHdr: true, dominantTransfer };
104476
+ }
104405
104477
 
104406
104478
  // ../engine/src/utils/runFfmpeg.ts
104407
104479
  import { spawn as spawn4 } from "child_process";
104408
104480
  var DEFAULT_TIMEOUT2 = 3e5;
104481
+ var DEFAULT_STDERR_TAIL_LINES = 15;
104482
+ function formatFfmpegError(exitCode, stderr, tailLines = DEFAULT_STDERR_TAIL_LINES) {
104483
+ const tail = (stderr ?? "").split(/\r?\n/).filter((line) => line.length > 0).slice(-tailLines).join("\n");
104484
+ if (exitCode === null) {
104485
+ return tail ? `[FFmpeg] ${tail}` : "[FFmpeg] process error";
104486
+ }
104487
+ return tail ? `FFmpeg exited with code ${exitCode}
104488
+ ffmpeg stderr (tail):
104489
+ ${tail}` : `FFmpeg exited with code ${exitCode}`;
104490
+ }
104409
104491
  async function runFfmpeg(args, opts) {
104410
104492
  const startMs = Date.now();
104411
104493
  const signal = opts?.signal;
104412
104494
  const timeout2 = opts?.timeout ?? DEFAULT_TIMEOUT2;
104413
104495
  const onStderr = opts?.onStderr;
104414
- return new Promise((resolve13) => {
104496
+ return new Promise((resolve14) => {
104415
104497
  const ffmpeg = spawn4("ffmpeg", args);
104416
104498
  let stderr = "";
104417
104499
  const onAbort = () => {
@@ -104437,7 +104519,7 @@ async function runFfmpeg(args, opts) {
104437
104519
  ffmpeg.on("close", (code) => {
104438
104520
  clearTimeout(timer2);
104439
104521
  if (signal) signal.removeEventListener("abort", onAbort);
104440
- resolve13({
104522
+ resolve14({
104441
104523
  success: !signal?.aborted && code === 0,
104442
104524
  exitCode: code,
104443
104525
  stderr,
@@ -104447,7 +104529,7 @@ async function runFfmpeg(args, opts) {
104447
104529
  ffmpeg.on("error", (err) => {
104448
104530
  clearTimeout(timer2);
104449
104531
  if (signal) signal.removeEventListener("abort", onAbort);
104450
- resolve13({
104532
+ resolve14({
104451
104533
  success: false,
104452
104534
  exitCode: null,
104453
104535
  stderr: err.message,
@@ -104502,6 +104584,12 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
104502
104584
  pixelFormat = "yuv420p",
104503
104585
  useGpu = false
104504
104586
  } = options;
104587
+ if (options.hdr && codec === "h264") {
104588
+ console.warn(
104589
+ "[chunkEncoder] HDR is not supported with codec=h264 (libx264 has no HDR support). Stripping HDR metadata and tagging output as SDR/BT.709. Use codec=h265 for HDR output."
104590
+ );
104591
+ options = { ...options, hdr: void 0 };
104592
+ }
104505
104593
  const args = [...inputArgs, "-r", String(fps)];
104506
104594
  const shouldUseGpu = useGpu && gpuEncoder !== null;
104507
104595
  if (codec === "h264" || codec === "h265") {
@@ -104510,7 +104598,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
104510
104598
  args.push("-c:v", encoderName);
104511
104599
  switch (gpuEncoder) {
104512
104600
  case "nvenc":
104513
- args.push("-preset", preset);
104601
+ args.push("-preset", mapPresetForGpuEncoder("nvenc", preset));
104514
104602
  if (bitrate) args.push("-b:v", bitrate);
104515
104603
  else args.push("-cq", String(quality));
104516
104604
  break;
@@ -104529,7 +104617,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
104529
104617
  else args.push("-qp", String(quality));
104530
104618
  break;
104531
104619
  case "qsv":
104532
- args.push("-preset", preset);
104620
+ args.push("-preset", mapPresetForGpuEncoder("qsv", preset));
104533
104621
  if (bitrate) args.push("-b:v", bitrate);
104534
104622
  else args.push("-global_quality", String(quality));
104535
104623
  break;
@@ -104540,7 +104628,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
104540
104628
  if (bitrate) args.push("-b:v", bitrate);
104541
104629
  else args.push("-crf", String(quality));
104542
104630
  const xParamsFlag = codec === "h264" ? "-x264-params" : "-x265-params";
104543
- const colorParams = "colorprim=bt709:transfer=bt709:colormatrix=bt709";
104631
+ const colorParams = codec === "h265" && options.hdr ? getHdrEncoderColorParams(options.hdr.transfer).x265ColorParams : "colorprim=bt709:transfer=bt709:colormatrix=bt709";
104544
104632
  if (preset === "ultrafast") {
104545
104633
  args.push(xParamsFlag, `aq-mode=3:${colorParams}`);
104546
104634
  } else {
@@ -104564,16 +104652,30 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
104564
104652
  return [...args, "-y", outputPath];
104565
104653
  }
104566
104654
  if (codec === "h264" || codec === "h265") {
104567
- args.push(
104568
- "-colorspace:v",
104569
- "bt709",
104570
- "-color_primaries:v",
104571
- "bt709",
104572
- "-color_trc:v",
104573
- "bt709",
104574
- "-color_range",
104575
- "tv"
104576
- );
104655
+ if (options.hdr) {
104656
+ const transferTag = options.hdr.transfer === "pq" ? "smpte2084" : "arib-std-b67";
104657
+ args.push(
104658
+ "-colorspace:v",
104659
+ "bt2020nc",
104660
+ "-color_primaries:v",
104661
+ "bt2020",
104662
+ "-color_trc:v",
104663
+ transferTag,
104664
+ "-color_range",
104665
+ "tv"
104666
+ );
104667
+ } else {
104668
+ args.push(
104669
+ "-colorspace:v",
104670
+ "bt709",
104671
+ "-color_primaries:v",
104672
+ "bt709",
104673
+ "-color_trc:v",
104674
+ "bt709",
104675
+ "-color_range",
104676
+ "tv"
104677
+ );
104678
+ }
104577
104679
  if (gpuEncoder === "vaapi") {
104578
104680
  const vfIdx = args.indexOf("-vf");
104579
104681
  if (vfIdx !== -1) {
@@ -104613,7 +104715,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
104613
104715
  const inputPath = join6(framesDir, framePattern);
104614
104716
  const inputArgs = ["-framerate", String(options.fps), "-i", inputPath];
104615
104717
  const args = buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder);
104616
- return new Promise((resolve13) => {
104718
+ return new Promise((resolve14) => {
104617
104719
  const ffmpeg = spawn5("ffmpeg", args);
104618
104720
  let stderr = "";
104619
104721
  const onAbort = () => {
@@ -104638,7 +104740,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
104638
104740
  if (signal) signal.removeEventListener("abort", onAbort);
104639
104741
  const durationMs = Date.now() - startTime;
104640
104742
  if (signal?.aborted) {
104641
- resolve13({
104743
+ resolve14({
104642
104744
  success: false,
104643
104745
  outputPath,
104644
104746
  durationMs,
@@ -104649,23 +104751,23 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
104649
104751
  return;
104650
104752
  }
104651
104753
  if (code !== 0) {
104652
- resolve13({
104754
+ resolve14({
104653
104755
  success: false,
104654
104756
  outputPath,
104655
104757
  durationMs,
104656
104758
  framesEncoded: 0,
104657
104759
  fileSize: 0,
104658
- error: `FFmpeg exited with code ${code}`
104760
+ error: formatFfmpegError(code, stderr)
104659
104761
  });
104660
104762
  return;
104661
104763
  }
104662
104764
  const fileSize = existsSync5(outputPath) ? statSync3(outputPath).size : 0;
104663
- resolve13({ success: true, outputPath, durationMs, framesEncoded: frameCount, fileSize });
104765
+ resolve14({ success: true, outputPath, durationMs, framesEncoded: frameCount, fileSize });
104664
104766
  });
104665
104767
  ffmpeg.on("error", (err) => {
104666
104768
  clearTimeout(timer2);
104667
104769
  if (signal) signal.removeEventListener("abort", onAbort);
104668
- resolve13({
104770
+ resolve14({
104669
104771
  success: false,
104670
104772
  outputPath,
104671
104773
  durationMs: Date.now() - startTime,
@@ -104723,18 +104825,18 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
104723
104825
  let gpuEncoder = null;
104724
104826
  if (options.useGpu) gpuEncoder = await getCachedGpuEncoder();
104725
104827
  const args = buildEncoderArgs(options, inputArgs, chunkPath, gpuEncoder);
104726
- const chunkResult = await new Promise((resolve13) => {
104828
+ const chunkResult = await new Promise((resolve14) => {
104727
104829
  const ffmpeg = spawn5("ffmpeg", args);
104728
104830
  let stderr = "";
104729
104831
  ffmpeg.stderr.on("data", (d) => {
104730
104832
  stderr += d.toString();
104731
104833
  });
104732
104834
  ffmpeg.on("close", (code) => {
104733
- if (code === 0) resolve13({ success: true });
104734
- else resolve13({ success: false, error: `Chunk ${i} encode failed: ${stderr.slice(-400)}` });
104835
+ if (code === 0) resolve14({ success: true });
104836
+ else resolve14({ success: false, error: `Chunk ${i} encode failed: ${stderr.slice(-400)}` });
104735
104837
  });
104736
104838
  ffmpeg.on("error", (err) => {
104737
- resolve13({ success: false, error: `Chunk ${i} encode error: ${err.message}` });
104839
+ resolve14({ success: false, error: `Chunk ${i} encode error: ${err.message}` });
104738
104840
  });
104739
104841
  });
104740
104842
  if (!chunkResult.success) {
@@ -104764,18 +104866,18 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
104764
104866
  "-y",
104765
104867
  outputPath
104766
104868
  ];
104767
- const concatResult = await new Promise((resolve13) => {
104869
+ const concatResult = await new Promise((resolve14) => {
104768
104870
  const ffmpeg = spawn5("ffmpeg", concatArgs);
104769
104871
  let stderr = "";
104770
104872
  ffmpeg.stderr.on("data", (d) => {
104771
104873
  stderr += d.toString();
104772
104874
  });
104773
104875
  ffmpeg.on("close", (code) => {
104774
- if (code === 0) resolve13({ success: true });
104775
- else resolve13({ success: false, error: `Chunk concat failed: ${stderr.slice(-400)}` });
104876
+ if (code === 0) resolve14({ success: true });
104877
+ else resolve14({ success: false, error: `Chunk concat failed: ${stderr.slice(-400)}` });
104776
104878
  });
104777
104879
  ffmpeg.on("error", (err) => {
104778
- resolve13({ success: false, error: `Chunk concat error: ${err.message}` });
104880
+ resolve14({ success: false, error: `Chunk concat error: ${err.message}` });
104779
104881
  });
104780
104882
  });
104781
104883
  if (!concatResult.success) {
@@ -104825,7 +104927,7 @@ async function muxVideoWithAudio(videoPath, audioPath, outputPath, signal, confi
104825
104927
  success: result.success,
104826
104928
  outputPath,
104827
104929
  durationMs: result.durationMs,
104828
- error: !result.success ? result.exitCode !== null ? `FFmpeg exited with code ${result.exitCode}` : `[FFmpeg] ${result.stderr}` : void 0
104930
+ error: !result.success ? formatFfmpegError(result.exitCode, result.stderr) : void 0
104829
104931
  };
104830
104932
  }
104831
104933
  async function applyFaststart(inputPath, outputPath, signal, config2) {
@@ -104848,7 +104950,7 @@ async function applyFaststart(inputPath, outputPath, signal, config2) {
104848
104950
  success: result.success,
104849
104951
  outputPath,
104850
104952
  durationMs: result.durationMs,
104851
- error: !result.success ? result.exitCode !== null ? `FFmpeg exited with code ${result.exitCode}` : `[FFmpeg] ${result.stderr}` : void 0
104953
+ error: !result.success ? formatFfmpegError(result.exitCode, result.stderr) : void 0
104852
104954
  };
104853
104955
  }
104854
104956
 
@@ -104856,81 +104958,40 @@ async function applyFaststart(inputPath, outputPath, signal, config2) {
104856
104958
  import { spawn as spawn6 } from "child_process";
104857
104959
  import { existsSync as existsSync6, mkdirSync as mkdirSync3, statSync as statSync4 } from "fs";
104858
104960
  import { dirname as dirname6 } from "path";
104859
-
104860
- // ../engine/src/utils/hdr.ts
104861
- function isHdrColorSpace(cs) {
104862
- if (!cs) return false;
104863
- return cs.colorPrimaries.includes("bt2020") || cs.colorSpace.includes("bt2020") || cs.colorTransfer === "smpte2084" || cs.colorTransfer === "arib-std-b67";
104864
- }
104865
- function detectTransfer(cs) {
104866
- if (cs?.colorTransfer === "smpte2084") return "pq";
104867
- return "hlg";
104868
- }
104869
- var DEFAULT_HDR10_MASTERING = {
104870
- masterDisplay: "G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1)",
104871
- maxCll: "1000,400"
104872
- };
104873
- function getHdrEncoderColorParams(transfer, mastering = DEFAULT_HDR10_MASTERING) {
104874
- const colorTrc = transfer === "pq" ? "smpte2084" : "arib-std-b67";
104875
- const tagging = `colorprim=bt2020:transfer=${colorTrc}:colormatrix=bt2020nc`;
104876
- const metadata = `master-display=${mastering.masterDisplay}:max-cll=${mastering.maxCll}`;
104877
- return {
104878
- colorPrimaries: "bt2020",
104879
- colorTrc,
104880
- colorspace: "bt2020nc",
104881
- pixelFormat: "yuv420p10le",
104882
- x265ColorParams: `${tagging}:${metadata}`,
104883
- mastering
104884
- };
104885
- }
104886
- function analyzeCompositionHdr(colorSpaces) {
104887
- let hasPq = false;
104888
- let hasHdr = false;
104889
- for (const cs of colorSpaces) {
104890
- if (!isHdrColorSpace(cs)) continue;
104891
- hasHdr = true;
104892
- if (cs?.colorTransfer === "smpte2084") hasPq = true;
104893
- }
104894
- if (!hasHdr) return { hasHdr: false, dominantTransfer: null };
104895
- const dominantTransfer = hasPq ? "pq" : "hlg";
104896
- return { hasHdr: true, dominantTransfer };
104897
- }
104898
-
104899
- // ../engine/src/services/streamingEncoder.ts
104900
104961
  function createFrameReorderBuffer(startFrame, endFrame) {
104901
104962
  let cursor = startFrame;
104902
104963
  const pending = /* @__PURE__ */ new Map();
104903
- const enqueueAt = (frame, resolve13) => {
104964
+ const enqueueAt = (frame, resolve14) => {
104904
104965
  const list = pending.get(frame);
104905
104966
  if (list === void 0) {
104906
- pending.set(frame, [resolve13]);
104967
+ pending.set(frame, [resolve14]);
104907
104968
  } else {
104908
- list.push(resolve13);
104969
+ list.push(resolve14);
104909
104970
  }
104910
104971
  };
104911
104972
  const flushAt = (frame) => {
104912
104973
  const list = pending.get(frame);
104913
104974
  if (list === void 0) return;
104914
104975
  pending.delete(frame);
104915
- for (const resolve13 of list) resolve13();
104976
+ for (const resolve14 of list) resolve14();
104916
104977
  };
104917
- const waitForFrame = (frame) => new Promise((resolve13) => {
104978
+ const waitForFrame = (frame) => new Promise((resolve14) => {
104918
104979
  if (frame === cursor) {
104919
- resolve13();
104980
+ resolve14();
104920
104981
  return;
104921
104982
  }
104922
- enqueueAt(frame, resolve13);
104983
+ enqueueAt(frame, resolve14);
104923
104984
  });
104924
104985
  const advanceTo = (frame) => {
104925
104986
  cursor = frame;
104926
104987
  flushAt(frame);
104927
104988
  };
104928
- const waitForAllDone = () => new Promise((resolve13) => {
104989
+ const waitForAllDone = () => new Promise((resolve14) => {
104929
104990
  if (cursor >= endFrame) {
104930
- resolve13();
104991
+ resolve14();
104931
104992
  return;
104932
104993
  }
104933
- enqueueAt(endFrame, resolve13);
104994
+ enqueueAt(endFrame, resolve14);
104934
104995
  });
104935
104996
  return { waitForFrame, advanceTo, waitForAllDone };
104936
104997
  }
@@ -104982,7 +105043,7 @@ function buildStreamingArgs(options, outputPath, gpuEncoder = null) {
104982
105043
  args.push("-c:v", encoderName);
104983
105044
  switch (gpuEncoder) {
104984
105045
  case "nvenc":
104985
- args.push("-preset", preset);
105046
+ args.push("-preset", mapPresetForGpuEncoder("nvenc", preset));
104986
105047
  if (bitrate) args.push("-b:v", bitrate);
104987
105048
  else args.push("-cq", String(quality));
104988
105049
  break;
@@ -105001,7 +105062,7 @@ function buildStreamingArgs(options, outputPath, gpuEncoder = null) {
105001
105062
  else args.push("-qp", String(quality));
105002
105063
  break;
105003
105064
  case "qsv":
105004
- args.push("-preset", preset);
105065
+ args.push("-preset", mapPresetForGpuEncoder("qsv", preset));
105005
105066
  if (bitrate) args.push("-b:v", bitrate);
105006
105067
  else args.push("-global_quality", String(quality));
105007
105068
  break;
@@ -105092,7 +105153,7 @@ async function spawnStreamingEncoder(outputPath, options, signal, config2) {
105092
105153
  let stderr = "";
105093
105154
  let exitCode = null;
105094
105155
  let exitPromiseResolve = null;
105095
- const exitPromise = new Promise((resolve13) => exitPromiseResolve = resolve13);
105156
+ const exitPromise = new Promise((resolve14) => exitPromiseResolve = resolve14);
105096
105157
  ffmpeg.stderr?.on("data", (data) => {
105097
105158
  stderr += data.toString();
105098
105159
  });
@@ -105138,8 +105199,8 @@ Process error: ${err.message}`;
105138
105199
  if (signal) signal.removeEventListener("abort", onAbort);
105139
105200
  const stdin = ffmpeg.stdin;
105140
105201
  if (stdin && !stdin.destroyed) {
105141
- await new Promise((resolve13) => {
105142
- stdin.end(() => resolve13());
105202
+ await new Promise((resolve14) => {
105203
+ stdin.end(() => resolve14());
105143
105204
  });
105144
105205
  }
105145
105206
  await exitPromise;
@@ -105157,7 +105218,7 @@ Process error: ${err.message}`;
105157
105218
  success: false,
105158
105219
  durationMs,
105159
105220
  fileSize: 0,
105160
- error: `FFmpeg exited with code ${exitCode}`
105221
+ error: formatFfmpegError(exitCode, stderr)
105161
105222
  };
105162
105223
  }
105163
105224
  const fileSize = existsSync6(outputPath) ? statSync4(outputPath).size : 0;
@@ -105171,14 +105232,14 @@ Process error: ${err.message}`;
105171
105232
  // ../engine/src/services/videoFrameExtractor.ts
105172
105233
  import { spawn as spawn8 } from "child_process";
105173
105234
  import { existsSync as existsSync8, mkdirSync as mkdirSync5, readdirSync as readdirSync4, rmSync } from "fs";
105174
- import { join as join8 } from "path";
105235
+ import { isAbsolute as isAbsolute2, join as join8 } from "path";
105175
105236
 
105176
105237
  // ../engine/src/utils/ffprobe.ts
105177
105238
  import { spawn as spawn7 } from "child_process";
105178
105239
  import { readFileSync as readFileSync5 } from "fs";
105179
105240
  import { extname as extname2 } from "path";
105180
105241
  function runFfprobe(args) {
105181
- return new Promise((resolve13, reject) => {
105242
+ return new Promise((resolve14, reject) => {
105182
105243
  const proc = spawn7("ffprobe", args);
105183
105244
  let stdout = "";
105184
105245
  let stderr = "";
@@ -105192,7 +105253,7 @@ function runFfprobe(args) {
105192
105253
  if (code !== 0) {
105193
105254
  reject(new Error(`[FFmpeg] ffprobe exited with code ${code}: ${stderr}`));
105194
105255
  } else {
105195
- resolve13(stdout);
105256
+ resolve14(stdout);
105196
105257
  }
105197
105258
  });
105198
105259
  proc.on("error", (err) => {
@@ -105286,7 +105347,7 @@ function parseFrameRate(frameRateStr) {
105286
105347
  }
105287
105348
  return parseFloat(frameRateStr) || 0;
105288
105349
  }
105289
- async function extractVideoMetadata(filePath) {
105350
+ async function extractMediaMetadata(filePath) {
105290
105351
  const cached = videoMetadataCache.get(filePath);
105291
105352
  if (cached) return cached;
105292
105353
  const probePromise = (async () => {
@@ -105572,7 +105633,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
105572
105633
  const { fps, outputDir, quality = 95, format: format3 = "jpg" } = options;
105573
105634
  const videoOutputDir = join8(outputDir, videoId);
105574
105635
  if (!existsSync8(videoOutputDir)) mkdirSync5(videoOutputDir, { recursive: true });
105575
- const metadata = await extractVideoMetadata(videoPath);
105636
+ const metadata = await extractMediaMetadata(videoPath);
105576
105637
  const framePattern = `frame_%05d.${format3}`;
105577
105638
  const outputPattern = join8(videoOutputDir, framePattern);
105578
105639
  const isHdr = isHdrColorSpace(metadata.colorSpace);
@@ -105591,7 +105652,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
105591
105652
  args.push("-q:v", format3 === "jpg" ? String(Math.ceil((100 - quality) / 3)) : "0");
105592
105653
  if (format3 === "png") args.push("-compression_level", "6");
105593
105654
  args.push("-y", outputPattern);
105594
- return new Promise((resolve13, reject) => {
105655
+ return new Promise((resolve14, reject) => {
105595
105656
  const ffmpeg = spawn8("ffmpeg", args);
105596
105657
  let stderr = "";
105597
105658
  const onAbort = () => {
@@ -105626,7 +105687,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
105626
105687
  files.forEach((file, index) => {
105627
105688
  framePaths.set(index, join8(videoOutputDir, file));
105628
105689
  });
105629
- resolve13({
105690
+ resolve14({
105630
105691
  videoId,
105631
105692
  srcPath: videoPath,
105632
105693
  outputDir: videoOutputDir,
@@ -105648,8 +105709,9 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
105648
105709
  });
105649
105710
  });
105650
105711
  }
105651
- async function convertSdrToHdr(inputPath, outputPath, signal, config2) {
105712
+ async function convertSdrToHdr(inputPath, outputPath, targetTransfer, signal, config2) {
105652
105713
  const timeout2 = config2?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
105714
+ const colorTrc = targetTransfer === "pq" ? "smpte2084" : "arib-std-b67";
105653
105715
  const args = [
105654
105716
  "-i",
105655
105717
  inputPath,
@@ -105658,7 +105720,7 @@ async function convertSdrToHdr(inputPath, outputPath, signal, config2) {
105658
105720
  "-color_primaries",
105659
105721
  "bt2020",
105660
105722
  "-color_trc",
105661
- "arib-std-b67",
105723
+ colorTrc,
105662
105724
  "-colorspace",
105663
105725
  "bt2020nc",
105664
105726
  "-c:v",
@@ -105720,7 +105782,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
105720
105782
  if (signal?.aborted) break;
105721
105783
  try {
105722
105784
  let videoPath = video.src;
105723
- if (!videoPath.startsWith("/") && !isHttpUrl(videoPath)) {
105785
+ if (!isAbsolute2(videoPath) && !isHttpUrl(videoPath)) {
105724
105786
  const fromCompiled = compiledDir ? join8(compiledDir, videoPath) : null;
105725
105787
  videoPath = fromCompiled && existsSync8(fromCompiled) ? fromCompiled : join8(baseDir, videoPath);
105726
105788
  }
@@ -105740,12 +105802,13 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
105740
105802
  }
105741
105803
  const videoColorSpaces = await Promise.all(
105742
105804
  resolvedVideos.map(async ({ videoPath }) => {
105743
- const metadata = await extractVideoMetadata(videoPath);
105805
+ const metadata = await extractMediaMetadata(videoPath);
105744
105806
  return metadata.colorSpace;
105745
105807
  })
105746
105808
  );
105747
- const hasAnyHdr = videoColorSpaces.some(isHdrColorSpace);
105748
- if (hasAnyHdr) {
105809
+ const hdrInfo = analyzeCompositionHdr(videoColorSpaces);
105810
+ if (hdrInfo.hasHdr && hdrInfo.dominantTransfer) {
105811
+ const targetTransfer = hdrInfo.dominantTransfer;
105749
105812
  const convertDir = join8(options.outputDir, "_hdr_normalized");
105750
105813
  mkdirSync5(convertDir, { recursive: true });
105751
105814
  for (let i = 0; i < resolvedVideos.length; i++) {
@@ -105756,7 +105819,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
105756
105819
  if (!entry) continue;
105757
105820
  const convertedPath = join8(convertDir, `${entry.video.id}_hdr.mp4`);
105758
105821
  try {
105759
- await convertSdrToHdr(entry.videoPath, convertedPath, signal, config2);
105822
+ await convertSdrToHdr(entry.videoPath, convertedPath, targetTransfer, signal, config2);
105760
105823
  entry.videoPath = convertedPath;
105761
105824
  } catch (err) {
105762
105825
  errors.push({
@@ -105772,7 +105835,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
105772
105835
  if (signal?.aborted) break;
105773
105836
  const entry = resolvedVideos[i];
105774
105837
  if (!entry) continue;
105775
- const metadata = await extractVideoMetadata(entry.videoPath);
105838
+ const metadata = await extractMediaMetadata(entry.videoPath);
105776
105839
  if (!metadata.isVFR) continue;
105777
105840
  let segDuration = entry.video.end - entry.video.start;
105778
105841
  if (!Number.isFinite(segDuration) || segDuration <= 0) {
@@ -105808,7 +105871,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
105808
105871
  try {
105809
105872
  let videoDuration = video.end - video.start;
105810
105873
  if (!Number.isFinite(videoDuration) || videoDuration <= 0) {
105811
- const metadata = await extractVideoMetadata(videoPath);
105874
+ const metadata = await extractMediaMetadata(videoPath);
105812
105875
  const sourceDuration = metadata.durationSeconds - video.mediaStart;
105813
105876
  videoDuration = sourceDuration > 0 ? sourceDuration : metadata.durationSeconds;
105814
105877
  video.end = video.start + videoDuration;
@@ -106061,12 +106124,12 @@ async function queryElementStacking(page, nativeHdrIds) {
106061
106124
  function resolveRadius(value, el) {
106062
106125
  if (value.includes("%")) {
106063
106126
  const pct = parseFloat(value) / 100;
106064
- const htmlEl = el;
106065
- const w = htmlEl.offsetWidth || 0;
106066
- const h = htmlEl.offsetHeight || 0;
106127
+ const w = el instanceof HTMLElement ? el.offsetWidth : 0;
106128
+ const h = el instanceof HTMLElement ? el.offsetHeight : 0;
106067
106129
  return pct * Math.min(w, h);
106068
106130
  }
106069
- return parseFloat(value) || 0;
106131
+ const parsed = parseFloat(value);
106132
+ return Number.isNaN(parsed) ? 0 : parsed;
106070
106133
  }
106071
106134
  const selfCs = window.getComputedStyle(node);
106072
106135
  const selfRadii = [
@@ -106150,8 +106213,7 @@ async function queryElementStacking(page, nativeHdrIds) {
106150
106213
  const style = window.getComputedStyle(el);
106151
106214
  const zIndex = getEffectiveZIndex(el);
106152
106215
  const isHdrEl = hdrSet.has(id);
106153
- const opacityStartNode = isHdrEl ? el.parentElement : el;
106154
- const opacity = opacityStartNode ? getEffectiveOpacity(opacityStartNode) : 1;
106216
+ const opacity = getEffectiveOpacity(el);
106155
106217
  const visible = style.visibility !== "hidden" && style.display !== "none" && rect.width > 0 && rect.height > 0;
106156
106218
  const htmlEl = el instanceof HTMLElement ? el : null;
106157
106219
  results.push({
@@ -106184,7 +106246,7 @@ async function queryElementStacking(page, nativeHdrIds) {
106184
106246
 
106185
106247
  // ../engine/src/services/audioMixer.ts
106186
106248
  import { existsSync as existsSync9, mkdirSync as mkdirSync6, rmSync as rmSync2 } from "fs";
106187
- import { join as join9, dirname as dirname7 } from "path";
106249
+ import { isAbsolute as isAbsolute3, join as join9, dirname as dirname7 } from "path";
106188
106250
  function parseAudioElements(html) {
106189
106251
  const elements = [];
106190
106252
  const { document: document2 } = parseHTML(html);
@@ -106411,7 +106473,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
106411
106473
  }
106412
106474
  try {
106413
106475
  let srcPath = element.src;
106414
- if (!srcPath.startsWith("/") && !isHttpUrl(srcPath)) {
106476
+ if (!isAbsolute3(srcPath) && !isHttpUrl(srcPath)) {
106415
106477
  const fromCompiled = compiledDir ? join9(compiledDir, srcPath) : null;
106416
106478
  srcPath = fromCompiled && existsSync9(fromCompiled) ? fromCompiled : join9(baseDir, srcPath);
106417
106479
  }
@@ -107137,13 +107199,51 @@ function normalizeObjectFit(value) {
107137
107199
  }
107138
107200
  function parseTransformMatrix(css) {
107139
107201
  if (!css || css === "none") return null;
107140
- const match2 = css.match(
107202
+ const match2d = css.match(
107141
107203
  /^matrix\(\s*([^,]+),\s*([^,]+),\s*([^,]+),\s*([^,]+),\s*([^,]+),\s*([^,)]+)\s*\)$/
107142
107204
  );
107143
- if (!match2) return null;
107144
- const values = match2.slice(1, 7).map(Number);
107145
- if (!values.every(Number.isFinite)) return null;
107146
- return values;
107205
+ if (match2d) {
107206
+ const values = match2d.slice(1, 7).map(Number);
107207
+ if (!values.every(Number.isFinite)) return null;
107208
+ return values;
107209
+ }
107210
+ const match3d = css.match(/^matrix3d\(\s*([^)]+)\)$/);
107211
+ if (match3d) {
107212
+ const raw2 = match3d[1];
107213
+ if (!raw2) return null;
107214
+ const parts = raw2.split(",").map((s) => Number(s.trim()));
107215
+ if (parts.length !== 16 || !parts.every(Number.isFinite)) return null;
107216
+ warnIfZSignificant(parts);
107217
+ return [
107218
+ parts[0],
107219
+ parts[1],
107220
+ parts[4],
107221
+ parts[5],
107222
+ parts[12],
107223
+ parts[13]
107224
+ ];
107225
+ }
107226
+ return null;
107227
+ }
107228
+ var warnedZSignificant = false;
107229
+ var Z_EPSILON = 1e-6;
107230
+ function warnIfZSignificant(parts) {
107231
+ if (warnedZSignificant) return;
107232
+ const a3 = parts[8] ?? 0;
107233
+ const b3 = parts[9] ?? 0;
107234
+ const c1 = parts[2] ?? 0;
107235
+ const c2 = parts[6] ?? 0;
107236
+ const c3 = parts[10] ?? 1;
107237
+ const d1 = parts[3] ?? 0;
107238
+ const d2 = parts[7] ?? 0;
107239
+ const d3 = parts[11] ?? 0;
107240
+ const d4 = parts[15] ?? 1;
107241
+ if (Math.abs(a3) > Z_EPSILON || Math.abs(b3) > Z_EPSILON || Math.abs(c1) > Z_EPSILON || Math.abs(c2) > Z_EPSILON || Math.abs(c3 - 1) > Z_EPSILON || Math.abs(d1) > Z_EPSILON || Math.abs(d2) > Z_EPSILON || Math.abs(d3) > Z_EPSILON || Math.abs(d4 - 1) > Z_EPSILON) {
107242
+ warnedZSignificant = true;
107243
+ console.warn(
107244
+ `[alphaBlit] parseTransformMatrix received a matrix3d with non-trivial 3D components (a3=${a3}, b3=${b3}, c1=${c1}, c2=${c2}, c3=${c3}, d1=${d1}, d2=${d2}, d3=${d3}, d4=${d4}). The engine projects 3D transforms to 2D (m11, m12, m21, m22, m41, m42) and silently discards perspective and out-of-plane rotation. If your composition uses real 3D (rotateX/Y, perspective), the rendered output will not match the studio preview. Z translation (translateZ) is dropped by design and does not trigger this warning. This warning is emitted once per process.`
107245
+ );
107246
+ }
107147
107247
  }
107148
107248
 
107149
107249
  // ../engine/src/utils/layerCompositor.ts
@@ -107797,14 +107897,14 @@ var ridgedBurn = (from2, to, out, w, h, p) => {
107797
107897
  TRANSITIONS["ridged-burn"] = ridgedBurn;
107798
107898
 
107799
107899
  // src/services/renderOrchestrator.ts
107800
- import { join as join15, dirname as dirname10, resolve as resolve10 } from "path";
107900
+ import { join as join15, dirname as dirname10, resolve as resolve11 } from "path";
107801
107901
  import { randomUUID } from "crypto";
107802
107902
  import { freemem as freemem2 } from "os";
107803
107903
  import { fileURLToPath as fileURLToPath3 } from "url";
107804
107904
 
107805
107905
  // src/services/fileServer.ts
107806
- import { readFileSync as readFileSync7, existsSync as existsSync12, statSync as statSync5 } from "node:fs";
107807
- import { join as join11, extname as extname4 } from "node:path";
107906
+ import { readFileSync as readFileSync7, existsSync as existsSync12, realpathSync, statSync as statSync5 } from "node:fs";
107907
+ import { join as join11, extname as extname4, resolve as resolve8, sep } from "node:path";
107808
107908
 
107809
107909
  // src/services/hyperframeRuntimeLoader.ts
107810
107910
  import { createHash as createHash2 } from "node:crypto";
@@ -107880,6 +107980,18 @@ function resolveVerifiedHyperframeRuntime() {
107880
107980
  }
107881
107981
 
107882
107982
  // src/services/fileServer.ts
107983
+ function isPathInside(child, parent, options = {}) {
107984
+ const { resolveSymlinks = false, pathModule } = options;
107985
+ const resolveFn = pathModule?.resolve ?? resolve8;
107986
+ const separator = pathModule?.sep ?? sep;
107987
+ const resolvedChild = resolveFn(child);
107988
+ const resolvedParent = resolveFn(parent);
107989
+ const normalizedChild = resolveSymlinks && existsSync12(resolvedChild) ? realpathSync.native(resolvedChild) : resolvedChild;
107990
+ const normalizedParent = resolveSymlinks && existsSync12(resolvedParent) ? realpathSync.native(resolvedParent) : resolvedParent;
107991
+ if (normalizedChild === normalizedParent) return true;
107992
+ const parentWithSep = normalizedParent.endsWith(separator) ? normalizedParent : normalizedParent + separator;
107993
+ return normalizedChild.startsWith(parentWithSep);
107994
+ }
107883
107995
  var MIME_TYPES = {
107884
107996
  ".html": "text/html; charset=utf-8",
107885
107997
  ".css": "text/css; charset=utf-8",
@@ -108272,12 +108384,20 @@ function createFileServer2(options) {
108272
108384
  let requestPath = c.req.path;
108273
108385
  if (requestPath === "/") requestPath = "/index.html";
108274
108386
  const relativePath = requestPath.replace(/^\//, "");
108275
- const compiledPath = compiledDir ? join11(compiledDir, relativePath) : null;
108276
- const hasCompiledFile = Boolean(
108277
- compiledPath && existsSync12(compiledPath) && statSync5(compiledPath).isFile()
108278
- );
108279
- const filePath = hasCompiledFile ? compiledPath : join11(projectDir, relativePath);
108280
- if (!existsSync12(filePath) || !statSync5(filePath).isFile()) {
108387
+ let filePath = null;
108388
+ if (compiledDir) {
108389
+ const candidate = join11(compiledDir, relativePath);
108390
+ if (existsSync12(candidate) && isPathInside(candidate, compiledDir, { resolveSymlinks: true }) && statSync5(candidate).isFile()) {
108391
+ filePath = candidate;
108392
+ }
108393
+ }
108394
+ if (!filePath) {
108395
+ const candidate = join11(projectDir, relativePath);
108396
+ if (existsSync12(candidate) && isPathInside(candidate, projectDir, { resolveSymlinks: true }) && statSync5(candidate).isFile()) {
108397
+ filePath = candidate;
108398
+ }
108399
+ }
108400
+ if (!filePath) {
108281
108401
  if (!/favicon\.ico$/i.test(requestPath)) {
108282
108402
  console.warn(`[FileServer] 404 Not Found: ${requestPath}`);
108283
108403
  }
@@ -108301,10 +108421,10 @@ function createFileServer2(options) {
108301
108421
  headers: { "Content-Type": contentType }
108302
108422
  });
108303
108423
  });
108304
- return new Promise((resolve13) => {
108424
+ return new Promise((resolve14) => {
108305
108425
  const connections = /* @__PURE__ */ new Set();
108306
108426
  const server = serve({ fetch: app.fetch, port }, (info) => {
108307
- resolve13({
108427
+ resolve14({
108308
108428
  url: `http://localhost:${info.port}`,
108309
108429
  port: info.port,
108310
108430
  close: () => {
@@ -108323,18 +108443,18 @@ function createFileServer2(options) {
108323
108443
 
108324
108444
  // src/services/htmlCompiler.ts
108325
108445
  import { readFileSync as readFileSync9, existsSync as existsSync14, mkdirSync as mkdirSync9 } from "fs";
108326
- import { join as join14, dirname as dirname9, resolve as resolve9 } from "path";
108446
+ import { join as join14, dirname as dirname9, resolve as resolve10 } from "path";
108327
108447
  import postcss from "postcss";
108328
108448
 
108329
108449
  // src/utils/paths.ts
108330
- import { resolve as resolve8, basename as basename2, join as join12, relative as relative2, isAbsolute as isAbsolute2 } from "node:path";
108331
- var DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ?? resolve8(new URL(import.meta.url).pathname, "../../..", "renders");
108332
- function isPathInside(childPath, parentPath) {
108333
- const absChild = resolve8(childPath);
108334
- const absParent = resolve8(parentPath);
108450
+ import { resolve as resolve9, basename as basename2, join as join12, relative as relative2, isAbsolute as isAbsolute4 } from "node:path";
108451
+ var DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ?? resolve9(new URL(import.meta.url).pathname, "../../..", "renders");
108452
+ function isPathInside2(childPath, parentPath) {
108453
+ const absChild = resolve9(childPath);
108454
+ const absParent = resolve9(parentPath);
108335
108455
  if (absChild === absParent) return true;
108336
108456
  const rel = relative2(absParent, absChild);
108337
- return rel !== "" && !rel.startsWith("..") && !isAbsolute2(rel);
108457
+ return rel !== "" && !rel.startsWith("..") && !isAbsolute4(rel);
108338
108458
  }
108339
108459
  function toExternalAssetKey(absPath) {
108340
108460
  if (absPath.startsWith("hf-ext/")) return absPath;
@@ -108347,10 +108467,10 @@ function toExternalAssetKey(absPath) {
108347
108467
  return "hf-ext/" + normalised;
108348
108468
  }
108349
108469
  function resolveRenderPaths(projectDir, outputPath, rendersDir = DEFAULT_RENDERS_DIR) {
108350
- const absoluteProjectDir = resolve8(projectDir);
108470
+ const absoluteProjectDir = resolve9(projectDir);
108351
108471
  const projectName = basename2(absoluteProjectDir);
108352
108472
  const resolvedOutputPath = outputPath ?? join12(rendersDir, `${projectName}.mp4`);
108353
- const absoluteOutputPath = resolve8(resolvedOutputPath);
108473
+ const absoluteOutputPath = resolve9(resolvedOutputPath);
108354
108474
  return { absoluteProjectDir, absoluteOutputPath };
108355
108475
  }
108356
108476
 
@@ -108797,7 +108917,7 @@ async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagNa
108797
108917
  if (!existsSync14(filePath)) {
108798
108918
  return { duration: 0, resolvedPath: filePath };
108799
108919
  }
108800
- const metadata = tagName19 === "video" ? await extractVideoMetadata(filePath) : await extractAudioMetadata(filePath);
108920
+ const metadata = tagName19 === "video" ? await extractMediaMetadata(filePath) : await extractAudioMetadata(filePath);
108801
108921
  const fileDuration = metadata.durationSeconds;
108802
108922
  const effectiveDuration = fileDuration - mediaStart;
108803
108923
  const duration = effectiveDuration > 0 ? effectiveDuration : fileDuration;
@@ -108859,7 +108979,7 @@ async function parseSubCompositions(html, projectDir, downloadDir, parentOffset
108859
108979
  const elEnd = elEndRaw ? parseFloat(elEndRaw) : Infinity;
108860
108980
  const absoluteStart = parentOffset + elStart;
108861
108981
  const absoluteEnd = Math.min(parentEnd, isFinite(elEnd) ? parentOffset + elEnd : Infinity);
108862
- const filePath = resolve9(projectDir, srcPath);
108982
+ const filePath = resolve10(projectDir, srcPath);
108863
108983
  if (visited.has(filePath)) {
108864
108984
  continue;
108865
108985
  }
@@ -109072,7 +109192,7 @@ function inlineSubCompositions(html, subCompositions, projectDir) {
109072
109192
  if (!srcPath) continue;
109073
109193
  let compHtml = subCompositions.get(srcPath) || null;
109074
109194
  if (!compHtml) {
109075
- const filePath = resolve9(projectDir, srcPath);
109195
+ const filePath = resolve10(projectDir, srcPath);
109076
109196
  if (existsSync14(filePath)) {
109077
109197
  compHtml = readFileSync9(filePath, "utf-8");
109078
109198
  }
@@ -109289,7 +109409,7 @@ ${safeText}
109289
109409
  return wrappedFragment ? document2.body.innerHTML || "" : document2.toString();
109290
109410
  }
109291
109411
  function collectExternalAssets(html, projectDir) {
109292
- const absProjectDir = resolve9(projectDir);
109412
+ const absProjectDir = resolve10(projectDir);
109293
109413
  const externalAssets = /* @__PURE__ */ new Map();
109294
109414
  const CSS_URL_RE2 = /\burl\(\s*(["']?)([^)"']+)\1\s*\)/g;
109295
109415
  function processPath(rawPath) {
@@ -109297,8 +109417,8 @@ function collectExternalAssets(html, projectDir) {
109297
109417
  if (!trimmed || trimmed.startsWith("/") || trimmed.startsWith("http://") || trimmed.startsWith("https://") || trimmed.startsWith("//") || trimmed.startsWith("data:") || trimmed.startsWith("#")) {
109298
109418
  return null;
109299
109419
  }
109300
- const absPath = resolve9(absProjectDir, trimmed);
109301
- if (isPathInside(absPath, absProjectDir)) {
109420
+ const absPath = resolve10(absProjectDir, trimmed);
109421
+ if (isPathInside2(absPath, absProjectDir)) {
109302
109422
  return null;
109303
109423
  }
109304
109424
  if (!existsSync14(absPath)) return null;
@@ -109378,9 +109498,9 @@ async function compileForRender(projectDir, htmlPath, downloadDir) {
109378
109498
  const images = dedupeElementsById([...mainImages, ...subImages]);
109379
109499
  for (const video of videos) {
109380
109500
  if (isHttpUrl(video.src)) continue;
109381
- const videoPath = resolve9(projectDir, video.src);
109501
+ const videoPath = resolve10(projectDir, video.src);
109382
109502
  const reencode = `ffmpeg -i "${video.src}" -c:v libx264 -r 30 -g 30 -keyint_min 30 -movflags +faststart -c:a copy output.mp4`;
109383
- Promise.all([analyzeKeyframeIntervals(videoPath), extractVideoMetadata(videoPath)]).then(([analysis, metadata]) => {
109503
+ Promise.all([analyzeKeyframeIntervals(videoPath), extractMediaMetadata(videoPath)]).then(([analysis, metadata]) => {
109384
109504
  if (analysis.isProblematic) {
109385
109505
  console.warn(
109386
109506
  `[Compiler] WARNING: Video "${video.id}" has sparse keyframes (max interval: ${analysis.maxIntervalSeconds}s). This causes seek failures and frame freezing. Re-encode with: ${reencode}`
@@ -109579,6 +109699,21 @@ function getMaxFrameIndex(frameDir) {
109579
109699
  frameDirMaxIndexCache.set(frameDir, max);
109580
109700
  return max;
109581
109701
  }
109702
+ function countNonZeroAlpha(rgba) {
109703
+ let n = 0;
109704
+ for (let p = 3; p < rgba.length; p += 4) {
109705
+ if (rgba[p] !== 0) n++;
109706
+ }
109707
+ return n;
109708
+ }
109709
+ function countNonZeroRgb48(buf) {
109710
+ let n = 0;
109711
+ for (let p = 0; p < buf.length; p += 6) {
109712
+ if (buf[p] !== 0 || buf[p + 1] !== 0 || buf[p + 2] !== 0 || buf[p + 3] !== 0 || buf[p + 4] !== 0 || buf[p + 5] !== 0)
109713
+ n++;
109714
+ }
109715
+ return n;
109716
+ }
109582
109717
  var RenderCancelledError = class extends Error {
109583
109718
  reason;
109584
109719
  constructor(message = "render_cancelled", reason = "aborted") {
@@ -109639,8 +109774,8 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
109639
109774
  writeFileSync4(outPath, html, "utf-8");
109640
109775
  }
109641
109776
  for (const [relativePath, absolutePath] of compiled.externalAssets) {
109642
- const outPath = resolve10(join15(compileDir, relativePath));
109643
- if (!isPathInside(outPath, compileDir)) {
109777
+ const outPath = resolve11(join15(compileDir, relativePath));
109778
+ if (!isPathInside2(outPath, compileDir)) {
109644
109779
  console.warn(`[Render] Skipping external asset with unsafe path: ${relativePath}`);
109645
109780
  continue;
109646
109781
  }
@@ -109786,6 +109921,165 @@ function blitHdrImageLayer(canvas, el, hdrImageBuffers, width, height, log, sour
109786
109921
  }
109787
109922
  }
109788
109923
  }
109924
+ async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter, debugFrameIndex = -1) {
109925
+ const {
109926
+ log,
109927
+ domSession,
109928
+ beforeCaptureHook,
109929
+ width,
109930
+ height,
109931
+ fps,
109932
+ effectiveHdr,
109933
+ nativeHdrImageIds,
109934
+ hdrImageBuffers,
109935
+ hdrFrameDirs,
109936
+ hdrVideoStartTimes,
109937
+ imageTransfers,
109938
+ videoTransfers,
109939
+ debugDumpEnabled,
109940
+ debugDumpDir
109941
+ } = ctx;
109942
+ const filteredStacking = elementFilter ? fullStacking.filter((e) => elementFilter.has(e.id)) : fullStacking;
109943
+ const layers = groupIntoLayers(filteredStacking);
109944
+ const shouldLog = debugDumpEnabled && debugFrameIndex >= 0;
109945
+ if (shouldLog) {
109946
+ log.info("[diag] compositeToBuffer plan", {
109947
+ frame: debugFrameIndex,
109948
+ time: time.toFixed(3),
109949
+ filterSize: elementFilter?.size,
109950
+ fullStackingCount: fullStacking.length,
109951
+ filteredCount: filteredStacking.length,
109952
+ layerCount: layers.length,
109953
+ layers: layers.map(
109954
+ (l) => l.type === "hdr" ? {
109955
+ type: "hdr",
109956
+ id: l.element.id,
109957
+ z: l.element.zIndex,
109958
+ visible: l.element.visible,
109959
+ opacity: l.element.opacity,
109960
+ bounds: `${Math.round(l.element.x)},${Math.round(l.element.y)} ${Math.round(l.element.width)}x${Math.round(l.element.height)}`
109961
+ } : { type: "dom", ids: l.elementIds }
109962
+ )
109963
+ });
109964
+ }
109965
+ for (const [layerIdx, layer] of layers.entries()) {
109966
+ if (layer.type === "hdr") {
109967
+ const before2 = shouldLog ? countNonZeroRgb48(canvas) : 0;
109968
+ const isHdrImage = nativeHdrImageIds.has(layer.element.id);
109969
+ if (isHdrImage) {
109970
+ blitHdrImageLayer(
109971
+ canvas,
109972
+ layer.element,
109973
+ hdrImageBuffers,
109974
+ width,
109975
+ height,
109976
+ log,
109977
+ imageTransfers.get(layer.element.id),
109978
+ effectiveHdr.transfer
109979
+ );
109980
+ } else {
109981
+ blitHdrVideoLayer(
109982
+ canvas,
109983
+ layer.element,
109984
+ time,
109985
+ fps,
109986
+ hdrFrameDirs,
109987
+ hdrVideoStartTimes,
109988
+ width,
109989
+ height,
109990
+ log,
109991
+ videoTransfers.get(layer.element.id),
109992
+ effectiveHdr.transfer
109993
+ );
109994
+ }
109995
+ if (shouldLog) {
109996
+ const after2 = countNonZeroRgb48(canvas);
109997
+ if (isHdrImage) {
109998
+ const buf = hdrImageBuffers.get(layer.element.id);
109999
+ log.info("[diag] hdr layer blit", {
110000
+ frame: debugFrameIndex,
110001
+ layerIdx,
110002
+ id: layer.element.id,
110003
+ kind: "image",
110004
+ pixelsAdded: after2 - before2,
110005
+ totalNonZero: after2,
110006
+ bufferDecoded: !!buf,
110007
+ bufferDims: buf ? `${buf.width}x${buf.height}` : null
110008
+ });
110009
+ } else {
110010
+ const frameDir = hdrFrameDirs.get(layer.element.id);
110011
+ const startTime = hdrVideoStartTimes.get(layer.element.id) ?? 0;
110012
+ const localTime = time - startTime;
110013
+ const frameNum = Math.floor(localTime * fps) + 1;
110014
+ const expectedFrame = frameDir ? join15(frameDir, `frame_${String(frameNum).padStart(4, "0")}.png`) : null;
110015
+ log.info("[diag] hdr layer blit", {
110016
+ frame: debugFrameIndex,
110017
+ layerIdx,
110018
+ id: layer.element.id,
110019
+ kind: "video",
110020
+ pixelsAdded: after2 - before2,
110021
+ totalNonZero: after2,
110022
+ startTime,
110023
+ localTime: localTime.toFixed(3),
110024
+ hdrFrameNum: frameNum,
110025
+ expectedFrame,
110026
+ expectedFrameExists: expectedFrame ? existsSync15(expectedFrame) : false
110027
+ });
110028
+ }
110029
+ }
110030
+ } else {
110031
+ const allElementIds = fullStacking.map((e) => e.id);
110032
+ const layerIds = new Set(layer.elementIds);
110033
+ const hideIds = allElementIds.filter((id) => !layerIds.has(id));
110034
+ await domSession.page.evaluate((t) => {
110035
+ if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110036
+ }, time);
110037
+ if (beforeCaptureHook) {
110038
+ await beforeCaptureHook(domSession.page, time);
110039
+ }
110040
+ await applyDomLayerMask(domSession.page, layer.elementIds, hideIds);
110041
+ const domPng = await captureAlphaPng(domSession.page, width, height);
110042
+ await removeDomLayerMask(domSession.page, hideIds);
110043
+ try {
110044
+ const { data: domRgba } = decodePng(domPng);
110045
+ const before2 = shouldLog ? countNonZeroRgb48(canvas) : 0;
110046
+ const alphaPixels = shouldLog ? countNonZeroAlpha(domRgba) : 0;
110047
+ blitRgba8OverRgb48le(domRgba, canvas, width, height, effectiveHdr.transfer);
110048
+ if (shouldLog && debugDumpDir) {
110049
+ const after2 = countNonZeroRgb48(canvas);
110050
+ const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
110051
+ const dumpPath = join15(debugDumpDir, dumpName);
110052
+ writeFileSync4(dumpPath, domPng);
110053
+ log.info("[diag] dom layer blit", {
110054
+ frame: debugFrameIndex,
110055
+ layerIdx,
110056
+ layerIds: layer.elementIds,
110057
+ hideCount: hideIds.length,
110058
+ pngBytes: domPng.length,
110059
+ alphaPixels,
110060
+ pixelsAdded: after2 - before2,
110061
+ totalNonZero: after2,
110062
+ dumpPath
110063
+ });
110064
+ }
110065
+ } catch (err) {
110066
+ log.warn("DOM layer decode/blit failed; skipping overlay", {
110067
+ layerIds: layer.elementIds,
110068
+ error: err instanceof Error ? err.message : String(err)
110069
+ });
110070
+ }
110071
+ }
110072
+ }
110073
+ if (shouldLog && debugDumpDir) {
110074
+ const finalNonZero = countNonZeroRgb48(canvas);
110075
+ log.info("[diag] compositeToBuffer end", {
110076
+ frame: debugFrameIndex,
110077
+ finalNonZeroPixels: finalNonZero,
110078
+ totalPixels: width * height,
110079
+ coverage: (finalNonZero / (width * height) * 100).toFixed(1) + "%"
110080
+ });
110081
+ }
110082
+ }
109789
110083
  function createRenderJob(config2) {
109790
110084
  return {
109791
110085
  id: randomUUID(),
@@ -109827,7 +110121,7 @@ function extractStandaloneEntryFromIndex(indexHtml, entryFile) {
109827
110121
  }
109828
110122
  async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSignal) {
109829
110123
  const moduleDir = dirname10(fileURLToPath3(import.meta.url));
109830
- const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve10(process.env.PRODUCER_RENDERS_DIR, "..") : resolve10(moduleDir, "../..");
110124
+ const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve11(process.env.PRODUCER_RENDERS_DIR, "..") : resolve11(moduleDir, "../..");
109831
110125
  const debugDir = join15(producerRoot, ".debug");
109832
110126
  const workDir = job.config.debug ? join15(debugDir, job.id) : join15(dirname10(outputPath), `work-${job.id}`);
109833
110127
  const pipelineStart = Date.now();
@@ -110130,7 +110424,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
110130
110424
  videoPath = fromCompiled;
110131
110425
  }
110132
110426
  if (!existsSync15(videoPath)) return;
110133
- const meta = await extractVideoMetadata(videoPath);
110427
+ const meta = await extractMediaMetadata(videoPath);
110134
110428
  if (isHdrColorSpace(meta.colorSpace)) {
110135
110429
  nativeHdrVideoIds.add(v.id);
110136
110430
  videoTransfers.set(v.id, detectTransfer(meta.colorSpace));
@@ -110151,7 +110445,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
110151
110445
  imgPath = fromCompiled;
110152
110446
  }
110153
110447
  if (!existsSync15(imgPath)) return null;
110154
- const meta = await extractVideoMetadata(imgPath);
110448
+ const meta = await extractMediaMetadata(imgPath);
110155
110449
  if (isHdrColorSpace(meta.colorSpace)) {
110156
110450
  nativeHdrImageIds.add(img.id);
110157
110451
  imageTransfers.set(img.id, detectTransfer(meta.colorSpace));
@@ -110263,6 +110557,10 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
110263
110557
  format: needsAlpha ? "png" : "jpeg",
110264
110558
  quality: needsAlpha ? void 0 : job.config.quality === "draft" ? 80 : 95
110265
110559
  };
110560
+ const buildHdrCaptureOptions = () => ({
110561
+ ...captureOptions,
110562
+ skipReadinessVideoIds: Array.from(nativeHdrVideoIds)
110563
+ });
110266
110564
  const workerCount = calculateOptimalWorkers(totalFrames, job.config.workers, cfg);
110267
110565
  const FORMAT_EXT = { mp4: ".mp4", webm: ".webm", mov: ".mov" };
110268
110566
  const videoExt = FORMAT_EXT[outputFormat] ?? ".mp4";
@@ -110271,6 +110569,13 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
110271
110569
  const hasHdrContent = effectiveHdr && nativeHdrIds.size > 0;
110272
110570
  const encoderHdr = hasHdrContent ? effectiveHdr : void 0;
110273
110571
  const preset = getEncoderPreset(job.config.quality, outputFormat, encoderHdr);
110572
+ if (job.config.crf != null && job.config.videoBitrate) {
110573
+ log.warn(
110574
+ `[Render] Both crf=${job.config.crf} and videoBitrate=${job.config.videoBitrate} were set. These are mutually exclusive; honoring crf and ignoring videoBitrate. Set only one to silence this warning.`
110575
+ );
110576
+ }
110577
+ const effectiveQuality = job.config.crf ?? preset.quality;
110578
+ const effectiveBitrate = job.config.crf != null ? void 0 : job.config.videoBitrate;
110274
110579
  job.framesRendered = 0;
110275
110580
  if (hasHdrContent) {
110276
110581
  log.info("[Render] HDR layered composite: z-ordered DOM + native HLG video layers");
@@ -110290,516 +110595,440 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
110290
110595
  const domSession = await createCaptureSession(
110291
110596
  fileServer.url,
110292
110597
  framesDir,
110293
- { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
110598
+ buildHdrCaptureOptions(),
110294
110599
  createVideoFrameInjector(frameLookup),
110295
110600
  cfg
110296
110601
  );
110297
- await initializeSession(domSession);
110298
- assertNotAborted();
110299
- lastBrowserConsole = domSession.browserConsoleBuffer;
110300
- await initTransparentBackground(domSession.page);
110301
- const transitionMeta = await domSession.page.evaluate(() => {
110302
- return window.__hf?.transitions ?? [];
110303
- });
110304
- const sceneElements = await domSession.page.evaluate(() => {
110305
- const scenes = document.querySelectorAll(".scene");
110306
- const map2 = {};
110307
- for (const scene of scenes) {
110308
- const els = scene.querySelectorAll("[data-start]");
110309
- map2[scene.id] = Array.from(els).map((e) => e.id);
110310
- }
110311
- return map2;
110312
- });
110313
- const transitionRanges = transitionMeta.map((t) => ({
110314
- ...t,
110315
- startFrame: Math.floor(t.time * job.config.fps),
110316
- endFrame: Math.ceil((t.time + t.duration) * job.config.fps)
110317
- }));
110318
- if (transitionRanges.length > 0) {
110319
- log.info("[Render] Detected shader transitions for HDR compositing", {
110320
- count: transitionRanges.length,
110321
- transitions: transitionRanges.map((t) => ({
110322
- shader: t.shader,
110323
- from: t.fromScene,
110324
- to: t.toScene,
110325
- frames: `${t.startFrame}-${t.endFrame}`
110326
- }))
110327
- });
110328
- }
110329
- const hdrEncoder = await spawnStreamingEncoder(
110330
- videoOnlyPath,
110331
- {
110332
- fps: job.config.fps,
110333
- width,
110334
- height,
110335
- codec: preset.codec,
110336
- preset: preset.preset,
110337
- quality: preset.quality,
110338
- pixelFormat: preset.pixelFormat,
110339
- hdr: preset.hdr,
110340
- rawInputFormat: "rgb48le"
110341
- },
110342
- abortSignal,
110343
- { ffmpegStreamingTimeout: 36e5 }
110344
- );
110345
- assertNotAborted();
110346
- const hdrExtractionDims = /* @__PURE__ */ new Map();
110347
- const hdrImageFitInfo = /* @__PURE__ */ new Map();
110348
- const hdrVideoStartTimes = /* @__PURE__ */ new Map();
110349
- for (const v of composition.videos) {
110350
- if (hdrVideoIds.includes(v.id)) {
110351
- hdrVideoStartTimes.set(v.id, v.start);
110352
- }
110353
- }
110354
- const hdrImageStartTimes = /* @__PURE__ */ new Map();
110355
- for (const img of composition.images) {
110356
- if (nativeHdrImageIds.has(img.id)) {
110357
- hdrImageStartTimes.set(img.id, img.start);
110358
- }
110359
- }
110360
- const uniqueStartTimes = [
110361
- .../* @__PURE__ */ new Set([...hdrVideoStartTimes.values(), ...hdrImageStartTimes.values()])
110362
- ].sort((a, b) => a - b);
110363
- for (const seekTime of uniqueStartTimes) {
110364
- await domSession.page.evaluate((t) => {
110365
- if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110366
- }, seekTime);
110367
- if (domSession.onBeforeCapture) {
110368
- await domSession.onBeforeCapture(domSession.page, seekTime);
110369
- }
110370
- const stacking = await queryElementStacking(domSession.page, nativeHdrIds);
110371
- for (const el of stacking) {
110372
- if (el.isHdr && el.layoutWidth > 0 && el.layoutHeight > 0 && !hdrExtractionDims.has(el.id)) {
110373
- hdrExtractionDims.set(el.id, { width: el.layoutWidth, height: el.layoutHeight });
110374
- }
110375
- if (el.isHdr && nativeHdrImageIds.has(el.id) && !hdrImageFitInfo.has(el.id)) {
110376
- hdrImageFitInfo.set(el.id, {
110377
- fit: el.objectFit,
110378
- position: el.objectPosition
110379
- });
110380
- }
110381
- }
110382
- }
110602
+ let hdrEncoder = null;
110603
+ let hdrEncoderClosed = false;
110604
+ let domSessionClosed = false;
110383
110605
  const hdrFrameDirs = /* @__PURE__ */ new Map();
110384
- for (const [videoId, srcPath] of hdrVideoSrcPaths) {
110385
- const video = composition.videos.find((v) => v.id === videoId);
110386
- if (!video) continue;
110387
- const frameDir = join15(framesDir, `hdr_${videoId}`);
110388
- mkdirSync10(frameDir, { recursive: true });
110389
- const duration = video.end - video.start;
110390
- const dims = hdrExtractionDims.get(videoId) ?? { width, height };
110391
- const ffmpegArgs = [
110392
- "-ss",
110393
- String(video.mediaStart),
110394
- "-i",
110395
- srcPath,
110396
- "-t",
110397
- String(duration),
110398
- "-r",
110399
- String(job.config.fps),
110400
- "-vf",
110401
- `scale=${dims.width}:${dims.height}:force_original_aspect_ratio=increase,crop=${dims.width}:${dims.height}`,
110402
- "-pix_fmt",
110403
- "rgb48le",
110404
- "-c:v",
110405
- "png",
110406
- "-y",
110407
- join15(frameDir, "frame_%04d.png")
110408
- ];
110409
- const result = await runFfmpeg(ffmpegArgs, { signal: abortSignal });
110410
- if (!result.success) {
110411
- hdrDiagnostics.videoExtractionFailures += 1;
110412
- log.error("HDR frame pre-extraction failed; aborting render", {
110413
- videoId,
110414
- srcPath,
110415
- stderr: result.stderr.slice(-400)
110416
- });
110417
- throw new Error(
110418
- `HDR frame extraction failed for video "${videoId}". Aborting render to avoid shipping black HDR layers.`
110419
- );
110420
- }
110421
- hdrFrameDirs.set(videoId, frameDir);
110422
- }
110423
- const hdrImageBuffers = /* @__PURE__ */ new Map();
110424
- for (const [imageId, srcPath] of hdrImageSrcPaths) {
110425
- try {
110426
- const decoded = decodePngToRgb48le(readFileSync10(srcPath));
110427
- const layout2 = hdrExtractionDims.get(imageId);
110428
- const fitInfo = hdrImageFitInfo.get(imageId);
110429
- if (layout2 && (layout2.width !== decoded.width || layout2.height !== decoded.height)) {
110430
- const fit = normalizeObjectFit(fitInfo?.fit);
110431
- const resampled = resampleRgb48leObjectFit(
110432
- decoded.data,
110433
- decoded.width,
110434
- decoded.height,
110435
- layout2.width,
110436
- layout2.height,
110437
- fit,
110438
- fitInfo?.position
110439
- );
110440
- hdrImageBuffers.set(imageId, {
110441
- data: resampled,
110442
- width: layout2.width,
110443
- height: layout2.height
110444
- });
110445
- } else {
110446
- hdrImageBuffers.set(imageId, {
110447
- data: Buffer.from(decoded.data),
110448
- width: decoded.width,
110449
- height: decoded.height
110450
- });
110606
+ try {
110607
+ await initializeSession(domSession);
110608
+ assertNotAborted();
110609
+ lastBrowserConsole = domSession.browserConsoleBuffer;
110610
+ await initTransparentBackground(domSession.page);
110611
+ const transitionMeta = await domSession.page.evaluate(() => {
110612
+ return window.__hf?.transitions ?? [];
110613
+ });
110614
+ const sceneElements = await domSession.page.evaluate(() => {
110615
+ const scenes = document.querySelectorAll(".scene");
110616
+ const map2 = {};
110617
+ for (const scene of scenes) {
110618
+ const els = scene.querySelectorAll("[data-start]");
110619
+ map2[scene.id] = Array.from(els).map((e) => e.id);
110451
110620
  }
110452
- } catch (err) {
110453
- hdrDiagnostics.imageDecodeFailures += 1;
110454
- log.error("HDR image decode failed; aborting render", {
110455
- imageId,
110456
- srcPath,
110457
- error: err instanceof Error ? err.message : String(err)
110621
+ return map2;
110622
+ });
110623
+ const transitionRanges = transitionMeta.map((t) => ({
110624
+ ...t,
110625
+ startFrame: Math.floor(t.time * job.config.fps),
110626
+ endFrame: Math.ceil((t.time + t.duration) * job.config.fps)
110627
+ }));
110628
+ if (transitionRanges.length > 0) {
110629
+ log.info("[Render] Detected shader transitions for HDR compositing", {
110630
+ count: transitionRanges.length,
110631
+ transitions: transitionRanges.map((t) => ({
110632
+ shader: t.shader,
110633
+ from: t.fromScene,
110634
+ to: t.toScene,
110635
+ frames: `${t.startFrame}-${t.endFrame}`
110636
+ }))
110458
110637
  });
110459
- throw new Error(
110460
- `HDR image decode failed for image "${imageId}". Aborting render to avoid shipping missing HDR image layers.`
110461
- );
110462
110638
  }
110463
- }
110464
- assertNotAborted();
110465
- try {
110466
- let countNonZeroAlpha2 = function(rgba) {
110467
- let n = 0;
110468
- for (let p = 3; p < rgba.length; p += 4) {
110469
- if (rgba[p] !== 0) n++;
110639
+ hdrEncoder = await spawnStreamingEncoder(
110640
+ videoOnlyPath,
110641
+ {
110642
+ fps: job.config.fps,
110643
+ width,
110644
+ height,
110645
+ codec: preset.codec,
110646
+ preset: preset.preset,
110647
+ quality: effectiveQuality,
110648
+ bitrate: effectiveBitrate,
110649
+ pixelFormat: preset.pixelFormat,
110650
+ hdr: preset.hdr,
110651
+ rawInputFormat: "rgb48le"
110652
+ },
110653
+ abortSignal,
110654
+ { ffmpegStreamingTimeout: 36e5 }
110655
+ );
110656
+ assertNotAborted();
110657
+ const hdrExtractionDims = /* @__PURE__ */ new Map();
110658
+ const hdrImageFitInfo = /* @__PURE__ */ new Map();
110659
+ const hdrVideoStartTimes = /* @__PURE__ */ new Map();
110660
+ for (const v of composition.videos) {
110661
+ if (hdrVideoIds.includes(v.id)) {
110662
+ hdrVideoStartTimes.set(v.id, v.start);
110470
110663
  }
110471
- return n;
110472
- }, countNonZeroRgb482 = function(buf) {
110473
- let n = 0;
110474
- for (let p = 0; p < buf.length; p += 6) {
110475
- if (buf[p] !== 0 || buf[p + 1] !== 0 || buf[p + 2] !== 0) n++;
110664
+ }
110665
+ const hdrImageStartTimes = /* @__PURE__ */ new Map();
110666
+ for (const img of composition.images) {
110667
+ if (nativeHdrImageIds.has(img.id)) {
110668
+ hdrImageStartTimes.set(img.id, img.start);
110476
110669
  }
110477
- return n;
110478
- };
110479
- var countNonZeroAlpha = countNonZeroAlpha2, countNonZeroRgb48 = countNonZeroRgb482;
110480
- const beforeCaptureHook = domSession.onBeforeCapture;
110481
- const cleanedUpVideos = /* @__PURE__ */ new Set();
110482
- const hdrVideoEndTimes = /* @__PURE__ */ new Map();
110483
- for (const v of composition.videos) {
110484
- if (hdrFrameDirs.has(v.id)) {
110485
- hdrVideoEndTimes.set(v.id, v.end);
110486
- }
110487
- }
110488
- const debugDumpEnabled = process.env.KEEP_TEMP === "1";
110489
- const debugDumpDir = debugDumpEnabled ? join15(framesDir, "debug-composite") : null;
110490
- if (debugDumpDir && !existsSync15(debugDumpDir)) {
110491
- mkdirSync10(debugDumpDir, { recursive: true });
110492
- }
110493
- async function compositeToBuffer(canvas, time, fullStacking, elementFilter, debugFrameIndex = -1) {
110494
- const filteredStacking = elementFilter ? fullStacking.filter((e) => elementFilter.has(e.id)) : fullStacking;
110495
- const layers = groupIntoLayers(filteredStacking);
110496
- const shouldLog = debugDumpEnabled && debugFrameIndex >= 0;
110497
- if (shouldLog) {
110498
- log.info("[diag] compositeToBuffer plan", {
110499
- frame: debugFrameIndex,
110500
- time: time.toFixed(3),
110501
- filterSize: elementFilter?.size,
110502
- fullStackingCount: fullStacking.length,
110503
- filteredCount: filteredStacking.length,
110504
- layerCount: layers.length,
110505
- layers: layers.map(
110506
- (l) => l.type === "hdr" ? {
110507
- type: "hdr",
110508
- id: l.element.id,
110509
- z: l.element.zIndex,
110510
- visible: l.element.visible,
110511
- opacity: l.element.opacity,
110512
- bounds: `${Math.round(l.element.x)},${Math.round(l.element.y)} ${Math.round(l.element.width)}x${Math.round(l.element.height)}`
110513
- } : { type: "dom", ids: l.elementIds }
110514
- )
110515
- });
110670
+ }
110671
+ const uniqueStartTimes = [
110672
+ .../* @__PURE__ */ new Set([...hdrVideoStartTimes.values(), ...hdrImageStartTimes.values()])
110673
+ ].sort((a, b) => a - b);
110674
+ for (const seekTime of uniqueStartTimes) {
110675
+ await domSession.page.evaluate((t) => {
110676
+ if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110677
+ }, seekTime);
110678
+ if (domSession.onBeforeCapture) {
110679
+ await domSession.onBeforeCapture(domSession.page, seekTime);
110680
+ }
110681
+ const stacking = await queryElementStacking(domSession.page, nativeHdrIds);
110682
+ for (const el of stacking) {
110683
+ if (el.isHdr && el.layoutWidth > 0 && el.layoutHeight > 0 && !hdrExtractionDims.has(el.id)) {
110684
+ hdrExtractionDims.set(el.id, { width: el.layoutWidth, height: el.layoutHeight });
110685
+ }
110686
+ if (el.isHdr && nativeHdrImageIds.has(el.id) && !hdrImageFitInfo.has(el.id)) {
110687
+ hdrImageFitInfo.set(el.id, {
110688
+ fit: el.objectFit,
110689
+ position: el.objectPosition
110690
+ });
110691
+ }
110516
110692
  }
110517
- for (const [layerIdx, layer] of layers.entries()) {
110518
- if (layer.type === "hdr") {
110519
- const before2 = shouldLog ? countNonZeroRgb482(canvas) : 0;
110520
- const isHdrImage = nativeHdrImageIds.has(layer.element.id);
110521
- if (isHdrImage) {
110522
- blitHdrImageLayer(
110523
- canvas,
110524
- layer.element,
110525
- hdrImageBuffers,
110526
- width,
110527
- height,
110528
- log,
110529
- imageTransfers.get(layer.element.id),
110530
- effectiveHdr?.transfer
110531
- );
110532
- } else {
110533
- blitHdrVideoLayer(
110534
- canvas,
110535
- layer.element,
110536
- time,
110537
- job.config.fps,
110538
- hdrFrameDirs,
110539
- hdrVideoStartTimes,
110540
- width,
110541
- height,
110542
- log,
110543
- videoTransfers.get(layer.element.id),
110544
- effectiveHdr?.transfer
110545
- );
110546
- }
110547
- if (shouldLog) {
110548
- const after2 = countNonZeroRgb482(canvas);
110549
- if (isHdrImage) {
110550
- const buf = hdrImageBuffers.get(layer.element.id);
110551
- log.info("[diag] hdr layer blit", {
110552
- frame: debugFrameIndex,
110553
- layerIdx,
110554
- id: layer.element.id,
110555
- kind: "image",
110556
- pixelsAdded: after2 - before2,
110557
- totalNonZero: after2,
110558
- bufferDecoded: !!buf,
110559
- bufferDims: buf ? `${buf.width}x${buf.height}` : null
110560
- });
110561
- } else {
110562
- const frameDir = hdrFrameDirs.get(layer.element.id);
110563
- const startTime = hdrVideoStartTimes.get(layer.element.id) ?? 0;
110564
- const localTime = time - startTime;
110565
- const frameNum = Math.floor(localTime * job.config.fps) + 1;
110566
- const expectedFrame = frameDir ? join15(frameDir, `frame_${String(frameNum).padStart(4, "0")}.png`) : null;
110567
- log.info("[diag] hdr layer blit", {
110568
- frame: debugFrameIndex,
110569
- layerIdx,
110570
- id: layer.element.id,
110571
- kind: "video",
110572
- pixelsAdded: after2 - before2,
110573
- totalNonZero: after2,
110574
- startTime,
110575
- localTime: localTime.toFixed(3),
110576
- hdrFrameNum: frameNum,
110577
- expectedFrame,
110578
- expectedFrameExists: expectedFrame ? existsSync15(expectedFrame) : false
110579
- });
110580
- }
110581
- }
110582
- } else {
110583
- const allElementIds = fullStacking.map((e) => e.id);
110584
- const layerIds = new Set(layer.elementIds);
110585
- const hideIds = allElementIds.filter((id) => !layerIds.has(id));
110586
- await domSession.page.evaluate((t) => {
110587
- if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110588
- }, time);
110589
- if (beforeCaptureHook) {
110590
- await beforeCaptureHook(domSession.page, time);
110591
- }
110592
- await applyDomLayerMask(domSession.page, layer.elementIds, hideIds);
110593
- const domPng = await captureAlphaPng(domSession.page, width, height);
110594
- await removeDomLayerMask(domSession.page, hideIds);
110595
- try {
110596
- const { data: domRgba } = decodePng(domPng);
110597
- if (!effectiveHdr) {
110598
- throw new Error(
110599
- "Invariant violation: effectiveHdr is undefined inside HDR layer branch"
110600
- );
110601
- }
110602
- const before2 = shouldLog ? countNonZeroRgb482(canvas) : 0;
110603
- const alphaPixels = shouldLog ? countNonZeroAlpha2(domRgba) : 0;
110604
- blitRgba8OverRgb48le(domRgba, canvas, width, height, effectiveHdr.transfer);
110605
- if (shouldLog && debugDumpDir) {
110606
- const after2 = countNonZeroRgb482(canvas);
110607
- const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
110608
- const dumpPath = join15(debugDumpDir, dumpName);
110609
- writeFileSync4(dumpPath, domPng);
110610
- log.info("[diag] dom layer blit", {
110611
- frame: debugFrameIndex,
110612
- layerIdx,
110613
- layerIds: layer.elementIds,
110614
- hideCount: hideIds.length,
110615
- pngBytes: domPng.length,
110616
- alphaPixels,
110617
- pixelsAdded: after2 - before2,
110618
- totalNonZero: after2,
110619
- dumpPath
110620
- });
110621
- }
110622
- } catch (err) {
110623
- log.warn("DOM layer decode/blit failed; skipping overlay", {
110624
- layerIds: layer.elementIds,
110625
- error: err instanceof Error ? err.message : String(err)
110626
- });
110693
+ }
110694
+ for (const [imageId, startTime] of hdrImageStartTimes) {
110695
+ if (hdrExtractionDims.has(imageId)) continue;
110696
+ const img = composition.images.find((i) => i.id === imageId);
110697
+ if (!img) continue;
110698
+ const duration = img.end - img.start;
110699
+ const retryTime = startTime + Math.min(0.5, duration * 0.1);
110700
+ await domSession.page.evaluate((t) => {
110701
+ if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110702
+ }, retryTime);
110703
+ if (domSession.onBeforeCapture) {
110704
+ await domSession.onBeforeCapture(domSession.page, retryTime);
110705
+ }
110706
+ const retryStacking = await queryElementStacking(domSession.page, nativeHdrIds);
110707
+ for (const el of retryStacking) {
110708
+ if (el.id === imageId && el.isHdr && el.layoutWidth > 0 && el.layoutHeight > 0) {
110709
+ hdrExtractionDims.set(el.id, { width: el.layoutWidth, height: el.layoutHeight });
110710
+ if (!hdrImageFitInfo.has(el.id)) {
110711
+ hdrImageFitInfo.set(el.id, { fit: el.objectFit, position: el.objectPosition });
110627
110712
  }
110713
+ break;
110628
110714
  }
110629
110715
  }
110630
- if (shouldLog && debugDumpDir) {
110631
- const finalNonZero = countNonZeroRgb482(canvas);
110632
- log.info("[diag] compositeToBuffer end", {
110633
- frame: debugFrameIndex,
110634
- finalNonZeroPixels: finalNonZero,
110635
- totalPixels: width * height,
110636
- coverage: (finalNonZero / (width * height) * 100).toFixed(1) + "%"
110716
+ }
110717
+ for (const [videoId, srcPath] of hdrVideoSrcPaths) {
110718
+ const video = composition.videos.find((v) => v.id === videoId);
110719
+ if (!video) continue;
110720
+ const frameDir = join15(framesDir, `hdr_${videoId}`);
110721
+ mkdirSync10(frameDir, { recursive: true });
110722
+ const duration = video.end - video.start;
110723
+ const dims = hdrExtractionDims.get(videoId) ?? { width, height };
110724
+ const ffmpegArgs = [
110725
+ "-ss",
110726
+ String(video.mediaStart),
110727
+ "-i",
110728
+ srcPath,
110729
+ "-t",
110730
+ String(duration),
110731
+ "-r",
110732
+ String(job.config.fps),
110733
+ "-vf",
110734
+ `scale=${dims.width}:${dims.height}:force_original_aspect_ratio=increase,crop=${dims.width}:${dims.height}`,
110735
+ "-pix_fmt",
110736
+ "rgb48le",
110737
+ "-c:v",
110738
+ "png",
110739
+ "-y",
110740
+ join15(frameDir, "frame_%04d.png")
110741
+ ];
110742
+ const result = await runFfmpeg(ffmpegArgs, { signal: abortSignal });
110743
+ if (!result.success) {
110744
+ hdrDiagnostics.videoExtractionFailures += 1;
110745
+ log.error("HDR frame pre-extraction failed; aborting render", {
110746
+ videoId,
110747
+ srcPath,
110748
+ stderr: result.stderr.slice(-400)
110637
110749
  });
110750
+ throw new Error(
110751
+ `HDR frame extraction failed for video "${videoId}". Aborting render to avoid shipping black HDR layers.`
110752
+ );
110638
110753
  }
110754
+ hdrFrameDirs.set(videoId, frameDir);
110639
110755
  }
110640
- const bufSize = width * height * 6;
110641
- const hasTransitions = transitionRanges.length > 0;
110642
- const transBufferA = hasTransitions ? Buffer.alloc(bufSize) : null;
110643
- const transBufferB = hasTransitions ? Buffer.alloc(bufSize) : null;
110644
- const transOutput = hasTransitions ? Buffer.alloc(bufSize) : null;
110645
- const normalCanvas = Buffer.alloc(bufSize);
110646
- for (let i = 0; i < totalFrames; i++) {
110647
- assertNotAborted();
110648
- const time = i / job.config.fps;
110649
- await domSession.page.evaluate((t) => {
110650
- if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110651
- }, time);
110652
- if (beforeCaptureHook) {
110653
- await beforeCaptureHook(domSession.page, time);
110654
- }
110655
- const stackingInfo = await queryElementStacking(domSession.page, nativeHdrIds);
110656
- const activeTransition = transitionRanges.find(
110657
- (t) => i >= t.startFrame && i <= t.endFrame
110658
- );
110659
- if (i % 30 === 0) {
110660
- const hdrEl = stackingInfo.find((e) => e.isHdr);
110661
- log.debug("[Render] HDR layer composite frame", {
110662
- frame: i,
110663
- time: time.toFixed(2),
110664
- hdrElement: hdrEl ? { z: hdrEl.zIndex, visible: hdrEl.visible, width: hdrEl.width } : null,
110665
- stackingCount: stackingInfo.length,
110666
- activeTransition: activeTransition?.shader
110756
+ const hdrImageBuffers = /* @__PURE__ */ new Map();
110757
+ for (const [imageId, srcPath] of hdrImageSrcPaths) {
110758
+ try {
110759
+ const decoded = decodePngToRgb48le(readFileSync10(srcPath));
110760
+ const layout2 = hdrExtractionDims.get(imageId);
110761
+ const fitInfo = hdrImageFitInfo.get(imageId);
110762
+ if (layout2 && (layout2.width !== decoded.width || layout2.height !== decoded.height)) {
110763
+ const fit = normalizeObjectFit(fitInfo?.fit);
110764
+ const resampled = resampleRgb48leObjectFit(
110765
+ decoded.data,
110766
+ decoded.width,
110767
+ decoded.height,
110768
+ layout2.width,
110769
+ layout2.height,
110770
+ fit,
110771
+ fitInfo?.position
110772
+ );
110773
+ hdrImageBuffers.set(imageId, {
110774
+ data: resampled,
110775
+ width: layout2.width,
110776
+ height: layout2.height
110777
+ });
110778
+ } else {
110779
+ hdrImageBuffers.set(imageId, {
110780
+ data: Buffer.from(decoded.data),
110781
+ width: decoded.width,
110782
+ height: decoded.height
110783
+ });
110784
+ }
110785
+ } catch (err) {
110786
+ hdrDiagnostics.imageDecodeFailures += 1;
110787
+ log.error("HDR image decode failed; aborting render", {
110788
+ imageId,
110789
+ srcPath,
110790
+ error: err instanceof Error ? err.message : String(err)
110667
110791
  });
110792
+ throw new Error(
110793
+ `HDR image decode failed for image "${imageId}". Aborting render to avoid shipping missing HDR image layers.`
110794
+ );
110668
110795
  }
110669
- if (activeTransition && transBufferA && transBufferB && transOutput) {
110670
- const progress = activeTransition.endFrame === activeTransition.startFrame ? 1 : (i - activeTransition.startFrame) / (activeTransition.endFrame - activeTransition.startFrame);
110671
- const sceneAIds = new Set(sceneElements[activeTransition.fromScene] ?? []);
110672
- const sceneBIds = new Set(sceneElements[activeTransition.toScene] ?? []);
110673
- transBufferA.fill(0);
110674
- transBufferB.fill(0);
110675
- for (const [sceneBuf, sceneIds] of [
110676
- [transBufferA, sceneAIds],
110677
- [transBufferB, sceneBIds]
110678
- ]) {
110679
- await domSession.page.evaluate((t) => {
110680
- if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110681
- }, time);
110682
- if (beforeCaptureHook) {
110683
- await beforeCaptureHook(domSession.page, time);
110684
- }
110685
- for (const el of stackingInfo) {
110686
- if (!el.isHdr || !sceneIds.has(el.id)) continue;
110687
- if (nativeHdrImageIds.has(el.id)) {
110688
- blitHdrImageLayer(
110689
- sceneBuf,
110690
- el,
110691
- hdrImageBuffers,
110692
- width,
110693
- height,
110694
- log,
110695
- imageTransfers.get(el.id),
110696
- effectiveHdr?.transfer
110697
- );
110698
- } else {
110699
- blitHdrVideoLayer(
110796
+ }
110797
+ assertNotAborted();
110798
+ try {
110799
+ const beforeCaptureHook = domSession.onBeforeCapture;
110800
+ const cleanedUpVideos = /* @__PURE__ */ new Set();
110801
+ const hdrVideoEndTimes = /* @__PURE__ */ new Map();
110802
+ for (const v of composition.videos) {
110803
+ if (hdrFrameDirs.has(v.id)) {
110804
+ hdrVideoEndTimes.set(v.id, v.end);
110805
+ }
110806
+ }
110807
+ const debugDumpEnabled = process.env.KEEP_TEMP === "1";
110808
+ const debugDumpDir = debugDumpEnabled ? join15(framesDir, "debug-composite") : null;
110809
+ if (debugDumpDir && !existsSync15(debugDumpDir)) {
110810
+ mkdirSync10(debugDumpDir, { recursive: true });
110811
+ }
110812
+ if (!effectiveHdr) {
110813
+ throw new Error(
110814
+ "Internal: HDR render path entered without effectiveHdr \u2014 this is a bug."
110815
+ );
110816
+ }
110817
+ const hdrCompositeCtx = {
110818
+ log,
110819
+ domSession,
110820
+ beforeCaptureHook,
110821
+ width,
110822
+ height,
110823
+ fps: job.config.fps,
110824
+ effectiveHdr,
110825
+ nativeHdrImageIds,
110826
+ hdrImageBuffers,
110827
+ hdrFrameDirs,
110828
+ hdrVideoStartTimes,
110829
+ imageTransfers,
110830
+ videoTransfers,
110831
+ debugDumpEnabled,
110832
+ debugDumpDir
110833
+ };
110834
+ const bufSize = width * height * 6;
110835
+ const hasTransitions = transitionRanges.length > 0;
110836
+ const transBufferA = hasTransitions ? Buffer.alloc(bufSize) : null;
110837
+ const transBufferB = hasTransitions ? Buffer.alloc(bufSize) : null;
110838
+ const transOutput = hasTransitions ? Buffer.alloc(bufSize) : null;
110839
+ const normalCanvas = Buffer.alloc(bufSize);
110840
+ for (let i = 0; i < totalFrames; i++) {
110841
+ assertNotAborted();
110842
+ const time = i / job.config.fps;
110843
+ await domSession.page.evaluate((t) => {
110844
+ if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110845
+ }, time);
110846
+ if (beforeCaptureHook) {
110847
+ await beforeCaptureHook(domSession.page, time);
110848
+ }
110849
+ const stackingInfo = await queryElementStacking(domSession.page, nativeHdrIds);
110850
+ const activeTransition = transitionRanges.find(
110851
+ (t) => i >= t.startFrame && i <= t.endFrame
110852
+ );
110853
+ if (i % 30 === 0) {
110854
+ const hdrEl = stackingInfo.find((e) => e.isHdr);
110855
+ log.debug("[Render] HDR layer composite frame", {
110856
+ frame: i,
110857
+ time: time.toFixed(2),
110858
+ hdrElement: hdrEl ? { z: hdrEl.zIndex, visible: hdrEl.visible, width: hdrEl.width } : null,
110859
+ stackingCount: stackingInfo.length,
110860
+ activeTransition: activeTransition?.shader
110861
+ });
110862
+ }
110863
+ if (activeTransition && transBufferA && transBufferB && transOutput) {
110864
+ const progress = activeTransition.endFrame === activeTransition.startFrame ? 1 : (i - activeTransition.startFrame) / (activeTransition.endFrame - activeTransition.startFrame);
110865
+ const sceneAIds = new Set(sceneElements[activeTransition.fromScene] ?? []);
110866
+ const sceneBIds = new Set(sceneElements[activeTransition.toScene] ?? []);
110867
+ transBufferA.fill(0);
110868
+ transBufferB.fill(0);
110869
+ for (const [sceneBuf, sceneIds] of [
110870
+ [transBufferA, sceneAIds],
110871
+ [transBufferB, sceneBIds]
110872
+ ]) {
110873
+ assertNotAborted();
110874
+ await domSession.page.evaluate((t) => {
110875
+ if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110876
+ }, time);
110877
+ if (beforeCaptureHook) {
110878
+ await beforeCaptureHook(domSession.page, time);
110879
+ }
110880
+ for (const el of stackingInfo) {
110881
+ if (!el.isHdr || !sceneIds.has(el.id)) continue;
110882
+ if (nativeHdrImageIds.has(el.id)) {
110883
+ blitHdrImageLayer(
110884
+ sceneBuf,
110885
+ el,
110886
+ hdrImageBuffers,
110887
+ width,
110888
+ height,
110889
+ log,
110890
+ imageTransfers.get(el.id),
110891
+ effectiveHdr?.transfer
110892
+ );
110893
+ } else {
110894
+ blitHdrVideoLayer(
110895
+ sceneBuf,
110896
+ el,
110897
+ time,
110898
+ job.config.fps,
110899
+ hdrFrameDirs,
110900
+ hdrVideoStartTimes,
110901
+ width,
110902
+ height,
110903
+ log,
110904
+ videoTransfers.get(el.id),
110905
+ effectiveHdr?.transfer
110906
+ );
110907
+ }
110908
+ }
110909
+ const showIds = Array.from(sceneIds);
110910
+ const hideIds = stackingInfo.map((e) => e.id).filter((id) => !sceneIds.has(id) || nativeHdrIds.has(id));
110911
+ await applyDomLayerMask(domSession.page, showIds, hideIds);
110912
+ const domPng = await captureAlphaPng(domSession.page, width, height);
110913
+ await removeDomLayerMask(domSession.page, hideIds);
110914
+ try {
110915
+ const { data: domRgba } = decodePng(domPng);
110916
+ if (!effectiveHdr) {
110917
+ throw new Error(
110918
+ "Invariant violation: effectiveHdr is undefined inside hasHdrVideo branch"
110919
+ );
110920
+ }
110921
+ blitRgba8OverRgb48le(
110922
+ domRgba,
110700
110923
  sceneBuf,
110701
- el,
110702
- time,
110703
- job.config.fps,
110704
- hdrFrameDirs,
110705
- hdrVideoStartTimes,
110706
110924
  width,
110707
110925
  height,
110708
- log,
110709
- videoTransfers.get(el.id),
110710
- effectiveHdr?.transfer
110926
+ effectiveHdr.transfer
110711
110927
  );
110928
+ } catch (err) {
110929
+ log.warn("DOM layer decode/blit failed; skipping overlay for transition scene", {
110930
+ frameIndex: i,
110931
+ sceneIds: Array.from(sceneIds),
110932
+ error: err instanceof Error ? err.message : String(err)
110933
+ });
110712
110934
  }
110713
110935
  }
110714
- const showIds = Array.from(sceneIds);
110715
- const hideIds = stackingInfo.map((e) => e.id).filter((id) => !sceneIds.has(id) || nativeHdrIds.has(id));
110716
- await applyDomLayerMask(domSession.page, showIds, hideIds);
110717
- const domPng = await captureAlphaPng(domSession.page, width, height);
110718
- await removeDomLayerMask(domSession.page, hideIds);
110719
- try {
110720
- const { data: domRgba } = decodePng(domPng);
110721
- if (!effectiveHdr) {
110722
- throw new Error(
110723
- "Invariant violation: effectiveHdr is undefined inside hasHdrVideo branch"
110724
- );
110725
- }
110726
- blitRgba8OverRgb48le(
110727
- domRgba,
110728
- sceneBuf,
110729
- width,
110730
- height,
110731
- effectiveHdr.transfer
110936
+ const transitionFn = TRANSITIONS[activeTransition.shader] ?? crossfade;
110937
+ transitionFn(transBufferA, transBufferB, transOutput, width, height, progress);
110938
+ hdrEncoder.writeFrame(transOutput);
110939
+ } else {
110940
+ normalCanvas.fill(0);
110941
+ await compositeHdrFrame(
110942
+ hdrCompositeCtx,
110943
+ normalCanvas,
110944
+ time,
110945
+ stackingInfo,
110946
+ void 0,
110947
+ i
110948
+ );
110949
+ if (debugDumpEnabled && debugDumpDir && i % 30 === 0) {
110950
+ const previewPath = join15(
110951
+ debugDumpDir,
110952
+ `frame_${String(i).padStart(4, "0")}_final_rgb48le.bin`
110732
110953
  );
110733
- } catch (err) {
110734
- log.warn("DOM layer decode/blit failed; skipping overlay for transition scene", {
110735
- frameIndex: i,
110736
- sceneIds: Array.from(sceneIds),
110737
- error: err instanceof Error ? err.message : String(err)
110738
- });
110954
+ writeFileSync4(previewPath, normalCanvas);
110739
110955
  }
110740
- }
110741
- const transitionFn = TRANSITIONS[activeTransition.shader] ?? crossfade;
110742
- transitionFn(transBufferA, transBufferB, transOutput, width, height, progress);
110743
- hdrEncoder.writeFrame(transOutput);
110744
- } else {
110745
- normalCanvas.fill(0);
110746
- await compositeToBuffer(normalCanvas, time, stackingInfo, void 0, i);
110747
- if (debugDumpEnabled && debugDumpDir && i % 30 === 0) {
110748
- const previewPath = join15(
110749
- debugDumpDir,
110750
- `frame_${String(i).padStart(4, "0")}_final_rgb48le.bin`
110751
- );
110752
- writeFileSync4(previewPath, normalCanvas);
110753
- }
110754
- hdrEncoder.writeFrame(normalCanvas);
110755
- }
110756
- if (process.env.KEEP_TEMP !== "1") {
110757
- for (const [videoId, endTime] of hdrVideoEndTimes) {
110758
- if (time > endTime && !cleanedUpVideos.has(videoId)) {
110759
- const stillNeeded = activeTransition && (sceneElements[activeTransition.fromScene]?.includes(videoId) || sceneElements[activeTransition.toScene]?.includes(videoId));
110760
- if (!stillNeeded) {
110761
- const frameDir = hdrFrameDirs.get(videoId);
110762
- if (frameDir) {
110763
- try {
110764
- rmSync3(frameDir, { recursive: true, force: true });
110765
- } catch (err) {
110766
- log.warn("Failed to clean up HDR frame directory", {
110767
- videoId,
110768
- frameDir,
110769
- error: err instanceof Error ? err.message : String(err)
110770
- });
110956
+ hdrEncoder.writeFrame(normalCanvas);
110957
+ }
110958
+ if (process.env.KEEP_TEMP !== "1") {
110959
+ for (const [videoId, endTime] of hdrVideoEndTimes) {
110960
+ if (time > endTime && !cleanedUpVideos.has(videoId)) {
110961
+ const stillNeeded = activeTransition && (sceneElements[activeTransition.fromScene]?.includes(videoId) || sceneElements[activeTransition.toScene]?.includes(videoId));
110962
+ if (!stillNeeded) {
110963
+ const frameDir = hdrFrameDirs.get(videoId);
110964
+ if (frameDir) {
110965
+ try {
110966
+ rmSync3(frameDir, { recursive: true, force: true });
110967
+ } catch (err) {
110968
+ log.warn("Failed to clean up HDR frame directory", {
110969
+ videoId,
110970
+ frameDir,
110971
+ error: err instanceof Error ? err.message : String(err)
110972
+ });
110973
+ }
110974
+ frameDirMaxIndexCache.delete(frameDir);
110975
+ hdrFrameDirs.delete(videoId);
110771
110976
  }
110977
+ cleanedUpVideos.add(videoId);
110772
110978
  }
110773
- cleanedUpVideos.add(videoId);
110774
110979
  }
110775
110980
  }
110776
110981
  }
110982
+ job.framesRendered = i + 1;
110983
+ if ((i + 1) % 10 === 0 || i + 1 === totalFrames) {
110984
+ const frameProgress = (i + 1) / totalFrames;
110985
+ updateJobStatus(
110986
+ job,
110987
+ "rendering",
110988
+ `HDR composite frame ${i + 1}/${job.totalFrames}`,
110989
+ Math.round(25 + frameProgress * 55),
110990
+ onProgress
110991
+ );
110992
+ }
110777
110993
  }
110778
- job.framesRendered = i + 1;
110779
- if ((i + 1) % 10 === 0 || i + 1 === totalFrames) {
110780
- const frameProgress = (i + 1) / totalFrames;
110781
- updateJobStatus(
110782
- job,
110783
- "rendering",
110784
- `HDR composite frame ${i + 1}/${job.totalFrames}`,
110785
- Math.round(25 + frameProgress * 55),
110786
- onProgress
110787
- );
110788
- }
110994
+ } finally {
110995
+ lastBrowserConsole = domSession.browserConsoleBuffer;
110996
+ await closeCaptureSession(domSession);
110997
+ domSessionClosed = true;
110789
110998
  }
110999
+ const hdrEncodeResult = await hdrEncoder.close();
111000
+ hdrEncoderClosed = true;
111001
+ assertNotAborted();
111002
+ if (!hdrEncodeResult.success) {
111003
+ throw new Error(`HDR encode failed: ${hdrEncodeResult.error}`);
111004
+ }
111005
+ perfStages.captureMs = Date.now() - stage4Start;
111006
+ perfStages.encodeMs = hdrEncodeResult.durationMs;
110790
111007
  } finally {
110791
- lastBrowserConsole = domSession.browserConsoleBuffer;
110792
- await closeCaptureSession(domSession);
110793
- }
110794
- const hdrEncodeResult = await hdrEncoder.close();
110795
- assertNotAborted();
110796
- if (!hdrEncodeResult.success) {
110797
- throw new Error(`HDR encode failed: ${hdrEncodeResult.error}`);
111008
+ if (hdrEncoder && !hdrEncoderClosed) {
111009
+ try {
111010
+ await hdrEncoder.close();
111011
+ } catch (err) {
111012
+ log.warn("hdrEncoder defensive close failed", {
111013
+ err: err instanceof Error ? err.message : String(err)
111014
+ });
111015
+ }
111016
+ }
111017
+ if (!domSessionClosed) {
111018
+ await closeCaptureSession(domSession).catch((err) => {
111019
+ log.warn("closeCaptureSession defensive close failed", {
111020
+ err: err instanceof Error ? err.message : String(err)
111021
+ });
111022
+ });
111023
+ }
111024
+ for (const frameDir of hdrFrameDirs.values()) {
111025
+ frameDirMaxIndexCache.delete(frameDir);
111026
+ }
111027
+ hdrFrameDirs.clear();
110798
111028
  }
110799
- perfStages.captureMs = Date.now() - stage4Start;
110800
- perfStages.encodeMs = hdrEncodeResult.durationMs;
110801
111029
  } else {
110802
111030
  let streamingEncoder = null;
111031
+ let streamingEncoderClosed = false;
110803
111032
  if (enableStreamingEncode) {
110804
111033
  streamingEncoder = await spawnStreamingEncoder(
110805
111034
  videoOnlyPath,
@@ -110809,7 +111038,8 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
110809
111038
  height,
110810
111039
  codec: preset.codec,
110811
111040
  preset: preset.preset,
110812
- quality: preset.quality,
111041
+ quality: effectiveQuality,
111042
+ bitrate: effectiveBitrate,
110813
111043
  pixelFormat: preset.pixelFormat,
110814
111044
  useGpu: job.config.useGpu,
110815
111045
  imageFormat: captureOptions.format || "jpeg",
@@ -110819,201 +111049,215 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
110819
111049
  );
110820
111050
  assertNotAborted();
110821
111051
  }
110822
- if (enableStreamingEncode && streamingEncoder) {
110823
- const reorderBuffer = createFrameReorderBuffer(0, totalFrames);
110824
- const currentEncoder = streamingEncoder;
110825
- if (workerCount > 1) {
110826
- const tasks = distributeFrames(job.totalFrames, workerCount, workDir);
110827
- const onFrameBuffer = async (frameIndex, buffer) => {
110828
- await reorderBuffer.waitForFrame(frameIndex);
110829
- currentEncoder.writeFrame(buffer);
110830
- reorderBuffer.advanceTo(frameIndex + 1);
110831
- };
110832
- await executeParallelCapture(
110833
- fileServer.url,
110834
- workDir,
110835
- tasks,
110836
- { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
110837
- () => createVideoFrameInjector(frameLookup),
110838
- abortSignal,
110839
- (progress) => {
110840
- job.framesRendered = progress.capturedFrames;
110841
- const frameProgress = progress.capturedFrames / progress.totalFrames;
110842
- const progressPct = 25 + frameProgress * 55;
110843
- if (progress.capturedFrames % 30 === 0 || progress.capturedFrames === progress.totalFrames) {
111052
+ try {
111053
+ if (enableStreamingEncode && streamingEncoder) {
111054
+ const reorderBuffer = createFrameReorderBuffer(0, totalFrames);
111055
+ const currentEncoder = streamingEncoder;
111056
+ if (workerCount > 1) {
111057
+ const tasks = distributeFrames(job.totalFrames, workerCount, workDir);
111058
+ const onFrameBuffer = async (frameIndex, buffer) => {
111059
+ await reorderBuffer.waitForFrame(frameIndex);
111060
+ currentEncoder.writeFrame(buffer);
111061
+ reorderBuffer.advanceTo(frameIndex + 1);
111062
+ };
111063
+ await executeParallelCapture(
111064
+ fileServer.url,
111065
+ workDir,
111066
+ tasks,
111067
+ buildHdrCaptureOptions(),
111068
+ () => createVideoFrameInjector(frameLookup),
111069
+ abortSignal,
111070
+ (progress) => {
111071
+ job.framesRendered = progress.capturedFrames;
111072
+ const frameProgress = progress.capturedFrames / progress.totalFrames;
111073
+ const progressPct = 25 + frameProgress * 55;
111074
+ if (progress.capturedFrames % 30 === 0 || progress.capturedFrames === progress.totalFrames) {
111075
+ updateJobStatus(
111076
+ job,
111077
+ "rendering",
111078
+ `Streaming frame ${progress.capturedFrames}/${progress.totalFrames} (${workerCount} workers)`,
111079
+ Math.round(progressPct),
111080
+ onProgress
111081
+ );
111082
+ }
111083
+ },
111084
+ onFrameBuffer,
111085
+ cfg
111086
+ );
111087
+ if (probeSession) {
111088
+ lastBrowserConsole = probeSession.browserConsoleBuffer;
111089
+ await closeCaptureSession(probeSession);
111090
+ probeSession = null;
111091
+ }
111092
+ } else {
111093
+ const videoInjector = createVideoFrameInjector(frameLookup);
111094
+ const session = probeSession ?? await createCaptureSession(
111095
+ fileServer.url,
111096
+ framesDir,
111097
+ buildHdrCaptureOptions(),
111098
+ videoInjector,
111099
+ cfg
111100
+ );
111101
+ if (probeSession) {
111102
+ prepareCaptureSessionForReuse(session, framesDir, videoInjector);
111103
+ probeSession = null;
111104
+ }
111105
+ try {
111106
+ if (!session.isInitialized) {
111107
+ await initializeSession(session);
111108
+ }
111109
+ assertNotAborted();
111110
+ lastBrowserConsole = session.browserConsoleBuffer;
111111
+ for (let i = 0; i < totalFrames; i++) {
111112
+ assertNotAborted();
111113
+ const time = i / job.config.fps;
111114
+ const { buffer } = await captureFrameToBuffer(session, i, time);
111115
+ await reorderBuffer.waitForFrame(i);
111116
+ currentEncoder.writeFrame(buffer);
111117
+ reorderBuffer.advanceTo(i + 1);
111118
+ job.framesRendered = i + 1;
111119
+ const frameProgress = (i + 1) / totalFrames;
111120
+ const progress = 25 + frameProgress * 55;
110844
111121
  updateJobStatus(
110845
111122
  job,
110846
111123
  "rendering",
110847
- `Streaming frame ${progress.capturedFrames}/${progress.totalFrames} (${workerCount} workers)`,
110848
- Math.round(progressPct),
111124
+ `Streaming frame ${i + 1}/${job.totalFrames}`,
111125
+ Math.round(progress),
110849
111126
  onProgress
110850
111127
  );
110851
111128
  }
110852
- },
110853
- onFrameBuffer,
110854
- cfg
110855
- );
110856
- if (probeSession) {
110857
- lastBrowserConsole = probeSession.browserConsoleBuffer;
110858
- await closeCaptureSession(probeSession);
110859
- probeSession = null;
111129
+ } finally {
111130
+ lastBrowserConsole = session.browserConsoleBuffer;
111131
+ await closeCaptureSession(session);
111132
+ }
110860
111133
  }
110861
- } else {
110862
- const videoInjector = createVideoFrameInjector(frameLookup);
110863
- const session = probeSession ?? await createCaptureSession(
110864
- fileServer.url,
110865
- framesDir,
110866
- { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
110867
- videoInjector,
110868
- cfg
110869
- );
110870
- if (probeSession) {
110871
- prepareCaptureSessionForReuse(session, framesDir, videoInjector);
110872
- probeSession = null;
111134
+ const encodeResult = await currentEncoder.close();
111135
+ streamingEncoderClosed = true;
111136
+ assertNotAborted();
111137
+ if (!encodeResult.success) {
111138
+ throw new Error(`Streaming encode failed: ${encodeResult.error}`);
110873
111139
  }
110874
- try {
110875
- if (!session.isInitialized) {
110876
- await initializeSession(session);
111140
+ perfStages.captureMs = Date.now() - stage4Start;
111141
+ perfStages.encodeMs = encodeResult.durationMs;
111142
+ } else {
111143
+ if (workerCount > 1) {
111144
+ const tasks = distributeFrames(job.totalFrames, workerCount, workDir);
111145
+ await executeParallelCapture(
111146
+ fileServer.url,
111147
+ workDir,
111148
+ tasks,
111149
+ buildHdrCaptureOptions(),
111150
+ () => createVideoFrameInjector(frameLookup),
111151
+ abortSignal,
111152
+ (progress) => {
111153
+ job.framesRendered = progress.capturedFrames;
111154
+ const frameProgress = progress.capturedFrames / progress.totalFrames;
111155
+ const progressPct = 25 + frameProgress * 45;
111156
+ if (progress.capturedFrames % 30 === 0 || progress.capturedFrames === progress.totalFrames) {
111157
+ updateJobStatus(
111158
+ job,
111159
+ "rendering",
111160
+ `Capturing frame ${progress.capturedFrames}/${progress.totalFrames} (${workerCount} workers)`,
111161
+ Math.round(progressPct),
111162
+ onProgress
111163
+ );
111164
+ }
111165
+ },
111166
+ void 0,
111167
+ cfg
111168
+ );
111169
+ await mergeWorkerFrames(workDir, tasks, framesDir);
111170
+ if (probeSession) {
111171
+ lastBrowserConsole = probeSession.browserConsoleBuffer;
111172
+ await closeCaptureSession(probeSession);
111173
+ probeSession = null;
110877
111174
  }
110878
- assertNotAborted();
110879
- lastBrowserConsole = session.browserConsoleBuffer;
110880
- for (let i = 0; i < totalFrames; i++) {
110881
- assertNotAborted();
110882
- const time = i / job.config.fps;
110883
- const { buffer } = await captureFrameToBuffer(session, i, time);
110884
- await reorderBuffer.waitForFrame(i);
110885
- currentEncoder.writeFrame(buffer);
110886
- reorderBuffer.advanceTo(i + 1);
110887
- job.framesRendered = i + 1;
110888
- const frameProgress = (i + 1) / totalFrames;
110889
- const progress = 25 + frameProgress * 55;
110890
- updateJobStatus(
110891
- job,
110892
- "rendering",
110893
- `Streaming frame ${i + 1}/${job.totalFrames}`,
110894
- Math.round(progress),
110895
- onProgress
110896
- );
111175
+ } else {
111176
+ const videoInjector = createVideoFrameInjector(frameLookup);
111177
+ const session = probeSession ?? await createCaptureSession(
111178
+ fileServer.url,
111179
+ framesDir,
111180
+ buildHdrCaptureOptions(),
111181
+ videoInjector,
111182
+ cfg
111183
+ );
111184
+ if (probeSession) {
111185
+ prepareCaptureSessionForReuse(session, framesDir, videoInjector);
111186
+ probeSession = null;
110897
111187
  }
110898
- } finally {
110899
- lastBrowserConsole = session.browserConsoleBuffer;
110900
- await closeCaptureSession(session);
110901
- }
110902
- }
110903
- const encodeResult = await currentEncoder.close();
110904
- assertNotAborted();
110905
- if (!encodeResult.success) {
110906
- throw new Error(`Streaming encode failed: ${encodeResult.error}`);
110907
- }
110908
- perfStages.captureMs = Date.now() - stage4Start;
110909
- perfStages.encodeMs = encodeResult.durationMs;
110910
- } else {
110911
- if (workerCount > 1) {
110912
- const tasks = distributeFrames(job.totalFrames, workerCount, workDir);
110913
- await executeParallelCapture(
110914
- fileServer.url,
110915
- workDir,
110916
- tasks,
110917
- { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
110918
- () => createVideoFrameInjector(frameLookup),
110919
- abortSignal,
110920
- (progress) => {
110921
- job.framesRendered = progress.capturedFrames;
110922
- const frameProgress = progress.capturedFrames / progress.totalFrames;
110923
- const progressPct = 25 + frameProgress * 45;
110924
- if (progress.capturedFrames % 30 === 0 || progress.capturedFrames === progress.totalFrames) {
111188
+ try {
111189
+ if (!session.isInitialized) {
111190
+ await initializeSession(session);
111191
+ }
111192
+ assertNotAborted();
111193
+ lastBrowserConsole = session.browserConsoleBuffer;
111194
+ for (let i = 0; i < job.totalFrames; i++) {
111195
+ assertNotAborted();
111196
+ const time = i / job.config.fps;
111197
+ await captureFrame(session, i, time);
111198
+ job.framesRendered = i + 1;
111199
+ const frameProgress = (i + 1) / job.totalFrames;
111200
+ const progress = 25 + frameProgress * 45;
110925
111201
  updateJobStatus(
110926
111202
  job,
110927
111203
  "rendering",
110928
- `Capturing frame ${progress.capturedFrames}/${progress.totalFrames} (${workerCount} workers)`,
110929
- Math.round(progressPct),
111204
+ `Capturing frame ${i + 1}/${job.totalFrames}`,
111205
+ Math.round(progress),
110930
111206
  onProgress
110931
111207
  );
110932
111208
  }
110933
- },
110934
- void 0,
110935
- cfg
110936
- );
110937
- await mergeWorkerFrames(workDir, tasks, framesDir);
110938
- if (probeSession) {
110939
- lastBrowserConsole = probeSession.browserConsoleBuffer;
110940
- await closeCaptureSession(probeSession);
110941
- probeSession = null;
111209
+ } finally {
111210
+ lastBrowserConsole = session.browserConsoleBuffer;
111211
+ await closeCaptureSession(session);
111212
+ }
110942
111213
  }
110943
- } else {
110944
- const videoInjector = createVideoFrameInjector(frameLookup);
110945
- const session = probeSession ?? await createCaptureSession(
110946
- fileServer.url,
111214
+ perfStages.captureMs = Date.now() - stage4Start;
111215
+ const stage5Start = Date.now();
111216
+ updateJobStatus(job, "encoding", "Encoding video", 75, onProgress);
111217
+ const frameExt = needsAlpha ? "png" : "jpg";
111218
+ const framePattern = `frame_%06d.${frameExt}`;
111219
+ const encoderOpts = {
111220
+ fps: job.config.fps,
111221
+ width,
111222
+ height,
111223
+ codec: preset.codec,
111224
+ preset: preset.preset,
111225
+ quality: effectiveQuality,
111226
+ bitrate: effectiveBitrate,
111227
+ pixelFormat: preset.pixelFormat,
111228
+ useGpu: job.config.useGpu,
111229
+ hdr: preset.hdr
111230
+ };
111231
+ const encodeResult = enableChunkedEncode ? await encodeFramesChunkedConcat(
110947
111232
  framesDir,
110948
- { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
110949
- videoInjector,
110950
- cfg
111233
+ framePattern,
111234
+ videoOnlyPath,
111235
+ encoderOpts,
111236
+ chunkedEncodeSize,
111237
+ abortSignal
111238
+ ) : await encodeFramesFromDir(
111239
+ framesDir,
111240
+ framePattern,
111241
+ videoOnlyPath,
111242
+ encoderOpts,
111243
+ abortSignal
110951
111244
  );
110952
- if (probeSession) {
110953
- prepareCaptureSessionForReuse(session, framesDir, videoInjector);
110954
- probeSession = null;
111245
+ assertNotAborted();
111246
+ if (!encodeResult.success) {
111247
+ throw new Error(`Encoding failed: ${encodeResult.error}`);
110955
111248
  }
111249
+ perfStages.encodeMs = Date.now() - stage5Start;
111250
+ }
111251
+ } finally {
111252
+ if (streamingEncoder && !streamingEncoderClosed) {
110956
111253
  try {
110957
- if (!session.isInitialized) {
110958
- await initializeSession(session);
110959
- }
110960
- assertNotAborted();
110961
- lastBrowserConsole = session.browserConsoleBuffer;
110962
- for (let i = 0; i < job.totalFrames; i++) {
110963
- assertNotAborted();
110964
- const time = i / job.config.fps;
110965
- await captureFrame(session, i, time);
110966
- job.framesRendered = i + 1;
110967
- const frameProgress = (i + 1) / job.totalFrames;
110968
- const progress = 25 + frameProgress * 45;
110969
- updateJobStatus(
110970
- job,
110971
- "rendering",
110972
- `Capturing frame ${i + 1}/${job.totalFrames}`,
110973
- Math.round(progress),
110974
- onProgress
110975
- );
110976
- }
110977
- } finally {
110978
- lastBrowserConsole = session.browserConsoleBuffer;
110979
- await closeCaptureSession(session);
111254
+ await streamingEncoder.close();
111255
+ } catch (err) {
111256
+ log.warn("streamingEncoder defensive close failed", {
111257
+ err: err instanceof Error ? err.message : String(err)
111258
+ });
110980
111259
  }
110981
111260
  }
110982
- perfStages.captureMs = Date.now() - stage4Start;
110983
- const stage5Start = Date.now();
110984
- updateJobStatus(job, "encoding", "Encoding video", 75, onProgress);
110985
- const frameExt = needsAlpha ? "png" : "jpg";
110986
- const framePattern = `frame_%06d.${frameExt}`;
110987
- const encoderOpts = {
110988
- fps: job.config.fps,
110989
- width,
110990
- height,
110991
- codec: preset.codec,
110992
- preset: preset.preset,
110993
- quality: preset.quality,
110994
- pixelFormat: preset.pixelFormat,
110995
- useGpu: job.config.useGpu,
110996
- hdr: preset.hdr
110997
- };
110998
- const encodeResult = enableChunkedEncode ? await encodeFramesChunkedConcat(
110999
- framesDir,
111000
- framePattern,
111001
- videoOnlyPath,
111002
- encoderOpts,
111003
- chunkedEncodeSize,
111004
- abortSignal
111005
- ) : await encodeFramesFromDir(
111006
- framesDir,
111007
- framePattern,
111008
- videoOnlyPath,
111009
- encoderOpts,
111010
- abortSignal
111011
- );
111012
- assertNotAborted();
111013
- if (!encodeResult.success) {
111014
- throw new Error(`Encoding failed: ${encodeResult.error}`);
111015
- }
111016
- perfStages.encodeMs = Date.now() - stage5Start;
111017
111261
  }
111018
111262
  }
111019
111263
  if (probeSession !== null) {
@@ -111177,7 +111421,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
111177
111421
 
111178
111422
  // src/services/hyperframeLint.ts
111179
111423
  import { existsSync as existsSync16, readFileSync as readFileSync11, statSync as statSync6 } from "node:fs";
111180
- import { resolve as resolve11, join as join16 } from "node:path";
111424
+ import { resolve as resolve12, join as join16 } from "node:path";
111181
111425
  function isStringRecord(value) {
111182
111426
  if (!value || typeof value !== "object" || Array.isArray(value)) {
111183
111427
  return false;
@@ -111204,7 +111448,7 @@ function pickEntryFile(files, preferredEntryFile) {
111204
111448
  return null;
111205
111449
  }
111206
111450
  function readProjectEntryFile(projectDir, preferredEntryFile) {
111207
- const absProjectDir = resolve11(projectDir);
111451
+ const absProjectDir = resolve12(projectDir);
111208
111452
  if (!existsSync16(absProjectDir) || !statSync6(absProjectDir).isDirectory()) {
111209
111453
  return { error: `Project directory not found: ${absProjectDir}` };
111210
111454
  }
@@ -111212,7 +111456,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
111212
111456
  (value) => typeof value === "string" && value.trim().length > 0
111213
111457
  );
111214
111458
  for (const entryFile of entryCandidates) {
111215
- const absoluteEntryPath = resolve11(absProjectDir, entryFile);
111459
+ const absoluteEntryPath = resolve12(absProjectDir, entryFile);
111216
111460
  if (!absoluteEntryPath.startsWith(absProjectDir)) {
111217
111461
  return { error: `Entry file must stay inside project directory: ${entryFile}` };
111218
111462
  }
@@ -111277,10 +111521,10 @@ var Semaphore = class {
111277
111521
  this.active++;
111278
111522
  return () => this.release();
111279
111523
  }
111280
- return new Promise((resolve13) => {
111524
+ return new Promise((resolve14) => {
111281
111525
  this.queue.push(() => {
111282
111526
  this.active++;
111283
- resolve13(() => this.release());
111527
+ resolve14(() => this.release());
111284
111528
  });
111285
111529
  });
111286
111530
  }
@@ -111315,12 +111559,12 @@ async function prepareRenderBody(body) {
111315
111559
  const options = parseRenderOptions(body);
111316
111560
  const projectDir = typeof body.projectDir === "string" ? body.projectDir : void 0;
111317
111561
  if (projectDir) {
111318
- const absProjectDir = resolve12(projectDir);
111562
+ const absProjectDir = resolve13(projectDir);
111319
111563
  if (!existsSync17(absProjectDir) || !statSync7(absProjectDir).isDirectory()) {
111320
111564
  return { error: `Project directory not found: ${absProjectDir}` };
111321
111565
  }
111322
111566
  const entry = options.entryFile || "index.html";
111323
- if (!existsSync17(resolve12(absProjectDir, entry))) {
111567
+ if (!existsSync17(resolve13(absProjectDir, entry))) {
111324
111568
  return { error: `Entry file "${entry}" not found in project directory: ${absProjectDir}` };
111325
111569
  }
111326
111570
  return { prepared: { input: { projectDir: absProjectDir, ...options } } };
@@ -111361,7 +111605,7 @@ function resolveOutputPath(projectDir, outputCandidate, rendersDir, log) {
111361
111605
  try {
111362
111606
  return resolveRenderPaths(projectDir, outputCandidate, rendersDir).absoluteOutputPath;
111363
111607
  } catch (error) {
111364
- const fallbackPath = resolve12(rendersDir, `producer-fallback-${Date.now()}.mp4`);
111608
+ const fallbackPath = resolve13(rendersDir, `producer-fallback-${Date.now()}.mp4`);
111365
111609
  log.warn("Failed to resolve output path, using fallback", {
111366
111610
  fallback: fallbackPath,
111367
111611
  error: error instanceof Error ? error.message : String(error)
@@ -111740,7 +111984,7 @@ function startServer(options = {}) {
111740
111984
  process.on("SIGINT", () => shutdown("SIGINT"));
111741
111985
  return server;
111742
111986
  }
111743
- var entryScript = process.argv[1] ? resolve12(process.argv[1]) : "";
111987
+ var entryScript = process.argv[1] ? resolve13(process.argv[1]) : "";
111744
111988
  var isPublicServerEntry = entryScript.endsWith("/public-server.js") || entryScript.endsWith("/src/server.ts");
111745
111989
  if (isPublicServerEntry) {
111746
111990
  const { values } = parseArgs({