@nainudhin/video-meeting-sdk 1.8.1 → 1.8.3
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 +47 -39
- package/dist/meet-sdk.umd.js +2 -2
- package/package.json +1 -1
package/dist/meet-sdk.mjs
CHANGED
|
@@ -958,7 +958,7 @@ function xt(r, e) {
|
|
|
958
958
|
}
|
|
959
959
|
}
|
|
960
960
|
}
|
|
961
|
-
function
|
|
961
|
+
function Pn(r, e) {
|
|
962
962
|
r.navigator.mediaDevices && (r.navigator.mediaDevices && "getDisplayMedia" in r.navigator.mediaDevices || (r.navigator.mediaDevices.getDisplayMedia = function(n) {
|
|
963
963
|
if (!(n && n.video)) {
|
|
964
964
|
const s = new DOMException("getDisplayMedia without video constraints is undefined");
|
|
@@ -1013,7 +1013,7 @@ function Rt(r, e) {
|
|
|
1013
1013
|
}).then(o, a);
|
|
1014
1014
|
};
|
|
1015
1015
|
}
|
|
1016
|
-
function
|
|
1016
|
+
function Pt(r) {
|
|
1017
1017
|
if (!(typeof r == "object" && r.RTCPeerConnection && r.RTCRtpSender) || r.RTCRtpSender && "getStats" in r.RTCRtpSender.prototype)
|
|
1018
1018
|
return;
|
|
1019
1019
|
const e = r.RTCPeerConnection.prototype.getSenders;
|
|
@@ -1029,7 +1029,7 @@ function Et(r) {
|
|
|
1029
1029
|
return this.track ? this._pc.getStats(this.track) : Promise.resolve(/* @__PURE__ */ new Map());
|
|
1030
1030
|
};
|
|
1031
1031
|
}
|
|
1032
|
-
function
|
|
1032
|
+
function Et(r) {
|
|
1033
1033
|
if (!(typeof r == "object" && r.RTCPeerConnection && r.RTCRtpSender) || r.RTCRtpSender && "getStats" in r.RTCRtpReceiver.prototype)
|
|
1034
1034
|
return;
|
|
1035
1035
|
const e = r.RTCPeerConnection.prototype.getReceivers;
|
|
@@ -1116,16 +1116,16 @@ const tt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
|
1116
1116
|
shimAddTransceiver: At,
|
|
1117
1117
|
shimCreateAnswer: Dt,
|
|
1118
1118
|
shimCreateOffer: It,
|
|
1119
|
-
shimGetDisplayMedia:
|
|
1119
|
+
shimGetDisplayMedia: Pn,
|
|
1120
1120
|
shimGetParameters: Ot,
|
|
1121
1121
|
shimGetStats: Rt,
|
|
1122
1122
|
shimGetUserMedia: xt,
|
|
1123
1123
|
shimOnTrack: Tt,
|
|
1124
1124
|
shimPeerConnection: me,
|
|
1125
1125
|
shimRTCDataChannel: Mt,
|
|
1126
|
-
shimReceiverGetStats:
|
|
1126
|
+
shimReceiverGetStats: Et,
|
|
1127
1127
|
shimRemoveStream: wt,
|
|
1128
|
-
shimSenderGetStats:
|
|
1128
|
+
shimSenderGetStats: Pt
|
|
1129
1129
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1130
1130
|
function Lt(r) {
|
|
1131
1131
|
if (!(typeof r != "object" || !r.RTCPeerConnection)) {
|
|
@@ -1292,7 +1292,7 @@ const nt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
|
1292
1292
|
shimRemoteStreamsAPI: $t,
|
|
1293
1293
|
shimTrackEventTransceiver: Ft
|
|
1294
1294
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1295
|
-
function
|
|
1295
|
+
function En(r) {
|
|
1296
1296
|
return r && r.__esModule && Object.prototype.hasOwnProperty.call(r, "default") ? r.default : r;
|
|
1297
1297
|
}
|
|
1298
1298
|
var Vt = { exports: {} };
|
|
@@ -1684,7 +1684,7 @@ t=0 0\r
|
|
|
1684
1684
|
}, r.exports = e;
|
|
1685
1685
|
})(Vt);
|
|
1686
1686
|
var Ht = Vt.exports;
|
|
1687
|
-
const L = /* @__PURE__ */
|
|
1687
|
+
const L = /* @__PURE__ */ En(Ht), wn = /* @__PURE__ */ _n({
|
|
1688
1688
|
__proto__: null,
|
|
1689
1689
|
default: L
|
|
1690
1690
|
}, [Ht]);
|
|
@@ -1936,7 +1936,7 @@ function An({ window: r } = {}, e = {
|
|
|
1936
1936
|
case "firefox":
|
|
1937
1937
|
if (!tt || !me || !e.shimFirefox)
|
|
1938
1938
|
return t("Firefox shim is not included in this adapter release."), s;
|
|
1939
|
-
t("adapter.js shimming firefox."), s.browserShim = tt, G(r, n), Q(r), xt(r, n), me(r, n), Rt(r, n), Tt(r), wt(r),
|
|
1939
|
+
t("adapter.js shimming firefox."), s.browserShim = tt, G(r, n), Q(r), xt(r, n), me(r, n), Rt(r, n), Tt(r), wt(r), Pt(r), Et(r), Mt(r), At(r, n), Ot(r, n), It(r, n), Dt(r, n), J(r), be(r), W(r, n), Y(r, n);
|
|
1940
1940
|
break;
|
|
1941
1941
|
case "safari":
|
|
1942
1942
|
if (!nt || !e.shimSafari)
|
|
@@ -2263,7 +2263,7 @@ I(D, "PeerErrorType", () => y);
|
|
|
2263
2263
|
I(D, "BaseConnectionErrorType", () => ve);
|
|
2264
2264
|
I(D, "DataConnectionErrorType", () => Le);
|
|
2265
2265
|
I(D, "SerializationType", () => ie);
|
|
2266
|
-
I(D, "SocketEventType", () =>
|
|
2266
|
+
I(D, "SocketEventType", () => E);
|
|
2267
2267
|
I(D, "ServerMessageType", () => v);
|
|
2268
2268
|
var w = /* @__PURE__ */ function(r) {
|
|
2269
2269
|
return r.Data = "data", r.Media = "media", r;
|
|
@@ -2275,7 +2275,7 @@ var w = /* @__PURE__ */ function(r) {
|
|
|
2275
2275
|
return r.NotOpenYet = "not-open-yet", r.MessageToBig = "message-too-big", r;
|
|
2276
2276
|
}({}), ie = /* @__PURE__ */ function(r) {
|
|
2277
2277
|
return r.Binary = "binary", r.BinaryUTF8 = "binary-utf8", r.JSON = "json", r.None = "raw", r;
|
|
2278
|
-
}({}),
|
|
2278
|
+
}({}), E = /* @__PURE__ */ function(r) {
|
|
2279
2279
|
return r.Message = "message", r.Disconnected = "disconnected", r.Error = "error", r.Close = "close", r;
|
|
2280
2280
|
}({}), v = /* @__PURE__ */ function(r) {
|
|
2281
2281
|
return r.Heartbeat = "HEARTBEAT", r.Candidate = "CANDIDATE", r.Offer = "OFFER", r.Answer = "ANSWER", r.Open = "OPEN", r.Error = "ERROR", r.IdTaken = "ID-TAKEN", r.InvalidKey = "INVALID-KEY", r.Leave = "LEAVE", r.Expire = "EXPIRE", r;
|
|
@@ -2298,9 +2298,9 @@ class Nn extends De.EventEmitter {
|
|
|
2298
2298
|
f.log("Invalid server message", s.data);
|
|
2299
2299
|
return;
|
|
2300
2300
|
}
|
|
2301
|
-
this.emit(
|
|
2301
|
+
this.emit(E.Message, i);
|
|
2302
2302
|
}, this._socket.onclose = (s) => {
|
|
2303
|
-
this._disconnected || (f.log("Socket closed.", s), this._cleanup(), this._disconnected = !0, this.emit(
|
|
2303
|
+
this._disconnected || (f.log("Socket closed.", s), this._cleanup(), this._disconnected = !0, this.emit(E.Disconnected));
|
|
2304
2304
|
}, this._socket.onopen = () => {
|
|
2305
2305
|
this._disconnected || (this._sendQueuedMessages(), f.log("Socket open"), this._scheduleHeartbeat());
|
|
2306
2306
|
});
|
|
@@ -2340,7 +2340,7 @@ class Nn extends De.EventEmitter {
|
|
|
2340
2340
|
return;
|
|
2341
2341
|
}
|
|
2342
2342
|
if (!e.type) {
|
|
2343
|
-
this.emit(
|
|
2343
|
+
this.emit(E.Error, "Invalid message");
|
|
2344
2344
|
return;
|
|
2345
2345
|
}
|
|
2346
2346
|
if (!this._wsOpen()) return;
|
|
@@ -2545,7 +2545,7 @@ class Xt extends Qt {
|
|
|
2545
2545
|
super(), this.peer = e, this.provider = t, this.options = n, this._open = !1, this.metadata = n.metadata;
|
|
2546
2546
|
}
|
|
2547
2547
|
}
|
|
2548
|
-
var
|
|
2548
|
+
var Ee;
|
|
2549
2549
|
const j = class j extends Xt {
|
|
2550
2550
|
/**
|
|
2551
2551
|
* For media connections, this is always 'media'.
|
|
@@ -2626,7 +2626,7 @@ const j = class j extends Xt {
|
|
|
2626
2626
|
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"));
|
|
2627
2627
|
}
|
|
2628
2628
|
};
|
|
2629
|
-
|
|
2629
|
+
Ee = new WeakMap(), B(j, Ee, j.ID_PREFIX = "mc_");
|
|
2630
2630
|
let re = j;
|
|
2631
2631
|
class Fn {
|
|
2632
2632
|
constructor(e) {
|
|
@@ -2944,13 +2944,13 @@ const q = class q extends Qt {
|
|
|
2944
2944
|
}
|
|
2945
2945
|
_createServerConnection() {
|
|
2946
2946
|
const e = new Nn(this._options.secure, this._options.host, this._options.port, this._options.path, this._options.key, this._options.pingInterval);
|
|
2947
|
-
return e.on(
|
|
2947
|
+
return e.on(E.Message, (t) => {
|
|
2948
2948
|
this._handleMessage(t);
|
|
2949
|
-
}), e.on(
|
|
2949
|
+
}), e.on(E.Error, (t) => {
|
|
2950
2950
|
this._abort(y.SocketError, t);
|
|
2951
|
-
}), e.on(
|
|
2951
|
+
}), e.on(E.Disconnected, () => {
|
|
2952
2952
|
this.disconnected || (this.emitError(y.Network, "Lost connection to server."), this.disconnect());
|
|
2953
|
-
}), e.on(
|
|
2953
|
+
}), e.on(E.Close, () => {
|
|
2954
2954
|
this.disconnected || this._abort(y.SocketClosed, "Underlying socket is already closed.");
|
|
2955
2955
|
}), e;
|
|
2956
2956
|
}
|
|
@@ -3217,6 +3217,14 @@ class Hn {
|
|
|
3217
3217
|
console.error("Peer error:", a), this.callbacks.onError && this.callbacks.onError(a), o || s(a);
|
|
3218
3218
|
}), this.peer.on("call", (a) => {
|
|
3219
3219
|
this.handleIncomingCall(a);
|
|
3220
|
+
}), this.peer.on("disconnected", () => {
|
|
3221
|
+
this._disposed || (console.warn("PeerJS signalling disconnected — attempting reconnect"), setTimeout(() => {
|
|
3222
|
+
try {
|
|
3223
|
+
this.peer && !this.peer.destroyed && this.peer.reconnect();
|
|
3224
|
+
} catch (a) {
|
|
3225
|
+
console.warn("Peer reconnect threw:", a && a.message);
|
|
3226
|
+
}
|
|
3227
|
+
}, 1e3));
|
|
3220
3228
|
});
|
|
3221
3229
|
});
|
|
3222
3230
|
}
|
|
@@ -3340,24 +3348,24 @@ class Hn {
|
|
|
3340
3348
|
this.callbacks.hasOwnProperty("on" + e.charAt(0).toUpperCase() + e.slice(1)) && (this.callbacks["on" + e.charAt(0).toUpperCase() + e.slice(1)] = t);
|
|
3341
3349
|
}
|
|
3342
3350
|
disconnect() {
|
|
3343
|
-
Object.values(this.connections).forEach(({ call: e }) => {
|
|
3351
|
+
this._disposed = !0, Object.values(this.connections).forEach(({ call: e }) => {
|
|
3344
3352
|
e.close();
|
|
3345
3353
|
}), this.connections = {}, this.localStream && (this.localStream.getTracks().forEach((e) => e.stop()), this.localStream = null), this.peer && (this.peer.destroy(), this.peer = null);
|
|
3346
3354
|
}
|
|
3347
3355
|
}
|
|
3348
|
-
const
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
+
const P = /* @__PURE__ */ Object.create(null);
|
|
3357
|
+
P.open = "0";
|
|
3358
|
+
P.close = "1";
|
|
3359
|
+
P.ping = "2";
|
|
3360
|
+
P.pong = "3";
|
|
3361
|
+
P.message = "4";
|
|
3362
|
+
P.upgrade = "5";
|
|
3363
|
+
P.noop = "6";
|
|
3356
3364
|
const Z = /* @__PURE__ */ Object.create(null);
|
|
3357
|
-
Object.keys(
|
|
3358
|
-
Z[
|
|
3365
|
+
Object.keys(P).forEach((r) => {
|
|
3366
|
+
Z[P[r]] = r;
|
|
3359
3367
|
});
|
|
3360
|
-
const Ce = { type: "error", data: "parser error" }, Zt = typeof Blob == "function" || typeof Blob < "u" && Object.prototype.toString.call(Blob) === "[object BlobConstructor]", en = typeof ArrayBuffer == "function", tn = (r) => typeof ArrayBuffer.isView == "function" ? ArrayBuffer.isView(r) : r && r.buffer instanceof ArrayBuffer, Be = ({ type: r, data: e }, t, n) => Zt && e instanceof Blob ? t ? n(e) : it(e, n) : en && (e instanceof ArrayBuffer || tn(e)) ? t ? n(e) : it(new Blob([e]), n) : n(
|
|
3368
|
+
const Ce = { type: "error", data: "parser error" }, Zt = typeof Blob == "function" || typeof Blob < "u" && Object.prototype.toString.call(Blob) === "[object BlobConstructor]", en = typeof ArrayBuffer == "function", tn = (r) => typeof ArrayBuffer.isView == "function" ? ArrayBuffer.isView(r) : r && r.buffer instanceof ArrayBuffer, Be = ({ type: r, data: e }, t, n) => Zt && e instanceof Blob ? t ? n(e) : it(e, n) : en && (e instanceof ArrayBuffer || tn(e)) ? t ? n(e) : it(new Blob([e]), n) : n(P[r] + (e || "")), it = (r, e) => {
|
|
3361
3369
|
const t = new FileReader();
|
|
3362
3370
|
return t.onload = function() {
|
|
3363
3371
|
const n = t.result.split(",")[1];
|
|
@@ -4490,9 +4498,9 @@ function Rr(r, e = "", t) {
|
|
|
4490
4498
|
const i = n.host.indexOf(":") !== -1 ? "[" + n.host + "]" : n.host;
|
|
4491
4499
|
return n.id = n.protocol + "://" + i + ":" + n.port + e, n.href = n.protocol + "://" + i + (t && t.port === n.port ? "" : ":" + n.port), n;
|
|
4492
4500
|
}
|
|
4493
|
-
const
|
|
4501
|
+
const Pr = typeof ArrayBuffer == "function", Er = (r) => typeof ArrayBuffer.isView == "function" ? ArrayBuffer.isView(r) : r.buffer instanceof ArrayBuffer, dn = Object.prototype.toString, wr = typeof Blob == "function" || typeof Blob < "u" && dn.call(Blob) === "[object BlobConstructor]", Mr = typeof File == "function" || typeof File < "u" && dn.call(File) === "[object FileConstructor]";
|
|
4494
4502
|
function ze(r) {
|
|
4495
|
-
return
|
|
4503
|
+
return Pr && (r instanceof ArrayBuffer || Er(r)) || wr && r instanceof Blob || Mr && r instanceof File;
|
|
4496
4504
|
}
|
|
4497
4505
|
function te(r, e) {
|
|
4498
4506
|
if (!r || typeof r != "object")
|
|
@@ -5398,7 +5406,7 @@ $.prototype.setMax = function(r) {
|
|
|
5398
5406
|
$.prototype.setJitter = function(r) {
|
|
5399
5407
|
this.jitter = r;
|
|
5400
5408
|
};
|
|
5401
|
-
class
|
|
5409
|
+
class Pe extends b {
|
|
5402
5410
|
constructor(e, t) {
|
|
5403
5411
|
var n;
|
|
5404
5412
|
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, ae(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 : 0.5), this.backoff = new $({
|
|
@@ -5641,10 +5649,10 @@ function ne(r, e) {
|
|
|
5641
5649
|
typeof r == "object" && (e = r, r = void 0), e = e || {};
|
|
5642
5650
|
const t = Rr(r, e.path || "/socket.io"), n = t.source, s = t.id, i = t.path, o = N[s] && i in N[s].nsps, a = e.forceNew || e["force new connection"] || e.multiplex === !1 || o;
|
|
5643
5651
|
let c;
|
|
5644
|
-
return a ? c = new
|
|
5652
|
+
return a ? c = new Pe(n, e) : (N[s] || (N[s] = new Pe(n, e)), c = N[s]), t.query && !e.query && (e.query = t.queryKey), c.socket(t.path, e);
|
|
5645
5653
|
}
|
|
5646
5654
|
Object.assign(ne, {
|
|
5647
|
-
Manager:
|
|
5655
|
+
Manager: Pe,
|
|
5648
5656
|
Socket: un,
|
|
5649
5657
|
io: ne,
|
|
5650
5658
|
connect: ne
|
|
@@ -6601,7 +6609,7 @@ class Zr {
|
|
|
6601
6609
|
}), this.peerLabels = /* @__PURE__ */ new Map(), this.socketManager.on("existingPeers", (e) => {
|
|
6602
6610
|
e.forEach((t) => {
|
|
6603
6611
|
this.peerLabels.set(t.peerId, t.userName || t.userId), this.peerManager.callPeer(t.peerId);
|
|
6604
|
-
});
|
|
6612
|
+
}), this.refreshParticipantsPanel();
|
|
6605
6613
|
}), this.socketManager.on("userJoined", (e) => {
|
|
6606
6614
|
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();
|
|
6607
6615
|
}), this.socketManager.on("userLeft", (e) => {
|
|
@@ -6629,7 +6637,7 @@ class Zr {
|
|
|
6629
6637
|
const t = this.roleResolvers;
|
|
6630
6638
|
this.roleResolvers = [];
|
|
6631
6639
|
for (const n of t) n(this.myRole);
|
|
6632
|
-
this.refreshParticipantsPanel();
|
|
6640
|
+
this.refreshParticipantsPanel(), this.codeSandbox && this.codeSandbox.refreshPermissionUI(), this.whiteboard && this.whiteboard.refreshPermissionUI();
|
|
6633
6641
|
});
|
|
6634
6642
|
}
|
|
6635
6643
|
async hydrateIceServers() {
|
package/dist/meet-sdk.umd.js
CHANGED
|
@@ -38,7 +38,7 @@ a=extmap-allow-mixed`)!==-1){const i=s.sdp.split(`
|
|
|
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}},wn=r=>!r||/^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/.test(r),$t=()=>Math.random().toString(36).slice(2),Bt={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 Mn extends Lt{noop(){}blobToArrayBuffer(e,t){const n=new FileReader;return n.onload=function(s){s.target&&t(s.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=Bt,this.browser=z.getBrowser(),this.browserVersion=z.getVersion(),this.pack=We,this.unpack=Je,this.supports=function(){const t={browser:z.isBrowserSupported(),webRTC:z.isWebRTCSupported(),audioVideo:!1,data:!1,binaryBlob:!1,reliable:!1};if(!t.webRTC)return t;let n;try{n=new RTCPeerConnection(Bt),t.audioVideo=!0;let s;try{s=n.createDataChannel("_PEERJSTEST",{ordered:!0}),t.data=!0,t.reliable=!!s.ordered;try{s.binaryType="blob",t.binaryBlob=!z.isIOS}catch{}}catch{}finally{s&&s.close()}}catch{}finally{n&&n.close()}return t}(),this.validateId=wn,this.randomToken=$t}}const k=new Mn,An="PeerJS: ";class On{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=[An,...t];for(const s in n)n[s]instanceof Error&&(n[s]="("+n[s].name+") "+n[s].message);e>=3?console.log(...n):e>=2?console.warn("WARNING",...n):e>=1&&console.error("ERROR",...n)}constructor(){this._logLevel=0}}var f=new On,ve={},In=Object.prototype.hasOwnProperty,C="~";function F(){}Object.create&&(F.prototype=Object.create(null),new F().__proto__||(C=!1));function Dn(r,e,t){this.fn=r,this.context=e,this.once=t||!1}function Ut(r,e,t,n,s){if(typeof t!="function")throw new TypeError("The listener must be a function");var i=new Dn(t,n||r,s),o=C?C+e:e;return r._events[o]?r._events[o].fn?r._events[o]=[r._events[o],i]:r._events[o].push(i):(r._events[o]=i,r._eventsCount++),r}function X(r,e){--r._eventsCount===0?r._events=new F:delete r._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)In.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 s=0,i=n.length,o=new Array(i);s<i;s++)o[s]=n[s].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,s,i,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,s),!0;case 5:return c.fn.call(c.context,t,n,s,i),!0;case 6:return c.fn.call(c.context,t,n,s,i,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,p;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,s);break;default:if(!l)for(p=1,l=new Array(h-1);p<h;p++)l[p-1]=arguments[p];c[d].fn.apply(c[d].context,l)}}return!0},v.prototype.on=function(e,t,n){return Ut(this,e,t,n,!1)},v.prototype.once=function(e,t,n){return Ut(this,e,t,n,!0)},v.prototype.removeListener=function(e,t,n,s){var i=C?C+e:e;if(!this._events[i])return this;if(!t)return X(this,i),this;var o=this._events[i];if(o.fn)o.fn===t&&(!s||o.once)&&(!n||o.context===n)&&X(this,i);else{for(var a=0,c=[],h=o.length;a<h;a++)(o[a].fn!==t||s&&!o[a].once||n&&o[a].context!==n)&&c.push(o[a]);c.length?this._events[i]=c.length===1?c[0]:c:X(this,i)}return this},v.prototype.removeAllListeners=function(e){var t;return e?(t=C?C+e:e,this._events[t]&&X(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,ve=v;var L={};D(L,"ConnectionType",()=>M),D(L,"PeerErrorType",()=>y),D(L,"BaseConnectionErrorType",()=>Se),D(L,"DataConnectionErrorType",()=>Ce),D(L,"SerializationType",()=>Z),D(L,"SocketEventType",()=>A),D(L,"ServerMessageType",()=>S);var M=function(r){return r.Data="data",r.Media="media",r}({}),y=function(r){return r.BrowserIncompatible="browser-incompatible",r.Disconnected="disconnected",r.InvalidID="invalid-id",r.InvalidKey="invalid-key",r.Network="network",r.PeerUnavailable="peer-unavailable",r.SslUnavailable="ssl-unavailable",r.ServerError="server-error",r.SocketError="socket-error",r.SocketClosed="socket-closed",r.UnavailableID="unavailable-id",r.WebRTC="webrtc",r}({}),Se=function(r){return r.NegotiationFailed="negotiation-failed",r.ConnectionClosed="connection-closed",r}({}),Ce=function(r){return r.NotOpenYet="not-open-yet",r.MessageToBig="message-too-big",r}({}),Z=function(r){return r.Binary="binary",r.BinaryUTF8="binary-utf8",r.JSON="json",r.None="raw",r}({}),A=function(r){return r.Message="message",r.Disconnected="disconnected",r.Error="error",r.Close="close",r}({}),S=function(r){return r.Heartbeat="HEARTBEAT",r.Candidate="CANDIDATE",r.Offer="OFFER",r.Answer="ANSWER",r.Open="OPEN",r.Error="ERROR",r.IdTaken="ID-TAKEN",r.InvalidKey="INVALID-KEY",r.Leave="LEAVE",r.Expire="EXPIRE",r}({});const Nt="1.5.5";class Ln extends ve.EventEmitter{constructor(e,t,n,s,i,o=5e3){super(),this.pingInterval=o,this._disconnected=!0,this._messagesQueue=[];const a=e?"wss://":"ws://";this._baseUrl=a+t+":"+n+s+"peerjs?key="+i}start(e,t){this._id=e;const n=`${this._baseUrl}&id=${e}&token=${t}`;this._socket||!this._disconnected||(this._socket=new WebSocket(n+"&version="+Nt),this._disconnected=!1,this._socket.onmessage=s=>{let i;try{i=JSON.parse(s.data),f.log("Server message received:",i)}catch{f.log("Invalid server message",s.data);return}this.emit(A.Message,i)},this._socket.onclose=s=>{this._disconnected||(f.log("Socket closed.",s),this._cleanup(),this._disconnected=!0,this.emit(A.Disconnected))},this._socket.onopen=()=>{this._disconnected||(this._sendQueuedMessages(),f.log("Socket open"),this._scheduleHeartbeat())})}_scheduleHeartbeat(){this._wsPingTimer=setTimeout(()=>{this._sendHeartbeat()},this.pingInterval)}_sendHeartbeat(){if(!this._wsOpen()){f.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 zt{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,s={ordered:!!e.reliable},i=t.createDataChannel(n.label,s);n._initializeDataChannel(i),this._makeOffer()}else this.handleSDP("OFFER",e.sdp)}_startPeerConnection(){f.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,s=this.connection.type,i=this.connection.provider;f.log("Listening for ICE candidates."),e.onicecandidate=o=>{!o.candidate||!o.candidate.candidate||(f.log(`Received ICE candidates for ${t}:`,o.candidate),i.socket.send({type:S.Candidate,payload:{candidate:o.candidate,type:s,connectionId:n},dst:t}))},e.oniceconnectionstatechange=()=>{switch(e.iceConnectionState){case"failed":f.log("iceConnectionState is failed, closing connections to "+t),this.connection.emitError(Se.NegotiationFailed,"Negotiation of connection to "+t+" failed."),this.connection.close();break;case"closed":f.log("iceConnectionState is closed, closing connections to "+t),this.connection.emitError(Se.ConnectionClosed,"Connection to "+t+" closed."),this.connection.close();break;case"disconnected":f.log("iceConnectionState changed to disconnected on the connection with "+t);break;case"completed":e.onicecandidate=()=>{};break}this.connection.emit("iceStateChanged",e.iceConnectionState)},f.log("Listening for data channel"),e.ondatachannel=o=>{f.log("Received data channel");const a=o.channel;i.getConnection(t,n)._initializeDataChannel(a)},f.log("Listening for remote stream"),e.ontrack=o=>{f.log("Received remote stream");const a=o.streams[0],c=i.getConnection(t,n);if(c.type===M.Media){const h=c;this._addStreamToMediaConnection(a,h)}}}cleanup(){f.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 s=this.connection.dataChannel;s&&(n=!!s.readyState&&s.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);f.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),f.log("Set localDescription:",n,`for:${this.connection.peer}`);let s={sdp:n,type:this.connection.type,connectionId:this.connection.connectionId,metadata:this.connection.metadata};if(this.connection.type===M.Data){const i=this.connection;s={...s,label:i.label,reliable:i.reliable,serialization:i.serialization}}t.socket.send({type:S.Offer,payload:s,dst:this.connection.peer})}catch(s){s!="OperationError: Failed to set local offer sdp: Called in wrong state: kHaveRemoteOffer"&&(t.emitError(y.WebRTC,s),f.log("Failed to setLocalDescription, ",s))}}catch(n){t.emitError(y.WebRTC,n),f.log("Failed to createOffer, ",n)}}async _makeAnswer(){const e=this.connection.peerConnection,t=this.connection.provider;try{const n=await e.createAnswer();f.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),f.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(s){t.emitError(y.WebRTC,s),f.log("Failed to setLocalDescription, ",s)}}catch(n){t.emitError(y.WebRTC,n),f.log("Failed to create answer, ",n)}}async handleSDP(e,t){t=new RTCSessionDescription(t);const n=this.connection.peerConnection,s=this.connection.provider;f.log("Setting remote description",t);const i=this;try{await n.setRemoteDescription(t),f.log(`Set remoteDescription:${e} for:${this.connection.peer}`),e==="OFFER"&&await i._makeAnswer()}catch(o){s.emitError(y.WebRTC,o),f.log("Failed to setRemoteDescription, ",o)}}async handleCandidate(e){f.log("handleCandidate:",e);try{await this.connection.peerConnection.addIceCandidate(e),f.log(`Added ICE candidate for:${this.connection.peer}`)}catch(t){this.connection.provider.emitError(y.WebRTC,t),f.log("Failed to handleCandidate, ",t)}}_addTracksToConnection(e,t){if(f.log(`add tracks from stream ${e.id} to peer connection`),!t.addTrack)return f.error("Your browser does't support RTCPeerConnection#addTrack. Ignored.");e.getTracks().forEach(n=>{t.addTrack(n,e)})}_addStreamToMediaConnection(e,t){f.log(`add stream ${e.id} to media connection ${t.connectionId}`),t.addStream(e)}}class Ft extends ve.EventEmitter{emitError(e,t){f.error("Error:",t),this.emit("error",new $n(`${e}`,t))}}class $n extends Error{constructor(e,t){typeof t=="string"?super(t):(super(),Object.assign(this,t)),this.type=e}}class jt extends Ft{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 V=class V extends jt{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||V.ID_PREFIX+k.randomToken(),this._negotiator=new zt(this),this._localStream&&this._negotiator.startConnection({_stream:this._localStream,originator:!0})}_initializeDataChannel(e){this.dataChannel=e,this.dataChannel.onopen=()=>{f.log(`DC#${this.connectionId} dc connection success`),this.emit("willCloseOnRemote")},this.dataChannel.onclose=()=>{f.log(`DC#${this.connectionId} dc closed for:`,this.peer),this.close()}}addStream(e){f.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:f.warn(`Unrecognized message type:${t} from peer:${this.peer}`);break}}answer(e,t={}){if(this._localStream){f.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 s of n)this.handleMessage(s);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"))}};je=new WeakMap,K(V,je,V.ID_PREFIX="mc_");let ee=V;class Bn{constructor(e){this._options=e}_buildRequest(e){const t=this._options.secure?"https":"http",{host:n,port:s,path:i,key:o}=this._options,a=new URL(`${t}://${n}:${s}${i}${o}/${e}`);return a.searchParams.set("ts",`${Date.now()}${Math.random()}`),a.searchParams.set("version",Nt),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){f.error("Error retrieving ID",e);let t="";throw this._options.path==="/"&&this._options.host!==k.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===k.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 f.error("Error retrieving list peers",e),new Error("Could not get list peers from the server."+e)}}}const $=class $ extends jt{get type(){return M.Data}constructor(e,t,n){super(e,t,n),this.connectionId=this.options.connectionId||$.ID_PREFIX+$t(),this.label=this.options.label||this.connectionId,this.reliable=!!this.options.reliable,this._negotiator=new zt(this),this._negotiator.startConnection(this.options._payload||{originator:!0,reliable:this.reliable})}_initializeDataChannel(e){this.dataChannel=e,this.dataChannel.onopen=()=>{f.log(`DC#${this.connectionId} dc connection success`),this._open=!0,this.emit("open")},this.dataChannel.onmessage=t=>{f.log(`DC#${this.connectionId} dc onmessage:`,t.data)},this.dataChannel.onclose=()=>{f.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(Ce.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:f.warn("Unrecognized message type:",e.type,"from peer:",this.peer);break}}};qe=new WeakMap,Ve=new WeakMap,K($,qe,$.ID_PREFIX="dc_"),K($,Ve,$.MAX_BUFFERED_AMOUNT=8388608);let te=$;class ke extends te{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>te.MAX_BUFFERED_AMOUNT)return this._buffering=!0,setTimeout(()=>{this._buffering=!1,this._tryBuffer()},50),!1;try{this.dataChannel.send(e)}catch(t){return f.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 xe extends ke{close(e){super.close(e),this._chunkedData={}}constructor(e,t,n){super(e,t,n),this.chunker=new Lt,this.serialization=Z.Binary,this._chunkedData={}}_handleDataMessage({data:e}){const t=Je(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 s=En(n.data);this._handleDataMessage({data:s})}}_send(e,t){const n=We(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);f.log(`DC#${this.connectionId} Try to send ${t.length} chunks...`);for(const n of t)this.send(n,!0)}}class Un extends ke{_handleDataMessage({data:e}){super.emit("data",e)}_send(e,t){this._bufferedSend(e)}constructor(...e){super(...e),this.serialization=Z.None}}class Nn extends ke{_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>=k.chunkedMTU){this.emitError(Ce.MessageToBig,"Message too big for JSON channel");return}this._bufferedSend(n)}constructor(...e){super(...e),this.serialization=Z.JSON,this.encoder=new TextEncoder,this.decoder=new TextDecoder,this.stringify=JSON.stringify,this.parse=JSON.parse}}const H=class H extends Ft{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:Un,json:Nn,binary:xe,"binary-utf8":xe,default:xe},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:k.CLOUD_HOST,port:k.CLOUD_PORT,path:"/",key:H.DEFAULT_KEY,token:k.randomToken(),config:k.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!==k.CLOUD_HOST?this._options.secure=k.isSecure():this._options.host==k.CLOUD_HOST&&(this._options.secure=!0),this._options.logFunction&&f.setLogFunction(this._options.logFunction),f.logLevel=this._options.debug||0,this._api=new Bn(t),this._socket=this._createServerConnection(),!k.supports.audioVideo&&!k.supports.data){this._delayedAbort(y.BrowserIncompatible,"The current browser does not support WebRTC");return}if(n&&!k.validateId(n)){this._delayedAbort(y.InvalidID,`ID "${n}" is invalid`);return}n?this._initialize(n):this._api.retrieveId().then(s=>this._initialize(s)).catch(s=>this._abort(y.ServerError,s))}_createServerConnection(){const e=new Ln(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,s=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:f.log(`Received leave message from ${s}`),this._cleanupPeer(s),this._connections.delete(s);break;case S.Expire:this.emitError(y.PeerUnavailable,`Could not connect to peer ${s}`);break;case S.Offer:{const i=n.connectionId;let o=this.getConnection(s,i);if(o&&(o.close(),f.warn(`Offer received for existing Connection ID:${i}`)),n.type===M.Media){const c=new ee(s,this,{connectionId:i,_payload:n,metadata:n.metadata});o=c,this._addConnection(s,o),this.emit("call",c)}else if(n.type===M.Data){const c=new this._serializers[n.serialization](s,this,{connectionId:i,_payload:n,metadata:n.metadata,label:n.label,serialization:n.serialization,reliable:n.reliable});o=c,this._addConnection(s,o),this.emit("connection",c)}else{f.warn(`Received malformed connection type:${n.type}`);return}const a=this._getMessages(i);for(const c of a)o.handleMessage(c);break}default:{if(!n){f.warn(`You received a malformed message from ${s} of type ${t}`);return}const i=n.connectionId,o=this.getConnection(s,i);o&&o.peerConnection?o.handleMessage(e):i?this._storeMessage(i,e):f.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){f.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){f.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){f.error("To call a peer, you must provide a stream from your browser's `getUserMedia`.");return}const s=new ee(e,this,{...n,_stream:t});return this._addConnection(e,s),s}_addConnection(e,t){f.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 s of n)if(s.connectionId===t)return s;return null}_delayedAbort(e,t){setTimeout(()=>{this._abort(e,t)},0)}_abort(e,t){f.error("Aborting!"),this.emitError(e,t),this._lastServerId?this.disconnect():this.destroy()}destroy(){this.destroyed||(f.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;f.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)f.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)f.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))}};He=new WeakMap,K(H,He,H.DEFAULT_KEY="peerjs");let Te=H;var zn=Te;class Fn{constructor(e){this.config=e,this.peer=null,this.localStream=null,this.connections={},this.callbacks={onStream:null,onPeerLeft:null,onError: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,s)=>{const i=t===0?e:`${e}-r${Math.random().toString(36).slice(2,6)}`;this.peer=new zn(i,{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 "${i}" 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){s(c)}return}console.error("Peer error:",a),this.callbacks.onError&&this.callbacks.onError(a),o||s(a)}),this.peer.on("call",a=>{this.handleIncomingCall(a)})})}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",s=>{console.log("Received stream from:",e),this.connections[e]={call:n,stream:s},this.callbacks.onStream&&this.callbacks.onStream(e,s,!1)}),n.on("close",()=>{console.log("Call closed:",e),delete this.connections[e],this.callbacks.onPeerLeft&&this.callbacks.onPeerLeft(e)}),n.on("error",s=>{console.error("Call error:",s),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 s=n.getSenders().find(i=>i.track&&i.track.kind==="video");s&&s.replaceTrack(e).catch(i=>console.warn("replaceTrack failed:",i&&i.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",()=>this.stopScreenShare().catch(()=>{})),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(){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 E=Object.create(null);E.open="0",E.close="1",E.ping="2",E.pong="3",E.message="4",E.upgrade="5",E.noop="6";const ne=Object.create(null);Object.keys(E).forEach(r=>{ne[E[r]]=r});const Re={type:"error",data:"parser error"},qt=typeof Blob=="function"||typeof Blob<"u"&&Object.prototype.toString.call(Blob)==="[object BlobConstructor]",Vt=typeof ArrayBuffer=="function",Ht=r=>typeof ArrayBuffer.isView=="function"?ArrayBuffer.isView(r):r&&r.buffer instanceof ArrayBuffer,Pe=({type:r,data:e},t,n)=>qt&&e instanceof Blob?t?n(e):Kt(e,n):Vt&&(e instanceof ArrayBuffer||Ht(e))?t?n(e):Kt(new Blob([e]),n):n(E[r]+(e||"")),Kt=(r,e)=>{const t=new FileReader;return t.onload=function(){const n=t.result.split(",")[1];e("b"+(n||""))},t.readAsDataURL(r)};function Jt(r){return r instanceof Uint8Array?r:r instanceof ArrayBuffer?new Uint8Array(r):new Uint8Array(r.buffer,r.byteOffset,r.byteLength)}let Ee;function jn(r,e){if(qt&&r.data instanceof Blob)return r.data.arrayBuffer().then(Jt).then(e);if(Vt&&(r.data instanceof ArrayBuffer||Ht(r.data)))return e(Jt(r.data));Pe(r,!1,t=>{Ee||(Ee=new TextEncoder),e(Ee.encode(t))})}const Wt="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",j=typeof Uint8Array>"u"?[]:new Uint8Array(256);for(let r=0;r<Wt.length;r++)j[Wt.charCodeAt(r)]=r;const qn=r=>{let e=r.length*.75,t=r.length,n,s=0,i,o,a,c;r[r.length-1]==="="&&(e--,r[r.length-2]==="="&&e--);const h=new ArrayBuffer(e),l=new Uint8Array(h);for(n=0;n<t;n+=4)i=j[r.charCodeAt(n)],o=j[r.charCodeAt(n+1)],a=j[r.charCodeAt(n+2)],c=j[r.charCodeAt(n+3)],l[s++]=i<<2|o>>4,l[s++]=(o&15)<<4|a>>2,l[s++]=(a&3)<<6|c&63;return h},Vn=typeof ArrayBuffer=="function",we=(r,e)=>{if(typeof r!="string")return{type:"message",data:Yt(r,e)};const t=r.charAt(0);return t==="b"?{type:"message",data:Hn(r.substring(1),e)}:ne[t]?r.length>1?{type:ne[t],data:r.substring(1)}:{type:ne[t]}:Re},Hn=(r,e)=>{if(Vn){const t=qn(r);return Yt(t,e)}else return{base64:!0,data:r}},Yt=(r,e)=>{switch(e){case"blob":return r instanceof Blob?r:new Blob([r]);case"arraybuffer":default:return r instanceof ArrayBuffer?r:r.buffer}},Gt="",Kn=(r,e)=>{const t=r.length,n=new Array(t);let s=0;r.forEach((i,o)=>{Pe(i,!1,a=>{n[o]=a,++s===t&&e(n.join(Gt))})})},Jn=(r,e)=>{const t=r.split(Gt),n=[];for(let s=0;s<t.length;s++){const i=we(t[s],e);if(n.push(i),i.type==="error")break}return n};function Wn(){return new TransformStream({transform(r,e){jn(r,t=>{const n=t.length;let s;if(n<126)s=new Uint8Array(1),new DataView(s.buffer).setUint8(0,n);else if(n<65536){s=new Uint8Array(3);const i=new DataView(s.buffer);i.setUint8(0,126),i.setUint16(1,n)}else{s=new Uint8Array(9);const i=new DataView(s.buffer);i.setUint8(0,127),i.setBigUint64(1,BigInt(n))}r.data&&typeof r.data!="string"&&(s[0]|=128),e.enqueue(s),e.enqueue(t)})}})}let Me;function re(r){return r.reduce((e,t)=>e+t.length,0)}function se(r,e){if(r[0].length===e)return r.shift();const t=new Uint8Array(e);let n=0;for(let s=0;s<e;s++)t[s]=r[0][n++],n===r[0].length&&(r.shift(),n=0);return r.length&&n<r[0].length&&(r[0]=r[0].slice(n)),t}function Yn(r,e){Me||(Me=new TextDecoder);const t=[];let n=0,s=-1,i=!1;return new TransformStream({transform(o,a){for(t.push(o);;){if(n===0){if(re(t)<1)break;const c=se(t,1);i=(c[0]&128)===128,s=c[0]&127,s<126?n=3:s===126?n=1:n=2}else if(n===1){if(re(t)<2)break;const c=se(t,2);s=new DataView(c.buffer,c.byteOffset,c.length).getUint16(0),n=3}else if(n===2){if(re(t)<8)break;const c=se(t,8),h=new DataView(c.buffer,c.byteOffset,c.length),l=h.getUint32(0);if(l>Math.pow(2,21)-1){a.enqueue(Re);break}s=l*Math.pow(2,32)+h.getUint32(4),n=3}else{if(re(t)<s)break;const c=se(t,s);a.enqueue(we(i?c:Me.decode(c),e)),n=0}if(s===0||s>r){a.enqueue(Re);break}}}})}const Qt=4;function b(r){if(r)return Gn(r)}function Gn(r){for(var e in b.prototype)r[e]=b.prototype[e];return r}b.prototype.on=b.prototype.addEventListener=function(r,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+r]=this._callbacks["$"+r]||[]).push(e),this},b.prototype.once=function(r,e){function t(){this.off(r,t),e.apply(this,arguments)}return t.fn=e,this.on(r,t),this},b.prototype.off=b.prototype.removeListener=b.prototype.removeAllListeners=b.prototype.removeEventListener=function(r,e){if(this._callbacks=this._callbacks||{},arguments.length==0)return this._callbacks={},this;var t=this._callbacks["$"+r];if(!t)return this;if(arguments.length==1)return delete this._callbacks["$"+r],this;for(var n,s=0;s<t.length;s++)if(n=t[s],n===e||n.fn===e){t.splice(s,1);break}return t.length===0&&delete this._callbacks["$"+r],this},b.prototype.emit=function(r){this._callbacks=this._callbacks||{};for(var e=new Array(arguments.length-1),t=this._callbacks["$"+r],n=1;n<arguments.length;n++)e[n-1]=arguments[n];if(t){t=t.slice(0);for(var n=0,s=t.length;n<s;++n)t[n].apply(this,e)}return this},b.prototype.emitReserved=b.prototype.emit,b.prototype.listeners=function(r){return this._callbacks=this._callbacks||{},this._callbacks["$"+r]||[]},b.prototype.hasListeners=function(r){return!!this.listeners(r).length};const ie=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")(),Qn="arraybuffer";function ts(){}function Xt(r,...e){return e.reduce((t,n)=>(r.hasOwnProperty(n)&&(t[n]=r[n]),t),{})}const Xn=T.setTimeout,Zn=T.clearTimeout;function oe(r,e){e.useNativeTimers?(r.setTimeoutFn=Xn.bind(T),r.clearTimeoutFn=Zn.bind(T)):(r.setTimeoutFn=T.setTimeout.bind(T),r.clearTimeoutFn=T.clearTimeout.bind(T))}const er=1.33;function tr(r){return typeof r=="string"?nr(r):Math.ceil((r.byteLength||r.size)*er)}function nr(r){let e=0,t=0;for(let n=0,s=r.length;n<s;n++)e=r.charCodeAt(n),e<128?t+=1:e<2048?t+=2:e<55296||e>=57344?t+=3:(n++,t+=4);return t}function Zt(){return Date.now().toString(36).substring(3)+Math.random().toString(36).substring(2,5)}function rr(r){let e="";for(let t in r)r.hasOwnProperty(t)&&(e.length&&(e+="&"),e+=encodeURIComponent(t)+"="+encodeURIComponent(r[t]));return e}function sr(r){let e={},t=r.split("&");for(let n=0,s=t.length;n<s;n++){let i=t[n].split("=");e[decodeURIComponent(i[0])]=decodeURIComponent(i[1])}return e}class ir extends Error{constructor(e,t,n){super(e),this.description=t,this.context=n,this.type="TransportError"}}class Ae extends b{constructor(e){super(),this.writable=!1,oe(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 ir(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=we(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=rr(e);return t.length?"?"+t:""}}class or extends Ae{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)};Jn(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,Kn(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]=Zt()),!this.supportsBinary&&!t.sid&&(t.b64=1),this.createUri(e,t)}}let en=!1;try{en=typeof XMLHttpRequest<"u"&&"withCredentials"in new XMLHttpRequest}catch{}const ar=en;function cr(){}class hr extends or{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",(s,i)=>{this.onError("xhr post error",s,i)})}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 w extends b{constructor(e,t,n){super(),this.createRequest=e,oe(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=Xt(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 s in this._opts.extraHeaders)this._opts.extraHeaders.hasOwnProperty(s)&&n.setRequestHeader(s,this._opts.extraHeaders[s])}}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 s;n.readyState===3&&((s=this._opts.cookieJar)===null||s===void 0||s.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(s){this.setTimeoutFn(()=>{this._onError(s)},0);return}typeof document<"u"&&(this._index=w.requestsCount++,w.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=cr,e)try{this._xhr.abort()}catch{}typeof document<"u"&&delete w.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(w.requestsCount=0,w.requests={},typeof document<"u"){if(typeof attachEvent=="function")attachEvent("onunload",tn);else if(typeof addEventListener=="function"){const r="onpagehide"in T?"pagehide":"unload";addEventListener(r,tn,!1)}}function tn(){for(let r in w.requests)w.requests.hasOwnProperty(r)&&w.requests[r].abort()}const lr=function(){const r=nn({xdomain:!1});return r&&r.responseType!==null}();class dr extends hr{constructor(e){super(e);const t=e&&e.forceBase64;this.supportsBinary=lr&&!t}request(e={}){return Object.assign(e,{xd:this.xd},this.opts),new w(nn,this.uri(),e)}}function nn(r){const e=r.xdomain;try{if(typeof XMLHttpRequest<"u"&&(!e||ar))return new XMLHttpRequest}catch{}if(!e)try{return new T[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP")}catch{}}const rn=typeof navigator<"u"&&typeof navigator.product=="string"&&navigator.product.toLowerCase()==="reactnative";class ur extends Ae{get name(){return"websocket"}doOpen(){const e=this.uri(),t=this.opts.protocols,n=rn?{}:Xt(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(s){return this.emitReserved("error",s)}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],s=t===e.length-1;Pe(n,this.supportsBinary,i=>{try{this.doWrite(n,i)}catch{}s&&ie(()=>{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]=Zt()),this.supportsBinary||(t.b64=1),this.createUri(e,t)}}const Oe=T.WebSocket||T.MozWebSocket;class fr extends ur{createSocket(e,t,n){return rn?new Oe(e,t,n):t?new Oe(e,t):new Oe(e)}doWrite(e,t){this.ws.send(t)}}class pr extends Ae{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=Yn(Number.MAX_SAFE_INTEGER,this.socket.binaryType),n=e.readable.pipeThrough(t).getReader(),s=Wn();s.readable.pipeTo(e.writable),this._writer=s.writable.getWriter();const i=()=>{n.read().then(({done:a,value:c})=>{a||(this.onPacket(c),i())}).catch(a=>{})};i();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],s=t===e.length-1;this._writer.write(n).then(()=>{s&&ie(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){var e;(e=this._transport)===null||e===void 0||e.close()}}const gr={websocket:fr,webtransport:pr,polling:dr},mr=/^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,yr=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];function Ie(r){if(r.length>8e3)throw"URI too long";const e=r,t=r.indexOf("["),n=r.indexOf("]");t!=-1&&n!=-1&&(r=r.substring(0,t)+r.substring(t,n).replace(/:/g,";")+r.substring(n,r.length));let s=mr.exec(r||""),i={},o=14;for(;o--;)i[yr[o]]=s[o]||"";return t!=-1&&n!=-1&&(i.source=e,i.host=i.host.substring(1,i.host.length-1).replace(/;/g,":"),i.authority=i.authority.replace("[","").replace("]","").replace(/;/g,":"),i.ipv6uri=!0),i.pathNames=br(i,i.path),i.queryKey=_r(i,i.query),i}function br(r,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 _r(r,e){const t={};return e.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,function(n,s,i){s&&(t[s]=i)}),t}const De=typeof addEventListener=="function"&&typeof removeEventListener=="function",ae=[];De&&addEventListener("offline",()=>{ae.forEach(r=>r())},!1);class O extends b{constructor(e,t){if(super(),this.binaryType=Qn,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=Ie(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=Ie(t.host).host);oe(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 s=n.prototype.name;this.transports.push(s),this._transportsByName[s]=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=sr(this.opts.query)),De&&(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"})},ae.push(this._offlineEventListener))),this.opts.withCredentials&&(this._cookieJar=void 0),this._open()}createTransport(e){const t=Object.assign({},this.opts.query);t.EIO=Qt,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&&O.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",O.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 s=this.writeBuffer[n].data;if(s&&(t+=tr(s)),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,ie(()=>{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,s){if(typeof t=="function"&&(s=t,t=void 0),typeof n=="function"&&(s=n,n=null),this.readyState==="closing"||this.readyState==="closed")return;n=n||{},n.compress=n.compress!==!1;const i={type:e,data:t,options:n};this.emitReserved("packetCreate",i),this.writeBuffer.push(i),s&&this.once("flush",s),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(O.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(),De&&(this._beforeunloadEventListener&&removeEventListener("beforeunload",this._beforeunloadEventListener,!1),this._offlineEventListener)){const n=ae.indexOf(this._offlineEventListener);n!==-1&&ae.splice(n,1)}this.readyState="closed",this.id=null,this.emitReserved("close",e,t),this.writeBuffer=[],this._prevBufferLen=0}}}O.protocol=Qt;class vr extends O{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;O.priorWebsocketSuccess=!1;const s=()=>{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;O.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 i(){n||(n=!0,l(),t.close(),t=null)}const o=d=>{const u=new Error("probe error: "+d);u.transport=t.name,i(),this.emitReserved("upgradeError",u)};function a(){o("transport closed")}function c(){o("socket closed")}function h(d){t&&d.name!==t.name&&i()}const l=()=>{t.removeListener("open",s),t.removeListener("error",o),t.removeListener("close",a),this.off("close",c),this.off("upgrading",h)};t.once("open",s),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 Sr=class extends vr{constructor(e,t={}){const n=typeof e=="object",s=n?{...e}:{...t};(!s.transports||s.transports&&typeof s.transports[0]=="string")&&(s.transports=(s.transports||["polling","websocket","webtransport"]).map(i=>gr[i]).filter(i=>!!i)),super(n?s:e,s)}};function Cr(r,e="",t){let n=r;t=t||typeof location<"u"&&location,r==null&&(r=t.protocol+"//"+t.host),typeof r=="string"&&(r.charAt(0)==="/"&&(r.charAt(1)==="/"?r=t.protocol+r:r=t.host+r),/^(https?|wss?):\/\//.test(r)||(typeof t<"u"?r=t.protocol+"//"+r:r="https://"+r),n=Ie(r)),n.port||(/^(http|ws)$/.test(n.protocol)?n.port="80":/^(http|ws)s$/.test(n.protocol)&&(n.port="443")),n.path=n.path||"/";const i=n.host.indexOf(":")!==-1?"["+n.host+"]":n.host;return n.id=n.protocol+"://"+i+":"+n.port+e,n.href=n.protocol+"://"+i+(t&&t.port===n.port?"":":"+n.port),n}const kr=typeof ArrayBuffer=="function",xr=r=>typeof ArrayBuffer.isView=="function"?ArrayBuffer.isView(r):r.buffer instanceof ArrayBuffer,sn=Object.prototype.toString,Tr=typeof Blob=="function"||typeof Blob<"u"&&sn.call(Blob)==="[object BlobConstructor]",Rr=typeof File=="function"||typeof File<"u"&&sn.call(File)==="[object FileConstructor]";function Le(r){return kr&&(r instanceof ArrayBuffer||xr(r))||Tr&&r instanceof Blob||Rr&&r instanceof File}function ce(r,e){if(!r||typeof r!="object")return!1;if(Array.isArray(r)){for(let t=0,n=r.length;t<n;t++)if(ce(r[t]))return!0;return!1}if(Le(r))return!0;if(r.toJSON&&typeof r.toJSON=="function"&&arguments.length===1)return ce(r.toJSON(),!0);for(const t in r)if(Object.prototype.hasOwnProperty.call(r,t)&&ce(r[t]))return!0;return!1}function Pr(r){const e=[],t=r.data,n=r;return n.data=$e(t,e),n.attachments=e.length,{packet:n,buffers:e}}function $e(r,e){if(!r)return r;if(Le(r)){const t={_placeholder:!0,num:e.length};return e.push(r),t}else if(Array.isArray(r)){const t=new Array(r.length);for(let n=0;n<r.length;n++)t[n]=$e(r[n],e);return t}else if(typeof r=="object"&&!(r instanceof Date)){const t={};for(const n in r)Object.prototype.hasOwnProperty.call(r,n)&&(t[n]=$e(r[n],e));return t}return r}function Er(r,e){return r.data=Be(r.data,e),delete r.attachments,r}function Be(r,e){if(!r)return r;if(r&&r._placeholder===!0){if(typeof r.num=="number"&&r.num>=0&&r.num<e.length)return e[r.num];throw new Error("illegal attachments")}else if(Array.isArray(r))for(let t=0;t<r.length;t++)r[t]=Be(r[t],e);else if(typeof r=="object")for(const t in r)Object.prototype.hasOwnProperty.call(r,t)&&(r[t]=Be(r[t],e));return r}const wr=["connect","connect_error","disconnect","disconnecting","newListener","removeListener"];var g;(function(r){r[r.CONNECT=0]="CONNECT",r[r.DISCONNECT=1]="DISCONNECT",r[r.EVENT=2]="EVENT",r[r.ACK=3]="ACK",r[r.CONNECT_ERROR=4]="CONNECT_ERROR",r[r.BINARY_EVENT=5]="BINARY_EVENT",r[r.BINARY_ACK=6]="BINARY_ACK"})(g||(g={}));class Mr{constructor(e){this.replacer=e}encode(e){return(e.type===g.EVENT||e.type===g.ACK)&&ce(e)?this.encodeAsBinary({type:e.type===g.EVENT?g.BINARY_EVENT:g.BINARY_ACK,nsp:e.nsp,data:e.data,id:e.id}):[this.encodeAsString(e)]}encodeAsString(e){let t=""+e.type;return(e.type===g.BINARY_EVENT||e.type===g.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=Pr(e),n=this.encodeAsString(t.packet),s=t.buffers;return s.unshift(n),s}}class Ue 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===g.BINARY_EVENT;n||t.type===g.BINARY_ACK?(t.type=n?g.EVENT:g.ACK,this.reconstructor=new Ar(t),t.attachments===0&&super.emitReserved("decoded",t)):super.emitReserved("decoded",t)}else if(Le(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(g[n.type]===void 0)throw new Error("unknown packet type "+n.type);if(n.type===g.BINARY_EVENT||n.type===g.BINARY_ACK){const i=t+1;for(;e.charAt(++t)!=="-"&&t!=e.length;);const o=e.substring(i,t);if(o!=Number(o)||e.charAt(t)!=="-")throw new Error("Illegal attachments");const a=Number(o);if(!Or(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 i=t+1;for(;++t&&!(e.charAt(t)===","||t===e.length););n.nsp=e.substring(i,t)}else n.nsp="/";const s=e.charAt(t+1);if(s!==""&&Number(s)==s){const i=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(i,t+1))}if(e.charAt(++t)){const i=this.tryParse(e.substr(t));if(Ue.isPayloadValid(n.type,i))n.data=i;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 g.CONNECT:return on(t);case g.DISCONNECT:return t===void 0;case g.CONNECT_ERROR:return typeof t=="string"||on(t);case g.EVENT:case g.BINARY_EVENT:return Array.isArray(t)&&(typeof t[0]=="number"||typeof t[0]=="string"&&wr.indexOf(t[0])===-1);case g.ACK:case g.BINARY_ACK:return Array.isArray(t)}}destroy(){this.reconstructor&&(this.reconstructor.finishedReconstruction(),this.reconstructor=null)}}class Ar{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=Er(this.reconPack,this.buffers);return this.finishedReconstruction(),t}return null}finishedReconstruction(){this.reconPack=null,this.buffers=[]}}const Or=Number.isInteger||function(r){return typeof r=="number"&&isFinite(r)&&Math.floor(r)===r};function on(r){return Object.prototype.toString.call(r)==="[object Object]"}const Ir=Object.freeze(Object.defineProperty({__proto__:null,Decoder:Ue,Encoder:Mr,get PacketType(){return g}},Symbol.toStringTag,{value:"Module"}));function R(r,e,t){return r.on(e,t),function(){r.off(e,t)}}const Dr=Object.freeze({connect:1,connect_error:1,disconnect:1,disconnecting:1,newListener:1,removeListener:1});class an 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,s,i;if(Dr.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:g.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=(s=(n=this.io.engine)===null||n===void 0?void 0:n.transport)===null||s===void 0?void 0:s.writable,c=this.connected&&!(!((i=this.io.engine)===null||i===void 0)&&i._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 s=(n=this.flags.timeout)!==null&&n!==void 0?n:this._opts.ackTimeout;if(s===void 0){this.acks[e]=t;return}const i=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"))},s),o=(...a)=>{this.io.clearTimeoutFn(i),t.apply(this,a)};o.withError=!0,this.acks[e]=o}emitWithAck(e,...t){return new Promise((n,s)=>{const i=(o,a)=>o?s(o):n(a);i.withError=!0,t.push(i),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((s,...i)=>(this._queue[0],s!==null?n.tryCount>this._opts.retries&&(this._queue.shift(),t&&t(s)):(this._queue.shift(),t&&t(null,...i)),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:g.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 g.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 g.EVENT:case g.BINARY_EVENT:this.onevent(e);break;case g.ACK:case g.BINARY_ACK:this.onack(e);break;case g.DISCONNECT:this.ondisconnect();break;case g.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(...s){n||(n=!0,t.packet({type:g.ACK,id:e,data:s}))}}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:g.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 U(r){r=r||{},this.ms=r.min||100,this.max=r.max||1e4,this.factor=r.factor||2,this.jitter=r.jitter>0&&r.jitter<=1?r.jitter:0,this.attempts=0}U.prototype.duration=function(){var r=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),t=Math.floor(e*this.jitter*r);r=Math.floor(e*10)&1?r+t:r-t}return Math.min(r,this.max)|0},U.prototype.reset=function(){this.attempts=0},U.prototype.setMin=function(r){this.ms=r},U.prototype.setMax=function(r){this.max=r},U.prototype.setJitter=function(r){this.jitter=r};class Ne 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,oe(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 U({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()}),this.timeout(t.timeout==null?2e4:t.timeout),this._readyState="closed",this.uri=e;const s=t.parser||Ir;this.encoder=new s.Encoder,this.decoder=new s.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 Sr(this.uri,this.opts);const t=this.engine,n=this;this._readyState="opening",this.skipReconnect=!1;const s=R(t,"open",function(){n.onopen(),e&&e()}),i=a=>{this.cleanup(),this._readyState="closed",this.emitReserved("error",a),e?e(a):this.maybeReconnectOnOpen()},o=R(t,"error",i);if(this._timeout!==!1){const a=this._timeout,c=this.setTimeoutFn(()=>{s(),i(new Error("timeout")),t.close()},a);this.opts.autoUnref&&c.unref(),this.subs.push(()=>{this.clearTimeoutFn(c)})}return this.subs.push(s),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){ie(()=>{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 an(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(s=>{s?(e._reconnecting=!1,e.reconnect(),this.emitReserved("reconnect_error",s)):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 q={};function he(r,e){typeof r=="object"&&(e=r,r=void 0),e=e||{};const t=Cr(r,e.path||"/socket.io"),n=t.source,s=t.id,i=t.path,o=q[s]&&i in q[s].nsps,a=e.forceNew||e["force new connection"]||e.multiplex===!1||o;let c;return a?c=new Ne(n,e):(q[s]||(q[s]=new Ne(n,e)),c=q[s]),t.query&&!e.query&&(e.query=t.queryKey),c.socket(t.path,e)}Object.assign(he,{Manager:Ne,Socket:an,io:he,connect:he});class Lr{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 i=new URL(this.config.socketUrl);t=`${i.protocol}//${i.host}`;const o=i.pathname.replace(/\/+$/,"");o&&(n=`${o}/socket.io/`)}catch{}this.socket=he(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",i=>{this.callbacks.onMessage&&this.callbacks.onMessage(i)}),this.socket.on("existing-peers",i=>{this.callbacks.onExistingPeers&&this.callbacks.onExistingPeers(i)}),this.socket.on("you-joined",i=>{this.callbacks.onYouJoined&&this.callbacks.onYouJoined(i)}),this.socket.on("user-joined",i=>{this.callbacks.onUserJoined&&this.callbacks.onUserJoined(i)}),this.socket.on("user-left",i=>{this.callbacks.onUserLeft&&this.callbacks.onUserLeft(i)}),this.socket.on("peer-media-state-change",i=>{this.callbacks.onPeerMediaStateChange&&this.callbacks.onPeerMediaStateChange(i)});const s=["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 i of s)this.socket.on(i,o=>{const a=this.rawListeners&&this.rawListeners.get(i);a&&a.forEach(c=>{try{c(o)}catch(h){console.warn(h)}})});this.socket.on("error",i=>{console.error("Socket error:",i),this.callbacks.onError&&this.callbacks.onError(i)})}joinRoom(e,t,n,s){this.socket&&this.socket.emit("join-room",{roomId:e,userId:t,userName:n,peerId:s})}emitMediaState(e,t,n,s){this.socket&&this.socket.emit("media-state-change",{roomId:e,userId:t,type:n,enabled:s})}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,s,i){if(this.socket){const o={roomId:e,userId:t,userName:n,message:s||""};Array.isArray(i)&&i.length&&(o.attachmentIds=i),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 $r{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 ze{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(!ze.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,s=Number.isFinite(t.videoBitsPerSecond)?t.videoBitsPerSecond:1e6,i=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:s,audioBitsPerSecond:i};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(p=>{console.warn(`Recording chunk seq=${h} upload failed:`,p&&p.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(i=>{this.recorder.onstop=i,this.recorder.stop()});const t=(await Promise.allSettled(this.pendingUploads)).filter(i=>i.status==="rejected").length,n=new Date,s={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"),s}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 Fe{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(!Fe.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}=zr(e.length),s=this.width/t,i=this.height/n;e.forEach((o,a)=>{const c=a%t,h=Math.floor(a/t),l=c*s,d=h*i;this.ctx.fillStyle="#1a1a1a",this.ctx.fillRect(l,d,s,i);const u=o.videoEl.videoWidth||0,p=o.videoEl.videoHeight||0,m=o.videoTrack,_=m&&m.enabled&&m.readyState==="live";if(u>0&&p>0&&_!==!1){const pn=Math.min(s/u,i/p),gn=u*pn,mn=p*pn,Xr=l+(s-gn)/2,Zr=d+(i-mn)/2;try{this.ctx.drawImage(o.videoEl,Xr,Zr,gn,mn)}catch{}}else Nr(this.ctx,o.label||"Peer",l,d,s,i);const ln=o.label||"Peer";this.ctx.font="bold 16px system-ui, sans-serif";const Yr=this.ctx.measureText(ln),dn=10,Gr=6,Qr=Yr.width+dn*2,Ke=24,un=l+12,fn=d+i-Ke-12;this.ctx.fillStyle="rgba(0,0,0,0.65)",this.ctx.fillRect(un,fn,Qr,Ke),this.ctx.fillStyle="#fff",this.ctx.fillText(ln,un+dn,fn+Ke-Gr-2)})}addStream(e,t,n={}){if(!this.running)return;this.videos.has(e)&&this.removeStream(e);const s=document.createElement("video");s.srcObject=t,s.autoplay=!0,s.muted=!0,s.playsInline=!0,s.style.cssText="position:absolute;left:-9999px;top:-9999px;",document.body.appendChild(s),s.play().catch(()=>{});const i=t.getVideoTracks()[0]||null;this.videos.set(e,{videoEl:s,videoTrack:i,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 Br(r){const e=String(r).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 Ur(r){let e=0;const t=String(r);for(let s=0;s<t.length;s++)e=e*31+t.charCodeAt(s)>>>0;return`hsl(${e%360}, 45%, 40%)`}function Nr(r,e,t,n,s,i){const o=t+s/2,a=n+i/2,c=Math.min(s,i)*.22;r.fillStyle=Ur(e),r.beginPath(),r.arc(o,a,c,0,Math.PI*2),r.fill(),r.fillStyle="#fff",r.font=`600 ${Math.floor(c)}px system-ui, sans-serif`,r.textAlign="center",r.textBaseline="middle",r.fillText(Br(e),o,a+1),r.textAlign="start",r.textBaseline="alphabetic"}function zr(r){if(r<=1)return{cols:1,rows:1};if(r===2)return{cols:2,rows:1};if(r<=4)return{cols:2,rows:2};if(r<=6)return{cols:3,rows:2};if(r<=9)return{cols:3,rows:3};const e=4;return{cols:e,rows:Math.ceil(r/e)}}function Fr(r,e){return r.includes("pdf")||/\.pdf$/i.test(e)?"📕":r.includes("word")||/\.docx?$/i.test(e)?"📘":r.includes("sheet")||r.includes("excel")||/\.(xlsx?|csv)$/i.test(e)?"📗":r.startsWith("text/")?"📄":"📎"}class jr{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={}}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.render()}render(){const e=this.recording==="manual"?'<button id="toggle-record" style="padding: 10px 20px; background-color: #7a3a3a; border: none; border-radius: 6px; color: white; cursor: pointer; font-size: 14px;">● Record</button>':"",t=this.recording!=="off"?'<button id="toggle-pause" style="display:none; padding: 10px 20px; background-color: #3a5a7a; border: none; border-radius: 6px; color: white; cursor: pointer; font-size: 14px;">⏸ Pause</button>':"",n=this.screenShare?'<button id="toggle-screenshare" style="padding: 10px 20px; background-color: #3a5a7a; border: none; border-radius: 6px; color: white; cursor: pointer; font-size: 14px;">Share Screen</button>':"",s=this.recording!=="off"?'<span id="recording-indicator" style="display:none; margin-left: 12px; color: #ff5252; font-size: 13px; font-weight: 600;"><span id="rec-dot" style="display:inline-block; width:8px; height:8px; background:#ff5252; border-radius:50%; margin-right:6px; animation: recPulse 1.2s ease-in-out infinite;"></span>REC <span id="rec-elapsed">00:00</span></span>':"",i=this.recording!=="off"?'<span id="queue-indicator" style="display:none; margin-left: 12px; color: #fbbf24; font-size: 12px;">⏳ <span id="queue-count">0</span> uploading</span>':"";this._panelWiredOnRender=!0,this.container.innerHTML=`
|
|
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}},wn=r=>!r||/^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/.test(r),$t=()=>Math.random().toString(36).slice(2),Bt={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 Mn extends Lt{noop(){}blobToArrayBuffer(e,t){const n=new FileReader;return n.onload=function(s){s.target&&t(s.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=Bt,this.browser=z.getBrowser(),this.browserVersion=z.getVersion(),this.pack=We,this.unpack=Je,this.supports=function(){const t={browser:z.isBrowserSupported(),webRTC:z.isWebRTCSupported(),audioVideo:!1,data:!1,binaryBlob:!1,reliable:!1};if(!t.webRTC)return t;let n;try{n=new RTCPeerConnection(Bt),t.audioVideo=!0;let s;try{s=n.createDataChannel("_PEERJSTEST",{ordered:!0}),t.data=!0,t.reliable=!!s.ordered;try{s.binaryType="blob",t.binaryBlob=!z.isIOS}catch{}}catch{}finally{s&&s.close()}}catch{}finally{n&&n.close()}return t}(),this.validateId=wn,this.randomToken=$t}}const k=new Mn,An="PeerJS: ";class On{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=[An,...t];for(const s in n)n[s]instanceof Error&&(n[s]="("+n[s].name+") "+n[s].message);e>=3?console.log(...n):e>=2?console.warn("WARNING",...n):e>=1&&console.error("ERROR",...n)}constructor(){this._logLevel=0}}var f=new On,ve={},In=Object.prototype.hasOwnProperty,C="~";function F(){}Object.create&&(F.prototype=Object.create(null),new F().__proto__||(C=!1));function Dn(r,e,t){this.fn=r,this.context=e,this.once=t||!1}function Ut(r,e,t,n,s){if(typeof t!="function")throw new TypeError("The listener must be a function");var i=new Dn(t,n||r,s),o=C?C+e:e;return r._events[o]?r._events[o].fn?r._events[o]=[r._events[o],i]:r._events[o].push(i):(r._events[o]=i,r._eventsCount++),r}function X(r,e){--r._eventsCount===0?r._events=new F:delete r._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)In.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 s=0,i=n.length,o=new Array(i);s<i;s++)o[s]=n[s].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,s,i,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,s),!0;case 5:return c.fn.call(c.context,t,n,s,i),!0;case 6:return c.fn.call(c.context,t,n,s,i,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,p;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,s);break;default:if(!l)for(p=1,l=new Array(h-1);p<h;p++)l[p-1]=arguments[p];c[d].fn.apply(c[d].context,l)}}return!0},v.prototype.on=function(e,t,n){return Ut(this,e,t,n,!1)},v.prototype.once=function(e,t,n){return Ut(this,e,t,n,!0)},v.prototype.removeListener=function(e,t,n,s){var i=C?C+e:e;if(!this._events[i])return this;if(!t)return X(this,i),this;var o=this._events[i];if(o.fn)o.fn===t&&(!s||o.once)&&(!n||o.context===n)&&X(this,i);else{for(var a=0,c=[],h=o.length;a<h;a++)(o[a].fn!==t||s&&!o[a].once||n&&o[a].context!==n)&&c.push(o[a]);c.length?this._events[i]=c.length===1?c[0]:c:X(this,i)}return this},v.prototype.removeAllListeners=function(e){var t;return e?(t=C?C+e:e,this._events[t]&&X(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,ve=v;var L={};D(L,"ConnectionType",()=>M),D(L,"PeerErrorType",()=>y),D(L,"BaseConnectionErrorType",()=>Se),D(L,"DataConnectionErrorType",()=>Ce),D(L,"SerializationType",()=>Z),D(L,"SocketEventType",()=>A),D(L,"ServerMessageType",()=>S);var M=function(r){return r.Data="data",r.Media="media",r}({}),y=function(r){return r.BrowserIncompatible="browser-incompatible",r.Disconnected="disconnected",r.InvalidID="invalid-id",r.InvalidKey="invalid-key",r.Network="network",r.PeerUnavailable="peer-unavailable",r.SslUnavailable="ssl-unavailable",r.ServerError="server-error",r.SocketError="socket-error",r.SocketClosed="socket-closed",r.UnavailableID="unavailable-id",r.WebRTC="webrtc",r}({}),Se=function(r){return r.NegotiationFailed="negotiation-failed",r.ConnectionClosed="connection-closed",r}({}),Ce=function(r){return r.NotOpenYet="not-open-yet",r.MessageToBig="message-too-big",r}({}),Z=function(r){return r.Binary="binary",r.BinaryUTF8="binary-utf8",r.JSON="json",r.None="raw",r}({}),A=function(r){return r.Message="message",r.Disconnected="disconnected",r.Error="error",r.Close="close",r}({}),S=function(r){return r.Heartbeat="HEARTBEAT",r.Candidate="CANDIDATE",r.Offer="OFFER",r.Answer="ANSWER",r.Open="OPEN",r.Error="ERROR",r.IdTaken="ID-TAKEN",r.InvalidKey="INVALID-KEY",r.Leave="LEAVE",r.Expire="EXPIRE",r}({});const Nt="1.5.5";class Ln extends ve.EventEmitter{constructor(e,t,n,s,i,o=5e3){super(),this.pingInterval=o,this._disconnected=!0,this._messagesQueue=[];const a=e?"wss://":"ws://";this._baseUrl=a+t+":"+n+s+"peerjs?key="+i}start(e,t){this._id=e;const n=`${this._baseUrl}&id=${e}&token=${t}`;this._socket||!this._disconnected||(this._socket=new WebSocket(n+"&version="+Nt),this._disconnected=!1,this._socket.onmessage=s=>{let i;try{i=JSON.parse(s.data),f.log("Server message received:",i)}catch{f.log("Invalid server message",s.data);return}this.emit(A.Message,i)},this._socket.onclose=s=>{this._disconnected||(f.log("Socket closed.",s),this._cleanup(),this._disconnected=!0,this.emit(A.Disconnected))},this._socket.onopen=()=>{this._disconnected||(this._sendQueuedMessages(),f.log("Socket open"),this._scheduleHeartbeat())})}_scheduleHeartbeat(){this._wsPingTimer=setTimeout(()=>{this._sendHeartbeat()},this.pingInterval)}_sendHeartbeat(){if(!this._wsOpen()){f.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 zt{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,s={ordered:!!e.reliable},i=t.createDataChannel(n.label,s);n._initializeDataChannel(i),this._makeOffer()}else this.handleSDP("OFFER",e.sdp)}_startPeerConnection(){f.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,s=this.connection.type,i=this.connection.provider;f.log("Listening for ICE candidates."),e.onicecandidate=o=>{!o.candidate||!o.candidate.candidate||(f.log(`Received ICE candidates for ${t}:`,o.candidate),i.socket.send({type:S.Candidate,payload:{candidate:o.candidate,type:s,connectionId:n},dst:t}))},e.oniceconnectionstatechange=()=>{switch(e.iceConnectionState){case"failed":f.log("iceConnectionState is failed, closing connections to "+t),this.connection.emitError(Se.NegotiationFailed,"Negotiation of connection to "+t+" failed."),this.connection.close();break;case"closed":f.log("iceConnectionState is closed, closing connections to "+t),this.connection.emitError(Se.ConnectionClosed,"Connection to "+t+" closed."),this.connection.close();break;case"disconnected":f.log("iceConnectionState changed to disconnected on the connection with "+t);break;case"completed":e.onicecandidate=()=>{};break}this.connection.emit("iceStateChanged",e.iceConnectionState)},f.log("Listening for data channel"),e.ondatachannel=o=>{f.log("Received data channel");const a=o.channel;i.getConnection(t,n)._initializeDataChannel(a)},f.log("Listening for remote stream"),e.ontrack=o=>{f.log("Received remote stream");const a=o.streams[0],c=i.getConnection(t,n);if(c.type===M.Media){const h=c;this._addStreamToMediaConnection(a,h)}}}cleanup(){f.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 s=this.connection.dataChannel;s&&(n=!!s.readyState&&s.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);f.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),f.log("Set localDescription:",n,`for:${this.connection.peer}`);let s={sdp:n,type:this.connection.type,connectionId:this.connection.connectionId,metadata:this.connection.metadata};if(this.connection.type===M.Data){const i=this.connection;s={...s,label:i.label,reliable:i.reliable,serialization:i.serialization}}t.socket.send({type:S.Offer,payload:s,dst:this.connection.peer})}catch(s){s!="OperationError: Failed to set local offer sdp: Called in wrong state: kHaveRemoteOffer"&&(t.emitError(y.WebRTC,s),f.log("Failed to setLocalDescription, ",s))}}catch(n){t.emitError(y.WebRTC,n),f.log("Failed to createOffer, ",n)}}async _makeAnswer(){const e=this.connection.peerConnection,t=this.connection.provider;try{const n=await e.createAnswer();f.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),f.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(s){t.emitError(y.WebRTC,s),f.log("Failed to setLocalDescription, ",s)}}catch(n){t.emitError(y.WebRTC,n),f.log("Failed to create answer, ",n)}}async handleSDP(e,t){t=new RTCSessionDescription(t);const n=this.connection.peerConnection,s=this.connection.provider;f.log("Setting remote description",t);const i=this;try{await n.setRemoteDescription(t),f.log(`Set remoteDescription:${e} for:${this.connection.peer}`),e==="OFFER"&&await i._makeAnswer()}catch(o){s.emitError(y.WebRTC,o),f.log("Failed to setRemoteDescription, ",o)}}async handleCandidate(e){f.log("handleCandidate:",e);try{await this.connection.peerConnection.addIceCandidate(e),f.log(`Added ICE candidate for:${this.connection.peer}`)}catch(t){this.connection.provider.emitError(y.WebRTC,t),f.log("Failed to handleCandidate, ",t)}}_addTracksToConnection(e,t){if(f.log(`add tracks from stream ${e.id} to peer connection`),!t.addTrack)return f.error("Your browser does't support RTCPeerConnection#addTrack. Ignored.");e.getTracks().forEach(n=>{t.addTrack(n,e)})}_addStreamToMediaConnection(e,t){f.log(`add stream ${e.id} to media connection ${t.connectionId}`),t.addStream(e)}}class Ft extends ve.EventEmitter{emitError(e,t){f.error("Error:",t),this.emit("error",new $n(`${e}`,t))}}class $n extends Error{constructor(e,t){typeof t=="string"?super(t):(super(),Object.assign(this,t)),this.type=e}}class jt extends Ft{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 V=class V extends jt{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||V.ID_PREFIX+k.randomToken(),this._negotiator=new zt(this),this._localStream&&this._negotiator.startConnection({_stream:this._localStream,originator:!0})}_initializeDataChannel(e){this.dataChannel=e,this.dataChannel.onopen=()=>{f.log(`DC#${this.connectionId} dc connection success`),this.emit("willCloseOnRemote")},this.dataChannel.onclose=()=>{f.log(`DC#${this.connectionId} dc closed for:`,this.peer),this.close()}}addStream(e){f.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:f.warn(`Unrecognized message type:${t} from peer:${this.peer}`);break}}answer(e,t={}){if(this._localStream){f.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 s of n)this.handleMessage(s);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"))}};je=new WeakMap,K(V,je,V.ID_PREFIX="mc_");let ee=V;class Bn{constructor(e){this._options=e}_buildRequest(e){const t=this._options.secure?"https":"http",{host:n,port:s,path:i,key:o}=this._options,a=new URL(`${t}://${n}:${s}${i}${o}/${e}`);return a.searchParams.set("ts",`${Date.now()}${Math.random()}`),a.searchParams.set("version",Nt),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){f.error("Error retrieving ID",e);let t="";throw this._options.path==="/"&&this._options.host!==k.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===k.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 f.error("Error retrieving list peers",e),new Error("Could not get list peers from the server."+e)}}}const $=class $ extends jt{get type(){return M.Data}constructor(e,t,n){super(e,t,n),this.connectionId=this.options.connectionId||$.ID_PREFIX+$t(),this.label=this.options.label||this.connectionId,this.reliable=!!this.options.reliable,this._negotiator=new zt(this),this._negotiator.startConnection(this.options._payload||{originator:!0,reliable:this.reliable})}_initializeDataChannel(e){this.dataChannel=e,this.dataChannel.onopen=()=>{f.log(`DC#${this.connectionId} dc connection success`),this._open=!0,this.emit("open")},this.dataChannel.onmessage=t=>{f.log(`DC#${this.connectionId} dc onmessage:`,t.data)},this.dataChannel.onclose=()=>{f.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(Ce.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:f.warn("Unrecognized message type:",e.type,"from peer:",this.peer);break}}};qe=new WeakMap,Ve=new WeakMap,K($,qe,$.ID_PREFIX="dc_"),K($,Ve,$.MAX_BUFFERED_AMOUNT=8388608);let te=$;class ke extends te{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>te.MAX_BUFFERED_AMOUNT)return this._buffering=!0,setTimeout(()=>{this._buffering=!1,this._tryBuffer()},50),!1;try{this.dataChannel.send(e)}catch(t){return f.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 xe extends ke{close(e){super.close(e),this._chunkedData={}}constructor(e,t,n){super(e,t,n),this.chunker=new Lt,this.serialization=Z.Binary,this._chunkedData={}}_handleDataMessage({data:e}){const t=Je(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 s=En(n.data);this._handleDataMessage({data:s})}}_send(e,t){const n=We(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);f.log(`DC#${this.connectionId} Try to send ${t.length} chunks...`);for(const n of t)this.send(n,!0)}}class Un extends ke{_handleDataMessage({data:e}){super.emit("data",e)}_send(e,t){this._bufferedSend(e)}constructor(...e){super(...e),this.serialization=Z.None}}class Nn extends ke{_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>=k.chunkedMTU){this.emitError(Ce.MessageToBig,"Message too big for JSON channel");return}this._bufferedSend(n)}constructor(...e){super(...e),this.serialization=Z.JSON,this.encoder=new TextEncoder,this.decoder=new TextDecoder,this.stringify=JSON.stringify,this.parse=JSON.parse}}const H=class H extends Ft{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:Un,json:Nn,binary:xe,"binary-utf8":xe,default:xe},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:k.CLOUD_HOST,port:k.CLOUD_PORT,path:"/",key:H.DEFAULT_KEY,token:k.randomToken(),config:k.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!==k.CLOUD_HOST?this._options.secure=k.isSecure():this._options.host==k.CLOUD_HOST&&(this._options.secure=!0),this._options.logFunction&&f.setLogFunction(this._options.logFunction),f.logLevel=this._options.debug||0,this._api=new Bn(t),this._socket=this._createServerConnection(),!k.supports.audioVideo&&!k.supports.data){this._delayedAbort(y.BrowserIncompatible,"The current browser does not support WebRTC");return}if(n&&!k.validateId(n)){this._delayedAbort(y.InvalidID,`ID "${n}" is invalid`);return}n?this._initialize(n):this._api.retrieveId().then(s=>this._initialize(s)).catch(s=>this._abort(y.ServerError,s))}_createServerConnection(){const e=new Ln(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,s=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:f.log(`Received leave message from ${s}`),this._cleanupPeer(s),this._connections.delete(s);break;case S.Expire:this.emitError(y.PeerUnavailable,`Could not connect to peer ${s}`);break;case S.Offer:{const i=n.connectionId;let o=this.getConnection(s,i);if(o&&(o.close(),f.warn(`Offer received for existing Connection ID:${i}`)),n.type===M.Media){const c=new ee(s,this,{connectionId:i,_payload:n,metadata:n.metadata});o=c,this._addConnection(s,o),this.emit("call",c)}else if(n.type===M.Data){const c=new this._serializers[n.serialization](s,this,{connectionId:i,_payload:n,metadata:n.metadata,label:n.label,serialization:n.serialization,reliable:n.reliable});o=c,this._addConnection(s,o),this.emit("connection",c)}else{f.warn(`Received malformed connection type:${n.type}`);return}const a=this._getMessages(i);for(const c of a)o.handleMessage(c);break}default:{if(!n){f.warn(`You received a malformed message from ${s} of type ${t}`);return}const i=n.connectionId,o=this.getConnection(s,i);o&&o.peerConnection?o.handleMessage(e):i?this._storeMessage(i,e):f.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){f.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){f.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){f.error("To call a peer, you must provide a stream from your browser's `getUserMedia`.");return}const s=new ee(e,this,{...n,_stream:t});return this._addConnection(e,s),s}_addConnection(e,t){f.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 s of n)if(s.connectionId===t)return s;return null}_delayedAbort(e,t){setTimeout(()=>{this._abort(e,t)},0)}_abort(e,t){f.error("Aborting!"),this.emitError(e,t),this._lastServerId?this.disconnect():this.destroy()}destroy(){this.destroyed||(f.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;f.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)f.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)f.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))}};He=new WeakMap,K(H,He,H.DEFAULT_KEY="peerjs");let Te=H;var zn=Te;class Fn{constructor(e){this.config=e,this.peer=null,this.localStream=null,this.connections={},this.callbacks={onStream:null,onPeerLeft:null,onError: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,s)=>{const i=t===0?e:`${e}-r${Math.random().toString(36).slice(2,6)}`;this.peer=new zn(i,{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 "${i}" 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){s(c)}return}console.error("Peer error:",a),this.callbacks.onError&&this.callbacks.onError(a),o||s(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",s=>{console.log("Received stream from:",e),this.connections[e]={call:n,stream:s},this.callbacks.onStream&&this.callbacks.onStream(e,s,!1)}),n.on("close",()=>{console.log("Call closed:",e),delete this.connections[e],this.callbacks.onPeerLeft&&this.callbacks.onPeerLeft(e)}),n.on("error",s=>{console.error("Call error:",s),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 s=n.getSenders().find(i=>i.track&&i.track.kind==="video");s&&s.replaceTrack(e).catch(i=>console.warn("replaceTrack failed:",i&&i.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",()=>this.stopScreenShare().catch(()=>{})),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 E=Object.create(null);E.open="0",E.close="1",E.ping="2",E.pong="3",E.message="4",E.upgrade="5",E.noop="6";const ne=Object.create(null);Object.keys(E).forEach(r=>{ne[E[r]]=r});const Re={type:"error",data:"parser error"},qt=typeof Blob=="function"||typeof Blob<"u"&&Object.prototype.toString.call(Blob)==="[object BlobConstructor]",Vt=typeof ArrayBuffer=="function",Ht=r=>typeof ArrayBuffer.isView=="function"?ArrayBuffer.isView(r):r&&r.buffer instanceof ArrayBuffer,Pe=({type:r,data:e},t,n)=>qt&&e instanceof Blob?t?n(e):Kt(e,n):Vt&&(e instanceof ArrayBuffer||Ht(e))?t?n(e):Kt(new Blob([e]),n):n(E[r]+(e||"")),Kt=(r,e)=>{const t=new FileReader;return t.onload=function(){const n=t.result.split(",")[1];e("b"+(n||""))},t.readAsDataURL(r)};function Jt(r){return r instanceof Uint8Array?r:r instanceof ArrayBuffer?new Uint8Array(r):new Uint8Array(r.buffer,r.byteOffset,r.byteLength)}let Ee;function jn(r,e){if(qt&&r.data instanceof Blob)return r.data.arrayBuffer().then(Jt).then(e);if(Vt&&(r.data instanceof ArrayBuffer||Ht(r.data)))return e(Jt(r.data));Pe(r,!1,t=>{Ee||(Ee=new TextEncoder),e(Ee.encode(t))})}const Wt="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",j=typeof Uint8Array>"u"?[]:new Uint8Array(256);for(let r=0;r<Wt.length;r++)j[Wt.charCodeAt(r)]=r;const qn=r=>{let e=r.length*.75,t=r.length,n,s=0,i,o,a,c;r[r.length-1]==="="&&(e--,r[r.length-2]==="="&&e--);const h=new ArrayBuffer(e),l=new Uint8Array(h);for(n=0;n<t;n+=4)i=j[r.charCodeAt(n)],o=j[r.charCodeAt(n+1)],a=j[r.charCodeAt(n+2)],c=j[r.charCodeAt(n+3)],l[s++]=i<<2|o>>4,l[s++]=(o&15)<<4|a>>2,l[s++]=(a&3)<<6|c&63;return h},Vn=typeof ArrayBuffer=="function",we=(r,e)=>{if(typeof r!="string")return{type:"message",data:Yt(r,e)};const t=r.charAt(0);return t==="b"?{type:"message",data:Hn(r.substring(1),e)}:ne[t]?r.length>1?{type:ne[t],data:r.substring(1)}:{type:ne[t]}:Re},Hn=(r,e)=>{if(Vn){const t=qn(r);return Yt(t,e)}else return{base64:!0,data:r}},Yt=(r,e)=>{switch(e){case"blob":return r instanceof Blob?r:new Blob([r]);case"arraybuffer":default:return r instanceof ArrayBuffer?r:r.buffer}},Gt="",Kn=(r,e)=>{const t=r.length,n=new Array(t);let s=0;r.forEach((i,o)=>{Pe(i,!1,a=>{n[o]=a,++s===t&&e(n.join(Gt))})})},Jn=(r,e)=>{const t=r.split(Gt),n=[];for(let s=0;s<t.length;s++){const i=we(t[s],e);if(n.push(i),i.type==="error")break}return n};function Wn(){return new TransformStream({transform(r,e){jn(r,t=>{const n=t.length;let s;if(n<126)s=new Uint8Array(1),new DataView(s.buffer).setUint8(0,n);else if(n<65536){s=new Uint8Array(3);const i=new DataView(s.buffer);i.setUint8(0,126),i.setUint16(1,n)}else{s=new Uint8Array(9);const i=new DataView(s.buffer);i.setUint8(0,127),i.setBigUint64(1,BigInt(n))}r.data&&typeof r.data!="string"&&(s[0]|=128),e.enqueue(s),e.enqueue(t)})}})}let Me;function re(r){return r.reduce((e,t)=>e+t.length,0)}function se(r,e){if(r[0].length===e)return r.shift();const t=new Uint8Array(e);let n=0;for(let s=0;s<e;s++)t[s]=r[0][n++],n===r[0].length&&(r.shift(),n=0);return r.length&&n<r[0].length&&(r[0]=r[0].slice(n)),t}function Yn(r,e){Me||(Me=new TextDecoder);const t=[];let n=0,s=-1,i=!1;return new TransformStream({transform(o,a){for(t.push(o);;){if(n===0){if(re(t)<1)break;const c=se(t,1);i=(c[0]&128)===128,s=c[0]&127,s<126?n=3:s===126?n=1:n=2}else if(n===1){if(re(t)<2)break;const c=se(t,2);s=new DataView(c.buffer,c.byteOffset,c.length).getUint16(0),n=3}else if(n===2){if(re(t)<8)break;const c=se(t,8),h=new DataView(c.buffer,c.byteOffset,c.length),l=h.getUint32(0);if(l>Math.pow(2,21)-1){a.enqueue(Re);break}s=l*Math.pow(2,32)+h.getUint32(4),n=3}else{if(re(t)<s)break;const c=se(t,s);a.enqueue(we(i?c:Me.decode(c),e)),n=0}if(s===0||s>r){a.enqueue(Re);break}}}})}const Qt=4;function b(r){if(r)return Gn(r)}function Gn(r){for(var e in b.prototype)r[e]=b.prototype[e];return r}b.prototype.on=b.prototype.addEventListener=function(r,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+r]=this._callbacks["$"+r]||[]).push(e),this},b.prototype.once=function(r,e){function t(){this.off(r,t),e.apply(this,arguments)}return t.fn=e,this.on(r,t),this},b.prototype.off=b.prototype.removeListener=b.prototype.removeAllListeners=b.prototype.removeEventListener=function(r,e){if(this._callbacks=this._callbacks||{},arguments.length==0)return this._callbacks={},this;var t=this._callbacks["$"+r];if(!t)return this;if(arguments.length==1)return delete this._callbacks["$"+r],this;for(var n,s=0;s<t.length;s++)if(n=t[s],n===e||n.fn===e){t.splice(s,1);break}return t.length===0&&delete this._callbacks["$"+r],this},b.prototype.emit=function(r){this._callbacks=this._callbacks||{};for(var e=new Array(arguments.length-1),t=this._callbacks["$"+r],n=1;n<arguments.length;n++)e[n-1]=arguments[n];if(t){t=t.slice(0);for(var n=0,s=t.length;n<s;++n)t[n].apply(this,e)}return this},b.prototype.emitReserved=b.prototype.emit,b.prototype.listeners=function(r){return this._callbacks=this._callbacks||{},this._callbacks["$"+r]||[]},b.prototype.hasListeners=function(r){return!!this.listeners(r).length};const ie=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")(),Qn="arraybuffer";function ts(){}function Xt(r,...e){return e.reduce((t,n)=>(r.hasOwnProperty(n)&&(t[n]=r[n]),t),{})}const Xn=T.setTimeout,Zn=T.clearTimeout;function oe(r,e){e.useNativeTimers?(r.setTimeoutFn=Xn.bind(T),r.clearTimeoutFn=Zn.bind(T)):(r.setTimeoutFn=T.setTimeout.bind(T),r.clearTimeoutFn=T.clearTimeout.bind(T))}const er=1.33;function tr(r){return typeof r=="string"?nr(r):Math.ceil((r.byteLength||r.size)*er)}function nr(r){let e=0,t=0;for(let n=0,s=r.length;n<s;n++)e=r.charCodeAt(n),e<128?t+=1:e<2048?t+=2:e<55296||e>=57344?t+=3:(n++,t+=4);return t}function Zt(){return Date.now().toString(36).substring(3)+Math.random().toString(36).substring(2,5)}function rr(r){let e="";for(let t in r)r.hasOwnProperty(t)&&(e.length&&(e+="&"),e+=encodeURIComponent(t)+"="+encodeURIComponent(r[t]));return e}function sr(r){let e={},t=r.split("&");for(let n=0,s=t.length;n<s;n++){let i=t[n].split("=");e[decodeURIComponent(i[0])]=decodeURIComponent(i[1])}return e}class ir extends Error{constructor(e,t,n){super(e),this.description=t,this.context=n,this.type="TransportError"}}class Ae extends b{constructor(e){super(),this.writable=!1,oe(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 ir(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=we(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=rr(e);return t.length?"?"+t:""}}class or extends Ae{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)};Jn(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,Kn(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]=Zt()),!this.supportsBinary&&!t.sid&&(t.b64=1),this.createUri(e,t)}}let en=!1;try{en=typeof XMLHttpRequest<"u"&&"withCredentials"in new XMLHttpRequest}catch{}const ar=en;function cr(){}class hr extends or{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",(s,i)=>{this.onError("xhr post error",s,i)})}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 w extends b{constructor(e,t,n){super(),this.createRequest=e,oe(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=Xt(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 s in this._opts.extraHeaders)this._opts.extraHeaders.hasOwnProperty(s)&&n.setRequestHeader(s,this._opts.extraHeaders[s])}}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 s;n.readyState===3&&((s=this._opts.cookieJar)===null||s===void 0||s.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(s){this.setTimeoutFn(()=>{this._onError(s)},0);return}typeof document<"u"&&(this._index=w.requestsCount++,w.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=cr,e)try{this._xhr.abort()}catch{}typeof document<"u"&&delete w.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(w.requestsCount=0,w.requests={},typeof document<"u"){if(typeof attachEvent=="function")attachEvent("onunload",tn);else if(typeof addEventListener=="function"){const r="onpagehide"in T?"pagehide":"unload";addEventListener(r,tn,!1)}}function tn(){for(let r in w.requests)w.requests.hasOwnProperty(r)&&w.requests[r].abort()}const lr=function(){const r=nn({xdomain:!1});return r&&r.responseType!==null}();class dr extends hr{constructor(e){super(e);const t=e&&e.forceBase64;this.supportsBinary=lr&&!t}request(e={}){return Object.assign(e,{xd:this.xd},this.opts),new w(nn,this.uri(),e)}}function nn(r){const e=r.xdomain;try{if(typeof XMLHttpRequest<"u"&&(!e||ar))return new XMLHttpRequest}catch{}if(!e)try{return new T[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP")}catch{}}const rn=typeof navigator<"u"&&typeof navigator.product=="string"&&navigator.product.toLowerCase()==="reactnative";class ur extends Ae{get name(){return"websocket"}doOpen(){const e=this.uri(),t=this.opts.protocols,n=rn?{}:Xt(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(s){return this.emitReserved("error",s)}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],s=t===e.length-1;Pe(n,this.supportsBinary,i=>{try{this.doWrite(n,i)}catch{}s&&ie(()=>{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]=Zt()),this.supportsBinary||(t.b64=1),this.createUri(e,t)}}const Oe=T.WebSocket||T.MozWebSocket;class fr extends ur{createSocket(e,t,n){return rn?new Oe(e,t,n):t?new Oe(e,t):new Oe(e)}doWrite(e,t){this.ws.send(t)}}class pr extends Ae{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=Yn(Number.MAX_SAFE_INTEGER,this.socket.binaryType),n=e.readable.pipeThrough(t).getReader(),s=Wn();s.readable.pipeTo(e.writable),this._writer=s.writable.getWriter();const i=()=>{n.read().then(({done:a,value:c})=>{a||(this.onPacket(c),i())}).catch(a=>{})};i();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],s=t===e.length-1;this._writer.write(n).then(()=>{s&&ie(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){var e;(e=this._transport)===null||e===void 0||e.close()}}const gr={websocket:fr,webtransport:pr,polling:dr},mr=/^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,yr=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];function Ie(r){if(r.length>8e3)throw"URI too long";const e=r,t=r.indexOf("["),n=r.indexOf("]");t!=-1&&n!=-1&&(r=r.substring(0,t)+r.substring(t,n).replace(/:/g,";")+r.substring(n,r.length));let s=mr.exec(r||""),i={},o=14;for(;o--;)i[yr[o]]=s[o]||"";return t!=-1&&n!=-1&&(i.source=e,i.host=i.host.substring(1,i.host.length-1).replace(/;/g,":"),i.authority=i.authority.replace("[","").replace("]","").replace(/;/g,":"),i.ipv6uri=!0),i.pathNames=br(i,i.path),i.queryKey=_r(i,i.query),i}function br(r,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 _r(r,e){const t={};return e.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,function(n,s,i){s&&(t[s]=i)}),t}const De=typeof addEventListener=="function"&&typeof removeEventListener=="function",ae=[];De&&addEventListener("offline",()=>{ae.forEach(r=>r())},!1);class O extends b{constructor(e,t){if(super(),this.binaryType=Qn,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=Ie(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=Ie(t.host).host);oe(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 s=n.prototype.name;this.transports.push(s),this._transportsByName[s]=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=sr(this.opts.query)),De&&(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"})},ae.push(this._offlineEventListener))),this.opts.withCredentials&&(this._cookieJar=void 0),this._open()}createTransport(e){const t=Object.assign({},this.opts.query);t.EIO=Qt,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&&O.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",O.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 s=this.writeBuffer[n].data;if(s&&(t+=tr(s)),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,ie(()=>{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,s){if(typeof t=="function"&&(s=t,t=void 0),typeof n=="function"&&(s=n,n=null),this.readyState==="closing"||this.readyState==="closed")return;n=n||{},n.compress=n.compress!==!1;const i={type:e,data:t,options:n};this.emitReserved("packetCreate",i),this.writeBuffer.push(i),s&&this.once("flush",s),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(O.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(),De&&(this._beforeunloadEventListener&&removeEventListener("beforeunload",this._beforeunloadEventListener,!1),this._offlineEventListener)){const n=ae.indexOf(this._offlineEventListener);n!==-1&&ae.splice(n,1)}this.readyState="closed",this.id=null,this.emitReserved("close",e,t),this.writeBuffer=[],this._prevBufferLen=0}}}O.protocol=Qt;class vr extends O{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;O.priorWebsocketSuccess=!1;const s=()=>{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;O.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 i(){n||(n=!0,l(),t.close(),t=null)}const o=d=>{const u=new Error("probe error: "+d);u.transport=t.name,i(),this.emitReserved("upgradeError",u)};function a(){o("transport closed")}function c(){o("socket closed")}function h(d){t&&d.name!==t.name&&i()}const l=()=>{t.removeListener("open",s),t.removeListener("error",o),t.removeListener("close",a),this.off("close",c),this.off("upgrading",h)};t.once("open",s),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 Sr=class extends vr{constructor(e,t={}){const n=typeof e=="object",s=n?{...e}:{...t};(!s.transports||s.transports&&typeof s.transports[0]=="string")&&(s.transports=(s.transports||["polling","websocket","webtransport"]).map(i=>gr[i]).filter(i=>!!i)),super(n?s:e,s)}};function Cr(r,e="",t){let n=r;t=t||typeof location<"u"&&location,r==null&&(r=t.protocol+"//"+t.host),typeof r=="string"&&(r.charAt(0)==="/"&&(r.charAt(1)==="/"?r=t.protocol+r:r=t.host+r),/^(https?|wss?):\/\//.test(r)||(typeof t<"u"?r=t.protocol+"//"+r:r="https://"+r),n=Ie(r)),n.port||(/^(http|ws)$/.test(n.protocol)?n.port="80":/^(http|ws)s$/.test(n.protocol)&&(n.port="443")),n.path=n.path||"/";const i=n.host.indexOf(":")!==-1?"["+n.host+"]":n.host;return n.id=n.protocol+"://"+i+":"+n.port+e,n.href=n.protocol+"://"+i+(t&&t.port===n.port?"":":"+n.port),n}const kr=typeof ArrayBuffer=="function",xr=r=>typeof ArrayBuffer.isView=="function"?ArrayBuffer.isView(r):r.buffer instanceof ArrayBuffer,sn=Object.prototype.toString,Tr=typeof Blob=="function"||typeof Blob<"u"&&sn.call(Blob)==="[object BlobConstructor]",Rr=typeof File=="function"||typeof File<"u"&&sn.call(File)==="[object FileConstructor]";function Le(r){return kr&&(r instanceof ArrayBuffer||xr(r))||Tr&&r instanceof Blob||Rr&&r instanceof File}function ce(r,e){if(!r||typeof r!="object")return!1;if(Array.isArray(r)){for(let t=0,n=r.length;t<n;t++)if(ce(r[t]))return!0;return!1}if(Le(r))return!0;if(r.toJSON&&typeof r.toJSON=="function"&&arguments.length===1)return ce(r.toJSON(),!0);for(const t in r)if(Object.prototype.hasOwnProperty.call(r,t)&&ce(r[t]))return!0;return!1}function Pr(r){const e=[],t=r.data,n=r;return n.data=$e(t,e),n.attachments=e.length,{packet:n,buffers:e}}function $e(r,e){if(!r)return r;if(Le(r)){const t={_placeholder:!0,num:e.length};return e.push(r),t}else if(Array.isArray(r)){const t=new Array(r.length);for(let n=0;n<r.length;n++)t[n]=$e(r[n],e);return t}else if(typeof r=="object"&&!(r instanceof Date)){const t={};for(const n in r)Object.prototype.hasOwnProperty.call(r,n)&&(t[n]=$e(r[n],e));return t}return r}function Er(r,e){return r.data=Be(r.data,e),delete r.attachments,r}function Be(r,e){if(!r)return r;if(r&&r._placeholder===!0){if(typeof r.num=="number"&&r.num>=0&&r.num<e.length)return e[r.num];throw new Error("illegal attachments")}else if(Array.isArray(r))for(let t=0;t<r.length;t++)r[t]=Be(r[t],e);else if(typeof r=="object")for(const t in r)Object.prototype.hasOwnProperty.call(r,t)&&(r[t]=Be(r[t],e));return r}const wr=["connect","connect_error","disconnect","disconnecting","newListener","removeListener"];var g;(function(r){r[r.CONNECT=0]="CONNECT",r[r.DISCONNECT=1]="DISCONNECT",r[r.EVENT=2]="EVENT",r[r.ACK=3]="ACK",r[r.CONNECT_ERROR=4]="CONNECT_ERROR",r[r.BINARY_EVENT=5]="BINARY_EVENT",r[r.BINARY_ACK=6]="BINARY_ACK"})(g||(g={}));class Mr{constructor(e){this.replacer=e}encode(e){return(e.type===g.EVENT||e.type===g.ACK)&&ce(e)?this.encodeAsBinary({type:e.type===g.EVENT?g.BINARY_EVENT:g.BINARY_ACK,nsp:e.nsp,data:e.data,id:e.id}):[this.encodeAsString(e)]}encodeAsString(e){let t=""+e.type;return(e.type===g.BINARY_EVENT||e.type===g.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=Pr(e),n=this.encodeAsString(t.packet),s=t.buffers;return s.unshift(n),s}}class Ue 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===g.BINARY_EVENT;n||t.type===g.BINARY_ACK?(t.type=n?g.EVENT:g.ACK,this.reconstructor=new Ar(t),t.attachments===0&&super.emitReserved("decoded",t)):super.emitReserved("decoded",t)}else if(Le(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(g[n.type]===void 0)throw new Error("unknown packet type "+n.type);if(n.type===g.BINARY_EVENT||n.type===g.BINARY_ACK){const i=t+1;for(;e.charAt(++t)!=="-"&&t!=e.length;);const o=e.substring(i,t);if(o!=Number(o)||e.charAt(t)!=="-")throw new Error("Illegal attachments");const a=Number(o);if(!Or(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 i=t+1;for(;++t&&!(e.charAt(t)===","||t===e.length););n.nsp=e.substring(i,t)}else n.nsp="/";const s=e.charAt(t+1);if(s!==""&&Number(s)==s){const i=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(i,t+1))}if(e.charAt(++t)){const i=this.tryParse(e.substr(t));if(Ue.isPayloadValid(n.type,i))n.data=i;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 g.CONNECT:return on(t);case g.DISCONNECT:return t===void 0;case g.CONNECT_ERROR:return typeof t=="string"||on(t);case g.EVENT:case g.BINARY_EVENT:return Array.isArray(t)&&(typeof t[0]=="number"||typeof t[0]=="string"&&wr.indexOf(t[0])===-1);case g.ACK:case g.BINARY_ACK:return Array.isArray(t)}}destroy(){this.reconstructor&&(this.reconstructor.finishedReconstruction(),this.reconstructor=null)}}class Ar{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=Er(this.reconPack,this.buffers);return this.finishedReconstruction(),t}return null}finishedReconstruction(){this.reconPack=null,this.buffers=[]}}const Or=Number.isInteger||function(r){return typeof r=="number"&&isFinite(r)&&Math.floor(r)===r};function on(r){return Object.prototype.toString.call(r)==="[object Object]"}const Ir=Object.freeze(Object.defineProperty({__proto__:null,Decoder:Ue,Encoder:Mr,get PacketType(){return g}},Symbol.toStringTag,{value:"Module"}));function R(r,e,t){return r.on(e,t),function(){r.off(e,t)}}const Dr=Object.freeze({connect:1,connect_error:1,disconnect:1,disconnecting:1,newListener:1,removeListener:1});class an 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,s,i;if(Dr.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:g.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=(s=(n=this.io.engine)===null||n===void 0?void 0:n.transport)===null||s===void 0?void 0:s.writable,c=this.connected&&!(!((i=this.io.engine)===null||i===void 0)&&i._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 s=(n=this.flags.timeout)!==null&&n!==void 0?n:this._opts.ackTimeout;if(s===void 0){this.acks[e]=t;return}const i=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"))},s),o=(...a)=>{this.io.clearTimeoutFn(i),t.apply(this,a)};o.withError=!0,this.acks[e]=o}emitWithAck(e,...t){return new Promise((n,s)=>{const i=(o,a)=>o?s(o):n(a);i.withError=!0,t.push(i),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((s,...i)=>(this._queue[0],s!==null?n.tryCount>this._opts.retries&&(this._queue.shift(),t&&t(s)):(this._queue.shift(),t&&t(null,...i)),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:g.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 g.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 g.EVENT:case g.BINARY_EVENT:this.onevent(e);break;case g.ACK:case g.BINARY_ACK:this.onack(e);break;case g.DISCONNECT:this.ondisconnect();break;case g.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(...s){n||(n=!0,t.packet({type:g.ACK,id:e,data:s}))}}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:g.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 U(r){r=r||{},this.ms=r.min||100,this.max=r.max||1e4,this.factor=r.factor||2,this.jitter=r.jitter>0&&r.jitter<=1?r.jitter:0,this.attempts=0}U.prototype.duration=function(){var r=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),t=Math.floor(e*this.jitter*r);r=Math.floor(e*10)&1?r+t:r-t}return Math.min(r,this.max)|0},U.prototype.reset=function(){this.attempts=0},U.prototype.setMin=function(r){this.ms=r},U.prototype.setMax=function(r){this.max=r},U.prototype.setJitter=function(r){this.jitter=r};class Ne 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,oe(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 U({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()}),this.timeout(t.timeout==null?2e4:t.timeout),this._readyState="closed",this.uri=e;const s=t.parser||Ir;this.encoder=new s.Encoder,this.decoder=new s.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 Sr(this.uri,this.opts);const t=this.engine,n=this;this._readyState="opening",this.skipReconnect=!1;const s=R(t,"open",function(){n.onopen(),e&&e()}),i=a=>{this.cleanup(),this._readyState="closed",this.emitReserved("error",a),e?e(a):this.maybeReconnectOnOpen()},o=R(t,"error",i);if(this._timeout!==!1){const a=this._timeout,c=this.setTimeoutFn(()=>{s(),i(new Error("timeout")),t.close()},a);this.opts.autoUnref&&c.unref(),this.subs.push(()=>{this.clearTimeoutFn(c)})}return this.subs.push(s),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){ie(()=>{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 an(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(s=>{s?(e._reconnecting=!1,e.reconnect(),this.emitReserved("reconnect_error",s)):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 q={};function he(r,e){typeof r=="object"&&(e=r,r=void 0),e=e||{};const t=Cr(r,e.path||"/socket.io"),n=t.source,s=t.id,i=t.path,o=q[s]&&i in q[s].nsps,a=e.forceNew||e["force new connection"]||e.multiplex===!1||o;let c;return a?c=new Ne(n,e):(q[s]||(q[s]=new Ne(n,e)),c=q[s]),t.query&&!e.query&&(e.query=t.queryKey),c.socket(t.path,e)}Object.assign(he,{Manager:Ne,Socket:an,io:he,connect:he});class Lr{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 i=new URL(this.config.socketUrl);t=`${i.protocol}//${i.host}`;const o=i.pathname.replace(/\/+$/,"");o&&(n=`${o}/socket.io/`)}catch{}this.socket=he(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",i=>{this.callbacks.onMessage&&this.callbacks.onMessage(i)}),this.socket.on("existing-peers",i=>{this.callbacks.onExistingPeers&&this.callbacks.onExistingPeers(i)}),this.socket.on("you-joined",i=>{this.callbacks.onYouJoined&&this.callbacks.onYouJoined(i)}),this.socket.on("user-joined",i=>{this.callbacks.onUserJoined&&this.callbacks.onUserJoined(i)}),this.socket.on("user-left",i=>{this.callbacks.onUserLeft&&this.callbacks.onUserLeft(i)}),this.socket.on("peer-media-state-change",i=>{this.callbacks.onPeerMediaStateChange&&this.callbacks.onPeerMediaStateChange(i)});const s=["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 i of s)this.socket.on(i,o=>{const a=this.rawListeners&&this.rawListeners.get(i);a&&a.forEach(c=>{try{c(o)}catch(h){console.warn(h)}})});this.socket.on("error",i=>{console.error("Socket error:",i),this.callbacks.onError&&this.callbacks.onError(i)})}joinRoom(e,t,n,s){this.socket&&this.socket.emit("join-room",{roomId:e,userId:t,userName:n,peerId:s})}emitMediaState(e,t,n,s){this.socket&&this.socket.emit("media-state-change",{roomId:e,userId:t,type:n,enabled:s})}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,s,i){if(this.socket){const o={roomId:e,userId:t,userName:n,message:s||""};Array.isArray(i)&&i.length&&(o.attachmentIds=i),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 $r{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 ze{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(!ze.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,s=Number.isFinite(t.videoBitsPerSecond)?t.videoBitsPerSecond:1e6,i=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:s,audioBitsPerSecond:i};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(p=>{console.warn(`Recording chunk seq=${h} upload failed:`,p&&p.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(i=>{this.recorder.onstop=i,this.recorder.stop()});const t=(await Promise.allSettled(this.pendingUploads)).filter(i=>i.status==="rejected").length,n=new Date,s={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"),s}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 Fe{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(!Fe.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}=zr(e.length),s=this.width/t,i=this.height/n;e.forEach((o,a)=>{const c=a%t,h=Math.floor(a/t),l=c*s,d=h*i;this.ctx.fillStyle="#1a1a1a",this.ctx.fillRect(l,d,s,i);const u=o.videoEl.videoWidth||0,p=o.videoEl.videoHeight||0,m=o.videoTrack,_=m&&m.enabled&&m.readyState==="live";if(u>0&&p>0&&_!==!1){const pn=Math.min(s/u,i/p),gn=u*pn,mn=p*pn,Xr=l+(s-gn)/2,Zr=d+(i-mn)/2;try{this.ctx.drawImage(o.videoEl,Xr,Zr,gn,mn)}catch{}}else Nr(this.ctx,o.label||"Peer",l,d,s,i);const ln=o.label||"Peer";this.ctx.font="bold 16px system-ui, sans-serif";const Yr=this.ctx.measureText(ln),dn=10,Gr=6,Qr=Yr.width+dn*2,Ke=24,un=l+12,fn=d+i-Ke-12;this.ctx.fillStyle="rgba(0,0,0,0.65)",this.ctx.fillRect(un,fn,Qr,Ke),this.ctx.fillStyle="#fff",this.ctx.fillText(ln,un+dn,fn+Ke-Gr-2)})}addStream(e,t,n={}){if(!this.running)return;this.videos.has(e)&&this.removeStream(e);const s=document.createElement("video");s.srcObject=t,s.autoplay=!0,s.muted=!0,s.playsInline=!0,s.style.cssText="position:absolute;left:-9999px;top:-9999px;",document.body.appendChild(s),s.play().catch(()=>{});const i=t.getVideoTracks()[0]||null;this.videos.set(e,{videoEl:s,videoTrack:i,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 Br(r){const e=String(r).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 Ur(r){let e=0;const t=String(r);for(let s=0;s<t.length;s++)e=e*31+t.charCodeAt(s)>>>0;return`hsl(${e%360}, 45%, 40%)`}function Nr(r,e,t,n,s,i){const o=t+s/2,a=n+i/2,c=Math.min(s,i)*.22;r.fillStyle=Ur(e),r.beginPath(),r.arc(o,a,c,0,Math.PI*2),r.fill(),r.fillStyle="#fff",r.font=`600 ${Math.floor(c)}px system-ui, sans-serif`,r.textAlign="center",r.textBaseline="middle",r.fillText(Br(e),o,a+1),r.textAlign="start",r.textBaseline="alphabetic"}function zr(r){if(r<=1)return{cols:1,rows:1};if(r===2)return{cols:2,rows:1};if(r<=4)return{cols:2,rows:2};if(r<=6)return{cols:3,rows:2};if(r<=9)return{cols:3,rows:3};const e=4;return{cols:e,rows:Math.ceil(r/e)}}function Fr(r,e){return r.includes("pdf")||/\.pdf$/i.test(e)?"📕":r.includes("word")||/\.docx?$/i.test(e)?"📘":r.includes("sheet")||r.includes("excel")||/\.(xlsx?|csv)$/i.test(e)?"📗":r.startsWith("text/")?"📄":"📎"}class jr{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={}}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.render()}render(){const e=this.recording==="manual"?'<button id="toggle-record" style="padding: 10px 20px; background-color: #7a3a3a; border: none; border-radius: 6px; color: white; cursor: pointer; font-size: 14px;">● Record</button>':"",t=this.recording!=="off"?'<button id="toggle-pause" style="display:none; padding: 10px 20px; background-color: #3a5a7a; border: none; border-radius: 6px; color: white; cursor: pointer; font-size: 14px;">⏸ Pause</button>':"",n=this.screenShare?'<button id="toggle-screenshare" style="padding: 10px 20px; background-color: #3a5a7a; border: none; border-radius: 6px; color: white; cursor: pointer; font-size: 14px;">Share Screen</button>':"",s=this.recording!=="off"?'<span id="recording-indicator" style="display:none; margin-left: 12px; color: #ff5252; font-size: 13px; font-weight: 600;"><span id="rec-dot" style="display:inline-block; width:8px; height:8px; background:#ff5252; border-radius:50%; margin-right:6px; animation: recPulse 1.2s ease-in-out infinite;"></span>REC <span id="rec-elapsed">00:00</span></span>':"",i=this.recording!=="off"?'<span id="queue-indicator" style="display:none; margin-left: 12px; color: #fbbf24; font-size: 12px;">⏳ <span id="queue-count">0</span> uploading</span>':"";this._panelWiredOnRender=!0,this.container.innerHTML=`
|
|
42
42
|
<style>
|
|
43
43
|
@keyframes recPulse { 0%,100%{opacity:1} 50%{opacity:0.3} }
|
|
44
44
|
</style>
|
|
@@ -186,4 +186,4 @@ a=extmap-allow-mixed`)!==-1){const i=s.sdp.split(`
|
|
|
186
186
|
<canvas id="wb-canvas" class="wb-canvas"></canvas>
|
|
187
187
|
</div>
|
|
188
188
|
<div class="wb-note" id="wb-note"></div>
|
|
189
|
-
`,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,s,i){const o=this.canvas.getBoundingClientRect().width,a=this.canvas.getBoundingClientRect().height;this.ctx.lineWidth=i,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)":s,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 Hr=new Set(["auto","manual","off"]),Kr=new Set(["local","composite"]),Jr="https://preproduction.tentoro.in/videocall";function Wr(r){const e=new URL(r),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 hn{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||Jr,n=Hr.has(e.recording)?e.recording:"off",s=n!=="off"&&!!e.transcribe,i=s&&!!e.summarize,o=e.recordOnlyIfHost!==!1,a=Kr.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,p=["chat","code","whiteboard"],m=Array.isArray(e.panels)&&e.panels.length?e.panels.filter(_=>p.includes(_)):["chat"];m.includes("chat")||m.unshift("chat"),this.config={...e,host:t,apiUrl:e.apiUrl||`${t}/api`,socketUrl:e.socketUrl||t,peerServer:e.peerServer||Wr(t),ai:{...e.ai||{}},recording:n,transcribe:s,summarize:i,recordOnlyIfHost:o,recordingMode:a,compositeWidth:c,compositeHeight:h,compositeFps:l,recordingVideoBps:d,recordingAudioBps:u,panels:m},this.myRole=null,this.roleResolvers=[],this.currentRoom=this.config.roomId,this.currentUser=this.config.user,this.peerManager=new Fn(this.config),this.socketManager=new Lr(this.config),this.mediaManager=new $r,this.uiManager=new jr({recording:n,screenShare:e.screenShare!==!1,panels:m}),this.recorder=n==="off"?null:new ze,this.compositor=null,this.setupEventHandlers(),this.isInitialized=!0,console.log("MeetSDK initialized")}setupEventHandlers(){this.peerManager.on("stream",(e,t,n)=>{const s=this.labelForPeer(e,n);this.mediaManager.addRemoteStream(e,t),this.uiManager.addVideoStream(e,t,n,s),this.compositor&&this.compositor.addStream(e,t,{isLocal:n,label:s}),this.refreshParticipantsPanel()}),this.peerManager.on("peerLeft",e=>{this.mediaManager.removeRemoteStream(e),this.uiManager.removeVideoStream(e),this.compositor&&this.compositor.removeStream(e),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.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()})}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",isYou:!0,isHost:this.myRole==="organizer",isSharing:this.peerManager&&this.peerManager.isScreenSharing&&this.peerManager.isScreenSharing()}),this.peerLabels)for(const[t,n]of this.peerLabels.entries())e.push({label:n,isYou:!1,isHost:this.hostPeerId===t,isSharing:this.presentingPeerId===t});this.uiManager.setParticipants(e)}waitForRole(e=3e3){return this.myRole?Promise.resolve(this.myRole):new Promise(t=>{const n=setTimeout(()=>t(this.myRole||"candidate"),e);this.roleResolvers.push(s=>{clearTimeout(n),t(s)})})}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 Fe({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(s){console.warn("Composite recording unavailable, falling back to local:",s.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(s=>console.error("setupRecording failed:",s)),this.setupCollabPanels(),this.fetchChatHistory().then(s=>{s&&s.messages&&this.uiManager.setChatHistory(s.messages)}).catch(s=>console.warn("Chat history fetch failed:",s&&s.message)),console.log("MeetSDK mounted")}setupCollabPanels(){if(this.uiManager&&!this.uiManager._panelWired&&(this.uiManager.wirePanelTabs(),this.uiManager._panelWired=!0),this.config.panels.includes("code")){const e=this.uiManager.getPanelSlot("code");e&&(this.codeSandbox=new qr({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(s=>s.userId===this.currentUser.id);this._codeEditPermission=!!(n&&n.canEdit)}this.codeSandbox.handleStateSync(t)}),this.socketManager.onRaw("code-permission-changed",t=>{if(t&&t.targetUserId===this.currentUser.id&&(this._codeEditPermission=!!t.canEdit),Array.isArray(t&&t.editPermissions)){const n=t.editPermissions.find(s=>s.userId===this.currentUser.id);n&&(this._codeEditPermission=!!n.canEdit)}this.codeSandbox.refreshPermissionUI()}),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 Vr({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(s=>s.userId===this.currentUser.id);this._whiteboardDrawPermission=!!(n&&n.canDraw)}this.whiteboard.handleStateSync(t)}),this.socketManager.onRaw("whiteboard-permission-changed",t=>{if(t&&t.targetUserId===this.currentUser.id&&(this._whiteboardDrawPermission=!!t.canDraw),Array.isArray(t&&t.drawPermissions)){const n=t.drawPermissions.find(s=>s.userId===this.currentUser.id);n&&(this._whiteboardDrawPermission=!!n.canDraw)}this.whiteboard.refreshPermissionUI()}),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(),s=await fetch(`${this.config.apiUrl}/rooms/${encodeURIComponent(this.currentRoom)}/chat/messages${n?"?"+n:""}`,{headers:this.buildHeaders()});if(!s.ok)throw new Error(`chat/messages: HTTP ${s.status}`);return s.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 s=await n.json().catch(()=>({}));throw new Error(s.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,s=0;if(t){const i=await this.probeSessionStatus(t.sessionId).catch(()=>null);i&&i.active?(n={sessionId:t.sessionId},s=(i.lastSeq||-1)+1,console.log(`MeetSDK: resuming recording session ${t.sessionId} at seq=${s}`)):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:s,videoBitsPerSecond:this.config.recordingVideoBps,audioBitsPerSecond:this.config.recordingAudioBps,onChunk:(i,o)=>(this.enqueueChunk(n.sessionId,i,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(s=>console.warn("Chunk drainer error:",s&&s.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(s=>setTimeout(s,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 s=new FormData;s.append("chunk",t,`chunk-${n}.webm`);const i=await fetch(`${this.config.apiUrl}/rooms/${encodeURIComponent(this.currentRoom)}/recordings/session/${encodeURIComponent(e)}/chunk?seq=${n}`,{method:"POST",headers:this.buildHeaders(),body:s});if(!i.ok)throw new Error(`chunk seq=${n}: HTTP ${i.status}`)}async finalizeRecordingSession(e,t){const n=Math.max(0,Math.round((t.endedAt-t.startedAt)/1e3)),s=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(!s.ok)throw new Error(`session/finalize failed: HTTP ${s.status}`);const i=await s.json();return this.clearStoredSession(),i}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,s)=>{this.socketManager.sendMessage(this.currentRoom,this.currentUser.id,this.currentUser.name,n,s)}),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})}async leave(){if(this.recorder&&this.recorder.isRecording())try{this.uiManager.setUploadingIndicator(!0),await this.stopRecording()}catch(e){console.warn("Recording upload on leave failed:",e)}finally{this.uiManager.setUploadingIndicator(!1)}if(this.socketManager.leaveRoom(),this.socketManager.disconnect(),this.peerManager.disconnect(),this.mediaManager.cleanup(),this.uiManager.destroy(),this.compositor){try{this.compositor.stop()}catch{}this.compositor=null}this.isInitialized=!1,console.log("Left meeting")}}typeof window<"u"&&(window.MeetSDK=new hn),x.default=hn,Object.defineProperties(x,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
|
189
|
+
`,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,s,i){const o=this.canvas.getBoundingClientRect().width,a=this.canvas.getBoundingClientRect().height;this.ctx.lineWidth=i,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)":s,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 Hr=new Set(["auto","manual","off"]),Kr=new Set(["local","composite"]),Jr="https://preproduction.tentoro.in/videocall";function Wr(r){const e=new URL(r),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 hn{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||Jr,n=Hr.has(e.recording)?e.recording:"off",s=n!=="off"&&!!e.transcribe,i=s&&!!e.summarize,o=e.recordOnlyIfHost!==!1,a=Kr.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,p=["chat","code","whiteboard"],m=Array.isArray(e.panels)&&e.panels.length?e.panels.filter(_=>p.includes(_)):["chat"];m.includes("chat")||m.unshift("chat"),this.config={...e,host:t,apiUrl:e.apiUrl||`${t}/api`,socketUrl:e.socketUrl||t,peerServer:e.peerServer||Wr(t),ai:{...e.ai||{}},recording:n,transcribe:s,summarize:i,recordOnlyIfHost:o,recordingMode:a,compositeWidth:c,compositeHeight:h,compositeFps:l,recordingVideoBps:d,recordingAudioBps:u,panels:m},this.myRole=null,this.roleResolvers=[],this.currentRoom=this.config.roomId,this.currentUser=this.config.user,this.peerManager=new Fn(this.config),this.socketManager=new Lr(this.config),this.mediaManager=new $r,this.uiManager=new jr({recording:n,screenShare:e.screenShare!==!1,panels:m}),this.recorder=n==="off"?null:new ze,this.compositor=null,this.setupEventHandlers(),this.isInitialized=!0,console.log("MeetSDK initialized")}setupEventHandlers(){this.peerManager.on("stream",(e,t,n)=>{const s=this.labelForPeer(e,n);this.mediaManager.addRemoteStream(e,t),this.uiManager.addVideoStream(e,t,n,s),this.compositor&&this.compositor.addStream(e,t,{isLocal:n,label:s}),this.refreshParticipantsPanel()}),this.peerManager.on("peerLeft",e=>{this.mediaManager.removeRemoteStream(e),this.uiManager.removeVideoStream(e),this.compositor&&this.compositor.removeStream(e),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",isYou:!0,isHost:this.myRole==="organizer",isSharing:this.peerManager&&this.peerManager.isScreenSharing&&this.peerManager.isScreenSharing()}),this.peerLabels)for(const[t,n]of this.peerLabels.entries())e.push({label:n,isYou:!1,isHost:this.hostPeerId===t,isSharing:this.presentingPeerId===t});this.uiManager.setParticipants(e)}waitForRole(e=3e3){return this.myRole?Promise.resolve(this.myRole):new Promise(t=>{const n=setTimeout(()=>t(this.myRole||"candidate"),e);this.roleResolvers.push(s=>{clearTimeout(n),t(s)})})}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 Fe({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(s){console.warn("Composite recording unavailable, falling back to local:",s.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(s=>console.error("setupRecording failed:",s)),this.setupCollabPanels(),this.fetchChatHistory().then(s=>{s&&s.messages&&this.uiManager.setChatHistory(s.messages)}).catch(s=>console.warn("Chat history fetch failed:",s&&s.message)),console.log("MeetSDK mounted")}setupCollabPanels(){if(this.uiManager&&!this.uiManager._panelWired&&(this.uiManager.wirePanelTabs(),this.uiManager._panelWired=!0),this.config.panels.includes("code")){const e=this.uiManager.getPanelSlot("code");e&&(this.codeSandbox=new qr({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(s=>s.userId===this.currentUser.id);this._codeEditPermission=!!(n&&n.canEdit)}this.codeSandbox.handleStateSync(t)}),this.socketManager.onRaw("code-permission-changed",t=>{if(t&&t.targetUserId===this.currentUser.id&&(this._codeEditPermission=!!t.canEdit),Array.isArray(t&&t.editPermissions)){const n=t.editPermissions.find(s=>s.userId===this.currentUser.id);n&&(this._codeEditPermission=!!n.canEdit)}this.codeSandbox.refreshPermissionUI()}),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 Vr({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(s=>s.userId===this.currentUser.id);this._whiteboardDrawPermission=!!(n&&n.canDraw)}this.whiteboard.handleStateSync(t)}),this.socketManager.onRaw("whiteboard-permission-changed",t=>{if(t&&t.targetUserId===this.currentUser.id&&(this._whiteboardDrawPermission=!!t.canDraw),Array.isArray(t&&t.drawPermissions)){const n=t.drawPermissions.find(s=>s.userId===this.currentUser.id);n&&(this._whiteboardDrawPermission=!!n.canDraw)}this.whiteboard.refreshPermissionUI()}),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(),s=await fetch(`${this.config.apiUrl}/rooms/${encodeURIComponent(this.currentRoom)}/chat/messages${n?"?"+n:""}`,{headers:this.buildHeaders()});if(!s.ok)throw new Error(`chat/messages: HTTP ${s.status}`);return s.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 s=await n.json().catch(()=>({}));throw new Error(s.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,s=0;if(t){const i=await this.probeSessionStatus(t.sessionId).catch(()=>null);i&&i.active?(n={sessionId:t.sessionId},s=(i.lastSeq||-1)+1,console.log(`MeetSDK: resuming recording session ${t.sessionId} at seq=${s}`)):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:s,videoBitsPerSecond:this.config.recordingVideoBps,audioBitsPerSecond:this.config.recordingAudioBps,onChunk:(i,o)=>(this.enqueueChunk(n.sessionId,i,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(s=>console.warn("Chunk drainer error:",s&&s.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(s=>setTimeout(s,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 s=new FormData;s.append("chunk",t,`chunk-${n}.webm`);const i=await fetch(`${this.config.apiUrl}/rooms/${encodeURIComponent(this.currentRoom)}/recordings/session/${encodeURIComponent(e)}/chunk?seq=${n}`,{method:"POST",headers:this.buildHeaders(),body:s});if(!i.ok)throw new Error(`chunk seq=${n}: HTTP ${i.status}`)}async finalizeRecordingSession(e,t){const n=Math.max(0,Math.round((t.endedAt-t.startedAt)/1e3)),s=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(!s.ok)throw new Error(`session/finalize failed: HTTP ${s.status}`);const i=await s.json();return this.clearStoredSession(),i}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,s)=>{this.socketManager.sendMessage(this.currentRoom,this.currentUser.id,this.currentUser.name,n,s)}),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})}async leave(){if(this.recorder&&this.recorder.isRecording())try{this.uiManager.setUploadingIndicator(!0),await this.stopRecording()}catch(e){console.warn("Recording upload on leave failed:",e)}finally{this.uiManager.setUploadingIndicator(!1)}if(this.socketManager.leaveRoom(),this.socketManager.disconnect(),this.peerManager.disconnect(),this.mediaManager.cleanup(),this.uiManager.destroy(),this.compositor){try{this.compositor.stop()}catch{}this.compositor=null}this.isInitialized=!1,console.log("Left meeting")}}typeof window<"u"&&(window.MeetSDK=new hn),x.default=hn,Object.defineProperties(x,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|