@streaming-cdn/rtc-web 1.3.20 → 1.3.22

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.
@@ -1,11 +1,11 @@
1
- const qe = 0.02, Oe = 1.4;
2
- function oe(a, e, t = 0.02, i = 1.4) {
1
+ const Ne = 0.02, je = 1.4;
2
+ function le(a, e, t = 0.02, i = 1.4) {
3
3
  const n = a.filter((r) => r.level >= t);
4
4
  if (n.length === 0) return null;
5
5
  const s = n.reduce((r, c) => c.level > r.level ? c : r), o = n.find((r) => r.participantId === e);
6
6
  return o ? s.participantId === e ? e : s.level >= o.level * i ? s.participantId : e : s.participantId;
7
7
  }
8
- function ce(a) {
8
+ function de(a) {
9
9
  const e = [];
10
10
  for (const t of a) {
11
11
  if (String(t.type ?? "") !== "inbound-rtp" || String(t.kind ?? t.mediaType ?? "") !== "audio") continue;
@@ -14,12 +14,12 @@ function ce(a) {
14
14
  }
15
15
  return e;
16
16
  }
17
- const N = {
17
+ const j = {
18
18
  audio: { active: !1, maxBitrate: 0, maxFramerate: 0, scaleResolutionDownBy: 4 },
19
19
  low: { active: !0, maxBitrate: 35e4, maxFramerate: 15, scaleResolutionDownBy: 4 },
20
20
  medium: { active: !0, maxBitrate: 11e5, maxFramerate: 24, scaleResolutionDownBy: 2 },
21
21
  high: { active: !0, maxBitrate: 28e5, maxFramerate: 30, scaleResolutionDownBy: 1 }
22
- }, he = {
22
+ }, me = {
23
23
  warmupSamples: 3,
24
24
  poorSamplesToStepDown: 2,
25
25
  goodSamplesToStepUp: 6,
@@ -29,29 +29,30 @@ const N = {
29
29
  poorRttMs: 350,
30
30
  goodLossPct: 1,
31
31
  goodRttMs: 250,
32
- sustainRatio: 0.8
32
+ sustainRatio: 0.8,
33
+ bandwidthHeadroomRatio: 1.25
33
34
  };
34
- function ue(a) {
35
+ function pe(a) {
35
36
  const e = String(a ?? "").trim().toLowerCase();
36
37
  return !e || e === "none" ? "" : e === "cpu" || e === "bandwidth" ? e : "other";
37
38
  }
38
- function me(a, e, t, i, n = {}) {
39
- const s = { ...he, ...n.thresholds }, o = ["low", "medium", "high"], r = n.ceiling && n.ceiling !== "audio" ? n.ceiling : "high", c = o.indexOf(r), l = o.indexOf(a), d = (n.samplesSeen ?? s.warmupSamples) + 1, u = d <= s.warmupSamples, S = ue(e.qualityLimitationReason), f = e.packetLossPct ?? 0, v = e.rttMs ?? 0, I = e.availableOutgoingBitrateBps, y = N[a].maxBitrate, k = f >= s.criticalLossPct || v >= s.criticalRttMs || S === "cpu", p = k || f >= s.poorLossPct || v >= s.poorRttMs || S === "bandwidth", C = I == null || I >= y * s.sustainRatio, P = f < s.goodLossPct && v < s.goodRttMs && !S && C, L = p ? t + 1 : 0, E = P ? i + 1 : 0, A = { quality: a, poorSamples: L, goodSamples: E, samplesSeen: d, changed: !1 };
40
- return l > c ? { quality: o[c], poorSamples: 0, goodSamples: 0, samplesSeen: d, changed: !0 } : u ? A : k && l > 0 ? { quality: o[l - 1], poorSamples: 0, goodSamples: 0, samplesSeen: d, changed: !0 } : L >= s.poorSamplesToStepDown && l > 0 ? { quality: o[l - 1], poorSamples: 0, goodSamples: 0, samplesSeen: d, changed: !0 } : E >= s.goodSamplesToStepUp && l < c ? { quality: o[l + 1], poorSamples: 0, goodSamples: 0, samplesSeen: d, changed: !0 } : A;
39
+ function fe(a, e, t, i, n = {}) {
40
+ const s = { ...me, ...n.thresholds }, o = ["low", "medium", "high"], r = n.ceiling && n.ceiling !== "audio" ? n.ceiling : "high", c = o.indexOf(r), l = o.indexOf(a), d = (n.samplesSeen ?? s.warmupSamples) + 1, u = d <= s.warmupSamples, k = pe(e.qualityLimitationReason), f = e.packetLossPct ?? 0, v = e.rttMs ?? 0, C = e.availableOutgoingBitrateBps, y = j[a].maxBitrate, w = f >= s.criticalLossPct || v >= s.criticalRttMs || k === "cpu", p = k === "bandwidth" && (C == null || C < y * s.bandwidthHeadroomRatio), R = w || f >= s.poorLossPct || v >= s.poorRttMs || p, P = C == null || C >= y * s.sustainRatio, L = f < s.goodLossPct && v < s.goodRttMs && !k && P, I = R ? t + 1 : 0, A = L ? i + 1 : 0, S = { quality: a, poorSamples: I, goodSamples: A, samplesSeen: d, changed: !1 };
41
+ return l > c ? { quality: o[c], poorSamples: 0, goodSamples: 0, samplesSeen: d, changed: !0 } : u ? S : w && l > 0 ? { quality: o[l - 1], poorSamples: 0, goodSamples: 0, samplesSeen: d, changed: !0 } : I >= s.poorSamplesToStepDown && l > 0 ? { quality: o[l - 1], poorSamples: 0, goodSamples: 0, samplesSeen: d, changed: !0 } : A >= s.goodSamplesToStepUp && l < c ? { quality: o[l + 1], poorSamples: 0, goodSamples: 0, samplesSeen: d, changed: !0 } : S;
41
42
  }
42
- function pe(a, e) {
43
+ function ge(a, e) {
43
44
  const t = a instanceof Map ? a : new Map(a);
44
45
  let i = 0, n = 0, s = null, o = null, r = null;
45
46
  for (const d of t.values()) {
46
47
  const u = String(d.type ?? "");
47
48
  if (u === "outbound-rtp" && String(d.kind ?? "") === "video" && (i += Number(d.packetsSent ?? 0), s = d.qualityLimitationReason ?? s), u === "remote-inbound-rtp" && String(d.kind ?? "") === "video") {
48
49
  n += Number(d.packetsLost ?? 0);
49
- const S = Number(d.roundTripTime ?? NaN);
50
- Number.isFinite(S) && (o = S * 1e3);
50
+ const k = Number(d.roundTripTime ?? NaN);
51
+ Number.isFinite(k) && (o = k * 1e3);
51
52
  }
52
53
  if (u === "candidate-pair" && (d.nominated === !0 || String(d.state ?? "") === "succeeded")) {
53
- const S = Number(d.currentRoundTripTime ?? NaN);
54
- o == null && Number.isFinite(S) && (o = S * 1e3);
54
+ const k = Number(d.currentRoundTripTime ?? NaN);
55
+ o == null && Number.isFinite(k) && (o = k * 1e3);
55
56
  const f = Number(d.availableOutgoingBitrate ?? NaN);
56
57
  Number.isFinite(f) && (r = f);
57
58
  }
@@ -67,9 +68,17 @@ function pe(a, e) {
67
68
  counters: c
68
69
  };
69
70
  }
70
- const fe = {
71
+ function $(a, e) {
72
+ const t = new URL(String(a), e);
73
+ return t.protocol === "https:" ? t.protocol = "wss:" : t.protocol === "http:" && (t.protocol = "ws:"), t;
74
+ }
75
+ function J(a, e) {
76
+ const t = new URL(String(a), e);
77
+ return t.protocol === "wss:" ? t.protocol = "https:" : t.protocol === "ws:" && (t.protocol = "http:"), t;
78
+ }
79
+ const ye = {
71
80
  audio: { active: !1, maxBitrate: 0, maxFramerate: 0, scaleResolutionDownBy: 4 }
72
- }, ge = { active: !0, maxBitrate: 4e6, maxFramerate: 30, scaleResolutionDownBy: 1 };
81
+ }, ve = { active: !0, maxBitrate: 4e6, maxFramerate: 30, scaleResolutionDownBy: 1 };
73
82
  class Q {
74
83
  options;
75
84
  socket = null;
@@ -212,9 +221,7 @@ class Q {
212
221
  this.stopped = !1, !this.localStream && (this.options.audio || this.options.video) && (this.localStream = await navigator.mediaDevices.getUserMedia({ audio: this.options.audio, video: this.options.video })), this.localStream && this.options.onEvent("localstream", { stream: this.localStream }), await this.openSocket(!1);
213
222
  }
214
223
  async openSocket(e) {
215
- const { credential: t } = this.options, i = new URL(t.signalingUrl, globalThis.location?.href);
216
- i.protocol = i.protocol === "https:" ? "wss:" : "ws:";
217
- const n = new Promise((c, l) => {
224
+ const { credential: t } = this.options, i = $(t.signalingUrl, globalThis.location?.href), n = new Promise((c, l) => {
218
225
  this.resolveJoin = c, this.rejectJoin = l;
219
226
  }), s = new WebSocket(i, ["rtc-client", t.signalingToken]), o = ++this.socketGeneration;
220
227
  this.socket = s;
@@ -351,7 +358,7 @@ class Q {
351
358
  });
352
359
  if (e.connection.signalingState !== "stable") return;
353
360
  await e.connection.setLocalDescription(t);
354
- const i = _();
361
+ const i = G();
355
362
  e.activeNegotiationId = i, this.send({
356
363
  type: "rtc.offer",
357
364
  targetParticipantId: e.identity.participantId,
@@ -391,7 +398,7 @@ class Q {
391
398
  async applyPeerVideoQuality(e) {
392
399
  const t = this.screenStream?.getVideoTracks()[0]?.id;
393
400
  for (const i of e.connection.getSenders().filter((n) => n.track?.kind === "video")) {
394
- const n = !!(t && i.track?.id === t), s = n ? ge : this.quality === "audio" ? fe.audio : N[e.quality], o = i.getParameters(), r = o.encodings?.length ? o.encodings : [{}];
401
+ const n = !!(t && i.track?.id === t), s = n ? ve : this.quality === "audio" ? ye.audio : j[e.quality], o = i.getParameters(), r = o.encodings?.length ? o.encodings : [{}];
395
402
  o.encodings = r.map((c) => ({ ...c, ...s })), o.degradationPreference = n ? "maintain-resolution" : "maintain-framerate", await i.setParameters(o);
396
403
  }
397
404
  }
@@ -411,11 +418,11 @@ class Q {
411
418
  if (i.connection.connectionState === "connected")
412
419
  try {
413
420
  const n = await i.connection.getStats();
414
- for (const s of ce(n.values()))
421
+ for (const s of de(n.values()))
415
422
  e.push({ participantId: i.identity.participantId, level: s.level });
416
423
  } catch {
417
424
  }
418
- const t = oe(e, this.activeSpeaker);
425
+ const t = le(e, this.activeSpeaker);
419
426
  t !== this.activeSpeaker && (this.activeSpeaker = t, this.options.onEvent("activespeaker", { participantId: t }));
420
427
  }
421
428
  async samplePeerQuality() {
@@ -428,9 +435,9 @@ class Q {
428
435
  } catch {
429
436
  continue;
430
437
  }
431
- const { sample: i, counters: n } = pe(t, e.counters);
438
+ const { sample: i, counters: n } = ge(t, e.counters);
432
439
  e.counters = n;
433
- const s = me(e.quality, i, e.poorSamples, e.goodSamples, {
440
+ const s = fe(e.quality, i, e.poorSamples, e.goodSamples, {
434
441
  samplesSeen: e.samplesSeen,
435
442
  ceiling: this.quality
436
443
  });
@@ -487,7 +494,7 @@ class Q {
487
494
  }
488
495
  send(e) {
489
496
  this.socket?.readyState === WebSocket.OPEN && this.socket.send(JSON.stringify({
490
- clientMessageId: e.clientMessageId ?? _(),
497
+ clientMessageId: e.clientMessageId ?? G(),
491
498
  ...e
492
499
  }));
493
500
  }
@@ -495,15 +502,15 @@ class Q {
495
502
  for (const t of e?.getTracks() ?? []) t.stop();
496
503
  }
497
504
  }
498
- function _() {
505
+ function G() {
499
506
  return globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
500
507
  }
501
- const z = { active: !0, maxBitrate: 4e6, maxFramerate: 30, scaleResolutionDownBy: 1 }, Y = [
502
- { rid: "a", maxBitrate: N.high.maxBitrate, maxFramerate: N.high.maxFramerate },
503
- { rid: "b", maxBitrate: N.medium.maxBitrate, maxFramerate: N.medium.maxFramerate, scaleResolutionDownBy: 2 },
504
- { rid: "c", maxBitrate: N.low.maxBitrate, maxFramerate: N.low.maxFramerate, scaleResolutionDownBy: 4 }
505
- ], G = { high: "a", medium: "b", low: "c" };
506
- class ye {
508
+ const H = { active: !0, maxBitrate: 4e6, maxFramerate: 30, scaleResolutionDownBy: 1 }, K = [
509
+ { rid: "a", maxBitrate: j.high.maxBitrate, maxFramerate: j.high.maxFramerate },
510
+ { rid: "b", maxBitrate: j.medium.maxBitrate, maxFramerate: j.medium.maxFramerate, scaleResolutionDownBy: 2 },
511
+ { rid: "c", maxBitrate: j.low.maxBitrate, maxFramerate: j.low.maxFramerate, scaleResolutionDownBy: 4 }
512
+ ], X = { high: "a", medium: "b", low: "c" };
513
+ class Se {
507
514
  options;
508
515
  apiBase;
509
516
  socket = null;
@@ -535,7 +542,7 @@ class ye {
535
542
  negotiationQueue = Promise.resolve();
536
543
  socketGeneration = 0;
537
544
  constructor(e) {
538
- this.options = e, this.localStream = e.localStream ?? null, this.quality = e.quality ?? "high", this.apiBase = new URL(e.credential.signalingUrl, globalThis.location?.href).origin;
545
+ this.options = e, this.localStream = e.localStream ?? null, this.quality = e.quality ?? "high", this.apiBase = J(e.credential.signalingUrl, globalThis.location?.href).origin;
539
546
  }
540
547
  async initialize() {
541
548
  if (!globalThis.RTCPeerConnection || !globalThis.WebSocket)
@@ -636,9 +643,7 @@ class ye {
636
643
  }
637
644
  // --- signaling -----------------------------------------------------------
638
645
  async openSocket(e) {
639
- const { credential: t } = this.options, i = new URL(t.signalingUrl, globalThis.location?.href);
640
- i.protocol = i.protocol === "https:" ? "wss:" : "ws:";
641
- const n = new Promise((c, l) => {
646
+ const { credential: t } = this.options, i = $(t.signalingUrl, globalThis.location?.href), n = new Promise((c, l) => {
642
647
  this.resolveJoin = c, this.rejectJoin = l;
643
648
  }), s = new WebSocket(i, ["rtc-client", t.signalingToken]), o = ++this.socketGeneration;
644
649
  this.socket = s;
@@ -721,7 +726,7 @@ class ye {
721
726
  // A single encoding when simulcast is off: constrained publishers
722
727
  // (phone CPU, cellular uplink) should not pay for three encoders. The
723
728
  // quality ladder then adapts that one encoding instead of gating layers.
724
- ...r.kind === "video" && this.simulcastEnabled() ? { sendEncodings: Y.map((c) => ({ ...c })) } : {}
729
+ ...r.kind === "video" && this.simulcastEnabled() ? { sendEncodings: K.map((c) => ({ ...c })) } : {}
725
730
  })), s = await t.createOffer();
726
731
  await t.setLocalDescription(s);
727
732
  const o = await this.sfuFetch(
@@ -821,7 +826,7 @@ class ye {
821
826
  n && await this.sfuFetch("PUT", `/v1/rtc/sfu/sessions/${encodeURIComponent(this.sessionId)}/tracks/update`, {
822
827
  tracks: [{
823
828
  mid: n,
824
- simulcast: { preferredRid: G[t], priorityOrdering: "asciibetical", ridNotAvailable: "asciibetical" }
829
+ simulcast: { preferredRid: X[t], priorityOrdering: "asciibetical", ridNotAvailable: "asciibetical" }
825
830
  }]
826
831
  });
827
832
  }
@@ -836,15 +841,15 @@ class ye {
836
841
  if (!e) return;
837
842
  const t = this.screenStream?.getVideoTracks()[0]?.id, i = !!(t && e.track?.id === t), n = e.getParameters(), s = n.encodings?.length ? n.encodings : [{}];
838
843
  if (s.length > 1) {
839
- const o = this.quality === "audio" ? null : G[this.quality];
844
+ const o = this.quality === "audio" ? null : X[this.quality];
840
845
  n.encodings = s.map((r) => {
841
846
  if (i)
842
- return { ...r, active: r.rid === "a", ...r.rid === "a" ? { maxBitrate: z.maxBitrate, maxFramerate: z.maxFramerate } : {} };
843
- const c = Y.find((d) => d.rid === r.rid), l = o != null && String(r.rid ?? "") >= o;
847
+ return { ...r, active: r.rid === "a", ...r.rid === "a" ? { maxBitrate: H.maxBitrate, maxFramerate: H.maxFramerate } : {} };
848
+ const c = K.find((d) => d.rid === r.rid), l = o != null && String(r.rid ?? "") >= o;
844
849
  return { ...r, ...c ?? {}, active: l };
845
850
  });
846
851
  } else {
847
- const o = this.quality === "audio" ? N.audio : N[this.quality], r = i ? z : o;
852
+ const o = this.quality === "audio" ? j.audio : j[this.quality], r = i ? H : o;
848
853
  n.encodings = s.map((c) => ({ ...c, ...r }));
849
854
  }
850
855
  n.degradationPreference = i ? "maintain-resolution" : "maintain-framerate", await e.setParameters(n);
@@ -911,11 +916,11 @@ class ye {
911
916
  return;
912
917
  }
913
918
  const i = [];
914
- for (const s of ce(t.values())) {
919
+ for (const s of de(t.values())) {
915
920
  const o = s.mid ? this.midToParticipant.get(s.mid) : void 0;
916
921
  o && i.push({ participantId: o, level: s.level });
917
922
  }
918
- const n = oe(i, this.activeSpeaker);
923
+ const n = le(i, this.activeSpeaker);
919
924
  n !== this.activeSpeaker && (this.activeSpeaker = n, this.options.onEvent("activespeaker", { participantId: n }));
920
925
  }
921
926
  clearTimers() {
@@ -932,7 +937,7 @@ class ye {
932
937
  }
933
938
  send(e) {
934
939
  this.socket?.readyState === WebSocket.OPEN && this.socket.send(JSON.stringify({
935
- clientMessageId: e.clientMessageId ?? ve(),
940
+ clientMessageId: e.clientMessageId ?? ke(),
936
941
  ...e
937
942
  }));
938
943
  }
@@ -940,10 +945,10 @@ class ye {
940
945
  for (const t of e?.getTracks() ?? []) t.stop();
941
946
  }
942
947
  }
943
- function ve() {
948
+ function ke() {
944
949
  return globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
945
950
  }
946
- function Ne(a, e = {}) {
951
+ function xe(a, e = {}) {
947
952
  const t = e.document ?? globalThis.document, i = !!(t && t.pictureInPictureEnabled);
948
953
  let n = null;
949
954
  function s() {
@@ -971,17 +976,17 @@ function Ne(a, e = {}) {
971
976
  }
972
977
  };
973
978
  }
974
- function je(a, e) {
975
- const t = e.document ?? globalThis.document, i = e.fetchImplementation ?? globalThis.fetch.bind(globalThis), n = new URL(e.credential.signalingUrl, globalThis.location?.href).origin, s = e.mimeType ?? "video/webm", o = e.height ?? 720, r = Math.round(o * 16 / 9);
976
- let c = null, l = null, d = null, u = null, S = 0, f = [], v = !1;
977
- async function I(y, k, p, C = "application/json") {
978
- const P = await i(`${n}${k}`, {
979
+ function Ve(a, e) {
980
+ const t = e.document ?? globalThis.document, i = e.fetchImplementation ?? globalThis.fetch.bind(globalThis), n = J(e.credential.signalingUrl, globalThis.location?.href).origin, s = e.mimeType ?? "video/webm", o = e.height ?? 720, r = Math.round(o * 16 / 9);
981
+ let c = null, l = null, d = null, u = null, k = 0, f = [], v = !1;
982
+ async function C(y, w, p, R = "application/json") {
983
+ const P = await i(`${n}${w}`, {
979
984
  method: y,
980
985
  headers: {
981
986
  authorization: `Bearer ${e.credential.signalingToken}`,
982
- "content-type": C
987
+ "content-type": R
983
988
  },
984
- body: p === void 0 ? void 0 : C === "application/json" ? JSON.stringify(p) : p
989
+ body: p === void 0 ? void 0 : R === "application/json" ? JSON.stringify(p) : p
985
990
  });
986
991
  if (!P.ok) throw new Error(`Recording request failed with HTTP ${P.status}`);
987
992
  return P.json();
@@ -992,60 +997,60 @@ function je(a, e) {
992
997
  },
993
998
  async start() {
994
999
  if (v) return;
995
- u = (await I("POST", "/v1/rtc/recordings")).recordingId;
996
- const k = t.createElement("canvas");
997
- k.width = r, k.height = o;
998
- const p = k.getContext("2d"), C = /* @__PURE__ */ new Map(), P = (T, R) => {
999
- let b = C.get(T);
1000
- return b || (b = t.createElement("video"), b.muted = !0, b.playsInline = !0, b.srcObject = R, b.play().catch(() => {
1001
- }), C.set(T, b)), b;
1000
+ u = (await C("POST", "/v1/rtc/recordings")).recordingId;
1001
+ const w = t.createElement("canvas");
1002
+ w.width = r, w.height = o;
1003
+ const p = w.getContext("2d"), R = /* @__PURE__ */ new Map(), P = (T, M) => {
1004
+ let b = R.get(T);
1005
+ return b || (b = t.createElement("video"), b.muted = !0, b.playsInline = !0, b.srcObject = M, b.play().catch(() => {
1006
+ }), R.set(T, b)), b;
1002
1007
  };
1003
1008
  l = setInterval(() => {
1004
- const T = a.getRemoteStreams(), R = a.getLocalStream(), b = [
1005
- ...T.map((j) => ({ key: j.participant.participantId, stream: j.stream, label: j.participant.displayName })),
1006
- ...R ? [{ key: "local", stream: R, label: "me" }] : []
1009
+ const T = a.getRemoteStreams(), M = a.getLocalStream(), b = [
1010
+ ...T.map((q) => ({ key: q.participant.participantId, stream: q.stream, label: q.participant.displayName })),
1011
+ ...M ? [{ key: "local", stream: M, label: "me" }] : []
1007
1012
  ];
1008
1013
  p.fillStyle = "#101418", p.fillRect(0, 0, r, o);
1009
- const O = Math.max(1, Math.ceil(Math.sqrt(b.length))), g = Math.max(1, Math.ceil(b.length / O)), q = r / O, x = o / g;
1010
- b.forEach((j, J) => {
1011
- const W = P(j.key, j.stream), B = J % O * q, F = Math.floor(J / O) * x;
1012
- W.videoWidth > 0 && p.drawImage(W, B + 2, F + 2, q - 4, x - 4), p.fillStyle = "rgba(0,0,0,.6)", p.fillRect(B + 8, F + x - 30, Math.min(q - 16, 12 + j.label.length * 9), 22), p.fillStyle = "#fff", p.font = "14px system-ui", p.fillText(j.label, B + 14, F + x - 14);
1014
+ const O = Math.max(1, Math.ceil(Math.sqrt(b.length))), V = Math.max(1, Math.ceil(b.length / O)), N = r / O, g = o / V;
1015
+ b.forEach((q, _) => {
1016
+ const Y = P(q.key, q.stream), B = _ % O * N, F = Math.floor(_ / O) * g;
1017
+ Y.videoWidth > 0 && p.drawImage(Y, B + 2, F + 2, N - 4, g - 4), p.fillStyle = "rgba(0,0,0,.6)", p.fillRect(B + 8, F + g - 30, Math.min(N - 16, 12 + q.label.length * 9), 22), p.fillStyle = "#fff", p.font = "14px system-ui", p.fillText(q.label, B + 14, F + g - 14);
1013
1018
  });
1014
1019
  }, 66);
1015
- const L = k.captureStream(15);
1020
+ const L = w.captureStream(15);
1016
1021
  d = new AudioContext();
1017
- const E = d.createMediaStreamDestination(), A = /* @__PURE__ */ new Set(), w = () => {
1022
+ const I = d.createMediaStreamDestination(), A = /* @__PURE__ */ new Set(), S = () => {
1018
1023
  const T = [
1019
- ...a.getRemoteStreams().map((R) => R.stream),
1024
+ ...a.getRemoteStreams().map((M) => M.stream),
1020
1025
  ...a.getLocalStream() ? [a.getLocalStream()] : []
1021
1026
  ];
1022
- for (const R of T)
1023
- for (const b of R.getAudioTracks())
1024
- A.has(b.id) || (A.add(b.id), d.createMediaStreamSource(new MediaStream([b])).connect(E));
1027
+ for (const M of T)
1028
+ for (const b of M.getAudioTracks())
1029
+ A.has(b.id) || (A.add(b.id), d.createMediaStreamSource(new MediaStream([b])).connect(I));
1025
1030
  };
1026
- w();
1027
- const M = setInterval(w, 1e3), m = () => clearInterval(M);
1028
- for (const T of E.stream.getAudioTracks()) L.addTrack(T);
1029
- c = (e.mediaRecorderFactory ?? ((T, R) => new MediaRecorder(T, R)))(L, { mimeType: s }), f = [], c.addEventListener("dataavailable", (T) => {
1031
+ S();
1032
+ const E = setInterval(S, 1e3), m = () => clearInterval(E);
1033
+ for (const T of I.stream.getAudioTracks()) L.addTrack(T);
1034
+ c = (e.mediaRecorderFactory ?? ((T, M) => new MediaRecorder(T, M)))(L, { mimeType: s }), f = [], c.addEventListener("dataavailable", (T) => {
1030
1035
  T.data && T.data.size > 0 && f.push(T.data);
1031
- }), c.addEventListener("stop", m), c.start(1e3), S = Date.now(), v = !0;
1036
+ }), c.addEventListener("stop", m), c.start(1e3), k = Date.now(), v = !0;
1032
1037
  },
1033
1038
  async stop() {
1034
1039
  if (!v || !c || !u) throw new Error("The recorder is not running");
1035
1040
  v = !1;
1036
- const y = c, k = new Promise((E) => y.addEventListener("stop", () => E(), { once: !0 }));
1037
- y.stop(), await k, l && clearInterval(l), l = null, await d?.close().catch(() => {
1041
+ const y = c, w = new Promise((I) => y.addEventListener("stop", () => I(), { once: !0 }));
1042
+ y.stop(), await w, l && clearInterval(l), l = null, await d?.close().catch(() => {
1038
1043
  }), d = null;
1039
1044
  const p = new Blob(f, { type: s });
1040
1045
  f = [];
1041
- const C = Math.max(1, Math.round((Date.now() - S) / 1e3)), P = await I(
1046
+ const R = Math.max(1, Math.round((Date.now() - k) / 1e3)), P = await C(
1042
1047
  "PUT",
1043
1048
  `/v1/rtc/recordings/${encodeURIComponent(u)}/media`,
1044
1049
  p,
1045
1050
  s
1046
1051
  );
1047
- await I("POST", `/v1/rtc/recordings/${encodeURIComponent(u)}/complete`, { durationSeconds: C });
1048
- const L = { recordingId: u, sizeBytes: P.sizeBytes, durationSeconds: C };
1052
+ await C("POST", `/v1/rtc/recordings/${encodeURIComponent(u)}/complete`, { durationSeconds: R });
1053
+ const L = { recordingId: u, sizeBytes: P.sizeBytes, durationSeconds: R };
1049
1054
  return u = null, c = null, L;
1050
1055
  },
1051
1056
  dispose() {
@@ -1059,7 +1064,7 @@ function je(a, e) {
1059
1064
  }
1060
1065
  };
1061
1066
  }
1062
- const Se = ["none", "blur", "aurora", "cybergrid", "bokeh", "sunset", "image"], ke = ["none", "snow", "confetti", "vignette"], K = {
1067
+ const we = ["none", "blur", "aurora", "cybergrid", "bokeh", "sunset", "image"], Te = ["none", "snow", "confetti", "vignette"], Z = {
1063
1068
  aurora(a, e, t, i) {
1064
1069
  const n = a.createLinearGradient(0, 0, 0, t);
1065
1070
  n.addColorStop(0, "#050b1e"), n.addColorStop(1, "#0b2540"), a.fillStyle = n, a.fillRect(0, 0, e, t);
@@ -1096,20 +1101,20 @@ const Se = ["none", "blur", "aurora", "cybergrid", "bokeh", "sunset", "image"],
1096
1101
  n.addColorStop(0, "#2b1055"), n.addColorStop(0.55, "#d1548a"), n.addColorStop(1, "#ffb36b"), a.fillStyle = n, a.fillRect(0, 0, e, t), a.fillStyle = "#ffdf8e", a.beginPath(), a.arc(e * 0.5, t * 0.62 + Math.sin(i / 4e3) * 4, t * 0.13, 0, Math.PI * 2), a.fill(), a.fillStyle = "rgba(20,8,40,0.85)", a.fillRect(0, t * 0.78, e, t * 0.22);
1097
1102
  }
1098
1103
  };
1099
- function Ve(a, e = {}) {
1104
+ function Ue(a, e = {}) {
1100
1105
  const t = e.document ?? globalThis.document;
1101
1106
  let i = e.width ?? 1280, n = e.height ?? 720;
1102
1107
  const s = !!(e.width || e.height), o = e.frameRate ?? 24, r = a instanceof MediaStreamTrack ? a : a.getVideoTracks()[0];
1103
1108
  if (!r) throw new Error("A video track is required");
1104
- let c = e.background ?? "none", l = e.overlay ?? "none", d = e.backgroundImage ?? null, u = e.segmenter ?? null, S = null, f = !1;
1109
+ let c = e.background ?? "none", l = e.overlay ?? "none", d = e.backgroundImage ?? null, u = e.segmenter ?? null, k = null, f = !1;
1105
1110
  const v = t.createElement("video");
1106
1111
  v.muted = !0, v.playsInline = !0, v.srcObject = new MediaStream([r]), v.play().catch(() => {
1107
1112
  });
1108
- const I = t.createElement("canvas");
1109
- I.width = i, I.height = n;
1110
- const y = I.getContext("2d"), k = t.createElement("canvas");
1111
- k.width = i, k.height = n;
1112
- const p = k.getContext("2d"), C = () => Array.from({ length: 80 }, (m, h) => ({
1113
+ const C = t.createElement("canvas");
1114
+ C.width = i, C.height = n;
1115
+ const y = C.getContext("2d"), w = t.createElement("canvas");
1116
+ w.width = i, w.height = n;
1117
+ const p = w.getContext("2d"), R = () => Array.from({ length: 80 }, (m, h) => ({
1113
1118
  x: (Math.sin(h * 12.9898) * 0.5 + 0.5) * i,
1114
1119
  y: (Math.sin(h * 78.233) * 0.5 + 0.5) * n,
1115
1120
  speed: 0.6 + h % 5 * 0.5,
@@ -1117,25 +1122,25 @@ function Ve(a, e = {}) {
1117
1122
  size: 2 + h % 4,
1118
1123
  hue: h * 47 % 360
1119
1124
  }));
1120
- let P = C();
1125
+ let P = R();
1121
1126
  const L = () => {
1122
1127
  if (s) return;
1123
1128
  const m = v.videoWidth, h = v.videoHeight;
1124
1129
  if (!m || !h) return;
1125
- const T = Math.min(1, 1280 / Math.max(m, h)), R = Math.round(m * T), b = Math.round(h * T);
1126
- R === i && b === n || (i = R, n = b, I.width = i, I.height = n, k.width = i, k.height = n, P = C());
1130
+ const T = Math.min(1, 1280 / Math.max(m, h)), M = Math.round(m * T), b = Math.round(h * T);
1131
+ M === i && b === n || (i = M, n = b, C.width = i, C.height = n, w.width = i, w.height = n, P = R());
1127
1132
  };
1128
1133
  v.addEventListener?.("loadedmetadata", L), v.addEventListener?.("resize", L);
1129
- function E() {
1130
- if (S) {
1131
- p.clearRect(0, 0, i, n), p.drawImage(S, 0, 0, i, n), p.globalCompositeOperation = "source-in", p.drawImage(v, 0, 0, i, n), p.globalCompositeOperation = "source-over", y.drawImage(k, 0, 0);
1134
+ function I() {
1135
+ if (k) {
1136
+ p.clearRect(0, 0, i, n), p.drawImage(k, 0, 0, i, n), p.globalCompositeOperation = "source-in", p.drawImage(v, 0, 0, i, n), p.globalCompositeOperation = "source-over", y.drawImage(w, 0, 0);
1132
1137
  return;
1133
1138
  }
1134
- const m = i * 0.42, h = m * 9 / 16, T = i - m - 24, R = n - h - 24;
1135
- y.save(), y.shadowColor = "rgba(0,0,0,.5)", y.shadowBlur = 24, y.beginPath(), y.roundRect(T, R, m, h, 14), y.clip(), y.drawImage(v, T, R, m, h), y.restore();
1139
+ const m = i * 0.42, h = m * 9 / 16, T = i - m - 24, M = n - h - 24;
1140
+ y.save(), y.shadowColor = "rgba(0,0,0,.5)", y.shadowBlur = 24, y.beginPath(), y.roundRect(T, M, m, h, 14), y.clip(), y.drawImage(v, T, M, m, h), y.restore();
1136
1141
  }
1137
1142
  function A(m) {
1138
- if (c === "none" ? y.drawImage(v, 0, 0, i, n) : c === "blur" ? (y.filter = "blur(14px)", y.drawImage(v, -16, -16, i + 32, n + 32), y.filter = "none", S && E()) : c === "image" && d ? (y.drawImage(d, 0, 0, i, n), E()) : ((K[c] ?? K.aurora)(y, i, n, m), E()), l === "snow" || l === "confetti")
1143
+ if (c === "none" ? y.drawImage(v, 0, 0, i, n) : c === "blur" ? (y.filter = "blur(14px)", y.drawImage(v, -16, -16, i + 32, n + 32), y.filter = "none", k && I()) : c === "image" && d ? (y.drawImage(d, 0, 0, i, n), I()) : ((Z[c] ?? Z.aurora)(y, i, n, m), I()), l === "snow" || l === "confetti")
1139
1144
  for (const h of P)
1140
1145
  h.y += h.speed * (l === "confetti" ? 1.6 : 1), h.x += h.drift, h.y > n && (h.y = -6, h.x = Math.random() * i), y.fillStyle = l === "snow" ? "rgba(255,255,255,.85)" : `hsl(${h.hue}, 90%, 60%)`, l === "confetti" ? y.fillRect(h.x, h.y, h.size + 2, h.size) : (y.beginPath(), y.arc(h.x, h.y, h.size / 2, 0, Math.PI * 2), y.fill());
1141
1146
  else if (l === "vignette") {
@@ -1143,35 +1148,35 @@ function Ve(a, e = {}) {
1143
1148
  h.addColorStop(0, "rgba(0,0,0,0)"), h.addColorStop(1, "rgba(0,0,0,0.55)"), y.fillStyle = h, y.fillRect(0, 0, i, n);
1144
1149
  }
1145
1150
  }
1146
- const w = setInterval(() => {
1151
+ const S = setInterval(() => {
1147
1152
  A(Date.now()), u && !f && c !== "none" && (f = !0, u.segment(v).then((m) => {
1148
- S = m;
1153
+ k = m;
1149
1154
  }).catch(() => {
1150
- S = null;
1155
+ k = null;
1151
1156
  }).finally(() => {
1152
1157
  f = !1;
1153
1158
  }));
1154
- }, Math.round(1e3 / o)), M = I.captureStream(o);
1159
+ }, Math.round(1e3 / o)), E = C.captureStream(o);
1155
1160
  return {
1156
- track: M.getVideoTracks()[0],
1157
- stream: M,
1161
+ track: E.getVideoTracks()[0],
1162
+ stream: E,
1158
1163
  setBackground(m, h) {
1159
- c = Se.includes(m) ? m : "none", h !== void 0 && (d = h), c === "none" && (S = null);
1164
+ c = we.includes(m) ? m : "none", h !== void 0 && (d = h), c === "none" && (k = null);
1160
1165
  },
1161
1166
  setOverlay(m) {
1162
- l = ke.includes(m) ? m : "none";
1167
+ l = Te.includes(m) ? m : "none";
1163
1168
  },
1164
1169
  setSegmenter(m) {
1165
- u = m, m || (S = null);
1170
+ u = m, m || (k = null);
1166
1171
  },
1167
1172
  dispose() {
1168
- clearInterval(w), u?.close?.();
1169
- for (const m of M.getTracks()) m.stop();
1173
+ clearInterval(S), u?.close?.();
1174
+ for (const m of E.getTracks()) m.stop();
1170
1175
  v.srcObject = null;
1171
1176
  }
1172
1177
  };
1173
1178
  }
1174
- function le() {
1179
+ function he() {
1175
1180
  return {
1176
1181
  blinkLeft: 0,
1177
1182
  blinkRight: 0,
@@ -1190,18 +1195,18 @@ function D(a, e) {
1190
1195
  const t = a.find((i) => i.categoryName === e);
1191
1196
  return t ? Math.max(0, Math.min(1, t.score)) : 0;
1192
1197
  }
1193
- function we(a) {
1198
+ function be(a) {
1194
1199
  if (!a || a.length < 16) return { yaw: 0, pitch: 0, roll: 0 };
1195
1200
  a[0], a[4];
1196
1201
  const e = a[8], t = a[1], i = a[5], n = a[9], s = a[10], o = Math.atan2(e, s), r = Math.asin(Math.max(-1, Math.min(1, -n))), c = Math.atan2(t, i);
1197
1202
  return { yaw: o, pitch: r, roll: c };
1198
1203
  }
1199
- function Te(a, e, t = 1) {
1200
- if (!a || a.length === 0) return le();
1201
- const i = we(e), n = (D(a, "eyeLookOutRight") + D(a, "eyeLookInLeft")) / 2, s = (D(a, "eyeLookOutLeft") + D(a, "eyeLookInRight")) / 2, o = (D(a, "eyeLookUpLeft") + D(a, "eyeLookUpRight")) / 2, r = (D(a, "eyeLookDownLeft") + D(a, "eyeLookDownRight")) / 2, c = (D(a, "mouthSmileLeft") + D(a, "mouthSmileRight")) / 2, l = (D(a, "mouthFrownLeft") + D(a, "mouthFrownRight")) / 2, d = D(a, "eyeBlinkLeft"), u = D(a, "eyeBlinkRight"), S = Math.min(1, Math.abs(i.yaw) / 0.35) * Math.max(0, Math.min(1, t)), f = (d + u) / 2;
1204
+ function Ce(a, e, t = 1) {
1205
+ if (!a || a.length === 0) return he();
1206
+ const i = be(e), n = (D(a, "eyeLookOutRight") + D(a, "eyeLookInLeft")) / 2, s = (D(a, "eyeLookOutLeft") + D(a, "eyeLookInRight")) / 2, o = (D(a, "eyeLookUpLeft") + D(a, "eyeLookUpRight")) / 2, r = (D(a, "eyeLookDownLeft") + D(a, "eyeLookDownRight")) / 2, c = (D(a, "mouthSmileLeft") + D(a, "mouthSmileRight")) / 2, l = (D(a, "mouthFrownLeft") + D(a, "mouthFrownRight")) / 2, d = D(a, "eyeBlinkLeft"), u = D(a, "eyeBlinkRight"), k = Math.min(1, Math.abs(i.yaw) / 0.35) * Math.max(0, Math.min(1, t)), f = (d + u) / 2;
1202
1207
  return {
1203
- blinkLeft: d + (f - d) * S,
1204
- blinkRight: u + (f - u) * S,
1208
+ blinkLeft: d + (f - d) * k,
1209
+ blinkRight: u + (f - u) * k,
1205
1210
  jawOpen: D(a, "jawOpen"),
1206
1211
  smile: c - l,
1207
1212
  browUp: (D(a, "browInnerUp") + D(a, "browOuterUpLeft") + D(a, "browOuterUpRight")) / 3,
@@ -1213,7 +1218,7 @@ function Te(a, e, t = 1) {
1213
1218
  tracked: !0
1214
1219
  };
1215
1220
  }
1216
- function X(a, e, t = 0.4) {
1221
+ function ee(a, e, t = 0.4) {
1217
1222
  const i = (n, s) => n + (s - n) * t;
1218
1223
  return {
1219
1224
  blinkLeft: i(a.blinkLeft, e.blinkLeft),
@@ -1229,36 +1234,36 @@ function X(a, e, t = 0.4) {
1229
1234
  tracked: e.tracked
1230
1235
  };
1231
1236
  }
1232
- function be(a, e, t, i, n) {
1237
+ function Re(a, e, t, i, n) {
1233
1238
  n || (a.fillStyle = "#101822", a.fillRect(0, 0, t, i));
1234
1239
  const s = n ? n.x + e.headYaw * n.radius * 0.1 : t / 2 + e.headYaw * t * 0.18, o = n ? n.y + e.headPitch * n.radius * 0.1 : i / 2 + e.headPitch * i * 0.18, r = n ? n.radius : Math.min(t, i) * 0.28;
1235
1240
  a.save(), a.translate(s, o), a.rotate(e.headRoll * 0.6);
1236
- const c = Math.max(-1.35, Math.min(1.35, e.headYaw)), l = Math.max(-0.9, Math.min(0.9, e.headPitch)), d = Math.sin(c), u = (A) => Math.sin(A + c) * r, S = (A) => Math.cos(A + c), f = Math.sin(l) * r * 0.22;
1241
+ const c = Math.max(-1.35, Math.min(1.35, e.headYaw)), l = Math.max(-0.9, Math.min(0.9, e.headPitch)), d = Math.sin(c), u = (A) => Math.sin(A + c) * r, k = (A) => Math.cos(A + c), f = Math.sin(l) * r * 0.22;
1237
1242
  a.fillStyle = "#3a2a1c", a.beginPath(), a.ellipse(-d * r * 0.35, -r * 0.25, r * 0.98, r * 0.95, 0, 0, Math.PI * 2), a.fill(), a.fillStyle = e.tracked ? "#f2c9a0" : "#5a6470", a.beginPath(), a.ellipse(0, 0, r * (1 - Math.abs(d) * 0.12), r * 1.12, 0, 0, Math.PI * 2), a.fill(), a.fillStyle = "#3a2a1c", a.beginPath(), a.ellipse(-d * r * 0.28, -r * 0.72 + f * 0.4, r * 0.92, r * 0.5, 0, Math.PI, Math.PI * 2), a.fill();
1238
1243
  const v = 0;
1239
1244
  a.fillStyle = "#e5b58a", a.beginPath();
1240
- const I = u(v) * 0.9, y = r * 0.12 + f;
1241
- a.ellipse(I + d * r * 0.14, y, r * 0.11, r * 0.14, 0, 0, Math.PI * 2), a.fill();
1245
+ const C = u(v) * 0.9, y = r * 0.12 + f;
1246
+ a.ellipse(C + d * r * 0.14, y, r * 0.11, r * 0.14, 0, 0, Math.PI * 2), a.fill();
1242
1247
  for (const A of [-1, 1]) {
1243
- const w = A * 0.42, M = S(w);
1244
- if (M <= 0.12) continue;
1245
- const m = u(w) * 0.82, h = Math.max(0.2, M), T = A < 0 ? e.blinkLeft : e.blinkRight, R = Math.max(0.06, 1 - T), b = e.browUp * r * 0.14;
1248
+ const S = A * 0.42, E = k(S);
1249
+ if (E <= 0.12) continue;
1250
+ const m = u(S) * 0.82, h = Math.max(0.2, E), T = A < 0 ? e.blinkLeft : e.blinkRight, M = Math.max(0.06, 1 - T), b = e.browUp * r * 0.14;
1246
1251
  a.strokeStyle = "#4a2e18", a.lineWidth = r * 0.07, a.lineCap = "round", a.beginPath(), a.moveTo(m - r * 0.2 * h, -r * 0.42 - b + f), a.quadraticCurveTo(m, -r * 0.52 - b + f, m + r * 0.2 * h, -r * 0.44 - b + f), a.stroke();
1247
1252
  const O = -r * 0.18 + f;
1248
- a.fillStyle = "#ffffff", a.beginPath(), a.ellipse(m, O, r * 0.16 * h, r * 0.12 * R, 0, 0, Math.PI * 2), a.fill(), a.fillStyle = "#22303c", a.beginPath(), a.ellipse(
1253
+ a.fillStyle = "#ffffff", a.beginPath(), a.ellipse(m, O, r * 0.16 * h, r * 0.12 * M, 0, 0, Math.PI * 2), a.fill(), a.fillStyle = "#22303c", a.beginPath(), a.ellipse(
1249
1254
  m + e.pupilX * r * 0.07 * h,
1250
1255
  O + e.pupilY * r * 0.05,
1251
1256
  r * 0.06 * h,
1252
- r * 0.06 * R,
1257
+ r * 0.06 * M,
1253
1258
  0,
1254
1259
  0,
1255
1260
  Math.PI * 2
1256
1261
  ), a.fill();
1257
1262
  }
1258
- const k = Math.max(0.25, S(0)), p = u(0) * 0.7, C = r * 0.55 * k, P = r * (0.04 + e.jawOpen * 0.34), L = e.smile * r * 0.12, E = r * 0.42 + f;
1259
- a.fillStyle = "#8c2f2f", a.beginPath(), a.moveTo(p - C / 2, E - L), a.quadraticCurveTo(p, E + P, p + C / 2, E - L), a.quadraticCurveTo(p, E - P * 0.25, p - C / 2, E - L), a.closePath(), a.fill(), a.restore(), !e.tracked && !n && (a.fillStyle = "#9fb0bd", a.font = `${Math.round(i * 0.045)}px system-ui`, a.textAlign = "center", a.fillText("No face detected", t / 2, i * 0.9), a.textAlign = "left");
1263
+ const w = Math.max(0.25, k(0)), p = u(0) * 0.7, R = r * 0.55 * w, P = r * (0.04 + e.jawOpen * 0.34), L = e.smile * r * 0.12, I = r * 0.42 + f;
1264
+ a.fillStyle = "#8c2f2f", a.beginPath(), a.moveTo(p - R / 2, I - L), a.quadraticCurveTo(p, I + P, p + R / 2, I - L), a.quadraticCurveTo(p, I - P * 0.25, p - R / 2, I - L), a.closePath(), a.fill(), a.restore(), !e.tracked && !n && (a.fillStyle = "#9fb0bd", a.font = `${Math.round(i * 0.045)}px system-ui`, a.textAlign = "center", a.fillText("No face detected", t / 2, i * 0.9), a.textAlign = "left");
1260
1265
  }
1261
- const Z = {
1266
+ const te = {
1262
1267
  mouthGain: 1.7,
1263
1268
  blinkGain: 1,
1264
1269
  eyeSync: 1,
@@ -1267,82 +1272,82 @@ const Z = {
1267
1272
  avatarLift: 0,
1268
1273
  lostHoldMs: 400
1269
1274
  };
1270
- function ee() {
1275
+ function ie() {
1271
1276
  return {
1272
1277
  render(a, e, t, i, n) {
1273
- be(a, e, t, i, n ?? void 0);
1278
+ Re(a, e, t, i, n ?? void 0);
1274
1279
  }
1275
1280
  };
1276
1281
  }
1277
- const $ = (a) => Math.max(0, Math.min(1, a));
1278
- function xe(a, e = {}) {
1282
+ const z = (a) => Math.max(0, Math.min(1, a));
1283
+ function Qe(a, e = {}) {
1279
1284
  const t = e.document ?? globalThis.document;
1280
1285
  let i = e.width ?? 1280, n = e.height ?? 720;
1281
1286
  const s = !!(e.width || e.height), o = e.frameRate ?? 24, r = a instanceof MediaStreamTrack ? a : a.getVideoTracks()[0];
1282
1287
  if (!r) throw new Error("A video track is required");
1283
- let c = e.tracker ?? null, l = e.renderer ?? ee(), d = e.mode ?? "replace";
1284
- const u = { ...Z, ...e.tuning }, S = e.backdrop ?? "#101822", f = t.createElement("video");
1288
+ let c = e.tracker ?? null, l = e.renderer ?? ie(), d = e.mode ?? "replace";
1289
+ const u = { ...te, ...e.tuning }, k = e.backdrop ?? "#101822", f = t.createElement("video");
1285
1290
  f.muted = !0, f.playsInline = !0, f.srcObject = new MediaStream([r]), f.play().catch(() => {
1286
1291
  });
1287
1292
  const v = t.createElement("canvas");
1288
1293
  v.width = i, v.height = n;
1289
- const I = v.getContext("2d"), y = () => {
1294
+ const C = v.getContext("2d"), y = () => {
1290
1295
  if (s) return;
1291
- const w = f.videoWidth, M = f.videoHeight;
1292
- if (!w || !M) return;
1293
- const m = Math.min(1, 1280 / Math.max(w, M)), h = Math.round(w * m), T = Math.round(M * m);
1296
+ const S = f.videoWidth, E = f.videoHeight;
1297
+ if (!S || !E) return;
1298
+ const m = Math.min(1, 1280 / Math.max(S, E)), h = Math.round(S * m), T = Math.round(E * m);
1294
1299
  (!(h === i || T === n) || h !== i || T !== n) && (i = h, n = T, v.width = i, v.height = n);
1295
1300
  };
1296
1301
  f.addEventListener?.("loadedmetadata", y), f.addEventListener?.("resize", y);
1297
- let k = le(), p = null, C = 0;
1298
- function P(w) {
1299
- if (w.length <= 454) return;
1300
- const M = w[10], m = w[152], h = w[234], T = w[454], R = (h.x + T.x) / 2 * i, b = (h.y + T.y) / 2 * n, O = Math.hypot((m.x - M.x) * i, (m.y - M.y) * n), g = Math.max(0.6, Math.cos(k.headPitch)), q = { x: R, y: b, radius: Math.max(24, O / g * 0.8) };
1301
- p = p ? { x: p.x + (q.x - p.x) * 0.4, y: p.y + (q.y - p.y) * 0.4, radius: p.radius + (q.radius - p.radius) * 0.15 } : q;
1302
+ let w = he(), p = null, R = 0;
1303
+ function P(S) {
1304
+ if (S.length <= 454) return;
1305
+ const E = S[10], m = S[152], h = S[234], T = S[454], M = (h.x + T.x) / 2 * i, b = (h.y + T.y) / 2 * n, O = Math.hypot((m.x - E.x) * i, (m.y - E.y) * n), V = Math.max(0.6, Math.cos(w.headPitch)), N = { x: M, y: b, radius: Math.max(24, O / V * 0.8) };
1306
+ p = p ? { x: p.x + (N.x - p.x) * 0.4, y: p.y + (N.y - p.y) * 0.4, radius: p.radius + (N.radius - p.radius) * 0.15 } : N;
1302
1307
  }
1303
- function L(w) {
1308
+ function L(S) {
1304
1309
  if (c && f.readyState >= 2) {
1305
1310
  let m = null;
1306
1311
  try {
1307
- m = c.detect(f, w);
1312
+ m = c.detect(f, S);
1308
1313
  } catch {
1309
1314
  }
1310
- const h = Te(m?.categories ?? null, m?.matrix ?? null, u.eyeSync);
1311
- h.jawOpen = $(h.jawOpen * u.mouthGain), h.blinkLeft = $(h.blinkLeft * u.blinkGain), h.blinkRight = $(h.blinkRight * u.blinkGain), h.tracked ? (C = w, k = X(k, h, u.smoothing), m?.landmarks && P(m.landmarks)) : k.tracked && w - C > u.lostHoldMs && (k = X(k, { ...k, jawOpen: 0, browUp: 0, smile: k.smile * 0.5, blinkLeft: 0.1, blinkRight: 0.1 }, 0.05));
1315
+ const h = Ce(m?.categories ?? null, m?.matrix ?? null, u.eyeSync);
1316
+ h.jawOpen = z(h.jawOpen * u.mouthGain), h.blinkLeft = z(h.blinkLeft * u.blinkGain), h.blinkRight = z(h.blinkRight * u.blinkGain), h.tracked ? (R = S, w = ee(w, h, u.smoothing), m?.landmarks && P(m.landmarks)) : w.tracked && S - R > u.lostHoldMs && (w = ee(w, { ...w, jawOpen: 0, browUp: 0, smile: w.smile * 0.5, blinkLeft: 0.1, blinkRight: 0.1 }, 0.05));
1312
1317
  }
1313
- d === "overlay" && f.readyState >= 2 ? I.drawImage(f, 0, 0, i, n) : (I.fillStyle = S, I.fillRect(0, 0, i, n));
1314
- const M = p ? { x: p.x, y: p.y + u.avatarLift * p.radius, radius: p.radius * u.avatarScale } : null;
1315
- l?.render(I, k, i, n, M);
1318
+ d === "overlay" && f.readyState >= 2 ? C.drawImage(f, 0, 0, i, n) : (C.fillStyle = k, C.fillRect(0, 0, i, n));
1319
+ const E = p ? { x: p.x, y: p.y + u.avatarLift * p.radius, radius: p.radius * u.avatarScale } : null;
1320
+ l?.render(C, w, i, n, E);
1316
1321
  }
1317
- const E = setInterval(() => L(Date.now()), Math.round(1e3 / o)), A = v.captureStream(o);
1322
+ const I = setInterval(() => L(Date.now()), Math.round(1e3 / o)), A = v.captureStream(o);
1318
1323
  return {
1319
1324
  track: A.getVideoTracks()[0],
1320
1325
  stream: A,
1321
- getRig: () => ({ ...k }),
1322
- setMode(w) {
1323
- d = w === "overlay" ? "overlay" : "replace";
1326
+ getRig: () => ({ ...w }),
1327
+ setMode(S) {
1328
+ d = S === "overlay" ? "overlay" : "replace";
1324
1329
  },
1325
- setTracker(w) {
1326
- c?.close?.(), c = w;
1330
+ setTracker(S) {
1331
+ c?.close?.(), c = S;
1327
1332
  },
1328
- setRenderer(w) {
1329
- l?.dispose?.(), l = w ?? ee();
1333
+ setRenderer(S) {
1334
+ l?.dispose?.(), l = S ?? ie();
1330
1335
  },
1331
- setTuning(w) {
1332
- for (const M of Object.keys(Z)) {
1333
- const m = w[M];
1334
- typeof m == "number" && Number.isFinite(m) && (u[M] = m);
1336
+ setTuning(S) {
1337
+ for (const E of Object.keys(te)) {
1338
+ const m = S[E];
1339
+ typeof m == "number" && Number.isFinite(m) && (u[E] = m);
1335
1340
  }
1336
1341
  },
1337
1342
  getTuning: () => ({ ...u }),
1338
1343
  dispose() {
1339
- clearInterval(E), c?.close?.(), l?.dispose?.();
1340
- for (const w of A.getTracks()) w.stop();
1344
+ clearInterval(I), c?.close?.(), l?.dispose?.();
1345
+ for (const S of A.getTracks()) S.stop();
1341
1346
  f.srcObject = null;
1342
1347
  }
1343
1348
  };
1344
1349
  }
1345
- class Ce extends EventTarget {
1350
+ class Ie extends EventTarget {
1346
1351
  mode;
1347
1352
  options;
1348
1353
  client = null;
@@ -1376,7 +1381,7 @@ class Ce extends EventTarget {
1376
1381
  async initialize() {
1377
1382
  if (this.client) return this;
1378
1383
  try {
1379
- const t = (this.options.transport === "auto" ? this.mode === "meeting" ? "sfu" : "mesh" : this.options.transport ?? "mesh") === "sfu" ? ye : Q;
1384
+ const t = (this.options.transport === "auto" ? this.mode === "meeting" ? "sfu" : "mesh" : this.options.transport ?? "mesh") === "sfu" ? Se : Q;
1380
1385
  return this.client = new t({
1381
1386
  credential: {
1382
1387
  signalingToken: this.options.credential.signalingToken,
@@ -1396,19 +1401,19 @@ class Ce extends EventTarget {
1396
1401
  localStream: this.options.localStream,
1397
1402
  simulcast: this.options.simulcast ?? !0,
1398
1403
  onEvent: (i, n) => this.handleNativeEvent(i, n)
1399
- }), await this.client.initialize(), this.startStats(), this.emit("initialized", { mode: this.mode, sdkVersion: De }), this.options.autoJoin && await this.join(), this;
1404
+ }), await this.client.initialize(), this.startStats(), this.emit("initialized", { mode: this.mode, sdkVersion: Oe }), this.options.autoJoin && await this.join(), this;
1400
1405
  } catch (e) {
1401
1406
  this.state = "failed";
1402
- const t = re(e, "RTC initialization failed");
1403
- throw this.emit("error", V(t)), t;
1407
+ const t = ce(e, "RTC initialization failed");
1408
+ throw this.emit("error", x(t)), t;
1404
1409
  }
1405
1410
  }
1406
1411
  async join() {
1407
1412
  const e = this.requireClient();
1408
1413
  return this.joinPromise ? this.joinPromise : (this.state = "joining", this.emit("joining", {}), this.joinPromise = e.join().catch((t) => {
1409
1414
  this.state = "failed";
1410
- const i = re(t, "RTC connection failed");
1411
- throw this.emit("error", V(i)), i;
1415
+ const i = ce(t, "RTC connection failed");
1416
+ throw this.emit("error", x(i)), i;
1412
1417
  }).finally(() => {
1413
1418
  this.joinPromise = null;
1414
1419
  }), this.joinPromise);
@@ -1446,14 +1451,14 @@ class Ce extends EventTarget {
1446
1451
  return navigator.mediaDevices?.enumerateDevices ? navigator.mediaDevices.enumerateDevices() : [];
1447
1452
  }
1448
1453
  getParticipants() {
1449
- return this.requireClient().getParticipants().map(ne);
1454
+ return this.requireClient().getParticipants().map(se);
1450
1455
  }
1451
1456
  getLocalStream() {
1452
1457
  return this.client?.getLocalStream() ?? null;
1453
1458
  }
1454
1459
  getRemoteStreams() {
1455
1460
  return (this.client?.getRemoteStreams() ?? []).map((e) => ({
1456
- participant: ne(e.participant),
1461
+ participant: se(e.participant),
1457
1462
  stream: e.stream
1458
1463
  }));
1459
1464
  }
@@ -1522,7 +1527,7 @@ class Ce extends EventTarget {
1522
1527
  let n = "unavailable";
1523
1528
  if (e.requestMedia !== !1 && navigator.mediaDevices?.getUserMedia)
1524
1529
  try {
1525
- (await navigator.mediaDevices.getUserMedia({ audio: this.options.audio, video: this.options.video })).getTracks().forEach((S) => S.stop()), n = "granted";
1530
+ (await navigator.mediaDevices.getUserMedia({ audio: this.options.audio, video: this.options.video })).getTracks().forEach((k) => k.stop()), n = "granted";
1526
1531
  } catch {
1527
1532
  n = "denied", t.push("media_permission_denied");
1528
1533
  }
@@ -1533,8 +1538,8 @@ class Ce extends EventTarget {
1533
1538
  if (c) {
1534
1539
  const u = performance.now();
1535
1540
  try {
1536
- const S = await fetch(c, { method: "HEAD", cache: "no-store", credentials: "omit" });
1537
- l = Math.round(performance.now() - u), S.ok || t.push("network_probe_failed");
1541
+ const k = await fetch(c, { method: "HEAD", cache: "no-store", credentials: "omit" });
1542
+ l = Math.round(performance.now() - u), k.ok || t.push("network_probe_failed");
1538
1543
  } catch {
1539
1544
  t.push("network_probe_failed");
1540
1545
  }
@@ -1547,7 +1552,7 @@ class Ce extends EventTarget {
1547
1552
  microphoneCount: o,
1548
1553
  cameraCount: r,
1549
1554
  probeLatencyMs: l,
1550
- effectiveConnectionType: ae()?.effectiveType ?? null,
1555
+ effectiveConnectionType: re()?.effectiveType ?? null,
1551
1556
  issues: t
1552
1557
  };
1553
1558
  return this.emit("preflight", d), this.options.autoReportStats && await this.reportQuality({
@@ -1560,7 +1565,7 @@ class Ce extends EventTarget {
1560
1565
  }), d;
1561
1566
  }
1562
1567
  async collectQualitySample(e = "runtime") {
1563
- const t = this.options.statsProvider ? await this.options.statsProvider() : {}, i = this.peerConnection ? await Pe(this.peerConnection, this.previousCounters) : null;
1568
+ const t = this.options.statsProvider ? await this.options.statsProvider() : {}, i = this.peerConnection ? await Le(this.peerConnection, this.previousCounters) : null;
1564
1569
  i?.counters && (this.previousCounters = i.counters);
1565
1570
  const s = { ...{
1566
1571
  sampleType: e,
@@ -1581,6 +1586,10 @@ class Ce extends EventTarget {
1581
1586
  framesPerSecond: null,
1582
1587
  frameWidth: null,
1583
1588
  frameHeight: null,
1589
+ inboundFrameWidth: null,
1590
+ inboundFrameHeight: null,
1591
+ outboundFrameWidth: null,
1592
+ outboundFrameHeight: null,
1584
1593
  framesDropped: null,
1585
1594
  freezeCount: null,
1586
1595
  freezeDurationMs: null,
@@ -1589,9 +1598,9 @@ class Ce extends EventTarget {
1589
1598
  transportProtocol: null,
1590
1599
  candidateType: null,
1591
1600
  qualityLimitationReason: null,
1592
- deviceMemoryGb: Le(),
1593
- effectiveConnectionType: ae()?.effectiveType ?? null
1594
- }, ...i?.sample ?? {}, ...t, sampleType: e, sampledAt: (/* @__PURE__ */ new Date()).toISOString() }, o = Ae(s);
1601
+ deviceMemoryGb: qe(),
1602
+ effectiveConnectionType: re()?.effectiveType ?? null
1603
+ }, ...i?.sample ?? {}, ...t, sampleType: e, sampledAt: (/* @__PURE__ */ new Date()).toISOString() }, o = De(s);
1595
1604
  return s.networkScore = o.networkScore, s.estimatedMos = o.estimatedMos, this.latestQuality = s, s;
1596
1605
  }
1597
1606
  async reportQuality(e) {
@@ -1642,7 +1651,7 @@ class Ce extends EventTarget {
1642
1651
  const i = Date.now(), n = e !== "runtime" || i - this.lastTelemetryAt >= this.options.telemetryInterval;
1643
1652
  this.options.autoReportStats && n && (await this.reportQuality(t), this.lastTelemetryAt = i);
1644
1653
  } catch (t) {
1645
- this.emit("telemetryerror", V(t));
1654
+ this.emit("telemetryerror", x(t));
1646
1655
  } finally {
1647
1656
  this.statsRunning = !1;
1648
1657
  }
@@ -1676,21 +1685,21 @@ class Ce extends EventTarget {
1676
1685
  this.dispatchEvent(new CustomEvent(e, { detail: i })), this.options.onEvent?.(i);
1677
1686
  }
1678
1687
  }
1679
- async function Ue(a) {
1680
- return new Ce(a).initialize();
1688
+ async function Be(a) {
1689
+ return new Ie(a).initialize();
1681
1690
  }
1682
1691
  let U = null;
1683
- function de() {
1692
+ function ue() {
1684
1693
  if (U) return U;
1685
1694
  const a = globalThis, e = a.AudioContext ?? a.webkitAudioContext;
1686
1695
  return e ? (U = new e(), U) : null;
1687
1696
  }
1688
- async function Re() {
1689
- const a = de();
1697
+ async function Ee() {
1698
+ const a = ue();
1690
1699
  return a ? (a.state === "suspended" && await a.resume().catch(() => {
1691
1700
  }), a.state === "running") : !1;
1692
1701
  }
1693
- class Ie {
1702
+ class Me {
1694
1703
  options;
1695
1704
  media = null;
1696
1705
  cadenceTimer = null;
@@ -1699,7 +1708,7 @@ class Ie {
1699
1708
  this.options = e;
1700
1709
  }
1701
1710
  unlock() {
1702
- return Re();
1711
+ return Ee();
1703
1712
  }
1704
1713
  startIncoming() {
1705
1714
  this.start("incoming", this.options.ringtoneUrl);
@@ -1727,7 +1736,7 @@ class Ie {
1727
1736
  i(), this.cadenceTimer = setInterval(i, e === "incoming" ? 3e3 : 3500);
1728
1737
  }
1729
1738
  playBuiltInTone(e) {
1730
- const t = de();
1739
+ const t = ue();
1731
1740
  if (!t || t.state !== "running") return;
1732
1741
  const i = e === "incoming" ? 1.25 : 1, n = e === "incoming" ? [440, 480] : [425], s = t.createGain(), o = t.currentTime;
1733
1742
  s.gain.setValueAtTime(1e-4, o), s.gain.exponentialRampToValueAtTime(0.045, o + 0.025), s.gain.setValueAtTime(0.045, o + i - 0.06), s.gain.exponentialRampToValueAtTime(1e-4, o + i), s.connect(t.destination);
@@ -1737,7 +1746,7 @@ class Ie {
1737
1746
  }
1738
1747
  }
1739
1748
  }
1740
- class Ee extends EventTarget {
1749
+ class Pe extends EventTarget {
1741
1750
  options;
1742
1751
  socket = null;
1743
1752
  stopped = !1;
@@ -1764,14 +1773,14 @@ class Ee extends EventTarget {
1764
1773
  if (e.token && !e.token.startsWith("rtcc_")) throw new Error("A valid RTC client token is required");
1765
1774
  if (!e.signalingUrl && !e.callActionsUrl && !e.apiBaseUrl && !globalThis.location?.origin)
1766
1775
  throw new Error("signalingUrl or callActionsUrl is required outside a browser");
1767
- this.options = e, this.currentToken = e.token ?? null, this.currentTokenExpiresAt = e.tokenExpiresAt, this.callAudio = new Ie(e), this.mount = te(e.mount), this.scheduleTokenRefresh();
1776
+ this.options = e, this.currentToken = e.token ?? null, this.currentTokenExpiresAt = e.tokenExpiresAt, this.callAudio = new Me(e), this.mount = ne(e.mount), this.scheduleTokenRefresh();
1768
1777
  }
1769
1778
  connect() {
1770
1779
  if (!this.options.signalingUrl) throw new Error("signalingUrl is required to connect signaling");
1771
1780
  return this.stopped = !1, this.scheduleTokenRefresh(), this.openSocket("initial"), this;
1772
1781
  }
1773
1782
  setMount(e) {
1774
- this.clearUi(), this.mount = te(e), this.currentCall && this.renderIncoming(this.currentCall);
1783
+ this.clearUi(), this.mount = ne(e), this.currentCall && this.renderIncoming(this.currentCall);
1775
1784
  }
1776
1785
  /** Binds media lifetime to a call. Terminal call states automatically leave and destroy it. */
1777
1786
  attachMediaClient(e, t) {
@@ -1857,7 +1866,7 @@ class Ee extends EventTarget {
1857
1866
  /** Applies a call state received through the application's own push or signaling channel. */
1858
1867
  handleCallUpdate(e) {
1859
1868
  const t = e.id === this.currentCall?.id || e.id === this.outgoingCallId;
1860
- t && e.status === "accepted" ? (this.activeCallIds.add(e.id), this.callAudio.stop(), this.dismiss(e.id)) : t && ["rejected", "busy", "cancelled", "ended", "failed", "missed"].includes(e.status) && this.showTerminal(e.id, Me(e.status)), ["rejected", "busy", "cancelled", "ended", "failed", "missed"].includes(e.status) && this.releaseMedia(e.id), this.emit("callupdated", e);
1869
+ t && e.status === "accepted" ? (this.activeCallIds.add(e.id), this.callAudio.stop(), this.dismiss(e.id)) : t && ["rejected", "busy", "cancelled", "ended", "failed", "missed"].includes(e.status) && this.showTerminal(e.id, Ae(e.status)), ["rejected", "busy", "cancelled", "ended", "failed", "missed"].includes(e.status) && this.releaseMedia(e.id), this.emit("callupdated", e);
1861
1870
  }
1862
1871
  disconnect() {
1863
1872
  this.stopped = !0, this.reconnectTimer && clearTimeout(this.reconnectTimer), this.heartbeatTimer && clearInterval(this.heartbeatTimer), this.tokenRefreshTimer && clearTimeout(this.tokenRefreshTimer), this.reconnectTimer = null, this.heartbeatTimer = null, this.tokenRefreshTimer = null, this.socket?.close(1e3, "Client disconnected"), this.socket = null, this.callAudio.stop(), this.dismiss();
@@ -1873,13 +1882,11 @@ class Ee extends EventTarget {
1873
1882
  try {
1874
1883
  t = await this.resolveToken(e, e === "reconnect");
1875
1884
  } catch (s) {
1876
- this.emit("tokenerror", V(s)), !this.stopped && this.options.reconnect !== !1 && this.scheduleReconnect();
1885
+ this.emit("tokenerror", x(s)), !this.stopped && this.options.reconnect !== !1 && this.scheduleReconnect();
1877
1886
  return;
1878
1887
  }
1879
1888
  if (this.stopped || this.socket) return;
1880
- const i = new URL(this.options.signalingUrl, globalThis.location?.href);
1881
- i.protocol = i.protocol === "https:" ? "wss:" : "ws:";
1882
- const n = new WebSocket(i, ["rtc-client", t]);
1889
+ const i = $(this.options.signalingUrl, globalThis.location?.href), n = new WebSocket(i, ["rtc-client", t]);
1883
1890
  this.socket = n, n.addEventListener("open", () => {
1884
1891
  const s = this.reconnectAttempt > 0, o = this.lastDisconnect;
1885
1892
  this.reconnectAttempt = 0, this.heartbeatDeadline = Date.now() + 45e3, this.emit("signalingconnected", { resumed: s }), o && (this.reportSignalingDiagnostic({ event: "recovered", code: o.code, reason: o.reason, wasClean: o.wasClean, outageMs: Date.now() - o.at }), this.lastDisconnect = null), this.heartbeatTimer && clearInterval(this.heartbeatTimer), this.heartbeatTimer = setInterval(() => {
@@ -1937,7 +1944,7 @@ class Ee extends EventTarget {
1937
1944
  async request(e, t, i = !1) {
1938
1945
  const n = this.options.callActionsUrl ?? this.options.apiBaseUrl ?? this.options.signalingUrl ?? globalThis.location?.origin;
1939
1946
  if (!n) throw new Error("callActionsUrl is required for call actions");
1940
- const s = new URL(n, globalThis.location?.href), o = await this.resolveToken("initial"), r = new Headers(t.headers);
1947
+ const s = J(n, globalThis.location?.href), o = await this.resolveToken("initial"), r = new Headers(t.headers);
1941
1948
  r.set("authorization", `Bearer ${o}`), r.set("content-type", "application/json");
1942
1949
  const c = await fetch(new URL(e, s.origin), { ...t, headers: r }), l = await c.json().catch(() => ({}));
1943
1950
  if (c.status === 401 && this.options.tokenProvider && !i)
@@ -1969,11 +1976,11 @@ class Ee extends EventTarget {
1969
1976
  n.textContent = e.caller.name, n.style.fontSize = "20px";
1970
1977
  const s = document.createElement("div");
1971
1978
  Object.assign(s.style, { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "10px" });
1972
- const o = ie("Decline", "#fff", "#a32920", "#d9a09b"), r = ie("Answer", "#fff", "#08745f", "#08745f");
1979
+ const o = ae("Decline", "#fff", "#a32920", "#d9a09b"), r = ae("Answer", "#fff", "#08745f", "#08745f");
1973
1980
  o.addEventListener("click", () => {
1974
- this.reject(e.id).catch((c) => this.emit("error", V(c)));
1981
+ this.reject(e.id).catch((c) => this.emit("error", x(c)));
1975
1982
  }), r.addEventListener("click", () => {
1976
- this.accept(e.id).catch((c) => this.emit("error", V(c)));
1983
+ this.accept(e.id).catch((c) => this.emit("error", x(c)));
1977
1984
  }), s.appendChild(o), s.appendChild(r), t.appendChild(i), t.appendChild(n), t.appendChild(s), this.mount.replaceChildren(t);
1978
1985
  }
1979
1986
  dismiss(e) {
@@ -2041,7 +2048,7 @@ class Ee extends EventTarget {
2041
2048
  const t = Math.max(0, e - this.refreshSkew(e));
2042
2049
  this.tokenRefreshTimer = setTimeout(() => {
2043
2050
  this.tokenRefreshTimer = null, this.resolveToken("expiring", !0).catch((i) => {
2044
- this.emit("tokenerror", V(i)), this.stopped || (this.tokenRefreshTimer = setTimeout(() => this.scheduleTokenRefresh(), 3e4));
2051
+ this.emit("tokenerror", x(i)), this.stopped || (this.tokenRefreshTimer = setTimeout(() => this.scheduleTokenRefresh(), 3e4));
2045
2052
  });
2046
2053
  }, Math.min(t, 2147e6));
2047
2054
  }
@@ -2055,21 +2062,21 @@ class Ee extends EventTarget {
2055
2062
  this.options.reportSignalingDiagnostics === !1 || this.stopped || this.request("/v1/rtc/client/signaling-events", {
2056
2063
  method: "POST",
2057
2064
  body: JSON.stringify({ ...e, occurredAt: (/* @__PURE__ */ new Date()).toISOString() })
2058
- }).catch((t) => this.emit("diagnosticserror", V(t)));
2065
+ }).catch((t) => this.emit("diagnosticserror", x(t)));
2059
2066
  }
2060
2067
  emit(e, t) {
2061
2068
  const i = { type: e, detail: t, timestamp: (/* @__PURE__ */ new Date()).toISOString() };
2062
2069
  this.dispatchEvent(new CustomEvent(e, { detail: i })), this.options.onEvent?.(i);
2063
2070
  }
2064
2071
  }
2065
- function Qe(a) {
2066
- const e = new Ee(a);
2072
+ function Fe(a) {
2073
+ const e = new Pe(a);
2067
2074
  return a.autoConnect !== !1 && a.signalingUrl && e.connect(), e;
2068
2075
  }
2069
- function te(a) {
2076
+ function ne(a) {
2070
2077
  return a ? typeof a == "string" ? document.querySelector(a) : a : null;
2071
2078
  }
2072
- function ie(a, e, t, i) {
2079
+ function ae(a, e, t, i) {
2073
2080
  const n = document.createElement("button");
2074
2081
  return n.type = "button", n.textContent = a, Object.assign(n.style, {
2075
2082
  minHeight: "44px",
@@ -2082,7 +2089,7 @@ function ie(a, e, t, i) {
2082
2089
  fontWeight: "700"
2083
2090
  }), n;
2084
2091
  }
2085
- function Me(a) {
2092
+ function Ae(a) {
2086
2093
  return {
2087
2094
  rejected: "Call declined",
2088
2095
  busy: "Line busy",
@@ -2092,102 +2099,106 @@ function Me(a) {
2092
2099
  missed: "No answer"
2093
2100
  }[a] ?? "Call ended";
2094
2101
  }
2095
- function ne(a) {
2102
+ function se(a) {
2096
2103
  return {
2097
2104
  id: a.participantId,
2098
2105
  name: a.displayName,
2099
2106
  role: "participant"
2100
2107
  };
2101
2108
  }
2102
- async function Pe(a, e) {
2109
+ async function Le(a, e) {
2103
2110
  const t = await a.getStats(), i = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
2104
- let s = 0, o = 0, r = 0, c = 0, l = 0, d = 0, u = 0, S = 0, f = 0, v = 0, I = 0, y = 0, k = 0, p = null, C = null, P = null, L = null, E = null, A = null;
2111
+ let s = 0, o = 0, r = 0, c = 0, l = 0, d = 0, u = 0, k = 0, f = 0, v = 0, C = 0, y = 0, w = 0, p = 0, R = 0, P = null, L = null, I = null, A = null, S = null, E = null;
2105
2112
  t.forEach((g) => {
2106
2113
  n.set(g.id, g), g.type === "codec" && i.set(g.id, String(g.mimeType ?? ""));
2107
2114
  }), t.forEach((g) => {
2108
- if (g.type === "inbound-rtp" && !g.isRemote && (s += Number(g.bytesReceived ?? 0), r += Math.max(0, Number(g.packetsLost ?? 0)), c += Math.max(0, Number(g.packetsReceived ?? 0)), Number.isFinite(g.jitter) && (l += Number(g.jitter), d += 1), u = Math.max(u, Number(g.framesPerSecond ?? 0)), S = Math.max(S, Number(g.frameWidth ?? 0)), f = Math.max(f, Number(g.frameHeight ?? 0)), v += Number(g.framesDropped ?? 0), I += Number(g.freezeCount ?? 0), y += Number(g.totalFreezesDuration ?? 0), k += Number(g.concealedSamples ?? 0), E ||= i.get(String(g.codecId ?? "")) ?? null), g.type === "outbound-rtp" && !g.isRemote && (o += Number(g.bytesSent ?? 0), A ||= g.qualityLimitationReason ? String(g.qualityLimitationReason) : null, E ||= i.get(String(g.codecId ?? "")) ?? null), g.type === "candidate-pair" && (g.selected || g.nominated) && g.state === "succeeded") {
2109
- p = Number.isFinite(g.currentRoundTripTime) ? Number(g.currentRoundTripTime) : p, C = Number.isFinite(g.availableOutgoingBitrate) ? Number(g.availableOutgoingBitrate) : C;
2115
+ if (g.type === "inbound-rtp" && !g.isRemote && (s += Number(g.bytesReceived ?? 0), r += Math.max(0, Number(g.packetsLost ?? 0)), c += Math.max(0, Number(g.packetsReceived ?? 0)), Number.isFinite(g.jitter) && (l += Number(g.jitter), d += 1), u = Math.max(u, Number(g.framesPerSecond ?? 0)), k = Math.max(k, Number(g.frameWidth ?? 0)), C = Math.max(C, Number(g.frameHeight ?? 0)), y += Number(g.framesDropped ?? 0), w += Number(g.freezeCount ?? 0), p += Number(g.totalFreezesDuration ?? 0), R += Number(g.concealedSamples ?? 0), S ||= i.get(String(g.codecId ?? "")) ?? null), g.type === "outbound-rtp" && !g.isRemote && (f = Math.max(f, Number(g.frameWidth ?? 0)), v = Math.max(v, Number(g.frameHeight ?? 0)), o += Number(g.bytesSent ?? 0), E ||= g.qualityLimitationReason ? String(g.qualityLimitationReason) : null, S ||= i.get(String(g.codecId ?? "")) ?? null), g.type === "candidate-pair" && (g.selected || g.nominated) && g.state === "succeeded") {
2116
+ P = Number.isFinite(g.currentRoundTripTime) ? Number(g.currentRoundTripTime) : P, L = Number.isFinite(g.availableOutgoingBitrate) ? Number(g.availableOutgoingBitrate) : L;
2110
2117
  const q = n.get(g.localCandidateId);
2111
- P = q?.candidateType ? String(q.candidateType) : P, L = q?.protocol ? String(q.protocol) : L;
2118
+ I = q?.candidateType ? String(q.candidateType) : I, A = q?.protocol ? String(q.protocol) : A;
2112
2119
  }
2113
2120
  });
2114
- const w = Date.now(), M = e ? Math.max(1e-3, (w - e.timestamp) / 1e3) : 0, m = e ? Math.max(0, Math.round((s - e.inboundBytes) * 8 / M)) : null, h = e ? Math.max(0, Math.round((o - e.outboundBytes) * 8 / M)) : null, T = r + c, R = e ? Math.max(0, r - e.packetsLost) : r, b = e ? Math.max(0, c - e.packetsReceived) : c, O = R + b;
2121
+ const m = Date.now(), h = e ? Math.max(1e-3, (m - e.timestamp) / 1e3) : 0, T = e ? Math.max(0, Math.round((s - e.inboundBytes) * 8 / h)) : null, M = e ? Math.max(0, Math.round((o - e.outboundBytes) * 8 / h)) : null, b = r + c, O = e ? Math.max(0, r - e.packetsLost) : r, V = e ? Math.max(0, c - e.packetsReceived) : c, N = O + V;
2115
2122
  return {
2116
- counters: { timestamp: w, inboundBytes: s, outboundBytes: o, packetsLost: r, packetsReceived: c },
2123
+ counters: { timestamp: m, inboundBytes: s, outboundBytes: o, packetsLost: r, packetsReceived: c },
2117
2124
  sample: {
2118
- rttMs: p === null ? null : p * 1e3,
2125
+ rttMs: P === null ? null : P * 1e3,
2119
2126
  jitterMs: d ? l / d * 1e3 : null,
2120
- packetLossPct: O ? R / O * 100 : null,
2121
- packetLossCumulativePct: T ? r / T * 100 : null,
2127
+ packetLossPct: N ? O / N * 100 : null,
2128
+ packetLossCumulativePct: b ? r / b * 100 : null,
2122
2129
  packetsLost: r,
2123
2130
  packetsReceived: c,
2124
- inboundBitrateBps: m,
2125
- outboundBitrateBps: h,
2126
- availableOutgoingBitrateBps: C,
2131
+ inboundBitrateBps: T,
2132
+ outboundBitrateBps: M,
2133
+ availableOutgoingBitrateBps: L,
2127
2134
  framesPerSecond: u || null,
2128
- frameWidth: S || null,
2129
- frameHeight: f || null,
2130
- framesDropped: v,
2131
- freezeCount: I,
2132
- freezeDurationMs: Math.round(y * 1e3),
2133
- concealedSamples: k,
2134
- codec: E,
2135
- transportProtocol: L,
2136
- candidateType: P,
2137
- qualityLimitationReason: A
2135
+ frameWidth: k || null,
2136
+ frameHeight: C || null,
2137
+ inboundFrameWidth: k || null,
2138
+ inboundFrameHeight: C || null,
2139
+ outboundFrameWidth: f || null,
2140
+ outboundFrameHeight: v || null,
2141
+ framesDropped: y,
2142
+ freezeCount: w,
2143
+ freezeDurationMs: Math.round(p * 1e3),
2144
+ concealedSamples: R,
2145
+ codec: S,
2146
+ transportProtocol: A,
2147
+ candidateType: I,
2148
+ qualityLimitationReason: E
2138
2149
  }
2139
2150
  };
2140
2151
  }
2141
- function Ae(a) {
2142
- let e = a.mediaScore == null ? 5 : Math.round(se(Number(a.mediaScore), 0, 5));
2143
- const t = H(a.packetLossPct) ?? 0, i = H(a.rttMs) ?? 0, n = H(a.jitterMs) ?? 0, s = String(a.connectionState ?? "unknown").toLowerCase();
2152
+ function De(a) {
2153
+ let e = a.mediaScore == null ? 5 : Math.round(oe(Number(a.mediaScore), 0, 5));
2154
+ const t = W(a.packetLossPct) ?? 0, i = W(a.rttMs) ?? 0, n = W(a.jitterMs) ?? 0, s = String(a.connectionState ?? "unknown").toLowerCase();
2144
2155
  ["failed", "closed", "disconnected"].includes(s) ? e = 0 : ["reconnecting", "checking"].includes(s) && (e = Math.min(e, 2)), t >= 15 ? e = Math.min(e, 0) : t >= 8 ? e = Math.min(e, 1) : t >= 3 ? e = Math.min(e, 2) : t >= 1 && (e = Math.min(e, 3)), i >= 1200 ? e = Math.min(e, 0) : i >= 800 ? e = Math.min(e, 1) : i >= 400 ? e = Math.min(e, 2) : i >= 250 && (e = Math.min(e, 3)), n >= 150 ? e = Math.min(e, 1) : n >= 80 ? e = Math.min(e, 2) : n >= 40 && (e = Math.min(e, 3));
2145
- const o = Number(se(4.5 - t * 0.09 - i * 11e-4 - n * 6e-3, 1, 4.5).toFixed(2));
2156
+ const o = Number(oe(4.5 - t * 0.09 - i * 11e-4 - n * 6e-3, 1, 4.5).toFixed(2));
2146
2157
  return { networkScore: e, estimatedMos: o };
2147
2158
  }
2148
- function ae() {
2159
+ function re() {
2149
2160
  return navigator.connection ?? null;
2150
2161
  }
2151
- function Le() {
2162
+ function qe() {
2152
2163
  const a = Number(navigator.deviceMemory);
2153
2164
  return Number.isFinite(a) ? a : null;
2154
2165
  }
2155
- function H(a) {
2166
+ function W(a) {
2156
2167
  const e = Number(a);
2157
2168
  return Number.isFinite(e) ? e : null;
2158
2169
  }
2159
- function se(a, e, t) {
2170
+ function oe(a, e, t) {
2160
2171
  return Math.min(t, Math.max(e, a));
2161
2172
  }
2162
- function V(a) {
2173
+ function x(a) {
2163
2174
  return a instanceof Error ? { name: a.name, message: a.message } : { name: "ServiceError", message: String(a ?? "Service request failed") };
2164
2175
  }
2165
- function re(a, e) {
2176
+ function ce(a, e) {
2166
2177
  return a instanceof Error ? a : new Error(e);
2167
2178
  }
2168
- const De = "1.3.20";
2179
+ const Oe = "1.3.22";
2169
2180
  export {
2170
- Z as AVATAR_TUNING_DEFAULTS,
2171
- Se as BACKGROUND_PRESETS,
2172
- ke as OVERLAY_EFFECTS,
2173
- Ce as RtcClient,
2174
- Ee as RtcIncomingClient,
2175
- qe as SPEAKER_NOISE_FLOOR,
2176
- Oe as SPEAKER_TAKEOVER_RATIO,
2177
- xe as createAvatarPipeline,
2178
- je as createCallRecorder,
2179
- Ne as createPictureInPictureController,
2180
- Ue as createRtcClient,
2181
- Qe as createRtcIncomingClient,
2182
- Ve as createVideoEffectsPipeline,
2183
- be as drawAvatar,
2184
- we as headPoseFromMatrix,
2185
- le as neutralRig,
2186
- oe as pickActiveSpeaker,
2187
- Te as rigFromBlendshapes,
2188
- K as scenePainters,
2189
- X as smoothRig,
2190
- ee as stylizedAvatarRenderer,
2191
- Re as unlockRtcCallAudio,
2192
- De as version
2181
+ te as AVATAR_TUNING_DEFAULTS,
2182
+ we as BACKGROUND_PRESETS,
2183
+ Te as OVERLAY_EFFECTS,
2184
+ Ie as RtcClient,
2185
+ Pe as RtcIncomingClient,
2186
+ Ne as SPEAKER_NOISE_FLOOR,
2187
+ je as SPEAKER_TAKEOVER_RATIO,
2188
+ Qe as createAvatarPipeline,
2189
+ Ve as createCallRecorder,
2190
+ xe as createPictureInPictureController,
2191
+ Be as createRtcClient,
2192
+ Fe as createRtcIncomingClient,
2193
+ Ue as createVideoEffectsPipeline,
2194
+ Re as drawAvatar,
2195
+ be as headPoseFromMatrix,
2196
+ he as neutralRig,
2197
+ le as pickActiveSpeaker,
2198
+ Ce as rigFromBlendshapes,
2199
+ Z as scenePainters,
2200
+ ee as smoothRig,
2201
+ ie as stylizedAvatarRenderer,
2202
+ Ee as unlockRtcCallAudio,
2203
+ Oe as version
2193
2204
  };