@klever-one/web-sdk
Version:
Web SDK for integrating real-time room management and streaming functionality into web applications
1,147 lines • 185 kB
JavaScript
"use client";
var N = { exports: {} }, ee;
function tt() {
return ee || (ee = 1, (function(a) {
const e = {};
e.generateIdentifier = function() {
return Math.random().toString(36).substring(2, 12);
}, e.localCName = e.generateIdentifier(), e.splitLines = function(t) {
return t.trim().split(`
`).map((s) => s.trim());
}, e.splitSections = function(t) {
return t.split(`
m=`).map((n, i) => (i > 0 ? "m=" + n : n).trim() + `\r
`);
}, e.getDescription = function(t) {
const s = e.splitSections(t);
return s && s[0];
}, e.getMediaSections = function(t) {
const s = e.splitSections(t);
return s.shift(), s;
}, e.matchPrefix = function(t, s) {
return e.splitLines(t).filter((n) => n.indexOf(s) === 0);
}, e.parseCandidate = function(t) {
let s;
t.indexOf("a=candidate:") === 0 ? s = t.substring(12).split(" ") : s = t.substring(10).split(" ");
const n = {
foundation: s[0],
component: { 1: "rtp", 2: "rtcp" }[s[1]] || s[1],
protocol: s[2].toLowerCase(),
priority: parseInt(s[3], 10),
ip: s[4],
address: s[4],
// address is an alias for ip.
port: parseInt(s[5], 10),
// skip parts[6] == 'typ'
type: s[7]
};
for (let i = 8; i < s.length; i += 2)
switch (s[i]) {
case "raddr":
n.relatedAddress = s[i + 1];
break;
case "rport":
n.relatedPort = parseInt(s[i + 1], 10);
break;
case "tcptype":
n.tcpType = s[i + 1];
break;
case "ufrag":
n.ufrag = s[i + 1], n.usernameFragment = s[i + 1];
break;
default:
n[s[i]] === void 0 && (n[s[i]] = s[i + 1]);
break;
}
return n;
}, e.writeCandidate = function(t) {
const s = [];
s.push(t.foundation);
const n = t.component;
n === "rtp" ? s.push(1) : n === "rtcp" ? s.push(2) : s.push(n), s.push(t.protocol.toUpperCase()), s.push(t.priority), s.push(t.address || t.ip), s.push(t.port);
const i = t.type;
return s.push("typ"), s.push(i), i !== "host" && t.relatedAddress && t.relatedPort && (s.push("raddr"), s.push(t.relatedAddress), s.push("rport"), s.push(t.relatedPort)), t.tcpType && t.protocol.toLowerCase() === "tcp" && (s.push("tcptype"), s.push(t.tcpType)), (t.usernameFragment || t.ufrag) && (s.push("ufrag"), s.push(t.usernameFragment || t.ufrag)), "candidate:" + s.join(" ");
}, e.parseIceOptions = function(t) {
return t.substring(14).split(" ");
}, e.parseRtpMap = function(t) {
let s = t.substring(9).split(" ");
const n = {
payloadType: parseInt(s.shift(), 10)
// was: id
};
return s = s[0].split("/"), n.name = s[0], n.clockRate = parseInt(s[1], 10), n.channels = s.length === 3 ? parseInt(s[2], 10) : 1, n.numChannels = n.channels, n;
}, e.writeRtpMap = function(t) {
let s = t.payloadType;
t.preferredPayloadType !== void 0 && (s = t.preferredPayloadType);
const n = t.channels || t.numChannels || 1;
return "a=rtpmap:" + s + " " + t.name + "/" + t.clockRate + (n !== 1 ? "/" + n : "") + `\r
`;
}, e.parseExtmap = function(t) {
const s = t.substring(9).split(" ");
return {
id: parseInt(s[0], 10),
direction: s[0].indexOf("/") > 0 ? s[0].split("/")[1] : "sendrecv",
uri: s[1],
attributes: s.slice(2).join(" ")
};
}, e.writeExtmap = function(t) {
return "a=extmap:" + (t.id || t.preferredId) + (t.direction && t.direction !== "sendrecv" ? "/" + t.direction : "") + " " + t.uri + (t.attributes ? " " + t.attributes : "") + `\r
`;
}, e.parseFmtp = function(t) {
const s = {};
let n;
const i = t.substring(t.indexOf(" ") + 1).split(";");
for (let o = 0; o < i.length; o++)
n = i[o].trim().split("="), s[n[0].trim()] = n[1];
return s;
}, e.writeFmtp = function(t) {
let s = "", n = t.payloadType;
if (t.preferredPayloadType !== void 0 && (n = t.preferredPayloadType), t.parameters && Object.keys(t.parameters).length) {
const i = [];
Object.keys(t.parameters).forEach((o) => {
t.parameters[o] !== void 0 ? i.push(o + "=" + t.parameters[o]) : i.push(o);
}), s += "a=fmtp:" + n + " " + i.join(";") + `\r
`;
}
return s;
}, e.parseRtcpFb = function(t) {
const s = t.substring(t.indexOf(" ") + 1).split(" ");
return {
type: s.shift(),
parameter: s.join(" ")
};
}, e.writeRtcpFb = function(t) {
let s = "", n = t.payloadType;
return t.preferredPayloadType !== void 0 && (n = t.preferredPayloadType), t.rtcpFeedback && t.rtcpFeedback.length && t.rtcpFeedback.forEach((i) => {
s += "a=rtcp-fb:" + n + " " + i.type + (i.parameter && i.parameter.length ? " " + i.parameter : "") + `\r
`;
}), s;
}, e.parseSsrcMedia = function(t) {
const s = t.indexOf(" "), n = {
ssrc: parseInt(t.substring(7, s), 10)
}, i = t.indexOf(":", s);
return i > -1 ? (n.attribute = t.substring(s + 1, i), n.value = t.substring(i + 1)) : n.attribute = t.substring(s + 1), n;
}, e.parseSsrcGroup = function(t) {
const s = t.substring(13).split(" ");
return {
semantics: s.shift(),
ssrcs: s.map((n) => parseInt(n, 10))
};
}, e.getMid = function(t) {
const s = e.matchPrefix(t, "a=mid:")[0];
if (s)
return s.substring(6);
}, e.parseFingerprint = function(t) {
const s = t.substring(14).split(" ");
return {
algorithm: s[0].toLowerCase(),
// algorithm is case-sensitive in Edge.
value: s[1].toUpperCase()
// the definition is upper-case in RFC 4572.
};
}, e.getDtlsParameters = function(t, s) {
return {
role: "auto",
fingerprints: e.matchPrefix(
t + s,
"a=fingerprint:"
).map(e.parseFingerprint)
};
}, e.writeDtlsParameters = function(t, s) {
let n = "a=setup:" + s + `\r
`;
return t.fingerprints.forEach((i) => {
n += "a=fingerprint:" + i.algorithm + " " + i.value + `\r
`;
}), n;
}, e.parseCryptoLine = function(t) {
const s = t.substring(9).split(" ");
return {
tag: parseInt(s[0], 10),
cryptoSuite: s[1],
keyParams: s[2],
sessionParams: s.slice(3)
};
}, e.writeCryptoLine = function(t) {
return "a=crypto:" + t.tag + " " + t.cryptoSuite + " " + (typeof t.keyParams == "object" ? e.writeCryptoKeyParams(t.keyParams) : t.keyParams) + (t.sessionParams ? " " + t.sessionParams.join(" ") : "") + `\r
`;
}, e.parseCryptoKeyParams = function(t) {
if (t.indexOf("inline:") !== 0)
return null;
const s = t.substring(7).split("|");
return {
keyMethod: "inline",
keySalt: s[0],
lifeTime: s[1],
mkiValue: s[2] ? s[2].split(":")[0] : void 0,
mkiLength: s[2] ? s[2].split(":")[1] : void 0
};
}, e.writeCryptoKeyParams = function(t) {
return t.keyMethod + ":" + t.keySalt + (t.lifeTime ? "|" + t.lifeTime : "") + (t.mkiValue && t.mkiLength ? "|" + t.mkiValue + ":" + t.mkiLength : "");
}, e.getCryptoParameters = function(t, s) {
return e.matchPrefix(
t + s,
"a=crypto:"
).map(e.parseCryptoLine);
}, e.getIceParameters = function(t, s) {
const n = e.matchPrefix(
t + s,
"a=ice-ufrag:"
)[0], i = e.matchPrefix(
t + s,
"a=ice-pwd:"
)[0];
return n && i ? {
usernameFragment: n.substring(12),
password: i.substring(10)
} : null;
}, e.writeIceParameters = function(t) {
let s = "a=ice-ufrag:" + t.usernameFragment + `\r
a=ice-pwd:` + t.password + `\r
`;
return t.iceLite && (s += `a=ice-lite\r
`), s;
}, e.parseRtpParameters = function(t) {
const s = {
codecs: [],
headerExtensions: [],
fecMechanisms: [],
rtcp: []
}, i = e.splitLines(t)[0].split(" ");
s.profile = i[2];
for (let d = 3; d < i.length; d++) {
const c = i[d], p = e.matchPrefix(
t,
"a=rtpmap:" + c + " "
)[0];
if (p) {
const g = e.parseRtpMap(p), f = e.matchPrefix(
t,
"a=fmtp:" + c + " "
);
switch (g.parameters = f.length ? e.parseFmtp(f[0]) : {}, g.rtcpFeedback = e.matchPrefix(
t,
"a=rtcp-fb:" + c + " "
).map(e.parseRtcpFb), s.codecs.push(g), g.name.toUpperCase()) {
case "RED":
case "ULPFEC":
s.fecMechanisms.push(g.name.toUpperCase());
break;
}
}
}
e.matchPrefix(t, "a=extmap:").forEach((d) => {
s.headerExtensions.push(e.parseExtmap(d));
});
const o = e.matchPrefix(t, "a=rtcp-fb:* ").map(e.parseRtcpFb);
return s.codecs.forEach((d) => {
o.forEach((c) => {
d.rtcpFeedback.find((g) => g.type === c.type && g.parameter === c.parameter) || d.rtcpFeedback.push(c);
});
}), s;
}, e.writeRtpDescription = function(t, s) {
let n = "";
n += "m=" + t + " ", n += s.codecs.length > 0 ? "9" : "0", n += " " + (s.profile || "UDP/TLS/RTP/SAVPF") + " ", n += s.codecs.map((o) => o.preferredPayloadType !== void 0 ? o.preferredPayloadType : o.payloadType).join(" ") + `\r
`, n += `c=IN IP4 0.0.0.0\r
`, n += `a=rtcp:9 IN IP4 0.0.0.0\r
`, s.codecs.forEach((o) => {
n += e.writeRtpMap(o), n += e.writeFmtp(o), n += e.writeRtcpFb(o);
});
let i = 0;
return s.codecs.forEach((o) => {
o.maxptime > i && (i = o.maxptime);
}), i > 0 && (n += "a=maxptime:" + i + `\r
`), s.headerExtensions && s.headerExtensions.forEach((o) => {
n += e.writeExtmap(o);
}), n;
}, e.parseRtpEncodingParameters = function(t) {
const s = [], n = e.parseRtpParameters(t), i = n.fecMechanisms.indexOf("RED") !== -1, o = n.fecMechanisms.indexOf("ULPFEC") !== -1, d = e.matchPrefix(t, "a=ssrc:").map((S) => e.parseSsrcMedia(S)).filter((S) => S.attribute === "cname"), c = d.length > 0 && d[0].ssrc;
let p;
const g = e.matchPrefix(t, "a=ssrc-group:FID").map((S) => S.substring(17).split(" ").map((L) => parseInt(L, 10)));
g.length > 0 && g[0].length > 1 && g[0][0] === c && (p = g[0][1]), n.codecs.forEach((S) => {
if (S.name.toUpperCase() === "RTX" && S.parameters.apt) {
let E = {
ssrc: c,
codecPayloadType: parseInt(S.parameters.apt, 10)
};
c && p && (E.rtx = { ssrc: p }), s.push(E), i && (E = JSON.parse(JSON.stringify(E)), E.fec = {
ssrc: c,
mechanism: o ? "red+ulpfec" : "red"
}, s.push(E));
}
}), s.length === 0 && c && s.push({
ssrc: c
});
let f = e.matchPrefix(t, "b=");
return f.length && (f[0].indexOf("b=TIAS:") === 0 ? f = parseInt(f[0].substring(7), 10) : f[0].indexOf("b=AS:") === 0 ? f = parseInt(f[0].substring(5), 10) * 1e3 * 0.95 - 2e3 * 8 : f = void 0, s.forEach((S) => {
S.maxBitrate = f;
})), s;
}, e.parseRtcpParameters = function(t) {
const s = {}, n = e.matchPrefix(t, "a=ssrc:").map((d) => e.parseSsrcMedia(d)).filter((d) => d.attribute === "cname")[0];
n && (s.cname = n.value, s.ssrc = n.ssrc);
const i = e.matchPrefix(t, "a=rtcp-rsize");
s.reducedSize = i.length > 0, s.compound = i.length === 0;
const o = e.matchPrefix(t, "a=rtcp-mux");
return s.mux = o.length > 0, s;
}, e.writeRtcpParameters = function(t) {
let s = "";
return t.reducedSize && (s += `a=rtcp-rsize\r
`), t.mux && (s += `a=rtcp-mux\r
`), t.ssrc !== void 0 && t.cname && (s += "a=ssrc:" + t.ssrc + " cname:" + t.cname + `\r
`), s;
}, e.parseMsid = function(t) {
let s;
const n = e.matchPrefix(t, "a=msid:");
if (n.length === 1)
return s = n[0].substring(7).split(" "), { stream: s[0], track: s[1] };
const i = e.matchPrefix(t, "a=ssrc:").map((o) => e.parseSsrcMedia(o)).filter((o) => o.attribute === "msid");
if (i.length > 0)
return s = i[0].value.split(" "), { stream: s[0], track: s[1] };
}, e.parseSctpDescription = function(t) {
const s = e.parseMLine(t), n = e.matchPrefix(t, "a=max-message-size:");
let i;
n.length > 0 && (i = parseInt(n[0].substring(19), 10)), isNaN(i) && (i = 65536);
const o = e.matchPrefix(t, "a=sctp-port:");
if (o.length > 0)
return {
port: parseInt(o[0].substring(12), 10),
protocol: s.fmt,
maxMessageSize: i
};
const d = e.matchPrefix(t, "a=sctpmap:");
if (d.length > 0) {
const c = d[0].substring(10).split(" ");
return {
port: parseInt(c[0], 10),
protocol: c[1],
maxMessageSize: i
};
}
}, e.writeSctpDescription = function(t, s) {
let n = [];
return t.protocol !== "DTLS/SCTP" ? n = [
"m=" + t.kind + " 9 " + t.protocol + " " + s.protocol + `\r
`,
`c=IN IP4 0.0.0.0\r
`,
"a=sctp-port:" + s.port + `\r
`
] : n = [
"m=" + t.kind + " 9 " + t.protocol + " " + s.port + `\r
`,
`c=IN IP4 0.0.0.0\r
`,
"a=sctpmap:" + s.port + " " + s.protocol + ` 65535\r
`
], s.maxMessageSize !== void 0 && n.push("a=max-message-size:" + s.maxMessageSize + `\r
`), n.join("");
}, e.generateSessionId = function() {
return Math.random().toString().substr(2, 22);
}, e.writeSessionBoilerplate = function(t, s, n) {
let i;
const o = s !== void 0 ? s : 2;
return t ? i = t : i = e.generateSessionId(), `v=0\r
o=` + (n || "thisisadapterortc") + " " + i + " " + o + ` IN IP4 127.0.0.1\r
s=-\r
t=0 0\r
`;
}, e.getDirection = function(t, s) {
const n = e.splitLines(t);
for (let i = 0; i < n.length; i++)
switch (n[i]) {
case "a=sendrecv":
case "a=sendonly":
case "a=recvonly":
case "a=inactive":
return n[i].substring(2);
}
return s ? e.getDirection(s) : "sendrecv";
}, e.getKind = function(t) {
return e.splitLines(t)[0].split(" ")[0].substring(2);
}, e.isRejected = function(t) {
return t.split(" ", 2)[1] === "0";
}, e.parseMLine = function(t) {
const n = e.splitLines(t)[0].substring(2).split(" ");
return {
kind: n[0],
port: parseInt(n[1], 10),
protocol: n[2],
fmt: n.slice(3).join(" ")
};
}, e.parseOLine = function(t) {
const n = e.matchPrefix(t, "o=")[0].substring(2).split(" ");
return {
username: n[0],
sessionId: n[1],
sessionVersion: parseInt(n[2], 10),
netType: n[3],
addressType: n[4],
address: n[5]
};
}, e.isValidSDP = function(t) {
if (typeof t != "string" || t.length === 0)
return !1;
const s = e.splitLines(t);
for (let n = 0; n < s.length; n++)
if (s[n].length < 2 || s[n].charAt(1) !== "=")
return !1;
return !0;
}, a.exports = e;
})(N)), N.exports;
}
var te = /* @__PURE__ */ tt(), R, T, H = { d: (a, e) => {
for (var t in e) H.o(e, t) && !H.o(a, t) && Object.defineProperty(a, t, { enumerable: !0, get: e[t] });
}, o: (a, e) => Object.prototype.hasOwnProperty.call(a, e) }, u = {};
H.d(u, { Dz: () => He, g$: () => he, Lt: () => de, Q9: () => ce, qf: () => j, hV: () => qe, z$: () => $t, J0: () => Y, De: () => yt, $C: () => U, al: () => Te, _W: () => ye, Gv: () => Oe, m: () => Ue, tz: () => Ce, Nu: () => Ke, zg: () => je, vp: () => Ve, vU: () => l, wF: () => xe, rv: () => We, Nh: () => Ne, ss: () => Xe, qW: () => Ge, QL: () => Ie, cf: () => Ye, eM: () => Le, Yd: () => r, Tk: () => m, iM: () => ae, qy: () => A, ce: () => ht, sK: () => h, Ok: () => v, q5: () => Qe, g: () => qt, xl: () => Re, I: () => ke, bx: () => J, dD: () => Be, Ib: () => _, Az: () => C, Iw: () => k, qY: () => X, db: () => le, mR: () => B, Tn: () => $, rV: () => Fe, gh: () => Me, Mi: () => we, j: () => be, YB: () => Pe, Yt: () => De, i5: () => Ae, x_: () => F, Am: () => Z, eR: () => ue, r8: () => Ee, u3: () => Je, vd: () => me, iV: () => Se, jZ: () => pe, SW: () => fe, ZH: () => ve, Ni: () => Ze, lh: () => ge, ZP: () => _e, bq: () => oe, $f: () => et, eu: () => ze, Ax: () => St, Mc: () => pt });
class r {
static GetStackTrace() {
const e = new Error();
let t = "No Stack Available for this browser";
return e.stack && (t = e.stack.toString().replace(/Error/g, "")), t;
}
static SetLoggerVerbosity(e) {
this.verboseLogLevel != null && (this.verboseLogLevel = e);
}
static Log(e, t, s) {
if (s > this.verboseLogLevel) return;
const n = `Level: Log
Msg: ${t}
Caller: ${e}`;
}
static Info(e, t, s) {
if (s > this.verboseLogLevel) return;
const n = `Level: Info
Msg: ${t}`;
console.info(n);
}
static Error(e, t) {
const s = `Level: Error
Msg: ${t}
Caller: ${e}`;
}
static Warning(e, t) {
const s = `Level: Warning
Caller: ${e}
Msg: ${t}`;
}
}
r.verboseLogLevel = 5, (function(a) {
a.LIST_STREAMERS = "listStreamers", a.SUBSCRIBE = "subscribe", a.UNSUBSCRIBE = "unsubscribe", a.ICE_CANDIDATE = "iceCandidate", a.OFFER = "offer", a.ANSWER = "answer", a.DATACHANNELREQUEST = "dataChannelRequest", a.SFURECVDATACHANNELREADY = "peerDataChannelsReady", a.PONG = "pong";
})(R || (R = {}));
class A {
sendFilter(e, t) {
return t;
}
payload() {
return r.Log(r.GetStackTrace(), `Sending =>
` + JSON.stringify(this, this.sendFilter, 4), 6), JSON.stringify(this, this.sendFilter);
}
}
class st extends A {
constructor() {
super(), this.type = R.LIST_STREAMERS;
}
}
class nt extends A {
constructor(e) {
super(), this.type = R.SUBSCRIBE, this.streamerId = e;
}
}
class rt extends A {
constructor() {
super(), this.type = R.UNSUBSCRIBE;
}
}
class it extends A {
constructor(e) {
super(), this.type = R.PONG, this.time = e;
}
}
class at extends A {
constructor(e, t) {
super(), this.type = R.OFFER, this.minBitrate = 0, this.maxBitrate = 0, e && (this.type = e.type, this.sdp = e.sdp, this.minBitrate = t.minBitrateBps, this.maxBitrate = t.maxBitrateBps);
}
sendFilter(e, t) {
if (e != "minBitrate" && e != "maxBitrate" || !(t <= 0)) return t;
}
}
class ot extends A {
constructor(e, t) {
super(), this.type = R.ANSWER, this.minBitrate = 0, this.maxBitrate = 0, e && (this.type = e.type, this.sdp = e.sdp, this.minBitrate = t.minBitrateBps, this.maxBitrate = t.maxBitrateBps);
}
sendFilter(e, t) {
if (e != "minBitrate" && e != "maxBitrate" || !(t <= 0)) return t;
}
}
class lt extends A {
constructor() {
super(), this.type = R.DATACHANNELREQUEST;
}
}
class dt extends A {
constructor() {
super(), this.type = R.SFURECVDATACHANNELREADY;
}
}
class ct {
constructor(e) {
this.type = R.ICE_CANDIDATE, this.candidate = e;
}
payload() {
return r.Log(r.GetStackTrace(), `Sending =>
` + JSON.stringify(this, void 0, 4), 6), JSON.stringify(this);
}
}
(function(a) {
a.CONFIG = "config", a.STREAMER_LIST = "streamerList", a.STREAMER_ID_CHANGED = "streamerIDChanged", a.PLAYER_COUNT = "playerCount", a.OFFER = "offer", a.ANSWER = "answer", a.ICE_CANDIDATE = "iceCandidate", a.PEER_DATA_CHANNELS = "peerDataChannels", a.PING = "ping", a.WARNING = "warning";
})(T || (T = {}));
class ae {
}
class ht extends ae {
}
class $ {
constructor() {
this.FromUEMessageHandlers = /* @__PURE__ */ new Map();
}
addMessageHandler(e, t) {
this.FromUEMessageHandlers.set(e, t);
}
handleMessage(e, t) {
this.FromUEMessageHandlers.has(e) ? this.FromUEMessageHandlers.get(e)(t) : r.Error(r.GetStackTrace(), `Message type of ${e} does not have a message handler registered on the frontend - ignoring message.`);
}
static setupDefaultHandlers(e) {
e.signallingProtocol.addMessageHandler(T.PING, ((t) => {
const s = new it((/* @__PURE__ */ new Date()).getTime()).payload();
r.Log(r.GetStackTrace(), T.PING + ": " + t, 6), e.webSocket.send(s);
})), e.signallingProtocol.addMessageHandler(T.CONFIG, ((t) => {
r.Log(r.GetStackTrace(), T.CONFIG, 6);
const s = JSON.parse(t);
e.onConfig(s);
})), e.signallingProtocol.addMessageHandler(T.STREAMER_LIST, ((t) => {
r.Log(r.GetStackTrace(), T.STREAMER_LIST, 6);
const s = JSON.parse(t);
e.onStreamerList(s);
})), e.signallingProtocol.addMessageHandler(T.STREAMER_ID_CHANGED, ((t) => {
r.Log(r.GetStackTrace(), T.STREAMER_ID_CHANGED, 6);
const s = JSON.parse(t);
e.onStreamerIDChanged(s);
})), e.signallingProtocol.addMessageHandler(T.PLAYER_COUNT, ((t) => {
r.Log(r.GetStackTrace(), T.PLAYER_COUNT, 6);
const s = JSON.parse(t);
r.Log(r.GetStackTrace(), "Player Count: " + s.count, 6), e.onPlayerCount(s);
})), e.signallingProtocol.addMessageHandler(T.ANSWER, ((t) => {
r.Log(r.GetStackTrace(), T.ANSWER, 6);
const s = JSON.parse(t);
e.onWebRtcAnswer(s);
})), e.signallingProtocol.addMessageHandler(T.OFFER, ((t) => {
r.Log(r.GetStackTrace(), T.OFFER, 6);
const s = JSON.parse(t);
e.onWebRtcOffer(s);
})), e.signallingProtocol.addMessageHandler(T.ICE_CANDIDATE, ((t) => {
r.Log(r.GetStackTrace(), T.ICE_CANDIDATE, 6);
const s = JSON.parse(t);
e.onIceCandidate(s.candidate);
})), e.signallingProtocol.addMessageHandler(T.WARNING, ((t) => {
r.Warning(r.GetStackTrace(), `Warning received: ${t}`);
})), e.signallingProtocol.addMessageHandler(T.PEER_DATA_CHANNELS, ((t) => {
r.Log(r.GetStackTrace(), T.PEER_DATA_CHANNELS, 6);
const s = JSON.parse(t);
e.onWebRtcPeerDataChannels(s);
}));
}
}
class oe {
constructor() {
this.WS_OPEN_STATE = 1, this.onOpen = new EventTarget(), this.onClose = new EventTarget(), this.signallingProtocol = new $(), $.setupDefaultHandlers(this);
}
connect(e) {
r.Log(r.GetStackTrace(), e, 6);
try {
return this.webSocket = new WebSocket(e), this.webSocket.onopen = (t) => this.handleOnOpen(t), this.webSocket.onerror = () => this.handleOnError(), this.webSocket.onclose = (t) => this.handleOnClose(t), this.webSocket.onmessage = (t) => this.handleOnMessage(t), this.webSocket.onmessagebinary = (t) => this.handleOnMessageBinary(t), !0;
} catch (t) {
return r.Error(t, t), !1;
}
}
handleOnMessageBinary(e) {
e && e.data && e.data.text().then(((t) => {
const s = new MessageEvent("messageFromBinary", { data: t });
this.handleOnMessage(s);
})).catch(((t) => {
r.Error(r.GetStackTrace(), `Failed to parse binary blob from websocket, reason: ${t}`);
}));
}
handleOnMessage(e) {
if (e.data && e.data instanceof Blob) return void this.handleOnMessageBinary(e);
const t = JSON.parse(e.data);
r.Log(r.GetStackTrace(), `received =>
` + JSON.stringify(JSON.parse(e.data), void 0, 4), 6), this.signallingProtocol.handleMessage(t.type, e.data);
}
handleOnOpen(e) {
r.Log(r.GetStackTrace(), "Connected to the signalling server via WebSocket", 6), this.onOpen.dispatchEvent(new Event("open"));
}
handleOnError() {
r.Error(r.GetStackTrace(), "WebSocket error");
}
handleOnClose(e) {
r.Log(r.GetStackTrace(), "Disconnected to the signalling server via WebSocket: " + JSON.stringify(e.code) + " - " + e.reason), this.onClose.dispatchEvent(new CustomEvent("close", { detail: e }));
}
requestStreamerList() {
const e = new st();
this.webSocket.send(e.payload());
}
sendSubscribe(e) {
const t = new nt(e);
this.webSocket.send(t.payload());
}
sendUnsubscribe() {
const e = new rt();
this.webSocket.send(e.payload());
}
sendWebRtcOffer(e, t) {
const s = new at(e, t);
this.webSocket.send(s.payload());
}
sendWebRtcAnswer(e, t) {
const s = new ot(e, t);
this.webSocket.send(s.payload());
}
sendWebRtcDatachannelRequest() {
const e = new lt();
this.webSocket.send(e.payload());
}
sendSFURecvDataChannelReady() {
const e = new dt();
this.webSocket.send(e.payload());
}
sendIceCandidate(e) {
if (r.Log(r.GetStackTrace(), "Sending Ice Candidate"), this.webSocket && this.webSocket.readyState === this.WS_OPEN_STATE) {
const t = new ct(e);
this.webSocket.send(t.payload());
}
}
close() {
var e;
(e = this.webSocket) === null || e === void 0 || e.close();
}
onConfig(e) {
}
onStreamerList(e) {
}
onStreamerIDChanged(e) {
}
onIceCandidate(e) {
}
onWebRtcAnswer(e) {
}
onWebRtcOffer(e) {
}
onWebRtcPeerDataChannels(e) {
}
onPlayerCount(e) {
}
}
class ut {
constructor(e) {
this.videoElementProvider = e, this.audioElement = document.createElement("Audio"), this.videoElementProvider.setAudioElement(this.audioElement);
}
handleOnTrack(e) {
if (r.Log(r.GetStackTrace(), "handleOnTrack " + JSON.stringify(e.streams), 6), e.track.id == "probator") return;
const t = this.videoElementProvider.getVideoElement();
if (e.track && r.Log(r.GetStackTrace(), "Got track - " + e.track.kind + " id=" + e.track.id + " readyState=" + e.track.readyState, 6), e.track.kind != "audio") return e.track.kind == "video" && t.srcObject !== e.streams[0] ? (t.srcObject = e.streams[0], void r.Log(r.GetStackTrace(), "Set video source from video track ontrack.")) : void 0;
this.CreateAudioTrack(e.streams[0]);
}
CreateAudioTrack(e) {
const t = this.videoElementProvider.getVideoElement();
t.srcObject != e && t.srcObject && t.srcObject !== e && (this.audioElement.srcObject = e, r.Log(r.GetStackTrace(), "Created new audio element to play separate audio stream."));
}
}
class gt {
constructor(e) {
this.freezeFrameHeight = 0, this.freezeFrameWidth = 0, this.rootDiv = e, this.rootElement = document.createElement("div"), this.rootElement.id = "freezeFrame", this.rootElement.style.display = "none", this.rootElement.style.pointerEvents = "none", this.rootElement.style.position = "absolute", this.rootElement.style.zIndex = "20", this.imageElement = document.createElement("img"), this.imageElement.style.position = "absolute", this.rootElement.appendChild(this.imageElement), this.rootDiv.appendChild(this.rootElement);
}
setElementForShow() {
this.rootElement.style.display = "block";
}
setElementForHide() {
this.rootElement.style.display = "none";
}
updateImageElementSource(e) {
const t = btoa(e.reduce(((s, n) => s + String.fromCharCode(n)), ""));
this.imageElement.src = "data:image/jpeg;base64," + t;
}
setDimensionsFromElementAndResize() {
this.freezeFrameHeight = this.imageElement.naturalHeight, this.freezeFrameWidth = this.imageElement.naturalWidth, this.resize();
}
resize() {
if (this.freezeFrameWidth !== 0 && this.freezeFrameHeight !== 0) {
let e = 0, t = 0, s = 0, n = 0;
const i = this.rootDiv.clientWidth / this.rootDiv.clientHeight, o = this.freezeFrameWidth / this.freezeFrameHeight;
i < o ? (e = this.rootDiv.clientWidth, t = Math.floor(this.rootDiv.clientWidth / o), s = Math.floor(0.5 * (this.rootDiv.clientHeight - t)), n = 0) : (e = Math.floor(this.rootDiv.clientHeight * o), t = this.rootDiv.clientHeight, s = 0, n = Math.floor(0.5 * (this.rootDiv.clientWidth - e))), this.rootElement.style.width = this.rootDiv.offsetWidth + "px", this.rootElement.style.height = this.rootDiv.offsetHeight + "px", this.rootElement.style.left = "0px", this.rootElement.style.top = "0px", this.imageElement.style.width = e + "px", this.imageElement.style.height = t + "px", this.imageElement.style.left = n + "px", this.imageElement.style.top = s + "px";
}
}
}
class mt {
constructor(e) {
this.receiving = !1, this.size = 0, this.jpeg = void 0, this.valid = !1, this.freezeFrameDelay = 50, this.freezeFrame = new gt(e);
}
showFreezeFrame() {
this.valid && this.freezeFrame.setElementForShow();
}
hideFreezeFrame() {
this.valid = !1, this.freezeFrame.setElementForHide();
}
updateFreezeFrameAndShow(e, t) {
this.freezeFrame.updateImageElementSource(e), this.freezeFrame.imageElement.onload = () => {
this.freezeFrame.setDimensionsFromElementAndResize(), t();
};
}
processFreezeFrameMessage(e, t) {
this.receiving || (this.receiving = !0, this.valid = !1, this.size = 0, this.jpeg = void 0), this.size = new DataView(e.slice(1, 5).buffer).getInt32(0, !0);
const s = e.slice(5);
if (this.jpeg) {
const n = new Uint8Array(this.jpeg.length + s.length);
n.set(this.jpeg, 0), n.set(s, this.jpeg.length), this.jpeg = n;
} else this.jpeg = s, this.receiving = !0, r.Log(r.GetStackTrace(), `received first chunk of freeze frame: ${this.jpeg.length}/${this.size}`, 6);
this.jpeg.length === this.size ? (this.receiving = !1, this.valid = !0, r.Log(r.GetStackTrace(), `received complete freeze frame ${this.size}`, 6), this.updateFreezeFrameAndShow(this.jpeg, t)) : this.jpeg.length > this.size && (r.Error(r.GetStackTrace(), `received bigger freeze frame than advertised: ${this.jpeg.length}/${this.size}`), this.jpeg = void 0, this.receiving = !1);
}
}
class _ {
constructor(e, t, s, n, i = (() => {
})) {
this.onChange = i, this.onChangeEmit = () => {
}, this.id = e, this.description = s, this.label = t, this.value = n;
}
set label(e) {
this._label = e, this.onChangeEmit(this._value);
}
get label() {
return this._label;
}
get value() {
return this._value;
}
set value(e) {
this._value = e, this.onChange(this._value, this), this.onChangeEmit(this._value);
}
}
class C extends _ {
constructor(e, t, s, n, i, o = (() => {
})) {
super(e, t, s, n, o);
const d = new URLSearchParams(window.location.search);
if (i && d.has(this.id)) {
const c = this.getUrlParamFlag();
this.flag = c;
} else this.flag = n;
this.useUrlParams = i;
}
getUrlParamFlag() {
const e = new URLSearchParams(window.location.search);
return !!e.has(this.id) && e.get(this.id) !== "false" && e.get(this.id) !== "False";
}
updateURLParams() {
if (this.useUrlParams) {
const e = new URLSearchParams(window.location.search);
this.flag === !0 ? e.set(this.id, "true") : e.set(this.id, "false"), window.history.replaceState({}, "", e.toString() !== "" ? `${location.pathname}?${e}` : `${location.pathname}`);
}
}
enable() {
this.flag = !0;
}
get flag() {
return !!this.value;
}
set flag(e) {
this.value = e;
}
}
class k extends _ {
constructor(e, t, s, n, i, o, d, c = (() => {
})) {
super(e, t, s, o, c), this._min = n, this._max = i;
const p = new URLSearchParams(window.location.search);
if (d && p.has(this.id)) {
const g = Number.parseFloat(p.get(this.id));
this.number = Number.isNaN(g) ? o : g;
} else this.number = o;
this.useUrlParams = d;
}
updateURLParams() {
if (this.useUrlParams) {
const e = new URLSearchParams(window.location.search);
e.set(this.id, this.number.toString()), window.history.replaceState({}, "", e.toString() !== "" ? `${location.pathname}?${e}` : `${location.pathname}`);
}
}
set number(e) {
this.value = this.clamp(e);
}
get number() {
return this.value;
}
clamp(e) {
return this._min == null && this._max == null ? e : this._min == null ? Math.min(this._max, e) : this._max == null ? Math.max(this._min, e) : Math.max(Math.min(this._max, e), this._min);
}
get min() {
return this._min;
}
get max() {
return this._max;
}
addOnChangedListener(e) {
this.onChange = e;
}
}
class le extends _ {
constructor(e, t, s, n, i, o = (() => {
})) {
super(e, t, s, n, o);
const d = new URLSearchParams(window.location.search);
if (i && d.has(this.id)) {
const c = this.getUrlParamText();
this.text = c;
} else this.text = n;
this.useUrlParams = i;
}
getUrlParamText() {
var e;
const t = new URLSearchParams(window.location.search);
return t.has(this.id) && (e = t.get(this.id)) !== null && e !== void 0 ? e : "";
}
updateURLParams() {
if (this.useUrlParams) {
const e = new URLSearchParams(window.location.search);
e.set(this.id, this.text), window.history.replaceState({}, "", e.toString() !== "" ? `${location.pathname}?${e}` : `${location.pathname}`);
}
}
get text() {
return this.value;
}
set text(e) {
this.value = e;
}
}
class X extends _ {
constructor(e, t, s, n, i, o, d = (() => {
})) {
super(e, t, s, n, d), this.options = i;
const c = new URLSearchParams(window.location.search), p = o && c.has(this.id) ? this.getUrlParamText() : n;
this.selected = p, this.useUrlParams = o;
}
getUrlParamText() {
var e;
const t = new URLSearchParams(window.location.search);
return t.has(this.id) && (e = t.get(this.id)) !== null && e !== void 0 ? e : "";
}
updateURLParams() {
if (this.useUrlParams) {
const e = new URLSearchParams(window.location.search);
e.set(this.id, this.selected), window.history.replaceState({}, "", e.toString() !== "" ? `${location.pathname}?${e}` : `${location.pathname}`);
}
}
addOnChangedListener(e) {
this.onChange = e;
}
get options() {
return this._options;
}
set options(e) {
this._options = e, this.onChangeEmit(this.selected);
}
get selected() {
return this.value;
}
set selected(e) {
let t = this.options.filter(((s) => s.indexOf(e) !== -1));
t.length ? this.value = t[0] : (t = this.options.filter(((s) => s.indexOf(e.split(" ")[0]) !== -1)), t.length && (this.value = t[0]));
}
}
class de extends Event {
constructor(e) {
super("afkWarningActivate"), this.data = e;
}
}
class j extends Event {
constructor(e) {
super("afkWarningUpdate"), this.data = e;
}
}
class ce extends Event {
constructor() {
super("afkWarningDeactivate");
}
}
class he extends Event {
constructor() {
super("afkTimedOut");
}
}
class ue extends Event {
constructor(e) {
super("videoEncoderAvgQP"), this.data = e;
}
}
class ge extends Event {
constructor() {
super("webRtcSdp");
}
}
class me extends Event {
constructor() {
super("webRtcAutoConnect");
}
}
class pe extends Event {
constructor() {
super("webRtcConnecting");
}
}
class Se extends Event {
constructor() {
super("webRtcConnected");
}
}
class ve extends Event {
constructor() {
super("webRtcFailed");
}
}
class fe extends Event {
constructor(e) {
super("webRtcDisconnected"), this.data = e;
}
}
class Ce extends Event {
constructor(e) {
super("dataChannelOpen"), this.data = e;
}
}
class Te extends Event {
constructor(e) {
super("dataChannelClose"), this.data = e;
}
}
class ye extends Event {
constructor(e) {
super("dataChannelError"), this.data = e;
}
}
class Ee extends Event {
constructor() {
super("videoInitialized");
}
}
class Me extends Event {
constructor() {
super("streamLoading");
}
}
class we extends Event {
constructor() {
super("streamConnect");
}
}
class be extends Event {
constructor() {
super("streamDisconnect");
}
}
class Pe extends Event {
constructor() {
super("streamReconnect");
}
}
class Re extends Event {
constructor(e) {
super("playStreamError"), this.data = e;
}
}
class ke extends Event {
constructor() {
super("playStream");
}
}
class J extends Event {
constructor(e) {
super("playStreamRejected"), this.data = e;
}
}
class Le extends Event {
constructor(e) {
super("loadFreezeFrame"), this.data = e;
}
}
class xe extends Event {
constructor() {
super("hideFreezeFrame");
}
}
class Fe extends Event {
constructor(e) {
super("statsReceived"), this.data = e;
}
}
class Ae extends Event {
constructor(e) {
super("streamerListMessage"), this.data = e;
}
}
class De extends Event {
constructor(e) {
super("StreamerIDChangedMessage"), this.data = e;
}
}
class Ie extends Event {
constructor(e) {
super("latencyTestResult"), this.data = e;
}
}
class Oe extends Event {
constructor(e) {
super("dataChannelLatencyTestResponse"), this.data = e;
}
}
class Ue extends Event {
constructor(e) {
super("dataChannelLatencyTestResult"), this.data = e;
}
}
class Ge extends Event {
constructor(e) {
super("initialSettings"), this.data = e;
}
}
class B extends Event {
constructor(e) {
super("settingsChanged"), this.data = e;
}
}
class pt extends Event {
constructor() {
super("xrSessionStarted");
}
}
class St extends Event {
constructor() {
super("xrSessionEnded");
}
}
class ze extends Event {
constructor(e) {
super("xrFrame"), this.data = e;
}
}
class Be extends Event {
constructor(e) {
super("playerCount"), this.data = e;
}
}
class _e extends Event {
constructor() {
super("webRtcTCPRelayDetected");
}
}
class Ve extends EventTarget {
dispatchEvent(e) {
return super.dispatchEvent(e);
}
addEventListener(e, t) {
super.addEventListener(e, t);
}
removeEventListener(e, t) {
super.removeEventListener(e, t);
}
}
class l {
}
l.AutoConnect = "AutoConnect", l.AutoPlayVideo = "AutoPlayVideo", l.AFKDetection = "TimeoutIfIdle", l.BrowserSendOffer = "OfferToReceive", l.HoveringMouseMode = "HoveringMouse", l.ForceMonoAudio = "ForceMonoAudio", l.ForceTURN = "ForceTURN", l.FakeMouseWithTouches = "FakeMouseWithTouches", l.IsQualityController = "ControlsQuality", l.MatchViewportResolution = "MatchViewportRes", l.StartVideoMuted = "StartVideoMuted", l.SuppressBrowserKeys = "SuppressBrowserKeys", l.UseMic = "UseMic", l.KeyboardInput = "KeyboardInput", l.MouseInput = "MouseInput", l.TouchInput = "TouchInput", l.GamepadInput = "GamepadInput", l.XRControllerInput = "XRControllerInput", l.WaitForStreamer = "WaitForStreamer", l.HideUI = "HideUI";
const vt = (a) => Object.getOwnPropertyNames(l).some(((e) => l[e] === a));
class h {
}
h.AFKTimeoutSecs = "AFKTimeout", h.AFKCountdownSecs = "AFKCountdown", h.MinQP = "MinQP", h.MaxQP = "MaxQP", h.WebRTCFPS = "WebRTCFPS", h.WebRTCMinBitrate = "WebRTCMinBitrate", h.WebRTCMaxBitrate = "WebRTCMaxBitrate", h.MaxReconnectAttempts = "MaxReconnectAttempts", h.StreamerAutoJoinInterval = "StreamerAutoJoinInterval";
const ft = (a) => Object.getOwnPropertyNames(h).some(((e) => h[e] === a));
class F {
}
F.SignallingServerUrl = "ss";
const Ct = (a) => Object.getOwnPropertyNames(F).some(((e) => F[e] === a));
class v {
}
v.PreferredCodec = "PreferredCodec", v.StreamerId = "StreamerId";
const Tt = (a) => Object.getOwnPropertyNames(v).some(((e) => v[e] === a));
class yt {
constructor(e = {}) {
this.flags = /* @__PURE__ */ new Map(), this.numericParameters = /* @__PURE__ */ new Map(), this.textParameters = /* @__PURE__ */ new Map(), this.optionParameters = /* @__PURE__ */ new Map();
const { initialSettings: t, useUrlParams: s } = e;
this._useUrlParams = !!s, this.populateDefaultSettings(this._useUrlParams, t);
}
get useUrlParams() {
return this._useUrlParams;
}
populateDefaultSettings(e, t) {
this.textParameters.set(F.SignallingServerUrl, new le(F.SignallingServerUrl, "Signalling url", "Url of the signalling server", t && t.hasOwnProperty(F.SignallingServerUrl) ? t[F.SignallingServerUrl] : (location.protocol === "https:" ? "wss://" : "ws://") + window.location.hostname + (window.location.port === "80" || window.location.port === "" ? "" : `:${window.location.port}`), e)), this.optionParameters.set(v.StreamerId, new X(v.StreamerId, "Streamer ID", "The ID of the streamer to stream.", t && t.hasOwnProperty(v.StreamerId) ? t[v.StreamerId] : "", [], e)), this.optionParameters.set(v.PreferredCodec, new X(v.PreferredCodec, "Preferred Codec", "The preferred codec to be used during codec negotiation", "H264 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f", t && t.hasOwnProperty(v.PreferredCodec) ? [t[v.PreferredCodec]] : (function() {
const s = [];
if (!RTCRtpReceiver.getCapabilities) return s.push("Only available on Chrome"), s;
const n = /(VP\d|H26\d|AV1).*/;
return RTCRtpReceiver.getCapabilities("video").codecs.forEach(((i) => {
const o = i.mimeType.split("/")[1] + " " + (i.sdpFmtpLine || "");
n.exec(o) !== null && s.push(o);
})), s;
})(), e)), this.flags.set(l.AutoConnect, new C(l.AutoConnect, "Auto connect to stream", "Whether we should attempt to auto connect to the signalling server or show a click to start prompt.", !(!t || !t.hasOwnProperty(l.AutoConnect)) && t[l.AutoConnect], e)), this.flags.set(l.AutoPlayVideo, new C(l.AutoPlayVideo, "Auto play video", "When video is ready automatically start playing it as opposed to showing a play button.", !t || !t.hasOwnProperty(l.AutoPlayVideo) || t[l.AutoPlayVideo], e)), this.flags.set(l.BrowserSendOffer, new C(l.BrowserSendOffer, "Browser send offer", "Browser will initiate the WebRTC handshake by sending the offer to the streamer", !(!t || !t.hasOwnProperty(l.BrowserSendOffer)) && t[l.BrowserSendOffer], e)), this.flags.set(l.UseMic, new C(l.UseMic, "Use microphone", "Make browser request microphone access and open an input audio track.", !(!t || !t.hasOwnProperty(l.UseMic)) && t[l.UseMic], e)), this.flags.set(l.StartVideoMuted, new C(l.StartVideoMuted, "Start video muted", "Video will start muted if true.", !(!t || !t.hasOwnProperty(l.StartVideoMuted)) && t[l.StartVideoMuted], e)), this.flags.set(l.SuppressBrowserKeys, new C(l.SuppressBrowserKeys, "Suppress browser keys", "Suppress certain browser keys that we use in UE, for example F5 to show shader complexity instead of refresh the page.", !t || !t.hasOwnProperty(l.SuppressBrowserKeys) || t[l.SuppressBrowserKeys], e)), this.flags.set(l.IsQualityController, new C(l.IsQualityController, "Is quality controller?", "True if this peer controls stream quality", !t || !t.hasOwnProperty(l.IsQualityController) || t[l.IsQualityController], e)), this.flags.set(l.ForceMonoAudio, new C(l.ForceMonoAudio, "Force mono audio", "Force browser to request mono audio in the SDP", !(!t || !t.hasOwnProperty(l.ForceMonoAudio)) && t[l.ForceMonoAudio], e)), this.flags.set(l.ForceTURN, new C(l.ForceTURN, "Force TURN", "Only generate TURN/Relayed ICE candidates.", !(!t || !t.hasOwnProperty(l.ForceTURN)) && t[l.ForceTURN], e)), this.flags.set(l.AFKDetection, new C(l.AFKDetection, "AFK if idle", "Timeout the experience if user is AFK for a period.", !(!t || !t.hasOwnProperty(l.AFKDetection)) && t[l.AFKDetection], e)), this.flags.set(l.MatchViewportResolution, new C(l.MatchViewportResolution, "Match viewport resolution", "Pixel Streaming will be instructed to dynamically resize the video stream to match the size of the video element.", !(!t || !t.hasOwnProperty(l.MatchViewportResolution)) && t[l.MatchViewportResolution], e)), this.flags.set(l.HoveringMouseMode, new C(l.HoveringMouseMode, "Control Scheme: Locked Mouse", "Either locked mouse, where the pointer is consumed by the video and locked to it, or hovering mouse, where the mouse is not consumed.", !(!t || !t.hasOwnProperty(l.HoveringMouseMode)) && t[l.HoveringMouseMode], e, ((s, n) => {
n.label = `Control Scheme: ${s ? "Hovering" : "Locked"} Mouse`;
}))), this.flags.set(l.FakeMouseWithTouches, new C(l.FakeMouseWithTouches, "Fake mouse with touches", "A single finger touch is converted into a mouse event. This allows a non-touch application to be controlled partially via a touch device.", !(!t || !t.hasOwnProperty(l.FakeMouseWithTouches)) && t[l.FakeMouseWithTouches], e)), this.flags.set(l.KeyboardInput, new C(l.KeyboardInput, "Keyboard input", "If enabled, send keyboard events to streamer", !t || !t.hasOwnProperty(l.KeyboardInput) || t[l.KeyboardInput], e)), this.flags.set(l.MouseInput, new C(l.MouseInput, "Mouse input", "If enabled, send mouse events to streamer", !t || !t.hasOwnProperty(l.MouseInput) || t[l.MouseInput], e)), this.flags.set(l.TouchInput, new C(l.TouchInput, "Touch input", "If enabled, send touch events to streamer", !t || !t.hasOwnProperty(l.TouchInput) || t[l.TouchInput], e)), this.flags.set(l.GamepadInput, new C(l.GamepadInput, "Gamepad input", "If enabled, send gamepad events to streamer", !t || !t.hasOwnProperty(l.GamepadInput) || t[l.GamepadInput], e)), this.flags.set(l.XRControllerInput, new C(l.XRControllerInput, "XR controller input", "If enabled, send XR controller events to streamer", !t || !t.hasOwnProperty(l.XRControllerInput) || t[l.XRControllerInput], e)), this.flags.set(l.WaitForStreamer, new C(l.WaitForStreamer, "Wait for streamer", "Will continue trying to connect to the first streamer available.", !t || !t.hasOwnProperty(l.WaitForStreamer) || t[l.WaitForStreamer], e)), this.flags.set(l.HideUI, new C(l.HideUI, "Hide the UI overlay", "Will hide all UI overlay details", !(!t || !t.hasOwnProperty(l.HideUI)) && t[l.HideUI], e)), this.numericParameters.set(h.AFKTimeoutSecs, new k(h.AFKTimeoutSecs, "AFK timeout", "The time (in seconds) it takes for the application to time out if AFK timeout is enabled.", 0, null, t && t.hasOwnProperty(h.AFKTimeoutSecs) ? t[h.AFKTimeoutSecs] : 120, e)), this.numericParameters.set(h.AFKCountdownSecs, new k(h.AFKCountdownSecs, "AFK countdown", "The time (in seconds) for a user to respond before the stream is ended after an AFK timeout.", 10, null, 10, e)), this.numericParameters.set(h.MaxReconnectAttempts, new k(h.MaxReconnectAttempts, "Max Reconnects", "Maximum number of reconnects the application will attempt when a streamer disconnects.", 0, 999, t && t.hasOwnProperty(h.MaxReconnectAttempts) ? t[h.MaxReconnectAttempts] : 3, e)), this.numericParameters.set(h.MinQP, new k(h.MinQP, "Min QP", "The lower bound for the quantization parameter (QP) of the encoder. 0 = Best quality, 51 = worst quality.", 0, 51, t && t.hasOwnProperty(h.MinQP) ? t[h.MinQP] : 0, e)), this.numericParameters.set(h.MaxQP, new k(h.MaxQP, "Max QP", "The upper bound for the quantization parameter (QP) of the encoder. 0 = Best quality, 51 = worst quality.", 0, 51, t && t.hasOwnProperty(h.MaxQP) ? t[h.MaxQP] : 51, e)), this.numericParameters.set(h.WebRTCFPS, new k(h.WebRTCFPS, "Max FPS", "The maximum FPS that WebRTC will try to transmit frames at.", 1, 999, t && t.hasOwnProperty(h.WebRTCFPS) ? t[h.WebRTCFPS] : 60, e)), this.numericParameters.set(h.WebRTCMinBitrate, new k(h.WebRTCMinBitrate, "Min Bitrate (kbps)", "The minimum bitrate that WebRTC should use.", 0, 5e5, t && t.hasOwnProperty(h.WebRTCMinBitrate) ? t[h.WebRTCMinBitrate] : 0, e)), this.numericParameters.set(h.WebRTCMaxBitrate, new k(h.WebRTCMaxBitrate, "Max Bitrate (kbps)", "The maximum bitrate that WebRTC should use.", 0, 5e5, t && t.hasOwnProperty(h.WebRTCMaxBitrate) ? t[h.WebRTCMaxBitrate] : 0, e)), this.numericParameters.set(h.StreamerAutoJoinInterval, new k(h.StreamerAutoJoinInterval, "Streamer Auto Join Interval (ms)", "Delay between retries when waiting for an available streamer.", 500, 9e5, t && t.hasOwnProperty(h.StreamerAutoJoinInterval) ? t[h.StreamerAutoJoinInterval] : 3e3, e));
}
_addOnNumericSettingChangedListener(e, t) {
this.numericParameters.has(e) && this.numericParameters.get(e).addOnChangedListener(t);
}
_addOnOptionSettingChangedListener(e, t) {
this.optionParameters.has(e) && this.optionParameters.get(e).addOnChangedListener(t);
}
getNumericSettingValue(e) {
if (this.numericParameters.has(e)) return this.numericParameters.get(e).number;
throw new Error(`There is no numeric setting with the id of ${e}`);
}
getTextSettingValue(e) {
if (this.textParameters.has(e)) return this.textParameters.get(e).value;
throw new Error(`There is no numeric setting with the id of ${e}`);
}
setNumericSetting(e, t) {
if (!this.numericParameters.has(e)) throw new Error(`There is no numeric setting with the id of ${e}`);
this.numericParameters.get(e).number = t;
}
_addOnSettingChangedListener(e, t) {
this.flags.has(e) && (this.flags.get(e).onChange = t);
}
_addOnTextSettingChangedListener(e, t) {
this.textParameters.has(e) && (this.textParameters.get(e).onChange = t);
}
getSettingOption(e) {
return this.optionParameters.get(e);
}
isFlagEnabled(e) {
return this.flags.get(e).flag;
}
setFlagEnabled(e, t) {
this.flags.has(e) ? this.flags.get(e).flag = t : r.Warning(r.GetStackTrace(), `Cannot toggle flag called ${e} - it does not exist in the Config.flags map.`);
}
setTextSetting(e, t) {
this.textParameters.has(e) ? this.textParameters.get(e).text = t : r.Warning(r.GetStackTrace(), `Cannot set text setting called ${e} - it does not exist in the Config.textParameters map.`);
}
setOptionSettingOptions(e, t) {
this.optionParameters.has(e) ? this.optionParameters.get(e).options = t : r.Warning(r.GetStackTrace(), `Cannot set text setting called ${e} - it does not exist in the Config.optionParameters map.`);
}
setOptionSettingValue(e, t) {
if (this.optionParameters.has(e)) {
const s = this.optionParameters.get(e), n = s.options;
n.includes(t) || (n.push(t), s.options = n), s.selected = t;
} else r.Warning(r.GetStackTrace(), `Cannot set text setting called ${e} - it does not exist in the Config.enumParameters map.`);
}
setFlagLabel(e, t) {
this.flags.has(e) ? this.flags.get(e).label = t : r.Warning(r.GetStackTrace(), `Cannot set label for flag called ${e} - it does not exist in the Config.flags map.`);
}
setSettings(e) {
for (const t of Object.keys(e)) vt(t) ? this.setFlagEnabled(t, e[t]) : ft(t) ? this.setNumericSetting(t, e[t]) : Ct(t) ? this.setTextSetting(t, e[t]) : Tt(t) && this.setOptionSettingValue(t, e[t]);
}
getSettings() {
const e = {};
for (const [t, s] of this.flags.entries()) e[t] = s.flag;
for (const [t, s] of this.numericParameters.entries()) e[t] = s.number;
for (cons