@nainudhin/video-meeting-sdk 1.11.0 → 1.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/meet-sdk.mjs +69 -42
- package/dist/meet-sdk.umd.js +6 -5
- package/package.json +2 -1
package/dist/meet-sdk.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
var
|
|
1
|
+
var xn = (s) => {
|
|
2
2
|
throw TypeError(s);
|
|
3
3
|
};
|
|
4
|
-
var U = (s, e, t) => e.has(s) ?
|
|
5
|
-
function
|
|
4
|
+
var U = (s, e, t) => e.has(s) ? xn("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(s) : e.set(s, t);
|
|
5
|
+
function kn(s, e) {
|
|
6
6
|
for (var t = 0; t < e.length; t++) {
|
|
7
7
|
const n = e[t];
|
|
8
8
|
if (typeof n != "string" && !Array.isArray(n)) {
|
|
@@ -585,7 +585,7 @@ function St(s, e) {
|
|
|
585
585
|
function Ct(s) {
|
|
586
586
|
s.MediaStream = s.MediaStream || s.webkitMediaStream;
|
|
587
587
|
}
|
|
588
|
-
function
|
|
588
|
+
function xt(s, e) {
|
|
589
589
|
if (!(e.version > 102))
|
|
590
590
|
if (typeof s == "object" && s.RTCPeerConnection && !("ontrack" in s.RTCPeerConnection.prototype)) {
|
|
591
591
|
Object.defineProperty(s.RTCPeerConnection.prototype, "ontrack", {
|
|
@@ -621,7 +621,7 @@ function kt(s, e) {
|
|
|
621
621
|
{ value: { receiver: t.receiver } }
|
|
622
622
|
), t));
|
|
623
623
|
}
|
|
624
|
-
function
|
|
624
|
+
function kt(s) {
|
|
625
625
|
if (typeof s == "object" && s.RTCPeerConnection && !("getSenders" in s.RTCPeerConnection.prototype) && "createDTMFSender" in s.RTCPeerConnection.prototype) {
|
|
626
626
|
const e = function(i, r) {
|
|
627
627
|
return {
|
|
@@ -920,10 +920,10 @@ const st = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
|
920
920
|
fixNegotiationNeeded: Pt,
|
|
921
921
|
shimAddTrackRemoveTrack: wt,
|
|
922
922
|
shimAddTrackRemoveTrackWithNative: Rt,
|
|
923
|
-
shimGetSendersWithDtmf:
|
|
923
|
+
shimGetSendersWithDtmf: kt,
|
|
924
924
|
shimGetUserMedia: St,
|
|
925
925
|
shimMediaStream: Ct,
|
|
926
|
-
shimOnTrack:
|
|
926
|
+
shimOnTrack: xt,
|
|
927
927
|
shimPeerConnection: be,
|
|
928
928
|
shimSenderReceiverGetStats: Tt
|
|
929
929
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -1684,7 +1684,7 @@ t=0 0\r
|
|
|
1684
1684
|
}, s.exports = e;
|
|
1685
1685
|
})(Yt);
|
|
1686
1686
|
var Gt = Yt.exports;
|
|
1687
|
-
const $ = /* @__PURE__ */ On(Gt), Dn = /* @__PURE__ */
|
|
1687
|
+
const $ = /* @__PURE__ */ On(Gt), Dn = /* @__PURE__ */ kn({
|
|
1688
1688
|
__proto__: null,
|
|
1689
1689
|
default: $
|
|
1690
1690
|
}, [Gt]);
|
|
@@ -1931,7 +1931,7 @@ function $n({ window: s } = {}, e = {
|
|
|
1931
1931
|
return t("Chrome shim is not included in this adapter release."), i;
|
|
1932
1932
|
if (n.version === null)
|
|
1933
1933
|
return t("Chrome shim can not determine version, not shimming."), i;
|
|
1934
|
-
t("adapter.js shimming chrome."), i.browserShim = st, Z(s, n), ee(s), St(s, n), Ct(s), be(s, n),
|
|
1934
|
+
t("adapter.js shimming chrome."), i.browserShim = st, Z(s, n), ee(s), St(s, n), Ct(s), be(s, n), xt(s, n), wt(s, n), kt(s), Tt(s, n), Pt(s, n), G(s), ve(s), Se(s), Q(s, n), X(s, n), Ce(s, n);
|
|
1935
1935
|
break;
|
|
1936
1936
|
case "firefox":
|
|
1937
1937
|
if (!it || !_e || !e.shimFirefox)
|
|
@@ -2112,7 +2112,7 @@ class zn extends Qt {
|
|
|
2112
2112
|
this.validateId = Un, this.randomToken = Xt;
|
|
2113
2113
|
}
|
|
2114
2114
|
}
|
|
2115
|
-
const
|
|
2115
|
+
const x = new zn(), Nn = "PeerJS: ";
|
|
2116
2116
|
class qn {
|
|
2117
2117
|
get logLevel() {
|
|
2118
2118
|
return this._logLevel;
|
|
@@ -2260,7 +2260,7 @@ Be = S;
|
|
|
2260
2260
|
var D = {};
|
|
2261
2261
|
O(D, "ConnectionType", () => E);
|
|
2262
2262
|
O(D, "PeerErrorType", () => y);
|
|
2263
|
-
O(D, "BaseConnectionErrorType", () =>
|
|
2263
|
+
O(D, "BaseConnectionErrorType", () => xe);
|
|
2264
2264
|
O(D, "DataConnectionErrorType", () => Ue);
|
|
2265
2265
|
O(D, "SerializationType", () => ce);
|
|
2266
2266
|
O(D, "SocketEventType", () => P);
|
|
@@ -2269,7 +2269,7 @@ var E = /* @__PURE__ */ function(s) {
|
|
|
2269
2269
|
return s.Data = "data", s.Media = "media", s;
|
|
2270
2270
|
}({}), y = /* @__PURE__ */ function(s) {
|
|
2271
2271
|
return s.BrowserIncompatible = "browser-incompatible", s.Disconnected = "disconnected", s.InvalidID = "invalid-id", s.InvalidKey = "invalid-key", s.Network = "network", s.PeerUnavailable = "peer-unavailable", s.SslUnavailable = "ssl-unavailable", s.ServerError = "server-error", s.SocketError = "socket-error", s.SocketClosed = "socket-closed", s.UnavailableID = "unavailable-id", s.WebRTC = "webrtc", s;
|
|
2272
|
-
}({}),
|
|
2272
|
+
}({}), xe = /* @__PURE__ */ function(s) {
|
|
2273
2273
|
return s.NegotiationFailed = "negotiation-failed", s.ConnectionClosed = "connection-closed", s;
|
|
2274
2274
|
}({}), Ue = /* @__PURE__ */ function(s) {
|
|
2275
2275
|
return s.NotOpenYet = "not-open-yet", s.MessageToBig = "message-too-big", s;
|
|
@@ -2390,10 +2390,10 @@ class tn {
|
|
|
2390
2390
|
}, e.oniceconnectionstatechange = () => {
|
|
2391
2391
|
switch (e.iceConnectionState) {
|
|
2392
2392
|
case "failed":
|
|
2393
|
-
p.log("iceConnectionState is failed, closing connections to " + t), this.connection.emitError(
|
|
2393
|
+
p.log("iceConnectionState is failed, closing connections to " + t), this.connection.emitError(xe.NegotiationFailed, "Negotiation of connection to " + t + " failed."), this.connection.close();
|
|
2394
2394
|
break;
|
|
2395
2395
|
case "closed":
|
|
2396
|
-
p.log("iceConnectionState is closed, closing connections to " + t), this.connection.emitError(
|
|
2396
|
+
p.log("iceConnectionState is closed, closing connections to " + t), this.connection.emitError(xe.ConnectionClosed, "Connection to " + t + " closed."), this.connection.close();
|
|
2397
2397
|
break;
|
|
2398
2398
|
case "disconnected":
|
|
2399
2399
|
p.log("iceConnectionState changed to disconnected on the connection with " + t);
|
|
@@ -2560,7 +2560,7 @@ const H = class H extends sn {
|
|
|
2560
2560
|
return this._remoteStream;
|
|
2561
2561
|
}
|
|
2562
2562
|
constructor(e, t, n) {
|
|
2563
|
-
super(e, t, n), this._localStream = this.options._stream, this.connectionId = this.options.connectionId || H.ID_PREFIX +
|
|
2563
|
+
super(e, t, n), this._localStream = this.options._stream, this.connectionId = this.options.connectionId || H.ID_PREFIX + x.randomToken(), this._negotiator = new tn(this), this._localStream && this._negotiator.startConnection({
|
|
2564
2564
|
_stream: this._localStream,
|
|
2565
2565
|
originator: !0
|
|
2566
2566
|
});
|
|
@@ -2647,7 +2647,7 @@ class Kn {
|
|
|
2647
2647
|
} catch (e) {
|
|
2648
2648
|
p.error("Error retrieving ID", e);
|
|
2649
2649
|
let t = "";
|
|
2650
|
-
throw this._options.path === "/" && this._options.host !==
|
|
2650
|
+
throw this._options.path === "/" && this._options.host !== x.CLOUD_HOST && (t = " If you passed in a `path` to your self-hosted PeerServer, you'll also need to pass in that same path when creating a new Peer."), new Error("Could not get an ID from the server." + t);
|
|
2651
2651
|
}
|
|
2652
2652
|
}
|
|
2653
2653
|
/** @deprecated */
|
|
@@ -2657,7 +2657,7 @@ class Kn {
|
|
|
2657
2657
|
if (e.status !== 200) {
|
|
2658
2658
|
if (e.status === 401) {
|
|
2659
2659
|
let t = "";
|
|
2660
|
-
throw this._options.host ===
|
|
2660
|
+
throw this._options.host === x.CLOUD_HOST ? t = "It looks like you're using the cloud server. You can email team@peerjs.com to enable peer listing for your API key." : t = "You need to enable `allow_discovery` on your self-hosted PeerServer to use this feature.", new Error("It doesn't look like you have permission to list peers IDs. " + t);
|
|
2661
2661
|
}
|
|
2662
2662
|
throw new Error(`Error. Status:${e.status}`);
|
|
2663
2663
|
}
|
|
@@ -2853,7 +2853,7 @@ class Wn extends ze {
|
|
|
2853
2853
|
}
|
|
2854
2854
|
_send(e, t) {
|
|
2855
2855
|
const n = this.encoder.encode(this.stringify(e));
|
|
2856
|
-
if (n.byteLength >=
|
|
2856
|
+
if (n.byteLength >= x.chunkedMTU) {
|
|
2857
2857
|
this.emitError(Ue.MessageToBig, "Message too big for JSON channel");
|
|
2858
2858
|
return;
|
|
2859
2859
|
}
|
|
@@ -2920,23 +2920,23 @@ const V = class V extends nn {
|
|
|
2920
2920
|
let n;
|
|
2921
2921
|
if (e && e.constructor == Object ? t = e : e && (n = e.toString()), t = {
|
|
2922
2922
|
debug: 0,
|
|
2923
|
-
host:
|
|
2924
|
-
port:
|
|
2923
|
+
host: x.CLOUD_HOST,
|
|
2924
|
+
port: x.CLOUD_PORT,
|
|
2925
2925
|
path: "/",
|
|
2926
2926
|
key: V.DEFAULT_KEY,
|
|
2927
|
-
token:
|
|
2928
|
-
config:
|
|
2927
|
+
token: x.randomToken(),
|
|
2928
|
+
config: x.defaultConfig,
|
|
2929
2929
|
referrerPolicy: "strict-origin-when-cross-origin",
|
|
2930
2930
|
serializers: {},
|
|
2931
2931
|
...t
|
|
2932
2932
|
}, this._options = t, this._serializers = {
|
|
2933
2933
|
...this._serializers,
|
|
2934
2934
|
...this.options.serializers
|
|
2935
|
-
}, this._options.host === "/" && (this._options.host = window.location.hostname), this._options.path && (this._options.path[0] !== "/" && (this._options.path = "/" + this._options.path), this._options.path[this._options.path.length - 1] !== "/" && (this._options.path += "/")), this._options.secure === void 0 && this._options.host !==
|
|
2935
|
+
}, this._options.host === "/" && (this._options.host = window.location.hostname), this._options.path && (this._options.path[0] !== "/" && (this._options.path = "/" + this._options.path), this._options.path[this._options.path.length - 1] !== "/" && (this._options.path += "/")), this._options.secure === void 0 && this._options.host !== x.CLOUD_HOST ? this._options.secure = x.isSecure() : this._options.host == x.CLOUD_HOST && (this._options.secure = !0), this._options.logFunction && p.setLogFunction(this._options.logFunction), p.logLevel = this._options.debug || 0, this._api = new Kn(t), this._socket = this._createServerConnection(), !x.supports.audioVideo && !x.supports.data) {
|
|
2936
2936
|
this._delayedAbort(y.BrowserIncompatible, "The current browser does not support WebRTC");
|
|
2937
2937
|
return;
|
|
2938
2938
|
}
|
|
2939
|
-
if (n && !
|
|
2939
|
+
if (n && !x.validateId(n)) {
|
|
2940
2940
|
this._delayedAbort(y.InvalidID, `ID "${n}" is invalid`);
|
|
2941
2941
|
return;
|
|
2942
2942
|
}
|
|
@@ -3168,8 +3168,8 @@ const V = class V extends nn {
|
|
|
3168
3168
|
}
|
|
3169
3169
|
};
|
|
3170
3170
|
De = new WeakMap(), U(V, De, V.DEFAULT_KEY = "peerjs");
|
|
3171
|
-
let
|
|
3172
|
-
var Yn =
|
|
3171
|
+
let ke = V;
|
|
3172
|
+
var Yn = ke;
|
|
3173
3173
|
class Gn {
|
|
3174
3174
|
constructor(e) {
|
|
3175
3175
|
this.config = e, this.peer = null, this.localStream = null, this.connections = {}, this.callbacks = {
|
|
@@ -3576,13 +3576,13 @@ b.prototype.listeners = function(s) {
|
|
|
3576
3576
|
b.prototype.hasListeners = function(s) {
|
|
3577
3577
|
return !!this.listeners(s).length;
|
|
3578
3578
|
};
|
|
3579
|
-
const he = typeof Promise == "function" && typeof Promise.resolve == "function" ? (e) => Promise.resolve().then(e) : (e, t) => t(e, 0),
|
|
3579
|
+
const he = typeof Promise == "function" && typeof Promise.resolve == "function" ? (e) => Promise.resolve().then(e) : (e, t) => t(e, 0), k = typeof self < "u" ? self : typeof window < "u" ? window : Function("return this")(), os = "arraybuffer";
|
|
3580
3580
|
function dn(s, ...e) {
|
|
3581
3581
|
return e.reduce((t, n) => (s.hasOwnProperty(n) && (t[n] = s[n]), t), {});
|
|
3582
3582
|
}
|
|
3583
|
-
const as =
|
|
3583
|
+
const as = k.setTimeout, cs = k.clearTimeout;
|
|
3584
3584
|
function le(s, e) {
|
|
3585
|
-
e.useNativeTimers ? (s.setTimeoutFn = as.bind(
|
|
3585
|
+
e.useNativeTimers ? (s.setTimeoutFn = as.bind(k), s.clearTimeoutFn = cs.bind(k)) : (s.setTimeoutFn = k.setTimeout.bind(k), s.clearTimeoutFn = k.clearTimeout.bind(k));
|
|
3586
3586
|
}
|
|
3587
3587
|
const hs = 1.33;
|
|
3588
3588
|
function ls(s) {
|
|
@@ -3959,7 +3959,7 @@ if (typeof document < "u") {
|
|
|
3959
3959
|
if (typeof attachEvent == "function")
|
|
3960
3960
|
attachEvent("onunload", dt);
|
|
3961
3961
|
else if (typeof addEventListener == "function") {
|
|
3962
|
-
const s = "onpagehide" in
|
|
3962
|
+
const s = "onpagehide" in k ? "pagehide" : "unload";
|
|
3963
3963
|
addEventListener(s, dt, !1);
|
|
3964
3964
|
}
|
|
3965
3965
|
}
|
|
@@ -3992,7 +3992,7 @@ function fn(s) {
|
|
|
3992
3992
|
}
|
|
3993
3993
|
if (!e)
|
|
3994
3994
|
try {
|
|
3995
|
-
return new
|
|
3995
|
+
return new k[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP");
|
|
3996
3996
|
} catch {
|
|
3997
3997
|
}
|
|
3998
3998
|
}
|
|
@@ -4053,7 +4053,7 @@ class Ss extends Fe {
|
|
|
4053
4053
|
return this.opts.timestampRequests && (t[this.opts.timestampParam] = un()), this.supportsBinary || (t.b64 = 1), this.createUri(e, t);
|
|
4054
4054
|
}
|
|
4055
4055
|
}
|
|
4056
|
-
const ge =
|
|
4056
|
+
const ge = k.WebSocket || k.MozWebSocket;
|
|
4057
4057
|
class Cs extends Ss {
|
|
4058
4058
|
createSocket(e, t, n) {
|
|
4059
4059
|
return mn ? new ge(e, t, n) : t ? new ge(e, t) : new ge(e);
|
|
@@ -4062,7 +4062,7 @@ class Cs extends Ss {
|
|
|
4062
4062
|
this.ws.send(t);
|
|
4063
4063
|
}
|
|
4064
4064
|
}
|
|
4065
|
-
class
|
|
4065
|
+
class xs extends Fe {
|
|
4066
4066
|
get name() {
|
|
4067
4067
|
return "webtransport";
|
|
4068
4068
|
}
|
|
@@ -4108,9 +4108,9 @@ class ks extends Fe {
|
|
|
4108
4108
|
(e = this._transport) === null || e === void 0 || e.close();
|
|
4109
4109
|
}
|
|
4110
4110
|
}
|
|
4111
|
-
const
|
|
4111
|
+
const ks = {
|
|
4112
4112
|
websocket: Cs,
|
|
4113
|
-
webtransport:
|
|
4113
|
+
webtransport: xs,
|
|
4114
4114
|
polling: vs
|
|
4115
4115
|
}, Ts = /^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/, Rs = [
|
|
4116
4116
|
"source",
|
|
@@ -4498,7 +4498,7 @@ class Es extends M {
|
|
|
4498
4498
|
let Ms = class extends Es {
|
|
4499
4499
|
constructor(e, t = {}) {
|
|
4500
4500
|
const n = typeof e == "object", i = n ? { ...e } : { ...t };
|
|
4501
|
-
(!i.transports || i.transports && typeof i.transports[0] == "string") && (i.transports = (i.transports || ["polling", "websocket", "webtransport"]).map((r) =>
|
|
4501
|
+
(!i.transports || i.transports && typeof i.transports[0] == "string") && (i.transports = (i.transports || ["polling", "websocket", "webtransport"]).map((r) => ks[r]).filter((r) => !!r)), super(n ? i : e, i);
|
|
4502
4502
|
}
|
|
4503
4503
|
};
|
|
4504
4504
|
function As(s, e = "", t) {
|
|
@@ -6390,6 +6390,7 @@ class Qs {
|
|
|
6390
6390
|
${r}
|
|
6391
6391
|
${o}
|
|
6392
6392
|
<span id="upload-indicator" style="display:none;">Uploading…</span>
|
|
6393
|
+
<span id="ms-status" class="ms-status" style="display:none; color:#f87171; font-size:12px; max-width:240px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;"></span>
|
|
6393
6394
|
<button id="panel-toggle-btn" class="ms-panel-toggle" aria-label="Open side panel">
|
|
6394
6395
|
☰<span class="ms-badge" id="chat-badge">0</span>
|
|
6395
6396
|
</button>
|
|
@@ -6640,7 +6641,7 @@ class Qs {
|
|
|
6640
6641
|
const i = e === "recording";
|
|
6641
6642
|
this._setButtonLabel(n, i ? "Stop" : "Record");
|
|
6642
6643
|
const r = n.querySelector(".ms-icon");
|
|
6643
|
-
r && (r.textContent = i ? "■" : "●"), n.classList.toggle("active", i), n.title = i ? "Stop recording" : "Start recording";
|
|
6644
|
+
r && (r.textContent = i ? "■" : "●"), n.classList.toggle("active", i), n.disabled || (n.title = i ? "Stop recording" : "Start recording");
|
|
6644
6645
|
}
|
|
6645
6646
|
e === "recording" ? this.startRecElapsed() : this.stopRecElapsed();
|
|
6646
6647
|
}
|
|
@@ -6714,6 +6715,17 @@ class Qs {
|
|
|
6714
6715
|
onParticipantPermToggle(e) {
|
|
6715
6716
|
this._onParticipantPermToggle = e;
|
|
6716
6717
|
}
|
|
6718
|
+
setRecordAllowed(e, t) {
|
|
6719
|
+
const n = this.container && this.container.querySelector("#toggle-record");
|
|
6720
|
+
n && (n.disabled = !e, n.title = e ? t || "Record" : t || "Only the meeting host can record");
|
|
6721
|
+
}
|
|
6722
|
+
setStatus(e) {
|
|
6723
|
+
if (!this.container) return;
|
|
6724
|
+
const t = this.container.querySelector("#ms-status");
|
|
6725
|
+
if (!t) return;
|
|
6726
|
+
const n = e == null ? "" : String(e);
|
|
6727
|
+
t.textContent = n, t.title = n, t.style.display = n ? "inline" : "none";
|
|
6728
|
+
}
|
|
6717
6729
|
setPauseButtonVisible(e) {
|
|
6718
6730
|
const t = this.container && this.container.querySelector("#toggle-pause");
|
|
6719
6731
|
t && (t.style.display = e ? "inline-flex" : "none");
|
|
@@ -7061,7 +7073,7 @@ class L {
|
|
|
7061
7073
|
const t = this.roleResolvers;
|
|
7062
7074
|
this.roleResolvers = [];
|
|
7063
7075
|
for (const n of t) n(this.myRole);
|
|
7064
|
-
this.refreshParticipantsPanel(), this.codeSandbox && this.codeSandbox.refreshPermissionUI(), this.whiteboard && this.whiteboard.refreshPermissionUI();
|
|
7076
|
+
this.refreshParticipantsPanel(), this.maybeAttachRecordingForHost(), this.codeSandbox && this.codeSandbox.refreshPermissionUI(), this.whiteboard && this.whiteboard.refreshPermissionUI();
|
|
7065
7077
|
});
|
|
7066
7078
|
}
|
|
7067
7079
|
async hydrateIceServers() {
|
|
@@ -7261,14 +7273,29 @@ class L {
|
|
|
7261
7273
|
}), this.uiManager.onControlClick("toggle-pause", () => {
|
|
7262
7274
|
this.recorder.isPaused() ? this.recorder.resume() : this.recorder.pause();
|
|
7263
7275
|
}), this.config.recordOnlyIfHost && await this.waitForRole() !== "organizer") {
|
|
7264
|
-
console.log("MeetSDK: not the host —
|
|
7276
|
+
this.uiManager.setRecordAllowed && this.uiManager.setRecordAllowed(!1, "Only the meeting host can record"), this._pendingRecordAttach = this.config.recording === "manual", console.log("MeetSDK: not the host — recording controls disabled until host role arrives");
|
|
7265
7277
|
return;
|
|
7266
7278
|
}
|
|
7267
|
-
this.
|
|
7268
|
-
this.recorder.isRecording() ? await this.stopRecording() : await this.startRecording();
|
|
7269
|
-
});
|
|
7279
|
+
this.enableAndAttachRecording();
|
|
7270
7280
|
}
|
|
7271
7281
|
}
|
|
7282
|
+
maybeAttachRecordingForHost() {
|
|
7283
|
+
this.myRole === "organizer" && this._pendingRecordAttach && (this._pendingRecordAttach = !1, this.uiManager && this.uiManager.setRecordAllowed && this.uiManager.setRecordAllowed(!0), this.attachRecordToggle());
|
|
7284
|
+
}
|
|
7285
|
+
enableAndAttachRecording() {
|
|
7286
|
+
this.uiManager && this.uiManager.setRecordAllowed && this.uiManager.setRecordAllowed(!0), this.config.recording === "auto" && this.startRecording().catch((e) => console.error("Auto-record failed:", e)), this.config.recording === "manual" && this.attachRecordToggle();
|
|
7287
|
+
}
|
|
7288
|
+
attachRecordToggle() {
|
|
7289
|
+
this._recordToggleAttached || (this._recordToggleAttached = !0, this._pendingRecordAttach = !1, this.uiManager.onControlClick("toggle-record", async () => {
|
|
7290
|
+
try {
|
|
7291
|
+
this.recorder.isRecording() ? await this.stopRecording() : await this.startRecording();
|
|
7292
|
+
} catch (e) {
|
|
7293
|
+
console.error("MeetSDK: record toggle failed:", e);
|
|
7294
|
+
const t = e && e.message || String(e);
|
|
7295
|
+
this.uiManager && typeof this.uiManager.setStatus == "function" && this.uiManager.setStatus(t);
|
|
7296
|
+
}
|
|
7297
|
+
}));
|
|
7298
|
+
}
|
|
7272
7299
|
async startRecording() {
|
|
7273
7300
|
if (!this.recorder) throw new Error("recording is disabled in SDK config");
|
|
7274
7301
|
let e;
|
package/dist/meet-sdk.umd.js
CHANGED
|
@@ -32,13 +32,13 @@ t=0 0\r
|
|
|
32
32
|
`},e.getDirection=function(t,n){const i=e.splitLines(t);for(let r=0;r<i.length;r++)switch(i[r]){case"a=sendrecv":case"a=sendonly":case"a=recvonly":case"a=inactive":return i[r].substring(2)}return n?e.getDirection(n):"sendrecv"},e.getKind=function(t){return e.splitLines(t)[0].split(" ")[0].substring(2)},e.isRejected=function(t){return t.split(" ",2)[1]==="0"},e.parseMLine=function(t){const i=e.splitLines(t)[0].substring(2).split(" ");return{kind:i[0],port:parseInt(i[1],10),protocol:i[2],fmt:i.slice(3).join(" ")}},e.parseOLine=function(t){const i=e.matchPrefix(t,"o=")[0].substring(2).split(" ");return{username:i[0],sessionId:i[1],sessionVersion:parseInt(i[2],10),netType:i[3],addressType:i[4],address:i[5]}},e.isValidSDP=function(t){if(typeof t!="string"||t.length===0)return!1;const n=e.splitLines(t);for(let i=0;i<n.length;i++)if(n[i].length<2||n[i].charAt(1)!=="=")return!1;return!0},s.exports=e})(Lt);var $t=Lt.exports;const U=Pn($t),En=w({__proto__:null,default:U},[$t]);function Y(s){if(!s.RTCIceCandidate||s.RTCIceCandidate&&"foundation"in s.RTCIceCandidate.prototype)return;const e=s.RTCIceCandidate;s.RTCIceCandidate=function(n){if(typeof n=="object"&&n.candidate&&n.candidate.indexOf("a=")===0&&(n=JSON.parse(JSON.stringify(n)),n.candidate=n.candidate.substring(2)),n.candidate&&n.candidate.length){const i=new e(n),r=U.parseCandidate(n.candidate);for(const o in r)o in i||Object.defineProperty(i,o,{value:r[o]});return i.toJSON=function(){return{candidate:i.candidate,sdpMid:i.sdpMid,sdpMLineIndex:i.sdpMLineIndex,usernameFragment:i.usernameFragment}},i}return new e(n)},s.RTCIceCandidate.prototype=e.prototype,O(s,"icecandidate",t=>(t.candidate&&Object.defineProperty(t,"candidate",{value:new s.RTCIceCandidate(t.candidate),writable:"false"}),t))}function _e(s){!s.RTCIceCandidate||s.RTCIceCandidate&&"relayProtocol"in s.RTCIceCandidate.prototype||O(s,"icecandidate",e=>{if(e.candidate){const t=U.parseCandidate(e.candidate.candidate);t.type==="relay"&&(e.candidate.relayProtocol={0:"tls",1:"tcp",2:"udp"}[t.priority>>24])}return e})}function G(s,e){if(!s.RTCPeerConnection||e.browser==="chrome"&&e.version>102||e.browser==="firefox"&&e.version>=113)return;"sctp"in s.RTCPeerConnection.prototype||Object.defineProperty(s.RTCPeerConnection.prototype,"sctp",{get(){return typeof this._sctp>"u"?null:this._sctp}});const t=function(a){if(!a||!a.sdp)return!1;const c=U.splitSections(a.sdp);return c.shift(),c.some(h=>{const l=U.parseMLine(h);return l&&l.kind==="application"&&l.protocol.indexOf("SCTP")!==-1})},n=function(a){const c=a.sdp.match(/mozilla...THIS_IS_SDPARTA-(\d+)/);if(c===null||c.length<2)return-1;const h=parseInt(c[1],10);return h!==h?-1:h},i=function(a){let c=65536;return e.browser==="firefox"&&(e.version<57?a===-1?c=16384:c=2147483637:e.version<60?c=e.version===57?65535:65536:c=2147483637),c},r=function(a,c){let h=65536;e.browser==="firefox"&&e.version===57&&(h=65535);const l=U.matchPrefix(a.sdp,"a=max-message-size:");return l.length>0?h=parseInt(l[0].substring(19),10):e.browser==="firefox"&&c!==-1&&(h=2147483637),h},o=s.RTCPeerConnection.prototype.setRemoteDescription;s.RTCPeerConnection.prototype.setRemoteDescription=function(){if(this._sctp=null,e.browser==="chrome"&&e.version>=76){const{sdpSemantics:c}=this.getConfiguration();c==="plan-b"&&Object.defineProperty(this,"sctp",{get(){return typeof this._sctp>"u"?null:this._sctp},enumerable:!0,configurable:!0})}if(t(arguments[0])){const c=n(arguments[0]),h=i(c),l=r(arguments[0],c);let d;h===0&&l===0?d=Number.POSITIVE_INFINITY:h===0||l===0?d=Math.max(h,l):d=Math.min(h,l);const u={};Object.defineProperty(u,"maxMessageSize",{get(){return d}}),this._sctp=u}return o.apply(this,arguments)}}function Q(s,e){if(!(s.RTCPeerConnection&&"createDataChannel"in s.RTCPeerConnection.prototype)||e.browser==="chrome"&&e.version>=149||e.browser==="firefox"&&e.version>60)return;function t(i,r){const o=i.send;i.send=function(){const c=arguments[0],h=c.length||c.size||c.byteLength;if(i.readyState==="open"&&r.sctp&&h>r.sctp.maxMessageSize)throw new TypeError("Message too large (can send a maximum of "+r.sctp.maxMessageSize+" bytes)");return o.apply(i,arguments)}}const n=s.RTCPeerConnection.prototype.createDataChannel;s.RTCPeerConnection.prototype.createDataChannel=function(){const r=n.apply(this,arguments);return t(r,this),r},O(s,"datachannel",i=>(t(i.channel,i.target),i))}function ve(s){if(!s.RTCPeerConnection||"connectionState"in s.RTCPeerConnection.prototype)return;const e=s.RTCPeerConnection.prototype;Object.defineProperty(e,"connectionState",{get(){return{completed:"connected",checking:"connecting"}[this.iceConnectionState]||this.iceConnectionState},enumerable:!0,configurable:!0}),Object.defineProperty(e,"onconnectionstatechange",{get(){return this._onconnectionstatechange||null},set(t){this._onconnectionstatechange&&(this.removeEventListener("connectionstatechange",this._onconnectionstatechange),delete this._onconnectionstatechange),t&&this.addEventListener("connectionstatechange",this._onconnectionstatechange=t)},enumerable:!0,configurable:!0}),["setLocalDescription","setRemoteDescription"].forEach(t=>{const n=e[t];e[t]=function(){return this._connectionstatechangepoly||(this._connectionstatechangepoly=i=>{const r=i.target;if(r._lastConnectionState!==r.connectionState){r._lastConnectionState=r.connectionState;const o=new Event("connectionstatechange",i);r.dispatchEvent(o)}return i},this.addEventListener("iceconnectionstatechange",this._connectionstatechangepoly)),n.apply(this,arguments)}})}function Se(s,e){if(!s.RTCPeerConnection||e.browser==="chrome"&&e.version>=71||e.browser==="safari"&&e._safariVersion>=13.1)return;const t=s.RTCPeerConnection.prototype.setRemoteDescription;s.RTCPeerConnection.prototype.setRemoteDescription=function(i){if(i&&i.sdp&&i.sdp.indexOf(`
|
|
33
33
|
a=extmap-allow-mixed`)!==-1){const r=i.sdp.split(`
|
|
34
34
|
`).filter(o=>o.trim()!=="a=extmap-allow-mixed").join(`
|
|
35
|
-
`);s.RTCSessionDescription&&i instanceof s.RTCSessionDescription?arguments[0]=new s.RTCSessionDescription({type:i.type,sdp:r}):i.sdp=r}return t.apply(this,arguments)}}function X(s,e){if(!(s.RTCPeerConnection&&s.RTCPeerConnection.prototype))return;const t=s.RTCPeerConnection.prototype.addIceCandidate;!t||t.length===0||(s.RTCPeerConnection.prototype.addIceCandidate=function(){return arguments[0]?(e.browser==="chrome"&&e.version<78||e.browser==="firefox"&&e.version<68||e.browser==="safari")&&arguments[0]&&arguments[0].candidate===""?Promise.resolve():t.apply(this,arguments):(arguments[1]&&arguments[1].apply(null),Promise.resolve())})}function Z(s,e){if(!(s.RTCPeerConnection&&s.RTCPeerConnection.prototype))return;const t=s.RTCPeerConnection.prototype.setLocalDescription;!t||t.length===0||(s.RTCPeerConnection.prototype.setLocalDescription=function(){let i=arguments[0]||{};if(typeof i!="object"||i.type&&i.sdp)return t.apply(this,arguments);if(i={type:i.type,sdp:i.sdp},!i.type)switch(this.signalingState){case"stable":case"have-local-offer":case"have-remote-pranswer":i.type="offer";break;default:i.type="answer";break}return i.sdp||i.type!=="offer"&&i.type!=="answer"?t.apply(this,[i]):(i.type==="offer"?this.createOffer:this.createAnswer).apply(this).then(o=>t.apply(this,[o]))})}const Mn=Object.freeze(Object.defineProperty({__proto__:null,removeExtmapAllowMixed:Se,shimAddIceCandidateNullOrEmpty:X,shimConnectionState:ve,shimMaxMessageSize:G,shimParameterlessSetLocalDescription:Z,shimRTCIceCandidate:Y,shimRTCIceCandidateRelayProtocol:_e,shimSendThrowTypeError:Q},Symbol.toStringTag,{value:"Module"}));function An({window:s}={},e={shimChrome:!0,shimFirefox:!0,shimSafari:!0}){const t=fe,n=Rn(s),i={browserDetails:n,commonShim:Mn,extractVersion:N,disableLog:kn,disableWarnings:Tn,sdp:En};switch(n.browser){case"chrome":if(!ut||!ye||!e.shimChrome)return t("Chrome shim is not included in this adapter release."),i;if(n.version===null)return t("Chrome shim can not determine version, not shimming."),i;t("adapter.js shimming chrome."),i.browserShim=ut,X(s,n),Z(s),it(s,n),rt(s),ye(s,n),ot(s,n),lt(s,n),at(s),ct(s,n),dt(s,n),Y(s),_e(s),ve(s),G(s,n),Q(s,n),Se(s,n);break;case"firefox":if(!kt||!be||!e.shimFirefox)return t("Firefox shim is not included in this adapter release."),i;t("adapter.js shimming firefox."),i.browserShim=kt,X(s,n),Z(s),pt(s,n),be(s,n),mt(s,n),ft(s),bt(s),gt(s),yt(s),_t(s),vt(s,n),St(s,n),Ct(s,n),xt(s,n),Y(s),ve(s),G(s,n),Q(s,n);break;case"safari":if(!Dt||!e.shimSafari)return t("Safari shim is not included in this adapter release."),i;t("adapter.js shimming safari."),i.browserShim=Dt,X(s,n),Z(s),Mt(s),It(s),wt(s),Tt(s),Rt(s),At(s),Pt(s),Ot(s),Y(s),_e(s),G(s,n),Q(s,n),Se(s,n);break;default:t("Unsupported browser!");break}return i}const Bt=An({window:typeof window>"u"?void 0:window});function D(s,e,t,n){Object.defineProperty(s,e,{get:t,set:n,enumerable:!0,configurable:!0})}class Ut{constructor(){this.chunkedMTU=16300,this._dataCount=1,this.chunk=e=>{const t=[],n=e.byteLength,i=Math.ceil(n/this.chunkedMTU);let r=0,o=0;for(;o<n;){const a=Math.min(n,o+this.chunkedMTU),c=e.slice(o,a),h={__peerData:this._dataCount,n:r,data:c,total:i};t.push(h),o=a,r++}return this._dataCount++,t}}}function In(s){let e=0;for(const i of s)e+=i.byteLength;const t=new Uint8Array(e);let n=0;for(const i of s)t.set(i,n),n+=i.byteLength;return t}const Ce=Bt.default||Bt,
|
|
35
|
+
`);s.RTCSessionDescription&&i instanceof s.RTCSessionDescription?arguments[0]=new s.RTCSessionDescription({type:i.type,sdp:r}):i.sdp=r}return t.apply(this,arguments)}}function X(s,e){if(!(s.RTCPeerConnection&&s.RTCPeerConnection.prototype))return;const t=s.RTCPeerConnection.prototype.addIceCandidate;!t||t.length===0||(s.RTCPeerConnection.prototype.addIceCandidate=function(){return arguments[0]?(e.browser==="chrome"&&e.version<78||e.browser==="firefox"&&e.version<68||e.browser==="safari")&&arguments[0]&&arguments[0].candidate===""?Promise.resolve():t.apply(this,arguments):(arguments[1]&&arguments[1].apply(null),Promise.resolve())})}function Z(s,e){if(!(s.RTCPeerConnection&&s.RTCPeerConnection.prototype))return;const t=s.RTCPeerConnection.prototype.setLocalDescription;!t||t.length===0||(s.RTCPeerConnection.prototype.setLocalDescription=function(){let i=arguments[0]||{};if(typeof i!="object"||i.type&&i.sdp)return t.apply(this,arguments);if(i={type:i.type,sdp:i.sdp},!i.type)switch(this.signalingState){case"stable":case"have-local-offer":case"have-remote-pranswer":i.type="offer";break;default:i.type="answer";break}return i.sdp||i.type!=="offer"&&i.type!=="answer"?t.apply(this,[i]):(i.type==="offer"?this.createOffer:this.createAnswer).apply(this).then(o=>t.apply(this,[o]))})}const Mn=Object.freeze(Object.defineProperty({__proto__:null,removeExtmapAllowMixed:Se,shimAddIceCandidateNullOrEmpty:X,shimConnectionState:ve,shimMaxMessageSize:G,shimParameterlessSetLocalDescription:Z,shimRTCIceCandidate:Y,shimRTCIceCandidateRelayProtocol:_e,shimSendThrowTypeError:Q},Symbol.toStringTag,{value:"Module"}));function An({window:s}={},e={shimChrome:!0,shimFirefox:!0,shimSafari:!0}){const t=fe,n=Rn(s),i={browserDetails:n,commonShim:Mn,extractVersion:N,disableLog:kn,disableWarnings:Tn,sdp:En};switch(n.browser){case"chrome":if(!ut||!ye||!e.shimChrome)return t("Chrome shim is not included in this adapter release."),i;if(n.version===null)return t("Chrome shim can not determine version, not shimming."),i;t("adapter.js shimming chrome."),i.browserShim=ut,X(s,n),Z(s),it(s,n),rt(s),ye(s,n),ot(s,n),lt(s,n),at(s),ct(s,n),dt(s,n),Y(s),_e(s),ve(s),G(s,n),Q(s,n),Se(s,n);break;case"firefox":if(!kt||!be||!e.shimFirefox)return t("Firefox shim is not included in this adapter release."),i;t("adapter.js shimming firefox."),i.browserShim=kt,X(s,n),Z(s),pt(s,n),be(s,n),mt(s,n),ft(s),bt(s),gt(s),yt(s),_t(s),vt(s,n),St(s,n),Ct(s,n),xt(s,n),Y(s),ve(s),G(s,n),Q(s,n);break;case"safari":if(!Dt||!e.shimSafari)return t("Safari shim is not included in this adapter release."),i;t("adapter.js shimming safari."),i.browserShim=Dt,X(s,n),Z(s),Mt(s),It(s),wt(s),Tt(s),Rt(s),At(s),Pt(s),Ot(s),Y(s),_e(s),G(s,n),Q(s,n),Se(s,n);break;default:t("Unsupported browser!");break}return i}const Bt=An({window:typeof window>"u"?void 0:window});function D(s,e,t,n){Object.defineProperty(s,e,{get:t,set:n,enumerable:!0,configurable:!0})}class Ut{constructor(){this.chunkedMTU=16300,this._dataCount=1,this.chunk=e=>{const t=[],n=e.byteLength,i=Math.ceil(n/this.chunkedMTU);let r=0,o=0;for(;o<n;){const a=Math.min(n,o+this.chunkedMTU),c=e.slice(o,a),h={__peerData:this._dataCount,n:r,data:c,total:i};t.push(h),o=a,r++}return this._dataCount++,t}}}function In(s){let e=0;for(const i of s)e+=i.byteLength;const t=new Uint8Array(e);let n=0;for(const i of s)t.set(i,n),n+=i.byteLength;return t}const Ce=Bt.default||Bt,q=new class{isWebRTCSupported(){return typeof RTCPeerConnection<"u"}isBrowserSupported(){const s=this.getBrowser(),e=this.getVersion();return this.supportedBrowsers.includes(s)?s==="chrome"?e>=this.minChromeVersion:s==="firefox"?e>=this.minFirefoxVersion:s==="safari"?!this.isIOS&&e>=this.minSafariVersion:!1:!1}getBrowser(){return Ce.browserDetails.browser}getVersion(){return Ce.browserDetails.version||0}isUnifiedPlanSupported(){const s=this.getBrowser(),e=Ce.browserDetails.version||0;if(s==="chrome"&&e<this.minChromeVersion)return!1;if(s==="firefox"&&e>=this.minFirefoxVersion)return!0;if(!window.RTCRtpTransceiver||!("currentDirection"in RTCRtpTransceiver.prototype))return!1;let t,n=!1;try{t=new RTCPeerConnection,t.addTransceiver("audio"),n=!0}catch{}finally{t&&t.close()}return n}toString(){return`Supports:
|
|
36
36
|
browser:${this.getBrowser()}
|
|
37
37
|
version:${this.getVersion()}
|
|
38
38
|
isIOS:${this.isIOS}
|
|
39
39
|
isWebRTCSupported:${this.isWebRTCSupported()}
|
|
40
40
|
isBrowserSupported:${this.isBrowserSupported()}
|
|
41
|
-
isUnifiedPlanSupported:${this.isUnifiedPlanSupported()}`}constructor(){this.isIOS=typeof navigator<"u"?["iPad","iPhone","iPod"].includes(navigator.platform):!1,this.supportedBrowsers=["firefox","chrome","safari"],this.minFirefoxVersion=59,this.minChromeVersion=72,this.minSafariVersion=605}},On=s=>!s||/^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/.test(s),zt=()=>Math.random().toString(36).slice(2),Nt={iceServers:[{urls:"stun:stun.l.google.com:19302"},{urls:["turn:eu-0.turn.peerjs.com:3478","turn:us-0.turn.peerjs.com:3478"],username:"peerjs",credential:"peerjsp"}],sdpSemantics:"unified-plan"};class Dn extends Ut{noop(){}blobToArrayBuffer(e,t){const n=new FileReader;return n.onload=function(i){i.target&&t(i.target.result)},n.readAsArrayBuffer(e),n}binaryStringToArrayBuffer(e){const t=new Uint8Array(e.length);for(let n=0;n<e.length;n++)t[n]=e.charCodeAt(n)&255;return t.buffer}isSecure(){return location.protocol==="https:"}constructor(...e){super(...e),this.CLOUD_HOST="0.peerjs.com",this.CLOUD_PORT=443,this.chunkedBrowsers={Chrome:1,chrome:1},this.defaultConfig=Nt,this.browser=j.getBrowser(),this.browserVersion=j.getVersion(),this.pack=Qe,this.unpack=Ge,this.supports=function(){const t={browser:j.isBrowserSupported(),webRTC:j.isWebRTCSupported(),audioVideo:!1,data:!1,binaryBlob:!1,reliable:!1};if(!t.webRTC)return t;let n;try{n=new RTCPeerConnection(Nt),t.audioVideo=!0;let i;try{i=n.createDataChannel("_PEERJSTEST",{ordered:!0}),t.data=!0,t.reliable=!!i.ordered;try{i.binaryType="blob",t.binaryBlob=!j.isIOS}catch{}}catch{}finally{i&&i.close()}}catch{}finally{n&&n.close()}return t}(),this.validateId=On,this.randomToken=zt}}const x=new Dn,Ln="PeerJS: ";class $n{get logLevel(){return this._logLevel}set logLevel(e){this._logLevel=e}log(...e){this._logLevel>=3&&this._print(3,...e)}warn(...e){this._logLevel>=2&&this._print(2,...e)}error(...e){this._logLevel>=1&&this._print(1,...e)}setLogFunction(e){this._print=e}_print(e,...t){const n=[Ln,...t];for(const i in n)n[i]instanceof Error&&(n[i]="("+n[i].name+") "+n[i].message);e>=3?console.log(...n):e>=2?console.warn("WARNING",...n):e>=1&&console.error("ERROR",...n)}constructor(){this._logLevel=0}}var p=new $n,xe={},Bn=Object.prototype.hasOwnProperty,C="~";function q(){}Object.create&&(q.prototype=Object.create(null),new q().__proto__||(C=!1));function Un(s,e,t){this.fn=s,this.context=e,this.once=t||!1}function jt(s,e,t,n,i){if(typeof t!="function")throw new TypeError("The listener must be a function");var r=new Un(t,n||s,i),o=C?C+e:e;return s._events[o]?s._events[o].fn?s._events[o]=[s._events[o],r]:s._events[o].push(r):(s._events[o]=r,s._eventsCount++),s}function ee(s,e){--s._eventsCount===0?s._events=new q:delete s._events[e]}function v(){this._events=new q,this._eventsCount=0}v.prototype.eventNames=function(){var e=[],t,n;if(this._eventsCount===0)return e;for(n in t=this._events)Bn.call(t,n)&&e.push(C?n.slice(1):n);return Object.getOwnPropertySymbols?e.concat(Object.getOwnPropertySymbols(t)):e},v.prototype.listeners=function(e){var t=C?C+e:e,n=this._events[t];if(!n)return[];if(n.fn)return[n.fn];for(var i=0,r=n.length,o=new Array(r);i<r;i++)o[i]=n[i].fn;return o},v.prototype.listenerCount=function(e){var t=C?C+e:e,n=this._events[t];return n?n.fn?1:n.length:0},v.prototype.emit=function(e,t,n,i,r,o){var a=C?C+e:e;if(!this._events[a])return!1;var c=this._events[a],h=arguments.length,l,d;if(c.fn){switch(c.once&&this.removeListener(e,c.fn,void 0,!0),h){case 1:return c.fn.call(c.context),!0;case 2:return c.fn.call(c.context,t),!0;case 3:return c.fn.call(c.context,t,n),!0;case 4:return c.fn.call(c.context,t,n,i),!0;case 5:return c.fn.call(c.context,t,n,i,r),!0;case 6:return c.fn.call(c.context,t,n,i,r,o),!0}for(d=1,l=new Array(h-1);d<h;d++)l[d-1]=arguments[d];c.fn.apply(c.context,l)}else{var u=c.length,f;for(d=0;d<u;d++)switch(c[d].once&&this.removeListener(e,c[d].fn,void 0,!0),h){case 1:c[d].fn.call(c[d].context);break;case 2:c[d].fn.call(c[d].context,t);break;case 3:c[d].fn.call(c[d].context,t,n);break;case 4:c[d].fn.call(c[d].context,t,n,i);break;default:if(!l)for(f=1,l=new Array(h-1);f<h;f++)l[f-1]=arguments[f];c[d].fn.apply(c[d].context,l)}}return!0},v.prototype.on=function(e,t,n){return jt(this,e,t,n,!1)},v.prototype.once=function(e,t,n){return jt(this,e,t,n,!0)},v.prototype.removeListener=function(e,t,n,i){var r=C?C+e:e;if(!this._events[r])return this;if(!t)return ee(this,r),this;var o=this._events[r];if(o.fn)o.fn===t&&(!i||o.once)&&(!n||o.context===n)&&ee(this,r);else{for(var a=0,c=[],h=o.length;a<h;a++)(o[a].fn!==t||i&&!o[a].once||n&&o[a].context!==n)&&c.push(o[a]);c.length?this._events[r]=c.length===1?c[0]:c:ee(this,r)}return this},v.prototype.removeAllListeners=function(e){var t;return e?(t=C?C+e:e,this._events[t]&&ee(this,t)):(this._events=new q,this._eventsCount=0),this},v.prototype.off=v.prototype.removeListener,v.prototype.addListener=v.prototype.on,v.prefixed=C,v.EventEmitter=v,xe=v;var L={};D(L,"ConnectionType",()=>M),D(L,"PeerErrorType",()=>y),D(L,"BaseConnectionErrorType",()=>ke),D(L,"DataConnectionErrorType",()=>Te),D(L,"SerializationType",()=>te),D(L,"SocketEventType",()=>A),D(L,"ServerMessageType",()=>S);var M=function(s){return s.Data="data",s.Media="media",s}({}),y=function(s){return s.BrowserIncompatible="browser-incompatible",s.Disconnected="disconnected",s.InvalidID="invalid-id",s.InvalidKey="invalid-key",s.Network="network",s.PeerUnavailable="peer-unavailable",s.SslUnavailable="ssl-unavailable",s.ServerError="server-error",s.SocketError="socket-error",s.SocketClosed="socket-closed",s.UnavailableID="unavailable-id",s.WebRTC="webrtc",s}({}),ke=function(s){return s.NegotiationFailed="negotiation-failed",s.ConnectionClosed="connection-closed",s}({}),Te=function(s){return s.NotOpenYet="not-open-yet",s.MessageToBig="message-too-big",s}({}),te=function(s){return s.Binary="binary",s.BinaryUTF8="binary-utf8",s.JSON="json",s.None="raw",s}({}),A=function(s){return s.Message="message",s.Disconnected="disconnected",s.Error="error",s.Close="close",s}({}),S=function(s){return s.Heartbeat="HEARTBEAT",s.Candidate="CANDIDATE",s.Offer="OFFER",s.Answer="ANSWER",s.Open="OPEN",s.Error="ERROR",s.IdTaken="ID-TAKEN",s.InvalidKey="INVALID-KEY",s.Leave="LEAVE",s.Expire="EXPIRE",s}({});const qt="1.5.5";class zn extends xe.EventEmitter{constructor(e,t,n,i,r,o=5e3){super(),this.pingInterval=o,this._disconnected=!0,this._messagesQueue=[];const a=e?"wss://":"ws://";this._baseUrl=a+t+":"+n+i+"peerjs?key="+r}start(e,t){this._id=e;const n=`${this._baseUrl}&id=${e}&token=${t}`;this._socket||!this._disconnected||(this._socket=new WebSocket(n+"&version="+qt),this._disconnected=!1,this._socket.onmessage=i=>{let r;try{r=JSON.parse(i.data),p.log("Server message received:",r)}catch{p.log("Invalid server message",i.data);return}this.emit(A.Message,r)},this._socket.onclose=i=>{this._disconnected||(p.log("Socket closed.",i),this._cleanup(),this._disconnected=!0,this.emit(A.Disconnected))},this._socket.onopen=()=>{this._disconnected||(this._sendQueuedMessages(),p.log("Socket open"),this._scheduleHeartbeat())})}_scheduleHeartbeat(){this._wsPingTimer=setTimeout(()=>{this._sendHeartbeat()},this.pingInterval)}_sendHeartbeat(){if(!this._wsOpen()){p.log("Cannot send heartbeat, because socket closed");return}const e=JSON.stringify({type:S.Heartbeat});this._socket.send(e),this._scheduleHeartbeat()}_wsOpen(){return!!this._socket&&this._socket.readyState===1}_sendQueuedMessages(){const e=[...this._messagesQueue];this._messagesQueue=[];for(const t of e)this.send(t)}send(e){if(this._disconnected)return;if(!this._id){this._messagesQueue.push(e);return}if(!e.type){this.emit(A.Error,"Invalid message");return}if(!this._wsOpen())return;const t=JSON.stringify(e);this._socket.send(t)}close(){this._disconnected||(this._cleanup(),this._disconnected=!0)}_cleanup(){this._socket&&(this._socket.onopen=this._socket.onmessage=this._socket.onclose=null,this._socket.close(),this._socket=void 0),clearTimeout(this._wsPingTimer)}}class Ft{constructor(e){this.connection=e}startConnection(e){const t=this._startPeerConnection();if(this.connection.peerConnection=t,this.connection.type===M.Media&&e._stream&&this._addTracksToConnection(e._stream,t),e.originator){const n=this.connection,i={ordered:!!e.reliable},r=t.createDataChannel(n.label,i);n._initializeDataChannel(r),this._makeOffer()}else this.handleSDP("OFFER",e.sdp)}_startPeerConnection(){p.log("Creating RTCPeerConnection.");const e=new RTCPeerConnection(this.connection.provider.options.config);return this._setupListeners(e),e}_setupListeners(e){const t=this.connection.peer,n=this.connection.connectionId,i=this.connection.type,r=this.connection.provider;p.log("Listening for ICE candidates."),e.onicecandidate=o=>{!o.candidate||!o.candidate.candidate||(p.log(`Received ICE candidates for ${t}:`,o.candidate),r.socket.send({type:S.Candidate,payload:{candidate:o.candidate,type:i,connectionId:n},dst:t}))},e.oniceconnectionstatechange=()=>{switch(e.iceConnectionState){case"failed":p.log("iceConnectionState is failed, closing connections to "+t),this.connection.emitError(ke.NegotiationFailed,"Negotiation of connection to "+t+" failed."),this.connection.close();break;case"closed":p.log("iceConnectionState is closed, closing connections to "+t),this.connection.emitError(ke.ConnectionClosed,"Connection to "+t+" closed."),this.connection.close();break;case"disconnected":p.log("iceConnectionState changed to disconnected on the connection with "+t);break;case"completed":e.onicecandidate=()=>{};break}this.connection.emit("iceStateChanged",e.iceConnectionState)},p.log("Listening for data channel"),e.ondatachannel=o=>{p.log("Received data channel");const a=o.channel;r.getConnection(t,n)._initializeDataChannel(a)},p.log("Listening for remote stream"),e.ontrack=o=>{p.log("Received remote stream");const a=o.streams[0],c=r.getConnection(t,n);if(c.type===M.Media){const h=c;this._addStreamToMediaConnection(a,h)}}}cleanup(){p.log("Cleaning up PeerConnection to "+this.connection.peer);const e=this.connection.peerConnection;if(!e)return;this.connection.peerConnection=null,e.onicecandidate=e.oniceconnectionstatechange=e.ondatachannel=e.ontrack=()=>{};const t=e.signalingState!=="closed";let n=!1;const i=this.connection.dataChannel;i&&(n=!!i.readyState&&i.readyState!=="closed"),(t||n)&&e.close()}async _makeOffer(){const e=this.connection.peerConnection,t=this.connection.provider;try{const n=await e.createOffer(this.connection.options.constraints);p.log("Created offer."),this.connection.options.sdpTransform&&typeof this.connection.options.sdpTransform=="function"&&(n.sdp=this.connection.options.sdpTransform(n.sdp)||n.sdp);try{await e.setLocalDescription(n),p.log("Set localDescription:",n,`for:${this.connection.peer}`);let i={sdp:n,type:this.connection.type,connectionId:this.connection.connectionId,metadata:this.connection.metadata};if(this.connection.type===M.Data){const r=this.connection;i={...i,label:r.label,reliable:r.reliable,serialization:r.serialization}}t.socket.send({type:S.Offer,payload:i,dst:this.connection.peer})}catch(i){i!="OperationError: Failed to set local offer sdp: Called in wrong state: kHaveRemoteOffer"&&(t.emitError(y.WebRTC,i),p.log("Failed to setLocalDescription, ",i))}}catch(n){t.emitError(y.WebRTC,n),p.log("Failed to createOffer, ",n)}}async _makeAnswer(){const e=this.connection.peerConnection,t=this.connection.provider;try{const n=await e.createAnswer();p.log("Created answer."),this.connection.options.sdpTransform&&typeof this.connection.options.sdpTransform=="function"&&(n.sdp=this.connection.options.sdpTransform(n.sdp)||n.sdp);try{await e.setLocalDescription(n),p.log("Set localDescription:",n,`for:${this.connection.peer}`),t.socket.send({type:S.Answer,payload:{sdp:n,type:this.connection.type,connectionId:this.connection.connectionId},dst:this.connection.peer})}catch(i){t.emitError(y.WebRTC,i),p.log("Failed to setLocalDescription, ",i)}}catch(n){t.emitError(y.WebRTC,n),p.log("Failed to create answer, ",n)}}async handleSDP(e,t){t=new RTCSessionDescription(t);const n=this.connection.peerConnection,i=this.connection.provider;p.log("Setting remote description",t);const r=this;try{await n.setRemoteDescription(t),p.log(`Set remoteDescription:${e} for:${this.connection.peer}`),e==="OFFER"&&await r._makeAnswer()}catch(o){i.emitError(y.WebRTC,o),p.log("Failed to setRemoteDescription, ",o)}}async handleCandidate(e){p.log("handleCandidate:",e);try{await this.connection.peerConnection.addIceCandidate(e),p.log(`Added ICE candidate for:${this.connection.peer}`)}catch(t){this.connection.provider.emitError(y.WebRTC,t),p.log("Failed to handleCandidate, ",t)}}_addTracksToConnection(e,t){if(p.log(`add tracks from stream ${e.id} to peer connection`),!t.addTrack)return p.error("Your browser does't support RTCPeerConnection#addTrack. Ignored.");e.getTracks().forEach(n=>{t.addTrack(n,e)})}_addStreamToMediaConnection(e,t){p.log(`add stream ${e.id} to media connection ${t.connectionId}`),t.addStream(e)}}class Ht extends xe.EventEmitter{emitError(e,t){p.error("Error:",t),this.emit("error",new Nn(`${e}`,t))}}class Nn extends Error{constructor(e,t){typeof t=="string"?super(t):(super(),Object.assign(this,t)),this.type=e}}class Vt extends Ht{get open(){return this._open}constructor(e,t,n){super(),this.peer=e,this.provider=t,this.options=n,this._open=!1,this.metadata=n.metadata}}const K=class K extends Vt{get type(){return M.Media}get localStream(){return this._localStream}get remoteStream(){return this._remoteStream}constructor(e,t,n){super(e,t,n),this._localStream=this.options._stream,this.connectionId=this.options.connectionId||K.ID_PREFIX+x.randomToken(),this._negotiator=new Ft(this),this._localStream&&this._negotiator.startConnection({_stream:this._localStream,originator:!0})}_initializeDataChannel(e){this.dataChannel=e,this.dataChannel.onopen=()=>{p.log(`DC#${this.connectionId} dc connection success`),this.emit("willCloseOnRemote")},this.dataChannel.onclose=()=>{p.log(`DC#${this.connectionId} dc closed for:`,this.peer),this.close()}}addStream(e){p.log("Receiving stream",e),this._remoteStream=e,super.emit("stream",e)}handleMessage(e){const t=e.type,n=e.payload;switch(e.type){case S.Answer:this._negotiator.handleSDP(t,n.sdp),this._open=!0;break;case S.Candidate:this._negotiator.handleCandidate(n.candidate);break;default:p.warn(`Unrecognized message type:${t} from peer:${this.peer}`);break}}answer(e,t={}){if(this._localStream){p.warn("Local stream already exists on this MediaConnection. Are you answering a call twice?");return}this._localStream=e,t&&t.sdpTransform&&(this.options.sdpTransform=t.sdpTransform),this._negotiator.startConnection({...this.options._payload,_stream:e});const n=this.provider._getMessages(this.connectionId);for(const i of n)this.handleMessage(i);this._open=!0}close(){this._negotiator&&(this._negotiator.cleanup(),this._negotiator=null),this._localStream=null,this._remoteStream=null,this.provider&&(this.provider._removeConnection(this),this.provider=null),this.options&&this.options._stream&&(this.options._stream=null),this.open&&(this._open=!1,super.emit("close"))}};Ve=new WeakMap,W(K,Ve,K.ID_PREFIX="mc_");let ne=K;class jn{constructor(e){this._options=e}_buildRequest(e){const t=this._options.secure?"https":"http",{host:n,port:i,path:r,key:o}=this._options,a=new URL(`${t}://${n}:${i}${r}${o}/${e}`);return a.searchParams.set("ts",`${Date.now()}${Math.random()}`),a.searchParams.set("version",qt),fetch(a.href,{referrerPolicy:this._options.referrerPolicy})}async retrieveId(){try{const e=await this._buildRequest("id");if(e.status!==200)throw new Error(`Error. Status:${e.status}`);return e.text()}catch(e){p.error("Error retrieving ID",e);let t="";throw this._options.path==="/"&&this._options.host!==x.CLOUD_HOST&&(t=" If you passed in a `path` to your self-hosted PeerServer, you'll also need to pass in that same path when creating a new Peer."),new Error("Could not get an ID from the server."+t)}}async listAllPeers(){try{const e=await this._buildRequest("peers");if(e.status!==200){if(e.status===401){let t="";throw this._options.host===x.CLOUD_HOST?t="It looks like you're using the cloud server. You can email team@peerjs.com to enable peer listing for your API key.":t="You need to enable `allow_discovery` on your self-hosted PeerServer to use this feature.",new Error("It doesn't look like you have permission to list peers IDs. "+t)}throw new Error(`Error. Status:${e.status}`)}return e.json()}catch(e){throw p.error("Error retrieving list peers",e),new Error("Could not get list peers from the server."+e)}}}const B=class B extends Vt{get type(){return M.Data}constructor(e,t,n){super(e,t,n),this.connectionId=this.options.connectionId||B.ID_PREFIX+zt(),this.label=this.options.label||this.connectionId,this.reliable=!!this.options.reliable,this._negotiator=new Ft(this),this._negotiator.startConnection(this.options._payload||{originator:!0,reliable:this.reliable})}_initializeDataChannel(e){this.dataChannel=e,this.dataChannel.onopen=()=>{p.log(`DC#${this.connectionId} dc connection success`),this._open=!0,this.emit("open")},this.dataChannel.onmessage=t=>{p.log(`DC#${this.connectionId} dc onmessage:`,t.data)},this.dataChannel.onclose=()=>{p.log(`DC#${this.connectionId} dc closed for:`,this.peer),this.close()}}close(e){if(e!=null&&e.flush){this.send({__peerData:{type:"close"}});return}this._negotiator&&(this._negotiator.cleanup(),this._negotiator=null),this.provider&&(this.provider._removeConnection(this),this.provider=null),this.dataChannel&&(this.dataChannel.onopen=null,this.dataChannel.onmessage=null,this.dataChannel.onclose=null,this.dataChannel=null),this.open&&(this._open=!1,super.emit("close"))}send(e,t=!1){if(!this.open){this.emitError(Te.NotOpenYet,"Connection is not open. You should listen for the `open` event before sending messages.");return}return this._send(e,t)}async handleMessage(e){const t=e.payload;switch(e.type){case S.Answer:await this._negotiator.handleSDP(e.type,t.sdp);break;case S.Candidate:await this._negotiator.handleCandidate(t.candidate);break;default:p.warn("Unrecognized message type:",e.type,"from peer:",this.peer);break}}};Ke=new WeakMap,Je=new WeakMap,W(B,Ke,B.ID_PREFIX="dc_"),W(B,Je,B.MAX_BUFFERED_AMOUNT=8388608);let se=B;class Re extends se{get bufferSize(){return this._bufferSize}_initializeDataChannel(e){super._initializeDataChannel(e),this.dataChannel.binaryType="arraybuffer",this.dataChannel.addEventListener("message",t=>this._handleDataMessage(t))}_bufferedSend(e){(this._buffering||!this._trySend(e))&&(this._buffer.push(e),this._bufferSize=this._buffer.length)}_trySend(e){if(!this.open)return!1;if(this.dataChannel.bufferedAmount>se.MAX_BUFFERED_AMOUNT)return this._buffering=!0,setTimeout(()=>{this._buffering=!1,this._tryBuffer()},50),!1;try{this.dataChannel.send(e)}catch(t){return p.error(`DC#:${this.connectionId} Error when sending:`,t),this._buffering=!0,this.close(),!1}return!0}_tryBuffer(){if(!this.open||this._buffer.length===0)return;const e=this._buffer[0];this._trySend(e)&&(this._buffer.shift(),this._bufferSize=this._buffer.length,this._tryBuffer())}close(e){if(e!=null&&e.flush){this.send({__peerData:{type:"close"}});return}this._buffer=[],this._bufferSize=0,super.close()}constructor(...e){super(...e),this._buffer=[],this._bufferSize=0,this._buffering=!1}}class we extends Re{close(e){super.close(e),this._chunkedData={}}constructor(e,t,n){super(e,t,n),this.chunker=new Ut,this.serialization=te.Binary,this._chunkedData={}}_handleDataMessage({data:e}){const t=Ge(e),n=t.__peerData;if(n){if(n.type==="close"){this.close();return}this._handleChunk(t);return}this.emit("data",t)}_handleChunk(e){const t=e.__peerData,n=this._chunkedData[t]||{data:[],count:0,total:e.total};if(n.data[e.n]=new Uint8Array(e.data),n.count++,this._chunkedData[t]=n,n.total===n.count){delete this._chunkedData[t];const i=In(n.data);this._handleDataMessage({data:i})}}_send(e,t){const n=Qe(e);if(n instanceof Promise)return this._send_blob(n);if(!t&&n.byteLength>this.chunker.chunkedMTU){this._sendChunks(n);return}this._bufferedSend(n)}async _send_blob(e){const t=await e;if(t.byteLength>this.chunker.chunkedMTU){this._sendChunks(t);return}this._bufferedSend(t)}_sendChunks(e){const t=this.chunker.chunk(e);p.log(`DC#${this.connectionId} Try to send ${t.length} chunks...`);for(const n of t)this.send(n,!0)}}class qn extends Re{_handleDataMessage({data:e}){super.emit("data",e)}_send(e,t){this._bufferedSend(e)}constructor(...e){super(...e),this.serialization=te.None}}class Fn extends Re{_handleDataMessage({data:e}){const t=this.parse(this.decoder.decode(e)),n=t.__peerData;if(n&&n.type==="close"){this.close();return}this.emit("data",t)}_send(e,t){const n=this.encoder.encode(this.stringify(e));if(n.byteLength>=x.chunkedMTU){this.emitError(Te.MessageToBig,"Message too big for JSON channel");return}this._bufferedSend(n)}constructor(...e){super(...e),this.serialization=te.JSON,this.encoder=new TextEncoder,this.decoder=new TextDecoder,this.stringify=JSON.stringify,this.parse=JSON.parse}}const J=class J extends Ht{get id(){return this._id}get options(){return this._options}get open(){return this._open}get socket(){return this._socket}get connections(){const e=Object.create(null);for(const[t,n]of this._connections)e[t]=n;return e}get destroyed(){return this._destroyed}get disconnected(){return this._disconnected}constructor(e,t){super(),this._serializers={raw:qn,json:Fn,binary:we,"binary-utf8":we,default:we},this._id=null,this._lastServerId=null,this._destroyed=!1,this._disconnected=!1,this._open=!1,this._connections=new Map,this._lostMessages=new Map;let n;if(e&&e.constructor==Object?t=e:e&&(n=e.toString()),t={debug:0,host:x.CLOUD_HOST,port:x.CLOUD_PORT,path:"/",key:J.DEFAULT_KEY,token:x.randomToken(),config:x.defaultConfig,referrerPolicy:"strict-origin-when-cross-origin",serializers:{},...t},this._options=t,this._serializers={...this._serializers,...this.options.serializers},this._options.host==="/"&&(this._options.host=window.location.hostname),this._options.path&&(this._options.path[0]!=="/"&&(this._options.path="/"+this._options.path),this._options.path[this._options.path.length-1]!=="/"&&(this._options.path+="/")),this._options.secure===void 0&&this._options.host!==x.CLOUD_HOST?this._options.secure=x.isSecure():this._options.host==x.CLOUD_HOST&&(this._options.secure=!0),this._options.logFunction&&p.setLogFunction(this._options.logFunction),p.logLevel=this._options.debug||0,this._api=new jn(t),this._socket=this._createServerConnection(),!x.supports.audioVideo&&!x.supports.data){this._delayedAbort(y.BrowserIncompatible,"The current browser does not support WebRTC");return}if(n&&!x.validateId(n)){this._delayedAbort(y.InvalidID,`ID "${n}" is invalid`);return}n?this._initialize(n):this._api.retrieveId().then(i=>this._initialize(i)).catch(i=>this._abort(y.ServerError,i))}_createServerConnection(){const e=new zn(this._options.secure,this._options.host,this._options.port,this._options.path,this._options.key,this._options.pingInterval);return e.on(A.Message,t=>{this._handleMessage(t)}),e.on(A.Error,t=>{this._abort(y.SocketError,t)}),e.on(A.Disconnected,()=>{this.disconnected||(this.emitError(y.Network,"Lost connection to server."),this.disconnect())}),e.on(A.Close,()=>{this.disconnected||this._abort(y.SocketClosed,"Underlying socket is already closed.")}),e}_initialize(e){this._id=e,this.socket.start(e,this._options.token)}_handleMessage(e){const t=e.type,n=e.payload,i=e.src;switch(t){case S.Open:this._lastServerId=this.id,this._open=!0,this.emit("open",this.id);break;case S.Error:this._abort(y.ServerError,n.msg);break;case S.IdTaken:this._abort(y.UnavailableID,`ID "${this.id}" is taken`);break;case S.InvalidKey:this._abort(y.InvalidKey,`API KEY "${this._options.key}" is invalid`);break;case S.Leave:p.log(`Received leave message from ${i}`),this._cleanupPeer(i),this._connections.delete(i);break;case S.Expire:this.emitError(y.PeerUnavailable,`Could not connect to peer ${i}`);break;case S.Offer:{const r=n.connectionId;let o=this.getConnection(i,r);if(o&&(o.close(),p.warn(`Offer received for existing Connection ID:${r}`)),n.type===M.Media){const c=new ne(i,this,{connectionId:r,_payload:n,metadata:n.metadata});o=c,this._addConnection(i,o),this.emit("call",c)}else if(n.type===M.Data){const c=new this._serializers[n.serialization](i,this,{connectionId:r,_payload:n,metadata:n.metadata,label:n.label,serialization:n.serialization,reliable:n.reliable});o=c,this._addConnection(i,o),this.emit("connection",c)}else{p.warn(`Received malformed connection type:${n.type}`);return}const a=this._getMessages(r);for(const c of a)o.handleMessage(c);break}default:{if(!n){p.warn(`You received a malformed message from ${i} of type ${t}`);return}const r=n.connectionId,o=this.getConnection(i,r);o&&o.peerConnection?o.handleMessage(e):r?this._storeMessage(r,e):p.warn("You received an unrecognized message:",e);break}}}_storeMessage(e,t){this._lostMessages.has(e)||this._lostMessages.set(e,[]),this._lostMessages.get(e).push(t)}_getMessages(e){const t=this._lostMessages.get(e);return t?(this._lostMessages.delete(e),t):[]}connect(e,t={}){if(t={serialization:"default",...t},this.disconnected){p.warn("You cannot connect to a new Peer because you called .disconnect() on this Peer and ended your connection with the server. You can create a new Peer to reconnect, or call reconnect on this peer if you believe its ID to still be available."),this.emitError(y.Disconnected,"Cannot connect to new Peer after disconnecting from server.");return}const n=new this._serializers[t.serialization](e,this,t);return this._addConnection(e,n),n}call(e,t,n={}){if(this.disconnected){p.warn("You cannot connect to a new Peer because you called .disconnect() on this Peer and ended your connection with the server. You can create a new Peer to reconnect."),this.emitError(y.Disconnected,"Cannot connect to new Peer after disconnecting from server.");return}if(!t){p.error("To call a peer, you must provide a stream from your browser's `getUserMedia`.");return}const i=new ne(e,this,{...n,_stream:t});return this._addConnection(e,i),i}_addConnection(e,t){p.log(`add connection ${t.type}:${t.connectionId} to peerId:${e}`),this._connections.has(e)||this._connections.set(e,[]),this._connections.get(e).push(t)}_removeConnection(e){const t=this._connections.get(e.peer);if(t){const n=t.indexOf(e);n!==-1&&t.splice(n,1)}this._lostMessages.delete(e.connectionId)}getConnection(e,t){const n=this._connections.get(e);if(!n)return null;for(const i of n)if(i.connectionId===t)return i;return null}_delayedAbort(e,t){setTimeout(()=>{this._abort(e,t)},0)}_abort(e,t){p.error("Aborting!"),this.emitError(e,t),this._lastServerId?this.disconnect():this.destroy()}destroy(){this.destroyed||(p.log(`Destroy peer with ID:${this.id}`),this.disconnect(),this._cleanup(),this._destroyed=!0,this.emit("close"))}_cleanup(){for(const e of this._connections.keys())this._cleanupPeer(e),this._connections.delete(e);this.socket.removeAllListeners()}_cleanupPeer(e){const t=this._connections.get(e);if(t)for(const n of t)n.close()}disconnect(){if(this.disconnected)return;const e=this.id;p.log(`Disconnect peer with ID:${e}`),this._disconnected=!0,this._open=!1,this.socket.close(),this._lastServerId=e,this._id=null,this.emit("disconnected",e)}reconnect(){if(this.disconnected&&!this.destroyed)p.log(`Attempting reconnection to server with ID ${this._lastServerId}`),this._disconnected=!1,this._initialize(this._lastServerId);else{if(this.destroyed)throw new Error("This peer cannot reconnect to the server. It has already been destroyed.");if(!this.disconnected&&!this.open)p.error("In a hurry? We're still trying to make the initial connection!");else throw new Error(`Peer ${this.id} cannot reconnect because it is not disconnected from the server!`)}}listAllPeers(e=t=>{}){this._api.listAllPeers().then(t=>e(t)).catch(t=>this._abort(y.ServerError,t))}};We=new WeakMap,W(J,We,J.DEFAULT_KEY="peerjs");let Pe=J;var Hn=Pe;class Vn{constructor(e){this.config=e,this.peer=null,this.localStream=null,this.connections={},this.callbacks={onStream:null,onPeerLeft:null,onError:null,onScreenShareEnded:null}}buildIceServers(){const e=[{urls:"stun:stun.l.google.com:19302"},{urls:"stun:stun1.l.google.com:19302"}],t=Array.isArray(this.config.iceServers)?this.config.iceServers:[];return[...e,...t]}async initialize(e,t=0){return new Promise((n,i)=>{const r=t===0?e:`${e}-r${Math.random().toString(36).slice(2,6)}`;this.peer=new Hn(r,{host:this.config.peerServer.host,port:this.config.peerServer.port,path:this.config.peerServer.path||"/peerjs",secure:this.config.peerServer.secure??!1,config:{iceServers:this.buildIceServers()}});let o=!1;this.peer.on("open",a=>{o=!0,console.log("Peer initialized:",a),this.actualPeerId=a,n(a)}),this.peer.on("error",async a=>{if(!o&&a&&a.type==="unavailable-id"&&t<1){console.warn(`Peer id "${r}" taken — retrying with a suffix`);try{this.peer.destroy()}catch{}this.peer=null;try{const c=await this.initialize(e,t+1);o=!0,n(c)}catch(c){i(c)}return}console.error("Peer error:",a),this.callbacks.onError&&this.callbacks.onError(a),o||i(a)}),this.peer.on("call",a=>{this.handleIncomingCall(a)}),this.peer.on("disconnected",()=>{this._disposed||(console.warn("PeerJS signalling disconnected — attempting reconnect"),setTimeout(()=>{try{this.peer&&!this.peer.destroyed&&this.peer.reconnect()}catch(a){console.warn("Peer reconnect threw:",a&&a.message)}},1e3))})})}async getLocalStream(){if(this.localStream)return this.localStream;try{return this.localStream=await navigator.mediaDevices.getUserMedia({video:!0,audio:!0}),this.localStream}catch(e){throw console.error("Failed to get local stream:",e),this.callbacks.onError&&this.callbacks.onError(e),e}}async handleIncomingCall(e){if(this.connections[e.peer]){console.log("Duplicate incoming call from",e.peer,"— closing");try{e.close()}catch{}return}this.connections[e.peer]={call:e,stream:null};const t=await this.getLocalStream();e.answer(t),e.on("stream",n=>{console.log("Received stream from:",e.peer),this.connections[e.peer]={call:e,stream:n},this.callbacks.onStream&&this.callbacks.onStream(e.peer,n,!1)}),e.on("close",()=>{console.log("Call closed:",e.peer),delete this.connections[e.peer],this.callbacks.onPeerLeft&&this.callbacks.onPeerLeft(e.peer)})}async callPeer(e){if(this.connections[e]){console.log("Already connected to:",e);return}if(this.peer&&this.peer.id&&this.peer.id>e){console.log(`Waiting for ${e} to call us (our id ${this.peer.id} > theirs)`);return}this.connections[e]={call:null,stream:null};const t=await this.getLocalStream();if(this.connections[e]&&this.connections[e].call)return;const n=this.peer.call(e,t);this.connections[e]={call:n,stream:null},n.on("stream",i=>{console.log("Received stream from:",e),this.connections[e]={call:n,stream:i},this.callbacks.onStream&&this.callbacks.onStream(e,i,!1)}),n.on("close",()=>{console.log("Call closed:",e),delete this.connections[e],this.callbacks.onPeerLeft&&this.callbacks.onPeerLeft(e)}),n.on("error",i=>{console.error("Call error:",i),delete this.connections[e]})}toggleVideo(){if(this.localStream){const e=this.localStream.getVideoTracks()[0];if(e)return e.enabled=!e.enabled,e.enabled}return!1}toggleAudio(){if(this.localStream){const e=this.localStream.getAudioTracks()[0];if(e)return e.enabled=!e.enabled,e.enabled}return!1}replaceVideoTrackOnAllConnections(e){for(const{call:t}of Object.values(this.connections)){const n=t&&t.peerConnection;if(!n)continue;const i=n.getSenders().find(r=>r.track&&r.track.kind==="video");i&&i.replaceTrack(e).catch(r=>console.warn("replaceTrack failed:",r&&r.message))}}async startScreenShare(){if(!navigator.mediaDevices||!navigator.mediaDevices.getDisplayMedia)throw new Error("Screen sharing is not supported in this browser");const t=(await navigator.mediaDevices.getDisplayMedia({video:!0,audio:!1})).getVideoTracks()[0];if(!t)throw new Error("Could not obtain display video track");return this.cameraVideoTrack=this.localStream.getVideoTracks()[0]||null,this.replaceVideoTrackOnAllConnections(t),this.cameraVideoTrack&&this.localStream.removeTrack(this.cameraVideoTrack),this.localStream.addTrack(t),this.screenTrack=t,t.addEventListener("ended",async()=>{const n=!!this.screenTrack;if(await this.stopScreenShare().catch(()=>{}),n&&this.callbacks.onScreenShareEnded)try{this.callbacks.onScreenShareEnded()}catch(i){console.warn(i)}}),t}async stopScreenShare(){if(!this.screenTrack)return!1;try{this.screenTrack.stop()}catch{}let e=this.cameraVideoTrack;if(!e||e.readyState==="ended")try{e=(await navigator.mediaDevices.getUserMedia({video:!0,audio:!1})).getVideoTracks()[0]}catch(t){console.warn("Could not restore camera after screen share:",t&&t.message),e=null}if(e){this.replaceVideoTrackOnAllConnections(e);try{this.localStream.removeTrack(this.screenTrack)}catch{}this.localStream.addTrack(e),this.cameraVideoTrack=e}return this.screenTrack=null,!0}isScreenSharing(){return!!this.screenTrack}on(e,t){this.callbacks.hasOwnProperty("on"+e.charAt(0).toUpperCase()+e.slice(1))&&(this.callbacks["on"+e.charAt(0).toUpperCase()+e.slice(1)]=t)}disconnect(){this._disposed=!0,Object.values(this.connections).forEach(({call:e})=>{e.close()}),this.connections={},this.localStream&&(this.localStream.getTracks().forEach(e=>e.stop()),this.localStream=null),this.peer&&(this.peer.destroy(),this.peer=null)}}const P=Object.create(null);P.open="0",P.close="1",P.ping="2",P.pong="3",P.message="4",P.upgrade="5",P.noop="6";const ie=Object.create(null);Object.keys(P).forEach(s=>{ie[P[s]]=s});const Ee={type:"error",data:"parser error"},Kt=typeof Blob=="function"||typeof Blob<"u"&&Object.prototype.toString.call(Blob)==="[object BlobConstructor]",Jt=typeof ArrayBuffer=="function",Wt=s=>typeof ArrayBuffer.isView=="function"?ArrayBuffer.isView(s):s&&s.buffer instanceof ArrayBuffer,Me=({type:s,data:e},t,n)=>Kt&&e instanceof Blob?t?n(e):Yt(e,n):Jt&&(e instanceof ArrayBuffer||Wt(e))?t?n(e):Yt(new Blob([e]),n):n(P[s]+(e||"")),Yt=(s,e)=>{const t=new FileReader;return t.onload=function(){const n=t.result.split(",")[1];e("b"+(n||""))},t.readAsDataURL(s)};function Gt(s){return s instanceof Uint8Array?s:s instanceof ArrayBuffer?new Uint8Array(s):new Uint8Array(s.buffer,s.byteOffset,s.byteLength)}let Ae;function Kn(s,e){if(Kt&&s.data instanceof Blob)return s.data.arrayBuffer().then(Gt).then(e);if(Jt&&(s.data instanceof ArrayBuffer||Wt(s.data)))return e(Gt(s.data));Me(s,!1,t=>{Ae||(Ae=new TextEncoder),e(Ae.encode(t))})}const Qt="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",F=typeof Uint8Array>"u"?[]:new Uint8Array(256);for(let s=0;s<Qt.length;s++)F[Qt.charCodeAt(s)]=s;const Jn=s=>{let e=s.length*.75,t=s.length,n,i=0,r,o,a,c;s[s.length-1]==="="&&(e--,s[s.length-2]==="="&&e--);const h=new ArrayBuffer(e),l=new Uint8Array(h);for(n=0;n<t;n+=4)r=F[s.charCodeAt(n)],o=F[s.charCodeAt(n+1)],a=F[s.charCodeAt(n+2)],c=F[s.charCodeAt(n+3)],l[i++]=r<<2|o>>4,l[i++]=(o&15)<<4|a>>2,l[i++]=(a&3)<<6|c&63;return h},Wn=typeof ArrayBuffer=="function",Ie=(s,e)=>{if(typeof s!="string")return{type:"message",data:Xt(s,e)};const t=s.charAt(0);return t==="b"?{type:"message",data:Yn(s.substring(1),e)}:ie[t]?s.length>1?{type:ie[t],data:s.substring(1)}:{type:ie[t]}:Ee},Yn=(s,e)=>{if(Wn){const t=Jn(s);return Xt(t,e)}else return{base64:!0,data:s}},Xt=(s,e)=>{switch(e){case"blob":return s instanceof Blob?s:new Blob([s]);case"arraybuffer":default:return s instanceof ArrayBuffer?s:s.buffer}},Zt="",Gn=(s,e)=>{const t=s.length,n=new Array(t);let i=0;s.forEach((r,o)=>{Me(r,!1,a=>{n[o]=a,++i===t&&e(n.join(Zt))})})},Qn=(s,e)=>{const t=s.split(Zt),n=[];for(let i=0;i<t.length;i++){const r=Ie(t[i],e);if(n.push(r),r.type==="error")break}return n};function Xn(){return new TransformStream({transform(s,e){Kn(s,t=>{const n=t.length;let i;if(n<126)i=new Uint8Array(1),new DataView(i.buffer).setUint8(0,n);else if(n<65536){i=new Uint8Array(3);const r=new DataView(i.buffer);r.setUint8(0,126),r.setUint16(1,n)}else{i=new Uint8Array(9);const r=new DataView(i.buffer);r.setUint8(0,127),r.setBigUint64(1,BigInt(n))}s.data&&typeof s.data!="string"&&(i[0]|=128),e.enqueue(i),e.enqueue(t)})}})}let Oe;function re(s){return s.reduce((e,t)=>e+t.length,0)}function oe(s,e){if(s[0].length===e)return s.shift();const t=new Uint8Array(e);let n=0;for(let i=0;i<e;i++)t[i]=s[0][n++],n===s[0].length&&(s.shift(),n=0);return s.length&&n<s[0].length&&(s[0]=s[0].slice(n)),t}function Zn(s,e){Oe||(Oe=new TextDecoder);const t=[];let n=0,i=-1,r=!1;return new TransformStream({transform(o,a){for(t.push(o);;){if(n===0){if(re(t)<1)break;const c=oe(t,1);r=(c[0]&128)===128,i=c[0]&127,i<126?n=3:i===126?n=1:n=2}else if(n===1){if(re(t)<2)break;const c=oe(t,2);i=new DataView(c.buffer,c.byteOffset,c.length).getUint16(0),n=3}else if(n===2){if(re(t)<8)break;const c=oe(t,8),h=new DataView(c.buffer,c.byteOffset,c.length),l=h.getUint32(0);if(l>Math.pow(2,21)-1){a.enqueue(Ee);break}i=l*Math.pow(2,32)+h.getUint32(4),n=3}else{if(re(t)<i)break;const c=oe(t,i);a.enqueue(Ie(r?c:Oe.decode(c),e)),n=0}if(i===0||i>s){a.enqueue(Ee);break}}}})}const en=4;function b(s){if(s)return es(s)}function es(s){for(var e in b.prototype)s[e]=b.prototype[e];return s}b.prototype.on=b.prototype.addEventListener=function(s,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+s]=this._callbacks["$"+s]||[]).push(e),this},b.prototype.once=function(s,e){function t(){this.off(s,t),e.apply(this,arguments)}return t.fn=e,this.on(s,t),this},b.prototype.off=b.prototype.removeListener=b.prototype.removeAllListeners=b.prototype.removeEventListener=function(s,e){if(this._callbacks=this._callbacks||{},arguments.length==0)return this._callbacks={},this;var t=this._callbacks["$"+s];if(!t)return this;if(arguments.length==1)return delete this._callbacks["$"+s],this;for(var n,i=0;i<t.length;i++)if(n=t[i],n===e||n.fn===e){t.splice(i,1);break}return t.length===0&&delete this._callbacks["$"+s],this},b.prototype.emit=function(s){this._callbacks=this._callbacks||{};for(var e=new Array(arguments.length-1),t=this._callbacks["$"+s],n=1;n<arguments.length;n++)e[n-1]=arguments[n];if(t){t=t.slice(0);for(var n=0,i=t.length;n<i;++n)t[n].apply(this,e)}return this},b.prototype.emitReserved=b.prototype.emit,b.prototype.listeners=function(s){return this._callbacks=this._callbacks||{},this._callbacks["$"+s]||[]},b.prototype.hasListeners=function(s){return!!this.listeners(s).length};const ae=typeof Promise=="function"&&typeof Promise.resolve=="function"?e=>Promise.resolve().then(e):(e,t)=>t(e,0),T=typeof self<"u"?self:typeof window<"u"?window:Function("return this")(),ts="arraybuffer";function oi(){}function tn(s,...e){return e.reduce((t,n)=>(s.hasOwnProperty(n)&&(t[n]=s[n]),t),{})}const ns=T.setTimeout,ss=T.clearTimeout;function ce(s,e){e.useNativeTimers?(s.setTimeoutFn=ns.bind(T),s.clearTimeoutFn=ss.bind(T)):(s.setTimeoutFn=T.setTimeout.bind(T),s.clearTimeoutFn=T.clearTimeout.bind(T))}const is=1.33;function rs(s){return typeof s=="string"?os(s):Math.ceil((s.byteLength||s.size)*is)}function os(s){let e=0,t=0;for(let n=0,i=s.length;n<i;n++)e=s.charCodeAt(n),e<128?t+=1:e<2048?t+=2:e<55296||e>=57344?t+=3:(n++,t+=4);return t}function nn(){return Date.now().toString(36).substring(3)+Math.random().toString(36).substring(2,5)}function as(s){let e="";for(let t in s)s.hasOwnProperty(t)&&(e.length&&(e+="&"),e+=encodeURIComponent(t)+"="+encodeURIComponent(s[t]));return e}function cs(s){let e={},t=s.split("&");for(let n=0,i=t.length;n<i;n++){let r=t[n].split("=");e[decodeURIComponent(r[0])]=decodeURIComponent(r[1])}return e}class hs extends Error{constructor(e,t,n){super(e),this.description=t,this.context=n,this.type="TransportError"}}class De extends b{constructor(e){super(),this.writable=!1,ce(this,e),this.opts=e,this.query=e.query,this.socket=e.socket,this.supportsBinary=!e.forceBase64}onError(e,t,n){return super.emitReserved("error",new hs(e,t,n)),this}open(){return this.readyState="opening",this.doOpen(),this}close(){return(this.readyState==="opening"||this.readyState==="open")&&(this.doClose(),this.onClose()),this}send(e){this.readyState==="open"&&this.write(e)}onOpen(){this.readyState="open",this.writable=!0,super.emitReserved("open")}onData(e){const t=Ie(e,this.socket.binaryType);this.onPacket(t)}onPacket(e){super.emitReserved("packet",e)}onClose(e){this.readyState="closed",super.emitReserved("close",e)}pause(e){}createUri(e,t={}){return e+"://"+this._hostname()+this._port()+this.opts.path+this._query(t)}_hostname(){const e=this.opts.hostname;return e.indexOf(":")===-1?e:"["+e+"]"}_port(){return this.opts.port&&(this.opts.secure&&Number(this.opts.port)!==443||!this.opts.secure&&Number(this.opts.port)!==80)?":"+this.opts.port:""}_query(e){const t=as(e);return t.length?"?"+t:""}}class ls extends De{constructor(){super(...arguments),this._polling=!1}get name(){return"polling"}doOpen(){this._poll()}pause(e){this.readyState="pausing";const t=()=>{this.readyState="paused",e()};if(this._polling||!this.writable){let n=0;this._polling&&(n++,this.once("pollComplete",function(){--n||t()})),this.writable||(n++,this.once("drain",function(){--n||t()}))}else t()}_poll(){this._polling=!0,this.doPoll(),this.emitReserved("poll")}onData(e){const t=n=>{if(this.readyState==="opening"&&n.type==="open"&&this.onOpen(),n.type==="close")return this.onClose({description:"transport closed by the server"}),!1;this.onPacket(n)};Qn(e,this.socket.binaryType).forEach(t),this.readyState!=="closed"&&(this._polling=!1,this.emitReserved("pollComplete"),this.readyState==="open"&&this._poll())}doClose(){const e=()=>{this.write([{type:"close"}])};this.readyState==="open"?e():this.once("open",e)}write(e){this.writable=!1,Gn(e,t=>{this.doWrite(t,()=>{this.writable=!0,this.emitReserved("drain")})})}uri(){const e=this.opts.secure?"https":"http",t=this.query||{};return this.opts.timestampRequests!==!1&&(t[this.opts.timestampParam]=nn()),!this.supportsBinary&&!t.sid&&(t.b64=1),this.createUri(e,t)}}let sn=!1;try{sn=typeof XMLHttpRequest<"u"&&"withCredentials"in new XMLHttpRequest}catch{}const ds=sn;function us(){}class ps extends ls{constructor(e){if(super(e),typeof location<"u"){const t=location.protocol==="https:";let n=location.port;n||(n=t?"443":"80"),this.xd=typeof location<"u"&&e.hostname!==location.hostname||n!==e.port}}doWrite(e,t){const n=this.request({method:"POST",data:e});n.on("success",t),n.on("error",(i,r)=>{this.onError("xhr post error",i,r)})}doPoll(){const e=this.request();e.on("data",this.onData.bind(this)),e.on("error",(t,n)=>{this.onError("xhr poll error",t,n)}),this.pollXhr=e}}class E extends b{constructor(e,t,n){super(),this.createRequest=e,ce(this,n),this._opts=n,this._method=n.method||"GET",this._uri=t,this._data=n.data!==void 0?n.data:null,this._create()}_create(){var e;const t=tn(this._opts,"agent","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","autoUnref");t.xdomain=!!this._opts.xd;const n=this._xhr=this.createRequest(t);try{n.open(this._method,this._uri,!0);try{if(this._opts.extraHeaders){n.setDisableHeaderCheck&&n.setDisableHeaderCheck(!0);for(let i in this._opts.extraHeaders)this._opts.extraHeaders.hasOwnProperty(i)&&n.setRequestHeader(i,this._opts.extraHeaders[i])}}catch{}if(this._method==="POST")try{n.setRequestHeader("Content-type","text/plain;charset=UTF-8")}catch{}try{n.setRequestHeader("Accept","*/*")}catch{}(e=this._opts.cookieJar)===null||e===void 0||e.addCookies(n),"withCredentials"in n&&(n.withCredentials=this._opts.withCredentials),this._opts.requestTimeout&&(n.timeout=this._opts.requestTimeout),n.onreadystatechange=()=>{var i;n.readyState===3&&((i=this._opts.cookieJar)===null||i===void 0||i.parseCookies(n.getResponseHeader("set-cookie"))),n.readyState===4&&(n.status===200||n.status===1223?this._onLoad():this.setTimeoutFn(()=>{this._onError(typeof n.status=="number"?n.status:0)},0))},n.send(this._data)}catch(i){this.setTimeoutFn(()=>{this._onError(i)},0);return}typeof document<"u"&&(this._index=E.requestsCount++,E.requests[this._index]=this)}_onError(e){this.emitReserved("error",e,this._xhr),this._cleanup(!0)}_cleanup(e){if(!(typeof this._xhr>"u"||this._xhr===null)){if(this._xhr.onreadystatechange=us,e)try{this._xhr.abort()}catch{}typeof document<"u"&&delete E.requests[this._index],this._xhr=null}}_onLoad(){const e=this._xhr.responseText;e!==null&&(this.emitReserved("data",e),this.emitReserved("success"),this._cleanup())}abort(){this._cleanup()}}if(E.requestsCount=0,E.requests={},typeof document<"u"){if(typeof attachEvent=="function")attachEvent("onunload",rn);else if(typeof addEventListener=="function"){const s="onpagehide"in T?"pagehide":"unload";addEventListener(s,rn,!1)}}function rn(){for(let s in E.requests)E.requests.hasOwnProperty(s)&&E.requests[s].abort()}const fs=function(){const s=on({xdomain:!1});return s&&s.responseType!==null}();class ms extends ps{constructor(e){super(e);const t=e&&e.forceBase64;this.supportsBinary=fs&&!t}request(e={}){return Object.assign(e,{xd:this.xd},this.opts),new E(on,this.uri(),e)}}function on(s){const e=s.xdomain;try{if(typeof XMLHttpRequest<"u"&&(!e||ds))return new XMLHttpRequest}catch{}if(!e)try{return new T[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP")}catch{}}const an=typeof navigator<"u"&&typeof navigator.product=="string"&&navigator.product.toLowerCase()==="reactnative";class gs extends De{get name(){return"websocket"}doOpen(){const e=this.uri(),t=this.opts.protocols,n=an?{}:tn(this.opts,"agent","perMessageDeflate","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","localAddress","protocolVersion","origin","maxPayload","family","checkServerIdentity");this.opts.extraHeaders&&(n.headers=this.opts.extraHeaders);try{this.ws=this.createSocket(e,t,n)}catch(i){return this.emitReserved("error",i)}this.ws.binaryType=this.socket.binaryType,this.addEventListeners()}addEventListeners(){this.ws.onopen=()=>{this.opts.autoUnref&&this.ws._socket.unref(),this.onOpen()},this.ws.onclose=e=>this.onClose({description:"websocket connection closed",context:e}),this.ws.onmessage=e=>this.onData(e.data),this.ws.onerror=e=>this.onError("websocket error",e)}write(e){this.writable=!1;for(let t=0;t<e.length;t++){const n=e[t],i=t===e.length-1;Me(n,this.supportsBinary,r=>{try{this.doWrite(n,r)}catch{}i&&ae(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){typeof this.ws<"u"&&(this.ws.onerror=()=>{},this.ws.close(),this.ws=null)}uri(){const e=this.opts.secure?"wss":"ws",t=this.query||{};return this.opts.timestampRequests&&(t[this.opts.timestampParam]=nn()),this.supportsBinary||(t.b64=1),this.createUri(e,t)}}const Le=T.WebSocket||T.MozWebSocket;class ys extends gs{createSocket(e,t,n){return an?new Le(e,t,n):t?new Le(e,t):new Le(e)}doWrite(e,t){this.ws.send(t)}}class bs extends De{get name(){return"webtransport"}doOpen(){try{this._transport=new WebTransport(this.createUri("https"),this.opts.transportOptions[this.name])}catch(e){return this.emitReserved("error",e)}this._transport.closed.then(()=>{this.onClose()}).catch(e=>{this.onError("webtransport error",e)}),this._transport.ready.then(()=>{this._transport.createBidirectionalStream().then(e=>{const t=Zn(Number.MAX_SAFE_INTEGER,this.socket.binaryType),n=e.readable.pipeThrough(t).getReader(),i=Xn();i.readable.pipeTo(e.writable),this._writer=i.writable.getWriter();const r=()=>{n.read().then(({done:a,value:c})=>{a||(this.onPacket(c),r())}).catch(a=>{})};r();const o={type:"open"};this.query.sid&&(o.data=`{"sid":"${this.query.sid}"}`),this._writer.write(o).then(()=>this.onOpen())})})}write(e){this.writable=!1;for(let t=0;t<e.length;t++){const n=e[t],i=t===e.length-1;this._writer.write(n).then(()=>{i&&ae(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){var e;(e=this._transport)===null||e===void 0||e.close()}}const _s={websocket:ys,webtransport:bs,polling:ms},vs=/^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,Ss=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];function $e(s){if(s.length>8e3)throw"URI too long";const e=s,t=s.indexOf("["),n=s.indexOf("]");t!=-1&&n!=-1&&(s=s.substring(0,t)+s.substring(t,n).replace(/:/g,";")+s.substring(n,s.length));let i=vs.exec(s||""),r={},o=14;for(;o--;)r[Ss[o]]=i[o]||"";return t!=-1&&n!=-1&&(r.source=e,r.host=r.host.substring(1,r.host.length-1).replace(/;/g,":"),r.authority=r.authority.replace("[","").replace("]","").replace(/;/g,":"),r.ipv6uri=!0),r.pathNames=Cs(r,r.path),r.queryKey=xs(r,r.query),r}function Cs(s,e){const t=/\/{2,9}/g,n=e.replace(t,"/").split("/");return(e.slice(0,1)=="/"||e.length===0)&&n.splice(0,1),e.slice(-1)=="/"&&n.splice(n.length-1,1),n}function xs(s,e){const t={};return e.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,function(n,i,r){i&&(t[i]=r)}),t}const Be=typeof addEventListener=="function"&&typeof removeEventListener=="function",he=[];Be&&addEventListener("offline",()=>{he.forEach(s=>s())},!1);class I extends b{constructor(e,t){if(super(),this.binaryType=ts,this.writeBuffer=[],this._prevBufferLen=0,this._pingInterval=-1,this._pingTimeout=-1,this._maxPayload=-1,this._pingTimeoutTime=1/0,e&&typeof e=="object"&&(t=e,e=null),e){const n=$e(e);t.hostname=n.host,t.secure=n.protocol==="https"||n.protocol==="wss",t.port=n.port,n.query&&(t.query=n.query)}else t.host&&(t.hostname=$e(t.host).host);ce(this,t),this.secure=t.secure!=null?t.secure:typeof location<"u"&&location.protocol==="https:",t.hostname&&!t.port&&(t.port=this.secure?"443":"80"),this.hostname=t.hostname||(typeof location<"u"?location.hostname:"localhost"),this.port=t.port||(typeof location<"u"&&location.port?location.port:this.secure?"443":"80"),this.transports=[],this._transportsByName={},t.transports.forEach(n=>{const i=n.prototype.name;this.transports.push(i),this._transportsByName[i]=n}),this.opts=Object.assign({path:"/engine.io",agent:!1,withCredentials:!1,upgrade:!0,timestampParam:"t",rememberUpgrade:!1,addTrailingSlash:!0,rejectUnauthorized:!0,perMessageDeflate:{threshold:1024},transportOptions:{},closeOnBeforeunload:!1},t),this.opts.path=this.opts.path.replace(/\/$/,"")+(this.opts.addTrailingSlash?"/":""),typeof this.opts.query=="string"&&(this.opts.query=cs(this.opts.query)),Be&&(this.opts.closeOnBeforeunload&&(this._beforeunloadEventListener=()=>{this.transport&&(this.transport.removeAllListeners(),this.transport.close())},addEventListener("beforeunload",this._beforeunloadEventListener,!1)),this.hostname!=="localhost"&&(this._offlineEventListener=()=>{this._onClose("transport close",{description:"network connection lost"})},he.push(this._offlineEventListener))),this.opts.withCredentials&&(this._cookieJar=void 0),this._open()}createTransport(e){const t=Object.assign({},this.opts.query);t.EIO=en,t.transport=e,this.id&&(t.sid=this.id);const n=Object.assign({},this.opts,{query:t,socket:this,hostname:this.hostname,secure:this.secure,port:this.port},this.opts.transportOptions[e]);return new this._transportsByName[e](n)}_open(){if(this.transports.length===0){this.setTimeoutFn(()=>{this.emitReserved("error","No transports available")},0);return}const e=this.opts.rememberUpgrade&&I.priorWebsocketSuccess&&this.transports.indexOf("websocket")!==-1?"websocket":this.transports[0];this.readyState="opening";const t=this.createTransport(e);t.open(),this.setTransport(t)}setTransport(e){this.transport&&this.transport.removeAllListeners(),this.transport=e,e.on("drain",this._onDrain.bind(this)).on("packet",this._onPacket.bind(this)).on("error",this._onError.bind(this)).on("close",t=>this._onClose("transport close",t))}onOpen(){this.readyState="open",I.priorWebsocketSuccess=this.transport.name==="websocket",this.emitReserved("open"),this.flush()}_onPacket(e){if(this.readyState==="opening"||this.readyState==="open"||this.readyState==="closing")switch(this.emitReserved("packet",e),this.emitReserved("heartbeat"),e.type){case"open":this.onHandshake(JSON.parse(e.data));break;case"ping":this._sendPacket("pong"),this.emitReserved("ping"),this.emitReserved("pong"),this._resetPingTimeout();break;case"error":const t=new Error("server error");t.code=e.data,this._onError(t);break;case"message":this.emitReserved("data",e.data),this.emitReserved("message",e.data);break}}onHandshake(e){this.emitReserved("handshake",e),this.id=e.sid,this.transport.query.sid=e.sid,this._pingInterval=e.pingInterval,this._pingTimeout=e.pingTimeout,this._maxPayload=e.maxPayload,this.onOpen(),this.readyState!=="closed"&&this._resetPingTimeout()}_resetPingTimeout(){this.clearTimeoutFn(this._pingTimeoutTimer);const e=this._pingInterval+this._pingTimeout;this._pingTimeoutTime=Date.now()+e,this._pingTimeoutTimer=this.setTimeoutFn(()=>{this._onClose("ping timeout")},e),this.opts.autoUnref&&this._pingTimeoutTimer.unref()}_onDrain(){this.writeBuffer.splice(0,this._prevBufferLen),this._prevBufferLen=0,this.writeBuffer.length===0?this.emitReserved("drain"):this.flush()}flush(){if(this.readyState!=="closed"&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length){const e=this._getWritablePackets();this.transport.send(e),this._prevBufferLen=e.length,this.emitReserved("flush")}}_getWritablePackets(){if(!(this._maxPayload&&this.transport.name==="polling"&&this.writeBuffer.length>1))return this.writeBuffer;let t=1;for(let n=0;n<this.writeBuffer.length;n++){const i=this.writeBuffer[n].data;if(i&&(t+=rs(i)),n>0&&t>this._maxPayload)return this.writeBuffer.slice(0,n);t+=2}return this.writeBuffer}_hasPingExpired(){if(!this._pingTimeoutTime)return!0;const e=Date.now()>this._pingTimeoutTime;return e&&(this._pingTimeoutTime=0,ae(()=>{this._onClose("ping timeout")},this.setTimeoutFn)),e}write(e,t,n){return this._sendPacket("message",e,t,n),this}send(e,t,n){return this._sendPacket("message",e,t,n),this}_sendPacket(e,t,n,i){if(typeof t=="function"&&(i=t,t=void 0),typeof n=="function"&&(i=n,n=null),this.readyState==="closing"||this.readyState==="closed")return;n=n||{},n.compress=n.compress!==!1;const r={type:e,data:t,options:n};this.emitReserved("packetCreate",r),this.writeBuffer.push(r),i&&this.once("flush",i),this.flush()}close(){const e=()=>{this._onClose("forced close"),this.transport.close()},t=()=>{this.off("upgrade",t),this.off("upgradeError",t),e()},n=()=>{this.once("upgrade",t),this.once("upgradeError",t)};return(this.readyState==="opening"||this.readyState==="open")&&(this.readyState="closing",this.writeBuffer.length?this.once("drain",()=>{this.upgrading?n():e()}):this.upgrading?n():e()),this}_onError(e){if(I.priorWebsocketSuccess=!1,this.opts.tryAllTransports&&this.transports.length>1&&this.readyState==="opening")return this.transports.shift(),this._open();this.emitReserved("error",e),this._onClose("transport error",e)}_onClose(e,t){if(this.readyState==="opening"||this.readyState==="open"||this.readyState==="closing"){if(this.clearTimeoutFn(this._pingTimeoutTimer),this.transport.removeAllListeners("close"),this.transport.close(),this.transport.removeAllListeners(),Be&&(this._beforeunloadEventListener&&removeEventListener("beforeunload",this._beforeunloadEventListener,!1),this._offlineEventListener)){const n=he.indexOf(this._offlineEventListener);n!==-1&&he.splice(n,1)}this.readyState="closed",this.id=null,this.emitReserved("close",e,t),this.writeBuffer=[],this._prevBufferLen=0}}}I.protocol=en;class ks extends I{constructor(){super(...arguments),this._upgrades=[]}onOpen(){if(super.onOpen(),this.readyState==="open"&&this.opts.upgrade)for(let e=0;e<this._upgrades.length;e++)this._probe(this._upgrades[e])}_probe(e){let t=this.createTransport(e),n=!1;I.priorWebsocketSuccess=!1;const i=()=>{n||(t.send([{type:"ping",data:"probe"}]),t.once("packet",d=>{if(!n)if(d.type==="pong"&&d.data==="probe"){if(this.upgrading=!0,this.emitReserved("upgrading",t),!t)return;I.priorWebsocketSuccess=t.name==="websocket",this.transport.pause(()=>{n||this.readyState!=="closed"&&(l(),this.setTransport(t),t.send([{type:"upgrade"}]),this.emitReserved("upgrade",t),t=null,this.upgrading=!1,this.flush())})}else{const u=new Error("probe error");u.transport=t.name,this.emitReserved("upgradeError",u)}}))};function r(){n||(n=!0,l(),t.close(),t=null)}const o=d=>{const u=new Error("probe error: "+d);u.transport=t.name,r(),this.emitReserved("upgradeError",u)};function a(){o("transport closed")}function c(){o("socket closed")}function h(d){t&&d.name!==t.name&&r()}const l=()=>{t.removeListener("open",i),t.removeListener("error",o),t.removeListener("close",a),this.off("close",c),this.off("upgrading",h)};t.once("open",i),t.once("error",o),t.once("close",a),this.once("close",c),this.once("upgrading",h),this._upgrades.indexOf("webtransport")!==-1&&e!=="webtransport"?this.setTimeoutFn(()=>{n||t.open()},200):t.open()}onHandshake(e){this._upgrades=this._filterUpgrades(e.upgrades),super.onHandshake(e)}_filterUpgrades(e){const t=[];for(let n=0;n<e.length;n++)~this.transports.indexOf(e[n])&&t.push(e[n]);return t}}let Ts=class extends ks{constructor(e,t={}){const n=typeof e=="object",i=n?{...e}:{...t};(!i.transports||i.transports&&typeof i.transports[0]=="string")&&(i.transports=(i.transports||["polling","websocket","webtransport"]).map(r=>_s[r]).filter(r=>!!r)),super(n?i:e,i)}};function Rs(s,e="",t){let n=s;t=t||typeof location<"u"&&location,s==null&&(s=t.protocol+"//"+t.host),typeof s=="string"&&(s.charAt(0)==="/"&&(s.charAt(1)==="/"?s=t.protocol+s:s=t.host+s),/^(https?|wss?):\/\//.test(s)||(typeof t<"u"?s=t.protocol+"//"+s:s="https://"+s),n=$e(s)),n.port||(/^(http|ws)$/.test(n.protocol)?n.port="80":/^(http|ws)s$/.test(n.protocol)&&(n.port="443")),n.path=n.path||"/";const r=n.host.indexOf(":")!==-1?"["+n.host+"]":n.host;return n.id=n.protocol+"://"+r+":"+n.port+e,n.href=n.protocol+"://"+r+(t&&t.port===n.port?"":":"+n.port),n}const ws=typeof ArrayBuffer=="function",Ps=s=>typeof ArrayBuffer.isView=="function"?ArrayBuffer.isView(s):s.buffer instanceof ArrayBuffer,cn=Object.prototype.toString,Es=typeof Blob=="function"||typeof Blob<"u"&&cn.call(Blob)==="[object BlobConstructor]",Ms=typeof File=="function"||typeof File<"u"&&cn.call(File)==="[object FileConstructor]";function Ue(s){return ws&&(s instanceof ArrayBuffer||Ps(s))||Es&&s instanceof Blob||Ms&&s instanceof File}function le(s,e){if(!s||typeof s!="object")return!1;if(Array.isArray(s)){for(let t=0,n=s.length;t<n;t++)if(le(s[t]))return!0;return!1}if(Ue(s))return!0;if(s.toJSON&&typeof s.toJSON=="function"&&arguments.length===1)return le(s.toJSON(),!0);for(const t in s)if(Object.prototype.hasOwnProperty.call(s,t)&&le(s[t]))return!0;return!1}function As(s){const e=[],t=s.data,n=s;return n.data=ze(t,e),n.attachments=e.length,{packet:n,buffers:e}}function ze(s,e){if(!s)return s;if(Ue(s)){const t={_placeholder:!0,num:e.length};return e.push(s),t}else if(Array.isArray(s)){const t=new Array(s.length);for(let n=0;n<s.length;n++)t[n]=ze(s[n],e);return t}else if(typeof s=="object"&&!(s instanceof Date)){const t={};for(const n in s)Object.prototype.hasOwnProperty.call(s,n)&&(t[n]=ze(s[n],e));return t}return s}function Is(s,e){return s.data=Ne(s.data,e),delete s.attachments,s}function Ne(s,e){if(!s)return s;if(s&&s._placeholder===!0){if(typeof s.num=="number"&&s.num>=0&&s.num<e.length)return e[s.num];throw new Error("illegal attachments")}else if(Array.isArray(s))for(let t=0;t<s.length;t++)s[t]=Ne(s[t],e);else if(typeof s=="object")for(const t in s)Object.prototype.hasOwnProperty.call(s,t)&&(s[t]=Ne(s[t],e));return s}const Os=["connect","connect_error","disconnect","disconnecting","newListener","removeListener"];var m;(function(s){s[s.CONNECT=0]="CONNECT",s[s.DISCONNECT=1]="DISCONNECT",s[s.EVENT=2]="EVENT",s[s.ACK=3]="ACK",s[s.CONNECT_ERROR=4]="CONNECT_ERROR",s[s.BINARY_EVENT=5]="BINARY_EVENT",s[s.BINARY_ACK=6]="BINARY_ACK"})(m||(m={}));class Ds{constructor(e){this.replacer=e}encode(e){return(e.type===m.EVENT||e.type===m.ACK)&&le(e)?this.encodeAsBinary({type:e.type===m.EVENT?m.BINARY_EVENT:m.BINARY_ACK,nsp:e.nsp,data:e.data,id:e.id}):[this.encodeAsString(e)]}encodeAsString(e){let t=""+e.type;return(e.type===m.BINARY_EVENT||e.type===m.BINARY_ACK)&&(t+=e.attachments+"-"),e.nsp&&e.nsp!=="/"&&(t+=e.nsp+","),e.id!=null&&(t+=e.id),e.data!=null&&(t+=JSON.stringify(e.data,this.replacer)),t}encodeAsBinary(e){const t=As(e),n=this.encodeAsString(t.packet),i=t.buffers;return i.unshift(n),i}}class je extends b{constructor(e){super(),this.opts=Object.assign({reviver:void 0,maxAttachments:10},typeof e=="function"?{reviver:e}:e)}add(e){let t;if(typeof e=="string"){if(this.reconstructor)throw new Error("got plaintext data when reconstructing a packet");t=this.decodeString(e);const n=t.type===m.BINARY_EVENT;n||t.type===m.BINARY_ACK?(t.type=n?m.EVENT:m.ACK,this.reconstructor=new Ls(t),t.attachments===0&&super.emitReserved("decoded",t)):super.emitReserved("decoded",t)}else if(Ue(e)||e.base64)if(this.reconstructor)t=this.reconstructor.takeBinaryData(e),t&&(this.reconstructor=null,super.emitReserved("decoded",t));else throw new Error("got binary data when not reconstructing a packet");else throw new Error("Unknown type: "+e)}decodeString(e){let t=0;const n={type:Number(e.charAt(0))};if(m[n.type]===void 0)throw new Error("unknown packet type "+n.type);if(n.type===m.BINARY_EVENT||n.type===m.BINARY_ACK){const r=t+1;for(;e.charAt(++t)!=="-"&&t!=e.length;);const o=e.substring(r,t);if(o!=Number(o)||e.charAt(t)!=="-")throw new Error("Illegal attachments");const a=Number(o);if(!$s(a)||a<0)throw new Error("Illegal attachments");if(a>this.opts.maxAttachments)throw new Error("too many attachments");n.attachments=a}if(e.charAt(t+1)==="/"){const r=t+1;for(;++t&&!(e.charAt(t)===","||t===e.length););n.nsp=e.substring(r,t)}else n.nsp="/";const i=e.charAt(t+1);if(i!==""&&Number(i)==i){const r=t+1;for(;++t;){const o=e.charAt(t);if(o==null||Number(o)!=o){--t;break}if(t===e.length)break}n.id=Number(e.substring(r,t+1))}if(e.charAt(++t)){const r=this.tryParse(e.substr(t));if(je.isPayloadValid(n.type,r))n.data=r;else throw new Error("invalid payload")}return n}tryParse(e){try{return JSON.parse(e,this.opts.reviver)}catch{return!1}}static isPayloadValid(e,t){switch(e){case m.CONNECT:return hn(t);case m.DISCONNECT:return t===void 0;case m.CONNECT_ERROR:return typeof t=="string"||hn(t);case m.EVENT:case m.BINARY_EVENT:return Array.isArray(t)&&(typeof t[0]=="number"||typeof t[0]=="string"&&Os.indexOf(t[0])===-1);case m.ACK:case m.BINARY_ACK:return Array.isArray(t)}}destroy(){this.reconstructor&&(this.reconstructor.finishedReconstruction(),this.reconstructor=null)}}class Ls{constructor(e){this.packet=e,this.buffers=[],this.reconPack=e}takeBinaryData(e){if(this.buffers.push(e),this.buffers.length===this.reconPack.attachments){const t=Is(this.reconPack,this.buffers);return this.finishedReconstruction(),t}return null}finishedReconstruction(){this.reconPack=null,this.buffers=[]}}const $s=Number.isInteger||function(s){return typeof s=="number"&&isFinite(s)&&Math.floor(s)===s};function hn(s){return Object.prototype.toString.call(s)==="[object Object]"}const Bs=Object.freeze(Object.defineProperty({__proto__:null,Decoder:je,Encoder:Ds,get PacketType(){return m}},Symbol.toStringTag,{value:"Module"}));function R(s,e,t){return s.on(e,t),function(){s.off(e,t)}}const Us=Object.freeze({connect:1,connect_error:1,disconnect:1,disconnecting:1,newListener:1,removeListener:1});class ln extends b{constructor(e,t,n){super(),this.connected=!1,this.recovered=!1,this.receiveBuffer=[],this.sendBuffer=[],this._queue=[],this._queueSeq=0,this.ids=0,this.acks={},this.flags={},this.io=e,this.nsp=t,n&&n.auth&&(this.auth=n.auth),this._opts=Object.assign({},n),this.io._autoConnect&&this.open()}get disconnected(){return!this.connected}subEvents(){if(this.subs)return;const e=this.io;this.subs=[R(e,"open",this.onopen.bind(this)),R(e,"packet",this.onpacket.bind(this)),R(e,"error",this.onerror.bind(this)),R(e,"close",this.onclose.bind(this))]}get active(){return!!this.subs}connect(){return this.connected?this:(this.subEvents(),this.io._reconnecting||this.io.open(),this.io._readyState==="open"&&this.onopen(),this)}open(){return this.connect()}send(...e){return e.unshift("message"),this.emit.apply(this,e),this}emit(e,...t){var n,i,r;if(Us.hasOwnProperty(e))throw new Error('"'+e.toString()+'" is a reserved event name');if(t.unshift(e),this._opts.retries&&!this.flags.fromQueue&&!this.flags.volatile)return this._addToQueue(t),this;const o={type:m.EVENT,data:t};if(o.options={},o.options.compress=this.flags.compress!==!1,typeof t[t.length-1]=="function"){const l=this.ids++,d=t.pop();this._registerAckCallback(l,d),o.id=l}const a=(i=(n=this.io.engine)===null||n===void 0?void 0:n.transport)===null||i===void 0?void 0:i.writable,c=this.connected&&!(!((r=this.io.engine)===null||r===void 0)&&r._hasPingExpired());return this.flags.volatile&&!a||(c?(this.notifyOutgoingListeners(o),this.packet(o)):this.sendBuffer.push(o)),this.flags={},this}_registerAckCallback(e,t){var n;const i=(n=this.flags.timeout)!==null&&n!==void 0?n:this._opts.ackTimeout;if(i===void 0){this.acks[e]=t;return}const r=this.io.setTimeoutFn(()=>{delete this.acks[e];for(let a=0;a<this.sendBuffer.length;a++)this.sendBuffer[a].id===e&&this.sendBuffer.splice(a,1);t.call(this,new Error("operation has timed out"))},i),o=(...a)=>{this.io.clearTimeoutFn(r),t.apply(this,a)};o.withError=!0,this.acks[e]=o}emitWithAck(e,...t){return new Promise((n,i)=>{const r=(o,a)=>o?i(o):n(a);r.withError=!0,t.push(r),this.emit(e,...t)})}_addToQueue(e){let t;typeof e[e.length-1]=="function"&&(t=e.pop());const n={id:this._queueSeq++,tryCount:0,pending:!1,args:e,flags:Object.assign({fromQueue:!0},this.flags)};e.push((i,...r)=>(this._queue[0],i!==null?n.tryCount>this._opts.retries&&(this._queue.shift(),t&&t(i)):(this._queue.shift(),t&&t(null,...r)),n.pending=!1,this._drainQueue())),this._queue.push(n),this._drainQueue()}_drainQueue(e=!1){if(!this.connected||this._queue.length===0)return;const t=this._queue[0];t.pending&&!e||(t.pending=!0,t.tryCount++,this.flags=t.flags,this.emit.apply(this,t.args))}packet(e){e.nsp=this.nsp,this.io._packet(e)}onopen(){typeof this.auth=="function"?this.auth(e=>{this._sendConnectPacket(e)}):this._sendConnectPacket(this.auth)}_sendConnectPacket(e){this.packet({type:m.CONNECT,data:this._pid?Object.assign({pid:this._pid,offset:this._lastOffset},e):e})}onerror(e){this.connected||this.emitReserved("connect_error",e)}onclose(e,t){this.connected=!1,delete this.id,this.emitReserved("disconnect",e,t),this._clearAcks()}_clearAcks(){Object.keys(this.acks).forEach(e=>{if(!this.sendBuffer.some(n=>String(n.id)===e)){const n=this.acks[e];delete this.acks[e],n.withError&&n.call(this,new Error("socket has been disconnected"))}})}onpacket(e){if(e.nsp===this.nsp)switch(e.type){case m.CONNECT:e.data&&e.data.sid?this.onconnect(e.data.sid,e.data.pid):this.emitReserved("connect_error",new Error("It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)"));break;case m.EVENT:case m.BINARY_EVENT:this.onevent(e);break;case m.ACK:case m.BINARY_ACK:this.onack(e);break;case m.DISCONNECT:this.ondisconnect();break;case m.CONNECT_ERROR:this.destroy();const n=new Error(e.data.message);n.data=e.data.data,this.emitReserved("connect_error",n);break}}onevent(e){const t=e.data||[];e.id!=null&&t.push(this.ack(e.id)),this.connected?this.emitEvent(t):this.receiveBuffer.push(Object.freeze(t))}emitEvent(e){if(this._anyListeners&&this._anyListeners.length){const t=this._anyListeners.slice();for(const n of t)n.apply(this,e)}super.emit.apply(this,e),this._pid&&e.length&&typeof e[e.length-1]=="string"&&(this._lastOffset=e[e.length-1])}ack(e){const t=this;let n=!1;return function(...i){n||(n=!0,t.packet({type:m.ACK,id:e,data:i}))}}onack(e){const t=this.acks[e.id];typeof t=="function"&&(delete this.acks[e.id],t.withError&&e.data.unshift(null),t.apply(this,e.data))}onconnect(e,t){this.id=e,this.recovered=t&&this._pid===t,this._pid=t,this.connected=!0,this.emitBuffered(),this._drainQueue(!0),this.emitReserved("connect")}emitBuffered(){this.receiveBuffer.forEach(e=>this.emitEvent(e)),this.receiveBuffer=[],this.sendBuffer.forEach(e=>{this.notifyOutgoingListeners(e),this.packet(e)}),this.sendBuffer=[]}ondisconnect(){this.destroy(),this.onclose("io server disconnect")}destroy(){this.subs&&(this.subs.forEach(e=>e()),this.subs=void 0),this.io._destroy(this)}disconnect(){return this.connected&&this.packet({type:m.DISCONNECT}),this.destroy(),this.connected&&this.onclose("io client disconnect"),this}close(){return this.disconnect()}compress(e){return this.flags.compress=e,this}get volatile(){return this.flags.volatile=!0,this}timeout(e){return this.flags.timeout=e,this}onAny(e){return this._anyListeners=this._anyListeners||[],this._anyListeners.push(e),this}prependAny(e){return this._anyListeners=this._anyListeners||[],this._anyListeners.unshift(e),this}offAny(e){if(!this._anyListeners)return this;if(e){const t=this._anyListeners;for(let n=0;n<t.length;n++)if(e===t[n])return t.splice(n,1),this}else this._anyListeners=[];return this}listenersAny(){return this._anyListeners||[]}onAnyOutgoing(e){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.push(e),this}prependAnyOutgoing(e){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.unshift(e),this}offAnyOutgoing(e){if(!this._anyOutgoingListeners)return this;if(e){const t=this._anyOutgoingListeners;for(let n=0;n<t.length;n++)if(e===t[n])return t.splice(n,1),this}else this._anyOutgoingListeners=[];return this}listenersAnyOutgoing(){return this._anyOutgoingListeners||[]}notifyOutgoingListeners(e){if(this._anyOutgoingListeners&&this._anyOutgoingListeners.length){const t=this._anyOutgoingListeners.slice();for(const n of t)n.apply(this,e.data)}}}function z(s){s=s||{},this.ms=s.min||100,this.max=s.max||1e4,this.factor=s.factor||2,this.jitter=s.jitter>0&&s.jitter<=1?s.jitter:0,this.attempts=0}z.prototype.duration=function(){var s=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),t=Math.floor(e*this.jitter*s);s=Math.floor(e*10)&1?s+t:s-t}return Math.min(s,this.max)|0},z.prototype.reset=function(){this.attempts=0},z.prototype.setMin=function(s){this.ms=s},z.prototype.setMax=function(s){this.max=s},z.prototype.setJitter=function(s){this.jitter=s};class qe extends b{constructor(e,t){var n;super(),this.nsps={},this.subs=[],e&&typeof e=="object"&&(t=e,e=void 0),t=t||{},t.path=t.path||"/socket.io",this.opts=t,ce(this,t),this.reconnection(t.reconnection!==!1),this.reconnectionAttempts(t.reconnectionAttempts||1/0),this.reconnectionDelay(t.reconnectionDelay||1e3),this.reconnectionDelayMax(t.reconnectionDelayMax||5e3),this.randomizationFactor((n=t.randomizationFactor)!==null&&n!==void 0?n:.5),this.backoff=new z({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()}),this.timeout(t.timeout==null?2e4:t.timeout),this._readyState="closed",this.uri=e;const i=t.parser||Bs;this.encoder=new i.Encoder,this.decoder=new i.Decoder,this._autoConnect=t.autoConnect!==!1,this._autoConnect&&this.open()}reconnection(e){return arguments.length?(this._reconnection=!!e,e||(this.skipReconnect=!0),this):this._reconnection}reconnectionAttempts(e){return e===void 0?this._reconnectionAttempts:(this._reconnectionAttempts=e,this)}reconnectionDelay(e){var t;return e===void 0?this._reconnectionDelay:(this._reconnectionDelay=e,(t=this.backoff)===null||t===void 0||t.setMin(e),this)}randomizationFactor(e){var t;return e===void 0?this._randomizationFactor:(this._randomizationFactor=e,(t=this.backoff)===null||t===void 0||t.setJitter(e),this)}reconnectionDelayMax(e){var t;return e===void 0?this._reconnectionDelayMax:(this._reconnectionDelayMax=e,(t=this.backoff)===null||t===void 0||t.setMax(e),this)}timeout(e){return arguments.length?(this._timeout=e,this):this._timeout}maybeReconnectOnOpen(){!this._reconnecting&&this._reconnection&&this.backoff.attempts===0&&this.reconnect()}open(e){if(~this._readyState.indexOf("open"))return this;this.engine=new Ts(this.uri,this.opts);const t=this.engine,n=this;this._readyState="opening",this.skipReconnect=!1;const i=R(t,"open",function(){n.onopen(),e&&e()}),r=a=>{this.cleanup(),this._readyState="closed",this.emitReserved("error",a),e?e(a):this.maybeReconnectOnOpen()},o=R(t,"error",r);if(this._timeout!==!1){const a=this._timeout,c=this.setTimeoutFn(()=>{i(),r(new Error("timeout")),t.close()},a);this.opts.autoUnref&&c.unref(),this.subs.push(()=>{this.clearTimeoutFn(c)})}return this.subs.push(i),this.subs.push(o),this}connect(e){return this.open(e)}onopen(){this.cleanup(),this._readyState="open",this.emitReserved("open");const e=this.engine;this.subs.push(R(e,"ping",this.onping.bind(this)),R(e,"data",this.ondata.bind(this)),R(e,"error",this.onerror.bind(this)),R(e,"close",this.onclose.bind(this)),R(this.decoder,"decoded",this.ondecoded.bind(this)))}onping(){this.emitReserved("ping")}ondata(e){try{this.decoder.add(e)}catch(t){this.onclose("parse error",t)}}ondecoded(e){ae(()=>{this.emitReserved("packet",e)},this.setTimeoutFn)}onerror(e){this.emitReserved("error",e)}socket(e,t){let n=this.nsps[e];return n?this._autoConnect&&!n.active&&n.connect():(n=new ln(this,e,t),this.nsps[e]=n),n}_destroy(e){const t=Object.keys(this.nsps);for(const n of t)if(this.nsps[n].active)return;this._close()}_packet(e){const t=this.encoder.encode(e);for(let n=0;n<t.length;n++)this.engine.write(t[n],e.options)}cleanup(){this.subs.forEach(e=>e()),this.subs.length=0,this.decoder.destroy()}_close(){this.skipReconnect=!0,this._reconnecting=!1,this.onclose("forced close")}disconnect(){return this._close()}onclose(e,t){var n;this.cleanup(),(n=this.engine)===null||n===void 0||n.close(),this.backoff.reset(),this._readyState="closed",this.emitReserved("close",e,t),this._reconnection&&!this.skipReconnect&&this.reconnect()}reconnect(){if(this._reconnecting||this.skipReconnect)return this;const e=this;if(this.backoff.attempts>=this._reconnectionAttempts)this.backoff.reset(),this.emitReserved("reconnect_failed"),this._reconnecting=!1;else{const t=this.backoff.duration();this._reconnecting=!0;const n=this.setTimeoutFn(()=>{e.skipReconnect||(this.emitReserved("reconnect_attempt",e.backoff.attempts),!e.skipReconnect&&e.open(i=>{i?(e._reconnecting=!1,e.reconnect(),this.emitReserved("reconnect_error",i)):e.onreconnect()}))},t);this.opts.autoUnref&&n.unref(),this.subs.push(()=>{this.clearTimeoutFn(n)})}}onreconnect(){const e=this.backoff.attempts;this._reconnecting=!1,this.backoff.reset(),this.emitReserved("reconnect",e)}}const H={};function de(s,e){typeof s=="object"&&(e=s,s=void 0),e=e||{};const t=Rs(s,e.path||"/socket.io"),n=t.source,i=t.id,r=t.path,o=H[i]&&r in H[i].nsps,a=e.forceNew||e["force new connection"]||e.multiplex===!1||o;let c;return a?c=new qe(n,e):(H[i]||(H[i]=new qe(n,e)),c=H[i]),t.query&&!e.query&&(e.query=t.queryKey),c.socket(t.path,e)}Object.assign(de,{Manager:qe,Socket:ln,io:de,connect:de});class zs{constructor(e){this.config=e,this.socket=null,this.callbacks={onMessage:null,onExistingPeers:null,onYouJoined:null,onUserJoined:null,onUserLeft:null,onPeerMediaStateChange:null,onError:null},this.rawListeners=new Map}connect(e){let t=this.config.socketUrl,n="/socket.io/";try{const r=new URL(this.config.socketUrl);t=`${r.protocol}//${r.host}`;const o=r.pathname.replace(/\/+$/,"");o&&(n=`${o}/socket.io/`)}catch{}this.socket=de(t,{path:n,auth:{workspace:e},transports:["websocket","polling"]}),this.socket.on("connect",()=>{console.log("Socket connected")}),this.socket.on("disconnect",()=>{console.log("Socket disconnected")}),this.socket.on("new-message",r=>{this.callbacks.onMessage&&this.callbacks.onMessage(r)}),this.socket.on("existing-peers",r=>{this.callbacks.onExistingPeers&&this.callbacks.onExistingPeers(r)}),this.socket.on("you-joined",r=>{this.callbacks.onYouJoined&&this.callbacks.onYouJoined(r)}),this.socket.on("user-joined",r=>{this.callbacks.onUserJoined&&this.callbacks.onUserJoined(r)}),this.socket.on("user-left",r=>{this.callbacks.onUserLeft&&this.callbacks.onUserLeft(r)}),this.socket.on("peer-media-state-change",r=>{this.callbacks.onPeerMediaStateChange&&this.callbacks.onPeerMediaStateChange(r)});const i=["code-changed","code-language-changed","code-executing","code-execution-result","code-state-sync","code-permission-changed","code-sandbox-toggled","whiteboard-drawing","whiteboard-cleared","whiteboard-image-uploaded","whiteboard-state-sync","whiteboard-permission-changed","whiteboard-toggled"];for(const r of i)this.socket.on(r,o=>{const a=this.rawListeners&&this.rawListeners.get(r);a&&a.forEach(c=>{try{c(o)}catch(h){console.warn(h)}})});this.socket.on("error",r=>{console.error("Socket error:",r),this.callbacks.onError&&this.callbacks.onError(r)})}joinRoom(e,t,n,i){this.socket&&this.socket.emit("join-room",{roomId:e,userId:t,userName:n,peerId:i})}emitMediaState(e,t,n,i){this.socket&&this.socket.emit("media-state-change",{roomId:e,userId:t,type:n,enabled:i})}emit(e,t){this.socket&&this.socket.emit(e,t)}onRaw(e,t){return this.rawListeners.has(e)||this.rawListeners.set(e,new Set),this.rawListeners.get(e).add(t),()=>{var n;return(n=this.rawListeners.get(e))==null?void 0:n.delete(t)}}sendMessage(e,t,n,i,r){if(this.socket){const o={roomId:e,userId:t,userName:n,message:i||""};Array.isArray(r)&&r.length&&(o.attachmentIds=r),this.socket.emit("send-message",o)}}leaveRoom(){this.socket&&this.socket.emit("leave-room")}on(e,t){this.callbacks.hasOwnProperty("on"+e.charAt(0).toUpperCase()+e.slice(1))&&(this.callbacks["on"+e.charAt(0).toUpperCase()+e.slice(1)]=t)}disconnect(){this.socket&&(this.socket.close(),this.socket=null)}}class Ns{constructor(){this.localStream=null,this.remoteStreams={}}async getLocalStream(){if(this.localStream)return this.localStream;try{return this.localStream=await navigator.mediaDevices.getUserMedia({video:!0,audio:!0}),this.localStream}catch(e){throw console.error("Failed to get media devices:",e),e}}addRemoteStream(e,t){this.remoteStreams[e]=t}removeRemoteStream(e){delete this.remoteStreams[e]}toggleVideo(){if(this.localStream){const e=this.localStream.getVideoTracks()[0];if(e)return e.enabled=!e.enabled,e.enabled}return!1}toggleAudio(){if(this.localStream){const e=this.localStream.getAudioTracks()[0];if(e)return e.enabled=!e.enabled,e.enabled}return!1}stopLocalStream(){this.localStream&&(this.localStream.getTracks().forEach(e=>e.stop()),this.localStream=null)}cleanup(){this.stopLocalStream(),this.remoteStreams={}}}class Fe{constructor(){this.recorder=null,this.stream=null,this.state="idle",this.startedAt=null,this.seq=0,this.pendingUploads=[],this.callbacks={onStateChange:null,onChunk:null}}static isSupported(){return typeof window<"u"&&typeof window.MediaRecorder<"u"}pickMimeType(){const e=["video/webm;codecs=vp9,opus","video/webm;codecs=vp8,opus","video/webm","video/mp4"];for(const t of e)if(window.MediaRecorder.isTypeSupported(t))return t;return""}setState(e){this.state=e,this.callbacks.onStateChange&&this.callbacks.onStateChange(e)}on(e,t){e==="stateChange"?this.callbacks.onStateChange=t:e==="chunk"&&(this.callbacks.onChunk=t)}start(e,t={}){if(!Fe.isSupported())throw new Error("MediaRecorder API not supported in this browser");if(this.state==="recording")return;if(!e)throw new Error("stream is required to start recording");const n=t.timesliceMs||15e3,i=Number.isFinite(t.videoBitsPerSecond)?t.videoBitsPerSecond:1e6,r=Number.isFinite(t.audioBitsPerSecond)?t.audioBitsPerSecond:64e3;t.onChunk&&(this.callbacks.onChunk=t.onChunk),this.stream=e,this.seq=typeof t.startSeq=="number"?t.startSeq:0,this.pendingUploads=[];const o=this.pickMimeType(),a={videoBitsPerSecond:i,audioBitsPerSecond:r};o&&(a.mimeType=o),this.recorder=new window.MediaRecorder(e,a),this.mimeType=this.recorder.mimeType||o||"video/webm",this.recorder.ondataavailable=c=>{if(!c.data||c.data.size===0)return;const h=this.seq++,l=c.data,d=this.callbacks.onChunk;if(!d)return;const u=Promise.resolve().then(()=>d(l,h)).catch(f=>{console.warn(`Recording chunk seq=${h} upload failed:`,f&&f.message)});this.pendingUploads.push(u)},this.recorder.onerror=c=>{console.error("MediaRecorder error:",c)},this.startedAt=new Date,this.recorder.start(n),this.setState("recording")}async stop(){if(this.state!=="recording"||!this.recorder)return null;await new Promise(r=>{this.recorder.onstop=r,this.recorder.stop()});const t=(await Promise.allSettled(this.pendingUploads)).filter(r=>r.status==="rejected").length,n=new Date,i={startedAt:this.startedAt,endedAt:n,mimeType:this.mimeType,totalChunks:this.seq,droppedChunks:t};return this.recorder=null,this.stream=null,this.startedAt=null,this.pendingUploads=[],this.setState("stopped"),i}isRecording(){return this.state==="recording"||this.state==="paused"}isPaused(){return this.state==="paused"}pause(){if(!this.recorder||this.state!=="recording")return!1;try{return this.recorder.pause(),this.setState("paused"),!0}catch{return!1}}resume(){if(!this.recorder||this.state!=="paused")return!1;try{return this.recorder.resume(),this.setState("recording"),!0}catch{return!1}}}class He{constructor(e={}){this.width=e.width||1280,this.height=e.height||720,this.fps=e.fps||30,this.canvas=null,this.ctx=null,this.videos=new Map,this.audioContext=null,this.audioDestination=null,this.audioSources=new Map,this.combinedStream=null,this.animationHandle=null,this.running=!1}static isSupported(){return typeof window<"u"&&typeof HTMLCanvasElement<"u"&&typeof HTMLCanvasElement.prototype.captureStream=="function"&&typeof(window.AudioContext||window.webkitAudioContext)<"u"}async start(){if(this.running)return this.combinedStream;if(!He.isSupported())throw new Error("Composite recording requires canvas.captureStream + AudioContext");this.canvas=document.createElement("canvas"),this.canvas.width=this.width,this.canvas.height=this.height,this.canvas.style.cssText="position:absolute;left:-9999px;top:-9999px;",document.body.appendChild(this.canvas),this.ctx=this.canvas.getContext("2d");const e=window.AudioContext||window.webkitAudioContext;if(this.audioContext=new e,this.audioContext.state==="suspended")try{await this.audioContext.resume()}catch{}this.audioDestination=this.audioContext.createMediaStreamDestination();const t=this.canvas.captureStream(this.fps);this.combinedStream=new MediaStream;for(const n of t.getVideoTracks())this.combinedStream.addTrack(n);for(const n of this.audioDestination.stream.getAudioTracks())this.combinedStream.addTrack(n);return this.running=!0,this.tick(),this.combinedStream}tick(){this.running&&(this.draw(),this.animationHandle=requestAnimationFrame(()=>this.tick()))}draw(){if(!this.ctx)return;this.ctx.fillStyle="#0d0d0d",this.ctx.fillRect(0,0,this.width,this.height);const e=Array.from(this.videos.values());if(e.length===0)return;const{cols:t,rows:n}=Hs(e.length),i=this.width/t,r=this.height/n;e.forEach((o,a)=>{const c=a%t,h=Math.floor(a/t),l=c*i,d=h*r;this.ctx.fillStyle="#1a1a1a",this.ctx.fillRect(l,d,i,r);const u=o.videoEl.videoWidth||0,f=o.videoEl.videoHeight||0,g=o.videoTrack,_=g&&g.enabled&&g.readyState==="live";if(u>0&&f>0&&_!==!1){const bn=Math.min(i/u,r/f),_n=u*bn,vn=f*bn,si=l+(i-_n)/2,ii=d+(r-vn)/2;try{this.ctx.drawImage(o.videoEl,si,ii,_n,vn)}catch{}}else Fs(this.ctx,o.label||"Peer",l,d,i,r);const fn=o.label||"Peer";this.ctx.font="bold 16px system-ui, sans-serif";const ei=this.ctx.measureText(fn),mn=10,ti=6,ni=ei.width+mn*2,Ye=24,gn=l+12,yn=d+r-Ye-12;this.ctx.fillStyle="rgba(0,0,0,0.65)",this.ctx.fillRect(gn,yn,ni,Ye),this.ctx.fillStyle="#fff",this.ctx.fillText(fn,gn+mn,yn+Ye-ti-2)})}addStream(e,t,n={}){if(!this.running)return;this.videos.has(e)&&this.removeStream(e);const i=document.createElement("video");i.srcObject=t,i.autoplay=!0,i.muted=!0,i.playsInline=!0,i.style.cssText="position:absolute;left:-9999px;top:-9999px;",document.body.appendChild(i),i.play().catch(()=>{});const r=t.getVideoTracks()[0]||null;this.videos.set(e,{videoEl:i,videoTrack:r,label:n.label||(n.isLocal?"You":e)});const o=t.getAudioTracks();if(o.length&&this.audioContext)try{const a=new MediaStream([o[0]]),c=this.audioContext.createMediaStreamSource(a),h=this.audioContext.createGain();h.gain.value=1,c.connect(h).connect(this.audioDestination),this.audioSources.set(e,{source:c,gain:h})}catch(a){console.warn("Compositor audio source failed for",e,a&&a.message)}}removeStream(e){const t=this.videos.get(e);t&&(t.videoEl.pause(),t.videoEl.srcObject=null,t.videoEl.remove(),this.videos.delete(e));const n=this.audioSources.get(e);if(n){try{n.source.disconnect()}catch{}try{n.gain.disconnect()}catch{}this.audioSources.delete(e)}}getStream(){return this.combinedStream}stop(){if(this.running){this.running=!1,this.animationHandle&&cancelAnimationFrame(this.animationHandle),this.animationHandle=null;for(const e of Array.from(this.videos.keys()))this.removeStream(e);this.combinedStream&&(this.combinedStream.getTracks().forEach(e=>{try{e.stop()}catch{}}),this.combinedStream=null),this.audioContext&&(this.audioContext.close().catch(()=>{}),this.audioContext=null),this.canvas&&(this.canvas.remove(),this.canvas=null,this.ctx=null)}}}function js(s){const e=String(s).trim().split(/\s+/).filter(Boolean);return e.length===0?"?":e.length===1?e[0].slice(0,2).toUpperCase():(e[0][0]+e[e.length-1][0]).toUpperCase()}function qs(s){let e=0;const t=String(s);for(let i=0;i<t.length;i++)e=e*31+t.charCodeAt(i)>>>0;return`hsl(${e%360}, 45%, 40%)`}function Fs(s,e,t,n,i,r){const o=t+i/2,a=n+r/2,c=Math.min(i,r)*.22;s.fillStyle=qs(e),s.beginPath(),s.arc(o,a,c,0,Math.PI*2),s.fill(),s.fillStyle="#fff",s.font=`600 ${Math.floor(c)}px system-ui, sans-serif`,s.textAlign="center",s.textBaseline="middle",s.fillText(js(e),o,a+1),s.textAlign="start",s.textBaseline="alphabetic"}function Hs(s){if(s<=1)return{cols:1,rows:1};if(s===2)return{cols:2,rows:1};if(s<=4)return{cols:2,rows:2};if(s<=6)return{cols:3,rows:2};if(s<=9)return{cols:3,rows:3};const e=4;return{cols:e,rows:Math.ceil(s/e)}}function Vs(s,e){return s.includes("pdf")||/\.pdf$/i.test(e)?"📕":s.includes("word")||/\.docx?$/i.test(e)?"📘":s.includes("sheet")||s.includes("excel")||/\.(xlsx?|csv)$/i.test(e)?"📗":s.startsWith("text/")?"📄":"📎"}const dn="repeat(auto-fit, minmax(280px, 1fr))",un="minmax(180px, 1fr)";class Ks{constructor(e={}){this.container=null,this.videoElements={},this.chatMessages=[],this.recording=e.recording||"off",this.screenShare=e.screenShare!==!1,this.enabledPanels=new Set(Array.isArray(e.panels)&&e.panels.length?e.panels:["chat"]),this.enabledPanels.add("chat"),this.activePanel="chat",this.panelSlots={},this._drawerOpen=!1,this._unreadChat=0}mount(e){if(typeof e=="string"?this.container=document.querySelector(e):e instanceof Element&&(this.container=e),!this.container)throw new Error(`Container not found: ${e}`);this._ownershipToken=Symbol("meet-sdk-ownership"),this.container.__meetSdkOwner=this._ownershipToken,this.render()}render(){const e=(a,c,h,l,d="")=>`<button id="${a}" class="ms-btn ${c}" title="${l}" style="${d}">
|
|
41
|
+
isUnifiedPlanSupported:${this.isUnifiedPlanSupported()}`}constructor(){this.isIOS=typeof navigator<"u"?["iPad","iPhone","iPod"].includes(navigator.platform):!1,this.supportedBrowsers=["firefox","chrome","safari"],this.minFirefoxVersion=59,this.minChromeVersion=72,this.minSafariVersion=605}},On=s=>!s||/^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/.test(s),zt=()=>Math.random().toString(36).slice(2),Nt={iceServers:[{urls:"stun:stun.l.google.com:19302"},{urls:["turn:eu-0.turn.peerjs.com:3478","turn:us-0.turn.peerjs.com:3478"],username:"peerjs",credential:"peerjsp"}],sdpSemantics:"unified-plan"};class Dn extends Ut{noop(){}blobToArrayBuffer(e,t){const n=new FileReader;return n.onload=function(i){i.target&&t(i.target.result)},n.readAsArrayBuffer(e),n}binaryStringToArrayBuffer(e){const t=new Uint8Array(e.length);for(let n=0;n<e.length;n++)t[n]=e.charCodeAt(n)&255;return t.buffer}isSecure(){return location.protocol==="https:"}constructor(...e){super(...e),this.CLOUD_HOST="0.peerjs.com",this.CLOUD_PORT=443,this.chunkedBrowsers={Chrome:1,chrome:1},this.defaultConfig=Nt,this.browser=q.getBrowser(),this.browserVersion=q.getVersion(),this.pack=Qe,this.unpack=Ge,this.supports=function(){const t={browser:q.isBrowserSupported(),webRTC:q.isWebRTCSupported(),audioVideo:!1,data:!1,binaryBlob:!1,reliable:!1};if(!t.webRTC)return t;let n;try{n=new RTCPeerConnection(Nt),t.audioVideo=!0;let i;try{i=n.createDataChannel("_PEERJSTEST",{ordered:!0}),t.data=!0,t.reliable=!!i.ordered;try{i.binaryType="blob",t.binaryBlob=!q.isIOS}catch{}}catch{}finally{i&&i.close()}}catch{}finally{n&&n.close()}return t}(),this.validateId=On,this.randomToken=zt}}const x=new Dn,Ln="PeerJS: ";class $n{get logLevel(){return this._logLevel}set logLevel(e){this._logLevel=e}log(...e){this._logLevel>=3&&this._print(3,...e)}warn(...e){this._logLevel>=2&&this._print(2,...e)}error(...e){this._logLevel>=1&&this._print(1,...e)}setLogFunction(e){this._print=e}_print(e,...t){const n=[Ln,...t];for(const i in n)n[i]instanceof Error&&(n[i]="("+n[i].name+") "+n[i].message);e>=3?console.log(...n):e>=2?console.warn("WARNING",...n):e>=1&&console.error("ERROR",...n)}constructor(){this._logLevel=0}}var p=new $n,xe={},Bn=Object.prototype.hasOwnProperty,C="~";function F(){}Object.create&&(F.prototype=Object.create(null),new F().__proto__||(C=!1));function Un(s,e,t){this.fn=s,this.context=e,this.once=t||!1}function qt(s,e,t,n,i){if(typeof t!="function")throw new TypeError("The listener must be a function");var r=new Un(t,n||s,i),o=C?C+e:e;return s._events[o]?s._events[o].fn?s._events[o]=[s._events[o],r]:s._events[o].push(r):(s._events[o]=r,s._eventsCount++),s}function ee(s,e){--s._eventsCount===0?s._events=new F:delete s._events[e]}function v(){this._events=new F,this._eventsCount=0}v.prototype.eventNames=function(){var e=[],t,n;if(this._eventsCount===0)return e;for(n in t=this._events)Bn.call(t,n)&&e.push(C?n.slice(1):n);return Object.getOwnPropertySymbols?e.concat(Object.getOwnPropertySymbols(t)):e},v.prototype.listeners=function(e){var t=C?C+e:e,n=this._events[t];if(!n)return[];if(n.fn)return[n.fn];for(var i=0,r=n.length,o=new Array(r);i<r;i++)o[i]=n[i].fn;return o},v.prototype.listenerCount=function(e){var t=C?C+e:e,n=this._events[t];return n?n.fn?1:n.length:0},v.prototype.emit=function(e,t,n,i,r,o){var a=C?C+e:e;if(!this._events[a])return!1;var c=this._events[a],h=arguments.length,l,d;if(c.fn){switch(c.once&&this.removeListener(e,c.fn,void 0,!0),h){case 1:return c.fn.call(c.context),!0;case 2:return c.fn.call(c.context,t),!0;case 3:return c.fn.call(c.context,t,n),!0;case 4:return c.fn.call(c.context,t,n,i),!0;case 5:return c.fn.call(c.context,t,n,i,r),!0;case 6:return c.fn.call(c.context,t,n,i,r,o),!0}for(d=1,l=new Array(h-1);d<h;d++)l[d-1]=arguments[d];c.fn.apply(c.context,l)}else{var u=c.length,f;for(d=0;d<u;d++)switch(c[d].once&&this.removeListener(e,c[d].fn,void 0,!0),h){case 1:c[d].fn.call(c[d].context);break;case 2:c[d].fn.call(c[d].context,t);break;case 3:c[d].fn.call(c[d].context,t,n);break;case 4:c[d].fn.call(c[d].context,t,n,i);break;default:if(!l)for(f=1,l=new Array(h-1);f<h;f++)l[f-1]=arguments[f];c[d].fn.apply(c[d].context,l)}}return!0},v.prototype.on=function(e,t,n){return qt(this,e,t,n,!1)},v.prototype.once=function(e,t,n){return qt(this,e,t,n,!0)},v.prototype.removeListener=function(e,t,n,i){var r=C?C+e:e;if(!this._events[r])return this;if(!t)return ee(this,r),this;var o=this._events[r];if(o.fn)o.fn===t&&(!i||o.once)&&(!n||o.context===n)&&ee(this,r);else{for(var a=0,c=[],h=o.length;a<h;a++)(o[a].fn!==t||i&&!o[a].once||n&&o[a].context!==n)&&c.push(o[a]);c.length?this._events[r]=c.length===1?c[0]:c:ee(this,r)}return this},v.prototype.removeAllListeners=function(e){var t;return e?(t=C?C+e:e,this._events[t]&&ee(this,t)):(this._events=new F,this._eventsCount=0),this},v.prototype.off=v.prototype.removeListener,v.prototype.addListener=v.prototype.on,v.prefixed=C,v.EventEmitter=v,xe=v;var L={};D(L,"ConnectionType",()=>M),D(L,"PeerErrorType",()=>y),D(L,"BaseConnectionErrorType",()=>ke),D(L,"DataConnectionErrorType",()=>Te),D(L,"SerializationType",()=>te),D(L,"SocketEventType",()=>A),D(L,"ServerMessageType",()=>S);var M=function(s){return s.Data="data",s.Media="media",s}({}),y=function(s){return s.BrowserIncompatible="browser-incompatible",s.Disconnected="disconnected",s.InvalidID="invalid-id",s.InvalidKey="invalid-key",s.Network="network",s.PeerUnavailable="peer-unavailable",s.SslUnavailable="ssl-unavailable",s.ServerError="server-error",s.SocketError="socket-error",s.SocketClosed="socket-closed",s.UnavailableID="unavailable-id",s.WebRTC="webrtc",s}({}),ke=function(s){return s.NegotiationFailed="negotiation-failed",s.ConnectionClosed="connection-closed",s}({}),Te=function(s){return s.NotOpenYet="not-open-yet",s.MessageToBig="message-too-big",s}({}),te=function(s){return s.Binary="binary",s.BinaryUTF8="binary-utf8",s.JSON="json",s.None="raw",s}({}),A=function(s){return s.Message="message",s.Disconnected="disconnected",s.Error="error",s.Close="close",s}({}),S=function(s){return s.Heartbeat="HEARTBEAT",s.Candidate="CANDIDATE",s.Offer="OFFER",s.Answer="ANSWER",s.Open="OPEN",s.Error="ERROR",s.IdTaken="ID-TAKEN",s.InvalidKey="INVALID-KEY",s.Leave="LEAVE",s.Expire="EXPIRE",s}({});const Ft="1.5.5";class zn extends xe.EventEmitter{constructor(e,t,n,i,r,o=5e3){super(),this.pingInterval=o,this._disconnected=!0,this._messagesQueue=[];const a=e?"wss://":"ws://";this._baseUrl=a+t+":"+n+i+"peerjs?key="+r}start(e,t){this._id=e;const n=`${this._baseUrl}&id=${e}&token=${t}`;this._socket||!this._disconnected||(this._socket=new WebSocket(n+"&version="+Ft),this._disconnected=!1,this._socket.onmessage=i=>{let r;try{r=JSON.parse(i.data),p.log("Server message received:",r)}catch{p.log("Invalid server message",i.data);return}this.emit(A.Message,r)},this._socket.onclose=i=>{this._disconnected||(p.log("Socket closed.",i),this._cleanup(),this._disconnected=!0,this.emit(A.Disconnected))},this._socket.onopen=()=>{this._disconnected||(this._sendQueuedMessages(),p.log("Socket open"),this._scheduleHeartbeat())})}_scheduleHeartbeat(){this._wsPingTimer=setTimeout(()=>{this._sendHeartbeat()},this.pingInterval)}_sendHeartbeat(){if(!this._wsOpen()){p.log("Cannot send heartbeat, because socket closed");return}const e=JSON.stringify({type:S.Heartbeat});this._socket.send(e),this._scheduleHeartbeat()}_wsOpen(){return!!this._socket&&this._socket.readyState===1}_sendQueuedMessages(){const e=[...this._messagesQueue];this._messagesQueue=[];for(const t of e)this.send(t)}send(e){if(this._disconnected)return;if(!this._id){this._messagesQueue.push(e);return}if(!e.type){this.emit(A.Error,"Invalid message");return}if(!this._wsOpen())return;const t=JSON.stringify(e);this._socket.send(t)}close(){this._disconnected||(this._cleanup(),this._disconnected=!0)}_cleanup(){this._socket&&(this._socket.onopen=this._socket.onmessage=this._socket.onclose=null,this._socket.close(),this._socket=void 0),clearTimeout(this._wsPingTimer)}}class jt{constructor(e){this.connection=e}startConnection(e){const t=this._startPeerConnection();if(this.connection.peerConnection=t,this.connection.type===M.Media&&e._stream&&this._addTracksToConnection(e._stream,t),e.originator){const n=this.connection,i={ordered:!!e.reliable},r=t.createDataChannel(n.label,i);n._initializeDataChannel(r),this._makeOffer()}else this.handleSDP("OFFER",e.sdp)}_startPeerConnection(){p.log("Creating RTCPeerConnection.");const e=new RTCPeerConnection(this.connection.provider.options.config);return this._setupListeners(e),e}_setupListeners(e){const t=this.connection.peer,n=this.connection.connectionId,i=this.connection.type,r=this.connection.provider;p.log("Listening for ICE candidates."),e.onicecandidate=o=>{!o.candidate||!o.candidate.candidate||(p.log(`Received ICE candidates for ${t}:`,o.candidate),r.socket.send({type:S.Candidate,payload:{candidate:o.candidate,type:i,connectionId:n},dst:t}))},e.oniceconnectionstatechange=()=>{switch(e.iceConnectionState){case"failed":p.log("iceConnectionState is failed, closing connections to "+t),this.connection.emitError(ke.NegotiationFailed,"Negotiation of connection to "+t+" failed."),this.connection.close();break;case"closed":p.log("iceConnectionState is closed, closing connections to "+t),this.connection.emitError(ke.ConnectionClosed,"Connection to "+t+" closed."),this.connection.close();break;case"disconnected":p.log("iceConnectionState changed to disconnected on the connection with "+t);break;case"completed":e.onicecandidate=()=>{};break}this.connection.emit("iceStateChanged",e.iceConnectionState)},p.log("Listening for data channel"),e.ondatachannel=o=>{p.log("Received data channel");const a=o.channel;r.getConnection(t,n)._initializeDataChannel(a)},p.log("Listening for remote stream"),e.ontrack=o=>{p.log("Received remote stream");const a=o.streams[0],c=r.getConnection(t,n);if(c.type===M.Media){const h=c;this._addStreamToMediaConnection(a,h)}}}cleanup(){p.log("Cleaning up PeerConnection to "+this.connection.peer);const e=this.connection.peerConnection;if(!e)return;this.connection.peerConnection=null,e.onicecandidate=e.oniceconnectionstatechange=e.ondatachannel=e.ontrack=()=>{};const t=e.signalingState!=="closed";let n=!1;const i=this.connection.dataChannel;i&&(n=!!i.readyState&&i.readyState!=="closed"),(t||n)&&e.close()}async _makeOffer(){const e=this.connection.peerConnection,t=this.connection.provider;try{const n=await e.createOffer(this.connection.options.constraints);p.log("Created offer."),this.connection.options.sdpTransform&&typeof this.connection.options.sdpTransform=="function"&&(n.sdp=this.connection.options.sdpTransform(n.sdp)||n.sdp);try{await e.setLocalDescription(n),p.log("Set localDescription:",n,`for:${this.connection.peer}`);let i={sdp:n,type:this.connection.type,connectionId:this.connection.connectionId,metadata:this.connection.metadata};if(this.connection.type===M.Data){const r=this.connection;i={...i,label:r.label,reliable:r.reliable,serialization:r.serialization}}t.socket.send({type:S.Offer,payload:i,dst:this.connection.peer})}catch(i){i!="OperationError: Failed to set local offer sdp: Called in wrong state: kHaveRemoteOffer"&&(t.emitError(y.WebRTC,i),p.log("Failed to setLocalDescription, ",i))}}catch(n){t.emitError(y.WebRTC,n),p.log("Failed to createOffer, ",n)}}async _makeAnswer(){const e=this.connection.peerConnection,t=this.connection.provider;try{const n=await e.createAnswer();p.log("Created answer."),this.connection.options.sdpTransform&&typeof this.connection.options.sdpTransform=="function"&&(n.sdp=this.connection.options.sdpTransform(n.sdp)||n.sdp);try{await e.setLocalDescription(n),p.log("Set localDescription:",n,`for:${this.connection.peer}`),t.socket.send({type:S.Answer,payload:{sdp:n,type:this.connection.type,connectionId:this.connection.connectionId},dst:this.connection.peer})}catch(i){t.emitError(y.WebRTC,i),p.log("Failed to setLocalDescription, ",i)}}catch(n){t.emitError(y.WebRTC,n),p.log("Failed to create answer, ",n)}}async handleSDP(e,t){t=new RTCSessionDescription(t);const n=this.connection.peerConnection,i=this.connection.provider;p.log("Setting remote description",t);const r=this;try{await n.setRemoteDescription(t),p.log(`Set remoteDescription:${e} for:${this.connection.peer}`),e==="OFFER"&&await r._makeAnswer()}catch(o){i.emitError(y.WebRTC,o),p.log("Failed to setRemoteDescription, ",o)}}async handleCandidate(e){p.log("handleCandidate:",e);try{await this.connection.peerConnection.addIceCandidate(e),p.log(`Added ICE candidate for:${this.connection.peer}`)}catch(t){this.connection.provider.emitError(y.WebRTC,t),p.log("Failed to handleCandidate, ",t)}}_addTracksToConnection(e,t){if(p.log(`add tracks from stream ${e.id} to peer connection`),!t.addTrack)return p.error("Your browser does't support RTCPeerConnection#addTrack. Ignored.");e.getTracks().forEach(n=>{t.addTrack(n,e)})}_addStreamToMediaConnection(e,t){p.log(`add stream ${e.id} to media connection ${t.connectionId}`),t.addStream(e)}}class Ht extends xe.EventEmitter{emitError(e,t){p.error("Error:",t),this.emit("error",new Nn(`${e}`,t))}}class Nn extends Error{constructor(e,t){typeof t=="string"?super(t):(super(),Object.assign(this,t)),this.type=e}}class Vt extends Ht{get open(){return this._open}constructor(e,t,n){super(),this.peer=e,this.provider=t,this.options=n,this._open=!1,this.metadata=n.metadata}}const K=class K extends Vt{get type(){return M.Media}get localStream(){return this._localStream}get remoteStream(){return this._remoteStream}constructor(e,t,n){super(e,t,n),this._localStream=this.options._stream,this.connectionId=this.options.connectionId||K.ID_PREFIX+x.randomToken(),this._negotiator=new jt(this),this._localStream&&this._negotiator.startConnection({_stream:this._localStream,originator:!0})}_initializeDataChannel(e){this.dataChannel=e,this.dataChannel.onopen=()=>{p.log(`DC#${this.connectionId} dc connection success`),this.emit("willCloseOnRemote")},this.dataChannel.onclose=()=>{p.log(`DC#${this.connectionId} dc closed for:`,this.peer),this.close()}}addStream(e){p.log("Receiving stream",e),this._remoteStream=e,super.emit("stream",e)}handleMessage(e){const t=e.type,n=e.payload;switch(e.type){case S.Answer:this._negotiator.handleSDP(t,n.sdp),this._open=!0;break;case S.Candidate:this._negotiator.handleCandidate(n.candidate);break;default:p.warn(`Unrecognized message type:${t} from peer:${this.peer}`);break}}answer(e,t={}){if(this._localStream){p.warn("Local stream already exists on this MediaConnection. Are you answering a call twice?");return}this._localStream=e,t&&t.sdpTransform&&(this.options.sdpTransform=t.sdpTransform),this._negotiator.startConnection({...this.options._payload,_stream:e});const n=this.provider._getMessages(this.connectionId);for(const i of n)this.handleMessage(i);this._open=!0}close(){this._negotiator&&(this._negotiator.cleanup(),this._negotiator=null),this._localStream=null,this._remoteStream=null,this.provider&&(this.provider._removeConnection(this),this.provider=null),this.options&&this.options._stream&&(this.options._stream=null),this.open&&(this._open=!1,super.emit("close"))}};Ve=new WeakMap,W(K,Ve,K.ID_PREFIX="mc_");let ne=K;class qn{constructor(e){this._options=e}_buildRequest(e){const t=this._options.secure?"https":"http",{host:n,port:i,path:r,key:o}=this._options,a=new URL(`${t}://${n}:${i}${r}${o}/${e}`);return a.searchParams.set("ts",`${Date.now()}${Math.random()}`),a.searchParams.set("version",Ft),fetch(a.href,{referrerPolicy:this._options.referrerPolicy})}async retrieveId(){try{const e=await this._buildRequest("id");if(e.status!==200)throw new Error(`Error. Status:${e.status}`);return e.text()}catch(e){p.error("Error retrieving ID",e);let t="";throw this._options.path==="/"&&this._options.host!==x.CLOUD_HOST&&(t=" If you passed in a `path` to your self-hosted PeerServer, you'll also need to pass in that same path when creating a new Peer."),new Error("Could not get an ID from the server."+t)}}async listAllPeers(){try{const e=await this._buildRequest("peers");if(e.status!==200){if(e.status===401){let t="";throw this._options.host===x.CLOUD_HOST?t="It looks like you're using the cloud server. You can email team@peerjs.com to enable peer listing for your API key.":t="You need to enable `allow_discovery` on your self-hosted PeerServer to use this feature.",new Error("It doesn't look like you have permission to list peers IDs. "+t)}throw new Error(`Error. Status:${e.status}`)}return e.json()}catch(e){throw p.error("Error retrieving list peers",e),new Error("Could not get list peers from the server."+e)}}}const B=class B extends Vt{get type(){return M.Data}constructor(e,t,n){super(e,t,n),this.connectionId=this.options.connectionId||B.ID_PREFIX+zt(),this.label=this.options.label||this.connectionId,this.reliable=!!this.options.reliable,this._negotiator=new jt(this),this._negotiator.startConnection(this.options._payload||{originator:!0,reliable:this.reliable})}_initializeDataChannel(e){this.dataChannel=e,this.dataChannel.onopen=()=>{p.log(`DC#${this.connectionId} dc connection success`),this._open=!0,this.emit("open")},this.dataChannel.onmessage=t=>{p.log(`DC#${this.connectionId} dc onmessage:`,t.data)},this.dataChannel.onclose=()=>{p.log(`DC#${this.connectionId} dc closed for:`,this.peer),this.close()}}close(e){if(e!=null&&e.flush){this.send({__peerData:{type:"close"}});return}this._negotiator&&(this._negotiator.cleanup(),this._negotiator=null),this.provider&&(this.provider._removeConnection(this),this.provider=null),this.dataChannel&&(this.dataChannel.onopen=null,this.dataChannel.onmessage=null,this.dataChannel.onclose=null,this.dataChannel=null),this.open&&(this._open=!1,super.emit("close"))}send(e,t=!1){if(!this.open){this.emitError(Te.NotOpenYet,"Connection is not open. You should listen for the `open` event before sending messages.");return}return this._send(e,t)}async handleMessage(e){const t=e.payload;switch(e.type){case S.Answer:await this._negotiator.handleSDP(e.type,t.sdp);break;case S.Candidate:await this._negotiator.handleCandidate(t.candidate);break;default:p.warn("Unrecognized message type:",e.type,"from peer:",this.peer);break}}};Ke=new WeakMap,Je=new WeakMap,W(B,Ke,B.ID_PREFIX="dc_"),W(B,Je,B.MAX_BUFFERED_AMOUNT=8388608);let se=B;class Re extends se{get bufferSize(){return this._bufferSize}_initializeDataChannel(e){super._initializeDataChannel(e),this.dataChannel.binaryType="arraybuffer",this.dataChannel.addEventListener("message",t=>this._handleDataMessage(t))}_bufferedSend(e){(this._buffering||!this._trySend(e))&&(this._buffer.push(e),this._bufferSize=this._buffer.length)}_trySend(e){if(!this.open)return!1;if(this.dataChannel.bufferedAmount>se.MAX_BUFFERED_AMOUNT)return this._buffering=!0,setTimeout(()=>{this._buffering=!1,this._tryBuffer()},50),!1;try{this.dataChannel.send(e)}catch(t){return p.error(`DC#:${this.connectionId} Error when sending:`,t),this._buffering=!0,this.close(),!1}return!0}_tryBuffer(){if(!this.open||this._buffer.length===0)return;const e=this._buffer[0];this._trySend(e)&&(this._buffer.shift(),this._bufferSize=this._buffer.length,this._tryBuffer())}close(e){if(e!=null&&e.flush){this.send({__peerData:{type:"close"}});return}this._buffer=[],this._bufferSize=0,super.close()}constructor(...e){super(...e),this._buffer=[],this._bufferSize=0,this._buffering=!1}}class we extends Re{close(e){super.close(e),this._chunkedData={}}constructor(e,t,n){super(e,t,n),this.chunker=new Ut,this.serialization=te.Binary,this._chunkedData={}}_handleDataMessage({data:e}){const t=Ge(e),n=t.__peerData;if(n){if(n.type==="close"){this.close();return}this._handleChunk(t);return}this.emit("data",t)}_handleChunk(e){const t=e.__peerData,n=this._chunkedData[t]||{data:[],count:0,total:e.total};if(n.data[e.n]=new Uint8Array(e.data),n.count++,this._chunkedData[t]=n,n.total===n.count){delete this._chunkedData[t];const i=In(n.data);this._handleDataMessage({data:i})}}_send(e,t){const n=Qe(e);if(n instanceof Promise)return this._send_blob(n);if(!t&&n.byteLength>this.chunker.chunkedMTU){this._sendChunks(n);return}this._bufferedSend(n)}async _send_blob(e){const t=await e;if(t.byteLength>this.chunker.chunkedMTU){this._sendChunks(t);return}this._bufferedSend(t)}_sendChunks(e){const t=this.chunker.chunk(e);p.log(`DC#${this.connectionId} Try to send ${t.length} chunks...`);for(const n of t)this.send(n,!0)}}class Fn extends Re{_handleDataMessage({data:e}){super.emit("data",e)}_send(e,t){this._bufferedSend(e)}constructor(...e){super(...e),this.serialization=te.None}}class jn extends Re{_handleDataMessage({data:e}){const t=this.parse(this.decoder.decode(e)),n=t.__peerData;if(n&&n.type==="close"){this.close();return}this.emit("data",t)}_send(e,t){const n=this.encoder.encode(this.stringify(e));if(n.byteLength>=x.chunkedMTU){this.emitError(Te.MessageToBig,"Message too big for JSON channel");return}this._bufferedSend(n)}constructor(...e){super(...e),this.serialization=te.JSON,this.encoder=new TextEncoder,this.decoder=new TextDecoder,this.stringify=JSON.stringify,this.parse=JSON.parse}}const J=class J extends Ht{get id(){return this._id}get options(){return this._options}get open(){return this._open}get socket(){return this._socket}get connections(){const e=Object.create(null);for(const[t,n]of this._connections)e[t]=n;return e}get destroyed(){return this._destroyed}get disconnected(){return this._disconnected}constructor(e,t){super(),this._serializers={raw:Fn,json:jn,binary:we,"binary-utf8":we,default:we},this._id=null,this._lastServerId=null,this._destroyed=!1,this._disconnected=!1,this._open=!1,this._connections=new Map,this._lostMessages=new Map;let n;if(e&&e.constructor==Object?t=e:e&&(n=e.toString()),t={debug:0,host:x.CLOUD_HOST,port:x.CLOUD_PORT,path:"/",key:J.DEFAULT_KEY,token:x.randomToken(),config:x.defaultConfig,referrerPolicy:"strict-origin-when-cross-origin",serializers:{},...t},this._options=t,this._serializers={...this._serializers,...this.options.serializers},this._options.host==="/"&&(this._options.host=window.location.hostname),this._options.path&&(this._options.path[0]!=="/"&&(this._options.path="/"+this._options.path),this._options.path[this._options.path.length-1]!=="/"&&(this._options.path+="/")),this._options.secure===void 0&&this._options.host!==x.CLOUD_HOST?this._options.secure=x.isSecure():this._options.host==x.CLOUD_HOST&&(this._options.secure=!0),this._options.logFunction&&p.setLogFunction(this._options.logFunction),p.logLevel=this._options.debug||0,this._api=new qn(t),this._socket=this._createServerConnection(),!x.supports.audioVideo&&!x.supports.data){this._delayedAbort(y.BrowserIncompatible,"The current browser does not support WebRTC");return}if(n&&!x.validateId(n)){this._delayedAbort(y.InvalidID,`ID "${n}" is invalid`);return}n?this._initialize(n):this._api.retrieveId().then(i=>this._initialize(i)).catch(i=>this._abort(y.ServerError,i))}_createServerConnection(){const e=new zn(this._options.secure,this._options.host,this._options.port,this._options.path,this._options.key,this._options.pingInterval);return e.on(A.Message,t=>{this._handleMessage(t)}),e.on(A.Error,t=>{this._abort(y.SocketError,t)}),e.on(A.Disconnected,()=>{this.disconnected||(this.emitError(y.Network,"Lost connection to server."),this.disconnect())}),e.on(A.Close,()=>{this.disconnected||this._abort(y.SocketClosed,"Underlying socket is already closed.")}),e}_initialize(e){this._id=e,this.socket.start(e,this._options.token)}_handleMessage(e){const t=e.type,n=e.payload,i=e.src;switch(t){case S.Open:this._lastServerId=this.id,this._open=!0,this.emit("open",this.id);break;case S.Error:this._abort(y.ServerError,n.msg);break;case S.IdTaken:this._abort(y.UnavailableID,`ID "${this.id}" is taken`);break;case S.InvalidKey:this._abort(y.InvalidKey,`API KEY "${this._options.key}" is invalid`);break;case S.Leave:p.log(`Received leave message from ${i}`),this._cleanupPeer(i),this._connections.delete(i);break;case S.Expire:this.emitError(y.PeerUnavailable,`Could not connect to peer ${i}`);break;case S.Offer:{const r=n.connectionId;let o=this.getConnection(i,r);if(o&&(o.close(),p.warn(`Offer received for existing Connection ID:${r}`)),n.type===M.Media){const c=new ne(i,this,{connectionId:r,_payload:n,metadata:n.metadata});o=c,this._addConnection(i,o),this.emit("call",c)}else if(n.type===M.Data){const c=new this._serializers[n.serialization](i,this,{connectionId:r,_payload:n,metadata:n.metadata,label:n.label,serialization:n.serialization,reliable:n.reliable});o=c,this._addConnection(i,o),this.emit("connection",c)}else{p.warn(`Received malformed connection type:${n.type}`);return}const a=this._getMessages(r);for(const c of a)o.handleMessage(c);break}default:{if(!n){p.warn(`You received a malformed message from ${i} of type ${t}`);return}const r=n.connectionId,o=this.getConnection(i,r);o&&o.peerConnection?o.handleMessage(e):r?this._storeMessage(r,e):p.warn("You received an unrecognized message:",e);break}}}_storeMessage(e,t){this._lostMessages.has(e)||this._lostMessages.set(e,[]),this._lostMessages.get(e).push(t)}_getMessages(e){const t=this._lostMessages.get(e);return t?(this._lostMessages.delete(e),t):[]}connect(e,t={}){if(t={serialization:"default",...t},this.disconnected){p.warn("You cannot connect to a new Peer because you called .disconnect() on this Peer and ended your connection with the server. You can create a new Peer to reconnect, or call reconnect on this peer if you believe its ID to still be available."),this.emitError(y.Disconnected,"Cannot connect to new Peer after disconnecting from server.");return}const n=new this._serializers[t.serialization](e,this,t);return this._addConnection(e,n),n}call(e,t,n={}){if(this.disconnected){p.warn("You cannot connect to a new Peer because you called .disconnect() on this Peer and ended your connection with the server. You can create a new Peer to reconnect."),this.emitError(y.Disconnected,"Cannot connect to new Peer after disconnecting from server.");return}if(!t){p.error("To call a peer, you must provide a stream from your browser's `getUserMedia`.");return}const i=new ne(e,this,{...n,_stream:t});return this._addConnection(e,i),i}_addConnection(e,t){p.log(`add connection ${t.type}:${t.connectionId} to peerId:${e}`),this._connections.has(e)||this._connections.set(e,[]),this._connections.get(e).push(t)}_removeConnection(e){const t=this._connections.get(e.peer);if(t){const n=t.indexOf(e);n!==-1&&t.splice(n,1)}this._lostMessages.delete(e.connectionId)}getConnection(e,t){const n=this._connections.get(e);if(!n)return null;for(const i of n)if(i.connectionId===t)return i;return null}_delayedAbort(e,t){setTimeout(()=>{this._abort(e,t)},0)}_abort(e,t){p.error("Aborting!"),this.emitError(e,t),this._lastServerId?this.disconnect():this.destroy()}destroy(){this.destroyed||(p.log(`Destroy peer with ID:${this.id}`),this.disconnect(),this._cleanup(),this._destroyed=!0,this.emit("close"))}_cleanup(){for(const e of this._connections.keys())this._cleanupPeer(e),this._connections.delete(e);this.socket.removeAllListeners()}_cleanupPeer(e){const t=this._connections.get(e);if(t)for(const n of t)n.close()}disconnect(){if(this.disconnected)return;const e=this.id;p.log(`Disconnect peer with ID:${e}`),this._disconnected=!0,this._open=!1,this.socket.close(),this._lastServerId=e,this._id=null,this.emit("disconnected",e)}reconnect(){if(this.disconnected&&!this.destroyed)p.log(`Attempting reconnection to server with ID ${this._lastServerId}`),this._disconnected=!1,this._initialize(this._lastServerId);else{if(this.destroyed)throw new Error("This peer cannot reconnect to the server. It has already been destroyed.");if(!this.disconnected&&!this.open)p.error("In a hurry? We're still trying to make the initial connection!");else throw new Error(`Peer ${this.id} cannot reconnect because it is not disconnected from the server!`)}}listAllPeers(e=t=>{}){this._api.listAllPeers().then(t=>e(t)).catch(t=>this._abort(y.ServerError,t))}};We=new WeakMap,W(J,We,J.DEFAULT_KEY="peerjs");let Pe=J;var Hn=Pe;class Vn{constructor(e){this.config=e,this.peer=null,this.localStream=null,this.connections={},this.callbacks={onStream:null,onPeerLeft:null,onError:null,onScreenShareEnded:null}}buildIceServers(){const e=[{urls:"stun:stun.l.google.com:19302"},{urls:"stun:stun1.l.google.com:19302"}],t=Array.isArray(this.config.iceServers)?this.config.iceServers:[];return[...e,...t]}async initialize(e,t=0){return new Promise((n,i)=>{const r=t===0?e:`${e}-r${Math.random().toString(36).slice(2,6)}`;this.peer=new Hn(r,{host:this.config.peerServer.host,port:this.config.peerServer.port,path:this.config.peerServer.path||"/peerjs",secure:this.config.peerServer.secure??!1,config:{iceServers:this.buildIceServers()}});let o=!1;this.peer.on("open",a=>{o=!0,console.log("Peer initialized:",a),this.actualPeerId=a,n(a)}),this.peer.on("error",async a=>{if(!o&&a&&a.type==="unavailable-id"&&t<1){console.warn(`Peer id "${r}" taken — retrying with a suffix`);try{this.peer.destroy()}catch{}this.peer=null;try{const c=await this.initialize(e,t+1);o=!0,n(c)}catch(c){i(c)}return}console.error("Peer error:",a),this.callbacks.onError&&this.callbacks.onError(a),o||i(a)}),this.peer.on("call",a=>{this.handleIncomingCall(a)}),this.peer.on("disconnected",()=>{this._disposed||(console.warn("PeerJS signalling disconnected — attempting reconnect"),setTimeout(()=>{try{this.peer&&!this.peer.destroyed&&this.peer.reconnect()}catch(a){console.warn("Peer reconnect threw:",a&&a.message)}},1e3))})})}async getLocalStream(){if(this.localStream)return this.localStream;try{return this.localStream=await navigator.mediaDevices.getUserMedia({video:!0,audio:!0}),this.localStream}catch(e){throw console.error("Failed to get local stream:",e),this.callbacks.onError&&this.callbacks.onError(e),e}}async handleIncomingCall(e){if(this.connections[e.peer]){console.log("Duplicate incoming call from",e.peer,"— closing");try{e.close()}catch{}return}this.connections[e.peer]={call:e,stream:null};const t=await this.getLocalStream();e.answer(t),e.on("stream",n=>{console.log("Received stream from:",e.peer),this.connections[e.peer]={call:e,stream:n},this.callbacks.onStream&&this.callbacks.onStream(e.peer,n,!1)}),e.on("close",()=>{console.log("Call closed:",e.peer),delete this.connections[e.peer],this.callbacks.onPeerLeft&&this.callbacks.onPeerLeft(e.peer)})}async callPeer(e){if(this.connections[e]){console.log("Already connected to:",e);return}if(this.peer&&this.peer.id&&this.peer.id>e){console.log(`Waiting for ${e} to call us (our id ${this.peer.id} > theirs)`);return}this.connections[e]={call:null,stream:null};const t=await this.getLocalStream();if(this.connections[e]&&this.connections[e].call)return;const n=this.peer.call(e,t);this.connections[e]={call:n,stream:null},n.on("stream",i=>{console.log("Received stream from:",e),this.connections[e]={call:n,stream:i},this.callbacks.onStream&&this.callbacks.onStream(e,i,!1)}),n.on("close",()=>{console.log("Call closed:",e),delete this.connections[e],this.callbacks.onPeerLeft&&this.callbacks.onPeerLeft(e)}),n.on("error",i=>{console.error("Call error:",i),delete this.connections[e]})}toggleVideo(){if(this.localStream){const e=this.localStream.getVideoTracks()[0];if(e)return e.enabled=!e.enabled,e.enabled}return!1}toggleAudio(){if(this.localStream){const e=this.localStream.getAudioTracks()[0];if(e)return e.enabled=!e.enabled,e.enabled}return!1}replaceVideoTrackOnAllConnections(e){for(const{call:t}of Object.values(this.connections)){const n=t&&t.peerConnection;if(!n)continue;const i=n.getSenders().find(r=>r.track&&r.track.kind==="video");i&&i.replaceTrack(e).catch(r=>console.warn("replaceTrack failed:",r&&r.message))}}async startScreenShare(){if(!navigator.mediaDevices||!navigator.mediaDevices.getDisplayMedia)throw new Error("Screen sharing is not supported in this browser");const t=(await navigator.mediaDevices.getDisplayMedia({video:!0,audio:!1})).getVideoTracks()[0];if(!t)throw new Error("Could not obtain display video track");return this.cameraVideoTrack=this.localStream.getVideoTracks()[0]||null,this.replaceVideoTrackOnAllConnections(t),this.cameraVideoTrack&&this.localStream.removeTrack(this.cameraVideoTrack),this.localStream.addTrack(t),this.screenTrack=t,t.addEventListener("ended",async()=>{const n=!!this.screenTrack;if(await this.stopScreenShare().catch(()=>{}),n&&this.callbacks.onScreenShareEnded)try{this.callbacks.onScreenShareEnded()}catch(i){console.warn(i)}}),t}async stopScreenShare(){if(!this.screenTrack)return!1;try{this.screenTrack.stop()}catch{}let e=this.cameraVideoTrack;if(!e||e.readyState==="ended")try{e=(await navigator.mediaDevices.getUserMedia({video:!0,audio:!1})).getVideoTracks()[0]}catch(t){console.warn("Could not restore camera after screen share:",t&&t.message),e=null}if(e){this.replaceVideoTrackOnAllConnections(e);try{this.localStream.removeTrack(this.screenTrack)}catch{}this.localStream.addTrack(e),this.cameraVideoTrack=e}return this.screenTrack=null,!0}isScreenSharing(){return!!this.screenTrack}on(e,t){this.callbacks.hasOwnProperty("on"+e.charAt(0).toUpperCase()+e.slice(1))&&(this.callbacks["on"+e.charAt(0).toUpperCase()+e.slice(1)]=t)}disconnect(){this._disposed=!0,Object.values(this.connections).forEach(({call:e})=>{e.close()}),this.connections={},this.localStream&&(this.localStream.getTracks().forEach(e=>e.stop()),this.localStream=null),this.peer&&(this.peer.destroy(),this.peer=null)}}const P=Object.create(null);P.open="0",P.close="1",P.ping="2",P.pong="3",P.message="4",P.upgrade="5",P.noop="6";const ie=Object.create(null);Object.keys(P).forEach(s=>{ie[P[s]]=s});const Ee={type:"error",data:"parser error"},Kt=typeof Blob=="function"||typeof Blob<"u"&&Object.prototype.toString.call(Blob)==="[object BlobConstructor]",Jt=typeof ArrayBuffer=="function",Wt=s=>typeof ArrayBuffer.isView=="function"?ArrayBuffer.isView(s):s&&s.buffer instanceof ArrayBuffer,Me=({type:s,data:e},t,n)=>Kt&&e instanceof Blob?t?n(e):Yt(e,n):Jt&&(e instanceof ArrayBuffer||Wt(e))?t?n(e):Yt(new Blob([e]),n):n(P[s]+(e||"")),Yt=(s,e)=>{const t=new FileReader;return t.onload=function(){const n=t.result.split(",")[1];e("b"+(n||""))},t.readAsDataURL(s)};function Gt(s){return s instanceof Uint8Array?s:s instanceof ArrayBuffer?new Uint8Array(s):new Uint8Array(s.buffer,s.byteOffset,s.byteLength)}let Ae;function Kn(s,e){if(Kt&&s.data instanceof Blob)return s.data.arrayBuffer().then(Gt).then(e);if(Jt&&(s.data instanceof ArrayBuffer||Wt(s.data)))return e(Gt(s.data));Me(s,!1,t=>{Ae||(Ae=new TextEncoder),e(Ae.encode(t))})}const Qt="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",j=typeof Uint8Array>"u"?[]:new Uint8Array(256);for(let s=0;s<Qt.length;s++)j[Qt.charCodeAt(s)]=s;const Jn=s=>{let e=s.length*.75,t=s.length,n,i=0,r,o,a,c;s[s.length-1]==="="&&(e--,s[s.length-2]==="="&&e--);const h=new ArrayBuffer(e),l=new Uint8Array(h);for(n=0;n<t;n+=4)r=j[s.charCodeAt(n)],o=j[s.charCodeAt(n+1)],a=j[s.charCodeAt(n+2)],c=j[s.charCodeAt(n+3)],l[i++]=r<<2|o>>4,l[i++]=(o&15)<<4|a>>2,l[i++]=(a&3)<<6|c&63;return h},Wn=typeof ArrayBuffer=="function",Ie=(s,e)=>{if(typeof s!="string")return{type:"message",data:Xt(s,e)};const t=s.charAt(0);return t==="b"?{type:"message",data:Yn(s.substring(1),e)}:ie[t]?s.length>1?{type:ie[t],data:s.substring(1)}:{type:ie[t]}:Ee},Yn=(s,e)=>{if(Wn){const t=Jn(s);return Xt(t,e)}else return{base64:!0,data:s}},Xt=(s,e)=>{switch(e){case"blob":return s instanceof Blob?s:new Blob([s]);case"arraybuffer":default:return s instanceof ArrayBuffer?s:s.buffer}},Zt="",Gn=(s,e)=>{const t=s.length,n=new Array(t);let i=0;s.forEach((r,o)=>{Me(r,!1,a=>{n[o]=a,++i===t&&e(n.join(Zt))})})},Qn=(s,e)=>{const t=s.split(Zt),n=[];for(let i=0;i<t.length;i++){const r=Ie(t[i],e);if(n.push(r),r.type==="error")break}return n};function Xn(){return new TransformStream({transform(s,e){Kn(s,t=>{const n=t.length;let i;if(n<126)i=new Uint8Array(1),new DataView(i.buffer).setUint8(0,n);else if(n<65536){i=new Uint8Array(3);const r=new DataView(i.buffer);r.setUint8(0,126),r.setUint16(1,n)}else{i=new Uint8Array(9);const r=new DataView(i.buffer);r.setUint8(0,127),r.setBigUint64(1,BigInt(n))}s.data&&typeof s.data!="string"&&(i[0]|=128),e.enqueue(i),e.enqueue(t)})}})}let Oe;function re(s){return s.reduce((e,t)=>e+t.length,0)}function oe(s,e){if(s[0].length===e)return s.shift();const t=new Uint8Array(e);let n=0;for(let i=0;i<e;i++)t[i]=s[0][n++],n===s[0].length&&(s.shift(),n=0);return s.length&&n<s[0].length&&(s[0]=s[0].slice(n)),t}function Zn(s,e){Oe||(Oe=new TextDecoder);const t=[];let n=0,i=-1,r=!1;return new TransformStream({transform(o,a){for(t.push(o);;){if(n===0){if(re(t)<1)break;const c=oe(t,1);r=(c[0]&128)===128,i=c[0]&127,i<126?n=3:i===126?n=1:n=2}else if(n===1){if(re(t)<2)break;const c=oe(t,2);i=new DataView(c.buffer,c.byteOffset,c.length).getUint16(0),n=3}else if(n===2){if(re(t)<8)break;const c=oe(t,8),h=new DataView(c.buffer,c.byteOffset,c.length),l=h.getUint32(0);if(l>Math.pow(2,21)-1){a.enqueue(Ee);break}i=l*Math.pow(2,32)+h.getUint32(4),n=3}else{if(re(t)<i)break;const c=oe(t,i);a.enqueue(Ie(r?c:Oe.decode(c),e)),n=0}if(i===0||i>s){a.enqueue(Ee);break}}}})}const en=4;function b(s){if(s)return es(s)}function es(s){for(var e in b.prototype)s[e]=b.prototype[e];return s}b.prototype.on=b.prototype.addEventListener=function(s,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+s]=this._callbacks["$"+s]||[]).push(e),this},b.prototype.once=function(s,e){function t(){this.off(s,t),e.apply(this,arguments)}return t.fn=e,this.on(s,t),this},b.prototype.off=b.prototype.removeListener=b.prototype.removeAllListeners=b.prototype.removeEventListener=function(s,e){if(this._callbacks=this._callbacks||{},arguments.length==0)return this._callbacks={},this;var t=this._callbacks["$"+s];if(!t)return this;if(arguments.length==1)return delete this._callbacks["$"+s],this;for(var n,i=0;i<t.length;i++)if(n=t[i],n===e||n.fn===e){t.splice(i,1);break}return t.length===0&&delete this._callbacks["$"+s],this},b.prototype.emit=function(s){this._callbacks=this._callbacks||{};for(var e=new Array(arguments.length-1),t=this._callbacks["$"+s],n=1;n<arguments.length;n++)e[n-1]=arguments[n];if(t){t=t.slice(0);for(var n=0,i=t.length;n<i;++n)t[n].apply(this,e)}return this},b.prototype.emitReserved=b.prototype.emit,b.prototype.listeners=function(s){return this._callbacks=this._callbacks||{},this._callbacks["$"+s]||[]},b.prototype.hasListeners=function(s){return!!this.listeners(s).length};const ae=typeof Promise=="function"&&typeof Promise.resolve=="function"?e=>Promise.resolve().then(e):(e,t)=>t(e,0),T=typeof self<"u"?self:typeof window<"u"?window:Function("return this")(),ts="arraybuffer";function oi(){}function tn(s,...e){return e.reduce((t,n)=>(s.hasOwnProperty(n)&&(t[n]=s[n]),t),{})}const ns=T.setTimeout,ss=T.clearTimeout;function ce(s,e){e.useNativeTimers?(s.setTimeoutFn=ns.bind(T),s.clearTimeoutFn=ss.bind(T)):(s.setTimeoutFn=T.setTimeout.bind(T),s.clearTimeoutFn=T.clearTimeout.bind(T))}const is=1.33;function rs(s){return typeof s=="string"?os(s):Math.ceil((s.byteLength||s.size)*is)}function os(s){let e=0,t=0;for(let n=0,i=s.length;n<i;n++)e=s.charCodeAt(n),e<128?t+=1:e<2048?t+=2:e<55296||e>=57344?t+=3:(n++,t+=4);return t}function nn(){return Date.now().toString(36).substring(3)+Math.random().toString(36).substring(2,5)}function as(s){let e="";for(let t in s)s.hasOwnProperty(t)&&(e.length&&(e+="&"),e+=encodeURIComponent(t)+"="+encodeURIComponent(s[t]));return e}function cs(s){let e={},t=s.split("&");for(let n=0,i=t.length;n<i;n++){let r=t[n].split("=");e[decodeURIComponent(r[0])]=decodeURIComponent(r[1])}return e}class hs extends Error{constructor(e,t,n){super(e),this.description=t,this.context=n,this.type="TransportError"}}class De extends b{constructor(e){super(),this.writable=!1,ce(this,e),this.opts=e,this.query=e.query,this.socket=e.socket,this.supportsBinary=!e.forceBase64}onError(e,t,n){return super.emitReserved("error",new hs(e,t,n)),this}open(){return this.readyState="opening",this.doOpen(),this}close(){return(this.readyState==="opening"||this.readyState==="open")&&(this.doClose(),this.onClose()),this}send(e){this.readyState==="open"&&this.write(e)}onOpen(){this.readyState="open",this.writable=!0,super.emitReserved("open")}onData(e){const t=Ie(e,this.socket.binaryType);this.onPacket(t)}onPacket(e){super.emitReserved("packet",e)}onClose(e){this.readyState="closed",super.emitReserved("close",e)}pause(e){}createUri(e,t={}){return e+"://"+this._hostname()+this._port()+this.opts.path+this._query(t)}_hostname(){const e=this.opts.hostname;return e.indexOf(":")===-1?e:"["+e+"]"}_port(){return this.opts.port&&(this.opts.secure&&Number(this.opts.port)!==443||!this.opts.secure&&Number(this.opts.port)!==80)?":"+this.opts.port:""}_query(e){const t=as(e);return t.length?"?"+t:""}}class ls extends De{constructor(){super(...arguments),this._polling=!1}get name(){return"polling"}doOpen(){this._poll()}pause(e){this.readyState="pausing";const t=()=>{this.readyState="paused",e()};if(this._polling||!this.writable){let n=0;this._polling&&(n++,this.once("pollComplete",function(){--n||t()})),this.writable||(n++,this.once("drain",function(){--n||t()}))}else t()}_poll(){this._polling=!0,this.doPoll(),this.emitReserved("poll")}onData(e){const t=n=>{if(this.readyState==="opening"&&n.type==="open"&&this.onOpen(),n.type==="close")return this.onClose({description:"transport closed by the server"}),!1;this.onPacket(n)};Qn(e,this.socket.binaryType).forEach(t),this.readyState!=="closed"&&(this._polling=!1,this.emitReserved("pollComplete"),this.readyState==="open"&&this._poll())}doClose(){const e=()=>{this.write([{type:"close"}])};this.readyState==="open"?e():this.once("open",e)}write(e){this.writable=!1,Gn(e,t=>{this.doWrite(t,()=>{this.writable=!0,this.emitReserved("drain")})})}uri(){const e=this.opts.secure?"https":"http",t=this.query||{};return this.opts.timestampRequests!==!1&&(t[this.opts.timestampParam]=nn()),!this.supportsBinary&&!t.sid&&(t.b64=1),this.createUri(e,t)}}let sn=!1;try{sn=typeof XMLHttpRequest<"u"&&"withCredentials"in new XMLHttpRequest}catch{}const ds=sn;function us(){}class ps extends ls{constructor(e){if(super(e),typeof location<"u"){const t=location.protocol==="https:";let n=location.port;n||(n=t?"443":"80"),this.xd=typeof location<"u"&&e.hostname!==location.hostname||n!==e.port}}doWrite(e,t){const n=this.request({method:"POST",data:e});n.on("success",t),n.on("error",(i,r)=>{this.onError("xhr post error",i,r)})}doPoll(){const e=this.request();e.on("data",this.onData.bind(this)),e.on("error",(t,n)=>{this.onError("xhr poll error",t,n)}),this.pollXhr=e}}class E extends b{constructor(e,t,n){super(),this.createRequest=e,ce(this,n),this._opts=n,this._method=n.method||"GET",this._uri=t,this._data=n.data!==void 0?n.data:null,this._create()}_create(){var e;const t=tn(this._opts,"agent","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","autoUnref");t.xdomain=!!this._opts.xd;const n=this._xhr=this.createRequest(t);try{n.open(this._method,this._uri,!0);try{if(this._opts.extraHeaders){n.setDisableHeaderCheck&&n.setDisableHeaderCheck(!0);for(let i in this._opts.extraHeaders)this._opts.extraHeaders.hasOwnProperty(i)&&n.setRequestHeader(i,this._opts.extraHeaders[i])}}catch{}if(this._method==="POST")try{n.setRequestHeader("Content-type","text/plain;charset=UTF-8")}catch{}try{n.setRequestHeader("Accept","*/*")}catch{}(e=this._opts.cookieJar)===null||e===void 0||e.addCookies(n),"withCredentials"in n&&(n.withCredentials=this._opts.withCredentials),this._opts.requestTimeout&&(n.timeout=this._opts.requestTimeout),n.onreadystatechange=()=>{var i;n.readyState===3&&((i=this._opts.cookieJar)===null||i===void 0||i.parseCookies(n.getResponseHeader("set-cookie"))),n.readyState===4&&(n.status===200||n.status===1223?this._onLoad():this.setTimeoutFn(()=>{this._onError(typeof n.status=="number"?n.status:0)},0))},n.send(this._data)}catch(i){this.setTimeoutFn(()=>{this._onError(i)},0);return}typeof document<"u"&&(this._index=E.requestsCount++,E.requests[this._index]=this)}_onError(e){this.emitReserved("error",e,this._xhr),this._cleanup(!0)}_cleanup(e){if(!(typeof this._xhr>"u"||this._xhr===null)){if(this._xhr.onreadystatechange=us,e)try{this._xhr.abort()}catch{}typeof document<"u"&&delete E.requests[this._index],this._xhr=null}}_onLoad(){const e=this._xhr.responseText;e!==null&&(this.emitReserved("data",e),this.emitReserved("success"),this._cleanup())}abort(){this._cleanup()}}if(E.requestsCount=0,E.requests={},typeof document<"u"){if(typeof attachEvent=="function")attachEvent("onunload",rn);else if(typeof addEventListener=="function"){const s="onpagehide"in T?"pagehide":"unload";addEventListener(s,rn,!1)}}function rn(){for(let s in E.requests)E.requests.hasOwnProperty(s)&&E.requests[s].abort()}const fs=function(){const s=on({xdomain:!1});return s&&s.responseType!==null}();class ms extends ps{constructor(e){super(e);const t=e&&e.forceBase64;this.supportsBinary=fs&&!t}request(e={}){return Object.assign(e,{xd:this.xd},this.opts),new E(on,this.uri(),e)}}function on(s){const e=s.xdomain;try{if(typeof XMLHttpRequest<"u"&&(!e||ds))return new XMLHttpRequest}catch{}if(!e)try{return new T[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP")}catch{}}const an=typeof navigator<"u"&&typeof navigator.product=="string"&&navigator.product.toLowerCase()==="reactnative";class gs extends De{get name(){return"websocket"}doOpen(){const e=this.uri(),t=this.opts.protocols,n=an?{}:tn(this.opts,"agent","perMessageDeflate","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","localAddress","protocolVersion","origin","maxPayload","family","checkServerIdentity");this.opts.extraHeaders&&(n.headers=this.opts.extraHeaders);try{this.ws=this.createSocket(e,t,n)}catch(i){return this.emitReserved("error",i)}this.ws.binaryType=this.socket.binaryType,this.addEventListeners()}addEventListeners(){this.ws.onopen=()=>{this.opts.autoUnref&&this.ws._socket.unref(),this.onOpen()},this.ws.onclose=e=>this.onClose({description:"websocket connection closed",context:e}),this.ws.onmessage=e=>this.onData(e.data),this.ws.onerror=e=>this.onError("websocket error",e)}write(e){this.writable=!1;for(let t=0;t<e.length;t++){const n=e[t],i=t===e.length-1;Me(n,this.supportsBinary,r=>{try{this.doWrite(n,r)}catch{}i&&ae(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){typeof this.ws<"u"&&(this.ws.onerror=()=>{},this.ws.close(),this.ws=null)}uri(){const e=this.opts.secure?"wss":"ws",t=this.query||{};return this.opts.timestampRequests&&(t[this.opts.timestampParam]=nn()),this.supportsBinary||(t.b64=1),this.createUri(e,t)}}const Le=T.WebSocket||T.MozWebSocket;class ys extends gs{createSocket(e,t,n){return an?new Le(e,t,n):t?new Le(e,t):new Le(e)}doWrite(e,t){this.ws.send(t)}}class bs extends De{get name(){return"webtransport"}doOpen(){try{this._transport=new WebTransport(this.createUri("https"),this.opts.transportOptions[this.name])}catch(e){return this.emitReserved("error",e)}this._transport.closed.then(()=>{this.onClose()}).catch(e=>{this.onError("webtransport error",e)}),this._transport.ready.then(()=>{this._transport.createBidirectionalStream().then(e=>{const t=Zn(Number.MAX_SAFE_INTEGER,this.socket.binaryType),n=e.readable.pipeThrough(t).getReader(),i=Xn();i.readable.pipeTo(e.writable),this._writer=i.writable.getWriter();const r=()=>{n.read().then(({done:a,value:c})=>{a||(this.onPacket(c),r())}).catch(a=>{})};r();const o={type:"open"};this.query.sid&&(o.data=`{"sid":"${this.query.sid}"}`),this._writer.write(o).then(()=>this.onOpen())})})}write(e){this.writable=!1;for(let t=0;t<e.length;t++){const n=e[t],i=t===e.length-1;this._writer.write(n).then(()=>{i&&ae(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){var e;(e=this._transport)===null||e===void 0||e.close()}}const _s={websocket:ys,webtransport:bs,polling:ms},vs=/^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,Ss=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];function $e(s){if(s.length>8e3)throw"URI too long";const e=s,t=s.indexOf("["),n=s.indexOf("]");t!=-1&&n!=-1&&(s=s.substring(0,t)+s.substring(t,n).replace(/:/g,";")+s.substring(n,s.length));let i=vs.exec(s||""),r={},o=14;for(;o--;)r[Ss[o]]=i[o]||"";return t!=-1&&n!=-1&&(r.source=e,r.host=r.host.substring(1,r.host.length-1).replace(/;/g,":"),r.authority=r.authority.replace("[","").replace("]","").replace(/;/g,":"),r.ipv6uri=!0),r.pathNames=Cs(r,r.path),r.queryKey=xs(r,r.query),r}function Cs(s,e){const t=/\/{2,9}/g,n=e.replace(t,"/").split("/");return(e.slice(0,1)=="/"||e.length===0)&&n.splice(0,1),e.slice(-1)=="/"&&n.splice(n.length-1,1),n}function xs(s,e){const t={};return e.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,function(n,i,r){i&&(t[i]=r)}),t}const Be=typeof addEventListener=="function"&&typeof removeEventListener=="function",he=[];Be&&addEventListener("offline",()=>{he.forEach(s=>s())},!1);class I extends b{constructor(e,t){if(super(),this.binaryType=ts,this.writeBuffer=[],this._prevBufferLen=0,this._pingInterval=-1,this._pingTimeout=-1,this._maxPayload=-1,this._pingTimeoutTime=1/0,e&&typeof e=="object"&&(t=e,e=null),e){const n=$e(e);t.hostname=n.host,t.secure=n.protocol==="https"||n.protocol==="wss",t.port=n.port,n.query&&(t.query=n.query)}else t.host&&(t.hostname=$e(t.host).host);ce(this,t),this.secure=t.secure!=null?t.secure:typeof location<"u"&&location.protocol==="https:",t.hostname&&!t.port&&(t.port=this.secure?"443":"80"),this.hostname=t.hostname||(typeof location<"u"?location.hostname:"localhost"),this.port=t.port||(typeof location<"u"&&location.port?location.port:this.secure?"443":"80"),this.transports=[],this._transportsByName={},t.transports.forEach(n=>{const i=n.prototype.name;this.transports.push(i),this._transportsByName[i]=n}),this.opts=Object.assign({path:"/engine.io",agent:!1,withCredentials:!1,upgrade:!0,timestampParam:"t",rememberUpgrade:!1,addTrailingSlash:!0,rejectUnauthorized:!0,perMessageDeflate:{threshold:1024},transportOptions:{},closeOnBeforeunload:!1},t),this.opts.path=this.opts.path.replace(/\/$/,"")+(this.opts.addTrailingSlash?"/":""),typeof this.opts.query=="string"&&(this.opts.query=cs(this.opts.query)),Be&&(this.opts.closeOnBeforeunload&&(this._beforeunloadEventListener=()=>{this.transport&&(this.transport.removeAllListeners(),this.transport.close())},addEventListener("beforeunload",this._beforeunloadEventListener,!1)),this.hostname!=="localhost"&&(this._offlineEventListener=()=>{this._onClose("transport close",{description:"network connection lost"})},he.push(this._offlineEventListener))),this.opts.withCredentials&&(this._cookieJar=void 0),this._open()}createTransport(e){const t=Object.assign({},this.opts.query);t.EIO=en,t.transport=e,this.id&&(t.sid=this.id);const n=Object.assign({},this.opts,{query:t,socket:this,hostname:this.hostname,secure:this.secure,port:this.port},this.opts.transportOptions[e]);return new this._transportsByName[e](n)}_open(){if(this.transports.length===0){this.setTimeoutFn(()=>{this.emitReserved("error","No transports available")},0);return}const e=this.opts.rememberUpgrade&&I.priorWebsocketSuccess&&this.transports.indexOf("websocket")!==-1?"websocket":this.transports[0];this.readyState="opening";const t=this.createTransport(e);t.open(),this.setTransport(t)}setTransport(e){this.transport&&this.transport.removeAllListeners(),this.transport=e,e.on("drain",this._onDrain.bind(this)).on("packet",this._onPacket.bind(this)).on("error",this._onError.bind(this)).on("close",t=>this._onClose("transport close",t))}onOpen(){this.readyState="open",I.priorWebsocketSuccess=this.transport.name==="websocket",this.emitReserved("open"),this.flush()}_onPacket(e){if(this.readyState==="opening"||this.readyState==="open"||this.readyState==="closing")switch(this.emitReserved("packet",e),this.emitReserved("heartbeat"),e.type){case"open":this.onHandshake(JSON.parse(e.data));break;case"ping":this._sendPacket("pong"),this.emitReserved("ping"),this.emitReserved("pong"),this._resetPingTimeout();break;case"error":const t=new Error("server error");t.code=e.data,this._onError(t);break;case"message":this.emitReserved("data",e.data),this.emitReserved("message",e.data);break}}onHandshake(e){this.emitReserved("handshake",e),this.id=e.sid,this.transport.query.sid=e.sid,this._pingInterval=e.pingInterval,this._pingTimeout=e.pingTimeout,this._maxPayload=e.maxPayload,this.onOpen(),this.readyState!=="closed"&&this._resetPingTimeout()}_resetPingTimeout(){this.clearTimeoutFn(this._pingTimeoutTimer);const e=this._pingInterval+this._pingTimeout;this._pingTimeoutTime=Date.now()+e,this._pingTimeoutTimer=this.setTimeoutFn(()=>{this._onClose("ping timeout")},e),this.opts.autoUnref&&this._pingTimeoutTimer.unref()}_onDrain(){this.writeBuffer.splice(0,this._prevBufferLen),this._prevBufferLen=0,this.writeBuffer.length===0?this.emitReserved("drain"):this.flush()}flush(){if(this.readyState!=="closed"&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length){const e=this._getWritablePackets();this.transport.send(e),this._prevBufferLen=e.length,this.emitReserved("flush")}}_getWritablePackets(){if(!(this._maxPayload&&this.transport.name==="polling"&&this.writeBuffer.length>1))return this.writeBuffer;let t=1;for(let n=0;n<this.writeBuffer.length;n++){const i=this.writeBuffer[n].data;if(i&&(t+=rs(i)),n>0&&t>this._maxPayload)return this.writeBuffer.slice(0,n);t+=2}return this.writeBuffer}_hasPingExpired(){if(!this._pingTimeoutTime)return!0;const e=Date.now()>this._pingTimeoutTime;return e&&(this._pingTimeoutTime=0,ae(()=>{this._onClose("ping timeout")},this.setTimeoutFn)),e}write(e,t,n){return this._sendPacket("message",e,t,n),this}send(e,t,n){return this._sendPacket("message",e,t,n),this}_sendPacket(e,t,n,i){if(typeof t=="function"&&(i=t,t=void 0),typeof n=="function"&&(i=n,n=null),this.readyState==="closing"||this.readyState==="closed")return;n=n||{},n.compress=n.compress!==!1;const r={type:e,data:t,options:n};this.emitReserved("packetCreate",r),this.writeBuffer.push(r),i&&this.once("flush",i),this.flush()}close(){const e=()=>{this._onClose("forced close"),this.transport.close()},t=()=>{this.off("upgrade",t),this.off("upgradeError",t),e()},n=()=>{this.once("upgrade",t),this.once("upgradeError",t)};return(this.readyState==="opening"||this.readyState==="open")&&(this.readyState="closing",this.writeBuffer.length?this.once("drain",()=>{this.upgrading?n():e()}):this.upgrading?n():e()),this}_onError(e){if(I.priorWebsocketSuccess=!1,this.opts.tryAllTransports&&this.transports.length>1&&this.readyState==="opening")return this.transports.shift(),this._open();this.emitReserved("error",e),this._onClose("transport error",e)}_onClose(e,t){if(this.readyState==="opening"||this.readyState==="open"||this.readyState==="closing"){if(this.clearTimeoutFn(this._pingTimeoutTimer),this.transport.removeAllListeners("close"),this.transport.close(),this.transport.removeAllListeners(),Be&&(this._beforeunloadEventListener&&removeEventListener("beforeunload",this._beforeunloadEventListener,!1),this._offlineEventListener)){const n=he.indexOf(this._offlineEventListener);n!==-1&&he.splice(n,1)}this.readyState="closed",this.id=null,this.emitReserved("close",e,t),this.writeBuffer=[],this._prevBufferLen=0}}}I.protocol=en;class ks extends I{constructor(){super(...arguments),this._upgrades=[]}onOpen(){if(super.onOpen(),this.readyState==="open"&&this.opts.upgrade)for(let e=0;e<this._upgrades.length;e++)this._probe(this._upgrades[e])}_probe(e){let t=this.createTransport(e),n=!1;I.priorWebsocketSuccess=!1;const i=()=>{n||(t.send([{type:"ping",data:"probe"}]),t.once("packet",d=>{if(!n)if(d.type==="pong"&&d.data==="probe"){if(this.upgrading=!0,this.emitReserved("upgrading",t),!t)return;I.priorWebsocketSuccess=t.name==="websocket",this.transport.pause(()=>{n||this.readyState!=="closed"&&(l(),this.setTransport(t),t.send([{type:"upgrade"}]),this.emitReserved("upgrade",t),t=null,this.upgrading=!1,this.flush())})}else{const u=new Error("probe error");u.transport=t.name,this.emitReserved("upgradeError",u)}}))};function r(){n||(n=!0,l(),t.close(),t=null)}const o=d=>{const u=new Error("probe error: "+d);u.transport=t.name,r(),this.emitReserved("upgradeError",u)};function a(){o("transport closed")}function c(){o("socket closed")}function h(d){t&&d.name!==t.name&&r()}const l=()=>{t.removeListener("open",i),t.removeListener("error",o),t.removeListener("close",a),this.off("close",c),this.off("upgrading",h)};t.once("open",i),t.once("error",o),t.once("close",a),this.once("close",c),this.once("upgrading",h),this._upgrades.indexOf("webtransport")!==-1&&e!=="webtransport"?this.setTimeoutFn(()=>{n||t.open()},200):t.open()}onHandshake(e){this._upgrades=this._filterUpgrades(e.upgrades),super.onHandshake(e)}_filterUpgrades(e){const t=[];for(let n=0;n<e.length;n++)~this.transports.indexOf(e[n])&&t.push(e[n]);return t}}let Ts=class extends ks{constructor(e,t={}){const n=typeof e=="object",i=n?{...e}:{...t};(!i.transports||i.transports&&typeof i.transports[0]=="string")&&(i.transports=(i.transports||["polling","websocket","webtransport"]).map(r=>_s[r]).filter(r=>!!r)),super(n?i:e,i)}};function Rs(s,e="",t){let n=s;t=t||typeof location<"u"&&location,s==null&&(s=t.protocol+"//"+t.host),typeof s=="string"&&(s.charAt(0)==="/"&&(s.charAt(1)==="/"?s=t.protocol+s:s=t.host+s),/^(https?|wss?):\/\//.test(s)||(typeof t<"u"?s=t.protocol+"//"+s:s="https://"+s),n=$e(s)),n.port||(/^(http|ws)$/.test(n.protocol)?n.port="80":/^(http|ws)s$/.test(n.protocol)&&(n.port="443")),n.path=n.path||"/";const r=n.host.indexOf(":")!==-1?"["+n.host+"]":n.host;return n.id=n.protocol+"://"+r+":"+n.port+e,n.href=n.protocol+"://"+r+(t&&t.port===n.port?"":":"+n.port),n}const ws=typeof ArrayBuffer=="function",Ps=s=>typeof ArrayBuffer.isView=="function"?ArrayBuffer.isView(s):s.buffer instanceof ArrayBuffer,cn=Object.prototype.toString,Es=typeof Blob=="function"||typeof Blob<"u"&&cn.call(Blob)==="[object BlobConstructor]",Ms=typeof File=="function"||typeof File<"u"&&cn.call(File)==="[object FileConstructor]";function Ue(s){return ws&&(s instanceof ArrayBuffer||Ps(s))||Es&&s instanceof Blob||Ms&&s instanceof File}function le(s,e){if(!s||typeof s!="object")return!1;if(Array.isArray(s)){for(let t=0,n=s.length;t<n;t++)if(le(s[t]))return!0;return!1}if(Ue(s))return!0;if(s.toJSON&&typeof s.toJSON=="function"&&arguments.length===1)return le(s.toJSON(),!0);for(const t in s)if(Object.prototype.hasOwnProperty.call(s,t)&&le(s[t]))return!0;return!1}function As(s){const e=[],t=s.data,n=s;return n.data=ze(t,e),n.attachments=e.length,{packet:n,buffers:e}}function ze(s,e){if(!s)return s;if(Ue(s)){const t={_placeholder:!0,num:e.length};return e.push(s),t}else if(Array.isArray(s)){const t=new Array(s.length);for(let n=0;n<s.length;n++)t[n]=ze(s[n],e);return t}else if(typeof s=="object"&&!(s instanceof Date)){const t={};for(const n in s)Object.prototype.hasOwnProperty.call(s,n)&&(t[n]=ze(s[n],e));return t}return s}function Is(s,e){return s.data=Ne(s.data,e),delete s.attachments,s}function Ne(s,e){if(!s)return s;if(s&&s._placeholder===!0){if(typeof s.num=="number"&&s.num>=0&&s.num<e.length)return e[s.num];throw new Error("illegal attachments")}else if(Array.isArray(s))for(let t=0;t<s.length;t++)s[t]=Ne(s[t],e);else if(typeof s=="object")for(const t in s)Object.prototype.hasOwnProperty.call(s,t)&&(s[t]=Ne(s[t],e));return s}const Os=["connect","connect_error","disconnect","disconnecting","newListener","removeListener"];var m;(function(s){s[s.CONNECT=0]="CONNECT",s[s.DISCONNECT=1]="DISCONNECT",s[s.EVENT=2]="EVENT",s[s.ACK=3]="ACK",s[s.CONNECT_ERROR=4]="CONNECT_ERROR",s[s.BINARY_EVENT=5]="BINARY_EVENT",s[s.BINARY_ACK=6]="BINARY_ACK"})(m||(m={}));class Ds{constructor(e){this.replacer=e}encode(e){return(e.type===m.EVENT||e.type===m.ACK)&&le(e)?this.encodeAsBinary({type:e.type===m.EVENT?m.BINARY_EVENT:m.BINARY_ACK,nsp:e.nsp,data:e.data,id:e.id}):[this.encodeAsString(e)]}encodeAsString(e){let t=""+e.type;return(e.type===m.BINARY_EVENT||e.type===m.BINARY_ACK)&&(t+=e.attachments+"-"),e.nsp&&e.nsp!=="/"&&(t+=e.nsp+","),e.id!=null&&(t+=e.id),e.data!=null&&(t+=JSON.stringify(e.data,this.replacer)),t}encodeAsBinary(e){const t=As(e),n=this.encodeAsString(t.packet),i=t.buffers;return i.unshift(n),i}}class qe extends b{constructor(e){super(),this.opts=Object.assign({reviver:void 0,maxAttachments:10},typeof e=="function"?{reviver:e}:e)}add(e){let t;if(typeof e=="string"){if(this.reconstructor)throw new Error("got plaintext data when reconstructing a packet");t=this.decodeString(e);const n=t.type===m.BINARY_EVENT;n||t.type===m.BINARY_ACK?(t.type=n?m.EVENT:m.ACK,this.reconstructor=new Ls(t),t.attachments===0&&super.emitReserved("decoded",t)):super.emitReserved("decoded",t)}else if(Ue(e)||e.base64)if(this.reconstructor)t=this.reconstructor.takeBinaryData(e),t&&(this.reconstructor=null,super.emitReserved("decoded",t));else throw new Error("got binary data when not reconstructing a packet");else throw new Error("Unknown type: "+e)}decodeString(e){let t=0;const n={type:Number(e.charAt(0))};if(m[n.type]===void 0)throw new Error("unknown packet type "+n.type);if(n.type===m.BINARY_EVENT||n.type===m.BINARY_ACK){const r=t+1;for(;e.charAt(++t)!=="-"&&t!=e.length;);const o=e.substring(r,t);if(o!=Number(o)||e.charAt(t)!=="-")throw new Error("Illegal attachments");const a=Number(o);if(!$s(a)||a<0)throw new Error("Illegal attachments");if(a>this.opts.maxAttachments)throw new Error("too many attachments");n.attachments=a}if(e.charAt(t+1)==="/"){const r=t+1;for(;++t&&!(e.charAt(t)===","||t===e.length););n.nsp=e.substring(r,t)}else n.nsp="/";const i=e.charAt(t+1);if(i!==""&&Number(i)==i){const r=t+1;for(;++t;){const o=e.charAt(t);if(o==null||Number(o)!=o){--t;break}if(t===e.length)break}n.id=Number(e.substring(r,t+1))}if(e.charAt(++t)){const r=this.tryParse(e.substr(t));if(qe.isPayloadValid(n.type,r))n.data=r;else throw new Error("invalid payload")}return n}tryParse(e){try{return JSON.parse(e,this.opts.reviver)}catch{return!1}}static isPayloadValid(e,t){switch(e){case m.CONNECT:return hn(t);case m.DISCONNECT:return t===void 0;case m.CONNECT_ERROR:return typeof t=="string"||hn(t);case m.EVENT:case m.BINARY_EVENT:return Array.isArray(t)&&(typeof t[0]=="number"||typeof t[0]=="string"&&Os.indexOf(t[0])===-1);case m.ACK:case m.BINARY_ACK:return Array.isArray(t)}}destroy(){this.reconstructor&&(this.reconstructor.finishedReconstruction(),this.reconstructor=null)}}class Ls{constructor(e){this.packet=e,this.buffers=[],this.reconPack=e}takeBinaryData(e){if(this.buffers.push(e),this.buffers.length===this.reconPack.attachments){const t=Is(this.reconPack,this.buffers);return this.finishedReconstruction(),t}return null}finishedReconstruction(){this.reconPack=null,this.buffers=[]}}const $s=Number.isInteger||function(s){return typeof s=="number"&&isFinite(s)&&Math.floor(s)===s};function hn(s){return Object.prototype.toString.call(s)==="[object Object]"}const Bs=Object.freeze(Object.defineProperty({__proto__:null,Decoder:qe,Encoder:Ds,get PacketType(){return m}},Symbol.toStringTag,{value:"Module"}));function R(s,e,t){return s.on(e,t),function(){s.off(e,t)}}const Us=Object.freeze({connect:1,connect_error:1,disconnect:1,disconnecting:1,newListener:1,removeListener:1});class ln extends b{constructor(e,t,n){super(),this.connected=!1,this.recovered=!1,this.receiveBuffer=[],this.sendBuffer=[],this._queue=[],this._queueSeq=0,this.ids=0,this.acks={},this.flags={},this.io=e,this.nsp=t,n&&n.auth&&(this.auth=n.auth),this._opts=Object.assign({},n),this.io._autoConnect&&this.open()}get disconnected(){return!this.connected}subEvents(){if(this.subs)return;const e=this.io;this.subs=[R(e,"open",this.onopen.bind(this)),R(e,"packet",this.onpacket.bind(this)),R(e,"error",this.onerror.bind(this)),R(e,"close",this.onclose.bind(this))]}get active(){return!!this.subs}connect(){return this.connected?this:(this.subEvents(),this.io._reconnecting||this.io.open(),this.io._readyState==="open"&&this.onopen(),this)}open(){return this.connect()}send(...e){return e.unshift("message"),this.emit.apply(this,e),this}emit(e,...t){var n,i,r;if(Us.hasOwnProperty(e))throw new Error('"'+e.toString()+'" is a reserved event name');if(t.unshift(e),this._opts.retries&&!this.flags.fromQueue&&!this.flags.volatile)return this._addToQueue(t),this;const o={type:m.EVENT,data:t};if(o.options={},o.options.compress=this.flags.compress!==!1,typeof t[t.length-1]=="function"){const l=this.ids++,d=t.pop();this._registerAckCallback(l,d),o.id=l}const a=(i=(n=this.io.engine)===null||n===void 0?void 0:n.transport)===null||i===void 0?void 0:i.writable,c=this.connected&&!(!((r=this.io.engine)===null||r===void 0)&&r._hasPingExpired());return this.flags.volatile&&!a||(c?(this.notifyOutgoingListeners(o),this.packet(o)):this.sendBuffer.push(o)),this.flags={},this}_registerAckCallback(e,t){var n;const i=(n=this.flags.timeout)!==null&&n!==void 0?n:this._opts.ackTimeout;if(i===void 0){this.acks[e]=t;return}const r=this.io.setTimeoutFn(()=>{delete this.acks[e];for(let a=0;a<this.sendBuffer.length;a++)this.sendBuffer[a].id===e&&this.sendBuffer.splice(a,1);t.call(this,new Error("operation has timed out"))},i),o=(...a)=>{this.io.clearTimeoutFn(r),t.apply(this,a)};o.withError=!0,this.acks[e]=o}emitWithAck(e,...t){return new Promise((n,i)=>{const r=(o,a)=>o?i(o):n(a);r.withError=!0,t.push(r),this.emit(e,...t)})}_addToQueue(e){let t;typeof e[e.length-1]=="function"&&(t=e.pop());const n={id:this._queueSeq++,tryCount:0,pending:!1,args:e,flags:Object.assign({fromQueue:!0},this.flags)};e.push((i,...r)=>(this._queue[0],i!==null?n.tryCount>this._opts.retries&&(this._queue.shift(),t&&t(i)):(this._queue.shift(),t&&t(null,...r)),n.pending=!1,this._drainQueue())),this._queue.push(n),this._drainQueue()}_drainQueue(e=!1){if(!this.connected||this._queue.length===0)return;const t=this._queue[0];t.pending&&!e||(t.pending=!0,t.tryCount++,this.flags=t.flags,this.emit.apply(this,t.args))}packet(e){e.nsp=this.nsp,this.io._packet(e)}onopen(){typeof this.auth=="function"?this.auth(e=>{this._sendConnectPacket(e)}):this._sendConnectPacket(this.auth)}_sendConnectPacket(e){this.packet({type:m.CONNECT,data:this._pid?Object.assign({pid:this._pid,offset:this._lastOffset},e):e})}onerror(e){this.connected||this.emitReserved("connect_error",e)}onclose(e,t){this.connected=!1,delete this.id,this.emitReserved("disconnect",e,t),this._clearAcks()}_clearAcks(){Object.keys(this.acks).forEach(e=>{if(!this.sendBuffer.some(n=>String(n.id)===e)){const n=this.acks[e];delete this.acks[e],n.withError&&n.call(this,new Error("socket has been disconnected"))}})}onpacket(e){if(e.nsp===this.nsp)switch(e.type){case m.CONNECT:e.data&&e.data.sid?this.onconnect(e.data.sid,e.data.pid):this.emitReserved("connect_error",new Error("It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)"));break;case m.EVENT:case m.BINARY_EVENT:this.onevent(e);break;case m.ACK:case m.BINARY_ACK:this.onack(e);break;case m.DISCONNECT:this.ondisconnect();break;case m.CONNECT_ERROR:this.destroy();const n=new Error(e.data.message);n.data=e.data.data,this.emitReserved("connect_error",n);break}}onevent(e){const t=e.data||[];e.id!=null&&t.push(this.ack(e.id)),this.connected?this.emitEvent(t):this.receiveBuffer.push(Object.freeze(t))}emitEvent(e){if(this._anyListeners&&this._anyListeners.length){const t=this._anyListeners.slice();for(const n of t)n.apply(this,e)}super.emit.apply(this,e),this._pid&&e.length&&typeof e[e.length-1]=="string"&&(this._lastOffset=e[e.length-1])}ack(e){const t=this;let n=!1;return function(...i){n||(n=!0,t.packet({type:m.ACK,id:e,data:i}))}}onack(e){const t=this.acks[e.id];typeof t=="function"&&(delete this.acks[e.id],t.withError&&e.data.unshift(null),t.apply(this,e.data))}onconnect(e,t){this.id=e,this.recovered=t&&this._pid===t,this._pid=t,this.connected=!0,this.emitBuffered(),this._drainQueue(!0),this.emitReserved("connect")}emitBuffered(){this.receiveBuffer.forEach(e=>this.emitEvent(e)),this.receiveBuffer=[],this.sendBuffer.forEach(e=>{this.notifyOutgoingListeners(e),this.packet(e)}),this.sendBuffer=[]}ondisconnect(){this.destroy(),this.onclose("io server disconnect")}destroy(){this.subs&&(this.subs.forEach(e=>e()),this.subs=void 0),this.io._destroy(this)}disconnect(){return this.connected&&this.packet({type:m.DISCONNECT}),this.destroy(),this.connected&&this.onclose("io client disconnect"),this}close(){return this.disconnect()}compress(e){return this.flags.compress=e,this}get volatile(){return this.flags.volatile=!0,this}timeout(e){return this.flags.timeout=e,this}onAny(e){return this._anyListeners=this._anyListeners||[],this._anyListeners.push(e),this}prependAny(e){return this._anyListeners=this._anyListeners||[],this._anyListeners.unshift(e),this}offAny(e){if(!this._anyListeners)return this;if(e){const t=this._anyListeners;for(let n=0;n<t.length;n++)if(e===t[n])return t.splice(n,1),this}else this._anyListeners=[];return this}listenersAny(){return this._anyListeners||[]}onAnyOutgoing(e){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.push(e),this}prependAnyOutgoing(e){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.unshift(e),this}offAnyOutgoing(e){if(!this._anyOutgoingListeners)return this;if(e){const t=this._anyOutgoingListeners;for(let n=0;n<t.length;n++)if(e===t[n])return t.splice(n,1),this}else this._anyOutgoingListeners=[];return this}listenersAnyOutgoing(){return this._anyOutgoingListeners||[]}notifyOutgoingListeners(e){if(this._anyOutgoingListeners&&this._anyOutgoingListeners.length){const t=this._anyOutgoingListeners.slice();for(const n of t)n.apply(this,e.data)}}}function z(s){s=s||{},this.ms=s.min||100,this.max=s.max||1e4,this.factor=s.factor||2,this.jitter=s.jitter>0&&s.jitter<=1?s.jitter:0,this.attempts=0}z.prototype.duration=function(){var s=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),t=Math.floor(e*this.jitter*s);s=Math.floor(e*10)&1?s+t:s-t}return Math.min(s,this.max)|0},z.prototype.reset=function(){this.attempts=0},z.prototype.setMin=function(s){this.ms=s},z.prototype.setMax=function(s){this.max=s},z.prototype.setJitter=function(s){this.jitter=s};class Fe extends b{constructor(e,t){var n;super(),this.nsps={},this.subs=[],e&&typeof e=="object"&&(t=e,e=void 0),t=t||{},t.path=t.path||"/socket.io",this.opts=t,ce(this,t),this.reconnection(t.reconnection!==!1),this.reconnectionAttempts(t.reconnectionAttempts||1/0),this.reconnectionDelay(t.reconnectionDelay||1e3),this.reconnectionDelayMax(t.reconnectionDelayMax||5e3),this.randomizationFactor((n=t.randomizationFactor)!==null&&n!==void 0?n:.5),this.backoff=new z({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()}),this.timeout(t.timeout==null?2e4:t.timeout),this._readyState="closed",this.uri=e;const i=t.parser||Bs;this.encoder=new i.Encoder,this.decoder=new i.Decoder,this._autoConnect=t.autoConnect!==!1,this._autoConnect&&this.open()}reconnection(e){return arguments.length?(this._reconnection=!!e,e||(this.skipReconnect=!0),this):this._reconnection}reconnectionAttempts(e){return e===void 0?this._reconnectionAttempts:(this._reconnectionAttempts=e,this)}reconnectionDelay(e){var t;return e===void 0?this._reconnectionDelay:(this._reconnectionDelay=e,(t=this.backoff)===null||t===void 0||t.setMin(e),this)}randomizationFactor(e){var t;return e===void 0?this._randomizationFactor:(this._randomizationFactor=e,(t=this.backoff)===null||t===void 0||t.setJitter(e),this)}reconnectionDelayMax(e){var t;return e===void 0?this._reconnectionDelayMax:(this._reconnectionDelayMax=e,(t=this.backoff)===null||t===void 0||t.setMax(e),this)}timeout(e){return arguments.length?(this._timeout=e,this):this._timeout}maybeReconnectOnOpen(){!this._reconnecting&&this._reconnection&&this.backoff.attempts===0&&this.reconnect()}open(e){if(~this._readyState.indexOf("open"))return this;this.engine=new Ts(this.uri,this.opts);const t=this.engine,n=this;this._readyState="opening",this.skipReconnect=!1;const i=R(t,"open",function(){n.onopen(),e&&e()}),r=a=>{this.cleanup(),this._readyState="closed",this.emitReserved("error",a),e?e(a):this.maybeReconnectOnOpen()},o=R(t,"error",r);if(this._timeout!==!1){const a=this._timeout,c=this.setTimeoutFn(()=>{i(),r(new Error("timeout")),t.close()},a);this.opts.autoUnref&&c.unref(),this.subs.push(()=>{this.clearTimeoutFn(c)})}return this.subs.push(i),this.subs.push(o),this}connect(e){return this.open(e)}onopen(){this.cleanup(),this._readyState="open",this.emitReserved("open");const e=this.engine;this.subs.push(R(e,"ping",this.onping.bind(this)),R(e,"data",this.ondata.bind(this)),R(e,"error",this.onerror.bind(this)),R(e,"close",this.onclose.bind(this)),R(this.decoder,"decoded",this.ondecoded.bind(this)))}onping(){this.emitReserved("ping")}ondata(e){try{this.decoder.add(e)}catch(t){this.onclose("parse error",t)}}ondecoded(e){ae(()=>{this.emitReserved("packet",e)},this.setTimeoutFn)}onerror(e){this.emitReserved("error",e)}socket(e,t){let n=this.nsps[e];return n?this._autoConnect&&!n.active&&n.connect():(n=new ln(this,e,t),this.nsps[e]=n),n}_destroy(e){const t=Object.keys(this.nsps);for(const n of t)if(this.nsps[n].active)return;this._close()}_packet(e){const t=this.encoder.encode(e);for(let n=0;n<t.length;n++)this.engine.write(t[n],e.options)}cleanup(){this.subs.forEach(e=>e()),this.subs.length=0,this.decoder.destroy()}_close(){this.skipReconnect=!0,this._reconnecting=!1,this.onclose("forced close")}disconnect(){return this._close()}onclose(e,t){var n;this.cleanup(),(n=this.engine)===null||n===void 0||n.close(),this.backoff.reset(),this._readyState="closed",this.emitReserved("close",e,t),this._reconnection&&!this.skipReconnect&&this.reconnect()}reconnect(){if(this._reconnecting||this.skipReconnect)return this;const e=this;if(this.backoff.attempts>=this._reconnectionAttempts)this.backoff.reset(),this.emitReserved("reconnect_failed"),this._reconnecting=!1;else{const t=this.backoff.duration();this._reconnecting=!0;const n=this.setTimeoutFn(()=>{e.skipReconnect||(this.emitReserved("reconnect_attempt",e.backoff.attempts),!e.skipReconnect&&e.open(i=>{i?(e._reconnecting=!1,e.reconnect(),this.emitReserved("reconnect_error",i)):e.onreconnect()}))},t);this.opts.autoUnref&&n.unref(),this.subs.push(()=>{this.clearTimeoutFn(n)})}}onreconnect(){const e=this.backoff.attempts;this._reconnecting=!1,this.backoff.reset(),this.emitReserved("reconnect",e)}}const H={};function de(s,e){typeof s=="object"&&(e=s,s=void 0),e=e||{};const t=Rs(s,e.path||"/socket.io"),n=t.source,i=t.id,r=t.path,o=H[i]&&r in H[i].nsps,a=e.forceNew||e["force new connection"]||e.multiplex===!1||o;let c;return a?c=new Fe(n,e):(H[i]||(H[i]=new Fe(n,e)),c=H[i]),t.query&&!e.query&&(e.query=t.queryKey),c.socket(t.path,e)}Object.assign(de,{Manager:Fe,Socket:ln,io:de,connect:de});class zs{constructor(e){this.config=e,this.socket=null,this.callbacks={onMessage:null,onExistingPeers:null,onYouJoined:null,onUserJoined:null,onUserLeft:null,onPeerMediaStateChange:null,onError:null},this.rawListeners=new Map}connect(e){let t=this.config.socketUrl,n="/socket.io/";try{const r=new URL(this.config.socketUrl);t=`${r.protocol}//${r.host}`;const o=r.pathname.replace(/\/+$/,"");o&&(n=`${o}/socket.io/`)}catch{}this.socket=de(t,{path:n,auth:{workspace:e},transports:["websocket","polling"]}),this.socket.on("connect",()=>{console.log("Socket connected")}),this.socket.on("disconnect",()=>{console.log("Socket disconnected")}),this.socket.on("new-message",r=>{this.callbacks.onMessage&&this.callbacks.onMessage(r)}),this.socket.on("existing-peers",r=>{this.callbacks.onExistingPeers&&this.callbacks.onExistingPeers(r)}),this.socket.on("you-joined",r=>{this.callbacks.onYouJoined&&this.callbacks.onYouJoined(r)}),this.socket.on("user-joined",r=>{this.callbacks.onUserJoined&&this.callbacks.onUserJoined(r)}),this.socket.on("user-left",r=>{this.callbacks.onUserLeft&&this.callbacks.onUserLeft(r)}),this.socket.on("peer-media-state-change",r=>{this.callbacks.onPeerMediaStateChange&&this.callbacks.onPeerMediaStateChange(r)});const i=["code-changed","code-language-changed","code-executing","code-execution-result","code-state-sync","code-permission-changed","code-sandbox-toggled","whiteboard-drawing","whiteboard-cleared","whiteboard-image-uploaded","whiteboard-state-sync","whiteboard-permission-changed","whiteboard-toggled"];for(const r of i)this.socket.on(r,o=>{const a=this.rawListeners&&this.rawListeners.get(r);a&&a.forEach(c=>{try{c(o)}catch(h){console.warn(h)}})});this.socket.on("error",r=>{console.error("Socket error:",r),this.callbacks.onError&&this.callbacks.onError(r)})}joinRoom(e,t,n,i){this.socket&&this.socket.emit("join-room",{roomId:e,userId:t,userName:n,peerId:i})}emitMediaState(e,t,n,i){this.socket&&this.socket.emit("media-state-change",{roomId:e,userId:t,type:n,enabled:i})}emit(e,t){this.socket&&this.socket.emit(e,t)}onRaw(e,t){return this.rawListeners.has(e)||this.rawListeners.set(e,new Set),this.rawListeners.get(e).add(t),()=>{var n;return(n=this.rawListeners.get(e))==null?void 0:n.delete(t)}}sendMessage(e,t,n,i,r){if(this.socket){const o={roomId:e,userId:t,userName:n,message:i||""};Array.isArray(r)&&r.length&&(o.attachmentIds=r),this.socket.emit("send-message",o)}}leaveRoom(){this.socket&&this.socket.emit("leave-room")}on(e,t){this.callbacks.hasOwnProperty("on"+e.charAt(0).toUpperCase()+e.slice(1))&&(this.callbacks["on"+e.charAt(0).toUpperCase()+e.slice(1)]=t)}disconnect(){this.socket&&(this.socket.close(),this.socket=null)}}class Ns{constructor(){this.localStream=null,this.remoteStreams={}}async getLocalStream(){if(this.localStream)return this.localStream;try{return this.localStream=await navigator.mediaDevices.getUserMedia({video:!0,audio:!0}),this.localStream}catch(e){throw console.error("Failed to get media devices:",e),e}}addRemoteStream(e,t){this.remoteStreams[e]=t}removeRemoteStream(e){delete this.remoteStreams[e]}toggleVideo(){if(this.localStream){const e=this.localStream.getVideoTracks()[0];if(e)return e.enabled=!e.enabled,e.enabled}return!1}toggleAudio(){if(this.localStream){const e=this.localStream.getAudioTracks()[0];if(e)return e.enabled=!e.enabled,e.enabled}return!1}stopLocalStream(){this.localStream&&(this.localStream.getTracks().forEach(e=>e.stop()),this.localStream=null)}cleanup(){this.stopLocalStream(),this.remoteStreams={}}}class je{constructor(){this.recorder=null,this.stream=null,this.state="idle",this.startedAt=null,this.seq=0,this.pendingUploads=[],this.callbacks={onStateChange:null,onChunk:null}}static isSupported(){return typeof window<"u"&&typeof window.MediaRecorder<"u"}pickMimeType(){const e=["video/webm;codecs=vp9,opus","video/webm;codecs=vp8,opus","video/webm","video/mp4"];for(const t of e)if(window.MediaRecorder.isTypeSupported(t))return t;return""}setState(e){this.state=e,this.callbacks.onStateChange&&this.callbacks.onStateChange(e)}on(e,t){e==="stateChange"?this.callbacks.onStateChange=t:e==="chunk"&&(this.callbacks.onChunk=t)}start(e,t={}){if(!je.isSupported())throw new Error("MediaRecorder API not supported in this browser");if(this.state==="recording")return;if(!e)throw new Error("stream is required to start recording");const n=t.timesliceMs||15e3,i=Number.isFinite(t.videoBitsPerSecond)?t.videoBitsPerSecond:1e6,r=Number.isFinite(t.audioBitsPerSecond)?t.audioBitsPerSecond:64e3;t.onChunk&&(this.callbacks.onChunk=t.onChunk),this.stream=e,this.seq=typeof t.startSeq=="number"?t.startSeq:0,this.pendingUploads=[];const o=this.pickMimeType(),a={videoBitsPerSecond:i,audioBitsPerSecond:r};o&&(a.mimeType=o),this.recorder=new window.MediaRecorder(e,a),this.mimeType=this.recorder.mimeType||o||"video/webm",this.recorder.ondataavailable=c=>{if(!c.data||c.data.size===0)return;const h=this.seq++,l=c.data,d=this.callbacks.onChunk;if(!d)return;const u=Promise.resolve().then(()=>d(l,h)).catch(f=>{console.warn(`Recording chunk seq=${h} upload failed:`,f&&f.message)});this.pendingUploads.push(u)},this.recorder.onerror=c=>{console.error("MediaRecorder error:",c)},this.startedAt=new Date,this.recorder.start(n),this.setState("recording")}async stop(){if(this.state!=="recording"||!this.recorder)return null;await new Promise(r=>{this.recorder.onstop=r,this.recorder.stop()});const t=(await Promise.allSettled(this.pendingUploads)).filter(r=>r.status==="rejected").length,n=new Date,i={startedAt:this.startedAt,endedAt:n,mimeType:this.mimeType,totalChunks:this.seq,droppedChunks:t};return this.recorder=null,this.stream=null,this.startedAt=null,this.pendingUploads=[],this.setState("stopped"),i}isRecording(){return this.state==="recording"||this.state==="paused"}isPaused(){return this.state==="paused"}pause(){if(!this.recorder||this.state!=="recording")return!1;try{return this.recorder.pause(),this.setState("paused"),!0}catch{return!1}}resume(){if(!this.recorder||this.state!=="paused")return!1;try{return this.recorder.resume(),this.setState("recording"),!0}catch{return!1}}}class He{constructor(e={}){this.width=e.width||1280,this.height=e.height||720,this.fps=e.fps||30,this.canvas=null,this.ctx=null,this.videos=new Map,this.audioContext=null,this.audioDestination=null,this.audioSources=new Map,this.combinedStream=null,this.animationHandle=null,this.running=!1}static isSupported(){return typeof window<"u"&&typeof HTMLCanvasElement<"u"&&typeof HTMLCanvasElement.prototype.captureStream=="function"&&typeof(window.AudioContext||window.webkitAudioContext)<"u"}async start(){if(this.running)return this.combinedStream;if(!He.isSupported())throw new Error("Composite recording requires canvas.captureStream + AudioContext");this.canvas=document.createElement("canvas"),this.canvas.width=this.width,this.canvas.height=this.height,this.canvas.style.cssText="position:absolute;left:-9999px;top:-9999px;",document.body.appendChild(this.canvas),this.ctx=this.canvas.getContext("2d");const e=window.AudioContext||window.webkitAudioContext;if(this.audioContext=new e,this.audioContext.state==="suspended")try{await this.audioContext.resume()}catch{}this.audioDestination=this.audioContext.createMediaStreamDestination();const t=this.canvas.captureStream(this.fps);this.combinedStream=new MediaStream;for(const n of t.getVideoTracks())this.combinedStream.addTrack(n);for(const n of this.audioDestination.stream.getAudioTracks())this.combinedStream.addTrack(n);return this.running=!0,this.tick(),this.combinedStream}tick(){this.running&&(this.draw(),this.animationHandle=requestAnimationFrame(()=>this.tick()))}draw(){if(!this.ctx)return;this.ctx.fillStyle="#0d0d0d",this.ctx.fillRect(0,0,this.width,this.height);const e=Array.from(this.videos.values());if(e.length===0)return;const{cols:t,rows:n}=Hs(e.length),i=this.width/t,r=this.height/n;e.forEach((o,a)=>{const c=a%t,h=Math.floor(a/t),l=c*i,d=h*r;this.ctx.fillStyle="#1a1a1a",this.ctx.fillRect(l,d,i,r);const u=o.videoEl.videoWidth||0,f=o.videoEl.videoHeight||0,g=o.videoTrack,_=g&&g.enabled&&g.readyState==="live";if(u>0&&f>0&&_!==!1){const bn=Math.min(i/u,r/f),_n=u*bn,vn=f*bn,si=l+(i-_n)/2,ii=d+(r-vn)/2;try{this.ctx.drawImage(o.videoEl,si,ii,_n,vn)}catch{}}else js(this.ctx,o.label||"Peer",l,d,i,r);const fn=o.label||"Peer";this.ctx.font="bold 16px system-ui, sans-serif";const ei=this.ctx.measureText(fn),mn=10,ti=6,ni=ei.width+mn*2,Ye=24,gn=l+12,yn=d+r-Ye-12;this.ctx.fillStyle="rgba(0,0,0,0.65)",this.ctx.fillRect(gn,yn,ni,Ye),this.ctx.fillStyle="#fff",this.ctx.fillText(fn,gn+mn,yn+Ye-ti-2)})}addStream(e,t,n={}){if(!this.running)return;this.videos.has(e)&&this.removeStream(e);const i=document.createElement("video");i.srcObject=t,i.autoplay=!0,i.muted=!0,i.playsInline=!0,i.style.cssText="position:absolute;left:-9999px;top:-9999px;",document.body.appendChild(i),i.play().catch(()=>{});const r=t.getVideoTracks()[0]||null;this.videos.set(e,{videoEl:i,videoTrack:r,label:n.label||(n.isLocal?"You":e)});const o=t.getAudioTracks();if(o.length&&this.audioContext)try{const a=new MediaStream([o[0]]),c=this.audioContext.createMediaStreamSource(a),h=this.audioContext.createGain();h.gain.value=1,c.connect(h).connect(this.audioDestination),this.audioSources.set(e,{source:c,gain:h})}catch(a){console.warn("Compositor audio source failed for",e,a&&a.message)}}removeStream(e){const t=this.videos.get(e);t&&(t.videoEl.pause(),t.videoEl.srcObject=null,t.videoEl.remove(),this.videos.delete(e));const n=this.audioSources.get(e);if(n){try{n.source.disconnect()}catch{}try{n.gain.disconnect()}catch{}this.audioSources.delete(e)}}getStream(){return this.combinedStream}stop(){if(this.running){this.running=!1,this.animationHandle&&cancelAnimationFrame(this.animationHandle),this.animationHandle=null;for(const e of Array.from(this.videos.keys()))this.removeStream(e);this.combinedStream&&(this.combinedStream.getTracks().forEach(e=>{try{e.stop()}catch{}}),this.combinedStream=null),this.audioContext&&(this.audioContext.close().catch(()=>{}),this.audioContext=null),this.canvas&&(this.canvas.remove(),this.canvas=null,this.ctx=null)}}}function qs(s){const e=String(s).trim().split(/\s+/).filter(Boolean);return e.length===0?"?":e.length===1?e[0].slice(0,2).toUpperCase():(e[0][0]+e[e.length-1][0]).toUpperCase()}function Fs(s){let e=0;const t=String(s);for(let i=0;i<t.length;i++)e=e*31+t.charCodeAt(i)>>>0;return`hsl(${e%360}, 45%, 40%)`}function js(s,e,t,n,i,r){const o=t+i/2,a=n+r/2,c=Math.min(i,r)*.22;s.fillStyle=Fs(e),s.beginPath(),s.arc(o,a,c,0,Math.PI*2),s.fill(),s.fillStyle="#fff",s.font=`600 ${Math.floor(c)}px system-ui, sans-serif`,s.textAlign="center",s.textBaseline="middle",s.fillText(qs(e),o,a+1),s.textAlign="start",s.textBaseline="alphabetic"}function Hs(s){if(s<=1)return{cols:1,rows:1};if(s===2)return{cols:2,rows:1};if(s<=4)return{cols:2,rows:2};if(s<=6)return{cols:3,rows:2};if(s<=9)return{cols:3,rows:3};const e=4;return{cols:e,rows:Math.ceil(s/e)}}function Vs(s,e){return s.includes("pdf")||/\.pdf$/i.test(e)?"📕":s.includes("word")||/\.docx?$/i.test(e)?"📘":s.includes("sheet")||s.includes("excel")||/\.(xlsx?|csv)$/i.test(e)?"📗":s.startsWith("text/")?"📄":"📎"}const dn="repeat(auto-fit, minmax(280px, 1fr))",un="minmax(180px, 1fr)";class Ks{constructor(e={}){this.container=null,this.videoElements={},this.chatMessages=[],this.recording=e.recording||"off",this.screenShare=e.screenShare!==!1,this.enabledPanels=new Set(Array.isArray(e.panels)&&e.panels.length?e.panels:["chat"]),this.enabledPanels.add("chat"),this.activePanel="chat",this.panelSlots={},this._drawerOpen=!1,this._unreadChat=0}mount(e){if(typeof e=="string"?this.container=document.querySelector(e):e instanceof Element&&(this.container=e),!this.container)throw new Error(`Container not found: ${e}`);this._ownershipToken=Symbol("meet-sdk-ownership"),this.container.__meetSdkOwner=this._ownershipToken,this.render()}render(){const e=(a,c,h,l,d="")=>`<button id="${a}" class="ms-btn ${c}" title="${l}" style="${d}">
|
|
42
42
|
<span class="ms-icon" aria-hidden="true">${h}</span><span class="ms-text">${l}</span>
|
|
43
43
|
</button>`,t=this.recording==="manual"?e("toggle-record","ms-btn-rec","●","Record"):"",n=this.recording!=="off"?e("toggle-pause","ms-btn-primary","⏸","Pause","display:none;"):"",i=this.screenShare?e("toggle-screenshare","ms-btn-primary","⛶","Share"):"",r=this.recording!=="off"?'<span id="recording-indicator" class="ms-rec-indicator" style="display:none;"><span id="rec-dot" class="ms-rec-dot"></span>REC <span id="rec-elapsed">00:00</span></span>':"",o=this.recording!=="off"?'<span id="queue-indicator" class="ms-queue-indicator" style="display:none;">⏳ <span id="queue-count">0</span> uploading</span>':"";this._panelWiredOnRender=!0,this.container.innerHTML=`
|
|
44
44
|
<style>
|
|
@@ -372,6 +372,7 @@ a=extmap-allow-mixed`)!==-1){const r=i.sdp.split(`
|
|
|
372
372
|
${r}
|
|
373
373
|
${o}
|
|
374
374
|
<span id="upload-indicator" style="display:none;">Uploading…</span>
|
|
375
|
+
<span id="ms-status" class="ms-status" style="display:none; color:#f87171; font-size:12px; max-width:240px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;"></span>
|
|
375
376
|
<button id="panel-toggle-btn" class="ms-panel-toggle" aria-label="Open side panel">
|
|
376
377
|
☰<span class="ms-badge" id="chat-badge">0</span>
|
|
377
378
|
</button>
|
|
@@ -443,14 +444,14 @@ a=extmap-allow-mixed`)!==-1){const r=i.sdp.split(`
|
|
|
443
444
|
<span style="display:inline-flex; align-items:center; gap:6px; padding:4px 8px; background:#333; border-radius:12px; font-size:12px; color:#ddd;">
|
|
444
445
|
${n.error?`<span style="color:#f87171;">✗ ${this.escapeHtml(n.error)}</span>`:n.pending?"⏳":"✓"} ${r}
|
|
445
446
|
<button data-idx="${i}" class="chat-attach-remove" style="background:transparent; border:0; color:#f87171; cursor:pointer; font-size:14px; padding:0;">×</button>
|
|
446
|
-
</span>`}).join(""),e.querySelectorAll(".chat-attach-remove").forEach(n=>{n.addEventListener("click",i=>{const r=parseInt(i.currentTarget.getAttribute("data-idx"),10);this._pendingAttachments.splice(r,1),this.renderPendingAttachments(),this.updateSendButtonState()})}),this.updateSendButtonState()}_setButtonLabel(e,t){if(!e)return;const n=e.querySelector(".ms-text");n?n.textContent=t:e.textContent=t}updateButtonState(e,t){const n=this.container.querySelector(`#${e}`);this._setButtonLabel(n,t),n&&(n.title=t)}updateRecordingIndicator(e){if(!this.container)return;const t=this.container.querySelector("#recording-indicator");t&&(t.style.display=e==="recording"?"inline-flex":"none");const n=this.container.querySelector("#toggle-record");if(n){const i=e==="recording";this._setButtonLabel(n,i?"Stop":"Record");const r=n.querySelector(".ms-icon");r&&(r.textContent=i?"■":"●"),n.classList.toggle("active",i),n.title=i?"Stop recording":"Start recording"}e==="recording"?this.startRecElapsed():this.stopRecElapsed()}startRecElapsed(){if(this._elapsedHandle)return;const e=Date.now(),t=()=>{const n=this.container&&this.container.querySelector("#rec-elapsed");if(!n)return;const i=Math.floor((Date.now()-e)/1e3),r=String(Math.floor(i/60)).padStart(2,"0"),o=String(i%60).padStart(2,"0");n.textContent=`${r}:${o}`};t(),this._elapsedHandle=setInterval(t,1e3)}stopRecElapsed(){this._elapsedHandle&&(clearInterval(this._elapsedHandle),this._elapsedHandle=null);const e=this.container&&this.container.querySelector("#rec-elapsed");e&&(e.textContent="00:00")}setUploadingIndicator(e){if(!this.container)return;const t=this.container.querySelector("#upload-indicator");t&&(t.style.display=e?"inline":"none")}setScreenSharingState(e){const t=this.container&&this.container.querySelector("#toggle-screenshare");t&&(this._setButtonLabel(t,e?"Stop":"Share"),t.classList.toggle("active",e),t.title=e?"Stop sharing":"Share screen")}setQueueCount(e){if(!this.container)return;const t=this.container.querySelector("#queue-indicator"),n=this.container.querySelector("#queue-count");t&&(t.style.display=e>0?"inline":"none"),n&&(n.textContent=String(e))}setPresentingPeer(e){if(!this.container)return;const t=this.container.querySelector("#video-container");if(!t)return;this._presentingPeer=e||null,e?(t.setAttribute("data-hero",e),t.style.display="flex",t.style.flexDirection="column",t.style.gap="8px",t.style.gridTemplateColumns="",t.style.gridAutoRows="",t.style.overflow="hidden"):(t.removeAttribute("data-hero"),t.style.display="grid",t.style.flexDirection="",t.style.gridTemplateColumns=dn,t.style.gridAutoRows=un,t.style.overflow="");let n=t.querySelector("#others-strip");if(e)n||(n=document.createElement("div"),n.id="others-strip",n.style.cssText="flex: 0 0 auto; display:flex; gap:8px; height:120px; overflow-x:auto; overflow-y:hidden; -webkit-overflow-scrolling: touch;",t.appendChild(n));else if(n){for(;n.firstChild;)t.appendChild(n.firstChild);n.remove()}Object.entries(this.videoElements).forEach(([i,r])=>{e&&i===e?(r.parentNode===n&&t.insertBefore(r,n),r.style.gridColumn="",r.style.flex="1 1 auto",r.style.minHeight="0",r.style.width="100%",r.style.aspectRatio="",r.style.maxHeight=""):e?(r.parentNode!==n&&n.appendChild(r),r.style.flex="0 0 auto",r.style.width="160px",r.style.height="120px",r.style.minHeight="",r.style.aspectRatio="",r.style.maxHeight="",r.style.gridColumn=""):(r.parentNode===n&&t.appendChild(r),r.style.flex="",r.style.width="",r.style.height="",r.style.minHeight="",r.style.gridColumn="",r.style.maxHeight="",r.style.aspectRatio="")})}setParticipants(e,t={}){if(!this.container)return;const n=this.container.querySelector("#participants-list"),i=this.container.querySelector("#participants-count");if(i&&(i.textContent=`(${e.length})`),!n)return;const r=!!t.showControls;n.innerHTML=e.map((o,a)=>{const c=o.isYou?" (You)":o.isHost?" · host":"",h=this.escapeHtml(o.label)+c,l=`<span style="display:inline-block; width:8px; height:8px; border-radius:50%; background:${o.isSharing?"#a3e635":"#6366f1"}; flex-shrink:0;"></span>`,d=r&&!o.isHost&&!o.isYou&&o.userId?`<span style="margin-left:auto; display:inline-flex; gap:4px; flex-shrink:0;">
|
|
447
|
+
</span>`}).join(""),e.querySelectorAll(".chat-attach-remove").forEach(n=>{n.addEventListener("click",i=>{const r=parseInt(i.currentTarget.getAttribute("data-idx"),10);this._pendingAttachments.splice(r,1),this.renderPendingAttachments(),this.updateSendButtonState()})}),this.updateSendButtonState()}_setButtonLabel(e,t){if(!e)return;const n=e.querySelector(".ms-text");n?n.textContent=t:e.textContent=t}updateButtonState(e,t){const n=this.container.querySelector(`#${e}`);this._setButtonLabel(n,t),n&&(n.title=t)}updateRecordingIndicator(e){if(!this.container)return;const t=this.container.querySelector("#recording-indicator");t&&(t.style.display=e==="recording"?"inline-flex":"none");const n=this.container.querySelector("#toggle-record");if(n){const i=e==="recording";this._setButtonLabel(n,i?"Stop":"Record");const r=n.querySelector(".ms-icon");r&&(r.textContent=i?"■":"●"),n.classList.toggle("active",i),n.disabled||(n.title=i?"Stop recording":"Start recording")}e==="recording"?this.startRecElapsed():this.stopRecElapsed()}startRecElapsed(){if(this._elapsedHandle)return;const e=Date.now(),t=()=>{const n=this.container&&this.container.querySelector("#rec-elapsed");if(!n)return;const i=Math.floor((Date.now()-e)/1e3),r=String(Math.floor(i/60)).padStart(2,"0"),o=String(i%60).padStart(2,"0");n.textContent=`${r}:${o}`};t(),this._elapsedHandle=setInterval(t,1e3)}stopRecElapsed(){this._elapsedHandle&&(clearInterval(this._elapsedHandle),this._elapsedHandle=null);const e=this.container&&this.container.querySelector("#rec-elapsed");e&&(e.textContent="00:00")}setUploadingIndicator(e){if(!this.container)return;const t=this.container.querySelector("#upload-indicator");t&&(t.style.display=e?"inline":"none")}setScreenSharingState(e){const t=this.container&&this.container.querySelector("#toggle-screenshare");t&&(this._setButtonLabel(t,e?"Stop":"Share"),t.classList.toggle("active",e),t.title=e?"Stop sharing":"Share screen")}setQueueCount(e){if(!this.container)return;const t=this.container.querySelector("#queue-indicator"),n=this.container.querySelector("#queue-count");t&&(t.style.display=e>0?"inline":"none"),n&&(n.textContent=String(e))}setPresentingPeer(e){if(!this.container)return;const t=this.container.querySelector("#video-container");if(!t)return;this._presentingPeer=e||null,e?(t.setAttribute("data-hero",e),t.style.display="flex",t.style.flexDirection="column",t.style.gap="8px",t.style.gridTemplateColumns="",t.style.gridAutoRows="",t.style.overflow="hidden"):(t.removeAttribute("data-hero"),t.style.display="grid",t.style.flexDirection="",t.style.gridTemplateColumns=dn,t.style.gridAutoRows=un,t.style.overflow="");let n=t.querySelector("#others-strip");if(e)n||(n=document.createElement("div"),n.id="others-strip",n.style.cssText="flex: 0 0 auto; display:flex; gap:8px; height:120px; overflow-x:auto; overflow-y:hidden; -webkit-overflow-scrolling: touch;",t.appendChild(n));else if(n){for(;n.firstChild;)t.appendChild(n.firstChild);n.remove()}Object.entries(this.videoElements).forEach(([i,r])=>{e&&i===e?(r.parentNode===n&&t.insertBefore(r,n),r.style.gridColumn="",r.style.flex="1 1 auto",r.style.minHeight="0",r.style.width="100%",r.style.aspectRatio="",r.style.maxHeight=""):e?(r.parentNode!==n&&n.appendChild(r),r.style.flex="0 0 auto",r.style.width="160px",r.style.height="120px",r.style.minHeight="",r.style.aspectRatio="",r.style.maxHeight="",r.style.gridColumn=""):(r.parentNode===n&&t.appendChild(r),r.style.flex="",r.style.width="",r.style.height="",r.style.minHeight="",r.style.gridColumn="",r.style.maxHeight="",r.style.aspectRatio="")})}setParticipants(e,t={}){if(!this.container)return;const n=this.container.querySelector("#participants-list"),i=this.container.querySelector("#participants-count");if(i&&(i.textContent=`(${e.length})`),!n)return;const r=!!t.showControls;n.innerHTML=e.map((o,a)=>{const c=o.isYou?" (You)":o.isHost?" · host":"",h=this.escapeHtml(o.label)+c,l=`<span style="display:inline-block; width:8px; height:8px; border-radius:50%; background:${o.isSharing?"#a3e635":"#6366f1"}; flex-shrink:0;"></span>`,d=r&&!o.isHost&&!o.isYou&&o.userId?`<span style="margin-left:auto; display:inline-flex; gap:4px; flex-shrink:0;">
|
|
447
448
|
<button data-idx="${a}" data-perm="code" title="Toggle code edit" style="padding:2px 6px; font-size:10px; border-radius:4px; border:1px solid ${o.canEditCode?"#22c55e":"#3a3a3a"}; background:${o.canEditCode?"#052e16":"#1a1a1a"}; color:${o.canEditCode?"#4ade80":"#888"}; cursor:pointer;">Code</button>
|
|
448
449
|
<button data-idx="${a}" data-perm="board" title="Toggle whiteboard draw" style="padding:2px 6px; font-size:10px; border-radius:4px; border:1px solid ${o.canDrawBoard?"#22c55e":"#3a3a3a"}; background:${o.canDrawBoard?"#052e16":"#1a1a1a"}; color:${o.canDrawBoard?"#4ade80":"#888"}; cursor:pointer;">Board</button>
|
|
449
450
|
</span>`:"";return`<div style="font-size:12px; color:#ccc; padding:4px 0; display:flex; align-items:center; gap:6px; min-width:0;">
|
|
450
451
|
${l}
|
|
451
452
|
<span style="overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0;">${h}${o.isSharing?" · presenting":""}</span>
|
|
452
453
|
${d}
|
|
453
|
-
</div>`}).join(""),r&&this._onParticipantPermToggle&&n.querySelectorAll("button[data-perm]").forEach(o=>{o.addEventListener("click",()=>{const a=e[parseInt(o.getAttribute("data-idx"),10)],c=o.getAttribute("data-perm");this._onParticipantPermToggle(a,c)})})}onParticipantPermToggle(e){this._onParticipantPermToggle=e}setPauseButtonVisible(e){const t=this.container&&this.container.querySelector("#toggle-pause");t&&(t.style.display=e?"inline-flex":"none")}setPauseButtonState(e){const t=this.container&&this.container.querySelector("#toggle-pause");if(!t)return;this._setButtonLabel(t,e?"Resume":"Pause");const n=t.querySelector(".ms-icon");n&&(n.textContent=e?"▶":"⏸"),t.title=e?"Resume recording":"Pause recording"}destroy(){this.container&&this.container.__meetSdkOwner===this._ownershipToken&&(this.container.innerHTML="",this.container.__meetSdkOwner=null),this._escHandler&&(window.removeEventListener("keydown",this._escHandler),this._escHandler=null),this._resizeHandler&&(window.removeEventListener("resize",this._resizeHandler),this._resizeHandler=null),this.videoElements={},this.chatMessages=[]}}class Js{constructor(e){this.container=e.container,this.emit=e.emit,this.canRun=e.canRun||(()=>!0),this.canEdit=e.canEdit||(()=>!0),this.userId=e.userId,this.state={code:"",language:"javascript",running:!1,output:null},this._broadcastTimer=null,this.render()}render(){this.container.innerHTML=`
|
|
454
|
+
</div>`}).join(""),r&&this._onParticipantPermToggle&&n.querySelectorAll("button[data-perm]").forEach(o=>{o.addEventListener("click",()=>{const a=e[parseInt(o.getAttribute("data-idx"),10)],c=o.getAttribute("data-perm");this._onParticipantPermToggle(a,c)})})}onParticipantPermToggle(e){this._onParticipantPermToggle=e}setRecordAllowed(e,t){const n=this.container&&this.container.querySelector("#toggle-record");n&&(n.disabled=!e,n.title=e?t||"Record":t||"Only the meeting host can record")}setStatus(e){if(!this.container)return;const t=this.container.querySelector("#ms-status");if(!t)return;const n=e==null?"":String(e);t.textContent=n,t.title=n,t.style.display=n?"inline":"none"}setPauseButtonVisible(e){const t=this.container&&this.container.querySelector("#toggle-pause");t&&(t.style.display=e?"inline-flex":"none")}setPauseButtonState(e){const t=this.container&&this.container.querySelector("#toggle-pause");if(!t)return;this._setButtonLabel(t,e?"Resume":"Pause");const n=t.querySelector(".ms-icon");n&&(n.textContent=e?"▶":"⏸"),t.title=e?"Resume recording":"Pause recording"}destroy(){this.container&&this.container.__meetSdkOwner===this._ownershipToken&&(this.container.innerHTML="",this.container.__meetSdkOwner=null),this._escHandler&&(window.removeEventListener("keydown",this._escHandler),this._escHandler=null),this._resizeHandler&&(window.removeEventListener("resize",this._resizeHandler),this._resizeHandler=null),this.videoElements={},this.chatMessages=[]}}class Js{constructor(e){this.container=e.container,this.emit=e.emit,this.canRun=e.canRun||(()=>!0),this.canEdit=e.canEdit||(()=>!0),this.userId=e.userId,this.state={code:"",language:"javascript",running:!1,output:null},this._broadcastTimer=null,this.render()}render(){this.container.innerHTML=`
|
|
454
455
|
<style>
|
|
455
456
|
.cs-topbar { display:flex; gap:8px; padding:8px 10px; border-bottom:1px solid #333; align-items:center; }
|
|
456
457
|
.cs-select, .cs-runbtn { font-size:13px; padding:6px 10px; border-radius:4px; border:1px solid #333; background:#262626; color:#eee; cursor:pointer; }
|
|
@@ -510,4 +511,4 @@ a=extmap-allow-mixed`)!==-1){const r=i.sdp.split(`
|
|
|
510
511
|
<canvas id="wb-canvas" class="wb-canvas"></canvas>
|
|
511
512
|
</div>
|
|
512
513
|
<div class="wb-note" id="wb-note"></div>
|
|
513
|
-
`,this.canvas=this.container.querySelector("#wb-canvas"),this.wrap=this.container.querySelector("#wb-wrap"),this.ctx=this.canvas.getContext("2d"),this.note=this.container.querySelector("#wb-note"),this._resize=this._resize.bind(this),requestAnimationFrame(()=>{this._resize(),this._replay()}),window.addEventListener("resize",this._resize),this._resizeObserver=null,typeof ResizeObserver<"u"&&(this._resizeObserver=new ResizeObserver(()=>this._resize()),this._resizeObserver.observe(this.wrap)),this.container.querySelectorAll(".wb-tool").forEach(e=>{e.addEventListener("click",()=>{this.tool=e.getAttribute("data-tool"),this.container.querySelectorAll(".wb-tool").forEach(t=>t.classList.toggle("active",t===e))})}),this.container.querySelectorAll(".wb-swatch").forEach(e=>{e.addEventListener("click",()=>{this.color=e.getAttribute("data-color"),this.container.querySelectorAll(".wb-swatch").forEach(t=>t.classList.toggle("active",t===e)),this.tool="pen",this.container.querySelectorAll(".wb-tool").forEach(t=>t.classList.toggle("active",t.getAttribute("data-tool")==="pen"))})}),this.container.querySelector("#wb-size").addEventListener("input",e=>{this.size=parseInt(e.target.value,10)||3}),this.container.querySelector("#wb-clear").addEventListener("click",()=>{this.canDraw()&&(this.emit("whiteboard-clear",{}),this._clearLocal())}),this.canvas.addEventListener("pointerdown",e=>this._onDown(e)),this.canvas.addEventListener("pointermove",e=>this._onMove(e)),this.canvas.addEventListener("pointerup",()=>this._onUp()),this.canvas.addEventListener("pointerleave",()=>this._onUp()),this.refreshPermissionUI()}refreshPermissionUI(){const e=this.canDraw();this.canvas.style.pointerEvents=e?"auto":"none",this.note.textContent=e?"":"View-only — request draw access from the host"}_resize(){if(!this.canvas||!this.wrap)return;const e=this.wrap.getBoundingClientRect(),t=window.devicePixelRatio||1;this.canvas.width=Math.max(300,Math.floor(e.width*t)),this.canvas.height=Math.max(200,Math.floor(e.height*t)),this.ctx.setTransform(t,0,0,t,0,0),this._replay()}_pointerCoords(e){const t=this.canvas.getBoundingClientRect();return{x:(e.clientX-t.left)/t.width,y:(e.clientY-t.top)/t.height}}_drawSegment(e,t,n,i,r){const o=this.canvas.getBoundingClientRect().width,a=this.canvas.getBoundingClientRect().height;this.ctx.lineWidth=r,this.ctx.lineCap="round",this.ctx.lineJoin="round",this.ctx.globalCompositeOperation=n==="eraser"?"destination-out":"source-over",this.ctx.strokeStyle=n==="eraser"?"rgba(0,0,0,1)":i,this.ctx.beginPath(),this.ctx.moveTo(e.x*o,e.y*a),this.ctx.lineTo(t.x*o,t.y*a),this.ctx.stroke()}_onDown(e){if(!this.canDraw())return;e.preventDefault(),this.canvas.setPointerCapture(e.pointerId);const t=this._pointerCoords(e);this.currentStroke={tool:this.tool,color:this.color,size:this.size,points:[t]}}_onMove(e){if(!this.currentStroke)return;const t=this._pointerCoords(e),n=this.currentStroke.points[this.currentStroke.points.length-1];this._drawSegment(n,t,this.currentStroke.tool,this.currentStroke.color,this.currentStroke.size),this.currentStroke.points.push(t)}_onUp(){if(!this.currentStroke||this.currentStroke.points.length<2){this.currentStroke=null;return}const e=this.currentStroke;this.currentStroke=null,this.remoteStrokes.push(e),this.emit("whiteboard-draw",{drawing:e})}_clearLocal(){this.remoteStrokes=[],this.imageData=null,this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height)}_replay(){if(this.ctx){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.imageData&&this._drawBackground();for(const e of this.remoteStrokes){const t=e.points||[];for(let n=1;n<t.length;n++)this._drawSegment(t[n-1],t[n],e.tool,e.color,e.size)}}}_drawBackground(){if(!this.imageData)return;const e=new Image;e.onload=()=>{const t=this.canvas.getBoundingClientRect().width,n=this.canvas.getBoundingClientRect().height;this.ctx.globalCompositeOperation="source-over",this.ctx.drawImage(e,0,0,t,n)},e.src=this.imageData}handleDrawing(e){if(e.userId&&e.userId===this.userId||!e.drawing)return;this.remoteStrokes.push(e.drawing);const t=e.drawing.points||[];for(let n=1;n<t.length;n++)this._drawSegment(t[n-1],t[n],e.drawing.tool,e.drawing.color,e.drawing.size)}handleCleared(){this._clearLocal()}handleImageUploaded(e){this.imageData=e.imageData||null,this._replay()}handleStateSync(e){e&&(this.imageData=e.imageData||null,this.remoteStrokes=Array.isArray(e.drawings)?e.drawings.slice():[],this._replay(),this.refreshPermissionUI())}destroy(){window.removeEventListener("resize",this._resize),this._resizeObserver&&this._resizeObserver.disconnect()}}const Ys=new Set(["auto","manual","off"]),Gs=new Set(["local","composite"]),V="https://preproduction.tentoro.in/videocall";function Qs(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")try{return crypto.randomUUID()}catch{}return"u-"+Date.now().toString(36)+"-"+Math.random().toString(36).slice(2,12)}function Xs({workspace:s,ai:e}){const t={workspace:s};return e&&(e.whisperKey&&(t["x-whisper-key"]=e.whisperKey),e.whisperUrl&&(t["x-whisper-url"]=e.whisperUrl),e.llmKey&&(t["x-llm-key"]=e.llmKey),e.llmUrl&&(t["x-llm-url"]=e.llmUrl),e.llmModel&&(t["x-llm-model"]=e.llmModel)),t}async function ue(s,e,{workspace:t,ai:n,body:i}={}){const r=Xs({workspace:t,ai:n}),o={method:s,headers:r};i!==void 0&&(r["Content-Type"]="application/json",o.body=JSON.stringify(i));const a=await fetch(e,o),c=await a.json().catch(()=>({}));if(!a.ok){const h=new Error(c.error||`HTTP ${a.status}`);throw h.status=a.status,h.body=c,h}return c}function Zs(s){const e=new URL(s),t=e.protocol==="https:",n=e.pathname.replace(/\/+$/,"");return{host:e.hostname,port:e.port?parseInt(e.port,10):t?443:80,path:`${n}/peerjs`,secure:t}}class ${constructor(){this.config=null,this.peerManager=null,this.socketManager=null,this.mediaManager=null,this.uiManager=null,this.isInitialized=!1,this.currentRoom=null,this.currentUser=null}init(e){if(!e||!e.workspace||!e.roomId||!e.user)throw new Error("workspace, roomId, and user are required");const t=e.host||V,n=Ys.has(e.recording)?e.recording:"off",i=n!=="off"&&!!e.transcribe,r=i&&!!e.summarize,o=e.recordOnlyIfHost!==!1,a=Gs.has(e.recordingMode)?e.recordingMode:"local",c=Number.isFinite(e.compositeWidth)?e.compositeWidth:1280,h=Number.isFinite(e.compositeHeight)?e.compositeHeight:720,l=Number.isFinite(e.compositeFps)?e.compositeFps:30,d=Number.isFinite(e.recordingVideoBps)?e.recordingVideoBps:1e6,u=Number.isFinite(e.recordingAudioBps)?e.recordingAudioBps:64e3,f=["chat","code","whiteboard"],g=Array.isArray(e.panels)&&e.panels.length?e.panels.filter(_=>f.includes(_)):["chat"];g.includes("chat")||g.unshift("chat"),this.config={...e,host:t,apiUrl:e.apiUrl||`${t}/api`,socketUrl:e.socketUrl||t,peerServer:e.peerServer||Zs(t),ai:{...e.ai||{}},recording:n,transcribe:i,summarize:r,recordOnlyIfHost:o,recordingMode:a,compositeWidth:c,compositeHeight:h,compositeFps:l,recordingVideoBps:d,recordingAudioBps:u,panels:g},this.myRole=null,this.roleResolvers=[],this.currentRoom=this.config.roomId,this.currentUser=this.config.user,this.peerManager=new Vn(this.config),this.socketManager=new zs(this.config),this.mediaManager=new Ns,this.uiManager=new Ks({recording:n,screenShare:e.screenShare!==!1,panels:g}),this.recorder=n==="off"?null:new Fe,this.compositor=null,this.setupEventHandlers(),this.isInitialized=!0,console.log("MeetSDK initialized")}setupEventHandlers(){this.peerManager.on("stream",(e,t,n)=>{const i=this.labelForPeer(e,n);this.mediaManager.addRemoteStream(e,t),this.uiManager.addVideoStream(e,t,n,i),this.compositor&&this.compositor.addStream(e,t,{isLocal:n,label:i}),this.refreshParticipantsPanel()}),this.peerManager.on("peerLeft",e=>{this.mediaManager.removeRemoteStream(e),this.uiManager.removeVideoStream(e),this.compositor&&this.compositor.removeStream(e),this.refreshParticipantsPanel()}),this.peerManager.on("screenShareEnded",()=>{this.uiManager.setScreenSharingState(!1),this.socketManager.emitMediaState(this.currentRoom,this.currentUser.id,"screen",!1),this.uiManager.setPresentingPeer&&this.uiManager.setPresentingPeer(null),this.presentingPeerId=null,this.refreshParticipantsPanel()}),this.socketManager.on("message",e=>{this.uiManager.addChatMessage(e)}),this.peerLabels=new Map,this.socketManager.on("existingPeers",e=>{e.forEach(t=>{this.peerLabels.set(t.peerId,t.userName||t.userId),this.peerManager.callPeer(t.peerId)}),this.refreshParticipantsPanel()}),this.socketManager.on("userJoined",e=>{this.peerLabels.set(e.peerId,e.userName||e.userId),this.uiManager.updateVideoStreamLabel(e.peerId,e.userName||e.userId),this.peerManager.callPeer(e.peerId),this.refreshParticipantsPanel()}),this.socketManager.on("userLeft",e=>{const t=e.peerId||e.userId;this.mediaManager.removeRemoteStream(t),this.uiManager.removeVideoStream(t),this.compositor&&t&&this.compositor.removeStream(t),e.peerId&&this.peerLabels.delete(e.peerId),this.refreshParticipantsPanel()}),this.socketManager.on("peerMediaStateChange",e=>{if(!e||!e.userId||e.type!=="screen")return;let t=null;for(const[n]of this.peerLabels.entries())if(n.endsWith(`-${e.userId}`)){t=n;break}t&&(e.enabled?this.setPresentingPeer(t):this.presentingPeerId===t&&this.setPresentingPeer(null))}),this.socketManager.on("youJoined",e=>{if(this.myRole=e&&e.role?e.role:"candidate",console.log(`MeetSDK: joined as ${this.myRole}`+(e&&e.hostId?` (host is ${e.hostName||e.hostId})`:"")),e&&e.hostId){for(const[n]of this.peerLabels.entries())if(n.endsWith(`-${e.hostId}`)){this.hostPeerId=n;break}}const t=this.roleResolvers;this.roleResolvers=[];for(const n of t)n(this.myRole);this.refreshParticipantsPanel(),this.codeSandbox&&this.codeSandbox.refreshPermissionUI(),this.whiteboard&&this.whiteboard.refreshPermissionUI()})}async hydrateIceServers(){try{const e=await fetch(`${this.config.apiUrl}/rt-config`,{headers:this.buildHeaders()});if(!e.ok)return;const t=await e.json();if(!t||!Array.isArray(t.iceServers)||t.iceServers.length===0)return;const n=Array.isArray(this.config.iceServers)?this.config.iceServers:[];this.config.iceServers=[...n,...t.iceServers]}catch(e){console.warn("rt-config fetch failed, using STUN defaults:",e&&e.message)}}labelForPeer(e,t){return t?this.currentUser&&this.currentUser.name?this.currentUser.name:"You":this.peerLabels&&this.peerLabels.has(e)?this.peerLabels.get(e):e}setPresentingPeer(e){this.presentingPeerId=e||null,this.uiManager&&this.uiManager.setPresentingPeer&&this.uiManager.setPresentingPeer(this.presentingPeerId),this.refreshParticipantsPanel()}refreshParticipantsPanel(){if(!this.uiManager)return;const e=[];if(this.currentUser&&e.push({label:this.currentUser.name||"You",userId:this.currentUser.id,isYou:!0,isHost:this.myRole==="organizer",isSharing:this.peerManager&&this.peerManager.isScreenSharing&&this.peerManager.isScreenSharing()}),this.peerLabels){const t=`${this.config.workspace}-${this.currentRoom}-`;for(const[n,i]of this.peerLabels.entries()){const r=n.startsWith(t)?n.slice(t.length):n;e.push({label:i,userId:r,isYou:!1,isHost:this.hostPeerId===n,isSharing:this.presentingPeerId===n,canEditCode:this.codePermsByUser?!!this.codePermsByUser.get(r):!1,canDrawBoard:this.boardPermsByUser?!!this.boardPermsByUser.get(r):!1})}}this.uiManager.setParticipants(e,{showControls:this.myRole==="organizer"})}waitForRole(e=3e3){return this.myRole?Promise.resolve(this.myRole):new Promise(t=>{const n=setTimeout(()=>t(this.myRole||"candidate"),e);this.roleResolvers.push(i=>{clearTimeout(n),t(i)})})}async mount(e){if(!this.isInitialized)throw new Error("SDK not initialized. Call init() first.");this.uiManager.mount(e),await this.hydrateIceServers();const t=`${this.config.workspace}-${this.currentRoom}-${this.currentUser.id}`;await this.peerManager.initialize(t);const n=await this.peerManager.getLocalStream();if(this.uiManager.addVideoStream("local",n,!0),this.config.recordingMode==="composite"&&this.recorder)try{this.compositor=new He({width:this.config.compositeWidth,height:this.config.compositeHeight,fps:this.config.compositeFps}),await this.compositor.start(),this.compositor.addStream("local",n,{isLocal:!0,label:this.labelForPeer("local",!0)})}catch(i){console.warn("Composite recording unavailable, falling back to local:",i.message),this.compositor=null}this.socketManager.connect(this.config.workspace),setTimeout(()=>{this.socketManager.joinRoom(this.currentRoom,this.currentUser.id,this.currentUser.name,t)},500),this.setupUIControls(),this.setupRecording(n).catch(i=>console.error("setupRecording failed:",i)),this.setupCollabPanels(),this.fetchChatHistory().then(i=>{i&&i.messages&&this.uiManager.setChatHistory(i.messages)}).catch(i=>console.warn("Chat history fetch failed:",i&&i.message)),console.log("MeetSDK mounted")}setupCollabPanels(){if(this.uiManager&&!this.uiManager._panelWired&&(this.uiManager.wirePanelTabs(),this.uiManager._panelWired=!0),this.codePermsByUser=this.codePermsByUser||new Map,this.boardPermsByUser=this.boardPermsByUser||new Map,this.uiManager&&this.uiManager.onParticipantPermToggle&&this.uiManager.onParticipantPermToggle((e,t)=>{if(!(this.myRole!=="organizer"||!e||!e.userId)){if(t==="code"){const n=!this.codePermsByUser.get(e.userId);this.grantCodeEdit(e.userId,e.label,n)}else if(t==="board"){const n=!this.boardPermsByUser.get(e.userId);this.grantWhiteboardDraw(e.userId,e.label,n)}}}),this.config.panels.includes("code")){const e=this.uiManager.getPanelSlot("code");e&&(this.codeSandbox=new Js({container:e,userId:this.currentUser.id,canEdit:()=>this._canEditCode(),canRun:()=>this._canEditCode(),emit:(t,n)=>{this.socketManager.emit(t,{roomId:this.currentRoom,userId:this.currentUser.id,userName:this.currentUser.name,...n})}}),this.socketManager.onRaw("code-changed",t=>this.codeSandbox.handleCodeChanged(t)),this.socketManager.onRaw("code-language-changed",t=>this.codeSandbox.handleLanguageChanged(t)),this.socketManager.onRaw("code-executing",t=>this.codeSandbox.handleExecuting(t)),this.socketManager.onRaw("code-execution-result",t=>this.codeSandbox.handleExecutionResult(t)),this.socketManager.onRaw("code-state-sync",t=>{if(t&&Array.isArray(t.editPermissions)){const n=t.editPermissions.find(i=>i.userId===this.currentUser.id);this._codeEditPermission=!!(n&&n.canEdit);for(const i of t.editPermissions)this.codePermsByUser.set(i.userId,!!i.canEdit)}this.codeSandbox.handleStateSync(t),this.refreshParticipantsPanel()}),this.socketManager.onRaw("code-permission-changed",t=>{if(t&&t.targetUserId===this.currentUser.id&&(this._codeEditPermission=!!t.canEdit),t&&t.targetUserId&&this.codePermsByUser.set(t.targetUserId,!!t.canEdit),Array.isArray(t&&t.editPermissions)){const n=t.editPermissions.find(i=>i.userId===this.currentUser.id);n&&(this._codeEditPermission=!!n.canEdit);for(const i of t.editPermissions)this.codePermsByUser.set(i.userId,!!i.canEdit)}this.codeSandbox.refreshPermissionUI(),this.refreshParticipantsPanel()}),this.socketManager.emit("code-state-request",{roomId:this.currentRoom}))}if(this.config.panels.includes("whiteboard")){const e=this.uiManager.getPanelSlot("whiteboard");e&&(this.whiteboard=new Ws({container:e,userId:this.currentUser.id,canDraw:()=>this._canDrawWhiteboard(),emit:(t,n)=>{this.socketManager.emit(t,{roomId:this.currentRoom,userId:this.currentUser.id,userName:this.currentUser.name,...n})}}),this.socketManager.onRaw("whiteboard-drawing",t=>this.whiteboard.handleDrawing(t)),this.socketManager.onRaw("whiteboard-cleared",()=>this.whiteboard.handleCleared()),this.socketManager.onRaw("whiteboard-image-uploaded",t=>this.whiteboard.handleImageUploaded(t)),this.socketManager.onRaw("whiteboard-state-sync",t=>{if(t&&Array.isArray(t.drawPermissions)){const n=t.drawPermissions.find(i=>i.userId===this.currentUser.id);this._whiteboardDrawPermission=!!(n&&n.canDraw);for(const i of t.drawPermissions)this.boardPermsByUser.set(i.userId,!!i.canDraw)}this.whiteboard.handleStateSync(t),this.refreshParticipantsPanel()}),this.socketManager.onRaw("whiteboard-permission-changed",t=>{if(t&&t.targetUserId===this.currentUser.id&&(this._whiteboardDrawPermission=!!t.canDraw),t&&t.targetUserId&&this.boardPermsByUser.set(t.targetUserId,!!t.canDraw),Array.isArray(t&&t.drawPermissions)){const n=t.drawPermissions.find(i=>i.userId===this.currentUser.id);n&&(this._whiteboardDrawPermission=!!n.canDraw);for(const i of t.drawPermissions)this.boardPermsByUser.set(i.userId,!!i.canDraw)}this.whiteboard.refreshPermissionUI(),this.refreshParticipantsPanel()}),this.socketManager.emit("whiteboard-state-request",{roomId:this.currentRoom}))}}_canEditCode(){return this.myRole==="organizer"?!0:!!this._codeEditPermission}_canDrawWhiteboard(){return this.myRole==="organizer"?!0:!!this._whiteboardDrawPermission}async fetchChatHistory(e={}){if(!this.isInitialized)throw new Error("SDK not initialized");const t=new URLSearchParams;e.limit&&t.set("limit",String(e.limit)),e.before&&t.set("before",e.before),e.after&&t.set("after",e.after);const n=t.toString(),i=await fetch(`${this.config.apiUrl}/rooms/${encodeURIComponent(this.currentRoom)}/chat/messages${n?"?"+n:""}`,{headers:this.buildHeaders()});if(!i.ok)throw new Error(`chat/messages: HTTP ${i.status}`);return i.json()}async uploadChatAttachment(e){if(!this.isInitialized)throw new Error("SDK not initialized");const t=new FormData;t.append("file",e,e.name),t.append("userId",this.currentUser.id),t.append("userName",this.currentUser.name);const n=await fetch(`${this.config.apiUrl}/rooms/${encodeURIComponent(this.currentRoom)}/chat/attachments`,{method:"POST",headers:this.buildHeaders(),body:t});if(!n.ok){const i=await n.json().catch(()=>({}));throw new Error(i.error||`Upload failed: HTTP ${n.status}`)}return n.json()}async setupRecording(e){if(this.recorder){if(this.recorder.on("stateChange",t=>{this.uiManager.updateRecordingIndicator(t),this.uiManager.setPauseButtonVisible(t==="recording"||t==="paused"),this.uiManager.setPauseButtonState(t==="paused")}),this.uiManager.onControlClick("toggle-pause",()=>{this.recorder.isPaused()?this.recorder.resume():this.recorder.pause()}),this.config.recordOnlyIfHost&&await this.waitForRole()!=="organizer"){console.log("MeetSDK: not the host — skipping recording");return}this.config.recording==="auto"&&this.startRecording().catch(t=>console.error("Auto-record failed:",t)),this.config.recording==="manual"&&this.uiManager.onControlClick("toggle-record",async()=>{this.recorder.isRecording()?await this.stopRecording():await this.startRecording()})}}async startRecording(){if(!this.recorder)throw new Error("recording is disabled in SDK config");let e;if(this.config.recordingMode==="composite"&&this.compositor){if(e=this.compositor.getStream(),!e)throw new Error("composite stream not ready")}else if(e=this.peerManager.localStream,!e)throw new Error("local stream not ready");const t=this.readStoredSession();let n=null,i=0;if(t){const r=await this.probeSessionStatus(t.sessionId).catch(()=>null);r&&r.active?(n={sessionId:t.sessionId},i=(r.lastSeq||-1)+1,console.log(`MeetSDK: resuming recording session ${t.sessionId} at seq=${i}`)):this.clearStoredSession()}n||(n=await this.startRecordingSession(),this.persistStoredSession(n)),this.recordingSession=n,this.chunkQueue=[],this.chunkDrainerRunning=!1,this.recorder.start(e,{timesliceMs:15e3,startSeq:i,videoBitsPerSecond:this.config.recordingVideoBps,audioBitsPerSecond:this.config.recordingAudioBps,onChunk:(r,o)=>(this.enqueueChunk(n.sessionId,r,o),Promise.resolve())})}storedSessionKey(){return`meetSdk.session.${this.config.workspace}.${this.currentRoom}`}readStoredSession(){try{const e=window.localStorage.getItem(this.storedSessionKey());if(!e)return null;const t=JSON.parse(e);return Date.now()-(t.at||0)>24*60*60*1e3?null:t}catch{return null}}persistStoredSession(e){try{window.localStorage.setItem(this.storedSessionKey(),JSON.stringify({sessionId:e.sessionId,at:Date.now()}))}catch{}}clearStoredSession(){try{window.localStorage.removeItem(this.storedSessionKey())}catch{}}async probeSessionStatus(e){const t=await fetch(`${this.config.apiUrl}/rooms/${encodeURIComponent(this.currentRoom)}/recordings/session/${encodeURIComponent(e)}/status`,{headers:this.buildHeaders()});return t.ok?t.json():null}enqueueChunk(e,t,n){this.chunkQueue=this.chunkQueue||[],this.chunkQueue.push({sessionId:e,blob:t,seq:n}),this.uiManager&&this.uiManager.setQueueCount&&this.uiManager.setQueueCount(this.chunkQueue.length),this.runChunkDrainer().catch(i=>console.warn("Chunk drainer error:",i&&i.message))}async runChunkDrainer(){if(!this.chunkDrainerRunning){this.chunkDrainerRunning=!0;try{for(;this.chunkQueue&&this.chunkQueue.length>0;){const e=this.chunkQueue[0];try{await this.uploadRecordingChunk(e.sessionId,e.blob,e.seq),this.chunkQueue.shift(),this.uiManager&&this.uiManager.setQueueCount&&this.uiManager.setQueueCount(this.chunkQueue.length)}catch(t){if(/HTTP 404|HTTP 409/.test(String(t&&t.message))){console.warn(`Dropping chunk seq=${e.seq}: ${t.message}`),this.chunkQueue.shift(),this.uiManager&&this.uiManager.setQueueCount&&this.uiManager.setQueueCount(this.chunkQueue.length);continue}const n=Math.min(3e4,1e3*Math.pow(2,this._chunkFailStreak||0));this._chunkFailStreak=(this._chunkFailStreak||0)+1,console.warn(`Chunk seq=${e.seq} failed, retrying in ${n}ms`),await new Promise(i=>setTimeout(i,n))}}this._chunkFailStreak=0}finally{this.chunkDrainerRunning=!1}}}async waitForChunkQueueEmpty(){for(;this.chunkQueue&&this.chunkQueue.length>0||this.chunkDrainerRunning;)await new Promise(e=>setTimeout(e,200))}async stopRecording(){if(!this.recorder)return null;const e=await this.recorder.stop();if(!e||!this.recordingSession)return null;const t=this.recordingSession.sessionId;this.recordingSession=null,await this.waitForChunkQueueEmpty();try{return await this.finalizeRecordingSession(t,e)}catch(n){throw console.error("Recording finalize failed:",n),n}}async startRecordingSession(){const e={recordedBy:this.currentUser.id,contentType:this.recorder.mimeType||"video/webm",transcribe:this.config.transcribe,summarize:this.config.summarize},t=await fetch(`${this.config.apiUrl}/rooms/${encodeURIComponent(this.currentRoom)}/recordings/session/start`,{method:"POST",headers:{...this.buildHeaders(),"Content-Type":"application/json"},body:JSON.stringify(e)});if(!t.ok)throw new Error(`session/start failed: HTTP ${t.status}`);return t.json()}async uploadRecordingChunk(e,t,n){const i=new FormData;i.append("chunk",t,`chunk-${n}.webm`);const r=await fetch(`${this.config.apiUrl}/rooms/${encodeURIComponent(this.currentRoom)}/recordings/session/${encodeURIComponent(e)}/chunk?seq=${n}`,{method:"POST",headers:this.buildHeaders(),body:i});if(!r.ok)throw new Error(`chunk seq=${n}: HTTP ${r.status}`)}async finalizeRecordingSession(e,t){const n=Math.max(0,Math.round((t.endedAt-t.startedAt)/1e3)),i=await fetch(`${this.config.apiUrl}/rooms/${encodeURIComponent(this.currentRoom)}/recordings/session/${encodeURIComponent(e)}/finalize`,{method:"POST",headers:{...this.buildHeaders(),"Content-Type":"application/json"},body:JSON.stringify({durationSec:n,startedAt:t.startedAt.toISOString(),endedAt:t.endedAt.toISOString()})});if(!i.ok)throw new Error(`session/finalize failed: HTTP ${i.status}`);const r=await i.json();return this.clearStoredSession(),r}async listRecordings(){if(!this.isInitialized)throw new Error("SDK not initialized");return(await fetch(`${this.config.apiUrl}/rooms/${encodeURIComponent(this.currentRoom)}/recordings`,{headers:this.buildHeaders()})).json()}async getRecording(e){if(!this.isInitialized)throw new Error("SDK not initialized");return(await fetch(`${this.config.apiUrl}/rooms/${encodeURIComponent(this.currentRoom)}/recordings/${encodeURIComponent(e)}`,{headers:this.buildHeaders()})).json()}setupUIControls(){let e=!0,t=!0;this.uiManager.onControlClick("toggle-video",()=>{e=this.peerManager.toggleVideo(),this.uiManager.updateButtonState("toggle-video",e?"Video On":"Video Off")}),this.uiManager.onControlClick("toggle-audio",()=>{t=this.peerManager.toggleAudio(),this.uiManager.updateButtonState("toggle-audio",t?"Mic On":"Mic Off")}),this.uiManager.onControlClick("leave-meeting",()=>{this.leave()}),this.uiManager.onControlClick("toggle-screenshare",async()=>{try{if(this.peerManager.isScreenSharing())await this.peerManager.stopScreenShare(),this.uiManager.setScreenSharingState(!1),this.socketManager.emitMediaState(this.currentRoom,this.currentUser.id,"screen",!1),this.setPresentingPeer(null);else{await this.peerManager.startScreenShare(),this.uiManager.setScreenSharingState(!0),this.socketManager.emitMediaState(this.currentRoom,this.currentUser.id,"screen",!0);const n=`${this.config.workspace}-${this.currentRoom}-${this.currentUser.id}`;this.setPresentingPeer(n)}}catch(n){console.warn("Screen share toggle failed:",n&&n.message)}}),this.uiManager.onChatSend((n,i)=>{this.socketManager.sendMessage(this.currentRoom,this.currentUser.id,this.currentUser.name,n,i)}),this.uiManager.onAttachFile(async n=>this.uploadChatAttachment(n))}buildHeaders(e={}){const t=this.config.ai||{},n={workspace:this.config.workspace,...e};return t.whisperKey&&(n["x-whisper-key"]=t.whisperKey),t.whisperUrl&&(n["x-whisper-url"]=t.whisperUrl),t.llmKey&&(n["x-llm-key"]=t.llmKey),t.llmUrl&&(n["x-llm-url"]=t.llmUrl),t.llmModel&&(n["x-llm-model"]=t.llmModel),n}setAiConfig(e={}){if(!this.config)throw new Error("SDK not initialized");this.config.ai={...this.config.ai||{},...e}}async getSummary(){if(!this.isInitialized)throw new Error("SDK not initialized");return(await fetch(`${this.config.apiUrl}/rooms/${this.currentRoom}/summary`,{headers:this.buildHeaders()})).json()}async generateSummary(){if(!this.isInitialized)throw new Error("SDK not initialized");return(await fetch(`${this.config.apiUrl}/rooms/${this.currentRoom}/summary/generate`,{method:"POST",headers:this.buildHeaders()})).json()}async transcribeAudio(e,t="audio.webm"){if(!this.isInitialized)throw new Error("SDK not initialized");const n=new FormData;return n.append("audio",e,t),(await fetch(`${this.config.apiUrl}/rooms/${this.currentRoom}/transcribe`,{method:"POST",headers:this.buildHeaders(),body:n})).json()}grantCodeEdit(e,t,n=!0){this.socketManager.emit("code-permission-change",{roomId:this.currentRoom,userId:this.currentUser.id,targetUserId:e,targetUserName:t||e,canEdit:!!n})}grantWhiteboardDraw(e,t,n=!0){this.socketManager.emit("whiteboard-permission-change",{roomId:this.currentRoom,userId:this.currentUser.id,targetUserId:e,targetUserName:t||e,canDraw:!!n})}static async createMeeting(e={}){const{workspace:t,host:n,ai:i,title:r,hostUserId:o,hostName:a,hostId:c,scheduledFor:h,users:l}=e;if(!t)throw new Error("workspace is required");const d=n||V,u={};return r!==void 0&&(u.title=r),o!==void 0&&(u.hostUserId=o),a!==void 0&&(u.hostName=a),c!==void 0&&(u.hostId=c),h!==void 0&&(u.scheduledFor=h),l!==void 0&&(u.users=l),ue("POST",`${d}/api/meetings/schedule`,{workspace:t,ai:i,body:u})}static async updateMeeting(e={}){const{workspace:t,roomId:n,host:i,ai:r,title:o,hostUserId:a,hostName:c,users:h,scheduledFor:l}=e;if(!t)throw new Error("workspace is required");if(!n)throw new Error("roomId is required");const d=i||V,u={};return o!==void 0&&(u.title=o),a!==void 0&&(u.hostUserId=a),c!==void 0&&(u.hostName=c),h!==void 0&&(u.users=h),l!==void 0&&(u.scheduledFor=l),ue("PATCH",`${d}/api/meetings/${encodeURIComponent(n)}`,{workspace:t,ai:r,body:u})}static async cancelMeeting(e={}){const{workspace:t,roomId:n,host:i,ai:r}=e;if(!t)throw new Error("workspace is required");if(!n)throw new Error("roomId is required");return ue("DELETE",`${i||V}/api/meetings/${encodeURIComponent(n)}`,{workspace:t,ai:r})}static async listMeetings(e={}){const{workspace:t,host:n,ai:i,status:r,upcoming:o}=e;if(!t)throw new Error("workspace is required");const a=n||V,c=new URLSearchParams;r&&c.set("status",r),o&&c.set("upcoming","true");const h=c.toString();return ue("GET",`${a}/api/meetings${h?"?"+h:""}`,{workspace:t,ai:i})}static async quickJoin(e={}){const{workspace:t,roomId:n,userName:i,container:r}=e;if(!t||!n||!i||!r)throw new Error("workspace, roomId, userName, and container are required");const o=e.userId||Qs(),{userId:a,userName:c,container:h,...l}=e,d=new $;return d.init({...l,workspace:t,roomId:n,user:{id:o,name:i}}),await d.mount(r),d}async leave(){if(!(this._leaving||this._left)){if(this._leaving=!0,this.recorder&&this.recorder.isRecording())try{this.uiManager.setUploadingIndicator(!0),await this.stopRecording()}catch(e){console.warn("Recording upload on leave failed:",e)}finally{try{this.uiManager.setUploadingIndicator(!1)}catch{}}try{this.socketManager.leaveRoom()}catch{}try{this.socketManager.disconnect()}catch{}try{this.peerManager.disconnect()}catch{}try{this.mediaManager.cleanup()}catch{}try{this.uiManager.destroy()}catch{}if(this.compositor){try{this.compositor.stop()}catch{}this.compositor=null}if(this.isInitialized=!1,this._left=!0,this._leaving=!1,console.log("Left meeting"),this.config&&typeof this.config.onLeave=="function")try{await this.config.onLeave(this)}catch(e){console.warn("onLeave threw:",e)}}}}if(typeof window<"u"){const s=new $;["createMeeting","updateMeeting","cancelMeeting","listMeetings","quickJoin"].forEach(e=>{s[e]=$[e].bind($)}),window.MeetSDK=s,window.MeetSDKClass=$}k.default=$,Object.defineProperties(k,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
|
514
|
+
`,this.canvas=this.container.querySelector("#wb-canvas"),this.wrap=this.container.querySelector("#wb-wrap"),this.ctx=this.canvas.getContext("2d"),this.note=this.container.querySelector("#wb-note"),this._resize=this._resize.bind(this),requestAnimationFrame(()=>{this._resize(),this._replay()}),window.addEventListener("resize",this._resize),this._resizeObserver=null,typeof ResizeObserver<"u"&&(this._resizeObserver=new ResizeObserver(()=>this._resize()),this._resizeObserver.observe(this.wrap)),this.container.querySelectorAll(".wb-tool").forEach(e=>{e.addEventListener("click",()=>{this.tool=e.getAttribute("data-tool"),this.container.querySelectorAll(".wb-tool").forEach(t=>t.classList.toggle("active",t===e))})}),this.container.querySelectorAll(".wb-swatch").forEach(e=>{e.addEventListener("click",()=>{this.color=e.getAttribute("data-color"),this.container.querySelectorAll(".wb-swatch").forEach(t=>t.classList.toggle("active",t===e)),this.tool="pen",this.container.querySelectorAll(".wb-tool").forEach(t=>t.classList.toggle("active",t.getAttribute("data-tool")==="pen"))})}),this.container.querySelector("#wb-size").addEventListener("input",e=>{this.size=parseInt(e.target.value,10)||3}),this.container.querySelector("#wb-clear").addEventListener("click",()=>{this.canDraw()&&(this.emit("whiteboard-clear",{}),this._clearLocal())}),this.canvas.addEventListener("pointerdown",e=>this._onDown(e)),this.canvas.addEventListener("pointermove",e=>this._onMove(e)),this.canvas.addEventListener("pointerup",()=>this._onUp()),this.canvas.addEventListener("pointerleave",()=>this._onUp()),this.refreshPermissionUI()}refreshPermissionUI(){const e=this.canDraw();this.canvas.style.pointerEvents=e?"auto":"none",this.note.textContent=e?"":"View-only — request draw access from the host"}_resize(){if(!this.canvas||!this.wrap)return;const e=this.wrap.getBoundingClientRect(),t=window.devicePixelRatio||1;this.canvas.width=Math.max(300,Math.floor(e.width*t)),this.canvas.height=Math.max(200,Math.floor(e.height*t)),this.ctx.setTransform(t,0,0,t,0,0),this._replay()}_pointerCoords(e){const t=this.canvas.getBoundingClientRect();return{x:(e.clientX-t.left)/t.width,y:(e.clientY-t.top)/t.height}}_drawSegment(e,t,n,i,r){const o=this.canvas.getBoundingClientRect().width,a=this.canvas.getBoundingClientRect().height;this.ctx.lineWidth=r,this.ctx.lineCap="round",this.ctx.lineJoin="round",this.ctx.globalCompositeOperation=n==="eraser"?"destination-out":"source-over",this.ctx.strokeStyle=n==="eraser"?"rgba(0,0,0,1)":i,this.ctx.beginPath(),this.ctx.moveTo(e.x*o,e.y*a),this.ctx.lineTo(t.x*o,t.y*a),this.ctx.stroke()}_onDown(e){if(!this.canDraw())return;e.preventDefault(),this.canvas.setPointerCapture(e.pointerId);const t=this._pointerCoords(e);this.currentStroke={tool:this.tool,color:this.color,size:this.size,points:[t]}}_onMove(e){if(!this.currentStroke)return;const t=this._pointerCoords(e),n=this.currentStroke.points[this.currentStroke.points.length-1];this._drawSegment(n,t,this.currentStroke.tool,this.currentStroke.color,this.currentStroke.size),this.currentStroke.points.push(t)}_onUp(){if(!this.currentStroke||this.currentStroke.points.length<2){this.currentStroke=null;return}const e=this.currentStroke;this.currentStroke=null,this.remoteStrokes.push(e),this.emit("whiteboard-draw",{drawing:e})}_clearLocal(){this.remoteStrokes=[],this.imageData=null,this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height)}_replay(){if(this.ctx){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.imageData&&this._drawBackground();for(const e of this.remoteStrokes){const t=e.points||[];for(let n=1;n<t.length;n++)this._drawSegment(t[n-1],t[n],e.tool,e.color,e.size)}}}_drawBackground(){if(!this.imageData)return;const e=new Image;e.onload=()=>{const t=this.canvas.getBoundingClientRect().width,n=this.canvas.getBoundingClientRect().height;this.ctx.globalCompositeOperation="source-over",this.ctx.drawImage(e,0,0,t,n)},e.src=this.imageData}handleDrawing(e){if(e.userId&&e.userId===this.userId||!e.drawing)return;this.remoteStrokes.push(e.drawing);const t=e.drawing.points||[];for(let n=1;n<t.length;n++)this._drawSegment(t[n-1],t[n],e.drawing.tool,e.drawing.color,e.drawing.size)}handleCleared(){this._clearLocal()}handleImageUploaded(e){this.imageData=e.imageData||null,this._replay()}handleStateSync(e){e&&(this.imageData=e.imageData||null,this.remoteStrokes=Array.isArray(e.drawings)?e.drawings.slice():[],this._replay(),this.refreshPermissionUI())}destroy(){window.removeEventListener("resize",this._resize),this._resizeObserver&&this._resizeObserver.disconnect()}}const Ys=new Set(["auto","manual","off"]),Gs=new Set(["local","composite"]),V="https://preproduction.tentoro.in/videocall";function Qs(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")try{return crypto.randomUUID()}catch{}return"u-"+Date.now().toString(36)+"-"+Math.random().toString(36).slice(2,12)}function Xs({workspace:s,ai:e}){const t={workspace:s};return e&&(e.whisperKey&&(t["x-whisper-key"]=e.whisperKey),e.whisperUrl&&(t["x-whisper-url"]=e.whisperUrl),e.llmKey&&(t["x-llm-key"]=e.llmKey),e.llmUrl&&(t["x-llm-url"]=e.llmUrl),e.llmModel&&(t["x-llm-model"]=e.llmModel)),t}async function ue(s,e,{workspace:t,ai:n,body:i}={}){const r=Xs({workspace:t,ai:n}),o={method:s,headers:r};i!==void 0&&(r["Content-Type"]="application/json",o.body=JSON.stringify(i));const a=await fetch(e,o),c=await a.json().catch(()=>({}));if(!a.ok){const h=new Error(c.error||`HTTP ${a.status}`);throw h.status=a.status,h.body=c,h}return c}function Zs(s){const e=new URL(s),t=e.protocol==="https:",n=e.pathname.replace(/\/+$/,"");return{host:e.hostname,port:e.port?parseInt(e.port,10):t?443:80,path:`${n}/peerjs`,secure:t}}class ${constructor(){this.config=null,this.peerManager=null,this.socketManager=null,this.mediaManager=null,this.uiManager=null,this.isInitialized=!1,this.currentRoom=null,this.currentUser=null}init(e){if(!e||!e.workspace||!e.roomId||!e.user)throw new Error("workspace, roomId, and user are required");const t=e.host||V,n=Ys.has(e.recording)?e.recording:"off",i=n!=="off"&&!!e.transcribe,r=i&&!!e.summarize,o=e.recordOnlyIfHost!==!1,a=Gs.has(e.recordingMode)?e.recordingMode:"local",c=Number.isFinite(e.compositeWidth)?e.compositeWidth:1280,h=Number.isFinite(e.compositeHeight)?e.compositeHeight:720,l=Number.isFinite(e.compositeFps)?e.compositeFps:30,d=Number.isFinite(e.recordingVideoBps)?e.recordingVideoBps:1e6,u=Number.isFinite(e.recordingAudioBps)?e.recordingAudioBps:64e3,f=["chat","code","whiteboard"],g=Array.isArray(e.panels)&&e.panels.length?e.panels.filter(_=>f.includes(_)):["chat"];g.includes("chat")||g.unshift("chat"),this.config={...e,host:t,apiUrl:e.apiUrl||`${t}/api`,socketUrl:e.socketUrl||t,peerServer:e.peerServer||Zs(t),ai:{...e.ai||{}},recording:n,transcribe:i,summarize:r,recordOnlyIfHost:o,recordingMode:a,compositeWidth:c,compositeHeight:h,compositeFps:l,recordingVideoBps:d,recordingAudioBps:u,panels:g},this.myRole=null,this.roleResolvers=[],this.currentRoom=this.config.roomId,this.currentUser=this.config.user,this.peerManager=new Vn(this.config),this.socketManager=new zs(this.config),this.mediaManager=new Ns,this.uiManager=new Ks({recording:n,screenShare:e.screenShare!==!1,panels:g}),this.recorder=n==="off"?null:new je,this.compositor=null,this.setupEventHandlers(),this.isInitialized=!0,console.log("MeetSDK initialized")}setupEventHandlers(){this.peerManager.on("stream",(e,t,n)=>{const i=this.labelForPeer(e,n);this.mediaManager.addRemoteStream(e,t),this.uiManager.addVideoStream(e,t,n,i),this.compositor&&this.compositor.addStream(e,t,{isLocal:n,label:i}),this.refreshParticipantsPanel()}),this.peerManager.on("peerLeft",e=>{this.mediaManager.removeRemoteStream(e),this.uiManager.removeVideoStream(e),this.compositor&&this.compositor.removeStream(e),this.refreshParticipantsPanel()}),this.peerManager.on("screenShareEnded",()=>{this.uiManager.setScreenSharingState(!1),this.socketManager.emitMediaState(this.currentRoom,this.currentUser.id,"screen",!1),this.uiManager.setPresentingPeer&&this.uiManager.setPresentingPeer(null),this.presentingPeerId=null,this.refreshParticipantsPanel()}),this.socketManager.on("message",e=>{this.uiManager.addChatMessage(e)}),this.peerLabels=new Map,this.socketManager.on("existingPeers",e=>{e.forEach(t=>{this.peerLabels.set(t.peerId,t.userName||t.userId),this.peerManager.callPeer(t.peerId)}),this.refreshParticipantsPanel()}),this.socketManager.on("userJoined",e=>{this.peerLabels.set(e.peerId,e.userName||e.userId),this.uiManager.updateVideoStreamLabel(e.peerId,e.userName||e.userId),this.peerManager.callPeer(e.peerId),this.refreshParticipantsPanel()}),this.socketManager.on("userLeft",e=>{const t=e.peerId||e.userId;this.mediaManager.removeRemoteStream(t),this.uiManager.removeVideoStream(t),this.compositor&&t&&this.compositor.removeStream(t),e.peerId&&this.peerLabels.delete(e.peerId),this.refreshParticipantsPanel()}),this.socketManager.on("peerMediaStateChange",e=>{if(!e||!e.userId||e.type!=="screen")return;let t=null;for(const[n]of this.peerLabels.entries())if(n.endsWith(`-${e.userId}`)){t=n;break}t&&(e.enabled?this.setPresentingPeer(t):this.presentingPeerId===t&&this.setPresentingPeer(null))}),this.socketManager.on("youJoined",e=>{if(this.myRole=e&&e.role?e.role:"candidate",console.log(`MeetSDK: joined as ${this.myRole}`+(e&&e.hostId?` (host is ${e.hostName||e.hostId})`:"")),e&&e.hostId){for(const[n]of this.peerLabels.entries())if(n.endsWith(`-${e.hostId}`)){this.hostPeerId=n;break}}const t=this.roleResolvers;this.roleResolvers=[];for(const n of t)n(this.myRole);this.refreshParticipantsPanel(),this.maybeAttachRecordingForHost(),this.codeSandbox&&this.codeSandbox.refreshPermissionUI(),this.whiteboard&&this.whiteboard.refreshPermissionUI()})}async hydrateIceServers(){try{const e=await fetch(`${this.config.apiUrl}/rt-config`,{headers:this.buildHeaders()});if(!e.ok)return;const t=await e.json();if(!t||!Array.isArray(t.iceServers)||t.iceServers.length===0)return;const n=Array.isArray(this.config.iceServers)?this.config.iceServers:[];this.config.iceServers=[...n,...t.iceServers]}catch(e){console.warn("rt-config fetch failed, using STUN defaults:",e&&e.message)}}labelForPeer(e,t){return t?this.currentUser&&this.currentUser.name?this.currentUser.name:"You":this.peerLabels&&this.peerLabels.has(e)?this.peerLabels.get(e):e}setPresentingPeer(e){this.presentingPeerId=e||null,this.uiManager&&this.uiManager.setPresentingPeer&&this.uiManager.setPresentingPeer(this.presentingPeerId),this.refreshParticipantsPanel()}refreshParticipantsPanel(){if(!this.uiManager)return;const e=[];if(this.currentUser&&e.push({label:this.currentUser.name||"You",userId:this.currentUser.id,isYou:!0,isHost:this.myRole==="organizer",isSharing:this.peerManager&&this.peerManager.isScreenSharing&&this.peerManager.isScreenSharing()}),this.peerLabels){const t=`${this.config.workspace}-${this.currentRoom}-`;for(const[n,i]of this.peerLabels.entries()){const r=n.startsWith(t)?n.slice(t.length):n;e.push({label:i,userId:r,isYou:!1,isHost:this.hostPeerId===n,isSharing:this.presentingPeerId===n,canEditCode:this.codePermsByUser?!!this.codePermsByUser.get(r):!1,canDrawBoard:this.boardPermsByUser?!!this.boardPermsByUser.get(r):!1})}}this.uiManager.setParticipants(e,{showControls:this.myRole==="organizer"})}waitForRole(e=3e3){return this.myRole?Promise.resolve(this.myRole):new Promise(t=>{const n=setTimeout(()=>t(this.myRole||"candidate"),e);this.roleResolvers.push(i=>{clearTimeout(n),t(i)})})}async mount(e){if(!this.isInitialized)throw new Error("SDK not initialized. Call init() first.");this.uiManager.mount(e),await this.hydrateIceServers();const t=`${this.config.workspace}-${this.currentRoom}-${this.currentUser.id}`;await this.peerManager.initialize(t);const n=await this.peerManager.getLocalStream();if(this.uiManager.addVideoStream("local",n,!0),this.config.recordingMode==="composite"&&this.recorder)try{this.compositor=new He({width:this.config.compositeWidth,height:this.config.compositeHeight,fps:this.config.compositeFps}),await this.compositor.start(),this.compositor.addStream("local",n,{isLocal:!0,label:this.labelForPeer("local",!0)})}catch(i){console.warn("Composite recording unavailable, falling back to local:",i.message),this.compositor=null}this.socketManager.connect(this.config.workspace),setTimeout(()=>{this.socketManager.joinRoom(this.currentRoom,this.currentUser.id,this.currentUser.name,t)},500),this.setupUIControls(),this.setupRecording(n).catch(i=>console.error("setupRecording failed:",i)),this.setupCollabPanels(),this.fetchChatHistory().then(i=>{i&&i.messages&&this.uiManager.setChatHistory(i.messages)}).catch(i=>console.warn("Chat history fetch failed:",i&&i.message)),console.log("MeetSDK mounted")}setupCollabPanels(){if(this.uiManager&&!this.uiManager._panelWired&&(this.uiManager.wirePanelTabs(),this.uiManager._panelWired=!0),this.codePermsByUser=this.codePermsByUser||new Map,this.boardPermsByUser=this.boardPermsByUser||new Map,this.uiManager&&this.uiManager.onParticipantPermToggle&&this.uiManager.onParticipantPermToggle((e,t)=>{if(!(this.myRole!=="organizer"||!e||!e.userId)){if(t==="code"){const n=!this.codePermsByUser.get(e.userId);this.grantCodeEdit(e.userId,e.label,n)}else if(t==="board"){const n=!this.boardPermsByUser.get(e.userId);this.grantWhiteboardDraw(e.userId,e.label,n)}}}),this.config.panels.includes("code")){const e=this.uiManager.getPanelSlot("code");e&&(this.codeSandbox=new Js({container:e,userId:this.currentUser.id,canEdit:()=>this._canEditCode(),canRun:()=>this._canEditCode(),emit:(t,n)=>{this.socketManager.emit(t,{roomId:this.currentRoom,userId:this.currentUser.id,userName:this.currentUser.name,...n})}}),this.socketManager.onRaw("code-changed",t=>this.codeSandbox.handleCodeChanged(t)),this.socketManager.onRaw("code-language-changed",t=>this.codeSandbox.handleLanguageChanged(t)),this.socketManager.onRaw("code-executing",t=>this.codeSandbox.handleExecuting(t)),this.socketManager.onRaw("code-execution-result",t=>this.codeSandbox.handleExecutionResult(t)),this.socketManager.onRaw("code-state-sync",t=>{if(t&&Array.isArray(t.editPermissions)){const n=t.editPermissions.find(i=>i.userId===this.currentUser.id);this._codeEditPermission=!!(n&&n.canEdit);for(const i of t.editPermissions)this.codePermsByUser.set(i.userId,!!i.canEdit)}this.codeSandbox.handleStateSync(t),this.refreshParticipantsPanel()}),this.socketManager.onRaw("code-permission-changed",t=>{if(t&&t.targetUserId===this.currentUser.id&&(this._codeEditPermission=!!t.canEdit),t&&t.targetUserId&&this.codePermsByUser.set(t.targetUserId,!!t.canEdit),Array.isArray(t&&t.editPermissions)){const n=t.editPermissions.find(i=>i.userId===this.currentUser.id);n&&(this._codeEditPermission=!!n.canEdit);for(const i of t.editPermissions)this.codePermsByUser.set(i.userId,!!i.canEdit)}this.codeSandbox.refreshPermissionUI(),this.refreshParticipantsPanel()}),this.socketManager.emit("code-state-request",{roomId:this.currentRoom}))}if(this.config.panels.includes("whiteboard")){const e=this.uiManager.getPanelSlot("whiteboard");e&&(this.whiteboard=new Ws({container:e,userId:this.currentUser.id,canDraw:()=>this._canDrawWhiteboard(),emit:(t,n)=>{this.socketManager.emit(t,{roomId:this.currentRoom,userId:this.currentUser.id,userName:this.currentUser.name,...n})}}),this.socketManager.onRaw("whiteboard-drawing",t=>this.whiteboard.handleDrawing(t)),this.socketManager.onRaw("whiteboard-cleared",()=>this.whiteboard.handleCleared()),this.socketManager.onRaw("whiteboard-image-uploaded",t=>this.whiteboard.handleImageUploaded(t)),this.socketManager.onRaw("whiteboard-state-sync",t=>{if(t&&Array.isArray(t.drawPermissions)){const n=t.drawPermissions.find(i=>i.userId===this.currentUser.id);this._whiteboardDrawPermission=!!(n&&n.canDraw);for(const i of t.drawPermissions)this.boardPermsByUser.set(i.userId,!!i.canDraw)}this.whiteboard.handleStateSync(t),this.refreshParticipantsPanel()}),this.socketManager.onRaw("whiteboard-permission-changed",t=>{if(t&&t.targetUserId===this.currentUser.id&&(this._whiteboardDrawPermission=!!t.canDraw),t&&t.targetUserId&&this.boardPermsByUser.set(t.targetUserId,!!t.canDraw),Array.isArray(t&&t.drawPermissions)){const n=t.drawPermissions.find(i=>i.userId===this.currentUser.id);n&&(this._whiteboardDrawPermission=!!n.canDraw);for(const i of t.drawPermissions)this.boardPermsByUser.set(i.userId,!!i.canDraw)}this.whiteboard.refreshPermissionUI(),this.refreshParticipantsPanel()}),this.socketManager.emit("whiteboard-state-request",{roomId:this.currentRoom}))}}_canEditCode(){return this.myRole==="organizer"?!0:!!this._codeEditPermission}_canDrawWhiteboard(){return this.myRole==="organizer"?!0:!!this._whiteboardDrawPermission}async fetchChatHistory(e={}){if(!this.isInitialized)throw new Error("SDK not initialized");const t=new URLSearchParams;e.limit&&t.set("limit",String(e.limit)),e.before&&t.set("before",e.before),e.after&&t.set("after",e.after);const n=t.toString(),i=await fetch(`${this.config.apiUrl}/rooms/${encodeURIComponent(this.currentRoom)}/chat/messages${n?"?"+n:""}`,{headers:this.buildHeaders()});if(!i.ok)throw new Error(`chat/messages: HTTP ${i.status}`);return i.json()}async uploadChatAttachment(e){if(!this.isInitialized)throw new Error("SDK not initialized");const t=new FormData;t.append("file",e,e.name),t.append("userId",this.currentUser.id),t.append("userName",this.currentUser.name);const n=await fetch(`${this.config.apiUrl}/rooms/${encodeURIComponent(this.currentRoom)}/chat/attachments`,{method:"POST",headers:this.buildHeaders(),body:t});if(!n.ok){const i=await n.json().catch(()=>({}));throw new Error(i.error||`Upload failed: HTTP ${n.status}`)}return n.json()}async setupRecording(e){if(this.recorder){if(this.recorder.on("stateChange",t=>{this.uiManager.updateRecordingIndicator(t),this.uiManager.setPauseButtonVisible(t==="recording"||t==="paused"),this.uiManager.setPauseButtonState(t==="paused")}),this.uiManager.onControlClick("toggle-pause",()=>{this.recorder.isPaused()?this.recorder.resume():this.recorder.pause()}),this.config.recordOnlyIfHost&&await this.waitForRole()!=="organizer"){this.uiManager.setRecordAllowed&&this.uiManager.setRecordAllowed(!1,"Only the meeting host can record"),this._pendingRecordAttach=this.config.recording==="manual",console.log("MeetSDK: not the host — recording controls disabled until host role arrives");return}this.enableAndAttachRecording()}}maybeAttachRecordingForHost(){this.myRole==="organizer"&&this._pendingRecordAttach&&(this._pendingRecordAttach=!1,this.uiManager&&this.uiManager.setRecordAllowed&&this.uiManager.setRecordAllowed(!0),this.attachRecordToggle())}enableAndAttachRecording(){this.uiManager&&this.uiManager.setRecordAllowed&&this.uiManager.setRecordAllowed(!0),this.config.recording==="auto"&&this.startRecording().catch(e=>console.error("Auto-record failed:",e)),this.config.recording==="manual"&&this.attachRecordToggle()}attachRecordToggle(){this._recordToggleAttached||(this._recordToggleAttached=!0,this._pendingRecordAttach=!1,this.uiManager.onControlClick("toggle-record",async()=>{try{this.recorder.isRecording()?await this.stopRecording():await this.startRecording()}catch(e){console.error("MeetSDK: record toggle failed:",e);const t=e&&e.message||String(e);this.uiManager&&typeof this.uiManager.setStatus=="function"&&this.uiManager.setStatus(t)}}))}async startRecording(){if(!this.recorder)throw new Error("recording is disabled in SDK config");let e;if(this.config.recordingMode==="composite"&&this.compositor){if(e=this.compositor.getStream(),!e)throw new Error("composite stream not ready")}else if(e=this.peerManager.localStream,!e)throw new Error("local stream not ready");const t=this.readStoredSession();let n=null,i=0;if(t){const r=await this.probeSessionStatus(t.sessionId).catch(()=>null);r&&r.active?(n={sessionId:t.sessionId},i=(r.lastSeq||-1)+1,console.log(`MeetSDK: resuming recording session ${t.sessionId} at seq=${i}`)):this.clearStoredSession()}n||(n=await this.startRecordingSession(),this.persistStoredSession(n)),this.recordingSession=n,this.chunkQueue=[],this.chunkDrainerRunning=!1,this.recorder.start(e,{timesliceMs:15e3,startSeq:i,videoBitsPerSecond:this.config.recordingVideoBps,audioBitsPerSecond:this.config.recordingAudioBps,onChunk:(r,o)=>(this.enqueueChunk(n.sessionId,r,o),Promise.resolve())})}storedSessionKey(){return`meetSdk.session.${this.config.workspace}.${this.currentRoom}`}readStoredSession(){try{const e=window.localStorage.getItem(this.storedSessionKey());if(!e)return null;const t=JSON.parse(e);return Date.now()-(t.at||0)>24*60*60*1e3?null:t}catch{return null}}persistStoredSession(e){try{window.localStorage.setItem(this.storedSessionKey(),JSON.stringify({sessionId:e.sessionId,at:Date.now()}))}catch{}}clearStoredSession(){try{window.localStorage.removeItem(this.storedSessionKey())}catch{}}async probeSessionStatus(e){const t=await fetch(`${this.config.apiUrl}/rooms/${encodeURIComponent(this.currentRoom)}/recordings/session/${encodeURIComponent(e)}/status`,{headers:this.buildHeaders()});return t.ok?t.json():null}enqueueChunk(e,t,n){this.chunkQueue=this.chunkQueue||[],this.chunkQueue.push({sessionId:e,blob:t,seq:n}),this.uiManager&&this.uiManager.setQueueCount&&this.uiManager.setQueueCount(this.chunkQueue.length),this.runChunkDrainer().catch(i=>console.warn("Chunk drainer error:",i&&i.message))}async runChunkDrainer(){if(!this.chunkDrainerRunning){this.chunkDrainerRunning=!0;try{for(;this.chunkQueue&&this.chunkQueue.length>0;){const e=this.chunkQueue[0];try{await this.uploadRecordingChunk(e.sessionId,e.blob,e.seq),this.chunkQueue.shift(),this.uiManager&&this.uiManager.setQueueCount&&this.uiManager.setQueueCount(this.chunkQueue.length)}catch(t){if(/HTTP 404|HTTP 409/.test(String(t&&t.message))){console.warn(`Dropping chunk seq=${e.seq}: ${t.message}`),this.chunkQueue.shift(),this.uiManager&&this.uiManager.setQueueCount&&this.uiManager.setQueueCount(this.chunkQueue.length);continue}const n=Math.min(3e4,1e3*Math.pow(2,this._chunkFailStreak||0));this._chunkFailStreak=(this._chunkFailStreak||0)+1,console.warn(`Chunk seq=${e.seq} failed, retrying in ${n}ms`),await new Promise(i=>setTimeout(i,n))}}this._chunkFailStreak=0}finally{this.chunkDrainerRunning=!1}}}async waitForChunkQueueEmpty(){for(;this.chunkQueue&&this.chunkQueue.length>0||this.chunkDrainerRunning;)await new Promise(e=>setTimeout(e,200))}async stopRecording(){if(!this.recorder)return null;const e=await this.recorder.stop();if(!e||!this.recordingSession)return null;const t=this.recordingSession.sessionId;this.recordingSession=null,await this.waitForChunkQueueEmpty();try{return await this.finalizeRecordingSession(t,e)}catch(n){throw console.error("Recording finalize failed:",n),n}}async startRecordingSession(){const e={recordedBy:this.currentUser.id,contentType:this.recorder.mimeType||"video/webm",transcribe:this.config.transcribe,summarize:this.config.summarize},t=await fetch(`${this.config.apiUrl}/rooms/${encodeURIComponent(this.currentRoom)}/recordings/session/start`,{method:"POST",headers:{...this.buildHeaders(),"Content-Type":"application/json"},body:JSON.stringify(e)});if(!t.ok)throw new Error(`session/start failed: HTTP ${t.status}`);return t.json()}async uploadRecordingChunk(e,t,n){const i=new FormData;i.append("chunk",t,`chunk-${n}.webm`);const r=await fetch(`${this.config.apiUrl}/rooms/${encodeURIComponent(this.currentRoom)}/recordings/session/${encodeURIComponent(e)}/chunk?seq=${n}`,{method:"POST",headers:this.buildHeaders(),body:i});if(!r.ok)throw new Error(`chunk seq=${n}: HTTP ${r.status}`)}async finalizeRecordingSession(e,t){const n=Math.max(0,Math.round((t.endedAt-t.startedAt)/1e3)),i=await fetch(`${this.config.apiUrl}/rooms/${encodeURIComponent(this.currentRoom)}/recordings/session/${encodeURIComponent(e)}/finalize`,{method:"POST",headers:{...this.buildHeaders(),"Content-Type":"application/json"},body:JSON.stringify({durationSec:n,startedAt:t.startedAt.toISOString(),endedAt:t.endedAt.toISOString()})});if(!i.ok)throw new Error(`session/finalize failed: HTTP ${i.status}`);const r=await i.json();return this.clearStoredSession(),r}async listRecordings(){if(!this.isInitialized)throw new Error("SDK not initialized");return(await fetch(`${this.config.apiUrl}/rooms/${encodeURIComponent(this.currentRoom)}/recordings`,{headers:this.buildHeaders()})).json()}async getRecording(e){if(!this.isInitialized)throw new Error("SDK not initialized");return(await fetch(`${this.config.apiUrl}/rooms/${encodeURIComponent(this.currentRoom)}/recordings/${encodeURIComponent(e)}`,{headers:this.buildHeaders()})).json()}setupUIControls(){let e=!0,t=!0;this.uiManager.onControlClick("toggle-video",()=>{e=this.peerManager.toggleVideo(),this.uiManager.updateButtonState("toggle-video",e?"Video On":"Video Off")}),this.uiManager.onControlClick("toggle-audio",()=>{t=this.peerManager.toggleAudio(),this.uiManager.updateButtonState("toggle-audio",t?"Mic On":"Mic Off")}),this.uiManager.onControlClick("leave-meeting",()=>{this.leave()}),this.uiManager.onControlClick("toggle-screenshare",async()=>{try{if(this.peerManager.isScreenSharing())await this.peerManager.stopScreenShare(),this.uiManager.setScreenSharingState(!1),this.socketManager.emitMediaState(this.currentRoom,this.currentUser.id,"screen",!1),this.setPresentingPeer(null);else{await this.peerManager.startScreenShare(),this.uiManager.setScreenSharingState(!0),this.socketManager.emitMediaState(this.currentRoom,this.currentUser.id,"screen",!0);const n=`${this.config.workspace}-${this.currentRoom}-${this.currentUser.id}`;this.setPresentingPeer(n)}}catch(n){console.warn("Screen share toggle failed:",n&&n.message)}}),this.uiManager.onChatSend((n,i)=>{this.socketManager.sendMessage(this.currentRoom,this.currentUser.id,this.currentUser.name,n,i)}),this.uiManager.onAttachFile(async n=>this.uploadChatAttachment(n))}buildHeaders(e={}){const t=this.config.ai||{},n={workspace:this.config.workspace,...e};return t.whisperKey&&(n["x-whisper-key"]=t.whisperKey),t.whisperUrl&&(n["x-whisper-url"]=t.whisperUrl),t.llmKey&&(n["x-llm-key"]=t.llmKey),t.llmUrl&&(n["x-llm-url"]=t.llmUrl),t.llmModel&&(n["x-llm-model"]=t.llmModel),n}setAiConfig(e={}){if(!this.config)throw new Error("SDK not initialized");this.config.ai={...this.config.ai||{},...e}}async getSummary(){if(!this.isInitialized)throw new Error("SDK not initialized");return(await fetch(`${this.config.apiUrl}/rooms/${this.currentRoom}/summary`,{headers:this.buildHeaders()})).json()}async generateSummary(){if(!this.isInitialized)throw new Error("SDK not initialized");return(await fetch(`${this.config.apiUrl}/rooms/${this.currentRoom}/summary/generate`,{method:"POST",headers:this.buildHeaders()})).json()}async transcribeAudio(e,t="audio.webm"){if(!this.isInitialized)throw new Error("SDK not initialized");const n=new FormData;return n.append("audio",e,t),(await fetch(`${this.config.apiUrl}/rooms/${this.currentRoom}/transcribe`,{method:"POST",headers:this.buildHeaders(),body:n})).json()}grantCodeEdit(e,t,n=!0){this.socketManager.emit("code-permission-change",{roomId:this.currentRoom,userId:this.currentUser.id,targetUserId:e,targetUserName:t||e,canEdit:!!n})}grantWhiteboardDraw(e,t,n=!0){this.socketManager.emit("whiteboard-permission-change",{roomId:this.currentRoom,userId:this.currentUser.id,targetUserId:e,targetUserName:t||e,canDraw:!!n})}static async createMeeting(e={}){const{workspace:t,host:n,ai:i,title:r,hostUserId:o,hostName:a,hostId:c,scheduledFor:h,users:l}=e;if(!t)throw new Error("workspace is required");const d=n||V,u={};return r!==void 0&&(u.title=r),o!==void 0&&(u.hostUserId=o),a!==void 0&&(u.hostName=a),c!==void 0&&(u.hostId=c),h!==void 0&&(u.scheduledFor=h),l!==void 0&&(u.users=l),ue("POST",`${d}/api/meetings/schedule`,{workspace:t,ai:i,body:u})}static async updateMeeting(e={}){const{workspace:t,roomId:n,host:i,ai:r,title:o,hostUserId:a,hostName:c,users:h,scheduledFor:l}=e;if(!t)throw new Error("workspace is required");if(!n)throw new Error("roomId is required");const d=i||V,u={};return o!==void 0&&(u.title=o),a!==void 0&&(u.hostUserId=a),c!==void 0&&(u.hostName=c),h!==void 0&&(u.users=h),l!==void 0&&(u.scheduledFor=l),ue("PATCH",`${d}/api/meetings/${encodeURIComponent(n)}`,{workspace:t,ai:r,body:u})}static async cancelMeeting(e={}){const{workspace:t,roomId:n,host:i,ai:r}=e;if(!t)throw new Error("workspace is required");if(!n)throw new Error("roomId is required");return ue("DELETE",`${i||V}/api/meetings/${encodeURIComponent(n)}`,{workspace:t,ai:r})}static async listMeetings(e={}){const{workspace:t,host:n,ai:i,status:r,upcoming:o}=e;if(!t)throw new Error("workspace is required");const a=n||V,c=new URLSearchParams;r&&c.set("status",r),o&&c.set("upcoming","true");const h=c.toString();return ue("GET",`${a}/api/meetings${h?"?"+h:""}`,{workspace:t,ai:i})}static async quickJoin(e={}){const{workspace:t,roomId:n,userName:i,container:r}=e;if(!t||!n||!i||!r)throw new Error("workspace, roomId, userName, and container are required");const o=e.userId||Qs(),{userId:a,userName:c,container:h,...l}=e,d=new $;return d.init({...l,workspace:t,roomId:n,user:{id:o,name:i}}),await d.mount(r),d}async leave(){if(!(this._leaving||this._left)){if(this._leaving=!0,this.recorder&&this.recorder.isRecording())try{this.uiManager.setUploadingIndicator(!0),await this.stopRecording()}catch(e){console.warn("Recording upload on leave failed:",e)}finally{try{this.uiManager.setUploadingIndicator(!1)}catch{}}try{this.socketManager.leaveRoom()}catch{}try{this.socketManager.disconnect()}catch{}try{this.peerManager.disconnect()}catch{}try{this.mediaManager.cleanup()}catch{}try{this.uiManager.destroy()}catch{}if(this.compositor){try{this.compositor.stop()}catch{}this.compositor=null}if(this.isInitialized=!1,this._left=!0,this._leaving=!1,console.log("Left meeting"),this.config&&typeof this.config.onLeave=="function")try{await this.config.onLeave(this)}catch(e){console.warn("onLeave threw:",e)}}}}if(typeof window<"u"){const s=new $;["createMeeting","updateMeeting","cancelMeeting","listMeetings","quickJoin"].forEach(e=>{s[e]=$[e].bind($)}),window.MeetSDK=s,window.MeetSDKClass=$}k.default=$,Object.defineProperties(k,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nainudhin/video-meeting-sdk",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.1",
|
|
4
4
|
"description": "Embeddable multi-tenant video meeting SDK (PeerJS + Socket.IO)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/meet-sdk.umd.js",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"scripts": {
|
|
35
35
|
"build": "vite build && cp types/meet-sdk.d.ts dist/meet-sdk.d.ts",
|
|
36
36
|
"dev": "vite build --watch",
|
|
37
|
+
"test": "node --test src/ui/embed.recordAllowed.test.js src/setupRecording.test.js",
|
|
37
38
|
"prepublishOnly": "npm run build"
|
|
38
39
|
},
|
|
39
40
|
"dependencies": {
|