@hyperframes/producer 0.4.15-alpha.1 → 0.4.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1356,12 +1356,12 @@ var require_CSSValueExpression = __commonJS({
1356
1356
  return false;
1357
1357
  }
1358
1358
  };
1359
- CSSOM.CSSValueExpression.prototype._parseJSString = function(token, idx, sep) {
1360
- var endIdx = this._findMatchedIdx(token, idx, sep), text;
1359
+ CSSOM.CSSValueExpression.prototype._parseJSString = function(token, idx, sep2) {
1360
+ var endIdx = this._findMatchedIdx(token, idx, sep2), text;
1361
1361
  if (endIdx === -1) {
1362
1362
  return false;
1363
1363
  } else {
1364
- text = token.substring(idx, endIdx + sep.length);
1364
+ text = token.substring(idx, endIdx + sep2.length);
1365
1365
  return {
1366
1366
  idx: endIdx,
1367
1367
  text
@@ -1401,15 +1401,15 @@ var require_CSSValueExpression = __commonJS({
1401
1401
  if (!isLegal) {
1402
1402
  return false;
1403
1403
  } else {
1404
- var sep = "/";
1405
- return this._parseJSString(token, idx, sep);
1404
+ var sep2 = "/";
1405
+ return this._parseJSString(token, idx, sep2);
1406
1406
  }
1407
1407
  };
1408
- CSSOM.CSSValueExpression.prototype._findMatchedIdx = function(token, idx, sep) {
1408
+ CSSOM.CSSValueExpression.prototype._findMatchedIdx = function(token, idx, sep2) {
1409
1409
  var startIdx = idx, endIdx;
1410
1410
  var NOT_FOUND = -1;
1411
1411
  while (true) {
1412
- endIdx = token.indexOf(sep, startIdx + 1);
1412
+ endIdx = token.indexOf(sep2, startIdx + 1);
1413
1413
  if (endIdx === -1) {
1414
1414
  endIdx = NOT_FOUND;
1415
1415
  break;
@@ -2148,11 +2148,11 @@ function __extends(d, b) {
2148
2148
  }
2149
2149
  function __awaiter(thisArg, _arguments, P, generator) {
2150
2150
  function adopt(value) {
2151
- return value instanceof P ? value : new P(function(resolve13) {
2152
- resolve13(value);
2151
+ return value instanceof P ? value : new P(function(resolve14) {
2152
+ resolve14(value);
2153
2153
  });
2154
2154
  }
2155
- return new (P || (P = Promise))(function(resolve13, reject) {
2155
+ return new (P || (P = Promise))(function(resolve14, reject) {
2156
2156
  function fulfilled(value) {
2157
2157
  try {
2158
2158
  step(generator.next(value));
@@ -2168,7 +2168,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
2168
2168
  }
2169
2169
  }
2170
2170
  function step(result) {
2171
- result.done ? resolve13(result.value) : adopt(result.value).then(fulfilled, rejected);
2171
+ result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected);
2172
2172
  }
2173
2173
  step((generator = generator.apply(thisArg, _arguments || [])).next());
2174
2174
  });
@@ -2331,14 +2331,14 @@ function __asyncValues(o) {
2331
2331
  }, i);
2332
2332
  function verb(n) {
2333
2333
  i[n] = o[n] && function(v) {
2334
- return new Promise(function(resolve13, reject) {
2335
- v = o[n](v), settle(resolve13, reject, v.done, v.value);
2334
+ return new Promise(function(resolve14, reject) {
2335
+ v = o[n](v), settle(resolve14, reject, v.done, v.value);
2336
2336
  });
2337
2337
  };
2338
2338
  }
2339
- function settle(resolve13, reject, d, v) {
2339
+ function settle(resolve14, reject, d, v) {
2340
2340
  Promise.resolve(v).then(function(v2) {
2341
- resolve13({ value: v2, done: d });
2341
+ resolve14({ value: v2, done: d });
2342
2342
  }, reject);
2343
2343
  }
2344
2344
  }
@@ -2863,7 +2863,7 @@ function of() {
2863
2863
  }
2864
2864
  function lastValueFrom(source2, config2) {
2865
2865
  var hasConfig = typeof config2 === "object";
2866
- return new Promise(function(resolve13, reject) {
2866
+ return new Promise(function(resolve14, reject) {
2867
2867
  var _hasValue = false;
2868
2868
  var _value;
2869
2869
  source2.subscribe({
@@ -2874,9 +2874,9 @@ function lastValueFrom(source2, config2) {
2874
2874
  error: reject,
2875
2875
  complete: function() {
2876
2876
  if (_hasValue) {
2877
- resolve13(_value);
2877
+ resolve14(_value);
2878
2878
  } else if (hasConfig) {
2879
- resolve13(config2.defaultValue);
2879
+ resolve14(config2.defaultValue);
2880
2880
  } else {
2881
2881
  reject(new EmptyError());
2882
2882
  }
@@ -2886,16 +2886,16 @@ function lastValueFrom(source2, config2) {
2886
2886
  }
2887
2887
  function firstValueFrom(source2, config2) {
2888
2888
  var hasConfig = typeof config2 === "object";
2889
- return new Promise(function(resolve13, reject) {
2889
+ return new Promise(function(resolve14, reject) {
2890
2890
  var subscriber = new SafeSubscriber({
2891
2891
  next: function(value) {
2892
- resolve13(value);
2892
+ resolve14(value);
2893
2893
  subscriber.unsubscribe();
2894
2894
  },
2895
2895
  error: reject,
2896
2896
  complete: function() {
2897
2897
  if (hasConfig) {
2898
- resolve13(config2.defaultValue);
2898
+ resolve14(config2.defaultValue);
2899
2899
  } else {
2900
2900
  reject(new EmptyError());
2901
2901
  }
@@ -3934,7 +3934,7 @@ var init_rxjs = __esm({
3934
3934
  Observable2.prototype.forEach = function(next, promiseCtor) {
3935
3935
  var _this = this;
3936
3936
  promiseCtor = getPromiseCtor(promiseCtor);
3937
- return new promiseCtor(function(resolve13, reject) {
3937
+ return new promiseCtor(function(resolve14, reject) {
3938
3938
  var subscriber = new SafeSubscriber({
3939
3939
  next: function(value) {
3940
3940
  try {
@@ -3945,7 +3945,7 @@ var init_rxjs = __esm({
3945
3945
  }
3946
3946
  },
3947
3947
  error: reject,
3948
- complete: resolve13
3948
+ complete: resolve14
3949
3949
  });
3950
3950
  _this.subscribe(subscriber);
3951
3951
  });
@@ -3967,14 +3967,14 @@ var init_rxjs = __esm({
3967
3967
  Observable2.prototype.toPromise = function(promiseCtor) {
3968
3968
  var _this = this;
3969
3969
  promiseCtor = getPromiseCtor(promiseCtor);
3970
- return new promiseCtor(function(resolve13, reject) {
3970
+ return new promiseCtor(function(resolve14, reject) {
3971
3971
  var value;
3972
3972
  _this.subscribe(function(x) {
3973
3973
  return value = x;
3974
3974
  }, function(err) {
3975
3975
  return reject(err);
3976
3976
  }, function() {
3977
- return resolve13(value);
3977
+ return resolve14(value);
3978
3978
  });
3979
3979
  });
3980
3980
  };
@@ -6404,8 +6404,8 @@ var init_Deferred = __esm({
6404
6404
  // SAFETY: This is ensured by #taskPromise.
6405
6405
  #resolve;
6406
6406
  // TODO: Switch to Promise.withResolvers with Node 22
6407
- #taskPromise = new Promise((resolve13) => {
6408
- this.#resolve = resolve13;
6407
+ #taskPromise = new Promise((resolve14) => {
6408
+ this.#resolve = resolve14;
6409
6409
  });
6410
6410
  #timeoutId;
6411
6411
  #timeoutError;
@@ -6495,12 +6495,12 @@ var init_Mutex = __esm({
6495
6495
  return new _Mutex.Guard(this, onRelease);
6496
6496
  }
6497
6497
  release() {
6498
- const resolve13 = this.#acquirers.shift();
6499
- if (!resolve13) {
6498
+ const resolve14 = this.#acquirers.shift();
6499
+ if (!resolve14) {
6500
6500
  this.#locked = false;
6501
6501
  return;
6502
6502
  }
6503
- resolve13();
6503
+ resolve14();
6504
6504
  }
6505
6505
  };
6506
6506
  }
@@ -8515,12 +8515,12 @@ var init_locators = __esm({
8515
8515
  }
8516
8516
  return defer(() => {
8517
8517
  return from(handle.evaluate((element) => {
8518
- return new Promise((resolve13) => {
8518
+ return new Promise((resolve14) => {
8519
8519
  window.requestAnimationFrame(() => {
8520
8520
  const rect1 = element.getBoundingClientRect();
8521
8521
  window.requestAnimationFrame(() => {
8522
8522
  const rect2 = element.getBoundingClientRect();
8523
- resolve13([
8523
+ resolve14([
8524
8524
  {
8525
8525
  x: rect1.x,
8526
8526
  y: rect1.y,
@@ -10259,9 +10259,9 @@ var init_ElementHandle = __esm({
10259
10259
  const handle = await this.#asSVGElementHandle();
10260
10260
  const target = __addDisposableResource6(env_5, handle && await handle.#getOwnerSVGElement(), false);
10261
10261
  return await (target ?? this).evaluate(async (element, threshold) => {
10262
- const visibleRatio = await new Promise((resolve13) => {
10262
+ const visibleRatio = await new Promise((resolve14) => {
10263
10263
  const observer = new IntersectionObserver((entries2) => {
10264
- resolve13(entries2[0].intersectionRatio);
10264
+ resolve14(entries2[0].intersectionRatio);
10265
10265
  observer.disconnect();
10266
10266
  });
10267
10267
  observer.observe(element);
@@ -10907,7 +10907,7 @@ var init_Frame = __esm({
10907
10907
  }
10908
10908
  type = type ?? "text/javascript";
10909
10909
  return await this.mainRealm().transferHandle(await this.isolatedRealm().evaluateHandle(async ({ url, id, type: type2, content: content2 }) => {
10910
- return await new Promise((resolve13, reject) => {
10910
+ return await new Promise((resolve14, reject) => {
10911
10911
  const script = document.createElement("script");
10912
10912
  script.type = type2;
10913
10913
  script.text = content2;
@@ -10920,12 +10920,12 @@ var init_Frame = __esm({
10920
10920
  if (url) {
10921
10921
  script.src = url;
10922
10922
  script.addEventListener("load", () => {
10923
- resolve13(script);
10923
+ resolve14(script);
10924
10924
  }, { once: true });
10925
10925
  document.head.appendChild(script);
10926
10926
  } else {
10927
10927
  document.head.appendChild(script);
10928
- resolve13(script);
10928
+ resolve14(script);
10929
10929
  }
10930
10930
  });
10931
10931
  }, { ...options, type, content }));
@@ -10945,7 +10945,7 @@ var init_Frame = __esm({
10945
10945
  options.content = content;
10946
10946
  }
10947
10947
  return await this.mainRealm().transferHandle(await this.isolatedRealm().evaluateHandle(async ({ url, content: content2 }) => {
10948
- return await new Promise((resolve13, reject) => {
10948
+ return await new Promise((resolve14, reject) => {
10949
10949
  let element;
10950
10950
  if (!url) {
10951
10951
  element = document.createElement("style");
@@ -10957,7 +10957,7 @@ var init_Frame = __esm({
10957
10957
  element = link;
10958
10958
  }
10959
10959
  element.addEventListener("load", () => {
10960
- resolve13(element);
10960
+ resolve14(element);
10961
10961
  }, { once: true });
10962
10962
  element.addEventListener("error", (event) => {
10963
10963
  reject(new Error(event.message ?? "Could not load style"));
@@ -12696,9 +12696,9 @@ var init_Page = __esm({
12696
12696
  ++this.#screencastSessionCount;
12697
12697
  if (!this.#startScreencastPromise) {
12698
12698
  this.#startScreencastPromise = this.mainFrame().client.send("Page.startScreencast", { format: "png" }).then(() => {
12699
- return new Promise((resolve13) => {
12699
+ return new Promise((resolve14) => {
12700
12700
  return this.mainFrame().client.once("Page.screencastFrame", () => {
12701
- return resolve13();
12701
+ return resolve14();
12702
12702
  });
12703
12703
  });
12704
12704
  });
@@ -16016,11 +16016,11 @@ function addPageBinding(type, name, prefix) {
16016
16016
  return value instanceof Node;
16017
16017
  })
16018
16018
  }));
16019
- return new Promise((resolve13, reject) => {
16019
+ return new Promise((resolve14, reject) => {
16020
16020
  callPuppeteer.callbacks.set(seq, {
16021
16021
  resolve(value) {
16022
16022
  callPuppeteer.args.delete(seq);
16023
- resolve13(value);
16023
+ resolve14(value);
16024
16024
  },
16025
16025
  reject(value) {
16026
16026
  callPuppeteer.args.delete(seq);
@@ -19683,8 +19683,8 @@ var init_Input2 = __esm({
19683
19683
  if (typeof delay === "number") {
19684
19684
  await Promise.all(actions);
19685
19685
  actions.length = 0;
19686
- await new Promise((resolve13) => {
19687
- setTimeout(resolve13, delay);
19686
+ await new Promise((resolve14) => {
19687
+ setTimeout(resolve14, delay);
19688
19688
  });
19689
19689
  }
19690
19690
  actions.push(this.up({ ...options, clickCount }));
@@ -19704,9 +19704,9 @@ var init_Input2 = __esm({
19704
19704
  });
19705
19705
  }
19706
19706
  async drag(start, target) {
19707
- const promise = new Promise((resolve13) => {
19707
+ const promise = new Promise((resolve14) => {
19708
19708
  this.#client.once("Input.dragIntercepted", (event) => {
19709
- return resolve13(event.data);
19709
+ return resolve14(event.data);
19710
19710
  });
19711
19711
  });
19712
19712
  await this.move(start.x, start.y);
@@ -19747,8 +19747,8 @@ var init_Input2 = __esm({
19747
19747
  await this.dragEnter(target, data);
19748
19748
  await this.dragOver(target, data);
19749
19749
  if (delay) {
19750
- await new Promise((resolve13) => {
19751
- return setTimeout(resolve13, delay);
19750
+ await new Promise((resolve14) => {
19751
+ return setTimeout(resolve14, delay);
19752
19752
  });
19753
19753
  }
19754
19754
  await this.drop(target, data);
@@ -20632,9 +20632,9 @@ var init_Page2 = __esm({
20632
20632
  async captureHeapSnapshot(options) {
20633
20633
  const { createWriteStream: createWriteStream3 } = environment.value.fs;
20634
20634
  const stream2 = createWriteStream3(options.path);
20635
- const streamPromise = new Promise((resolve13, reject) => {
20635
+ const streamPromise = new Promise((resolve14, reject) => {
20636
20636
  stream2.on("error", reject);
20637
- stream2.on("finish", resolve13);
20637
+ stream2.on("finish", resolve14);
20638
20638
  });
20639
20639
  const client = this.#primaryTargetClient;
20640
20640
  await client.send("HeapProfiler.enable");
@@ -22276,10 +22276,10 @@ var init_BrowserWebSocketTransport = __esm({
22276
22276
  "../../node_modules/.bun/puppeteer-core@24.40.0/node_modules/puppeteer-core/lib/esm/puppeteer/common/BrowserWebSocketTransport.js"() {
22277
22277
  BrowserWebSocketTransport = class _BrowserWebSocketTransport {
22278
22278
  static create(url) {
22279
- return new Promise((resolve13, reject) => {
22279
+ return new Promise((resolve14, reject) => {
22280
22280
  const ws = new WebSocket(url);
22281
22281
  ws.addEventListener("open", () => {
22282
- return resolve13(new _BrowserWebSocketTransport(ws));
22282
+ return resolve14(new _BrowserWebSocketTransport(ws));
22283
22283
  });
22284
22284
  ws.addEventListener("error", reject);
22285
22285
  });
@@ -25201,11 +25201,11 @@ var require_BrowsingContextProcessor = __commonJS({
25201
25201
  }
25202
25202
  const parentCdpClient = context2.cdpTarget.parentCdpClient;
25203
25203
  try {
25204
- const detachedFromTargetPromise = new Promise((resolve13) => {
25204
+ const detachedFromTargetPromise = new Promise((resolve14) => {
25205
25205
  const onContextDestroyed = (event) => {
25206
25206
  if (event.targetId === params.context) {
25207
25207
  parentCdpClient.off("Target.detachedFromTarget", onContextDestroyed);
25208
- resolve13();
25208
+ resolve14();
25209
25209
  }
25210
25210
  };
25211
25211
  parentCdpClient.on("Target.detachedFromTarget", onContextDestroyed);
@@ -26568,7 +26568,7 @@ var require_ActionDispatcher = __commonJS({
26568
26568
  }
26569
26569
  }
26570
26570
  const promises = [
26571
- new Promise((resolve13) => setTimeout(resolve13, this.#tickDuration))
26571
+ new Promise((resolve14) => setTimeout(resolve14, this.#tickDuration))
26572
26572
  ];
26573
26573
  for (const option of options) {
26574
26574
  promises.push(this.#dispatchAction(option));
@@ -27169,8 +27169,8 @@ var require_Mutex = __commonJS({
27169
27169
  acquire() {
27170
27170
  const state = { resolved: false };
27171
27171
  if (this.#locked) {
27172
- return new Promise((resolve13) => {
27173
- this.#acquirers.push(() => resolve13(this.#release.bind(this, state)));
27172
+ return new Promise((resolve14) => {
27173
+ this.#acquirers.push(() => resolve14(this.#release.bind(this, state)));
27174
27174
  });
27175
27175
  }
27176
27176
  this.#locked = true;
@@ -27181,12 +27181,12 @@ var require_Mutex = __commonJS({
27181
27181
  throw new Error("Cannot release more than once.");
27182
27182
  }
27183
27183
  state.resolved = true;
27184
- const resolve13 = this.#acquirers.shift();
27185
- if (!resolve13) {
27184
+ const resolve14 = this.#acquirers.shift();
27185
+ if (!resolve14) {
27186
27186
  this.#locked = false;
27187
27187
  return;
27188
27188
  }
27189
- resolve13();
27189
+ resolve14();
27190
27190
  }
27191
27191
  async run(action) {
27192
27192
  const release = await this.acquire();
@@ -28368,8 +28368,8 @@ var require_ChannelProxy = __commonJS({
28368
28368
  * in the queue.
28369
28369
  */
28370
28370
  async getMessage() {
28371
- const onMessage = queue.length > 0 ? Promise.resolve() : new Promise((resolve13) => {
28372
- queueNonEmptyResolver = resolve13;
28371
+ const onMessage = queue.length > 0 ? Promise.resolve() : new Promise((resolve14) => {
28372
+ queueNonEmptyResolver = resolve14;
28373
28373
  });
28374
28374
  await onMessage;
28375
28375
  return queue.shift();
@@ -28474,7 +28474,7 @@ var require_ChannelProxy = __commonJS({
28474
28474
  functionDeclaration: String((id) => {
28475
28475
  const w = window;
28476
28476
  if (w[id] === void 0) {
28477
- return new Promise((resolve13) => w[id] = resolve13);
28477
+ return new Promise((resolve14) => w[id] = resolve14);
28478
28478
  }
28479
28479
  const channelProxy = w[id];
28480
28480
  delete w[id];
@@ -29975,8 +29975,8 @@ var require_Deferred = __commonJS({
29975
29975
  return this.#result;
29976
29976
  }
29977
29977
  constructor() {
29978
- this.#promise = new Promise((resolve13, reject) => {
29979
- this.#resolve = resolve13;
29978
+ this.#promise = new Promise((resolve14, reject) => {
29979
+ this.#resolve = resolve14;
29980
29980
  this.#reject = reject;
29981
29981
  });
29982
29982
  this.#promise.catch((_error) => {
@@ -34820,11 +34820,11 @@ var require_BrowsingContextStorage = __commonJS({
34820
34820
  if (this.#contexts.has(browsingContextId)) {
34821
34821
  return Promise.resolve(this.getContext(browsingContextId));
34822
34822
  }
34823
- return new Promise((resolve13) => {
34823
+ return new Promise((resolve14) => {
34824
34824
  const listener = (event) => {
34825
34825
  if (event.browsingContext.id === browsingContextId) {
34826
34826
  this.#eventEmitter.off("added", listener);
34827
- resolve13(event.browsingContext);
34827
+ resolve14(event.browsingContext);
34828
34828
  }
34829
34829
  };
34830
34830
  this.#eventEmitter.on("added", listener);
@@ -38406,8 +38406,8 @@ var init_ExposedFunction = __esm({
38406
38406
  const functionDeclaration = stringifyFunction(interpolateFunction((callback) => {
38407
38407
  Object.assign(globalThis, {
38408
38408
  [PLACEHOLDER("name")]: function(...args) {
38409
- return new Promise((resolve13, reject) => {
38410
- callback([resolve13, reject, args]);
38409
+ return new Promise((resolve14, reject) => {
38410
+ callback([resolve14, reject, args]);
38411
38411
  });
38412
38412
  }
38413
38413
  });
@@ -38495,8 +38495,8 @@ var init_ExposedFunction = __esm({
38495
38495
  return;
38496
38496
  }
38497
38497
  try {
38498
- await dataHandle.evaluate(([resolve13], result2) => {
38499
- resolve13(result2);
38498
+ await dataHandle.evaluate(([resolve14], result2) => {
38499
+ resolve14(result2);
38500
38500
  }, result);
38501
38501
  } catch (error) {
38502
38502
  debugError(error);
@@ -46577,7 +46577,7 @@ var init_NodeWebSocketTransport = __esm({
46577
46577
  init_version();
46578
46578
  NodeWebSocketTransport = class _NodeWebSocketTransport {
46579
46579
  static create(url, headers) {
46580
- return new Promise((resolve13, reject) => {
46580
+ return new Promise((resolve14, reject) => {
46581
46581
  const ws = new wrapper_default(url, [], {
46582
46582
  followRedirects: true,
46583
46583
  perMessageDeflate: false,
@@ -46590,7 +46590,7 @@ var init_NodeWebSocketTransport = __esm({
46590
46590
  }
46591
46591
  });
46592
46592
  ws.addEventListener("open", () => {
46593
- return resolve13(new _NodeWebSocketTransport(ws));
46593
+ return resolve14(new _NodeWebSocketTransport(ws));
46594
46594
  });
46595
46595
  ws.addEventListener("error", reject);
46596
46596
  });
@@ -49651,8 +49651,8 @@ var require_helpers = __commonJS({
49651
49651
  function req(url, opts = {}) {
49652
49652
  const href = typeof url === "string" ? url : url.href;
49653
49653
  const req2 = (href.startsWith("https:") ? https2 : http2).request(url, opts);
49654
- const promise = new Promise((resolve13, reject) => {
49655
- req2.once("response", resolve13).once("error", reject).end();
49654
+ const promise = new Promise((resolve14, reject) => {
49655
+ req2.once("response", resolve14).once("error", reject).end();
49656
49656
  });
49657
49657
  req2.then = promise.then.bind(promise);
49658
49658
  return req2;
@@ -50029,7 +50029,7 @@ var require_parse_proxy_response = __commonJS({
50029
50029
  var debug_1 = __importDefault2(require_src());
50030
50030
  var debug6 = (0, debug_1.default)("https-proxy-agent:parse-proxy-response");
50031
50031
  function parseProxyResponse(socket) {
50032
- return new Promise((resolve13, reject) => {
50032
+ return new Promise((resolve14, reject) => {
50033
50033
  let buffersLength = 0;
50034
50034
  const buffers = [];
50035
50035
  function read() {
@@ -50095,7 +50095,7 @@ var require_parse_proxy_response = __commonJS({
50095
50095
  }
50096
50096
  debug6("got proxy server response: %o %o", firstLine, headers);
50097
50097
  cleanup();
50098
- resolve13({
50098
+ resolve14({
50099
50099
  connect: {
50100
50100
  statusCode,
50101
50101
  statusText,
@@ -53353,11 +53353,11 @@ var require_socksclient = __commonJS({
53353
53353
  "use strict";
53354
53354
  var __awaiter3 = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
53355
53355
  function adopt(value) {
53356
- return value instanceof P ? value : new P(function(resolve13) {
53357
- resolve13(value);
53356
+ return value instanceof P ? value : new P(function(resolve14) {
53357
+ resolve14(value);
53358
53358
  });
53359
53359
  }
53360
- return new (P || (P = Promise))(function(resolve13, reject) {
53360
+ return new (P || (P = Promise))(function(resolve14, reject) {
53361
53361
  function fulfilled(value) {
53362
53362
  try {
53363
53363
  step(generator.next(value));
@@ -53373,7 +53373,7 @@ var require_socksclient = __commonJS({
53373
53373
  }
53374
53374
  }
53375
53375
  function step(result) {
53376
- result.done ? resolve13(result.value) : adopt(result.value).then(fulfilled, rejected);
53376
+ result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected);
53377
53377
  }
53378
53378
  step((generator = generator.apply(thisArg, _arguments || [])).next());
53379
53379
  });
@@ -53407,13 +53407,13 @@ var require_socksclient = __commonJS({
53407
53407
  * @returns { Promise }
53408
53408
  */
53409
53409
  static createConnection(options, callback) {
53410
- return new Promise((resolve13, reject) => {
53410
+ return new Promise((resolve14, reject) => {
53411
53411
  try {
53412
53412
  (0, helpers_1.validateSocksClientOptions)(options, ["connect"]);
53413
53413
  } catch (err) {
53414
53414
  if (typeof callback === "function") {
53415
53415
  callback(err);
53416
- return resolve13(err);
53416
+ return resolve14(err);
53417
53417
  } else {
53418
53418
  return reject(err);
53419
53419
  }
@@ -53424,16 +53424,16 @@ var require_socksclient = __commonJS({
53424
53424
  client.removeAllListeners();
53425
53425
  if (typeof callback === "function") {
53426
53426
  callback(null, info);
53427
- resolve13(info);
53427
+ resolve14(info);
53428
53428
  } else {
53429
- resolve13(info);
53429
+ resolve14(info);
53430
53430
  }
53431
53431
  });
53432
53432
  client.once("error", (err) => {
53433
53433
  client.removeAllListeners();
53434
53434
  if (typeof callback === "function") {
53435
53435
  callback(err);
53436
- resolve13(err);
53436
+ resolve14(err);
53437
53437
  } else {
53438
53438
  reject(err);
53439
53439
  }
@@ -53450,13 +53450,13 @@ var require_socksclient = __commonJS({
53450
53450
  * @returns { Promise }
53451
53451
  */
53452
53452
  static createConnectionChain(options, callback) {
53453
- return new Promise((resolve13, reject) => __awaiter3(this, void 0, void 0, function* () {
53453
+ return new Promise((resolve14, reject) => __awaiter3(this, void 0, void 0, function* () {
53454
53454
  try {
53455
53455
  (0, helpers_1.validateSocksClientChainOptions)(options);
53456
53456
  } catch (err) {
53457
53457
  if (typeof callback === "function") {
53458
53458
  callback(err);
53459
- return resolve13(err);
53459
+ return resolve14(err);
53460
53460
  } else {
53461
53461
  return reject(err);
53462
53462
  }
@@ -53482,14 +53482,14 @@ var require_socksclient = __commonJS({
53482
53482
  }
53483
53483
  if (typeof callback === "function") {
53484
53484
  callback(null, { socket: sock });
53485
- resolve13({ socket: sock });
53485
+ resolve14({ socket: sock });
53486
53486
  } else {
53487
- resolve13({ socket: sock });
53487
+ resolve14({ socket: sock });
53488
53488
  }
53489
53489
  } catch (err) {
53490
53490
  if (typeof callback === "function") {
53491
53491
  callback(err);
53492
- resolve13(err);
53492
+ resolve14(err);
53493
53493
  } else {
53494
53494
  reject(err);
53495
53495
  }
@@ -54173,12 +54173,12 @@ var require_dist4 = __commonJS({
54173
54173
  let { host } = opts;
54174
54174
  const { port, lookup: lookupFn = dns.lookup } = opts;
54175
54175
  if (shouldLookup) {
54176
- host = await new Promise((resolve13, reject) => {
54176
+ host = await new Promise((resolve14, reject) => {
54177
54177
  lookupFn(host, {}, (err, res) => {
54178
54178
  if (err) {
54179
54179
  reject(err);
54180
54180
  } else {
54181
- resolve13(res);
54181
+ resolve14(res);
54182
54182
  }
54183
54183
  });
54184
54184
  });
@@ -55363,7 +55363,7 @@ var require_netUtils = __commonJS({
55363
55363
  return `${socket.remoteAddress}:${socket.remotePort}`;
55364
55364
  }
55365
55365
  function upgradeSocket(socket, options) {
55366
- return new Promise((resolve13, reject) => {
55366
+ return new Promise((resolve14, reject) => {
55367
55367
  const tlsOptions = Object.assign({}, options, {
55368
55368
  socket
55369
55369
  });
@@ -55373,7 +55373,7 @@ var require_netUtils = __commonJS({
55373
55373
  reject(tlsSocket.authorizationError);
55374
55374
  } else {
55375
55375
  tlsSocket.removeAllListeners("error");
55376
- resolve13(tlsSocket);
55376
+ resolve14(tlsSocket);
55377
55377
  }
55378
55378
  }).once("error", (error) => {
55379
55379
  reject(error);
@@ -55468,7 +55468,7 @@ var require_transfer = __commonJS({
55468
55468
  };
55469
55469
  }
55470
55470
  function connectForPassiveTransfer(host, port, ftp) {
55471
- return new Promise((resolve13, reject) => {
55471
+ return new Promise((resolve14, reject) => {
55472
55472
  let socket = ftp._newSocket();
55473
55473
  const handleConnErr = function(err) {
55474
55474
  err.message = "Can't open data connection in passive mode: " + err.message;
@@ -55496,7 +55496,7 @@ var require_transfer = __commonJS({
55496
55496
  socket.removeListener("error", handleConnErr);
55497
55497
  socket.removeListener("timeout", handleTimeout);
55498
55498
  ftp.dataSocket = socket;
55499
- resolve13();
55499
+ resolve14();
55500
55500
  });
55501
55501
  });
55502
55502
  }
@@ -67965,11 +67965,11 @@ function __metadata(metadataKey, metadataValue) {
67965
67965
  }
67966
67966
  function __awaiter2(thisArg, _arguments, P, generator) {
67967
67967
  function adopt(value) {
67968
- return value instanceof P ? value : new P(function(resolve13) {
67969
- resolve13(value);
67968
+ return value instanceof P ? value : new P(function(resolve14) {
67969
+ resolve14(value);
67970
67970
  });
67971
67971
  }
67972
- return new (P || (P = Promise))(function(resolve13, reject) {
67972
+ return new (P || (P = Promise))(function(resolve14, reject) {
67973
67973
  function fulfilled(value) {
67974
67974
  try {
67975
67975
  step(generator.next(value));
@@ -67985,7 +67985,7 @@ function __awaiter2(thisArg, _arguments, P, generator) {
67985
67985
  }
67986
67986
  }
67987
67987
  function step(result) {
67988
- result.done ? resolve13(result.value) : adopt(result.value).then(fulfilled, rejected);
67988
+ result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected);
67989
67989
  }
67990
67990
  step((generator = generator.apply(thisArg, _arguments || [])).next());
67991
67991
  });
@@ -68176,14 +68176,14 @@ function __asyncValues2(o) {
68176
68176
  }, i);
68177
68177
  function verb(n) {
68178
68178
  i[n] = o[n] && function(v) {
68179
- return new Promise(function(resolve13, reject) {
68180
- v = o[n](v), settle(resolve13, reject, v.done, v.value);
68179
+ return new Promise(function(resolve14, reject) {
68180
+ v = o[n](v), settle(resolve14, reject, v.done, v.value);
68181
68181
  });
68182
68182
  };
68183
68183
  }
68184
- function settle(resolve13, reject, d, v) {
68184
+ function settle(resolve14, reject, d, v) {
68185
68185
  Promise.resolve(v).then(function(v2) {
68186
- resolve13({ value: v2, done: d });
68186
+ resolve14({ value: v2, done: d });
68187
68187
  }, reject);
68188
68188
  }
68189
68189
  }
@@ -71736,12 +71736,12 @@ var require_util3 = __commonJS({
71736
71736
  exports.isGMT = exports.dnsLookup = void 0;
71737
71737
  var dns_1 = __require("dns");
71738
71738
  function dnsLookup(host, opts) {
71739
- return new Promise((resolve13, reject) => {
71739
+ return new Promise((resolve14, reject) => {
71740
71740
  (0, dns_1.lookup)(host, opts, (err, res) => {
71741
71741
  if (err) {
71742
71742
  reject(err);
71743
71743
  } else {
71744
- resolve13(res);
71744
+ resolve14(res);
71745
71745
  }
71746
71746
  });
71747
71747
  });
@@ -72106,10 +72106,10 @@ var require_myIpAddress = __commonJS({
72106
72106
  var ip_1 = require_ip();
72107
72107
  var net_1 = __importDefault2(__require("net"));
72108
72108
  async function myIpAddress() {
72109
- return new Promise((resolve13, reject) => {
72109
+ return new Promise((resolve14, reject) => {
72110
72110
  const socket = net_1.default.connect({ host: "8.8.8.8", port: 53 });
72111
72111
  const onError = () => {
72112
- resolve13(ip_1.ip.address());
72112
+ resolve14(ip_1.ip.address());
72113
72113
  };
72114
72114
  socket.once("error", onError);
72115
72115
  socket.once("connect", () => {
@@ -72117,9 +72117,9 @@ var require_myIpAddress = __commonJS({
72117
72117
  const addr = socket.address();
72118
72118
  socket.destroy();
72119
72119
  if (typeof addr === "string") {
72120
- resolve13(addr);
72120
+ resolve14(addr);
72121
72121
  } else if (addr.address) {
72122
- resolve13(addr.address);
72122
+ resolve14(addr.address);
72123
72123
  } else {
72124
72124
  reject(new Error("Expected a `string`"));
72125
72125
  }
@@ -72697,8 +72697,8 @@ var require_deferred_promise = __commonJS({
72697
72697
  this.context = args.context;
72698
72698
  this.owner = args.context.runtime;
72699
72699
  this.handle = args.promiseHandle;
72700
- this.settled = new Promise((resolve13) => {
72701
- this.onSettled = resolve13;
72700
+ this.settled = new Promise((resolve14) => {
72701
+ this.onSettled = resolve14;
72702
72702
  });
72703
72703
  this.resolveHandle = args.resolveHandle;
72704
72704
  this.rejectHandle = args.rejectHandle;
@@ -73219,13 +73219,13 @@ var require_context = __commonJS({
73219
73219
  if (vmResolveResult.error) {
73220
73220
  return Promise.resolve(vmResolveResult);
73221
73221
  }
73222
- return new Promise((resolve13) => {
73222
+ return new Promise((resolve14) => {
73223
73223
  lifetime_1.Scope.withScope((scope) => {
73224
73224
  const resolveHandle = scope.manage(this.newFunction("resolve", (value) => {
73225
- resolve13({ value: value && value.dup() });
73225
+ resolve14({ value: value && value.dup() });
73226
73226
  }));
73227
73227
  const rejectHandle = scope.manage(this.newFunction("reject", (error) => {
73228
- resolve13({ error: error && error.dup() });
73228
+ resolve14({ error: error && error.dup() });
73229
73229
  }));
73230
73230
  const promiseHandle = scope.manage(vmResolveResult.value);
73231
73231
  const promiseThenHandle = scope.manage(this.getProp(promiseHandle, "then"));
@@ -75600,13 +75600,13 @@ import * as http from "node:http";
75600
75600
  import * as https from "node:https";
75601
75601
  import { URL as URL2, urlToHttpOptions } from "node:url";
75602
75602
  function headHttpRequest(url) {
75603
- return new Promise((resolve13) => {
75603
+ return new Promise((resolve14) => {
75604
75604
  const request3 = httpRequest(url, "HEAD", (response) => {
75605
75605
  response.resume();
75606
- resolve13(response.statusCode === 200);
75606
+ resolve14(response.statusCode === 200);
75607
75607
  }, false);
75608
75608
  request3.on("error", () => {
75609
- resolve13(false);
75609
+ resolve14(false);
75610
75610
  });
75611
75611
  });
75612
75612
  }
@@ -75634,7 +75634,7 @@ function httpRequest(url, method, response, keepAlive = true) {
75634
75634
  return request3;
75635
75635
  }
75636
75636
  function downloadFile(url, destinationPath, progressCallback) {
75637
- return new Promise((resolve13, reject) => {
75637
+ return new Promise((resolve14, reject) => {
75638
75638
  let downloadedBytes = 0;
75639
75639
  let totalBytes = 0;
75640
75640
  function onData(chunk) {
@@ -75650,7 +75650,7 @@ function downloadFile(url, destinationPath, progressCallback) {
75650
75650
  }
75651
75651
  const file = createWriteStream(destinationPath);
75652
75652
  file.on("close", () => {
75653
- return resolve13();
75653
+ return resolve14();
75654
75654
  });
75655
75655
  file.on("error", (error) => {
75656
75656
  return reject(error);
@@ -75675,7 +75675,7 @@ async function getJSON(url) {
75675
75675
  }
75676
75676
  }
75677
75677
  function getText3(url) {
75678
- return new Promise((resolve13, reject) => {
75678
+ return new Promise((resolve14, reject) => {
75679
75679
  const request3 = httpRequest(url, "GET", (response) => {
75680
75680
  let data = "";
75681
75681
  if (response.statusCode && response.statusCode >= 400) {
@@ -75686,7 +75686,7 @@ function getText3(url) {
75686
75686
  });
75687
75687
  response.on("end", () => {
75688
75688
  try {
75689
- return resolve13(String(data));
75689
+ return resolve14(String(data));
75690
75690
  } catch {
75691
75691
  return reject(new Error(`Failed to read text response from ${url}`));
75692
75692
  }
@@ -77078,7 +77078,7 @@ var init_launch = __esm({
77078
77078
  if (opts.onExit) {
77079
77079
  this.#onExitHook = opts.onExit;
77080
77080
  }
77081
- this.#browserProcessExiting = new Promise((resolve13, reject) => {
77081
+ this.#browserProcessExiting = new Promise((resolve14, reject) => {
77082
77082
  this.#browserProcess.once("exit", async () => {
77083
77083
  debugLaunch(`Browser process ${this.#browserProcess.pid} onExit`);
77084
77084
  this.#clearListeners();
@@ -77089,7 +77089,7 @@ var init_launch = __esm({
77089
77089
  reject(err);
77090
77090
  return;
77091
77091
  }
77092
- resolve13();
77092
+ resolve14();
77093
77093
  });
77094
77094
  });
77095
77095
  }
@@ -77205,7 +77205,7 @@ Error cause: ${isErrorLike2(error) ? error.stack : error}`);
77205
77205
  return [...this.#logs];
77206
77206
  }
77207
77207
  waitForLineOutput(regex, timeout2 = 0) {
77208
- return new Promise((resolve13, reject) => {
77208
+ return new Promise((resolve14, reject) => {
77209
77209
  const onClose = (errorOrCode) => {
77210
77210
  cleanup();
77211
77211
  reject(new Error([
@@ -77241,7 +77241,7 @@ Error cause: ${isErrorLike2(error) ? error.stack : error}`);
77241
77241
  return;
77242
77242
  }
77243
77243
  cleanup();
77244
- resolve13(match2[1]);
77244
+ resolve14(match2[1]);
77245
77245
  }
77246
77246
  });
77247
77247
  }
@@ -77710,7 +77710,7 @@ var require_get_stream = __commonJS({
77710
77710
  };
77711
77711
  const { maxBuffer } = options;
77712
77712
  let stream2;
77713
- await new Promise((resolve13, reject) => {
77713
+ await new Promise((resolve14, reject) => {
77714
77714
  const rejectPromise = (error) => {
77715
77715
  if (error && stream2.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
77716
77716
  error.bufferedData = stream2.getBufferedValue();
@@ -77722,7 +77722,7 @@ var require_get_stream = __commonJS({
77722
77722
  rejectPromise(error);
77723
77723
  return;
77724
77724
  }
77725
- resolve13();
77725
+ resolve14();
77726
77726
  });
77727
77727
  stream2.on("data", () => {
77728
77728
  if (stream2.getBufferedLength() > maxBuffer) {
@@ -79011,7 +79011,7 @@ var require_extract_zip = __commonJS({
79011
79011
  debug6("opening", this.zipPath, "with opts", this.opts);
79012
79012
  this.zipfile = await openZip(this.zipPath, { lazyEntries: true });
79013
79013
  this.canceled = false;
79014
- return new Promise((resolve13, reject) => {
79014
+ return new Promise((resolve14, reject) => {
79015
79015
  this.zipfile.on("error", (err) => {
79016
79016
  this.canceled = true;
79017
79017
  reject(err);
@@ -79020,7 +79020,7 @@ var require_extract_zip = __commonJS({
79020
79020
  this.zipfile.on("close", () => {
79021
79021
  if (!this.canceled) {
79022
79022
  debug6("zip extraction complete");
79023
- resolve13();
79023
+ resolve14();
79024
79024
  }
79025
79025
  });
79026
79026
  this.zipfile.on("entry", async (entry) => {
@@ -80277,8 +80277,8 @@ var require_streamx = __commonJS({
80277
80277
  return this;
80278
80278
  },
80279
80279
  next() {
80280
- return new Promise(function(resolve13, reject) {
80281
- promiseResolve = resolve13;
80280
+ return new Promise(function(resolve14, reject) {
80281
+ promiseResolve = resolve14;
80282
80282
  promiseReject = reject;
80283
80283
  const data = stream2.read();
80284
80284
  if (data !== null) ondata(data);
@@ -80308,11 +80308,11 @@ var require_streamx = __commonJS({
80308
80308
  }
80309
80309
  function destroy(err) {
80310
80310
  stream2.destroy(err);
80311
- return new Promise((resolve13, reject) => {
80312
- if (stream2._duplexState & DESTROYED) return resolve13({ value: void 0, done: true });
80311
+ return new Promise((resolve14, reject) => {
80312
+ if (stream2._duplexState & DESTROYED) return resolve14({ value: void 0, done: true });
80313
80313
  stream2.once("close", function() {
80314
80314
  if (err) reject(err);
80315
- else resolve13({ value: void 0, done: true });
80315
+ else resolve14({ value: void 0, done: true });
80316
80316
  });
80317
80317
  });
80318
80318
  }
@@ -80356,8 +80356,8 @@ var require_streamx = __commonJS({
80356
80356
  const writes = pending + (ws._duplexState & WRITE_WRITING ? 1 : 0);
80357
80357
  if (writes === 0) return Promise.resolve(true);
80358
80358
  if (state.drains === null) state.drains = [];
80359
- return new Promise((resolve13) => {
80360
- state.drains.push({ writes, resolve: resolve13 });
80359
+ return new Promise((resolve14) => {
80360
+ state.drains.push({ writes, resolve: resolve14 });
80361
80361
  });
80362
80362
  }
80363
80363
  write(data) {
@@ -80462,10 +80462,10 @@ var require_streamx = __commonJS({
80462
80462
  cb(null);
80463
80463
  }
80464
80464
  function pipelinePromise(...streams) {
80465
- return new Promise((resolve13, reject) => {
80465
+ return new Promise((resolve14, reject) => {
80466
80466
  return pipeline(...streams, (err) => {
80467
80467
  if (err) return reject(err);
80468
- resolve13();
80468
+ resolve14();
80469
80469
  });
80470
80470
  });
80471
80471
  }
@@ -81120,16 +81120,16 @@ var require_extract = __commonJS({
81120
81120
  entryCallback = null;
81121
81121
  cb(err);
81122
81122
  }
81123
- function onnext(resolve13, reject) {
81123
+ function onnext(resolve14, reject) {
81124
81124
  if (error) {
81125
81125
  return reject(error);
81126
81126
  }
81127
81127
  if (entryStream) {
81128
- resolve13({ value: entryStream, done: false });
81128
+ resolve14({ value: entryStream, done: false });
81129
81129
  entryStream = null;
81130
81130
  return;
81131
81131
  }
81132
- promiseResolve = resolve13;
81132
+ promiseResolve = resolve14;
81133
81133
  promiseReject = reject;
81134
81134
  consumeCallback(null);
81135
81135
  if (extract._finished && promiseResolve) {
@@ -81157,11 +81157,11 @@ var require_extract = __commonJS({
81157
81157
  function destroy(err) {
81158
81158
  extract.destroy(err);
81159
81159
  consumeCallback(err);
81160
- return new Promise((resolve13, reject) => {
81161
- if (extract.destroyed) return resolve13({ value: void 0, done: true });
81160
+ return new Promise((resolve14, reject) => {
81161
+ if (extract.destroyed) return resolve14({ value: void 0, done: true });
81162
81162
  extract.once("close", function() {
81163
81163
  if (err) reject(err);
81164
- else resolve13({ value: void 0, done: true });
81164
+ else resolve14({ value: void 0, done: true });
81165
81165
  });
81166
81166
  });
81167
81167
  }
@@ -84930,13 +84930,13 @@ function usage(yargs, shim3) {
84930
84930
  };
84931
84931
  self2.stringifiedValues = function stringifiedValues(values, separator) {
84932
84932
  let string = "";
84933
- const sep = separator || ", ";
84933
+ const sep2 = separator || ", ";
84934
84934
  const array = [].concat(values);
84935
84935
  if (!values || !array.length)
84936
84936
  return string;
84937
84937
  array.forEach((value) => {
84938
84938
  if (string.length)
84939
- string += sep;
84939
+ string += sep2;
84940
84940
  string += JSON.stringify(value);
84941
84941
  });
84942
84942
  return string;
@@ -86137,12 +86137,12 @@ var init_yargs_factory = __esm({
86137
86137
  async getCompletion(args, done) {
86138
86138
  argsert("<array> [function]", [args, done], arguments.length);
86139
86139
  if (!done) {
86140
- return new Promise((resolve13, reject) => {
86140
+ return new Promise((resolve14, reject) => {
86141
86141
  __classPrivateFieldGet2(this, _YargsInstance_completion, "f").getCompletion(args, (err, completions) => {
86142
86142
  if (err)
86143
86143
  reject(err);
86144
86144
  else
86145
- resolve13(completions);
86145
+ resolve14(completions);
86146
86146
  });
86147
86147
  });
86148
86148
  } else {
@@ -88943,8 +88943,8 @@ var init_ScreenRecorder = __esm({
88943
88943
  static {
88944
88944
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
88945
88945
  __esDecorate23(this, _private_writeFrame_descriptor = { value: __setFunctionName6(async function(buffer) {
88946
- const error = await new Promise((resolve13) => {
88947
- this.#process.stdin.write(buffer, resolve13);
88946
+ const error = await new Promise((resolve14) => {
88947
+ this.#process.stdin.write(buffer, resolve14);
88948
88948
  });
88949
88949
  if (error) {
88950
88950
  console.log(`ffmpeg failed to write: ${error.message}.`);
@@ -89134,8 +89134,8 @@ var init_ScreenRecorder = __esm({
89134
89134
  const [buffer, timestamp] = await this.#lastFrame;
89135
89135
  await Promise.all(Array(Math.max(1, Math.round(this.#fps * (performance.now() - timestamp) / 1e3))).fill(buffer).map(this.#writeFrame.bind(this)));
89136
89136
  this.#process.stdin.end();
89137
- await new Promise((resolve13) => {
89138
- this.#process.once("close", resolve13);
89137
+ await new Promise((resolve14) => {
89138
+ this.#process.once("close", resolve14);
89139
89139
  });
89140
89140
  }
89141
89141
  /**
@@ -93033,8 +93033,8 @@ var CustomElementRegistry = class {
93033
93033
  } : (element) => element.localName === localName;
93034
93034
  registry.set(localName, { Class, check });
93035
93035
  if (waiting.has(localName)) {
93036
- for (const resolve13 of waiting.get(localName))
93037
- resolve13(Class);
93036
+ for (const resolve14 of waiting.get(localName))
93037
+ resolve14(Class);
93038
93038
  waiting.delete(localName);
93039
93039
  }
93040
93040
  ownerDocument.querySelectorAll(
@@ -93074,13 +93074,13 @@ var CustomElementRegistry = class {
93074
93074
  */
93075
93075
  whenDefined(localName) {
93076
93076
  const { registry, waiting } = this;
93077
- return new Promise((resolve13) => {
93077
+ return new Promise((resolve14) => {
93078
93078
  if (registry.has(localName))
93079
- resolve13(registry.get(localName).Class);
93079
+ resolve14(registry.get(localName).Class);
93080
93080
  else {
93081
93081
  if (!waiting.has(localName))
93082
93082
  waiting.set(localName, []);
93083
- waiting.get(localName).push(resolve13);
93083
+ waiting.get(localName).push(resolve14);
93084
93084
  }
93085
93085
  });
93086
93086
  }
@@ -98730,7 +98730,7 @@ function resolveConfig(overrides) {
98730
98730
  hdr: (() => {
98731
98731
  const raw2 = env2("PRODUCER_HDR_TRANSFER");
98732
98732
  if (raw2 === "hlg" || raw2 === "pq") return { transfer: raw2 };
98733
- return void 0;
98733
+ return false;
98734
98734
  })(),
98735
98735
  hdrAutoDetect: envBool("PRODUCER_HDR_AUTO_DETECT", DEFAULT_CONFIG.hdrAutoDetect),
98736
98736
  audioGain: envNum("PRODUCER_AUDIO_GAIN", DEFAULT_CONFIG.audioGain),
@@ -101132,7 +101132,8 @@ async function injectVideoFramesBatch(page, updates) {
101132
101132
  let img = video.nextElementSibling;
101133
101133
  const isNewImage = !img || !img.classList.contains("__render_frame__");
101134
101134
  const computedStyle = window.getComputedStyle(video);
101135
- const computedOpacity = parseFloat(computedStyle.opacity) || 1;
101135
+ const opacityParsed = parseFloat(computedStyle.opacity);
101136
+ const computedOpacity = Number.isNaN(opacityParsed) ? 1 : opacityParsed;
101136
101137
  const sourceIsStatic = !computedStyle.position || computedStyle.position === "static";
101137
101138
  if (isNewImage) {
101138
101139
  img = document.createElement("img");
@@ -101178,7 +101179,6 @@ async function injectVideoFramesBatch(page, updates) {
101178
101179
  img.style.opacity = String(computedOpacity);
101179
101180
  img.style.visibility = "visible";
101180
101181
  video.style.setProperty("visibility", "hidden", "important");
101181
- video.style.setProperty("opacity", "0", "important");
101182
101182
  video.style.setProperty("pointer-events", "none", "important");
101183
101183
  }
101184
101184
  if (pendingDecodes.length > 0) {
@@ -101205,7 +101205,6 @@ async function syncVideoFrameVisibility(page, activeVideoIds) {
101205
101205
  } else {
101206
101206
  video.style.removeProperty("display");
101207
101207
  video.style.setProperty("visibility", "hidden", "important");
101208
- video.style.setProperty("opacity", "0", "important");
101209
101208
  video.style.setProperty("pointer-events", "none", "important");
101210
101209
  if (hasImg) {
101211
101210
  img.style.visibility = "hidden";
@@ -101296,7 +101295,7 @@ async function pollPageExpression(page, expression, timeoutMs, intervalMs = 100)
101296
101295
  while (Date.now() < deadline) {
101297
101296
  const ready = Boolean(await page.evaluate(expression));
101298
101297
  if (ready) return true;
101299
- await new Promise((resolve13) => setTimeout(resolve13, intervalMs));
101298
+ await new Promise((resolve14) => setTimeout(resolve14, intervalMs));
101300
101299
  }
101301
101300
  return Boolean(await page.evaluate(expression));
101302
101301
  }
@@ -101527,9 +101526,15 @@ async function captureFrameToBuffer(session, frameIndex, time) {
101527
101526
  return { buffer, captureTimeMs };
101528
101527
  }
101529
101528
  async function closeCaptureSession(session) {
101530
- if (session.page) await session.page.close().catch(() => {
101531
- });
101532
- if (session.browser) await releaseBrowser(session.browser, session.config);
101529
+ if (!session.pageReleased && session.page) {
101530
+ await session.page.close().catch(() => {
101531
+ });
101532
+ session.pageReleased = true;
101533
+ }
101534
+ if (!session.browserReleased && session.browser) {
101535
+ await releaseBrowser(session.browser, session.config);
101536
+ session.browserReleased = true;
101537
+ }
101533
101538
  session.isInitialized = false;
101534
101539
  }
101535
101540
  function prepareCaptureSessionForReuse(session, outputDir, onBeforeCapture) {
@@ -101573,7 +101578,7 @@ import { join as join6, dirname as dirname5 } from "path";
101573
101578
  // ../engine/src/utils/gpuEncoder.ts
101574
101579
  import { spawn as spawn3 } from "child_process";
101575
101580
  async function detectGpuEncoder() {
101576
- return new Promise((resolve13) => {
101581
+ return new Promise((resolve14) => {
101577
101582
  const ffmpeg = spawn3("ffmpeg", ["-encoders"], {
101578
101583
  stdio: ["pipe", "pipe", "pipe"]
101579
101584
  });
@@ -101582,13 +101587,13 @@ async function detectGpuEncoder() {
101582
101587
  stdout += data.toString();
101583
101588
  });
101584
101589
  ffmpeg.on("close", () => {
101585
- if (stdout.includes("h264_nvenc")) resolve13("nvenc");
101586
- else if (stdout.includes("h264_videotoolbox")) resolve13("videotoolbox");
101587
- else if (stdout.includes("h264_vaapi")) resolve13("vaapi");
101588
- else if (stdout.includes("h264_qsv")) resolve13("qsv");
101589
- else resolve13(null);
101590
+ if (stdout.includes("h264_nvenc")) resolve14("nvenc");
101591
+ else if (stdout.includes("h264_videotoolbox")) resolve14("videotoolbox");
101592
+ else if (stdout.includes("h264_vaapi")) resolve14("vaapi");
101593
+ else if (stdout.includes("h264_qsv")) resolve14("qsv");
101594
+ else resolve14(null);
101590
101595
  });
101591
- ffmpeg.on("error", () => resolve13(null));
101596
+ ffmpeg.on("error", () => resolve14(null));
101592
101597
  });
101593
101598
  }
101594
101599
  var cachedGpuEncoder = void 0;
@@ -101614,6 +101619,45 @@ function getGpuEncoderName(encoder, codec) {
101614
101619
  }
101615
101620
  }
101616
101621
 
101622
+ // ../engine/src/utils/hdr.ts
101623
+ function isHdrColorSpace(cs) {
101624
+ if (!cs) return false;
101625
+ return cs.colorPrimaries.includes("bt2020") || cs.colorSpace.includes("bt2020") || cs.colorTransfer === "smpte2084" || cs.colorTransfer === "arib-std-b67";
101626
+ }
101627
+ function detectTransfer(cs) {
101628
+ if (cs?.colorTransfer === "smpte2084") return "pq";
101629
+ return "hlg";
101630
+ }
101631
+ var DEFAULT_HDR10_MASTERING = {
101632
+ masterDisplay: "G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1)",
101633
+ maxCll: "1000,400"
101634
+ };
101635
+ function getHdrEncoderColorParams(transfer, mastering = DEFAULT_HDR10_MASTERING) {
101636
+ const colorTrc = transfer === "pq" ? "smpte2084" : "arib-std-b67";
101637
+ const tagging = `colorprim=bt2020:transfer=${colorTrc}:colormatrix=bt2020nc`;
101638
+ const metadata = `master-display=${mastering.masterDisplay}:max-cll=${mastering.maxCll}`;
101639
+ return {
101640
+ colorPrimaries: "bt2020",
101641
+ colorTrc,
101642
+ colorspace: "bt2020nc",
101643
+ pixelFormat: "yuv420p10le",
101644
+ x265ColorParams: `${tagging}:${metadata}`,
101645
+ mastering
101646
+ };
101647
+ }
101648
+ function analyzeCompositionHdr(colorSpaces) {
101649
+ let hasPq = false;
101650
+ let hasHdr = false;
101651
+ for (const cs of colorSpaces) {
101652
+ if (!isHdrColorSpace(cs)) continue;
101653
+ hasHdr = true;
101654
+ if (cs?.colorTransfer === "smpte2084") hasPq = true;
101655
+ }
101656
+ if (!hasHdr) return { hasHdr: false, dominantTransfer: null };
101657
+ const dominantTransfer = hasPq ? "pq" : "hlg";
101658
+ return { hasHdr: true, dominantTransfer };
101659
+ }
101660
+
101617
101661
  // ../engine/src/utils/runFfmpeg.ts
101618
101662
  import { spawn as spawn4 } from "child_process";
101619
101663
  var DEFAULT_TIMEOUT2 = 3e5;
@@ -101622,7 +101666,7 @@ async function runFfmpeg(args, opts) {
101622
101666
  const signal = opts?.signal;
101623
101667
  const timeout2 = opts?.timeout ?? DEFAULT_TIMEOUT2;
101624
101668
  const onStderr = opts?.onStderr;
101625
- return new Promise((resolve13) => {
101669
+ return new Promise((resolve14) => {
101626
101670
  const ffmpeg = spawn4("ffmpeg", args);
101627
101671
  let stderr = "";
101628
101672
  const onAbort = () => {
@@ -101648,7 +101692,7 @@ async function runFfmpeg(args, opts) {
101648
101692
  ffmpeg.on("close", (code) => {
101649
101693
  clearTimeout(timer2);
101650
101694
  if (signal) signal.removeEventListener("abort", onAbort);
101651
- resolve13({
101695
+ resolve14({
101652
101696
  success: !signal?.aborted && code === 0,
101653
101697
  exitCode: code,
101654
101698
  stderr,
@@ -101658,7 +101702,7 @@ async function runFfmpeg(args, opts) {
101658
101702
  ffmpeg.on("error", (err) => {
101659
101703
  clearTimeout(timer2);
101660
101704
  if (signal) signal.removeEventListener("abort", onAbort);
101661
- resolve13({
101705
+ resolve14({
101662
101706
  success: false,
101663
101707
  exitCode: null,
101664
101708
  stderr: err.message,
@@ -101713,6 +101757,12 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
101713
101757
  pixelFormat = "yuv420p",
101714
101758
  useGpu = false
101715
101759
  } = options;
101760
+ if (options.hdr && codec === "h264") {
101761
+ console.warn(
101762
+ "[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."
101763
+ );
101764
+ options = { ...options, hdr: void 0 };
101765
+ }
101716
101766
  const args = [...inputArgs, "-r", String(fps)];
101717
101767
  const shouldUseGpu = useGpu && gpuEncoder !== null;
101718
101768
  if (codec === "h264" || codec === "h265") {
@@ -101751,7 +101801,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
101751
101801
  if (bitrate) args.push("-b:v", bitrate);
101752
101802
  else args.push("-crf", String(quality));
101753
101803
  const xParamsFlag = codec === "h264" ? "-x264-params" : "-x265-params";
101754
- const colorParams = "colorprim=bt709:transfer=bt709:colormatrix=bt709";
101804
+ const colorParams = codec === "h265" && options.hdr ? getHdrEncoderColorParams(options.hdr.transfer).x265ColorParams : "colorprim=bt709:transfer=bt709:colormatrix=bt709";
101755
101805
  if (preset === "ultrafast") {
101756
101806
  args.push(xParamsFlag, `aq-mode=3:${colorParams}`);
101757
101807
  } else {
@@ -101775,16 +101825,30 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
101775
101825
  return [...args, "-y", outputPath];
101776
101826
  }
101777
101827
  if (codec === "h264" || codec === "h265") {
101778
- args.push(
101779
- "-colorspace:v",
101780
- "bt709",
101781
- "-color_primaries:v",
101782
- "bt709",
101783
- "-color_trc:v",
101784
- "bt709",
101785
- "-color_range",
101786
- "tv"
101787
- );
101828
+ if (options.hdr) {
101829
+ const transferTag = options.hdr.transfer === "pq" ? "smpte2084" : "arib-std-b67";
101830
+ args.push(
101831
+ "-colorspace:v",
101832
+ "bt2020nc",
101833
+ "-color_primaries:v",
101834
+ "bt2020",
101835
+ "-color_trc:v",
101836
+ transferTag,
101837
+ "-color_range",
101838
+ "tv"
101839
+ );
101840
+ } else {
101841
+ args.push(
101842
+ "-colorspace:v",
101843
+ "bt709",
101844
+ "-color_primaries:v",
101845
+ "bt709",
101846
+ "-color_trc:v",
101847
+ "bt709",
101848
+ "-color_range",
101849
+ "tv"
101850
+ );
101851
+ }
101788
101852
  if (gpuEncoder === "vaapi") {
101789
101853
  const vfIdx = args.indexOf("-vf");
101790
101854
  if (vfIdx !== -1) {
@@ -101824,7 +101888,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
101824
101888
  const inputPath = join6(framesDir, framePattern);
101825
101889
  const inputArgs = ["-framerate", String(options.fps), "-i", inputPath];
101826
101890
  const args = buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder);
101827
- return new Promise((resolve13) => {
101891
+ return new Promise((resolve14) => {
101828
101892
  const ffmpeg = spawn5("ffmpeg", args);
101829
101893
  let stderr = "";
101830
101894
  const onAbort = () => {
@@ -101849,7 +101913,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
101849
101913
  if (signal) signal.removeEventListener("abort", onAbort);
101850
101914
  const durationMs = Date.now() - startTime;
101851
101915
  if (signal?.aborted) {
101852
- resolve13({
101916
+ resolve14({
101853
101917
  success: false,
101854
101918
  outputPath,
101855
101919
  durationMs,
@@ -101860,7 +101924,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
101860
101924
  return;
101861
101925
  }
101862
101926
  if (code !== 0) {
101863
- resolve13({
101927
+ resolve14({
101864
101928
  success: false,
101865
101929
  outputPath,
101866
101930
  durationMs,
@@ -101871,12 +101935,12 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
101871
101935
  return;
101872
101936
  }
101873
101937
  const fileSize = existsSync5(outputPath) ? statSync3(outputPath).size : 0;
101874
- resolve13({ success: true, outputPath, durationMs, framesEncoded: frameCount, fileSize });
101938
+ resolve14({ success: true, outputPath, durationMs, framesEncoded: frameCount, fileSize });
101875
101939
  });
101876
101940
  ffmpeg.on("error", (err) => {
101877
101941
  clearTimeout(timer2);
101878
101942
  if (signal) signal.removeEventListener("abort", onAbort);
101879
- resolve13({
101943
+ resolve14({
101880
101944
  success: false,
101881
101945
  outputPath,
101882
101946
  durationMs: Date.now() - startTime,
@@ -101934,18 +101998,18 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
101934
101998
  let gpuEncoder = null;
101935
101999
  if (options.useGpu) gpuEncoder = await getCachedGpuEncoder();
101936
102000
  const args = buildEncoderArgs(options, inputArgs, chunkPath, gpuEncoder);
101937
- const chunkResult = await new Promise((resolve13) => {
102001
+ const chunkResult = await new Promise((resolve14) => {
101938
102002
  const ffmpeg = spawn5("ffmpeg", args);
101939
102003
  let stderr = "";
101940
102004
  ffmpeg.stderr.on("data", (d) => {
101941
102005
  stderr += d.toString();
101942
102006
  });
101943
102007
  ffmpeg.on("close", (code) => {
101944
- if (code === 0) resolve13({ success: true });
101945
- else resolve13({ success: false, error: `Chunk ${i} encode failed: ${stderr.slice(-400)}` });
102008
+ if (code === 0) resolve14({ success: true });
102009
+ else resolve14({ success: false, error: `Chunk ${i} encode failed: ${stderr.slice(-400)}` });
101946
102010
  });
101947
102011
  ffmpeg.on("error", (err) => {
101948
- resolve13({ success: false, error: `Chunk ${i} encode error: ${err.message}` });
102012
+ resolve14({ success: false, error: `Chunk ${i} encode error: ${err.message}` });
101949
102013
  });
101950
102014
  });
101951
102015
  if (!chunkResult.success) {
@@ -101975,18 +102039,18 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
101975
102039
  "-y",
101976
102040
  outputPath
101977
102041
  ];
101978
- const concatResult = await new Promise((resolve13) => {
102042
+ const concatResult = await new Promise((resolve14) => {
101979
102043
  const ffmpeg = spawn5("ffmpeg", concatArgs);
101980
102044
  let stderr = "";
101981
102045
  ffmpeg.stderr.on("data", (d) => {
101982
102046
  stderr += d.toString();
101983
102047
  });
101984
102048
  ffmpeg.on("close", (code) => {
101985
- if (code === 0) resolve13({ success: true });
101986
- else resolve13({ success: false, error: `Chunk concat failed: ${stderr.slice(-400)}` });
102049
+ if (code === 0) resolve14({ success: true });
102050
+ else resolve14({ success: false, error: `Chunk concat failed: ${stderr.slice(-400)}` });
101987
102051
  });
101988
102052
  ffmpeg.on("error", (err) => {
101989
- resolve13({ success: false, error: `Chunk concat error: ${err.message}` });
102053
+ resolve14({ success: false, error: `Chunk concat error: ${err.message}` });
101990
102054
  });
101991
102055
  });
101992
102056
  if (!concatResult.success) {
@@ -102067,81 +102131,40 @@ async function applyFaststart(inputPath, outputPath, signal, config2) {
102067
102131
  import { spawn as spawn6 } from "child_process";
102068
102132
  import { existsSync as existsSync6, mkdirSync as mkdirSync3, statSync as statSync4 } from "fs";
102069
102133
  import { dirname as dirname6 } from "path";
102070
-
102071
- // ../engine/src/utils/hdr.ts
102072
- function isHdrColorSpace(cs) {
102073
- if (!cs) return false;
102074
- return cs.colorPrimaries.includes("bt2020") || cs.colorSpace.includes("bt2020") || cs.colorTransfer === "smpte2084" || cs.colorTransfer === "arib-std-b67";
102075
- }
102076
- function detectTransfer(cs) {
102077
- if (cs?.colorTransfer === "smpte2084") return "pq";
102078
- return "hlg";
102079
- }
102080
- var DEFAULT_HDR10_MASTERING = {
102081
- masterDisplay: "G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1)",
102082
- maxCll: "1000,400"
102083
- };
102084
- function getHdrEncoderColorParams(transfer, mastering = DEFAULT_HDR10_MASTERING) {
102085
- const colorTrc = transfer === "pq" ? "smpte2084" : "arib-std-b67";
102086
- const tagging = `colorprim=bt2020:transfer=${colorTrc}:colormatrix=bt2020nc`;
102087
- const metadata = `master-display=${mastering.masterDisplay}:max-cll=${mastering.maxCll}`;
102088
- return {
102089
- colorPrimaries: "bt2020",
102090
- colorTrc,
102091
- colorspace: "bt2020nc",
102092
- pixelFormat: "yuv420p10le",
102093
- x265ColorParams: `${tagging}:${metadata}`,
102094
- mastering
102095
- };
102096
- }
102097
- function analyzeCompositionHdr(colorSpaces) {
102098
- let hasPq = false;
102099
- let hasHdr = false;
102100
- for (const cs of colorSpaces) {
102101
- if (!isHdrColorSpace(cs)) continue;
102102
- hasHdr = true;
102103
- if (cs?.colorTransfer === "smpte2084") hasPq = true;
102104
- }
102105
- if (!hasHdr) return { hasHdr: false, dominantTransfer: null };
102106
- const dominantTransfer = hasPq ? "pq" : "hlg";
102107
- return { hasHdr: true, dominantTransfer };
102108
- }
102109
-
102110
- // ../engine/src/services/streamingEncoder.ts
102111
102134
  function createFrameReorderBuffer(startFrame, endFrame) {
102112
102135
  let cursor = startFrame;
102113
102136
  const pending = /* @__PURE__ */ new Map();
102114
- const enqueueAt = (frame, resolve13) => {
102137
+ const enqueueAt = (frame, resolve14) => {
102115
102138
  const list = pending.get(frame);
102116
102139
  if (list === void 0) {
102117
- pending.set(frame, [resolve13]);
102140
+ pending.set(frame, [resolve14]);
102118
102141
  } else {
102119
- list.push(resolve13);
102142
+ list.push(resolve14);
102120
102143
  }
102121
102144
  };
102122
102145
  const flushAt = (frame) => {
102123
102146
  const list = pending.get(frame);
102124
102147
  if (list === void 0) return;
102125
102148
  pending.delete(frame);
102126
- for (const resolve13 of list) resolve13();
102149
+ for (const resolve14 of list) resolve14();
102127
102150
  };
102128
- const waitForFrame = (frame) => new Promise((resolve13) => {
102151
+ const waitForFrame = (frame) => new Promise((resolve14) => {
102129
102152
  if (frame === cursor) {
102130
- resolve13();
102153
+ resolve14();
102131
102154
  return;
102132
102155
  }
102133
- enqueueAt(frame, resolve13);
102156
+ enqueueAt(frame, resolve14);
102134
102157
  });
102135
102158
  const advanceTo = (frame) => {
102136
102159
  cursor = frame;
102137
102160
  flushAt(frame);
102138
102161
  };
102139
- const waitForAllDone = () => new Promise((resolve13) => {
102162
+ const waitForAllDone = () => new Promise((resolve14) => {
102140
102163
  if (cursor >= endFrame) {
102141
- resolve13();
102164
+ resolve14();
102142
102165
  return;
102143
102166
  }
102144
- enqueueAt(endFrame, resolve13);
102167
+ enqueueAt(endFrame, resolve14);
102145
102168
  });
102146
102169
  return { waitForFrame, advanceTo, waitForAllDone };
102147
102170
  }
@@ -102303,7 +102326,7 @@ async function spawnStreamingEncoder(outputPath, options, signal, config2) {
102303
102326
  let stderr = "";
102304
102327
  let exitCode = null;
102305
102328
  let exitPromiseResolve = null;
102306
- const exitPromise = new Promise((resolve13) => exitPromiseResolve = resolve13);
102329
+ const exitPromise = new Promise((resolve14) => exitPromiseResolve = resolve14);
102307
102330
  ffmpeg.stderr?.on("data", (data) => {
102308
102331
  stderr += data.toString();
102309
102332
  });
@@ -102349,8 +102372,8 @@ Process error: ${err.message}`;
102349
102372
  if (signal) signal.removeEventListener("abort", onAbort);
102350
102373
  const stdin = ffmpeg.stdin;
102351
102374
  if (stdin && !stdin.destroyed) {
102352
- await new Promise((resolve13) => {
102353
- stdin.end(() => resolve13());
102375
+ await new Promise((resolve14) => {
102376
+ stdin.end(() => resolve14());
102354
102377
  });
102355
102378
  }
102356
102379
  await exitPromise;
@@ -102389,7 +102412,7 @@ import { spawn as spawn7 } from "child_process";
102389
102412
  import { readFileSync as readFileSync5 } from "fs";
102390
102413
  import { extname as extname2 } from "path";
102391
102414
  function runFfprobe(args) {
102392
- return new Promise((resolve13, reject) => {
102415
+ return new Promise((resolve14, reject) => {
102393
102416
  const proc = spawn7("ffprobe", args);
102394
102417
  let stdout = "";
102395
102418
  let stderr = "";
@@ -102403,7 +102426,7 @@ function runFfprobe(args) {
102403
102426
  if (code !== 0) {
102404
102427
  reject(new Error(`[FFmpeg] ffprobe exited with code ${code}: ${stderr}`));
102405
102428
  } else {
102406
- resolve13(stdout);
102429
+ resolve14(stdout);
102407
102430
  }
102408
102431
  });
102409
102432
  proc.on("error", (err) => {
@@ -102802,7 +102825,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
102802
102825
  args.push("-q:v", format3 === "jpg" ? String(Math.ceil((100 - quality) / 3)) : "0");
102803
102826
  if (format3 === "png") args.push("-compression_level", "6");
102804
102827
  args.push("-y", outputPattern);
102805
- return new Promise((resolve13, reject) => {
102828
+ return new Promise((resolve14, reject) => {
102806
102829
  const ffmpeg = spawn8("ffmpeg", args);
102807
102830
  let stderr = "";
102808
102831
  const onAbort = () => {
@@ -102837,7 +102860,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
102837
102860
  files.forEach((file, index) => {
102838
102861
  framePaths.set(index, join8(videoOutputDir, file));
102839
102862
  });
102840
- resolve13({
102863
+ resolve14({
102841
102864
  videoId,
102842
102865
  srcPath: videoPath,
102843
102866
  outputDir: videoOutputDir,
@@ -102859,8 +102882,9 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
102859
102882
  });
102860
102883
  });
102861
102884
  }
102862
- async function convertSdrToHdr(inputPath, outputPath, signal, config2) {
102885
+ async function convertSdrToHdr(inputPath, outputPath, targetTransfer, signal, config2) {
102863
102886
  const timeout2 = config2?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
102887
+ const colorTrc = targetTransfer === "pq" ? "smpte2084" : "arib-std-b67";
102864
102888
  const args = [
102865
102889
  "-i",
102866
102890
  inputPath,
@@ -102869,7 +102893,7 @@ async function convertSdrToHdr(inputPath, outputPath, signal, config2) {
102869
102893
  "-color_primaries",
102870
102894
  "bt2020",
102871
102895
  "-color_trc",
102872
- "arib-std-b67",
102896
+ colorTrc,
102873
102897
  "-colorspace",
102874
102898
  "bt2020nc",
102875
102899
  "-c:v",
@@ -102955,8 +102979,9 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
102955
102979
  return metadata.colorSpace;
102956
102980
  })
102957
102981
  );
102958
- const hasAnyHdr = videoColorSpaces.some(isHdrColorSpace);
102959
- if (hasAnyHdr) {
102982
+ const hdrInfo = analyzeCompositionHdr(videoColorSpaces);
102983
+ if (hdrInfo.hasHdr && hdrInfo.dominantTransfer) {
102984
+ const targetTransfer = hdrInfo.dominantTransfer;
102960
102985
  const convertDir = join8(options.outputDir, "_hdr_normalized");
102961
102986
  mkdirSync5(convertDir, { recursive: true });
102962
102987
  for (let i = 0; i < resolvedVideos.length; i++) {
@@ -102967,7 +102992,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
102967
102992
  if (!entry) continue;
102968
102993
  const convertedPath = join8(convertDir, `${entry.video.id}_hdr.mp4`);
102969
102994
  try {
102970
- await convertSdrToHdr(entry.videoPath, convertedPath, signal, config2);
102995
+ await convertSdrToHdr(entry.videoPath, convertedPath, targetTransfer, signal, config2);
102971
102996
  entry.videoPath = convertedPath;
102972
102997
  } catch (err) {
102973
102998
  errors.push({
@@ -103272,12 +103297,12 @@ async function queryElementStacking(page, nativeHdrIds) {
103272
103297
  function resolveRadius(value, el) {
103273
103298
  if (value.includes("%")) {
103274
103299
  const pct = parseFloat(value) / 100;
103275
- const htmlEl = el;
103276
- const w = htmlEl.offsetWidth || 0;
103277
- const h = htmlEl.offsetHeight || 0;
103300
+ const w = el instanceof HTMLElement ? el.offsetWidth : 0;
103301
+ const h = el instanceof HTMLElement ? el.offsetHeight : 0;
103278
103302
  return pct * Math.min(w, h);
103279
103303
  }
103280
- return parseFloat(value) || 0;
103304
+ const parsed = parseFloat(value);
103305
+ return Number.isNaN(parsed) ? 0 : parsed;
103281
103306
  }
103282
103307
  const selfCs = window.getComputedStyle(node);
103283
103308
  const selfRadii = [
@@ -103361,8 +103386,7 @@ async function queryElementStacking(page, nativeHdrIds) {
103361
103386
  const style = window.getComputedStyle(el);
103362
103387
  const zIndex = getEffectiveZIndex(el);
103363
103388
  const isHdrEl = hdrSet.has(id);
103364
- const opacityStartNode = isHdrEl ? el.parentElement : el;
103365
- const opacity = opacityStartNode ? getEffectiveOpacity(opacityStartNode) : 1;
103389
+ const opacity = getEffectiveOpacity(el);
103366
103390
  const visible = style.visibility !== "hidden" && style.display !== "none" && rect.width > 0 && rect.height > 0;
103367
103391
  const htmlEl = el instanceof HTMLElement ? el : null;
103368
103392
  results.push({
@@ -106359,7 +106383,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
106359
106383
  });
106360
106384
  if (!chunk) {
106361
106385
  if (i === 1) {
106362
- await new Promise((resolve13) => setTimeout(resolve13));
106386
+ await new Promise((resolve14) => setTimeout(resolve14));
106363
106387
  maxReadCount = 3;
106364
106388
  continue;
106365
106389
  }
@@ -107632,14 +107656,14 @@ var ridgedBurn = (from2, to, out, w, h, p) => {
107632
107656
  TRANSITIONS["ridged-burn"] = ridgedBurn;
107633
107657
 
107634
107658
  // src/services/renderOrchestrator.ts
107635
- import { join as join15, dirname as dirname10, resolve as resolve10 } from "path";
107659
+ import { join as join15, dirname as dirname10, resolve as resolve11 } from "path";
107636
107660
  import { randomUUID } from "crypto";
107637
107661
  import { freemem as freemem2 } from "os";
107638
107662
  import { fileURLToPath as fileURLToPath3 } from "url";
107639
107663
 
107640
107664
  // src/services/fileServer.ts
107641
- import { readFileSync as readFileSync7, existsSync as existsSync12, statSync as statSync5 } from "node:fs";
107642
- import { join as join11, extname as extname4 } from "node:path";
107665
+ import { readFileSync as readFileSync7, existsSync as existsSync12, realpathSync, statSync as statSync5 } from "node:fs";
107666
+ import { join as join11, extname as extname4, resolve as resolve8, sep } from "node:path";
107643
107667
 
107644
107668
  // src/services/hyperframeRuntimeLoader.ts
107645
107669
  import { createHash as createHash2 } from "node:crypto";
@@ -107715,6 +107739,18 @@ function resolveVerifiedHyperframeRuntime() {
107715
107739
  }
107716
107740
 
107717
107741
  // src/services/fileServer.ts
107742
+ function isPathInside(child, parent, options = {}) {
107743
+ const { resolveSymlinks = false, pathModule } = options;
107744
+ const resolveFn = pathModule?.resolve ?? resolve8;
107745
+ const separator = pathModule?.sep ?? sep;
107746
+ const resolvedChild = resolveFn(child);
107747
+ const resolvedParent = resolveFn(parent);
107748
+ const normalizedChild = resolveSymlinks && existsSync12(resolvedChild) ? realpathSync.native(resolvedChild) : resolvedChild;
107749
+ const normalizedParent = resolveSymlinks && existsSync12(resolvedParent) ? realpathSync.native(resolvedParent) : resolvedParent;
107750
+ if (normalizedChild === normalizedParent) return true;
107751
+ const parentWithSep = normalizedParent.endsWith(separator) ? normalizedParent : normalizedParent + separator;
107752
+ return normalizedChild.startsWith(parentWithSep);
107753
+ }
107718
107754
  var MIME_TYPES = {
107719
107755
  ".html": "text/html; charset=utf-8",
107720
107756
  ".css": "text/css; charset=utf-8",
@@ -108107,12 +108143,20 @@ function createFileServer2(options) {
108107
108143
  let requestPath = c.req.path;
108108
108144
  if (requestPath === "/") requestPath = "/index.html";
108109
108145
  const relativePath = requestPath.replace(/^\//, "");
108110
- const compiledPath = compiledDir ? join11(compiledDir, relativePath) : null;
108111
- const hasCompiledFile = Boolean(
108112
- compiledPath && existsSync12(compiledPath) && statSync5(compiledPath).isFile()
108113
- );
108114
- const filePath = hasCompiledFile ? compiledPath : join11(projectDir, relativePath);
108115
- if (!existsSync12(filePath) || !statSync5(filePath).isFile()) {
108146
+ let filePath = null;
108147
+ if (compiledDir) {
108148
+ const candidate = join11(compiledDir, relativePath);
108149
+ if (existsSync12(candidate) && isPathInside(candidate, compiledDir, { resolveSymlinks: true }) && statSync5(candidate).isFile()) {
108150
+ filePath = candidate;
108151
+ }
108152
+ }
108153
+ if (!filePath) {
108154
+ const candidate = join11(projectDir, relativePath);
108155
+ if (existsSync12(candidate) && isPathInside(candidate, projectDir, { resolveSymlinks: true }) && statSync5(candidate).isFile()) {
108156
+ filePath = candidate;
108157
+ }
108158
+ }
108159
+ if (!filePath) {
108116
108160
  if (!/favicon\.ico$/i.test(requestPath)) {
108117
108161
  console.warn(`[FileServer] 404 Not Found: ${requestPath}`);
108118
108162
  }
@@ -108136,10 +108180,10 @@ function createFileServer2(options) {
108136
108180
  headers: { "Content-Type": contentType }
108137
108181
  });
108138
108182
  });
108139
- return new Promise((resolve13) => {
108183
+ return new Promise((resolve14) => {
108140
108184
  const connections = /* @__PURE__ */ new Set();
108141
108185
  const server = serve({ fetch: app.fetch, port }, (info) => {
108142
- resolve13({
108186
+ resolve14({
108143
108187
  url: `http://localhost:${info.port}`,
108144
108188
  port: info.port,
108145
108189
  close: () => {
@@ -108158,15 +108202,15 @@ function createFileServer2(options) {
108158
108202
 
108159
108203
  // src/services/htmlCompiler.ts
108160
108204
  import { readFileSync as readFileSync9, existsSync as existsSync14, mkdirSync as mkdirSync9 } from "fs";
108161
- import { join as join14, dirname as dirname9, resolve as resolve9 } from "path";
108205
+ import { join as join14, dirname as dirname9, resolve as resolve10 } from "path";
108162
108206
  import postcss from "postcss";
108163
108207
 
108164
108208
  // src/utils/paths.ts
108165
- import { resolve as resolve8, basename as basename2, join as join12, relative as relative2, isAbsolute as isAbsolute2 } from "node:path";
108166
- var DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ?? resolve8(new URL(import.meta.url).pathname, "../../..", "renders");
108167
- function isPathInside(childPath, parentPath) {
108168
- const absChild = resolve8(childPath);
108169
- const absParent = resolve8(parentPath);
108209
+ import { resolve as resolve9, basename as basename2, join as join12, relative as relative2, isAbsolute as isAbsolute2 } from "node:path";
108210
+ var DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ?? resolve9(new URL(import.meta.url).pathname, "../../..", "renders");
108211
+ function isPathInside2(childPath, parentPath) {
108212
+ const absChild = resolve9(childPath);
108213
+ const absParent = resolve9(parentPath);
108170
108214
  if (absChild === absParent) return true;
108171
108215
  const rel = relative2(absParent, absChild);
108172
108216
  return rel !== "" && !rel.startsWith("..") && !isAbsolute2(rel);
@@ -108182,10 +108226,10 @@ function toExternalAssetKey(absPath) {
108182
108226
  return "hf-ext/" + normalised;
108183
108227
  }
108184
108228
  function resolveRenderPaths(projectDir, outputPath, rendersDir = DEFAULT_RENDERS_DIR) {
108185
- const absoluteProjectDir = resolve8(projectDir);
108229
+ const absoluteProjectDir = resolve9(projectDir);
108186
108230
  const projectName = basename2(absoluteProjectDir);
108187
108231
  const resolvedOutputPath = outputPath ?? join12(rendersDir, `${projectName}.mp4`);
108188
- const absoluteOutputPath = resolve8(resolvedOutputPath);
108232
+ const absoluteOutputPath = resolve9(resolvedOutputPath);
108189
108233
  return { absoluteProjectDir, absoluteOutputPath };
108190
108234
  }
108191
108235
 
@@ -108694,7 +108738,7 @@ async function parseSubCompositions(html, projectDir, downloadDir, parentOffset
108694
108738
  const elEnd = elEndRaw ? parseFloat(elEndRaw) : Infinity;
108695
108739
  const absoluteStart = parentOffset + elStart;
108696
108740
  const absoluteEnd = Math.min(parentEnd, isFinite(elEnd) ? parentOffset + elEnd : Infinity);
108697
- const filePath = resolve9(projectDir, srcPath);
108741
+ const filePath = resolve10(projectDir, srcPath);
108698
108742
  if (visited.has(filePath)) {
108699
108743
  continue;
108700
108744
  }
@@ -108907,7 +108951,7 @@ function inlineSubCompositions(html, subCompositions, projectDir) {
108907
108951
  if (!srcPath) continue;
108908
108952
  let compHtml = subCompositions.get(srcPath) || null;
108909
108953
  if (!compHtml) {
108910
- const filePath = resolve9(projectDir, srcPath);
108954
+ const filePath = resolve10(projectDir, srcPath);
108911
108955
  if (existsSync14(filePath)) {
108912
108956
  compHtml = readFileSync9(filePath, "utf-8");
108913
108957
  }
@@ -109124,7 +109168,7 @@ ${safeText}
109124
109168
  return wrappedFragment ? document2.body.innerHTML || "" : document2.toString();
109125
109169
  }
109126
109170
  function collectExternalAssets(html, projectDir) {
109127
- const absProjectDir = resolve9(projectDir);
109171
+ const absProjectDir = resolve10(projectDir);
109128
109172
  const externalAssets = /* @__PURE__ */ new Map();
109129
109173
  const CSS_URL_RE2 = /\burl\(\s*(["']?)([^)"']+)\1\s*\)/g;
109130
109174
  function processPath(rawPath) {
@@ -109132,8 +109176,8 @@ function collectExternalAssets(html, projectDir) {
109132
109176
  if (!trimmed || trimmed.startsWith("/") || trimmed.startsWith("http://") || trimmed.startsWith("https://") || trimmed.startsWith("//") || trimmed.startsWith("data:") || trimmed.startsWith("#")) {
109133
109177
  return null;
109134
109178
  }
109135
- const absPath = resolve9(absProjectDir, trimmed);
109136
- if (isPathInside(absPath, absProjectDir)) {
109179
+ const absPath = resolve10(absProjectDir, trimmed);
109180
+ if (isPathInside2(absPath, absProjectDir)) {
109137
109181
  return null;
109138
109182
  }
109139
109183
  if (!existsSync14(absPath)) return null;
@@ -109213,7 +109257,7 @@ async function compileForRender(projectDir, htmlPath, downloadDir) {
109213
109257
  const images = dedupeElementsById([...mainImages, ...subImages]);
109214
109258
  for (const video of videos) {
109215
109259
  if (isHttpUrl(video.src)) continue;
109216
- const videoPath = resolve9(projectDir, video.src);
109260
+ const videoPath = resolve10(projectDir, video.src);
109217
109261
  const reencode = `ffmpeg -i "${video.src}" -c:v libx264 -r 30 -g 30 -keyint_min 30 -movflags +faststart -c:a copy output.mp4`;
109218
109262
  Promise.all([analyzeKeyframeIntervals(videoPath), extractVideoMetadata(videoPath)]).then(([analysis, metadata]) => {
109219
109263
  if (analysis.isProblematic) {
@@ -109474,8 +109518,8 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
109474
109518
  writeFileSync4(outPath, html, "utf-8");
109475
109519
  }
109476
109520
  for (const [relativePath, absolutePath] of compiled.externalAssets) {
109477
- const outPath = resolve10(join15(compileDir, relativePath));
109478
- if (!isPathInside(outPath, compileDir)) {
109521
+ const outPath = resolve11(join15(compileDir, relativePath));
109522
+ if (!isPathInside2(outPath, compileDir)) {
109479
109523
  console.warn(`[Render] Skipping external asset with unsafe path: ${relativePath}`);
109480
109524
  continue;
109481
109525
  }
@@ -109662,7 +109706,7 @@ function extractStandaloneEntryFromIndex(indexHtml, entryFile) {
109662
109706
  }
109663
109707
  async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSignal) {
109664
109708
  const moduleDir = dirname10(fileURLToPath3(import.meta.url));
109665
- const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve10(process.env.PRODUCER_RENDERS_DIR, "..") : resolve10(moduleDir, "../..");
109709
+ const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve11(process.env.PRODUCER_RENDERS_DIR, "..") : resolve11(moduleDir, "../..");
109666
109710
  const debugDir = join15(producerRoot, ".debug");
109667
109711
  const workDir = job.config.debug ? join15(debugDir, job.id) : join15(dirname10(outputPath), `work-${job.id}`);
109668
109712
  const pipelineStart = Date.now();
@@ -110106,6 +110150,13 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
110106
110150
  const hasHdrContent = effectiveHdr && nativeHdrIds.size > 0;
110107
110151
  const encoderHdr = hasHdrContent ? effectiveHdr : void 0;
110108
110152
  const preset = getEncoderPreset(job.config.quality, outputFormat, encoderHdr);
110153
+ if (job.config.crf != null && job.config.videoBitrate) {
110154
+ log.warn(
110155
+ `[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.`
110156
+ );
110157
+ }
110158
+ const effectiveQuality = job.config.crf ?? preset.quality;
110159
+ const effectiveBitrate = job.config.crf != null ? void 0 : job.config.videoBitrate;
110109
110160
  job.framesRendered = 0;
110110
110161
  if (hasHdrContent) {
110111
110162
  log.info("[Render] HDR layered composite: z-ordered DOM + native HLG video layers");
@@ -110129,411 +110180,251 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
110129
110180
  createVideoFrameInjector(frameLookup),
110130
110181
  cfg
110131
110182
  );
110132
- await initializeSession(domSession);
110133
- assertNotAborted();
110134
- lastBrowserConsole = domSession.browserConsoleBuffer;
110135
- await initTransparentBackground(domSession.page);
110136
- const transitionMeta = await domSession.page.evaluate(() => {
110137
- return window.__hf?.transitions ?? [];
110138
- });
110139
- const sceneElements = await domSession.page.evaluate(() => {
110140
- const scenes = document.querySelectorAll(".scene");
110141
- const map2 = {};
110142
- for (const scene of scenes) {
110143
- const els = scene.querySelectorAll("[data-start]");
110144
- map2[scene.id] = Array.from(els).map((e) => e.id);
110145
- }
110146
- return map2;
110147
- });
110148
- const transitionRanges = transitionMeta.map((t) => ({
110149
- ...t,
110150
- startFrame: Math.floor(t.time * job.config.fps),
110151
- endFrame: Math.ceil((t.time + t.duration) * job.config.fps)
110152
- }));
110153
- if (transitionRanges.length > 0) {
110154
- log.info("[Render] Detected shader transitions for HDR compositing", {
110155
- count: transitionRanges.length,
110156
- transitions: transitionRanges.map((t) => ({
110157
- shader: t.shader,
110158
- from: t.fromScene,
110159
- to: t.toScene,
110160
- frames: `${t.startFrame}-${t.endFrame}`
110161
- }))
110162
- });
110163
- }
110164
- const hdrEncoder = await spawnStreamingEncoder(
110165
- videoOnlyPath,
110166
- {
110167
- fps: job.config.fps,
110168
- width,
110169
- height,
110170
- codec: preset.codec,
110171
- preset: preset.preset,
110172
- quality: preset.quality,
110173
- pixelFormat: preset.pixelFormat,
110174
- hdr: preset.hdr,
110175
- rawInputFormat: "rgb48le"
110176
- },
110177
- abortSignal,
110178
- { ffmpegStreamingTimeout: 36e5 }
110179
- );
110180
- assertNotAborted();
110181
- const hdrExtractionDims = /* @__PURE__ */ new Map();
110182
- const hdrImageFitInfo = /* @__PURE__ */ new Map();
110183
- const hdrVideoStartTimes = /* @__PURE__ */ new Map();
110184
- for (const v of composition.videos) {
110185
- if (hdrVideoIds.includes(v.id)) {
110186
- hdrVideoStartTimes.set(v.id, v.start);
110187
- }
110188
- }
110189
- const hdrImageStartTimes = /* @__PURE__ */ new Map();
110190
- for (const img of composition.images) {
110191
- if (nativeHdrImageIds.has(img.id)) {
110192
- hdrImageStartTimes.set(img.id, img.start);
110193
- }
110194
- }
110195
- const uniqueStartTimes = [
110196
- .../* @__PURE__ */ new Set([...hdrVideoStartTimes.values(), ...hdrImageStartTimes.values()])
110197
- ].sort((a, b) => a - b);
110198
- for (const seekTime of uniqueStartTimes) {
110199
- await domSession.page.evaluate((t) => {
110200
- if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110201
- }, seekTime);
110202
- if (domSession.onBeforeCapture) {
110203
- await domSession.onBeforeCapture(domSession.page, seekTime);
110204
- }
110205
- const stacking = await queryElementStacking(domSession.page, nativeHdrIds);
110206
- for (const el of stacking) {
110207
- if (el.isHdr && el.layoutWidth > 0 && el.layoutHeight > 0 && !hdrExtractionDims.has(el.id)) {
110208
- hdrExtractionDims.set(el.id, { width: el.layoutWidth, height: el.layoutHeight });
110209
- }
110210
- if (el.isHdr && nativeHdrImageIds.has(el.id) && !hdrImageFitInfo.has(el.id)) {
110211
- hdrImageFitInfo.set(el.id, {
110212
- fit: el.objectFit,
110213
- position: el.objectPosition
110214
- });
110215
- }
110216
- }
110217
- }
110183
+ let hdrEncoder = null;
110184
+ let hdrEncoderClosed = false;
110185
+ let domSessionClosed = false;
110218
110186
  const hdrFrameDirs = /* @__PURE__ */ new Map();
110219
- for (const [videoId, srcPath] of hdrVideoSrcPaths) {
110220
- const video = composition.videos.find((v) => v.id === videoId);
110221
- if (!video) continue;
110222
- const frameDir = join15(framesDir, `hdr_${videoId}`);
110223
- mkdirSync10(frameDir, { recursive: true });
110224
- const duration = video.end - video.start;
110225
- const dims = hdrExtractionDims.get(videoId) ?? { width, height };
110226
- const ffmpegArgs = [
110227
- "-ss",
110228
- String(video.mediaStart),
110229
- "-i",
110230
- srcPath,
110231
- "-t",
110232
- String(duration),
110233
- "-r",
110234
- String(job.config.fps),
110235
- "-vf",
110236
- `scale=${dims.width}:${dims.height}:force_original_aspect_ratio=increase,crop=${dims.width}:${dims.height}`,
110237
- "-pix_fmt",
110238
- "rgb48le",
110239
- "-c:v",
110240
- "png",
110241
- "-y",
110242
- join15(frameDir, "frame_%04d.png")
110243
- ];
110244
- const result = await runFfmpeg(ffmpegArgs, { signal: abortSignal });
110245
- if (!result.success) {
110246
- hdrDiagnostics.videoExtractionFailures += 1;
110247
- log.error("HDR frame pre-extraction failed; aborting render", {
110248
- videoId,
110249
- srcPath,
110250
- stderr: result.stderr.slice(-400)
110187
+ try {
110188
+ await initializeSession(domSession);
110189
+ assertNotAborted();
110190
+ lastBrowserConsole = domSession.browserConsoleBuffer;
110191
+ await initTransparentBackground(domSession.page);
110192
+ const transitionMeta = await domSession.page.evaluate(() => {
110193
+ return window.__hf?.transitions ?? [];
110194
+ });
110195
+ const sceneElements = await domSession.page.evaluate(() => {
110196
+ const scenes = document.querySelectorAll(".scene");
110197
+ const map2 = {};
110198
+ for (const scene of scenes) {
110199
+ const els = scene.querySelectorAll("[data-start]");
110200
+ map2[scene.id] = Array.from(els).map((e) => e.id);
110201
+ }
110202
+ return map2;
110203
+ });
110204
+ const transitionRanges = transitionMeta.map((t) => ({
110205
+ ...t,
110206
+ startFrame: Math.floor(t.time * job.config.fps),
110207
+ endFrame: Math.ceil((t.time + t.duration) * job.config.fps)
110208
+ }));
110209
+ if (transitionRanges.length > 0) {
110210
+ log.info("[Render] Detected shader transitions for HDR compositing", {
110211
+ count: transitionRanges.length,
110212
+ transitions: transitionRanges.map((t) => ({
110213
+ shader: t.shader,
110214
+ from: t.fromScene,
110215
+ to: t.toScene,
110216
+ frames: `${t.startFrame}-${t.endFrame}`
110217
+ }))
110251
110218
  });
110252
- throw new Error(
110253
- `HDR frame extraction failed for video "${videoId}". Aborting render to avoid shipping black HDR layers.`
110254
- );
110255
110219
  }
110256
- hdrFrameDirs.set(videoId, frameDir);
110257
- }
110258
- const hdrImageBuffers = /* @__PURE__ */ new Map();
110259
- for (const [imageId, srcPath] of hdrImageSrcPaths) {
110260
- try {
110261
- const decoded = decodePngToRgb48le(readFileSync10(srcPath));
110262
- const layout2 = hdrExtractionDims.get(imageId);
110263
- const fitInfo = hdrImageFitInfo.get(imageId);
110264
- if (layout2 && (layout2.width !== decoded.width || layout2.height !== decoded.height)) {
110265
- const fit = normalizeObjectFit(fitInfo?.fit);
110266
- const resampled = resampleRgb48leObjectFit(
110267
- decoded.data,
110268
- decoded.width,
110269
- decoded.height,
110270
- layout2.width,
110271
- layout2.height,
110272
- fit,
110273
- fitInfo?.position
110274
- );
110275
- hdrImageBuffers.set(imageId, {
110276
- data: resampled,
110277
- width: layout2.width,
110278
- height: layout2.height
110279
- });
110280
- } else {
110281
- hdrImageBuffers.set(imageId, {
110282
- data: Buffer.from(decoded.data),
110283
- width: decoded.width,
110284
- height: decoded.height
110285
- });
110220
+ hdrEncoder = await spawnStreamingEncoder(
110221
+ videoOnlyPath,
110222
+ {
110223
+ fps: job.config.fps,
110224
+ width,
110225
+ height,
110226
+ codec: preset.codec,
110227
+ preset: preset.preset,
110228
+ quality: effectiveQuality,
110229
+ bitrate: effectiveBitrate,
110230
+ pixelFormat: preset.pixelFormat,
110231
+ hdr: preset.hdr,
110232
+ rawInputFormat: "rgb48le"
110233
+ },
110234
+ abortSignal,
110235
+ { ffmpegStreamingTimeout: 36e5 }
110236
+ );
110237
+ assertNotAborted();
110238
+ const hdrExtractionDims = /* @__PURE__ */ new Map();
110239
+ const hdrImageFitInfo = /* @__PURE__ */ new Map();
110240
+ const hdrVideoStartTimes = /* @__PURE__ */ new Map();
110241
+ for (const v of composition.videos) {
110242
+ if (hdrVideoIds.includes(v.id)) {
110243
+ hdrVideoStartTimes.set(v.id, v.start);
110286
110244
  }
110287
- } catch (err) {
110288
- hdrDiagnostics.imageDecodeFailures += 1;
110289
- log.error("HDR image decode failed; aborting render", {
110290
- imageId,
110291
- srcPath,
110292
- error: err instanceof Error ? err.message : String(err)
110293
- });
110294
- throw new Error(
110295
- `HDR image decode failed for image "${imageId}". Aborting render to avoid shipping missing HDR image layers.`
110296
- );
110297
110245
  }
110298
- }
110299
- assertNotAborted();
110300
- try {
110301
- let countNonZeroAlpha2 = function(rgba) {
110302
- let n = 0;
110303
- for (let p = 3; p < rgba.length; p += 4) {
110304
- if (rgba[p] !== 0) n++;
110246
+ const hdrImageStartTimes = /* @__PURE__ */ new Map();
110247
+ for (const img of composition.images) {
110248
+ if (nativeHdrImageIds.has(img.id)) {
110249
+ hdrImageStartTimes.set(img.id, img.start);
110305
110250
  }
110306
- return n;
110307
- }, countNonZeroRgb482 = function(buf) {
110308
- let n = 0;
110309
- for (let p = 0; p < buf.length; p += 6) {
110310
- if (buf[p] !== 0 || buf[p + 1] !== 0 || buf[p + 2] !== 0) n++;
110251
+ }
110252
+ const uniqueStartTimes = [
110253
+ .../* @__PURE__ */ new Set([...hdrVideoStartTimes.values(), ...hdrImageStartTimes.values()])
110254
+ ].sort((a, b) => a - b);
110255
+ for (const seekTime of uniqueStartTimes) {
110256
+ await domSession.page.evaluate((t) => {
110257
+ if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110258
+ }, seekTime);
110259
+ if (domSession.onBeforeCapture) {
110260
+ await domSession.onBeforeCapture(domSession.page, seekTime);
110261
+ }
110262
+ const stacking = await queryElementStacking(domSession.page, nativeHdrIds);
110263
+ for (const el of stacking) {
110264
+ if (el.isHdr && el.layoutWidth > 0 && el.layoutHeight > 0 && !hdrExtractionDims.has(el.id)) {
110265
+ hdrExtractionDims.set(el.id, { width: el.layoutWidth, height: el.layoutHeight });
110266
+ }
110267
+ if (el.isHdr && nativeHdrImageIds.has(el.id) && !hdrImageFitInfo.has(el.id)) {
110268
+ hdrImageFitInfo.set(el.id, {
110269
+ fit: el.objectFit,
110270
+ position: el.objectPosition
110271
+ });
110272
+ }
110311
110273
  }
110312
- return n;
110313
- };
110314
- var countNonZeroAlpha = countNonZeroAlpha2, countNonZeroRgb48 = countNonZeroRgb482;
110315
- const beforeCaptureHook = domSession.onBeforeCapture;
110316
- const cleanedUpVideos = /* @__PURE__ */ new Set();
110317
- const hdrVideoEndTimes = /* @__PURE__ */ new Map();
110318
- for (const v of composition.videos) {
110319
- if (hdrFrameDirs.has(v.id)) {
110320
- hdrVideoEndTimes.set(v.id, v.end);
110321
- }
110322
- }
110323
- const debugDumpEnabled = process.env.KEEP_TEMP === "1";
110324
- const debugDumpDir = debugDumpEnabled ? join15(framesDir, "debug-composite") : null;
110325
- if (debugDumpDir && !existsSync15(debugDumpDir)) {
110326
- mkdirSync10(debugDumpDir, { recursive: true });
110327
- }
110328
- async function compositeToBuffer(canvas, time, fullStacking, elementFilter, debugFrameIndex = -1) {
110329
- const filteredStacking = elementFilter ? fullStacking.filter((e) => elementFilter.has(e.id)) : fullStacking;
110330
- const layers = groupIntoLayers(filteredStacking);
110331
- const shouldLog = debugDumpEnabled && debugFrameIndex >= 0;
110332
- if (shouldLog) {
110333
- log.info("[diag] compositeToBuffer plan", {
110334
- frame: debugFrameIndex,
110335
- time: time.toFixed(3),
110336
- filterSize: elementFilter?.size,
110337
- fullStackingCount: fullStacking.length,
110338
- filteredCount: filteredStacking.length,
110339
- layerCount: layers.length,
110340
- layers: layers.map(
110341
- (l) => l.type === "hdr" ? {
110342
- type: "hdr",
110343
- id: l.element.id,
110344
- z: l.element.zIndex,
110345
- visible: l.element.visible,
110346
- opacity: l.element.opacity,
110347
- bounds: `${Math.round(l.element.x)},${Math.round(l.element.y)} ${Math.round(l.element.width)}x${Math.round(l.element.height)}`
110348
- } : { type: "dom", ids: l.elementIds }
110349
- )
110274
+ }
110275
+ for (const [videoId, srcPath] of hdrVideoSrcPaths) {
110276
+ const video = composition.videos.find((v) => v.id === videoId);
110277
+ if (!video) continue;
110278
+ const frameDir = join15(framesDir, `hdr_${videoId}`);
110279
+ mkdirSync10(frameDir, { recursive: true });
110280
+ const duration = video.end - video.start;
110281
+ const dims = hdrExtractionDims.get(videoId) ?? { width, height };
110282
+ const ffmpegArgs = [
110283
+ "-ss",
110284
+ String(video.mediaStart),
110285
+ "-i",
110286
+ srcPath,
110287
+ "-t",
110288
+ String(duration),
110289
+ "-r",
110290
+ String(job.config.fps),
110291
+ "-vf",
110292
+ `scale=${dims.width}:${dims.height}:force_original_aspect_ratio=increase,crop=${dims.width}:${dims.height}`,
110293
+ "-pix_fmt",
110294
+ "rgb48le",
110295
+ "-c:v",
110296
+ "png",
110297
+ "-y",
110298
+ join15(frameDir, "frame_%04d.png")
110299
+ ];
110300
+ const result = await runFfmpeg(ffmpegArgs, { signal: abortSignal });
110301
+ if (!result.success) {
110302
+ hdrDiagnostics.videoExtractionFailures += 1;
110303
+ log.error("HDR frame pre-extraction failed; aborting render", {
110304
+ videoId,
110305
+ srcPath,
110306
+ stderr: result.stderr.slice(-400)
110350
110307
  });
110308
+ throw new Error(
110309
+ `HDR frame extraction failed for video "${videoId}". Aborting render to avoid shipping black HDR layers.`
110310
+ );
110351
110311
  }
110352
- for (const [layerIdx, layer] of layers.entries()) {
110353
- if (layer.type === "hdr") {
110354
- const before2 = shouldLog ? countNonZeroRgb482(canvas) : 0;
110355
- const isHdrImage = nativeHdrImageIds.has(layer.element.id);
110356
- if (isHdrImage) {
110357
- blitHdrImageLayer(
110358
- canvas,
110359
- layer.element,
110360
- hdrImageBuffers,
110361
- width,
110362
- height,
110363
- log,
110364
- imageTransfers.get(layer.element.id),
110365
- effectiveHdr?.transfer
110366
- );
110367
- } else {
110368
- blitHdrVideoLayer(
110369
- canvas,
110370
- layer.element,
110371
- time,
110372
- job.config.fps,
110373
- hdrFrameDirs,
110374
- hdrVideoStartTimes,
110375
- width,
110376
- height,
110377
- log,
110378
- videoTransfers.get(layer.element.id),
110379
- effectiveHdr?.transfer
110380
- );
110381
- }
110382
- if (shouldLog) {
110383
- const after2 = countNonZeroRgb482(canvas);
110384
- if (isHdrImage) {
110385
- const buf = hdrImageBuffers.get(layer.element.id);
110386
- log.info("[diag] hdr layer blit", {
110387
- frame: debugFrameIndex,
110388
- layerIdx,
110389
- id: layer.element.id,
110390
- kind: "image",
110391
- pixelsAdded: after2 - before2,
110392
- totalNonZero: after2,
110393
- bufferDecoded: !!buf,
110394
- bufferDims: buf ? `${buf.width}x${buf.height}` : null
110395
- });
110396
- } else {
110397
- const frameDir = hdrFrameDirs.get(layer.element.id);
110398
- const startTime = hdrVideoStartTimes.get(layer.element.id) ?? 0;
110399
- const localTime = time - startTime;
110400
- const frameNum = Math.floor(localTime * job.config.fps) + 1;
110401
- const expectedFrame = frameDir ? join15(frameDir, `frame_${String(frameNum).padStart(4, "0")}.png`) : null;
110402
- log.info("[diag] hdr layer blit", {
110403
- frame: debugFrameIndex,
110404
- layerIdx,
110405
- id: layer.element.id,
110406
- kind: "video",
110407
- pixelsAdded: after2 - before2,
110408
- totalNonZero: after2,
110409
- startTime,
110410
- localTime: localTime.toFixed(3),
110411
- hdrFrameNum: frameNum,
110412
- expectedFrame,
110413
- expectedFrameExists: expectedFrame ? existsSync15(expectedFrame) : false
110414
- });
110415
- }
110416
- }
110312
+ hdrFrameDirs.set(videoId, frameDir);
110313
+ }
110314
+ const hdrImageBuffers = /* @__PURE__ */ new Map();
110315
+ for (const [imageId, srcPath] of hdrImageSrcPaths) {
110316
+ try {
110317
+ const decoded = decodePngToRgb48le(readFileSync10(srcPath));
110318
+ const layout2 = hdrExtractionDims.get(imageId);
110319
+ const fitInfo = hdrImageFitInfo.get(imageId);
110320
+ if (layout2 && (layout2.width !== decoded.width || layout2.height !== decoded.height)) {
110321
+ const fit = normalizeObjectFit(fitInfo?.fit);
110322
+ const resampled = resampleRgb48leObjectFit(
110323
+ decoded.data,
110324
+ decoded.width,
110325
+ decoded.height,
110326
+ layout2.width,
110327
+ layout2.height,
110328
+ fit,
110329
+ fitInfo?.position
110330
+ );
110331
+ hdrImageBuffers.set(imageId, {
110332
+ data: resampled,
110333
+ width: layout2.width,
110334
+ height: layout2.height
110335
+ });
110417
110336
  } else {
110418
- const allElementIds = fullStacking.map((e) => e.id);
110419
- const layerIds = new Set(layer.elementIds);
110420
- const hideIds = allElementIds.filter((id) => !layerIds.has(id));
110421
- await domSession.page.evaluate((t) => {
110422
- if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110423
- }, time);
110424
- if (beforeCaptureHook) {
110425
- await beforeCaptureHook(domSession.page, time);
110426
- }
110427
- await applyDomLayerMask(domSession.page, layer.elementIds, hideIds);
110428
- const domPng = await captureAlphaPng(domSession.page, width, height);
110429
- await removeDomLayerMask(domSession.page, hideIds);
110430
- try {
110431
- const { data: domRgba } = decodePng(domPng);
110432
- if (!effectiveHdr) {
110433
- throw new Error(
110434
- "Invariant violation: effectiveHdr is undefined inside HDR layer branch"
110435
- );
110436
- }
110437
- const before2 = shouldLog ? countNonZeroRgb482(canvas) : 0;
110438
- const alphaPixels = shouldLog ? countNonZeroAlpha2(domRgba) : 0;
110439
- blitRgba8OverRgb48le(domRgba, canvas, width, height, effectiveHdr.transfer);
110440
- if (shouldLog && debugDumpDir) {
110441
- const after2 = countNonZeroRgb482(canvas);
110442
- const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
110443
- const dumpPath = join15(debugDumpDir, dumpName);
110444
- writeFileSync4(dumpPath, domPng);
110445
- log.info("[diag] dom layer blit", {
110446
- frame: debugFrameIndex,
110447
- layerIdx,
110448
- layerIds: layer.elementIds,
110449
- hideCount: hideIds.length,
110450
- pngBytes: domPng.length,
110451
- alphaPixels,
110452
- pixelsAdded: after2 - before2,
110453
- totalNonZero: after2,
110454
- dumpPath
110455
- });
110456
- }
110457
- } catch (err) {
110458
- log.warn("DOM layer decode/blit failed; skipping overlay", {
110459
- layerIds: layer.elementIds,
110460
- error: err instanceof Error ? err.message : String(err)
110461
- });
110462
- }
110337
+ hdrImageBuffers.set(imageId, {
110338
+ data: Buffer.from(decoded.data),
110339
+ width: decoded.width,
110340
+ height: decoded.height
110341
+ });
110463
110342
  }
110464
- }
110465
- if (shouldLog && debugDumpDir) {
110466
- const finalNonZero = countNonZeroRgb482(canvas);
110467
- log.info("[diag] compositeToBuffer end", {
110468
- frame: debugFrameIndex,
110469
- finalNonZeroPixels: finalNonZero,
110470
- totalPixels: width * height,
110471
- coverage: (finalNonZero / (width * height) * 100).toFixed(1) + "%"
110343
+ } catch (err) {
110344
+ hdrDiagnostics.imageDecodeFailures += 1;
110345
+ log.error("HDR image decode failed; aborting render", {
110346
+ imageId,
110347
+ srcPath,
110348
+ error: err instanceof Error ? err.message : String(err)
110472
110349
  });
110350
+ throw new Error(
110351
+ `HDR image decode failed for image "${imageId}". Aborting render to avoid shipping missing HDR image layers.`
110352
+ );
110473
110353
  }
110474
110354
  }
110475
- const bufSize = width * height * 6;
110476
- const hasTransitions = transitionRanges.length > 0;
110477
- const transBufferA = hasTransitions ? Buffer.alloc(bufSize) : null;
110478
- const transBufferB = hasTransitions ? Buffer.alloc(bufSize) : null;
110479
- const transOutput = hasTransitions ? Buffer.alloc(bufSize) : null;
110480
- const normalCanvas = Buffer.alloc(bufSize);
110481
- for (let i = 0; i < totalFrames; i++) {
110482
- assertNotAborted();
110483
- const time = i / job.config.fps;
110484
- await domSession.page.evaluate((t) => {
110485
- if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110486
- }, time);
110487
- if (beforeCaptureHook) {
110488
- await beforeCaptureHook(domSession.page, time);
110489
- }
110490
- const stackingInfo = await queryElementStacking(domSession.page, nativeHdrIds);
110491
- const activeTransition = transitionRanges.find(
110492
- (t) => i >= t.startFrame && i <= t.endFrame
110493
- );
110494
- if (i % 30 === 0) {
110495
- const hdrEl = stackingInfo.find((e) => e.isHdr);
110496
- log.debug("[Render] HDR layer composite frame", {
110497
- frame: i,
110498
- time: time.toFixed(2),
110499
- hdrElement: hdrEl ? { z: hdrEl.zIndex, visible: hdrEl.visible, width: hdrEl.width } : null,
110500
- stackingCount: stackingInfo.length,
110501
- activeTransition: activeTransition?.shader
110502
- });
110503
- }
110504
- if (activeTransition && transBufferA && transBufferB && transOutput) {
110505
- const progress = activeTransition.endFrame === activeTransition.startFrame ? 1 : (i - activeTransition.startFrame) / (activeTransition.endFrame - activeTransition.startFrame);
110506
- const sceneAIds = new Set(sceneElements[activeTransition.fromScene] ?? []);
110507
- const sceneBIds = new Set(sceneElements[activeTransition.toScene] ?? []);
110508
- transBufferA.fill(0);
110509
- transBufferB.fill(0);
110510
- for (const [sceneBuf, sceneIds] of [
110511
- [transBufferA, sceneAIds],
110512
- [transBufferB, sceneBIds]
110513
- ]) {
110514
- await domSession.page.evaluate((t) => {
110515
- if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110516
- }, time);
110517
- if (beforeCaptureHook) {
110518
- await beforeCaptureHook(domSession.page, time);
110519
- }
110520
- for (const el of stackingInfo) {
110521
- if (!el.isHdr || !sceneIds.has(el.id)) continue;
110522
- if (nativeHdrImageIds.has(el.id)) {
110355
+ assertNotAborted();
110356
+ try {
110357
+ let countNonZeroAlpha2 = function(rgba) {
110358
+ let n = 0;
110359
+ for (let p = 3; p < rgba.length; p += 4) {
110360
+ if (rgba[p] !== 0) n++;
110361
+ }
110362
+ return n;
110363
+ }, countNonZeroRgb482 = function(buf) {
110364
+ let n = 0;
110365
+ for (let p = 0; p < buf.length; p += 6) {
110366
+ if (buf[p] !== 0 || buf[p + 1] !== 0 || buf[p + 2] !== 0 || buf[p + 3] !== 0 || buf[p + 4] !== 0 || buf[p + 5] !== 0)
110367
+ n++;
110368
+ }
110369
+ return n;
110370
+ };
110371
+ var countNonZeroAlpha = countNonZeroAlpha2, countNonZeroRgb48 = countNonZeroRgb482;
110372
+ const beforeCaptureHook = domSession.onBeforeCapture;
110373
+ const cleanedUpVideos = /* @__PURE__ */ new Set();
110374
+ const hdrVideoEndTimes = /* @__PURE__ */ new Map();
110375
+ for (const v of composition.videos) {
110376
+ if (hdrFrameDirs.has(v.id)) {
110377
+ hdrVideoEndTimes.set(v.id, v.end);
110378
+ }
110379
+ }
110380
+ const debugDumpEnabled = process.env.KEEP_TEMP === "1";
110381
+ const debugDumpDir = debugDumpEnabled ? join15(framesDir, "debug-composite") : null;
110382
+ if (debugDumpDir && !existsSync15(debugDumpDir)) {
110383
+ mkdirSync10(debugDumpDir, { recursive: true });
110384
+ }
110385
+ async function compositeToBuffer(canvas, time, fullStacking, elementFilter, debugFrameIndex = -1) {
110386
+ const filteredStacking = elementFilter ? fullStacking.filter((e) => elementFilter.has(e.id)) : fullStacking;
110387
+ const layers = groupIntoLayers(filteredStacking);
110388
+ const shouldLog = debugDumpEnabled && debugFrameIndex >= 0;
110389
+ if (shouldLog) {
110390
+ log.info("[diag] compositeToBuffer plan", {
110391
+ frame: debugFrameIndex,
110392
+ time: time.toFixed(3),
110393
+ filterSize: elementFilter?.size,
110394
+ fullStackingCount: fullStacking.length,
110395
+ filteredCount: filteredStacking.length,
110396
+ layerCount: layers.length,
110397
+ layers: layers.map(
110398
+ (l) => l.type === "hdr" ? {
110399
+ type: "hdr",
110400
+ id: l.element.id,
110401
+ z: l.element.zIndex,
110402
+ visible: l.element.visible,
110403
+ opacity: l.element.opacity,
110404
+ bounds: `${Math.round(l.element.x)},${Math.round(l.element.y)} ${Math.round(l.element.width)}x${Math.round(l.element.height)}`
110405
+ } : { type: "dom", ids: l.elementIds }
110406
+ )
110407
+ });
110408
+ }
110409
+ for (const [layerIdx, layer] of layers.entries()) {
110410
+ if (layer.type === "hdr") {
110411
+ const before2 = shouldLog ? countNonZeroRgb482(canvas) : 0;
110412
+ const isHdrImage = nativeHdrImageIds.has(layer.element.id);
110413
+ if (isHdrImage) {
110523
110414
  blitHdrImageLayer(
110524
- sceneBuf,
110525
- el,
110415
+ canvas,
110416
+ layer.element,
110526
110417
  hdrImageBuffers,
110527
110418
  width,
110528
110419
  height,
110529
110420
  log,
110530
- imageTransfers.get(el.id),
110421
+ imageTransfers.get(layer.element.id),
110531
110422
  effectiveHdr?.transfer
110532
110423
  );
110533
110424
  } else {
110534
110425
  blitHdrVideoLayer(
110535
- sceneBuf,
110536
- el,
110426
+ canvas,
110427
+ layer.element,
110537
110428
  time,
110538
110429
  job.config.fps,
110539
110430
  hdrFrameDirs,
@@ -110541,100 +110432,294 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
110541
110432
  width,
110542
110433
  height,
110543
110434
  log,
110544
- videoTransfers.get(el.id),
110435
+ videoTransfers.get(layer.element.id),
110545
110436
  effectiveHdr?.transfer
110546
110437
  );
110547
110438
  }
110439
+ if (shouldLog) {
110440
+ const after2 = countNonZeroRgb482(canvas);
110441
+ if (isHdrImage) {
110442
+ const buf = hdrImageBuffers.get(layer.element.id);
110443
+ log.info("[diag] hdr layer blit", {
110444
+ frame: debugFrameIndex,
110445
+ layerIdx,
110446
+ id: layer.element.id,
110447
+ kind: "image",
110448
+ pixelsAdded: after2 - before2,
110449
+ totalNonZero: after2,
110450
+ bufferDecoded: !!buf,
110451
+ bufferDims: buf ? `${buf.width}x${buf.height}` : null
110452
+ });
110453
+ } else {
110454
+ const frameDir = hdrFrameDirs.get(layer.element.id);
110455
+ const startTime = hdrVideoStartTimes.get(layer.element.id) ?? 0;
110456
+ const localTime = time - startTime;
110457
+ const frameNum = Math.floor(localTime * job.config.fps) + 1;
110458
+ const expectedFrame = frameDir ? join15(frameDir, `frame_${String(frameNum).padStart(4, "0")}.png`) : null;
110459
+ log.info("[diag] hdr layer blit", {
110460
+ frame: debugFrameIndex,
110461
+ layerIdx,
110462
+ id: layer.element.id,
110463
+ kind: "video",
110464
+ pixelsAdded: after2 - before2,
110465
+ totalNonZero: after2,
110466
+ startTime,
110467
+ localTime: localTime.toFixed(3),
110468
+ hdrFrameNum: frameNum,
110469
+ expectedFrame,
110470
+ expectedFrameExists: expectedFrame ? existsSync15(expectedFrame) : false
110471
+ });
110472
+ }
110473
+ }
110474
+ } else {
110475
+ const allElementIds = fullStacking.map((e) => e.id);
110476
+ const layerIds = new Set(layer.elementIds);
110477
+ const hideIds = allElementIds.filter((id) => !layerIds.has(id));
110478
+ await domSession.page.evaluate((t) => {
110479
+ if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110480
+ }, time);
110481
+ if (beforeCaptureHook) {
110482
+ await beforeCaptureHook(domSession.page, time);
110483
+ }
110484
+ await applyDomLayerMask(domSession.page, layer.elementIds, hideIds);
110485
+ const domPng = await captureAlphaPng(domSession.page, width, height);
110486
+ await removeDomLayerMask(domSession.page, hideIds);
110487
+ try {
110488
+ const { data: domRgba } = decodePng(domPng);
110489
+ if (!effectiveHdr) {
110490
+ throw new Error(
110491
+ "Invariant violation: effectiveHdr is undefined inside HDR layer branch"
110492
+ );
110493
+ }
110494
+ const before2 = shouldLog ? countNonZeroRgb482(canvas) : 0;
110495
+ const alphaPixels = shouldLog ? countNonZeroAlpha2(domRgba) : 0;
110496
+ blitRgba8OverRgb48le(domRgba, canvas, width, height, effectiveHdr.transfer);
110497
+ if (shouldLog && debugDumpDir) {
110498
+ const after2 = countNonZeroRgb482(canvas);
110499
+ const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
110500
+ const dumpPath = join15(debugDumpDir, dumpName);
110501
+ writeFileSync4(dumpPath, domPng);
110502
+ log.info("[diag] dom layer blit", {
110503
+ frame: debugFrameIndex,
110504
+ layerIdx,
110505
+ layerIds: layer.elementIds,
110506
+ hideCount: hideIds.length,
110507
+ pngBytes: domPng.length,
110508
+ alphaPixels,
110509
+ pixelsAdded: after2 - before2,
110510
+ totalNonZero: after2,
110511
+ dumpPath
110512
+ });
110513
+ }
110514
+ } catch (err) {
110515
+ log.warn("DOM layer decode/blit failed; skipping overlay", {
110516
+ layerIds: layer.elementIds,
110517
+ error: err instanceof Error ? err.message : String(err)
110518
+ });
110519
+ }
110548
110520
  }
110549
- const showIds = Array.from(sceneIds);
110550
- const hideIds = stackingInfo.map((e) => e.id).filter((id) => !sceneIds.has(id) || nativeHdrIds.has(id));
110551
- await applyDomLayerMask(domSession.page, showIds, hideIds);
110552
- const domPng = await captureAlphaPng(domSession.page, width, height);
110553
- await removeDomLayerMask(domSession.page, hideIds);
110554
- try {
110555
- const { data: domRgba } = decodePng(domPng);
110556
- if (!effectiveHdr) {
110557
- throw new Error(
110558
- "Invariant violation: effectiveHdr is undefined inside hasHdrVideo branch"
110521
+ }
110522
+ if (shouldLog && debugDumpDir) {
110523
+ const finalNonZero = countNonZeroRgb482(canvas);
110524
+ log.info("[diag] compositeToBuffer end", {
110525
+ frame: debugFrameIndex,
110526
+ finalNonZeroPixels: finalNonZero,
110527
+ totalPixels: width * height,
110528
+ coverage: (finalNonZero / (width * height) * 100).toFixed(1) + "%"
110529
+ });
110530
+ }
110531
+ }
110532
+ const bufSize = width * height * 6;
110533
+ const hasTransitions = transitionRanges.length > 0;
110534
+ const transBufferA = hasTransitions ? Buffer.alloc(bufSize) : null;
110535
+ const transBufferB = hasTransitions ? Buffer.alloc(bufSize) : null;
110536
+ const transOutput = hasTransitions ? Buffer.alloc(bufSize) : null;
110537
+ const normalCanvas = Buffer.alloc(bufSize);
110538
+ for (let i = 0; i < totalFrames; i++) {
110539
+ assertNotAborted();
110540
+ const time = i / job.config.fps;
110541
+ await domSession.page.evaluate((t) => {
110542
+ if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110543
+ }, time);
110544
+ if (beforeCaptureHook) {
110545
+ await beforeCaptureHook(domSession.page, time);
110546
+ }
110547
+ const stackingInfo = await queryElementStacking(domSession.page, nativeHdrIds);
110548
+ const activeTransition = transitionRanges.find(
110549
+ (t) => i >= t.startFrame && i <= t.endFrame
110550
+ );
110551
+ if (i % 30 === 0) {
110552
+ const hdrEl = stackingInfo.find((e) => e.isHdr);
110553
+ log.debug("[Render] HDR layer composite frame", {
110554
+ frame: i,
110555
+ time: time.toFixed(2),
110556
+ hdrElement: hdrEl ? { z: hdrEl.zIndex, visible: hdrEl.visible, width: hdrEl.width } : null,
110557
+ stackingCount: stackingInfo.length,
110558
+ activeTransition: activeTransition?.shader
110559
+ });
110560
+ }
110561
+ if (activeTransition && transBufferA && transBufferB && transOutput) {
110562
+ const progress = activeTransition.endFrame === activeTransition.startFrame ? 1 : (i - activeTransition.startFrame) / (activeTransition.endFrame - activeTransition.startFrame);
110563
+ const sceneAIds = new Set(sceneElements[activeTransition.fromScene] ?? []);
110564
+ const sceneBIds = new Set(sceneElements[activeTransition.toScene] ?? []);
110565
+ transBufferA.fill(0);
110566
+ transBufferB.fill(0);
110567
+ for (const [sceneBuf, sceneIds] of [
110568
+ [transBufferA, sceneAIds],
110569
+ [transBufferB, sceneBIds]
110570
+ ]) {
110571
+ assertNotAborted();
110572
+ await domSession.page.evaluate((t) => {
110573
+ if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110574
+ }, time);
110575
+ if (beforeCaptureHook) {
110576
+ await beforeCaptureHook(domSession.page, time);
110577
+ }
110578
+ for (const el of stackingInfo) {
110579
+ if (!el.isHdr || !sceneIds.has(el.id)) continue;
110580
+ if (nativeHdrImageIds.has(el.id)) {
110581
+ blitHdrImageLayer(
110582
+ sceneBuf,
110583
+ el,
110584
+ hdrImageBuffers,
110585
+ width,
110586
+ height,
110587
+ log,
110588
+ imageTransfers.get(el.id),
110589
+ effectiveHdr?.transfer
110590
+ );
110591
+ } else {
110592
+ blitHdrVideoLayer(
110593
+ sceneBuf,
110594
+ el,
110595
+ time,
110596
+ job.config.fps,
110597
+ hdrFrameDirs,
110598
+ hdrVideoStartTimes,
110599
+ width,
110600
+ height,
110601
+ log,
110602
+ videoTransfers.get(el.id),
110603
+ effectiveHdr?.transfer
110604
+ );
110605
+ }
110606
+ }
110607
+ const showIds = Array.from(sceneIds);
110608
+ const hideIds = stackingInfo.map((e) => e.id).filter((id) => !sceneIds.has(id) || nativeHdrIds.has(id));
110609
+ await applyDomLayerMask(domSession.page, showIds, hideIds);
110610
+ const domPng = await captureAlphaPng(domSession.page, width, height);
110611
+ await removeDomLayerMask(domSession.page, hideIds);
110612
+ try {
110613
+ const { data: domRgba } = decodePng(domPng);
110614
+ if (!effectiveHdr) {
110615
+ throw new Error(
110616
+ "Invariant violation: effectiveHdr is undefined inside hasHdrVideo branch"
110617
+ );
110618
+ }
110619
+ blitRgba8OverRgb48le(
110620
+ domRgba,
110621
+ sceneBuf,
110622
+ width,
110623
+ height,
110624
+ effectiveHdr.transfer
110559
110625
  );
110626
+ } catch (err) {
110627
+ log.warn("DOM layer decode/blit failed; skipping overlay for transition scene", {
110628
+ frameIndex: i,
110629
+ sceneIds: Array.from(sceneIds),
110630
+ error: err instanceof Error ? err.message : String(err)
110631
+ });
110560
110632
  }
110561
- blitRgba8OverRgb48le(
110562
- domRgba,
110563
- sceneBuf,
110564
- width,
110565
- height,
110566
- effectiveHdr.transfer
110633
+ }
110634
+ const transitionFn = TRANSITIONS[activeTransition.shader] ?? crossfade;
110635
+ transitionFn(transBufferA, transBufferB, transOutput, width, height, progress);
110636
+ hdrEncoder.writeFrame(transOutput);
110637
+ } else {
110638
+ normalCanvas.fill(0);
110639
+ await compositeToBuffer(normalCanvas, time, stackingInfo, void 0, i);
110640
+ if (debugDumpEnabled && debugDumpDir && i % 30 === 0) {
110641
+ const previewPath = join15(
110642
+ debugDumpDir,
110643
+ `frame_${String(i).padStart(4, "0")}_final_rgb48le.bin`
110567
110644
  );
110568
- } catch (err) {
110569
- log.warn("DOM layer decode/blit failed; skipping overlay for transition scene", {
110570
- frameIndex: i,
110571
- sceneIds: Array.from(sceneIds),
110572
- error: err instanceof Error ? err.message : String(err)
110573
- });
110645
+ writeFileSync4(previewPath, normalCanvas);
110574
110646
  }
110575
- }
110576
- const transitionFn = TRANSITIONS[activeTransition.shader] ?? crossfade;
110577
- transitionFn(transBufferA, transBufferB, transOutput, width, height, progress);
110578
- hdrEncoder.writeFrame(transOutput);
110579
- } else {
110580
- normalCanvas.fill(0);
110581
- await compositeToBuffer(normalCanvas, time, stackingInfo, void 0, i);
110582
- if (debugDumpEnabled && debugDumpDir && i % 30 === 0) {
110583
- const previewPath = join15(
110584
- debugDumpDir,
110585
- `frame_${String(i).padStart(4, "0")}_final_rgb48le.bin`
110586
- );
110587
- writeFileSync4(previewPath, normalCanvas);
110588
- }
110589
- hdrEncoder.writeFrame(normalCanvas);
110590
- }
110591
- if (process.env.KEEP_TEMP !== "1") {
110592
- for (const [videoId, endTime] of hdrVideoEndTimes) {
110593
- if (time > endTime && !cleanedUpVideos.has(videoId)) {
110594
- const stillNeeded = activeTransition && (sceneElements[activeTransition.fromScene]?.includes(videoId) || sceneElements[activeTransition.toScene]?.includes(videoId));
110595
- if (!stillNeeded) {
110596
- const frameDir = hdrFrameDirs.get(videoId);
110597
- if (frameDir) {
110598
- try {
110599
- rmSync3(frameDir, { recursive: true, force: true });
110600
- } catch (err) {
110601
- log.warn("Failed to clean up HDR frame directory", {
110602
- videoId,
110603
- frameDir,
110604
- error: err instanceof Error ? err.message : String(err)
110605
- });
110647
+ hdrEncoder.writeFrame(normalCanvas);
110648
+ }
110649
+ if (process.env.KEEP_TEMP !== "1") {
110650
+ for (const [videoId, endTime] of hdrVideoEndTimes) {
110651
+ if (time > endTime && !cleanedUpVideos.has(videoId)) {
110652
+ const stillNeeded = activeTransition && (sceneElements[activeTransition.fromScene]?.includes(videoId) || sceneElements[activeTransition.toScene]?.includes(videoId));
110653
+ if (!stillNeeded) {
110654
+ const frameDir = hdrFrameDirs.get(videoId);
110655
+ if (frameDir) {
110656
+ try {
110657
+ rmSync3(frameDir, { recursive: true, force: true });
110658
+ } catch (err) {
110659
+ log.warn("Failed to clean up HDR frame directory", {
110660
+ videoId,
110661
+ frameDir,
110662
+ error: err instanceof Error ? err.message : String(err)
110663
+ });
110664
+ }
110665
+ frameDirMaxIndexCache.delete(frameDir);
110666
+ hdrFrameDirs.delete(videoId);
110606
110667
  }
110668
+ cleanedUpVideos.add(videoId);
110607
110669
  }
110608
- cleanedUpVideos.add(videoId);
110609
110670
  }
110610
110671
  }
110611
110672
  }
110673
+ job.framesRendered = i + 1;
110674
+ if ((i + 1) % 10 === 0 || i + 1 === totalFrames) {
110675
+ const frameProgress = (i + 1) / totalFrames;
110676
+ updateJobStatus(
110677
+ job,
110678
+ "rendering",
110679
+ `HDR composite frame ${i + 1}/${job.totalFrames}`,
110680
+ Math.round(25 + frameProgress * 55),
110681
+ onProgress
110682
+ );
110683
+ }
110612
110684
  }
110613
- job.framesRendered = i + 1;
110614
- if ((i + 1) % 10 === 0 || i + 1 === totalFrames) {
110615
- const frameProgress = (i + 1) / totalFrames;
110616
- updateJobStatus(
110617
- job,
110618
- "rendering",
110619
- `HDR composite frame ${i + 1}/${job.totalFrames}`,
110620
- Math.round(25 + frameProgress * 55),
110621
- onProgress
110622
- );
110623
- }
110685
+ } finally {
110686
+ lastBrowserConsole = domSession.browserConsoleBuffer;
110687
+ await closeCaptureSession(domSession);
110688
+ domSessionClosed = true;
110689
+ }
110690
+ const hdrEncodeResult = await hdrEncoder.close();
110691
+ hdrEncoderClosed = true;
110692
+ assertNotAborted();
110693
+ if (!hdrEncodeResult.success) {
110694
+ throw new Error(`HDR encode failed: ${hdrEncodeResult.error}`);
110624
110695
  }
110696
+ perfStages.captureMs = Date.now() - stage4Start;
110697
+ perfStages.encodeMs = hdrEncodeResult.durationMs;
110625
110698
  } finally {
110626
- lastBrowserConsole = domSession.browserConsoleBuffer;
110627
- await closeCaptureSession(domSession);
110628
- }
110629
- const hdrEncodeResult = await hdrEncoder.close();
110630
- assertNotAborted();
110631
- if (!hdrEncodeResult.success) {
110632
- throw new Error(`HDR encode failed: ${hdrEncodeResult.error}`);
110699
+ if (hdrEncoder && !hdrEncoderClosed) {
110700
+ try {
110701
+ await hdrEncoder.close();
110702
+ } catch (err) {
110703
+ log.warn("hdrEncoder defensive close failed", {
110704
+ err: err instanceof Error ? err.message : String(err)
110705
+ });
110706
+ }
110707
+ }
110708
+ if (!domSessionClosed) {
110709
+ await closeCaptureSession(domSession).catch((err) => {
110710
+ log.warn("closeCaptureSession defensive close failed", {
110711
+ err: err instanceof Error ? err.message : String(err)
110712
+ });
110713
+ });
110714
+ }
110715
+ for (const frameDir of hdrFrameDirs.values()) {
110716
+ frameDirMaxIndexCache.delete(frameDir);
110717
+ }
110718
+ hdrFrameDirs.clear();
110633
110719
  }
110634
- perfStages.captureMs = Date.now() - stage4Start;
110635
- perfStages.encodeMs = hdrEncodeResult.durationMs;
110636
110720
  } else {
110637
110721
  let streamingEncoder = null;
110722
+ let streamingEncoderClosed = false;
110638
110723
  if (enableStreamingEncode) {
110639
110724
  streamingEncoder = await spawnStreamingEncoder(
110640
110725
  videoOnlyPath,
@@ -110644,7 +110729,8 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
110644
110729
  height,
110645
110730
  codec: preset.codec,
110646
110731
  preset: preset.preset,
110647
- quality: preset.quality,
110732
+ quality: effectiveQuality,
110733
+ bitrate: effectiveBitrate,
110648
110734
  pixelFormat: preset.pixelFormat,
110649
110735
  useGpu: job.config.useGpu,
110650
110736
  imageFormat: captureOptions.format || "jpeg",
@@ -110654,201 +110740,215 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
110654
110740
  );
110655
110741
  assertNotAborted();
110656
110742
  }
110657
- if (enableStreamingEncode && streamingEncoder) {
110658
- const reorderBuffer = createFrameReorderBuffer(0, totalFrames);
110659
- const currentEncoder = streamingEncoder;
110660
- if (workerCount > 1) {
110661
- const tasks = distributeFrames(job.totalFrames, workerCount, workDir);
110662
- const onFrameBuffer = async (frameIndex, buffer) => {
110663
- await reorderBuffer.waitForFrame(frameIndex);
110664
- currentEncoder.writeFrame(buffer);
110665
- reorderBuffer.advanceTo(frameIndex + 1);
110666
- };
110667
- await executeParallelCapture(
110668
- fileServer.url,
110669
- workDir,
110670
- tasks,
110671
- { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
110672
- () => createVideoFrameInjector(frameLookup),
110673
- abortSignal,
110674
- (progress) => {
110675
- job.framesRendered = progress.capturedFrames;
110676
- const frameProgress = progress.capturedFrames / progress.totalFrames;
110677
- const progressPct = 25 + frameProgress * 55;
110678
- if (progress.capturedFrames % 30 === 0 || progress.capturedFrames === progress.totalFrames) {
110743
+ try {
110744
+ if (enableStreamingEncode && streamingEncoder) {
110745
+ const reorderBuffer = createFrameReorderBuffer(0, totalFrames);
110746
+ const currentEncoder = streamingEncoder;
110747
+ if (workerCount > 1) {
110748
+ const tasks = distributeFrames(job.totalFrames, workerCount, workDir);
110749
+ const onFrameBuffer = async (frameIndex, buffer) => {
110750
+ await reorderBuffer.waitForFrame(frameIndex);
110751
+ currentEncoder.writeFrame(buffer);
110752
+ reorderBuffer.advanceTo(frameIndex + 1);
110753
+ };
110754
+ await executeParallelCapture(
110755
+ fileServer.url,
110756
+ workDir,
110757
+ tasks,
110758
+ { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
110759
+ () => createVideoFrameInjector(frameLookup),
110760
+ abortSignal,
110761
+ (progress) => {
110762
+ job.framesRendered = progress.capturedFrames;
110763
+ const frameProgress = progress.capturedFrames / progress.totalFrames;
110764
+ const progressPct = 25 + frameProgress * 55;
110765
+ if (progress.capturedFrames % 30 === 0 || progress.capturedFrames === progress.totalFrames) {
110766
+ updateJobStatus(
110767
+ job,
110768
+ "rendering",
110769
+ `Streaming frame ${progress.capturedFrames}/${progress.totalFrames} (${workerCount} workers)`,
110770
+ Math.round(progressPct),
110771
+ onProgress
110772
+ );
110773
+ }
110774
+ },
110775
+ onFrameBuffer,
110776
+ cfg
110777
+ );
110778
+ if (probeSession) {
110779
+ lastBrowserConsole = probeSession.browserConsoleBuffer;
110780
+ await closeCaptureSession(probeSession);
110781
+ probeSession = null;
110782
+ }
110783
+ } else {
110784
+ const videoInjector = createVideoFrameInjector(frameLookup);
110785
+ const session = probeSession ?? await createCaptureSession(
110786
+ fileServer.url,
110787
+ framesDir,
110788
+ { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
110789
+ videoInjector,
110790
+ cfg
110791
+ );
110792
+ if (probeSession) {
110793
+ prepareCaptureSessionForReuse(session, framesDir, videoInjector);
110794
+ probeSession = null;
110795
+ }
110796
+ try {
110797
+ if (!session.isInitialized) {
110798
+ await initializeSession(session);
110799
+ }
110800
+ assertNotAborted();
110801
+ lastBrowserConsole = session.browserConsoleBuffer;
110802
+ for (let i = 0; i < totalFrames; i++) {
110803
+ assertNotAborted();
110804
+ const time = i / job.config.fps;
110805
+ const { buffer } = await captureFrameToBuffer(session, i, time);
110806
+ await reorderBuffer.waitForFrame(i);
110807
+ currentEncoder.writeFrame(buffer);
110808
+ reorderBuffer.advanceTo(i + 1);
110809
+ job.framesRendered = i + 1;
110810
+ const frameProgress = (i + 1) / totalFrames;
110811
+ const progress = 25 + frameProgress * 55;
110679
110812
  updateJobStatus(
110680
110813
  job,
110681
110814
  "rendering",
110682
- `Streaming frame ${progress.capturedFrames}/${progress.totalFrames} (${workerCount} workers)`,
110683
- Math.round(progressPct),
110815
+ `Streaming frame ${i + 1}/${job.totalFrames}`,
110816
+ Math.round(progress),
110684
110817
  onProgress
110685
110818
  );
110686
110819
  }
110687
- },
110688
- onFrameBuffer,
110689
- cfg
110690
- );
110691
- if (probeSession) {
110692
- lastBrowserConsole = probeSession.browserConsoleBuffer;
110693
- await closeCaptureSession(probeSession);
110694
- probeSession = null;
110820
+ } finally {
110821
+ lastBrowserConsole = session.browserConsoleBuffer;
110822
+ await closeCaptureSession(session);
110823
+ }
110695
110824
  }
110696
- } else {
110697
- const videoInjector = createVideoFrameInjector(frameLookup);
110698
- const session = probeSession ?? await createCaptureSession(
110699
- fileServer.url,
110700
- framesDir,
110701
- { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
110702
- videoInjector,
110703
- cfg
110704
- );
110705
- if (probeSession) {
110706
- prepareCaptureSessionForReuse(session, framesDir, videoInjector);
110707
- probeSession = null;
110825
+ const encodeResult = await currentEncoder.close();
110826
+ streamingEncoderClosed = true;
110827
+ assertNotAborted();
110828
+ if (!encodeResult.success) {
110829
+ throw new Error(`Streaming encode failed: ${encodeResult.error}`);
110708
110830
  }
110709
- try {
110710
- if (!session.isInitialized) {
110711
- await initializeSession(session);
110831
+ perfStages.captureMs = Date.now() - stage4Start;
110832
+ perfStages.encodeMs = encodeResult.durationMs;
110833
+ } else {
110834
+ if (workerCount > 1) {
110835
+ const tasks = distributeFrames(job.totalFrames, workerCount, workDir);
110836
+ await executeParallelCapture(
110837
+ fileServer.url,
110838
+ workDir,
110839
+ tasks,
110840
+ { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
110841
+ () => createVideoFrameInjector(frameLookup),
110842
+ abortSignal,
110843
+ (progress) => {
110844
+ job.framesRendered = progress.capturedFrames;
110845
+ const frameProgress = progress.capturedFrames / progress.totalFrames;
110846
+ const progressPct = 25 + frameProgress * 45;
110847
+ if (progress.capturedFrames % 30 === 0 || progress.capturedFrames === progress.totalFrames) {
110848
+ updateJobStatus(
110849
+ job,
110850
+ "rendering",
110851
+ `Capturing frame ${progress.capturedFrames}/${progress.totalFrames} (${workerCount} workers)`,
110852
+ Math.round(progressPct),
110853
+ onProgress
110854
+ );
110855
+ }
110856
+ },
110857
+ void 0,
110858
+ cfg
110859
+ );
110860
+ await mergeWorkerFrames(workDir, tasks, framesDir);
110861
+ if (probeSession) {
110862
+ lastBrowserConsole = probeSession.browserConsoleBuffer;
110863
+ await closeCaptureSession(probeSession);
110864
+ probeSession = null;
110712
110865
  }
110713
- assertNotAborted();
110714
- lastBrowserConsole = session.browserConsoleBuffer;
110715
- for (let i = 0; i < totalFrames; i++) {
110716
- assertNotAborted();
110717
- const time = i / job.config.fps;
110718
- const { buffer } = await captureFrameToBuffer(session, i, time);
110719
- await reorderBuffer.waitForFrame(i);
110720
- currentEncoder.writeFrame(buffer);
110721
- reorderBuffer.advanceTo(i + 1);
110722
- job.framesRendered = i + 1;
110723
- const frameProgress = (i + 1) / totalFrames;
110724
- const progress = 25 + frameProgress * 55;
110725
- updateJobStatus(
110726
- job,
110727
- "rendering",
110728
- `Streaming frame ${i + 1}/${job.totalFrames}`,
110729
- Math.round(progress),
110730
- onProgress
110731
- );
110866
+ } else {
110867
+ const videoInjector = createVideoFrameInjector(frameLookup);
110868
+ const session = probeSession ?? await createCaptureSession(
110869
+ fileServer.url,
110870
+ framesDir,
110871
+ { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
110872
+ videoInjector,
110873
+ cfg
110874
+ );
110875
+ if (probeSession) {
110876
+ prepareCaptureSessionForReuse(session, framesDir, videoInjector);
110877
+ probeSession = null;
110732
110878
  }
110733
- } finally {
110734
- lastBrowserConsole = session.browserConsoleBuffer;
110735
- await closeCaptureSession(session);
110736
- }
110737
- }
110738
- const encodeResult = await currentEncoder.close();
110739
- assertNotAborted();
110740
- if (!encodeResult.success) {
110741
- throw new Error(`Streaming encode failed: ${encodeResult.error}`);
110742
- }
110743
- perfStages.captureMs = Date.now() - stage4Start;
110744
- perfStages.encodeMs = encodeResult.durationMs;
110745
- } else {
110746
- if (workerCount > 1) {
110747
- const tasks = distributeFrames(job.totalFrames, workerCount, workDir);
110748
- await executeParallelCapture(
110749
- fileServer.url,
110750
- workDir,
110751
- tasks,
110752
- { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
110753
- () => createVideoFrameInjector(frameLookup),
110754
- abortSignal,
110755
- (progress) => {
110756
- job.framesRendered = progress.capturedFrames;
110757
- const frameProgress = progress.capturedFrames / progress.totalFrames;
110758
- const progressPct = 25 + frameProgress * 45;
110759
- if (progress.capturedFrames % 30 === 0 || progress.capturedFrames === progress.totalFrames) {
110879
+ try {
110880
+ if (!session.isInitialized) {
110881
+ await initializeSession(session);
110882
+ }
110883
+ assertNotAborted();
110884
+ lastBrowserConsole = session.browserConsoleBuffer;
110885
+ for (let i = 0; i < job.totalFrames; i++) {
110886
+ assertNotAborted();
110887
+ const time = i / job.config.fps;
110888
+ await captureFrame(session, i, time);
110889
+ job.framesRendered = i + 1;
110890
+ const frameProgress = (i + 1) / job.totalFrames;
110891
+ const progress = 25 + frameProgress * 45;
110760
110892
  updateJobStatus(
110761
110893
  job,
110762
110894
  "rendering",
110763
- `Capturing frame ${progress.capturedFrames}/${progress.totalFrames} (${workerCount} workers)`,
110764
- Math.round(progressPct),
110895
+ `Capturing frame ${i + 1}/${job.totalFrames}`,
110896
+ Math.round(progress),
110765
110897
  onProgress
110766
110898
  );
110767
110899
  }
110768
- },
110769
- void 0,
110770
- cfg
110771
- );
110772
- await mergeWorkerFrames(workDir, tasks, framesDir);
110773
- if (probeSession) {
110774
- lastBrowserConsole = probeSession.browserConsoleBuffer;
110775
- await closeCaptureSession(probeSession);
110776
- probeSession = null;
110900
+ } finally {
110901
+ lastBrowserConsole = session.browserConsoleBuffer;
110902
+ await closeCaptureSession(session);
110903
+ }
110777
110904
  }
110778
- } else {
110779
- const videoInjector = createVideoFrameInjector(frameLookup);
110780
- const session = probeSession ?? await createCaptureSession(
110781
- fileServer.url,
110905
+ perfStages.captureMs = Date.now() - stage4Start;
110906
+ const stage5Start = Date.now();
110907
+ updateJobStatus(job, "encoding", "Encoding video", 75, onProgress);
110908
+ const frameExt = needsAlpha ? "png" : "jpg";
110909
+ const framePattern = `frame_%06d.${frameExt}`;
110910
+ const encoderOpts = {
110911
+ fps: job.config.fps,
110912
+ width,
110913
+ height,
110914
+ codec: preset.codec,
110915
+ preset: preset.preset,
110916
+ quality: effectiveQuality,
110917
+ bitrate: effectiveBitrate,
110918
+ pixelFormat: preset.pixelFormat,
110919
+ useGpu: job.config.useGpu,
110920
+ hdr: preset.hdr
110921
+ };
110922
+ const encodeResult = enableChunkedEncode ? await encodeFramesChunkedConcat(
110923
+ framesDir,
110924
+ framePattern,
110925
+ videoOnlyPath,
110926
+ encoderOpts,
110927
+ chunkedEncodeSize,
110928
+ abortSignal
110929
+ ) : await encodeFramesFromDir(
110782
110930
  framesDir,
110783
- { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
110784
- videoInjector,
110785
- cfg
110931
+ framePattern,
110932
+ videoOnlyPath,
110933
+ encoderOpts,
110934
+ abortSignal
110786
110935
  );
110787
- if (probeSession) {
110788
- prepareCaptureSessionForReuse(session, framesDir, videoInjector);
110789
- probeSession = null;
110936
+ assertNotAborted();
110937
+ if (!encodeResult.success) {
110938
+ throw new Error(`Encoding failed: ${encodeResult.error}`);
110790
110939
  }
110940
+ perfStages.encodeMs = Date.now() - stage5Start;
110941
+ }
110942
+ } finally {
110943
+ if (streamingEncoder && !streamingEncoderClosed) {
110791
110944
  try {
110792
- if (!session.isInitialized) {
110793
- await initializeSession(session);
110794
- }
110795
- assertNotAborted();
110796
- lastBrowserConsole = session.browserConsoleBuffer;
110797
- for (let i = 0; i < job.totalFrames; i++) {
110798
- assertNotAborted();
110799
- const time = i / job.config.fps;
110800
- await captureFrame(session, i, time);
110801
- job.framesRendered = i + 1;
110802
- const frameProgress = (i + 1) / job.totalFrames;
110803
- const progress = 25 + frameProgress * 45;
110804
- updateJobStatus(
110805
- job,
110806
- "rendering",
110807
- `Capturing frame ${i + 1}/${job.totalFrames}`,
110808
- Math.round(progress),
110809
- onProgress
110810
- );
110811
- }
110812
- } finally {
110813
- lastBrowserConsole = session.browserConsoleBuffer;
110814
- await closeCaptureSession(session);
110945
+ await streamingEncoder.close();
110946
+ } catch (err) {
110947
+ log.warn("streamingEncoder defensive close failed", {
110948
+ err: err instanceof Error ? err.message : String(err)
110949
+ });
110815
110950
  }
110816
110951
  }
110817
- perfStages.captureMs = Date.now() - stage4Start;
110818
- const stage5Start = Date.now();
110819
- updateJobStatus(job, "encoding", "Encoding video", 75, onProgress);
110820
- const frameExt = needsAlpha ? "png" : "jpg";
110821
- const framePattern = `frame_%06d.${frameExt}`;
110822
- const encoderOpts = {
110823
- fps: job.config.fps,
110824
- width,
110825
- height,
110826
- codec: preset.codec,
110827
- preset: preset.preset,
110828
- quality: preset.quality,
110829
- pixelFormat: preset.pixelFormat,
110830
- useGpu: job.config.useGpu,
110831
- hdr: preset.hdr
110832
- };
110833
- const encodeResult = enableChunkedEncode ? await encodeFramesChunkedConcat(
110834
- framesDir,
110835
- framePattern,
110836
- videoOnlyPath,
110837
- encoderOpts,
110838
- chunkedEncodeSize,
110839
- abortSignal
110840
- ) : await encodeFramesFromDir(
110841
- framesDir,
110842
- framePattern,
110843
- videoOnlyPath,
110844
- encoderOpts,
110845
- abortSignal
110846
- );
110847
- assertNotAborted();
110848
- if (!encodeResult.success) {
110849
- throw new Error(`Encoding failed: ${encodeResult.error}`);
110850
- }
110851
- perfStages.encodeMs = Date.now() - stage5Start;
110852
110952
  }
110853
110953
  }
110854
110954
  if (probeSession !== null) {
@@ -111020,7 +111120,7 @@ import {
111020
111120
  rmSync as rmSync4,
111021
111121
  createReadStream as createReadStream2
111022
111122
  } from "node:fs";
111023
- import { resolve as resolve12, dirname as dirname11, join as join17 } from "node:path";
111123
+ import { resolve as resolve13, dirname as dirname11, join as join17 } from "node:path";
111024
111124
  import { tmpdir as tmpdir2 } from "node:os";
111025
111125
  import { parseArgs } from "node:util";
111026
111126
  import crypto2 from "node:crypto";
@@ -111176,7 +111276,7 @@ var streamSSE = (c, cb, onError) => {
111176
111276
 
111177
111277
  // src/services/hyperframeLint.ts
111178
111278
  import { existsSync as existsSync16, readFileSync as readFileSync11, statSync as statSync6 } from "node:fs";
111179
- import { resolve as resolve11, join as join16 } from "node:path";
111279
+ import { resolve as resolve12, join as join16 } from "node:path";
111180
111280
  function isStringRecord(value) {
111181
111281
  if (!value || typeof value !== "object" || Array.isArray(value)) {
111182
111282
  return false;
@@ -111203,7 +111303,7 @@ function pickEntryFile(files, preferredEntryFile) {
111203
111303
  return null;
111204
111304
  }
111205
111305
  function readProjectEntryFile(projectDir, preferredEntryFile) {
111206
- const absProjectDir = resolve11(projectDir);
111306
+ const absProjectDir = resolve12(projectDir);
111207
111307
  if (!existsSync16(absProjectDir) || !statSync6(absProjectDir).isDirectory()) {
111208
111308
  return { error: `Project directory not found: ${absProjectDir}` };
111209
111309
  }
@@ -111211,7 +111311,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
111211
111311
  (value) => typeof value === "string" && value.trim().length > 0
111212
111312
  );
111213
111313
  for (const entryFile of entryCandidates) {
111214
- const absoluteEntryPath = resolve11(absProjectDir, entryFile);
111314
+ const absoluteEntryPath = resolve12(absProjectDir, entryFile);
111215
111315
  if (!absoluteEntryPath.startsWith(absProjectDir)) {
111216
111316
  return { error: `Entry file must stay inside project directory: ${entryFile}` };
111217
111317
  }
@@ -111276,10 +111376,10 @@ var Semaphore = class {
111276
111376
  this.active++;
111277
111377
  return () => this.release();
111278
111378
  }
111279
- return new Promise((resolve13) => {
111379
+ return new Promise((resolve14) => {
111280
111380
  this.queue.push(() => {
111281
111381
  this.active++;
111282
- resolve13(() => this.release());
111382
+ resolve14(() => this.release());
111283
111383
  });
111284
111384
  });
111285
111385
  }
@@ -111314,12 +111414,12 @@ async function prepareRenderBody(body) {
111314
111414
  const options = parseRenderOptions(body);
111315
111415
  const projectDir = typeof body.projectDir === "string" ? body.projectDir : void 0;
111316
111416
  if (projectDir) {
111317
- const absProjectDir = resolve12(projectDir);
111417
+ const absProjectDir = resolve13(projectDir);
111318
111418
  if (!existsSync17(absProjectDir) || !statSync7(absProjectDir).isDirectory()) {
111319
111419
  return { error: `Project directory not found: ${absProjectDir}` };
111320
111420
  }
111321
111421
  const entry = options.entryFile || "index.html";
111322
- if (!existsSync17(resolve12(absProjectDir, entry))) {
111422
+ if (!existsSync17(resolve13(absProjectDir, entry))) {
111323
111423
  return { error: `Entry file "${entry}" not found in project directory: ${absProjectDir}` };
111324
111424
  }
111325
111425
  return { prepared: { input: { projectDir: absProjectDir, ...options } } };
@@ -111360,7 +111460,7 @@ function resolveOutputPath(projectDir, outputCandidate, rendersDir, log) {
111360
111460
  try {
111361
111461
  return resolveRenderPaths(projectDir, outputCandidate, rendersDir).absoluteOutputPath;
111362
111462
  } catch (error) {
111363
- const fallbackPath = resolve12(rendersDir, `producer-fallback-${Date.now()}.mp4`);
111463
+ const fallbackPath = resolve13(rendersDir, `producer-fallback-${Date.now()}.mp4`);
111364
111464
  log.warn("Failed to resolve output path, using fallback", {
111365
111465
  fallback: fallbackPath,
111366
111466
  error: error instanceof Error ? error.message : String(error)
@@ -111739,7 +111839,7 @@ function startServer(options = {}) {
111739
111839
  process.on("SIGINT", () => shutdown("SIGINT"));
111740
111840
  return server;
111741
111841
  }
111742
- var entryScript = process.argv[1] ? resolve12(process.argv[1]) : "";
111842
+ var entryScript = process.argv[1] ? resolve13(process.argv[1]) : "";
111743
111843
  var isPublicServerEntry = entryScript.endsWith("/public-server.js") || entryScript.endsWith("/src/server.ts");
111744
111844
  if (isPublicServerEntry) {
111745
111845
  const { values } = parseArgs({