@streaming-cdn/rtc-web 1.3.23 → 1.3.25

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 Ne = 0.02, Oe = 1.4;
2
- function le(a, e, t = 0.02, i = 1.4) {
1
+ const at = 0.02, st = 1.4;
2
+ function ge(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 de(a) {
8
+ function ye(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 de(a) {
14
14
  }
15
15
  return e;
16
16
  }
17
- const O = {
17
+ const V = {
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
- }, me = {
22
+ }, Re = {
23
23
  warmupSamples: 3,
24
24
  poorSamplesToStepDown: 2,
25
25
  goodSamplesToStepUp: 6,
@@ -30,31 +30,31 @@ const O = {
30
30
  goodLossPct: 1,
31
31
  goodRttMs: 250,
32
32
  sustainRatio: 0.8,
33
- bandwidthHeadroomRatio: 1.25
33
+ bandwidthSustainRatio: 0.7
34
34
  };
35
- function pe(a) {
35
+ function Ie(a) {
36
36
  const e = String(a ?? "").trim().toLowerCase();
37
37
  return !e || e === "none" ? "" : e === "cpu" || e === "bandwidth" ? e : "other";
38
38
  }
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 = O[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, E = R ? t + 1 : 0, A = L ? i + 1 : 0, S = { quality: a, poorSamples: E, 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 } : E >= 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;
39
+ function Pe(a, e, t, i, n = {}) {
40
+ const s = { ...Re, ...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, v = Ie(e.qualityLimitationReason), p = e.packetLossPct ?? 0, S = e.rttMs ?? 0, T = e.availableOutgoingBitrateBps, y = V[a].maxBitrate, k = p >= s.criticalLossPct || S >= s.criticalRttMs || v === "cpu", f = v === "bandwidth" && (T == null || T < y * s.bandwidthSustainRatio), M = k || p >= s.poorLossPct || S >= s.poorRttMs || f, R = l < o.length - 1 ? V[o[l + 1]].maxBitrate : null, L = v === "bandwidth" && T != null && R != null && T >= R * s.bandwidthSustainRatio, P = T == null || T >= y * s.sustainRatio, A = p < s.goodLossPct && S < s.goodRttMs && (!v || L) && P, w = M ? t + 1 : 0, E = A ? i + 1 : 0, m = { quality: a, poorSamples: w, goodSamples: E, samplesSeen: d, changed: !1 };
41
+ return l > c ? { quality: o[c], poorSamples: 0, goodSamples: 0, samplesSeen: d, changed: !0 } : u ? m : k && l > 0 ? { quality: o[l - 1], poorSamples: 0, goodSamples: 0, samplesSeen: d, changed: !0 } : w >= 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 } : m;
42
42
  }
43
- function ge(a, e) {
43
+ function Ae(a, e) {
44
44
  const t = a instanceof Map ? a : new Map(a);
45
45
  let i = 0, n = 0, s = null, o = null, r = null;
46
46
  for (const d of t.values()) {
47
47
  const u = String(d.type ?? "");
48
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") {
49
49
  n += Number(d.packetsLost ?? 0);
50
- const k = Number(d.roundTripTime ?? NaN);
51
- Number.isFinite(k) && (o = k * 1e3);
50
+ const v = Number(d.roundTripTime ?? NaN);
51
+ Number.isFinite(v) && (o = v * 1e3);
52
52
  }
53
53
  if (u === "candidate-pair" && (d.nominated === !0 || String(d.state ?? "") === "succeeded")) {
54
- const k = Number(d.currentRoundTripTime ?? NaN);
55
- o == null && Number.isFinite(k) && (o = k * 1e3);
56
- const f = Number(d.availableOutgoingBitrate ?? NaN);
57
- Number.isFinite(f) && (r = f);
54
+ const v = Number(d.currentRoundTripTime ?? NaN);
55
+ o == null && Number.isFinite(v) && (o = v * 1e3);
56
+ const p = Number(d.availableOutgoingBitrate ?? NaN);
57
+ Number.isFinite(p) && (r = p);
58
58
  }
59
59
  }
60
60
  const c = { packetsSent: i, packetsLost: n, timestamp: Date.now() };
@@ -68,18 +68,18 @@ function ge(a, e) {
68
68
  counters: c
69
69
  };
70
70
  }
71
- function $(a, e) {
71
+ function X(a, e) {
72
72
  const t = new URL(String(a), e);
73
73
  return t.protocol === "https:" ? t.protocol = "wss:" : t.protocol === "http:" && (t.protocol = "ws:"), t;
74
74
  }
75
- function J(a, e) {
75
+ function Z(a, e) {
76
76
  const t = new URL(String(a), e);
77
77
  return t.protocol === "wss:" ? t.protocol = "https:" : t.protocol === "ws:" && (t.protocol = "http:"), t;
78
78
  }
79
- const ye = {
79
+ const Le = {
80
80
  audio: { active: !1, maxBitrate: 0, maxFramerate: 0, scaleResolutionDownBy: 4 }
81
- }, ve = { active: !0, maxBitrate: 4e6, maxFramerate: 30, scaleResolutionDownBy: 1 };
82
- class Q {
81
+ }, De = { active: !0, maxBitrate: 4e6, maxFramerate: 30, scaleResolutionDownBy: 1 };
82
+ class F {
83
83
  options;
84
84
  socket = null;
85
85
  localStream = null;
@@ -177,7 +177,7 @@ class Q {
177
177
  this.quality = e;
178
178
  for (const t of this.localStream?.getVideoTracks() ?? []) t.enabled = e !== "audio";
179
179
  for (const t of this.peers.values())
180
- t.quality = Q.clampToCeiling(t.quality, e), t.poorSamples = 0, t.goodSamples = 0;
180
+ t.quality = F.clampToCeiling(t.quality, e), t.poorSamples = 0, t.goodSamples = 0;
181
181
  await this.applyVideoQuality();
182
182
  }
183
183
  static clampToCeiling(e, t) {
@@ -221,7 +221,7 @@ class Q {
221
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);
222
222
  }
223
223
  async openSocket(e) {
224
- const { credential: t } = this.options, i = $(t.signalingUrl, globalThis.location?.href), n = new Promise((c, l) => {
224
+ const { credential: t } = this.options, i = X(t.signalingUrl, globalThis.location?.href), n = new Promise((c, l) => {
225
225
  this.resolveJoin = c, this.rejectJoin = l;
226
226
  }), s = new WebSocket(i, ["rtc-client", t.signalingToken]), o = ++this.socketGeneration;
227
227
  this.socket = s;
@@ -320,7 +320,7 @@ class Q {
320
320
  makingOffer: !1,
321
321
  offerTask: null,
322
322
  activeNegotiationId: null,
323
- quality: Q.startingQuality(this.quality),
323
+ quality: F.startingQuality(this.quality),
324
324
  poorSamples: 0,
325
325
  goodSamples: 0,
326
326
  samplesSeen: 0,
@@ -358,7 +358,7 @@ class Q {
358
358
  });
359
359
  if (e.connection.signalingState !== "stable") return;
360
360
  await e.connection.setLocalDescription(t);
361
- const i = G();
361
+ const i = ie();
362
362
  e.activeNegotiationId = i, this.send({
363
363
  type: "rtc.offer",
364
364
  targetParticipantId: e.identity.participantId,
@@ -398,7 +398,7 @@ class Q {
398
398
  async applyPeerVideoQuality(e) {
399
399
  const t = this.screenStream?.getVideoTracks()[0]?.id;
400
400
  for (const i of e.connection.getSenders().filter((n) => n.track?.kind === "video")) {
401
- const n = !!(t && i.track?.id === t), s = n ? ve : this.quality === "audio" ? ye.audio : O[e.quality], o = i.getParameters(), r = o.encodings?.length ? o.encodings : [{}];
401
+ const n = !!(t && i.track?.id === t), s = n ? De : this.quality === "audio" ? Le.audio : V[e.quality], o = i.getParameters(), r = o.encodings?.length ? o.encodings : [{}];
402
402
  o.encodings = r.map((c) => ({ ...c, ...s })), o.degradationPreference = n ? "maintain-resolution" : "maintain-framerate", await i.setParameters(o);
403
403
  }
404
404
  }
@@ -418,11 +418,11 @@ class Q {
418
418
  if (i.connection.connectionState === "connected")
419
419
  try {
420
420
  const n = await i.connection.getStats();
421
- for (const s of de(n.values()))
421
+ for (const s of ye(n.values()))
422
422
  e.push({ participantId: i.identity.participantId, level: s.level });
423
423
  } catch {
424
424
  }
425
- const t = le(e, this.activeSpeaker);
425
+ const t = ge(e, this.activeSpeaker);
426
426
  t !== this.activeSpeaker && (this.activeSpeaker = t, this.options.onEvent("activespeaker", { participantId: t }));
427
427
  }
428
428
  async samplePeerQuality() {
@@ -435,9 +435,9 @@ class Q {
435
435
  } catch {
436
436
  continue;
437
437
  }
438
- const { sample: i, counters: n } = ge(t, e.counters);
438
+ const { sample: i, counters: n } = Ae(t, e.counters);
439
439
  e.counters = n;
440
- const s = fe(e.quality, i, e.poorSamples, e.goodSamples, {
440
+ const s = Pe(e.quality, i, e.poorSamples, e.goodSamples, {
441
441
  samplesSeen: e.samplesSeen,
442
442
  ceiling: this.quality
443
443
  });
@@ -494,7 +494,7 @@ class Q {
494
494
  }
495
495
  send(e) {
496
496
  this.socket?.readyState === WebSocket.OPEN && this.socket.send(JSON.stringify({
497
- clientMessageId: e.clientMessageId ?? G(),
497
+ clientMessageId: e.clientMessageId ?? ie(),
498
498
  ...e
499
499
  }));
500
500
  }
@@ -502,15 +502,15 @@ class Q {
502
502
  for (const t of e?.getTracks() ?? []) t.stop();
503
503
  }
504
504
  }
505
- function G() {
505
+ function ie() {
506
506
  return globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
507
507
  }
508
- const H = { active: !0, maxBitrate: 4e6, maxFramerate: 30, scaleResolutionDownBy: 1 }, K = [
509
- { rid: "a", maxBitrate: O.high.maxBitrate, maxFramerate: O.high.maxFramerate },
510
- { rid: "b", maxBitrate: O.medium.maxBitrate, maxFramerate: O.medium.maxFramerate, scaleResolutionDownBy: 2 },
511
- { rid: "c", maxBitrate: O.low.maxBitrate, maxFramerate: O.low.maxFramerate, scaleResolutionDownBy: 4 }
512
- ], X = { high: "a", medium: "b", low: "c" };
513
- class Se {
508
+ const J = { active: !0, maxBitrate: 4e6, maxFramerate: 30, scaleResolutionDownBy: 1 }, ne = [
509
+ { rid: "a", maxBitrate: V.high.maxBitrate, maxFramerate: V.high.maxFramerate },
510
+ { rid: "b", maxBitrate: V.medium.maxBitrate, maxFramerate: V.medium.maxFramerate, scaleResolutionDownBy: 2 },
511
+ { rid: "c", maxBitrate: V.low.maxBitrate, maxFramerate: V.low.maxFramerate, scaleResolutionDownBy: 4 }
512
+ ], ae = { high: "a", medium: "b", low: "c" };
513
+ class xe {
514
514
  options;
515
515
  apiBase;
516
516
  socket = null;
@@ -542,7 +542,7 @@ class Se {
542
542
  negotiationQueue = Promise.resolve();
543
543
  socketGeneration = 0;
544
544
  constructor(e) {
545
- this.options = e, this.localStream = e.localStream ?? null, this.quality = e.quality ?? "high", this.apiBase = J(e.credential.signalingUrl, globalThis.location?.href).origin;
545
+ this.options = e, this.localStream = e.localStream ?? null, this.quality = e.quality ?? "high", this.apiBase = Z(e.credential.signalingUrl, globalThis.location?.href).origin;
546
546
  }
547
547
  async initialize() {
548
548
  if (!globalThis.RTCPeerConnection || !globalThis.WebSocket)
@@ -643,7 +643,7 @@ class Se {
643
643
  }
644
644
  // --- signaling -----------------------------------------------------------
645
645
  async openSocket(e) {
646
- const { credential: t } = this.options, i = $(t.signalingUrl, globalThis.location?.href), n = new Promise((c, l) => {
646
+ const { credential: t } = this.options, i = X(t.signalingUrl, globalThis.location?.href), n = new Promise((c, l) => {
647
647
  this.resolveJoin = c, this.rejectJoin = l;
648
648
  }), s = new WebSocket(i, ["rtc-client", t.signalingToken]), o = ++this.socketGeneration;
649
649
  this.socket = s;
@@ -726,7 +726,7 @@ class Se {
726
726
  // A single encoding when simulcast is off: constrained publishers
727
727
  // (phone CPU, cellular uplink) should not pay for three encoders. The
728
728
  // quality ladder then adapts that one encoding instead of gating layers.
729
- ...r.kind === "video" && this.simulcastEnabled() ? { sendEncodings: K.map((c) => ({ ...c })) } : {}
729
+ ...r.kind === "video" && this.simulcastEnabled() ? { sendEncodings: ne.map((c) => ({ ...c })) } : {}
730
730
  })), s = await t.createOffer();
731
731
  await t.setLocalDescription(s);
732
732
  const o = await this.sfuFetch(
@@ -826,7 +826,7 @@ class Se {
826
826
  n && await this.sfuFetch("PUT", `/v1/rtc/sfu/sessions/${encodeURIComponent(this.sessionId)}/tracks/update`, {
827
827
  tracks: [{
828
828
  mid: n,
829
- simulcast: { preferredRid: X[t], priorityOrdering: "asciibetical", ridNotAvailable: "asciibetical" }
829
+ simulcast: { preferredRid: ae[t], priorityOrdering: "asciibetical", ridNotAvailable: "asciibetical" }
830
830
  }]
831
831
  });
832
832
  }
@@ -841,15 +841,15 @@ class Se {
841
841
  if (!e) return;
842
842
  const t = this.screenStream?.getVideoTracks()[0]?.id, i = !!(t && e.track?.id === t), n = e.getParameters(), s = n.encodings?.length ? n.encodings : [{}];
843
843
  if (s.length > 1) {
844
- const o = this.quality === "audio" ? null : X[this.quality];
844
+ const o = this.quality === "audio" ? null : ae[this.quality];
845
845
  n.encodings = s.map((r) => {
846
846
  if (i)
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;
847
+ return { ...r, active: r.rid === "a", ...r.rid === "a" ? { maxBitrate: J.maxBitrate, maxFramerate: J.maxFramerate } : {} };
848
+ const c = ne.find((d) => d.rid === r.rid), l = o != null && String(r.rid ?? "") >= o;
849
849
  return { ...r, ...c ?? {}, active: l };
850
850
  });
851
851
  } else {
852
- const o = this.quality === "audio" ? O.audio : O[this.quality], r = i ? H : o;
852
+ const o = this.quality === "audio" ? V.audio : V[this.quality], r = i ? J : o;
853
853
  n.encodings = s.map((c) => ({ ...c, ...r }));
854
854
  }
855
855
  n.degradationPreference = i ? "maintain-resolution" : "maintain-framerate", await e.setParameters(n);
@@ -916,11 +916,11 @@ class Se {
916
916
  return;
917
917
  }
918
918
  const i = [];
919
- for (const s of de(t.values())) {
919
+ for (const s of ye(t.values())) {
920
920
  const o = s.mid ? this.midToParticipant.get(s.mid) : void 0;
921
921
  o && i.push({ participantId: o, level: s.level });
922
922
  }
923
- const n = le(i, this.activeSpeaker);
923
+ const n = ge(i, this.activeSpeaker);
924
924
  n !== this.activeSpeaker && (this.activeSpeaker = n, this.options.onEvent("activespeaker", { participantId: n }));
925
925
  }
926
926
  clearTimers() {
@@ -937,7 +937,7 @@ class Se {
937
937
  }
938
938
  send(e) {
939
939
  this.socket?.readyState === WebSocket.OPEN && this.socket.send(JSON.stringify({
940
- clientMessageId: e.clientMessageId ?? ke(),
940
+ clientMessageId: e.clientMessageId ?? Ue(),
941
941
  ...e
942
942
  }));
943
943
  }
@@ -945,10 +945,10 @@ class Se {
945
945
  for (const t of e?.getTracks() ?? []) t.stop();
946
946
  }
947
947
  }
948
- function ke() {
948
+ function Ue() {
949
949
  return globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
950
950
  }
951
- function je(a, e = {}) {
951
+ function rt(a, e = {}) {
952
952
  const t = e.document ?? globalThis.document, i = !!(t && t.pictureInPictureEnabled);
953
953
  let n = null;
954
954
  function s() {
@@ -976,81 +976,81 @@ function je(a, e = {}) {
976
976
  }
977
977
  };
978
978
  }
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
+ function ot(a, e) {
980
+ const t = e.document ?? globalThis.document, i = e.fetchImplementation ?? globalThis.fetch.bind(globalThis), n = Z(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, v = 0, p = [], S = !1;
982
+ async function T(y, k, f, M = "application/json") {
983
+ const R = await i(`${n}${k}`, {
984
984
  method: y,
985
985
  headers: {
986
986
  authorization: `Bearer ${e.credential.signalingToken}`,
987
- "content-type": R
987
+ "content-type": M
988
988
  },
989
- body: p === void 0 ? void 0 : R === "application/json" ? JSON.stringify(p) : p
989
+ body: f === void 0 ? void 0 : M === "application/json" ? JSON.stringify(f) : f
990
990
  });
991
- if (!P.ok) throw new Error(`Recording request failed with HTTP ${P.status}`);
992
- return P.json();
991
+ if (!R.ok) throw new Error(`Recording request failed with HTTP ${R.status}`);
992
+ return R.json();
993
993
  }
994
994
  return {
995
995
  get recording() {
996
- return v;
996
+ return S;
997
997
  },
998
998
  async start() {
999
- if (v) return;
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;
999
+ if (S) return;
1000
+ u = (await T("POST", "/v1/rtc/recordings")).recordingId;
1001
+ const k = t.createElement("canvas");
1002
+ k.width = r, k.height = o;
1003
+ const f = k.getContext("2d"), M = /* @__PURE__ */ new Map(), R = (b, I) => {
1004
+ let C = M.get(b);
1005
+ return C || (C = t.createElement("video"), C.muted = !0, C.playsInline = !0, C.srcObject = I, C.play().catch(() => {
1006
+ }), M.set(b, C)), C;
1007
1007
  };
1008
1008
  l = setInterval(() => {
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" }] : []
1009
+ const b = a.getRemoteStreams(), I = a.getLocalStream(), C = [
1010
+ ...b.map((U) => ({ key: U.participant.participantId, stream: U.stream, label: U.participant.displayName })),
1011
+ ...I ? [{ key: "local", stream: I, label: "me" }] : []
1012
1012
  ];
1013
- p.fillStyle = "#101418", p.fillRect(0, 0, r, o);
1014
- const x = Math.max(1, Math.ceil(Math.sqrt(b.length))), V = Math.max(1, Math.ceil(b.length / x)), N = r / x, g = o / V;
1015
- b.forEach((q, _) => {
1016
- const Y = P(q.key, q.stream), B = _ % x * N, F = Math.floor(_ / x) * 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
+ f.fillStyle = "#101418", f.fillRect(0, 0, r, o);
1014
+ const N = Math.max(1, Math.ceil(Math.sqrt(C.length))), Q = Math.max(1, Math.ceil(C.length / N)), O = r / N, g = o / Q;
1015
+ C.forEach((U, ee) => {
1016
+ const te = R(U.key, U.stream), $ = ee % N * O, W = Math.floor(ee / N) * g;
1017
+ te.videoWidth > 0 && f.drawImage(te, $ + 2, W + 2, O - 4, g - 4), f.fillStyle = "rgba(0,0,0,.6)", f.fillRect($ + 8, W + g - 30, Math.min(O - 16, 12 + U.label.length * 9), 22), f.fillStyle = "#fff", f.font = "14px system-ui", f.fillText(U.label, $ + 14, W + g - 14);
1018
1018
  });
1019
1019
  }, 66);
1020
- const L = w.captureStream(15);
1020
+ const L = k.captureStream(15);
1021
1021
  d = new AudioContext();
1022
- const E = d.createMediaStreamDestination(), A = /* @__PURE__ */ new Set(), S = () => {
1023
- const T = [
1024
- ...a.getRemoteStreams().map((M) => M.stream),
1022
+ const P = d.createMediaStreamDestination(), A = /* @__PURE__ */ new Set(), w = () => {
1023
+ const b = [
1024
+ ...a.getRemoteStreams().map((I) => I.stream),
1025
1025
  ...a.getLocalStream() ? [a.getLocalStream()] : []
1026
1026
  ];
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(E));
1027
+ for (const I of b)
1028
+ for (const C of I.getAudioTracks())
1029
+ A.has(C.id) || (A.add(C.id), d.createMediaStreamSource(new MediaStream([C])).connect(P));
1030
1030
  };
1031
- S();
1032
- const I = setInterval(S, 1e3), m = () => clearInterval(I);
1033
- for (const T of E.stream.getAudioTracks()) L.addTrack(T);
1034
- c = (e.mediaRecorderFactory ?? ((T, M) => new MediaRecorder(T, M)))(L, { mimeType: s }), f = [], c.addEventListener("dataavailable", (T) => {
1035
- T.data && T.data.size > 0 && f.push(T.data);
1036
- }), c.addEventListener("stop", m), c.start(1e3), k = Date.now(), v = !0;
1031
+ w();
1032
+ const E = setInterval(w, 1e3), m = () => clearInterval(E);
1033
+ for (const b of P.stream.getAudioTracks()) L.addTrack(b);
1034
+ c = (e.mediaRecorderFactory ?? ((b, I) => new MediaRecorder(b, I)))(L, { mimeType: s }), p = [], c.addEventListener("dataavailable", (b) => {
1035
+ b.data && b.data.size > 0 && p.push(b.data);
1036
+ }), c.addEventListener("stop", m), c.start(1e3), v = Date.now(), S = !0;
1037
1037
  },
1038
1038
  async stop() {
1039
- if (!v || !c || !u) throw new Error("The recorder is not running");
1040
- v = !1;
1041
- const y = c, w = new Promise((E) => y.addEventListener("stop", () => E(), { once: !0 }));
1042
- y.stop(), await w, l && clearInterval(l), l = null, await d?.close().catch(() => {
1039
+ if (!S || !c || !u) throw new Error("The recorder is not running");
1040
+ S = !1;
1041
+ const y = c, k = new Promise((P) => y.addEventListener("stop", () => P(), { once: !0 }));
1042
+ y.stop(), await k, l && clearInterval(l), l = null, await d?.close().catch(() => {
1043
1043
  }), d = null;
1044
- const p = new Blob(f, { type: s });
1045
- f = [];
1046
- const R = Math.max(1, Math.round((Date.now() - k) / 1e3)), P = await C(
1044
+ const f = new Blob(p, { type: s });
1045
+ p = [];
1046
+ const M = Math.max(1, Math.round((Date.now() - v) / 1e3)), R = await T(
1047
1047
  "PUT",
1048
1048
  `/v1/rtc/recordings/${encodeURIComponent(u)}/media`,
1049
- p,
1049
+ f,
1050
1050
  s
1051
1051
  );
1052
- await C("POST", `/v1/rtc/recordings/${encodeURIComponent(u)}/complete`, { durationSeconds: R });
1053
- const L = { recordingId: u, sizeBytes: P.sizeBytes, durationSeconds: R };
1052
+ await T("POST", `/v1/rtc/recordings/${encodeURIComponent(u)}/complete`, { durationSeconds: M });
1053
+ const L = { recordingId: u, sizeBytes: R.sizeBytes, durationSeconds: M };
1054
1054
  return u = null, c = null, L;
1055
1055
  },
1056
1056
  dispose() {
@@ -1060,11 +1060,11 @@ function Ve(a, e) {
1060
1060
  } catch {
1061
1061
  }
1062
1062
  c = null, d?.close().catch(() => {
1063
- }), d = null, v = !1;
1063
+ }), d = null, S = !1;
1064
1064
  }
1065
1065
  };
1066
1066
  }
1067
- const we = ["none", "blur", "aurora", "cybergrid", "bokeh", "sunset", "image"], Te = ["none", "snow", "confetti", "vignette"], Z = {
1067
+ const Ne = ["none", "blur", "aurora", "cybergrid", "bokeh", "sunset", "image"], qe = ["none", "snow", "confetti", "vignette"], se = {
1068
1068
  aurora(a, e, t, i) {
1069
1069
  const n = a.createLinearGradient(0, 0, 0, t);
1070
1070
  n.addColorStop(0, "#050b1e"), n.addColorStop(1, "#0b2540"), a.fillStyle = n, a.fillRect(0, 0, e, t);
@@ -1101,20 +1101,20 @@ const we = ["none", "blur", "aurora", "cybergrid", "bokeh", "sunset", "image"],
1101
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);
1102
1102
  }
1103
1103
  };
1104
- function Ue(a, e = {}) {
1104
+ function ct(a, e = {}) {
1105
1105
  const t = e.document ?? globalThis.document;
1106
1106
  let i = e.width ?? 1280, n = e.height ?? 720;
1107
1107
  const s = !!(e.width || e.height), o = e.frameRate ?? 24, r = a instanceof MediaStreamTrack ? a : a.getVideoTracks()[0];
1108
1108
  if (!r) throw new Error("A video track is required");
1109
- let c = e.background ?? "none", l = e.overlay ?? "none", d = e.backgroundImage ?? null, u = e.segmenter ?? null, k = null, f = !1;
1110
- const v = t.createElement("video");
1111
- v.muted = !0, v.playsInline = !0, v.srcObject = new MediaStream([r]), v.play().catch(() => {
1109
+ let c = e.background ?? "none", l = e.overlay ?? "none", d = e.backgroundImage ?? null, u = e.segmenter ?? null, v = null, p = !1;
1110
+ const S = t.createElement("video");
1111
+ S.muted = !0, S.playsInline = !0, S.srcObject = new MediaStream([r]), S.play().catch(() => {
1112
1112
  });
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
+ const T = t.createElement("canvas");
1114
+ T.width = i, T.height = n;
1115
+ const y = T.getContext("2d"), k = t.createElement("canvas");
1116
+ k.width = i, k.height = n;
1117
+ const f = k.getContext("2d"), M = () => Array.from({ length: 80 }, (m, h) => ({
1118
1118
  x: (Math.sin(h * 12.9898) * 0.5 + 0.5) * i,
1119
1119
  y: (Math.sin(h * 78.233) * 0.5 + 0.5) * n,
1120
1120
  speed: 0.6 + h % 5 * 0.5,
@@ -1122,61 +1122,61 @@ function Ue(a, e = {}) {
1122
1122
  size: 2 + h % 4,
1123
1123
  hue: h * 47 % 360
1124
1124
  }));
1125
- let P = R();
1125
+ let R = M();
1126
1126
  const L = () => {
1127
1127
  if (s) return;
1128
- const m = v.videoWidth, h = v.videoHeight;
1128
+ const m = S.videoWidth, h = S.videoHeight;
1129
1129
  if (!m || !h) return;
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());
1130
+ const b = Math.min(1, 1280 / Math.max(m, h)), I = Math.round(m * b), C = Math.round(h * b);
1131
+ I === i && C === n || (i = I, n = C, T.width = i, T.height = n, k.width = i, k.height = n, R = M());
1132
1132
  };
1133
- v.addEventListener?.("loadedmetadata", L), v.addEventListener?.("resize", L);
1134
- function E() {
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);
1133
+ S.addEventListener?.("loadedmetadata", L), S.addEventListener?.("resize", L);
1134
+ function P() {
1135
+ if (v) {
1136
+ f.clearRect(0, 0, i, n), f.drawImage(v, 0, 0, i, n), f.globalCompositeOperation = "source-in", f.drawImage(S, 0, 0, i, n), f.globalCompositeOperation = "source-over", y.drawImage(k, 0, 0);
1137
1137
  return;
1138
1138
  }
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();
1139
+ const m = i * 0.42, h = m * 9 / 16, b = i - m - 24, I = n - h - 24;
1140
+ y.save(), y.shadowColor = "rgba(0,0,0,.5)", y.shadowBlur = 24, y.beginPath(), y.roundRect(b, I, m, h, 14), y.clip(), y.drawImage(S, b, I, m, h), y.restore();
1141
1141
  }
1142
1142
  function A(m) {
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 && E()) : c === "image" && d ? (y.drawImage(d, 0, 0, i, n), E()) : ((Z[c] ?? Z.aurora)(y, i, n, m), E()), l === "snow" || l === "confetti")
1144
- for (const h of P)
1143
+ if (c === "none" ? y.drawImage(S, 0, 0, i, n) : c === "blur" ? (y.filter = "blur(14px)", y.drawImage(S, -16, -16, i + 32, n + 32), y.filter = "none", v && P()) : c === "image" && d ? (y.drawImage(d, 0, 0, i, n), P()) : ((se[c] ?? se.aurora)(y, i, n, m), P()), l === "snow" || l === "confetti")
1144
+ for (const h of R)
1145
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());
1146
1146
  else if (l === "vignette") {
1147
1147
  const h = y.createRadialGradient(i / 2, n / 2, n * 0.4, i / 2, n / 2, n * 0.85);
1148
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);
1149
1149
  }
1150
1150
  }
1151
- const S = setInterval(() => {
1152
- A(Date.now()), u && !f && c !== "none" && (f = !0, u.segment(v).then((m) => {
1153
- k = m;
1151
+ const w = setInterval(() => {
1152
+ A(Date.now()), u && !p && c !== "none" && (p = !0, u.segment(S).then((m) => {
1153
+ v = m;
1154
1154
  }).catch(() => {
1155
- k = null;
1155
+ v = null;
1156
1156
  }).finally(() => {
1157
- f = !1;
1157
+ p = !1;
1158
1158
  }));
1159
- }, Math.round(1e3 / o)), I = C.captureStream(o);
1159
+ }, Math.round(1e3 / o)), E = T.captureStream(o);
1160
1160
  return {
1161
- track: I.getVideoTracks()[0],
1162
- stream: I,
1161
+ track: E.getVideoTracks()[0],
1162
+ stream: E,
1163
1163
  setBackground(m, h) {
1164
- c = we.includes(m) ? m : "none", h !== void 0 && (d = h), c === "none" && (k = null);
1164
+ c = Ne.includes(m) ? m : "none", h !== void 0 && (d = h), c === "none" && (v = null);
1165
1165
  },
1166
1166
  setOverlay(m) {
1167
- l = Te.includes(m) ? m : "none";
1167
+ l = qe.includes(m) ? m : "none";
1168
1168
  },
1169
1169
  setSegmenter(m) {
1170
- u = m, m || (k = null);
1170
+ u = m, m || (v = null);
1171
1171
  },
1172
1172
  dispose() {
1173
- clearInterval(S), u?.close?.();
1174
- for (const m of I.getTracks()) m.stop();
1175
- v.srcObject = null;
1173
+ clearInterval(w), u?.close?.();
1174
+ for (const m of E.getTracks()) m.stop();
1175
+ S.srcObject = null;
1176
1176
  }
1177
1177
  };
1178
1178
  }
1179
- function he() {
1179
+ function ve() {
1180
1180
  return {
1181
1181
  blinkLeft: 0,
1182
1182
  blinkRight: 0,
@@ -1195,18 +1195,18 @@ function D(a, e) {
1195
1195
  const t = a.find((i) => i.categoryName === e);
1196
1196
  return t ? Math.max(0, Math.min(1, t.score)) : 0;
1197
1197
  }
1198
- function be(a) {
1198
+ function Oe(a) {
1199
1199
  if (!a || a.length < 16) return { yaw: 0, pitch: 0, roll: 0 };
1200
1200
  a[0], a[4];
1201
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);
1202
1202
  return { yaw: o, pitch: r, roll: c };
1203
1203
  }
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;
1204
+ function Ve(a, e, t = 1) {
1205
+ if (!a || a.length === 0) return ve();
1206
+ const i = Oe(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"), v = Math.min(1, Math.abs(i.yaw) / 0.35) * Math.max(0, Math.min(1, t)), p = (d + u) / 2;
1207
1207
  return {
1208
- blinkLeft: d + (f - d) * k,
1209
- blinkRight: u + (f - u) * k,
1208
+ blinkLeft: d + (p - d) * v,
1209
+ blinkRight: u + (p - u) * v,
1210
1210
  jawOpen: D(a, "jawOpen"),
1211
1211
  smile: c - l,
1212
1212
  browUp: (D(a, "browInnerUp") + D(a, "browOuterUpLeft") + D(a, "browOuterUpRight")) / 3,
@@ -1218,7 +1218,7 @@ function Ce(a, e, t = 1) {
1218
1218
  tracked: !0
1219
1219
  };
1220
1220
  }
1221
- function ee(a, e, t = 0.4) {
1221
+ function re(a, e, t = 0.4) {
1222
1222
  const i = (n, s) => n + (s - n) * t;
1223
1223
  return {
1224
1224
  blinkLeft: i(a.blinkLeft, e.blinkLeft),
@@ -1234,36 +1234,36 @@ function ee(a, e, t = 0.4) {
1234
1234
  tracked: e.tracked
1235
1235
  };
1236
1236
  }
1237
- function Re(a, e, t, i, n) {
1237
+ function je(a, e, t, i, n) {
1238
1238
  n || (a.fillStyle = "#101822", a.fillRect(0, 0, t, i));
1239
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;
1240
1240
  a.save(), a.translate(s, o), a.rotate(e.headRoll * 0.6);
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;
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();
1243
- const v = 0;
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, v = (A) => Math.cos(A + c), p = Math.sin(l) * r * 0.22;
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 + p * 0.4, r * 0.92, r * 0.5, 0, Math.PI, Math.PI * 2), a.fill();
1243
+ const S = 0;
1244
1244
  a.fillStyle = "#e5b58a", a.beginPath();
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();
1245
+ const T = u(S) * 0.9, y = r * 0.12 + p;
1246
+ a.ellipse(T + d * r * 0.14, y, r * 0.11, r * 0.14, 0, 0, Math.PI * 2), a.fill();
1247
1247
  for (const A of [-1, 1]) {
1248
- const S = A * 0.42, I = k(S);
1249
- if (I <= 0.12) continue;
1250
- const m = u(S) * 0.82, h = Math.max(0.2, I), T = A < 0 ? e.blinkLeft : e.blinkRight, M = Math.max(0.06, 1 - T), b = e.browUp * r * 0.14;
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();
1252
- const x = -r * 0.18 + f;
1253
- a.fillStyle = "#ffffff", a.beginPath(), a.ellipse(m, x, r * 0.16 * h, r * 0.12 * M, 0, 0, Math.PI * 2), a.fill(), a.fillStyle = "#22303c", a.beginPath(), a.ellipse(
1248
+ const w = A * 0.42, E = v(w);
1249
+ if (E <= 0.12) continue;
1250
+ const m = u(w) * 0.82, h = Math.max(0.2, E), b = A < 0 ? e.blinkLeft : e.blinkRight, I = Math.max(0.06, 1 - b), C = e.browUp * r * 0.14;
1251
+ a.strokeStyle = "#4a2e18", a.lineWidth = r * 0.07, a.lineCap = "round", a.beginPath(), a.moveTo(m - r * 0.2 * h, -r * 0.42 - C + p), a.quadraticCurveTo(m, -r * 0.52 - C + p, m + r * 0.2 * h, -r * 0.44 - C + p), a.stroke();
1252
+ const N = -r * 0.18 + p;
1253
+ a.fillStyle = "#ffffff", a.beginPath(), a.ellipse(m, N, r * 0.16 * h, r * 0.12 * I, 0, 0, Math.PI * 2), a.fill(), a.fillStyle = "#22303c", a.beginPath(), a.ellipse(
1254
1254
  m + e.pupilX * r * 0.07 * h,
1255
- x + e.pupilY * r * 0.05,
1255
+ N + e.pupilY * r * 0.05,
1256
1256
  r * 0.06 * h,
1257
- r * 0.06 * M,
1257
+ r * 0.06 * I,
1258
1258
  0,
1259
1259
  0,
1260
1260
  Math.PI * 2
1261
1261
  ), a.fill();
1262
1262
  }
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, E = r * 0.42 + f;
1264
- a.fillStyle = "#8c2f2f", a.beginPath(), a.moveTo(p - R / 2, E - L), a.quadraticCurveTo(p, E + P, p + R / 2, E - L), a.quadraticCurveTo(p, E - P * 0.25, p - R / 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 k = Math.max(0.25, v(0)), f = u(0) * 0.7, M = r * 0.55 * k, R = r * (0.04 + e.jawOpen * 0.34), L = e.smile * r * 0.12, P = r * 0.42 + p;
1264
+ a.fillStyle = "#8c2f2f", a.beginPath(), a.moveTo(f - M / 2, P - L), a.quadraticCurveTo(f, P + R, f + M / 2, P - L), a.quadraticCurveTo(f, P - R * 0.25, f - M / 2, P - 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");
1265
1265
  }
1266
- const te = {
1266
+ const oe = {
1267
1267
  mouthGain: 1.7,
1268
1268
  blinkGain: 1,
1269
1269
  eyeSync: 1,
@@ -1272,82 +1272,303 @@ const te = {
1272
1272
  avatarLift: 0,
1273
1273
  lostHoldMs: 400
1274
1274
  };
1275
- function ie() {
1275
+ function ce() {
1276
1276
  return {
1277
1277
  render(a, e, t, i, n) {
1278
- Re(a, e, t, i, n ?? void 0);
1278
+ je(a, e, t, i, n ?? void 0);
1279
1279
  }
1280
1280
  };
1281
1281
  }
1282
- const z = (a) => Math.max(0, Math.min(1, a));
1283
- function Qe(a, e = {}) {
1282
+ const G = (a) => Math.max(0, Math.min(1, a));
1283
+ function lt(a, e = {}) {
1284
1284
  const t = e.document ?? globalThis.document;
1285
1285
  let i = e.width ?? 1280, n = e.height ?? 720;
1286
1286
  const s = !!(e.width || e.height), o = e.frameRate ?? 24, r = a instanceof MediaStreamTrack ? a : a.getVideoTracks()[0];
1287
1287
  if (!r) throw new Error("A video track is required");
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");
1290
- f.muted = !0, f.playsInline = !0, f.srcObject = new MediaStream([r]), f.play().catch(() => {
1288
+ let c = e.tracker ?? null, l = e.renderer ?? ce(), d = e.mode ?? "replace";
1289
+ const u = { ...oe, ...e.tuning }, v = e.backdrop ?? "#101822", p = t.createElement("video");
1290
+ p.muted = !0, p.playsInline = !0, p.srcObject = new MediaStream([r]), p.play().catch(() => {
1291
1291
  });
1292
- const v = t.createElement("canvas");
1293
- v.width = i, v.height = n;
1294
- const C = v.getContext("2d"), y = () => {
1292
+ const S = t.createElement("canvas");
1293
+ S.width = i, S.height = n;
1294
+ const T = S.getContext("2d"), y = () => {
1295
1295
  if (s) return;
1296
- const S = f.videoWidth, I = f.videoHeight;
1297
- if (!S || !I) return;
1298
- const m = Math.min(1, 1280 / Math.max(S, I)), h = Math.round(S * m), T = Math.round(I * m);
1299
- (!(h === i || T === n) || h !== i || T !== n) && (i = h, n = T, v.width = i, v.height = n);
1296
+ const w = p.videoWidth, E = p.videoHeight;
1297
+ if (!w || !E) return;
1298
+ const m = Math.min(1, 1280 / Math.max(w, E)), h = Math.round(w * m), b = Math.round(E * m);
1299
+ (!(h === i || b === n) || h !== i || b !== n) && (i = h, n = b, S.width = i, S.height = n);
1300
1300
  };
1301
- f.addEventListener?.("loadedmetadata", y), f.addEventListener?.("resize", y);
1302
- let w = he(), p = null, R = 0;
1303
- function P(S) {
1304
- if (S.length <= 454) return;
1305
- const I = 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, x = Math.hypot((m.x - I.x) * i, (m.y - I.y) * n), V = Math.max(0.6, Math.cos(w.headPitch)), N = { x: M, y: b, radius: Math.max(24, x / 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;
1307
- }
1308
- function L(S) {
1309
- if (c && f.readyState >= 2) {
1301
+ p.addEventListener?.("loadedmetadata", y), p.addEventListener?.("resize", y);
1302
+ let k = ve(), f = null, M = 0;
1303
+ function R(w) {
1304
+ if (w.length <= 454) return;
1305
+ const E = w[10], m = w[152], h = w[234], b = w[454], I = (h.x + b.x) / 2 * i, C = (h.y + b.y) / 2 * n, N = Math.hypot((m.x - E.x) * i, (m.y - E.y) * n), Q = Math.max(0.6, Math.cos(k.headPitch)), O = { x: I, y: C, radius: Math.max(24, N / Q * 0.8) };
1306
+ f = f ? { x: f.x + (O.x - f.x) * 0.4, y: f.y + (O.y - f.y) * 0.4, radius: f.radius + (O.radius - f.radius) * 0.15 } : O;
1307
+ }
1308
+ function L(w) {
1309
+ if (c && p.readyState >= 2) {
1310
1310
  let m = null;
1311
1311
  try {
1312
- m = c.detect(f, S);
1312
+ m = c.detect(p, w);
1313
1313
  } catch {
1314
1314
  }
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));
1315
+ const h = Ve(m?.categories ?? null, m?.matrix ?? null, u.eyeSync);
1316
+ h.jawOpen = G(h.jawOpen * u.mouthGain), h.blinkLeft = G(h.blinkLeft * u.blinkGain), h.blinkRight = G(h.blinkRight * u.blinkGain), h.tracked ? (M = w, k = re(k, h, u.smoothing), m?.landmarks && R(m.landmarks)) : k.tracked && w - M > u.lostHoldMs && (k = re(k, { ...k, jawOpen: 0, browUp: 0, smile: k.smile * 0.5, blinkLeft: 0.1, blinkRight: 0.1 }, 0.05));
1317
1317
  }
1318
- d === "overlay" && f.readyState >= 2 ? C.drawImage(f, 0, 0, i, n) : (C.fillStyle = k, C.fillRect(0, 0, i, n));
1319
- const I = p ? { x: p.x, y: p.y + u.avatarLift * p.radius, radius: p.radius * u.avatarScale } : null;
1320
- l?.render(C, w, i, n, I);
1318
+ d === "overlay" && p.readyState >= 2 ? T.drawImage(p, 0, 0, i, n) : (T.fillStyle = v, T.fillRect(0, 0, i, n));
1319
+ const E = f ? { x: f.x, y: f.y + u.avatarLift * f.radius, radius: f.radius * u.avatarScale } : null;
1320
+ l?.render(T, k, i, n, E);
1321
1321
  }
1322
- const E = setInterval(() => L(Date.now()), Math.round(1e3 / o)), A = v.captureStream(o);
1322
+ const P = setInterval(() => L(Date.now()), Math.round(1e3 / o)), A = S.captureStream(o);
1323
1323
  return {
1324
1324
  track: A.getVideoTracks()[0],
1325
1325
  stream: A,
1326
- getRig: () => ({ ...w }),
1327
- setMode(S) {
1328
- d = S === "overlay" ? "overlay" : "replace";
1326
+ getRig: () => ({ ...k }),
1327
+ setMode(w) {
1328
+ d = w === "overlay" ? "overlay" : "replace";
1329
1329
  },
1330
- setTracker(S) {
1331
- c?.close?.(), c = S;
1330
+ setTracker(w) {
1331
+ c?.close?.(), c = w;
1332
1332
  },
1333
- setRenderer(S) {
1334
- l?.dispose?.(), l = S ?? ie();
1333
+ setRenderer(w) {
1334
+ l?.dispose?.(), l = w ?? ce();
1335
1335
  },
1336
- setTuning(S) {
1337
- for (const I of Object.keys(te)) {
1338
- const m = S[I];
1339
- typeof m == "number" && Number.isFinite(m) && (u[I] = m);
1336
+ setTuning(w) {
1337
+ for (const E of Object.keys(oe)) {
1338
+ const m = w[E];
1339
+ typeof m == "number" && Number.isFinite(m) && (u[E] = m);
1340
1340
  }
1341
1341
  },
1342
1342
  getTuning: () => ({ ...u }),
1343
1343
  dispose() {
1344
- clearInterval(E), c?.close?.(), l?.dispose?.();
1345
- for (const S of A.getTracks()) S.stop();
1346
- f.srcObject = null;
1344
+ clearInterval(P), c?.close?.(), l?.dispose?.();
1345
+ for (const w of A.getTracks()) w.stop();
1346
+ p.srcObject = null;
1347
+ }
1348
+ };
1349
+ }
1350
+ class j extends Error {
1351
+ constructor(e, t) {
1352
+ super(t), this.code = e, this.name = "ZipError";
1353
+ }
1354
+ code;
1355
+ }
1356
+ const Se = 101010256, we = 33639248, ke = 67324752, K = 4294967295;
1357
+ function Te(a) {
1358
+ if (a.byteLength < 4) return !1;
1359
+ const e = new DataView(a).getUint32(0, !0);
1360
+ return e === ke || e === we || e === Se;
1361
+ }
1362
+ function Be(a) {
1363
+ const e = Math.max(0, a.byteLength - 22 - 65535);
1364
+ for (let t = a.byteLength - 22; t >= e; t -= 1)
1365
+ if (a.getUint32(t, !0) === Se) return t;
1366
+ throw new j("zip_unreadable", "The archive index could not be found.");
1367
+ }
1368
+ function be(a) {
1369
+ const e = new DataView(a), t = Be(e), i = e.getUint16(t + 10, !0);
1370
+ let n = e.getUint32(t + 16, !0);
1371
+ if (n === K) throw new j("zip_unsupported", "ZIP64 archives are not supported.");
1372
+ const s = new TextDecoder(), o = [];
1373
+ for (let r = 0; r < i; r += 1) {
1374
+ if (n + 46 > a.byteLength || e.getUint32(n, !0) !== we)
1375
+ throw new j("zip_unreadable", "The archive index is malformed.");
1376
+ const c = e.getUint16(n + 8, !0), l = e.getUint16(n + 10, !0), d = e.getUint32(n + 20, !0), u = e.getUint32(n + 24, !0), v = e.getUint16(n + 28, !0), p = e.getUint16(n + 30, !0), S = e.getUint16(n + 32, !0), T = e.getUint32(n + 42, !0), y = s.decode(new Uint8Array(a, n + 46, v));
1377
+ o.push({
1378
+ path: y,
1379
+ bytes: u,
1380
+ compressedBytes: d,
1381
+ compressionMethod: l,
1382
+ encrypted: (c & 1) !== 0,
1383
+ localHeaderOffset: T
1384
+ }), n += 46 + v + p + S;
1385
+ }
1386
+ return o;
1387
+ }
1388
+ async function Qe(a, e) {
1389
+ if (e.encrypted) throw new j("zip_encrypted", "The archive is password protected.");
1390
+ if (e.bytes === K || e.compressedBytes === K)
1391
+ throw new j("zip_unsupported", "ZIP64 archives are not supported.");
1392
+ const t = new DataView(a), i = e.localHeaderOffset;
1393
+ if (i + 30 > a.byteLength || t.getUint32(i, !0) !== ke)
1394
+ throw new j("zip_unreadable", "An archive entry header is malformed.");
1395
+ const n = t.getUint16(i + 26, !0), s = t.getUint16(i + 28, !0), o = i + 30 + n + s;
1396
+ if (o + e.compressedBytes > a.byteLength)
1397
+ throw new j("zip_unreadable", "An archive entry runs past the end of the file.");
1398
+ const r = a.slice(o, o + e.compressedBytes);
1399
+ if (e.compressionMethod === 0) return r;
1400
+ if (e.compressionMethod !== 8)
1401
+ throw new j("zip_unsupported", `Archive compression method ${e.compressionMethod} is not supported.`);
1402
+ if (typeof DecompressionStream > "u")
1403
+ throw new j("zip_unsupported", "This browser cannot expand compressed archives.");
1404
+ const c = new Blob([r]).stream().pipeThrough(new DecompressionStream("deflate-raw"));
1405
+ return new Response(c).arrayBuffer();
1406
+ }
1407
+ async function dt(a) {
1408
+ const e = typeof File < "u" && a instanceof File ? await a.arrayBuffer() : a;
1409
+ if (!Te(e)) return [];
1410
+ try {
1411
+ return Ce(be(e)).map((t) => t.path);
1412
+ } catch {
1413
+ return [];
1414
+ }
1415
+ }
1416
+ const _e = 64 * 1024 * 1024, Fe = "streaming-cdn-avatars", z = "models", ze = 1179937895, He = 1313821514;
1417
+ class x extends Error {
1418
+ constructor(e, t, i = []) {
1419
+ super(t), this.code = e, this.name = "AvatarModelError", this.choices = i;
1420
+ }
1421
+ code;
1422
+ /**
1423
+ * The characters found inside an archive. Set only for
1424
+ * "archive_many_models", so the caller can ask which one to import and pass
1425
+ * it back as importAvatarModel's entryPath.
1426
+ */
1427
+ choices;
1428
+ }
1429
+ function Ce(a) {
1430
+ return a.filter((e) => /\.vrm$/i.test(e.path) && !e.path.endsWith("/") && !e.path.split("/").some((t) => t === "__MACOSX" || t.startsWith("._")));
1431
+ }
1432
+ function q(a) {
1433
+ const e = typeof a == "string" ? a.trim() : "";
1434
+ return e.length > 0 ? e : null;
1435
+ }
1436
+ function $e(a) {
1437
+ const e = new DataView(a);
1438
+ if (a.byteLength < 20 || e.getUint32(0, !0) !== ze)
1439
+ throw new x("model_not_glb", "The file is not a binary glTF (.vrm / .glb) model.");
1440
+ let t = 12, i = null;
1441
+ for (; t + 8 <= a.byteLength; ) {
1442
+ const r = e.getUint32(t, !0), c = e.getUint32(t + 4, !0), l = t + 8;
1443
+ if (l + r > a.byteLength) break;
1444
+ if (c === He) {
1445
+ try {
1446
+ const d = new TextDecoder().decode(new Uint8Array(a, l, r)).replace(/[\s\u0000]+$/, "");
1447
+ i = JSON.parse(d);
1448
+ } catch {
1449
+ throw new x("model_unreadable", "The model's glTF descriptor could not be read.");
1450
+ }
1451
+ break;
1347
1452
  }
1453
+ t = l + r + (4 - r % 4) % 4;
1454
+ }
1455
+ const n = i?.extensions ?? {}, s = n.VRM?.meta, o = n.VRMC_vrm?.meta;
1456
+ if (!s && !o) return null;
1457
+ if (o) {
1458
+ const r = Array.isArray(o.authors) ? o.authors.filter((c) => typeof c == "string") : [];
1459
+ return {
1460
+ title: q(o.name),
1461
+ author: r.length ? r.join(", ") : null,
1462
+ allowedUser: q(o.avatarPermission),
1463
+ commercialUse: q(o.commercialUsage),
1464
+ licenseName: q(o.licenseUrl) ? "VRM 1.0" : null,
1465
+ licenseUrl: q(o.licenseUrl) ?? q(o.otherLicenseUrl)
1466
+ };
1467
+ }
1468
+ return {
1469
+ title: q(s?.title),
1470
+ author: q(s?.author),
1471
+ allowedUser: q(s?.allowedUserName),
1472
+ commercialUse: q(s?.commercialUssageName),
1473
+ licenseName: q(s?.licenseName),
1474
+ licenseUrl: q(s?.otherLicenseUrl)
1348
1475
  };
1349
1476
  }
1350
- class Ee extends EventTarget {
1477
+ function We() {
1478
+ return new Promise((a, e) => {
1479
+ if (typeof indexedDB > "u") {
1480
+ e(new x("storage_unavailable", "This browser cannot store imported avatar models."));
1481
+ return;
1482
+ }
1483
+ const t = indexedDB.open(Fe, 1);
1484
+ t.onupgradeneeded = () => {
1485
+ t.result.objectStoreNames.contains(z) || t.result.createObjectStore(z, { keyPath: "id" });
1486
+ }, t.onsuccess = () => a(t.result), t.onerror = () => e(new x("storage_unavailable", "Imported avatar storage could not be opened."));
1487
+ });
1488
+ }
1489
+ async function H(a, e) {
1490
+ const t = await We();
1491
+ try {
1492
+ return await new Promise((i, n) => {
1493
+ const s = e(t.transaction(z, a).objectStore(z));
1494
+ s.onsuccess = () => i(s.result), s.onerror = () => n(new x("storage_unavailable", "The imported avatar could not be stored."));
1495
+ });
1496
+ } finally {
1497
+ t.close();
1498
+ }
1499
+ }
1500
+ const Ee = (a) => ({
1501
+ id: a.id,
1502
+ name: a.name,
1503
+ bytes: a.bytes,
1504
+ importedAt: a.importedAt,
1505
+ license: a.license
1506
+ });
1507
+ async function ht(a, e = {}) {
1508
+ const t = e.maxBytes ?? _e, i = typeof File < "u" && a instanceof File;
1509
+ let n = i ? a.name : null, s = i ? await a.arrayBuffer() : a;
1510
+ if (Te(s)) {
1511
+ const l = await Je(s, e.entryPath, t);
1512
+ s = l.buffer, n = l.path.split("/").pop() ?? n;
1513
+ }
1514
+ if (s.byteLength > t)
1515
+ throw new x(
1516
+ "model_too_large",
1517
+ "The model is larger than the " + Math.round(t / 1024 / 1024) + " MB limit."
1518
+ );
1519
+ const o = $e(s);
1520
+ if (!o)
1521
+ throw new x("model_not_vrm", "The file is a glTF model but carries no VRM character data.");
1522
+ const r = o.title || (n ? n.replace(/\.(vrm|glb)$/i, "") : null), c = {
1523
+ id: "avatar_" + Date.now().toString(36) + "_" + Math.random().toString(36).slice(2, 8),
1524
+ name: e.name?.trim() || r || "Imported avatar",
1525
+ bytes: s.byteLength,
1526
+ importedAt: (/* @__PURE__ */ new Date()).toISOString(),
1527
+ license: o,
1528
+ data: s
1529
+ };
1530
+ return await H("readwrite", (l) => l.put(c)), Ee(c);
1531
+ }
1532
+ async function Je(a, e, t) {
1533
+ let i;
1534
+ try {
1535
+ i = Ce(be(a));
1536
+ } catch (s) {
1537
+ throw s instanceof j ? new x(le(s.code), s.message) : new x("archive_unreadable", "The archive could not be read.");
1538
+ }
1539
+ if (i.length === 0)
1540
+ throw new x("archive_no_model", "The archive contains no .vrm character.");
1541
+ const n = e ? i.find((s) => s.path === e) : i.length === 1 ? i[0] : null;
1542
+ if (!n)
1543
+ throw new x(
1544
+ "archive_many_models",
1545
+ "The archive contains several characters; choose one.",
1546
+ i.map((s) => s.path)
1547
+ );
1548
+ if (n.bytes > t)
1549
+ throw new x(
1550
+ "model_too_large",
1551
+ "The character inside the archive is larger than the " + Math.round(t / 1024 / 1024) + " MB limit."
1552
+ );
1553
+ try {
1554
+ return { buffer: await Qe(a, n), path: n.path };
1555
+ } catch (s) {
1556
+ throw s instanceof j ? new x(le(s.code), s.message) : new x("archive_unreadable", "The character could not be expanded from the archive.");
1557
+ }
1558
+ }
1559
+ function le(a) {
1560
+ return a === "zip_encrypted" ? "archive_encrypted" : a === "zip_unsupported" ? "archive_unsupported" : "archive_unreadable";
1561
+ }
1562
+ async function ut() {
1563
+ return (await H("readonly", (e) => e.getAll()) ?? []).map(Ee).sort((e, t) => t.importedAt.localeCompare(e.importedAt));
1564
+ }
1565
+ async function mt(a) {
1566
+ return (await H("readonly", (t) => t.get(a)))?.data ?? null;
1567
+ }
1568
+ async function pt(a) {
1569
+ await H("readwrite", (e) => e.delete(a));
1570
+ }
1571
+ class Ge extends EventTarget {
1351
1572
  mode;
1352
1573
  options;
1353
1574
  client = null;
@@ -1381,7 +1602,7 @@ class Ee extends EventTarget {
1381
1602
  async initialize() {
1382
1603
  if (this.client) return this;
1383
1604
  try {
1384
- const t = (this.options.transport === "auto" ? this.mode === "meeting" ? "sfu" : "mesh" : this.options.transport ?? "mesh") === "sfu" ? Se : Q;
1605
+ const t = (this.options.transport === "auto" ? this.mode === "meeting" ? "sfu" : "mesh" : this.options.transport ?? "mesh") === "sfu" ? xe : F;
1385
1606
  return this.client = new t({
1386
1607
  credential: {
1387
1608
  signalingToken: this.options.credential.signalingToken,
@@ -1401,19 +1622,19 @@ class Ee extends EventTarget {
1401
1622
  localStream: this.options.localStream,
1402
1623
  simulcast: this.options.simulcast ?? !0,
1403
1624
  onEvent: (i, n) => this.handleNativeEvent(i, n)
1404
- }), await this.client.initialize(), this.startStats(), this.emit("initialized", { mode: this.mode, sdkVersion: xe }), this.options.autoJoin && await this.join(), this;
1625
+ }), await this.client.initialize(), this.startStats(), this.emit("initialized", { mode: this.mode, sdkVersion: nt }), this.options.autoJoin && await this.join(), this;
1405
1626
  } catch (e) {
1406
1627
  this.state = "failed";
1407
- const t = ce(e, "RTC initialization failed");
1408
- throw this.emit("error", j(t)), t;
1628
+ const t = fe(e, "RTC initialization failed");
1629
+ throw this.emit("error", B(t)), t;
1409
1630
  }
1410
1631
  }
1411
1632
  async join() {
1412
1633
  const e = this.requireClient();
1413
1634
  return this.joinPromise ? this.joinPromise : (this.state = "joining", this.emit("joining", {}), this.joinPromise = e.join().catch((t) => {
1414
1635
  this.state = "failed";
1415
- const i = ce(t, "RTC connection failed");
1416
- throw this.emit("error", j(i)), i;
1636
+ const i = fe(t, "RTC connection failed");
1637
+ throw this.emit("error", B(i)), i;
1417
1638
  }).finally(() => {
1418
1639
  this.joinPromise = null;
1419
1640
  }), this.joinPromise);
@@ -1451,14 +1672,14 @@ class Ee extends EventTarget {
1451
1672
  return navigator.mediaDevices?.enumerateDevices ? navigator.mediaDevices.enumerateDevices() : [];
1452
1673
  }
1453
1674
  getParticipants() {
1454
- return this.requireClient().getParticipants().map(se);
1675
+ return this.requireClient().getParticipants().map(ue);
1455
1676
  }
1456
1677
  getLocalStream() {
1457
1678
  return this.client?.getLocalStream() ?? null;
1458
1679
  }
1459
1680
  getRemoteStreams() {
1460
1681
  return (this.client?.getRemoteStreams() ?? []).map((e) => ({
1461
- participant: se(e.participant),
1682
+ participant: ue(e.participant),
1462
1683
  stream: e.stream
1463
1684
  }));
1464
1685
  }
@@ -1527,7 +1748,7 @@ class Ee extends EventTarget {
1527
1748
  let n = "unavailable";
1528
1749
  if (e.requestMedia !== !1 && navigator.mediaDevices?.getUserMedia)
1529
1750
  try {
1530
- (await navigator.mediaDevices.getUserMedia({ audio: this.options.audio, video: this.options.video })).getTracks().forEach((k) => k.stop()), n = "granted";
1751
+ (await navigator.mediaDevices.getUserMedia({ audio: this.options.audio, video: this.options.video })).getTracks().forEach((v) => v.stop()), n = "granted";
1531
1752
  } catch {
1532
1753
  n = "denied", t.push("media_permission_denied");
1533
1754
  }
@@ -1538,8 +1759,8 @@ class Ee extends EventTarget {
1538
1759
  if (c) {
1539
1760
  const u = performance.now();
1540
1761
  try {
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");
1762
+ const v = await fetch(c, { method: "HEAD", cache: "no-store", credentials: "omit" });
1763
+ l = Math.round(performance.now() - u), v.ok || t.push("network_probe_failed");
1543
1764
  } catch {
1544
1765
  t.push("network_probe_failed");
1545
1766
  }
@@ -1552,7 +1773,7 @@ class Ee extends EventTarget {
1552
1773
  microphoneCount: o,
1553
1774
  cameraCount: r,
1554
1775
  probeLatencyMs: l,
1555
- effectiveConnectionType: re()?.effectiveType ?? null,
1776
+ effectiveConnectionType: me()?.effectiveType ?? null,
1556
1777
  issues: t
1557
1778
  };
1558
1779
  return this.emit("preflight", d), this.options.autoReportStats && await this.reportQuality({
@@ -1565,7 +1786,7 @@ class Ee extends EventTarget {
1565
1786
  }), d;
1566
1787
  }
1567
1788
  async collectQualitySample(e = "runtime") {
1568
- const t = this.options.statsProvider ? await this.options.statsProvider() : {}, i = this.peerConnection ? await Le(this.peerConnection, this.previousCounters) : null;
1789
+ const t = this.options.statsProvider ? await this.options.statsProvider() : {}, i = this.peerConnection ? await et(this.peerConnection, this.previousCounters) : null;
1569
1790
  i?.counters && (this.previousCounters = i.counters);
1570
1791
  const s = { ...{
1571
1792
  sampleType: e,
@@ -1598,9 +1819,9 @@ class Ee extends EventTarget {
1598
1819
  transportProtocol: null,
1599
1820
  candidateType: null,
1600
1821
  qualityLimitationReason: null,
1601
- deviceMemoryGb: qe(),
1602
- effectiveConnectionType: re()?.effectiveType ?? null
1603
- }, ...i?.sample ?? {}, ...t, sampleType: e, sampledAt: (/* @__PURE__ */ new Date()).toISOString() }, o = De(s);
1822
+ deviceMemoryGb: it(),
1823
+ effectiveConnectionType: me()?.effectiveType ?? null
1824
+ }, ...i?.sample ?? {}, ...t, sampleType: e, sampledAt: (/* @__PURE__ */ new Date()).toISOString() }, o = tt(s);
1604
1825
  return s.networkScore = o.networkScore, s.estimatedMos = o.estimatedMos, this.latestQuality = s, s;
1605
1826
  }
1606
1827
  async reportQuality(e) {
@@ -1651,7 +1872,7 @@ class Ee extends EventTarget {
1651
1872
  const i = Date.now(), n = e !== "runtime" || i - this.lastTelemetryAt >= this.options.telemetryInterval;
1652
1873
  this.options.autoReportStats && n && (await this.reportQuality(t), this.lastTelemetryAt = i);
1653
1874
  } catch (t) {
1654
- this.emit("telemetryerror", j(t));
1875
+ this.emit("telemetryerror", B(t));
1655
1876
  } finally {
1656
1877
  this.statsRunning = !1;
1657
1878
  }
@@ -1685,21 +1906,21 @@ class Ee extends EventTarget {
1685
1906
  this.dispatchEvent(new CustomEvent(e, { detail: i })), this.options.onEvent?.(i);
1686
1907
  }
1687
1908
  }
1688
- async function Be(a) {
1689
- return new Ee(a).initialize();
1909
+ async function ft(a) {
1910
+ return new Ge(a).initialize();
1690
1911
  }
1691
- let U = null;
1692
- function ue() {
1693
- if (U) return U;
1912
+ let _ = null;
1913
+ function Me() {
1914
+ if (_) return _;
1694
1915
  const a = globalThis, e = a.AudioContext ?? a.webkitAudioContext;
1695
- return e ? (U = new e(), U) : null;
1916
+ return e ? (_ = new e(), _) : null;
1696
1917
  }
1697
- async function Ie() {
1698
- const a = ue();
1918
+ async function Ye() {
1919
+ const a = Me();
1699
1920
  return a ? (a.state === "suspended" && await a.resume().catch(() => {
1700
1921
  }), a.state === "running") : !1;
1701
1922
  }
1702
- class Me {
1923
+ class Ke {
1703
1924
  options;
1704
1925
  media = null;
1705
1926
  cadenceTimer = null;
@@ -1708,7 +1929,7 @@ class Me {
1708
1929
  this.options = e;
1709
1930
  }
1710
1931
  unlock() {
1711
- return Ie();
1932
+ return Ye();
1712
1933
  }
1713
1934
  startIncoming() {
1714
1935
  this.start("incoming", this.options.ringtoneUrl);
@@ -1736,7 +1957,7 @@ class Me {
1736
1957
  i(), this.cadenceTimer = setInterval(i, e === "incoming" ? 3e3 : 3500);
1737
1958
  }
1738
1959
  playBuiltInTone(e) {
1739
- const t = ue();
1960
+ const t = Me();
1740
1961
  if (!t || t.state !== "running") return;
1741
1962
  const i = e === "incoming" ? 1.25 : 1, n = e === "incoming" ? [440, 480] : [425], s = t.createGain(), o = t.currentTime;
1742
1963
  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);
@@ -1746,7 +1967,7 @@ class Me {
1746
1967
  }
1747
1968
  }
1748
1969
  }
1749
- class Pe extends EventTarget {
1970
+ class Xe extends EventTarget {
1750
1971
  options;
1751
1972
  socket = null;
1752
1973
  stopped = !1;
@@ -1774,14 +1995,14 @@ class Pe extends EventTarget {
1774
1995
  if (e.token && !e.token.startsWith("rtcc_")) throw new Error("A valid RTC client token is required");
1775
1996
  if (!e.signalingUrl && !e.callActionsUrl && !e.apiBaseUrl && !globalThis.location?.origin)
1776
1997
  throw new Error("signalingUrl or callActionsUrl is required outside a browser");
1777
- this.options = e, this.currentToken = e.token ?? null, this.currentTokenExpiresAt = e.tokenExpiresAt, this.callAudio = new Me(e), this.mount = ne(e.mount), this.scheduleTokenRefresh();
1998
+ this.options = e, this.currentToken = e.token ?? null, this.currentTokenExpiresAt = e.tokenExpiresAt, this.callAudio = new Ke(e), this.mount = de(e.mount), this.scheduleTokenRefresh();
1778
1999
  }
1779
2000
  connect() {
1780
2001
  if (!this.options.signalingUrl) throw new Error("signalingUrl is required to connect signaling");
1781
2002
  return this.stopped = !1, this.scheduleTokenRefresh(), this.openSocket("initial"), this;
1782
2003
  }
1783
2004
  setMount(e) {
1784
- this.clearUi(), this.mount = ne(e), this.currentCall && this.renderIncoming(this.currentCall);
2005
+ this.clearUi(), this.mount = de(e), this.currentCall && this.renderIncoming(this.currentCall);
1785
2006
  }
1786
2007
  /** Binds media lifetime to a call. Terminal call states automatically leave and destroy it. */
1787
2008
  attachMediaClient(e, t) {
@@ -1892,7 +2113,7 @@ class Pe extends EventTarget {
1892
2113
  /** Applies a call state received through the application's own push or signaling channel. */
1893
2114
  handleCallUpdate(e) {
1894
2115
  const t = e.id === this.currentCall?.id || e.id === this.outgoingCallId, i = ["answered_elsewhere", "rejected", "busy", "cancelled", "ended", "failed", "missed"];
1895
- (e.status === "accepted" || i.includes(e.status)) && this.clearInvitationExpiry(e.id), t && e.status === "accepted" ? (this.activeCallIds.add(e.id), this.callAudio.stop(), this.dismiss(e.id)) : t && i.includes(e.status) && this.showTerminal(e.id, Ae(e.status)), i.includes(e.status) && this.releaseMedia(e.id), this.emit("callupdated", e);
2116
+ (e.status === "accepted" || i.includes(e.status)) && this.clearInvitationExpiry(e.id), t && e.status === "accepted" ? (this.activeCallIds.add(e.id), this.callAudio.stop(), this.dismiss(e.id)) : t && i.includes(e.status) && this.showTerminal(e.id, Ze(e.status)), i.includes(e.status) && this.releaseMedia(e.id), this.emit("callupdated", e);
1896
2117
  }
1897
2118
  disconnect() {
1898
2119
  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();
@@ -1910,11 +2131,11 @@ class Pe extends EventTarget {
1910
2131
  try {
1911
2132
  t = await this.resolveToken(e, e === "reconnect");
1912
2133
  } catch (s) {
1913
- this.emit("tokenerror", j(s)), !this.stopped && this.options.reconnect !== !1 && this.scheduleReconnect();
2134
+ this.emit("tokenerror", B(s)), !this.stopped && this.options.reconnect !== !1 && this.scheduleReconnect();
1914
2135
  return;
1915
2136
  }
1916
2137
  if (this.stopped || this.socket) return;
1917
- const i = $(this.options.signalingUrl, globalThis.location?.href), n = new WebSocket(i, ["rtc-client", t]);
2138
+ const i = X(this.options.signalingUrl, globalThis.location?.href), n = new WebSocket(i, ["rtc-client", t]);
1918
2139
  this.socket = n, n.addEventListener("open", () => {
1919
2140
  const s = this.reconnectAttempt > 0, o = this.lastDisconnect;
1920
2141
  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(() => {
@@ -1958,7 +2179,11 @@ class Pe extends EventTarget {
1958
2179
  }
1959
2180
  if (i === "call.updated") {
1960
2181
  const n = t.call;
1961
- n?.id && n.status && this.handleCallUpdate({ id: n.id, status: n.status });
2182
+ n?.id && n.status && this.handleCallUpdate({
2183
+ id: n.id,
2184
+ status: n.status,
2185
+ actorExternalId: typeof n.actorExternalId == "string" ? n.actorExternalId : null
2186
+ });
1962
2187
  return;
1963
2188
  }
1964
2189
  i === "presence" ? this.emit("presence", { users: t.users ?? [] }) : i !== "pong" && this.emit(i || "signal", t);
@@ -1972,7 +2197,7 @@ class Pe extends EventTarget {
1972
2197
  async request(e, t, i = !1) {
1973
2198
  const n = this.options.callActionsUrl ?? this.options.apiBaseUrl ?? this.options.signalingUrl ?? globalThis.location?.origin;
1974
2199
  if (!n) throw new Error("callActionsUrl is required for call actions");
1975
- const s = J(n, globalThis.location?.href), o = await this.resolveToken("initial"), r = new Headers(t.headers);
2200
+ const s = Z(n, globalThis.location?.href), o = await this.resolveToken("initial"), r = new Headers(t.headers);
1976
2201
  r.set("authorization", `Bearer ${o}`), r.set("content-type", "application/json");
1977
2202
  const c = await fetch(new URL(e, s.origin), { ...t, headers: r }), l = await c.json().catch(() => ({}));
1978
2203
  if (c.status === 401 && this.options.tokenProvider && !i)
@@ -2004,11 +2229,11 @@ class Pe extends EventTarget {
2004
2229
  n.textContent = e.caller.name, n.style.fontSize = "20px";
2005
2230
  const s = document.createElement("div");
2006
2231
  Object.assign(s.style, { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "10px" });
2007
- const o = ae("Decline", "#fff", "#a32920", "#d9a09b"), r = ae("Answer", "#fff", "#08745f", "#08745f");
2232
+ const o = he("Decline", "#fff", "#a32920", "#d9a09b"), r = he("Answer", "#fff", "#08745f", "#08745f");
2008
2233
  o.addEventListener("click", () => {
2009
- this.reject(e.id).catch((c) => this.emit("error", j(c)));
2234
+ this.reject(e.id).catch((c) => this.emit("error", B(c)));
2010
2235
  }), r.addEventListener("click", () => {
2011
- this.accept(e.id).catch((c) => this.emit("error", j(c)));
2236
+ this.accept(e.id).catch((c) => this.emit("error", B(c)));
2012
2237
  }), s.appendChild(o), s.appendChild(r), t.appendChild(i), t.appendChild(n), t.appendChild(s), this.mount.replaceChildren(t);
2013
2238
  }
2014
2239
  dismiss(e) {
@@ -2076,7 +2301,7 @@ class Pe extends EventTarget {
2076
2301
  const t = Math.max(0, e - this.refreshSkew(e));
2077
2302
  this.tokenRefreshTimer = setTimeout(() => {
2078
2303
  this.tokenRefreshTimer = null, this.resolveToken("expiring", !0).catch((i) => {
2079
- this.emit("tokenerror", j(i)), this.stopped || (this.tokenRefreshTimer = setTimeout(() => this.scheduleTokenRefresh(), 3e4));
2304
+ this.emit("tokenerror", B(i)), this.stopped || (this.tokenRefreshTimer = setTimeout(() => this.scheduleTokenRefresh(), 3e4));
2080
2305
  });
2081
2306
  }, Math.min(t, 2147e6));
2082
2307
  }
@@ -2090,21 +2315,21 @@ class Pe extends EventTarget {
2090
2315
  this.options.reportSignalingDiagnostics === !1 || this.stopped || this.request("/v1/rtc/client/signaling-events", {
2091
2316
  method: "POST",
2092
2317
  body: JSON.stringify({ ...e, occurredAt: (/* @__PURE__ */ new Date()).toISOString() })
2093
- }).catch((t) => this.emit("diagnosticserror", j(t)));
2318
+ }).catch((t) => this.emit("diagnosticserror", B(t)));
2094
2319
  }
2095
2320
  emit(e, t) {
2096
2321
  const i = { type: e, detail: t, timestamp: (/* @__PURE__ */ new Date()).toISOString() };
2097
2322
  this.dispatchEvent(new CustomEvent(e, { detail: i })), this.options.onEvent?.(i);
2098
2323
  }
2099
2324
  }
2100
- function Fe(a) {
2101
- const e = new Pe(a);
2325
+ function gt(a) {
2326
+ const e = new Xe(a);
2102
2327
  return a.autoConnect !== !1 && a.signalingUrl && e.connect(), e;
2103
2328
  }
2104
- function ne(a) {
2329
+ function de(a) {
2105
2330
  return a ? typeof a == "string" ? document.querySelector(a) : a : null;
2106
2331
  }
2107
- function ae(a, e, t, i) {
2332
+ function he(a, e, t, i) {
2108
2333
  const n = document.createElement("button");
2109
2334
  return n.type = "button", n.textContent = a, Object.assign(n.style, {
2110
2335
  minHeight: "44px",
@@ -2117,7 +2342,7 @@ function ae(a, e, t, i) {
2117
2342
  fontWeight: "700"
2118
2343
  }), n;
2119
2344
  }
2120
- function Ae(a) {
2345
+ function Ze(a) {
2121
2346
  return {
2122
2347
  rejected: "Call declined",
2123
2348
  busy: "Line busy",
@@ -2128,106 +2353,114 @@ function Ae(a) {
2128
2353
  answered_elsewhere: "Answered on another device"
2129
2354
  }[a] ?? "Call ended";
2130
2355
  }
2131
- function se(a) {
2356
+ function ue(a) {
2132
2357
  return {
2133
2358
  id: a.participantId,
2134
2359
  name: a.displayName,
2135
2360
  role: "participant"
2136
2361
  };
2137
2362
  }
2138
- async function Le(a, e) {
2363
+ async function et(a, e) {
2139
2364
  const t = await a.getStats(), i = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
2140
- 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, E = null, A = null, S = null, I = null;
2365
+ let s = 0, o = 0, r = 0, c = 0, l = 0, d = 0, u = 0, v = 0, p = 0, S = 0, T = 0, y = 0, k = 0, f = 0, M = 0, R = null, L = null, P = null, A = null, w = null, E = null;
2141
2366
  t.forEach((g) => {
2142
2367
  n.set(g.id, g), g.type === "codec" && i.set(g.id, String(g.mimeType ?? ""));
2143
2368
  }), t.forEach((g) => {
2144
- 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), I ||= g.qualityLimitationReason ? String(g.qualityLimitationReason) : null, S ||= i.get(String(g.codecId ?? "")) ?? null), g.type === "candidate-pair" && (g.selected || g.nominated) && g.state === "succeeded") {
2145
- P = Number.isFinite(g.currentRoundTripTime) ? Number(g.currentRoundTripTime) : P, L = Number.isFinite(g.availableOutgoingBitrate) ? Number(g.availableOutgoingBitrate) : L;
2146
- const q = n.get(g.localCandidateId);
2147
- E = q?.candidateType ? String(q.candidateType) : E, A = q?.protocol ? String(q.protocol) : A;
2369
+ 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)), v = Math.max(v, Number(g.frameWidth ?? 0)), T = Math.max(T, Number(g.frameHeight ?? 0)), y += Number(g.framesDropped ?? 0), k += Number(g.freezeCount ?? 0), f += Number(g.totalFreezesDuration ?? 0), M += Number(g.concealedSamples ?? 0), w ||= i.get(String(g.codecId ?? "")) ?? null), g.type === "outbound-rtp" && !g.isRemote && (p = Math.max(p, Number(g.frameWidth ?? 0)), S = Math.max(S, Number(g.frameHeight ?? 0)), o += Number(g.bytesSent ?? 0), E ||= g.qualityLimitationReason ? String(g.qualityLimitationReason) : null, w ||= i.get(String(g.codecId ?? "")) ?? null), g.type === "candidate-pair" && (g.selected || g.nominated) && g.state === "succeeded") {
2370
+ R = Number.isFinite(g.currentRoundTripTime) ? Number(g.currentRoundTripTime) : R, L = Number.isFinite(g.availableOutgoingBitrate) ? Number(g.availableOutgoingBitrate) : L;
2371
+ const U = n.get(g.localCandidateId);
2372
+ P = U?.candidateType ? String(U.candidateType) : P, A = U?.protocol ? String(U.protocol) : A;
2148
2373
  }
2149
2374
  });
2150
- 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, x = e ? Math.max(0, r - e.packetsLost) : r, V = e ? Math.max(0, c - e.packetsReceived) : c, N = x + V;
2375
+ const m = Date.now(), h = e ? Math.max(1e-3, (m - e.timestamp) / 1e3) : 0, b = e ? Math.max(0, Math.round((s - e.inboundBytes) * 8 / h)) : null, I = e ? Math.max(0, Math.round((o - e.outboundBytes) * 8 / h)) : null, C = r + c, N = e ? Math.max(0, r - e.packetsLost) : r, Q = e ? Math.max(0, c - e.packetsReceived) : c, O = N + Q;
2151
2376
  return {
2152
2377
  counters: { timestamp: m, inboundBytes: s, outboundBytes: o, packetsLost: r, packetsReceived: c },
2153
2378
  sample: {
2154
- rttMs: P === null ? null : P * 1e3,
2379
+ rttMs: R === null ? null : R * 1e3,
2155
2380
  jitterMs: d ? l / d * 1e3 : null,
2156
- packetLossPct: N ? x / N * 100 : null,
2157
- packetLossCumulativePct: b ? r / b * 100 : null,
2381
+ packetLossPct: O ? N / O * 100 : null,
2382
+ packetLossCumulativePct: C ? r / C * 100 : null,
2158
2383
  packetsLost: r,
2159
2384
  packetsReceived: c,
2160
- inboundBitrateBps: T,
2161
- outboundBitrateBps: M,
2385
+ inboundBitrateBps: b,
2386
+ outboundBitrateBps: I,
2162
2387
  availableOutgoingBitrateBps: L,
2163
2388
  framesPerSecond: u || null,
2164
- frameWidth: k || null,
2165
- frameHeight: C || null,
2166
- inboundFrameWidth: k || null,
2167
- inboundFrameHeight: C || null,
2168
- outboundFrameWidth: f || null,
2169
- outboundFrameHeight: v || null,
2389
+ frameWidth: v || null,
2390
+ frameHeight: T || null,
2391
+ inboundFrameWidth: v || null,
2392
+ inboundFrameHeight: T || null,
2393
+ outboundFrameWidth: p || null,
2394
+ outboundFrameHeight: S || null,
2170
2395
  framesDropped: y,
2171
- freezeCount: w,
2172
- freezeDurationMs: Math.round(p * 1e3),
2173
- concealedSamples: R,
2174
- codec: S,
2396
+ freezeCount: k,
2397
+ freezeDurationMs: Math.round(f * 1e3),
2398
+ concealedSamples: M,
2399
+ codec: w,
2175
2400
  transportProtocol: A,
2176
- candidateType: E,
2177
- qualityLimitationReason: I
2401
+ candidateType: P,
2402
+ qualityLimitationReason: E
2178
2403
  }
2179
2404
  };
2180
2405
  }
2181
- function De(a) {
2182
- let e = a.mediaScore == null ? 5 : Math.round(oe(Number(a.mediaScore), 0, 5));
2183
- const t = W(a.packetLossPct) ?? 0, i = W(a.rttMs) ?? 0, n = W(a.jitterMs) ?? 0, s = String(a.connectionState ?? "unknown").toLowerCase();
2406
+ function tt(a) {
2407
+ let e = a.mediaScore == null ? 5 : Math.round(pe(Number(a.mediaScore), 0, 5));
2408
+ const t = Y(a.packetLossPct) ?? 0, i = Y(a.rttMs) ?? 0, n = Y(a.jitterMs) ?? 0, s = String(a.connectionState ?? "unknown").toLowerCase();
2184
2409
  ["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));
2185
- const o = Number(oe(4.5 - t * 0.09 - i * 11e-4 - n * 6e-3, 1, 4.5).toFixed(2));
2410
+ const o = Number(pe(4.5 - t * 0.09 - i * 11e-4 - n * 6e-3, 1, 4.5).toFixed(2));
2186
2411
  return { networkScore: e, estimatedMos: o };
2187
2412
  }
2188
- function re() {
2413
+ function me() {
2189
2414
  return navigator.connection ?? null;
2190
2415
  }
2191
- function qe() {
2416
+ function it() {
2192
2417
  const a = Number(navigator.deviceMemory);
2193
2418
  return Number.isFinite(a) ? a : null;
2194
2419
  }
2195
- function W(a) {
2420
+ function Y(a) {
2196
2421
  const e = Number(a);
2197
2422
  return Number.isFinite(e) ? e : null;
2198
2423
  }
2199
- function oe(a, e, t) {
2424
+ function pe(a, e, t) {
2200
2425
  return Math.min(t, Math.max(e, a));
2201
2426
  }
2202
- function j(a) {
2427
+ function B(a) {
2203
2428
  return a instanceof Error ? { name: a.name, message: a.message } : { name: "ServiceError", message: String(a ?? "Service request failed") };
2204
2429
  }
2205
- function ce(a, e) {
2430
+ function fe(a, e) {
2206
2431
  return a instanceof Error ? a : new Error(e);
2207
2432
  }
2208
- const xe = "1.3.23";
2433
+ const nt = "1.3.25";
2209
2434
  export {
2210
- te as AVATAR_TUNING_DEFAULTS,
2211
- we as BACKGROUND_PRESETS,
2212
- Te as OVERLAY_EFFECTS,
2213
- Ee as RtcClient,
2214
- Pe as RtcIncomingClient,
2215
- Ne as SPEAKER_NOISE_FLOOR,
2216
- Oe as SPEAKER_TAKEOVER_RATIO,
2217
- Qe as createAvatarPipeline,
2218
- Ve as createCallRecorder,
2219
- je as createPictureInPictureController,
2220
- Be as createRtcClient,
2221
- Fe as createRtcIncomingClient,
2222
- Ue as createVideoEffectsPipeline,
2223
- Re as drawAvatar,
2224
- be as headPoseFromMatrix,
2225
- he as neutralRig,
2226
- le as pickActiveSpeaker,
2227
- Ce as rigFromBlendshapes,
2228
- Z as scenePainters,
2229
- ee as smoothRig,
2230
- ie as stylizedAvatarRenderer,
2231
- Ie as unlockRtcCallAudio,
2232
- xe as version
2435
+ _e as AVATAR_MODEL_MAX_BYTES,
2436
+ oe as AVATAR_TUNING_DEFAULTS,
2437
+ x as AvatarModelError,
2438
+ Ne as BACKGROUND_PRESETS,
2439
+ qe as OVERLAY_EFFECTS,
2440
+ Ge as RtcClient,
2441
+ Xe as RtcIncomingClient,
2442
+ at as SPEAKER_NOISE_FLOOR,
2443
+ st as SPEAKER_TAKEOVER_RATIO,
2444
+ lt as createAvatarPipeline,
2445
+ ot as createCallRecorder,
2446
+ rt as createPictureInPictureController,
2447
+ ft as createRtcClient,
2448
+ gt as createRtcIncomingClient,
2449
+ ct as createVideoEffectsPipeline,
2450
+ je as drawAvatar,
2451
+ Oe as headPoseFromMatrix,
2452
+ ht as importAvatarModel,
2453
+ dt as listArchiveModels,
2454
+ ut as listAvatarModels,
2455
+ ve as neutralRig,
2456
+ ge as pickActiveSpeaker,
2457
+ mt as readAvatarModel,
2458
+ $e as readAvatarModelMetadata,
2459
+ pt as removeAvatarModel,
2460
+ Ve as rigFromBlendshapes,
2461
+ se as scenePainters,
2462
+ re as smoothRig,
2463
+ ce as stylizedAvatarRenderer,
2464
+ Ye as unlockRtcCallAudio,
2465
+ nt as version
2233
2466
  };